X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=src%2Fclient%2Fmain.c;h=3c017a49a7cc06ba068f0a1cf665eb3c1a9d0e71;hb=9caffbc7ed251136bab144a957058e7d9f470b00;hp=2bd4312745a4a55fec20b9f8329dcd52d7261bd2;hpb=466d9edbb22becc1ece59bfef6b3e5ef39d8381f;p=tpg%2Fopendispense2.git diff --git a/src/client/main.c b/src/client/main.c index 2bd4312..3c017a4 100644 --- a/src/client/main.c +++ b/src/client/main.c @@ -16,6 +16,8 @@ #include // close/getuid #include // INT_MIN/INT_MAX #include "common.h" +#include "../common/doregex.h" +#include "../common/config.h" #define USE_NCURSES_INTERFACE 0 #define DEBUG_TRACE_SERVER 0 @@ -37,8 +39,12 @@ char *trim(char *string); void CompileRegex(regex_t *regex, const char *pattern, int flags); // === GLOBALS === -char *gsDispenseServer = "merlo.ucc.gu.uwa.edu.au"; +const char *gsConfigFile = "/etc/opendispense/client.conf"; + +const char *gsDispenseServer = "merlo.ucc.gu.uwa.edu.au"; int giDispensePort = 11020; + int giDispenseServerSet = 0; // True if set by command line + int giDispensePortSet = 0; // True if set by command line tItem *gaItems; int giNumItems; @@ -143,11 +149,19 @@ void ShowUsage(void) " Show help text\n" " -G\n" " Use simple textual interface (instead of ncurses)\n" + " -D\n" + " Drinks only in user interface\n" " -n\n" " Dry run - Do not actually do dispenses\n" " -m \n" " -M \n" " Set the Maximum/Minimum balances shown in `dispense acct`\n" + " -f \n" + " Set the config file path (default: `/etc/opendispense/client.conf'\n" + " -H \n" + " Set a different dispense host\n" + " -P \n" + " Set a different dispense port\n" "Definitions:\n" " \n" " Item ID of the form : where is a non-empty string of alpha-numeric characters, and is a non-negative integer\n" @@ -603,6 +617,21 @@ int main(int argc, char *argv[]) if( ret ) return ret; + // Load config file + // - Don't check return value, leads to defaults being used + if( Config_ParseFile(gsConfigFile) ) { + fprintf(stderr, "NOTICE: Loading of config file '%s' failed, using defaults\n", gsConfigFile); + } + + // Parse config values + if( !giDispenseServerSet ) { + Config_GetValue_Str("dispense_server", &gsDispenseServer); + } + if (!giDispensePortSet) { + Config_GetValue_Int("dispense_port", &giDispensePort); + } + + // Sub-commands if( strcmp(gsTextArgs[0], "finger") == 0 ) { return subcommand_finger(); @@ -818,22 +847,34 @@ int main(int argc, char *argv[]) int ParseArguments(int argc, char *argv[]) { + bool rest_free = false; for( int i = 1; i < argc; i ++ ) { char *arg = argv[i]; - if( arg[0] == '-' ) + // If it doesn't start with a '-', or -- has been seen + // XXX: Hack - If parsing "user type", don't parse - options + bool hack_usertype = (i > 2 && strcmp(argv[i-2], "user") == 0 && strcmp(argv[i-1], "type") == 0); + if( rest_free || arg[0] != '-' || hack_usertype ) + { + if( giTextArgc == MAX_TXT_ARGS ) + { + fprintf(stderr, "ERROR: Too many arguments\n"); + return RV_ARGUMENTS; + } + + gsTextArgs[giTextArgc++] = argv[i]; + } + else if( arg[1] != '-' ) { switch(arg[1]) { case 'h': case '?': ShowUsage(); - return 0; + exit(0); case 'c': - if( i > 2 && strcmp(argv[i-1], "type") == 0 ) - goto _default; if( i + 1 >= argc ) { fprintf(stderr, "%s: -c takes an argument\n", argv[0]); ShowUsage(); @@ -864,6 +905,15 @@ int ParseArguments(int argc, char *argv[]) giMaximumBalance = atoi(argv[++i]); break; + case 'f': // Override Config File + if( i + 1 >= argc ) { + fprintf(stderr, "%s: -f takes an argument\n", argv[0]); + ShowUsage(); + return RV_ARGUMENTS; + } + gsConfigFile = argv[++i]; + break; + case 'u': // Override User if( i + 1 >= argc ) { fprintf(stderr, "%s: -u takes an argument\n", argv[0]); @@ -880,6 +930,7 @@ int ParseArguments(int argc, char *argv[]) return RV_ARGUMENTS; } gsDispenseServer = argv[++i]; + giDispenseServerSet = 1; break; case 'P': // Override remote port if( i + 1 >= argc ) { @@ -888,6 +939,7 @@ int ParseArguments(int argc, char *argv[]) return RV_ARGUMENTS; } giDispensePort = atoi(argv[++i]); + giDispensePortSet = 1; break; // Set slot name/price @@ -910,54 +962,47 @@ int ParseArguments(int argc, char *argv[]) case 'n': // Dry Run / read-only gbDryRun = 1; break; - case '-': - if( strcmp(argv[i], "--help") == 0 ) { - ShowUsage(); - return 0; - } - else if( strcmp(argv[i], "--dry-run") == 0 ) { - gbDryRun = 1; - } - else if( strcmp(argv[i], "--drinks-only") == 0 ) { - giUIMode = UI_MODE_DRINKSONLY; - } - else if( strcmp(argv[i], "--can-select-all") == 0 ) { - gbDisallowSelectWithoutBalance = 0; - } - else { - fprintf(stderr, "%s: Unknown switch '%s'\n", argv[0], argv[i]); - ShowUsage(); - return RV_ARGUMENTS; - } - break; - default: _default: - // The first argument is not allowed to begin with 'i' - // (catches most bad flags) - if( giTextArgc == 0 ) { - fprintf(stderr, "%s: Unknown switch '%s'\n", argv[0], argv[i]); - ShowUsage(); - return RV_ARGUMENTS; - } - if( giTextArgc == MAX_TXT_ARGS ) - { - fprintf(stderr, "ERROR: Too many arguments\n"); - return RV_ARGUMENTS; - } - gsTextArgs[giTextArgc++] = argv[i]; - break; + default: + fprintf(stderr, "%s: Unknown switch '%s'\n", argv[0], argv[i]); + ShowUsage(); + return RV_ARGUMENTS; } continue; } - - if( giTextArgc == MAX_TXT_ARGS ) + else { - fprintf(stderr, "ERROR: Too many arguments\n"); - return RV_ARGUMENTS; + // '--' : Terminate argument processing (remainder is free) + if( arg[2] == '\0' ) { + rest_free = true; + } + else if( strcmp(arg, "--help") == 0 ) { + ShowUsage(); + exit(0); + } + else if( strcmp(arg, "--dry-run") == 0 ) { + gbDryRun = 1; + } + else if( strcmp(arg, "--drinks-only") == 0 ) { + giUIMode = UI_MODE_DRINKSONLY; + } + else if( strcmp(arg, "--can-select-all") == 0 ) { + gbDisallowSelectWithoutBalance = 0; + } + else if( strcmp(arg, "--configfile") == 0 ) { + if( i + 1 >= argc ) { + fprintf(stderr, "%s: %s takes an argument\n", argv[0], arg); + ShowUsage(); + return RV_ARGUMENTS; + } + gsConfigFile = argv[++i]; + } + else { + fprintf(stderr, "%s: Unknown switch '%s'\n", argv[0], arg); + ShowUsage(); + return RV_ARGUMENTS; + } } - - gsTextArgs[giTextArgc++] = argv[i]; - } return 0; } @@ -967,47 +1012,13 @@ int ParseArguments(int argc, char *argv[]) // --------------- char *trim(char *string) { - int i; - + // Increment pointer while it points to a space while( isspace(*string) ) string ++; - for( i = strlen(string); i--; ) - { - if( isspace(string[i]) ) - string[i] = '\0'; - else - break; - } + // And repalce trailing spaces with NUL bytes + for( int i = strlen(string); i-- && isspace(string[i]); ) + string[i] = '\0'; return string; } - -int RunRegex(regex_t *regex, const char *string, int nMatches, regmatch_t *matches, const char *errorMessage) -{ - int ret; - - ret = regexec(regex, string, nMatches, matches, 0); - if( ret && errorMessage ) { - size_t len = regerror(ret, regex, NULL, 0); - char errorStr[len]; - regerror(ret, regex, errorStr, len); - printf("string = '%s'\n", string); - fprintf(stderr, "%s\n%s", errorMessage, errorStr); - exit(-1); - } - - return ret; -} - -void CompileRegex(regex_t *regex, const char *pattern, int flags) -{ - int ret = regcomp(regex, pattern, flags); - if( ret ) { - size_t len = regerror(ret, regex, NULL, 0); - char errorStr[len]; - regerror(ret, regex, errorStr, len); - fprintf(stderr, "Regex compilation failed - %s\n", errorStr); - exit(-1); - } -}