X-Git-Url: https://git.ucc.asn.au/?p=tpg%2Fopendispense2.git;a=blobdiff_plain;f=src%2Fserver%2Fitemdb.c;h=e48ab868a7a50278cd0479a7c0933566ee69b6a0;hp=e63bb65df618d8a40c85e7428347a3050e53cf0d;hb=ec400f11ebc2e81079e464145915fb2d25602fbc;hpb=3e1c2bf267dea8c592f41636c3d0fb1c7253ee26 diff --git a/src/server/itemdb.c b/src/server/itemdb.c index e63bb65..e48ab86 100644 --- a/src/server/itemdb.c +++ b/src/server/itemdb.c @@ -13,10 +13,8 @@ #include #include "common.h" #include -#include -#include -#include -#include +#include +#include // === IMPORTS === extern tHandler gCoke_Handler; @@ -25,13 +23,14 @@ extern tHandler gDoor_Handler; // === PROTOTYPES === void Init_Handlers(void); -void ItemList_Changed(int signum); void Load_Itemlist(void); +void Items_ReadFromFile(void); char *trim(char *__str); // === GLOBALS === int giNumItems = 0; tItem *gaItems = NULL; +time_t gItems_LastUpdated; tHandler gPseudo_Handler = {Name:"pseudo"}; tHandler *gaHandlers[] = {&gPseudo_Handler, &gCoke_Handler, &gSnack_Handler, &gDoor_Handler}; int giNumHandlers = sizeof(gaHandlers)/sizeof(gaHandlers[0]); @@ -39,6 +38,7 @@ char *gsItemListFile = DEFAULT_ITEM_FILE; #if USE_INOTIFY int giItem_INotifyFD; #endif +regex_t gItemFile_Regex; // === CODE === void Init_Handlers() @@ -81,30 +81,55 @@ void ItemList_Changed(int signum) #endif /** - * \brief Read the item list from disk + * \brief Read the initiali item list */ void Load_Itemlist(void) { - FILE *fp = fopen(gsItemListFile, "r"); + int rv; + rv = regcomp(&gItemFile_Regex, "^-?([a-zA-Z][a-zA-Z]*)\\s+([0-9]+)\\s+([0-9]+)\\s+(.*)", REG_EXTENDED); + if( rv ) + { + size_t len = regerror(rv, &gItemFile_Regex, NULL, 0); + char errorStr[len]; + regerror(rv, &gItemFile_Regex, errorStr, len); + fprintf(stderr, "Rexex compilation failed - %s\n", errorStr); + exit(-1); + } + + Items_ReadFromFile(); + + // Re-read the item file periodically + // TODO: Be less lazy here and check the timestamp + AddPeriodicFunction( Items_ReadFromFile ); +} +/** + * \brief Read the item list from disk + */ +void Items_ReadFromFile(void) +{ + FILE *fp; char buffer[BUFSIZ]; char *line; int lineNum = 0; - int i; - regex_t regex; + int i, numItems = 0; + tItem *items = NULL; regmatch_t matches[5]; - - i = regcomp(®ex, "^-?([a-zA-Z][a-zA-Z]*)\\s+([0-9]+)\\s+([0-9]+)\\s+(.*)", REG_EXTENDED); - if( i ) + + if( gItems_LastUpdated ) { - size_t len = regerror(i, ®ex, NULL, 0); - char *errorStr = malloc(len); - regerror(i, ®ex, errorStr, len); - fprintf(stderr, "Rexex compilation failed - %s\n", errorStr); - free(errorStr); - exit(-1); + struct stat buf; + if( stat(gsItemListFile, &buf) ) { + fprintf(stderr, "Unable to stat() item file '%s'\n", gsItemListFile); + return ; + } + + // Check if the update is needed + if( gItems_LastUpdated > buf.st_mtime ) + return ; } // Error check + fp = fopen(gsItemListFile, "r"); if(!fp) { fprintf(stderr, "Unable to open item file '%s'\n", gsItemListFile); perror("Unable to open item file"); @@ -131,13 +156,9 @@ void Load_Itemlist(void) if(strlen(line) == 0) continue; // Pass regex over line - if( (i = regexec(®ex, line, 5, matches, 0)) ) { - size_t len = regerror(i, ®ex, NULL, 0); - char *errorStr = malloc(len); - regerror(i, ®ex, errorStr, len); - fprintf(stderr, "Syntax error on line %i of item file '%s'\n%s", lineNum, gsItemListFile, errorStr); - free(errorStr); - exit(-1); + if( RunRegex( &gItemFile_Regex, line, 5, matches, NULL) ) { + fprintf(stderr, "Syntax error on line %i of item file '%s'\n", lineNum, gsItemListFile); + return ; } // Read line data @@ -162,27 +183,41 @@ void Load_Itemlist(void) continue ; } - for( i = 0; i < giNumItems; i ++ ) + for( i = 0; i < numItems; i ++ ) { - if( gaItems[i].Handler != handler ) continue; - if( gaItems[i].ID != num ) continue; + if( items[i].Handler != handler ) continue; + if( items[i].ID != num ) continue; printf("Redefinition of %s:%i, updated\n", handler->Name, num); - gaItems[i].Price = price; - free(gaItems[i].Name); - gaItems[i].Name = strdup(desc); + items[i].Price = price; + free(items[i].Name); + items[i].Name = strdup(desc); break; } - if( i < giNumItems ) continue; - - gaItems = realloc( gaItems, (giNumItems + 1)*sizeof(gaItems[0]) ); - gaItems[giNumItems].Handler = handler; - gaItems[giNumItems].ID = num; - gaItems[giNumItems].Price = price; - gaItems[giNumItems].Name = strdup(desc); - gaItems[giNumItems].bHidden = (line[0] == '-'); - giNumItems ++; - } + if( i < numItems ) continue; + + items = realloc( items, (numItems + 1)*sizeof(items[0]) ); + items[numItems].Handler = handler; + items[numItems].ID = num; + items[numItems].Price = price; + items[numItems].Name = strdup(desc); + items[numItems].bHidden = (line[0] == '-'); + numItems ++; + } + + // Clean up old + if( giNumItems ) + { + giNumItems = 0; + free(gaItems); + gaItems = NULL; + } + + // Replace with new + giNumItems = numItems; + gaItems = items; + + gItems_LastUpdated = time(NULL); } char *trim(char *__str)