Merge branch 'master' of git://mutabah.net/opendispense2
[tpg/opendispense2.git] / src / server / handler_door.c
1 /*
2  * OpenDispense 2 
3  * UCC (University [of WA] Computer Club) Electronic Accounting System
4  *
5  * handler_doror.c - Door Relay code
6  *
7  * This file is licenced under the 3-clause BSD Licence. See the file
8  * COPYING for full details.
9  */
10 #define DEBUG   1
11 #define USE_POPEN       0
12
13 #include "common.h"
14 #include <stdio.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 #include <signal.h>
20 #if !USE_POPEN
21 # include <unistd.h>
22 #endif
23
24 #define DOOR_UNLOCKED_DELAY     10      // 10 seconds before it re-locks
25
26 // === IMPORTS ===
27
28 // === PROTOTYPES ===
29  int    Door_InitHandler();
30  int    Door_CanDispense(int User, int Item);
31  int    Door_DoDispense(int User, int Item);
32
33 // === GLOBALS ===
34 tHandler        gDoor_Handler = {
35         "door",
36         Door_InitHandler,
37         Door_CanDispense,
38         Door_DoDispense
39 };
40 char    *gsDoor_Password = "";
41
42 // == CODE ===
43 int Door_InitHandler(void)
44 {       
45         return 0;
46 }
47
48 /**
49  */
50 int Door_CanDispense(int User, int Item)
51 {
52         #if DEBUG
53         printf("Door_CanDispense: (User=%i,Item=%i)\n", User, Item);
54         #endif
55         // Sanity please
56         if( Item != 0 ) return -1;
57         
58         if( !(Bank_GetFlags(User) & USER_FLAG_DOORGROUP) )
59         {
60                 #if DEBUG
61                 printf("Door_CanDispense: User %i not in door\n", User);
62                 #endif
63                 return 1;
64         }
65         
66         #if DEBUG
67         printf("Door_CanDispense: User %i can open the door\n", User);
68         #endif
69         
70         return 0;
71 }
72
73 /**
74  * \brief Actually do a dispense from the coke machine
75  */
76 int Door_DoDispense(int User, int Item)
77 {
78         FILE    *child_stdin;
79         char    buf[512];
80         #if !USE_POPEN
81          int    stdin_pair[2];
82          int    stdout_pair[2];
83         pid_t   childPid;
84         #endif
85         
86         #if DEBUG
87         printf("Door_DoDispense: (User=%i,Item=%i)\n", User, Item);
88         #endif
89         
90         // Sanity please
91         if( Item != 0 ) return -1;
92         
93         // Check if user is in door
94         if( !(Bank_GetFlags(User) & USER_FLAG_DOORGROUP) )
95         {
96                 #if DEBUG
97                 printf("Door_CanDispense: User %i not in door\n", User);
98                 #endif
99                 return 1;
100         }
101         
102         #if !USE_POPEN
103         // Create stdin/stdout
104         if( pipe(stdin_pair) || pipe(stdout_pair) )
105         {
106                 perror("pipe");
107                 return -1;
108         }
109         
110         childPid = fork();
111         
112         if( childPid < 0 )
113         {
114                 perror("fork");
115                 return -1;
116         }
117         
118         // Child process
119         if( childPid == 0 )
120         {
121                 // Close write end of stdin, and set it to #0
122                 close(stdin_pair[1]);   dup2(stdin_pair[0], 0);
123                 // Close read end of stdout, and set it to #1
124                 close(stdout_pair[0]);  dup2(stdout_pair[1], 1);
125                 
126                 execl("/bin/sh", "sh", "-c", "llogin door -w-", NULL);
127                 perror("execl");
128                 exit(-1);
129         }
130         
131         child_stdin = fdopen(stdin_pair[1], "w");
132         close(stdin_pair[0]);   // child stdin read
133         close(stdout_pair[1]);  // child stdout write
134         
135         #else
136         // llogin or other
137         child_stdin = popen("llogin door -w -", "w");
138         if( !child_stdin || child_stdin == (void*)-1 ) {
139                 #if DEBUG
140                 printf("Door_DoDispense: llogin failure\n");
141                 #endif
142                 return -1;
143         }
144         #endif
145         
146         if(fread(buf, 1, 512, child_stdin) == 0) {
147                 #if DEBUG
148                 printf("Door_DoDispense: fread fail\n");
149                 #endif
150                 return -1;
151         }
152         
153         // Send password
154         if( fputs(gsDoor_Password, child_stdin) <= 0 ) {
155                 #if DEBUG
156                 printf("Door_DoDispense: fputs password\n");
157                 #endif
158                 return -1;
159         }
160         fputs("\n", child_stdin);
161         
162         
163         #if DEBUG
164         printf("Door_DoDispense: Door unlock\n");
165         #endif
166         
167         // ATH1 - Unlock door
168         if( fputs("ATH1\n", child_stdin) <= 0) {
169                 #if DEBUG
170                 printf("Door_DoDispense: fputs unlock\n");
171                 #endif
172                 return -1;
173         }
174         
175         // Wait before re-locking
176         sleep(DOOR_UNLOCKED_DELAY);
177
178
179         #if DEBUG
180         printf("Door_DoDispense: Door re-lock\n");
181         #endif
182
183         // Re-lock the door
184         if( fputs("ATH0\n", child_stdin) <= 0 ) {
185                 #if DEBUG
186                 printf("Door_DoDispense: fputs lock\n");
187                 #endif
188                 return -1;
189         }
190         
191         #if !USE_POPEN
192         fclose(child_stdin);
193         close(stdin_pair[1]);   // child stdin write
194         close(stdout_pair[0]);  // child stdout read
195         #else
196         pclose(child_stdin);
197         #endif
198         
199         #if DEBUG
200         printf("Door_DoDispense: User %i opened door\n", User);
201         #endif
202
203         return 0;
204 }
205

UCC git Repository :: git.ucc.asn.au