3 * UCC (University [of WA] Computer Club) Electronic Accounting System
5 * handler_doror.c - Door Relay code
7 * This file is licenced under the 3-clause BSD Licence. See the file
8 * COPYING for full details.
24 #define DOOR_UNLOCKED_DELAY 5 // Time in seconds before the door re-locks
29 int Door_InitHandler();
30 int Door_CanDispense(int User, int Item);
31 int Door_DoDispense(int User, int Item);
34 tHandler gDoor_Handler = {
40 char *gsDoor_Password = "";
41 volatile int giDoor_ChildStatus;
44 void Door_SIGCHLDHandler(int signum)
47 giDoor_ChildStatus ++;
48 printf("SIGCHLD: giDoor_ChildStatus = %i \n", giDoor_ChildStatus);
51 int Door_InitHandler(void)
53 signal(SIGCHLD, Door_SIGCHLDHandler);
59 int Door_CanDispense(int User, int Item)
62 printf("Door_CanDispense: (User=%i,Item=%i)\n", User, Item);
65 if( Item != 0 ) return -1;
67 if( !(Bank_GetFlags(User) & USER_FLAG_DOORGROUP) )
70 printf("Door_CanDispense: User %i not in door\n", User);
76 printf("Door_CanDispense: User %i can open the door\n", User);
83 * \brief Actually do a dispense from the coke machine
85 int Door_DoDispense(int User, int Item)
98 printf("Door_DoDispense: (User=%i,Item=%i)\n", User, Item);
102 if( Item != 0 ) return -1;
104 // Check if user is in door
105 if( !(Bank_GetFlags(User) & USER_FLAG_DOORGROUP) )
108 printf("Door_CanDispense: User %i not in door\n", User);
113 giDoor_ChildStatus = 0; // Set child status to zero
114 parentPid = getpid();
115 childPid = forkpty(&child_stdin_fd, NULL, NULL, NULL);
126 execl("/usr/bin/llogin", "llogin", "door", "-w-", NULL);
131 child_stdin = fdopen(child_stdin_fd, "w");
133 int read_child_output()
137 if( giDoor_ChildStatus || (len = read(child_stdin_fd, buf, sizeof buf)) < 0)
140 printf("Door_DoDispense: fread fail\n");
147 printf("Door_DoDispense: buf = %i '%s'\n", len, buf);
152 if( read_child_output() ) return -1;
155 if( giDoor_ChildStatus || fputs(gsDoor_Password, child_stdin) <= 0 ) {
156 printf("Door_DoDispense: fputs password fail\n");
159 fputs("\n", child_stdin);
162 if( read_child_output() ) return -1;
165 printf("Door_DoDispense: Door unlock\n");
167 // ATH1 - Unlock door
168 if( giDoor_ChildStatus || fputs("ATH1\n", child_stdin) == 0) {
170 printf("Door_DoDispense: fputs unlock failed (or child terminated)\n");
176 // Wait before re-locking
177 sleep(DOOR_UNLOCKED_DELAY);
180 printf("Door_DoDispense: Door re-lock\n");
182 // Re-lock the door (and quit llogin)
183 if( giDoor_ChildStatus || fputs("ATH0\n", child_stdin) == 0 ) {
184 fprintf(stderr, "Oh F**k, the door may be stuck unlocked, someone use llogin!\n");
188 fputs("\x1D", child_stdin);
190 // Wait a little so llogin can send the lock message
194 close(child_stdin_fd);
197 printf("Door_DoDispense: User %i opened door\n", User);
200 kill(childPid, SIGKILL);