3 * UCC (University [of WA] Computer Club) Electronic Accounting System
5 * main.c - Initialisation Code
7 * This file is licenced under the 3-clause BSD Licence. See the file
8 * COPYING for full details.
22 #include "../cokebank.h"
25 extern void Init_Handlers(void);
26 extern void Load_Itemlist(void);
27 extern void Server_Start(void);
28 extern int gbServer_RunInBackground;
29 extern int giServer_Port;
30 extern char *gsItemListFile;
31 extern char *gsCoke_SerialPort;
32 extern char *gsSnack_SerialPort;
33 extern char *gsDoor_Password;
36 void *Periodic_Thread(void *Unused);
40 char *gsCokebankPath = "cokebank.db";
41 // - Functions called every 20s (or so)
42 #define ciMaxPeriodics 10
43 struct sPeriodicCall {
44 void (*Function)(void);
45 } gaPeriodicCalls[ciMaxPeriodics];
53 void PrintUsage(const char *progname)
55 fprintf(stderr, "Usage: %s\n", progname);
56 fprintf(stderr, " -p Set server port (default 11020)\n");
57 fprintf(stderr, " -d Set debug level (0 - 2, default 0)\n");
58 fprintf(stderr, " --itemsfile\n");
59 fprintf(stderr, " Set debug level (0 - 2, default 0)\n");
60 fprintf(stderr, " --cokeport\n");
61 fprintf(stderr, " Coke machine serial port (Default \"/dev/ttyS0\")\n");
62 fprintf(stderr, " --doorpass\n");
63 fprintf(stderr, " Door LAT password file (Default empty password)\n");
64 fprintf(stderr, " --cokebank\n");
65 fprintf(stderr, " Coke bank database file (Default \"cokebank.db\")\n");
68 int main(int argc, char *argv[])
71 pthread_t timer_thread;
74 for( i = 1; i < argc; i++ )
77 if( arg[0] == '-' && arg[1] != '-')
82 if( i + 1 >= argc ) return -1;
83 giServer_Port = atoi(argv[++i]);
86 if( i + 1 >= argc ) return -1;
87 giDebugLevel = atoi(argv[++i]);
90 gbServer_RunInBackground = 1;
98 else if( arg[0] == '-' && arg[1] == '-' ) {
99 if( strcmp(arg, "--itemsfile") == 0 ) {
100 if( i + 1 >= argc ) return -1;
101 gsItemListFile = argv[++i];
103 else if( strcmp(arg, "--cokeport") == 0 ) {
104 if( i + 1 >= argc ) return -1;
105 gsCoke_SerialPort = argv[++i];
107 else if( strcmp(arg, "--snackport") == 0 ) {
108 if( i + 1 >= argc ) return -1;
109 gsSnack_SerialPort = argv[++i];
111 else if( strcmp(arg, "--doorpass") == 0 ) {
114 if( i + 1 >= argc ) return -1;
115 fp = fopen(argv[++i], "r");
117 fprintf(stderr, "ERROR: Unable to read password file\n");
118 perror("reading LAT password");
121 fgets(buf, sizeof buf, fp);
123 gsDoor_Password = strdup(buf);
125 else if( strcmp(arg, "--cokebank") == 0 ) {
126 if( i + 1 >= argc ) return -1;
127 gsCokebankPath = argv[++i];
129 else if( strcmp(arg, "--daemonise") == 0 ) {
130 gbServer_RunInBackground = 1;
132 else if( strcmp(arg, "--dont-daemonise") == 0 ) {
133 gbServer_RunInBackground = 1;
148 signal(SIGINT, sigint_handler);
149 signal(SIGTERM, sigint_handler);
151 openlog("odispense2", 0, LOG_LOCAL4);
153 if( Bank_Initialise(gsCokebankPath) )
160 pthread_create( &timer_thread, NULL, Periodic_Thread, NULL );
164 pthread_kill(timer_thread, SIGKILL);
169 void *Periodic_Thread(void *Unused)
172 Unused = NULL; // quiet, gcc
176 sleep(10); // Sleep for a while
177 // printf("Periodic firing\n");
178 for( i = 0; i < ciMaxPeriodics; i ++ )
180 if( gaPeriodicCalls[i].Function )
181 gaPeriodicCalls[i].Function();
187 void AddPeriodicFunction(void (*Fcn)(void))
190 for( i = 0; i < ciMaxPeriodics; i ++ )
192 if( gaPeriodicCalls[i].Function ) continue;
193 gaPeriodicCalls[i].Function = Fcn;
197 fprintf(stderr, "Error: No space for %p in periodic list\n", Fcn);
200 int RunRegex(regex_t *regex, const char *string, int nMatches, regmatch_t *matches, const char *errorMessage)
204 ret = regexec(regex, string, nMatches, matches, 0);
205 if( ret == REG_NOMATCH ) {
209 size_t len = regerror(ret, regex, NULL, 0);
211 regerror(ret, regex, errorStr, len);
212 printf("string = '%s'\n", string);
213 fprintf(stderr, "%s\n%s", errorMessage, errorStr);
220 void CompileRegex(regex_t *regex, const char *pattern, int flags)
222 int ret = regcomp(regex, pattern, flags);
224 size_t len = regerror(ret, regex, NULL, 0);
226 regerror(ret, regex, errorStr, len);
227 fprintf(stderr, "Regex compilation failed - %s\n", errorStr);
233 int InitSerial(const char *File, int BaudRate)
239 fd = open(File, O_RDWR | O_NOCTTY | O_NONBLOCK);
240 if( fd == -1 ) return -1;
244 case 9600: baud = B9600; break;
245 default: close(fd); return -1;
248 info.c_lflag = 0; // Non-Canoical, No Echo
249 info.c_cflag = baud | CS8 | CLOCAL | CREAD; // baud, 8N1
250 cfsetspeed(&info, baud);
251 info.c_cc[VTIME] = 0; // No time limit
252 info.c_cc[VMIN] = 1; // Block until 1 char
254 tcflush(fd, TCIFLUSH);
255 tcsetattr(fd, TCSANOW, &info);
262 * \brief Create a formatted heap string
264 char *mkstr(const char *Format, ...)
270 va_start(args, Format);
271 len = vsnprintf(NULL, 0, Format, args);
274 ret = malloc( len + 1 );
275 if(!ret) return NULL;
277 va_start(args, Format);
278 vsprintf(ret, Format, args);