# HG changeset patch # User markus schnalke # Date 1288879362 10800 # Node ID f9da5a7caeda0bcd0b274f3e166b43aa48ff4abb # Parent 018cfd163f5cad3c9411b3accdaa3c0a234dcd00 refactored the cmdline argument processing I replaced the nested switch statements with one single large else-if construct. Instead of char comparision now str(n)cmp(3) is used. Although this is slower it is much more readable and covers corner-cases which were uncovered before (e.g. -bdxxx). As always: Readability and simplicity matter, not performance. diff -r 018cfd163f5c -r f9da5a7caeda src/masqmail.c --- a/src/masqmail.c Mon Nov 01 14:53:26 2010 -0300 +++ b/src/masqmail.c Thu Nov 04 11:02:42 2010 -0300 @@ -91,19 +91,25 @@ } #endif +/* +argv: the original argv +argp: number of arg (may get modified!) +cp: pointing to the char after the option + e.g. `-d 6' `-d6' + ^ ^ +*/ gchar* -get_optarg(char *argv[], gint argc, gint * argp, gint * pos) +get_optarg(char* argv[], gint* argp, char* cp) { - if (argv[*argp][*pos]) - return &(argv[*argp][*pos]); - else { - if (*argp + 1 < argc) { - if (argv[(*argp) + 1][0] != '-') { - (*argp)++; - *pos = 0; - return &(argv[*argp][*pos]); - } - } + if (*cp) { + /* this kind: -xval */ + return cp; + } + cp = argv[*argp+1]; + if (cp && (*cp != '-')) { + /* this kind: -x val */ + (*argp)++; + return cp; } return NULL; } @@ -288,7 +294,8 @@ { /* cmd line flags */ gchar *conf_file = CONF_FILE; - gint arg = 1; + char* opt; + gint arg; gboolean do_listen = FALSE; gboolean do_runq = FALSE; @@ -336,166 +343,124 @@ } /* parse cmd line */ - while (arg < argc) { - gint pos = 0; - if ((argv[arg][pos] == '-') && (argv[arg][pos + 1] != '-')) { - pos++; - switch (argv[arg][pos++]) { - case 'b': - switch (argv[arg][pos++]) { - case 'd': - do_listen = TRUE; - mta_mode = MODE_DAEMON; - break; - case 'i': - /* ignored */ - mta_mode = MODE_BI; - break; - case 's': - mta_mode = MODE_SMTP; - break; - case 'p': - mta_mode = MODE_LIST; - break; - case 'V': - mta_mode = MODE_VERSION; - break; - default: - fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); - exit(EXIT_FAILURE); - } - break; - case 'B': - /* we ignore this and throw the argument away */ - get_optarg(argv, argc, &arg, &pos); - break; - case 'C': - if (!(conf_file = get_optarg(argv, argc, &arg, &pos))) { - fprintf(stderr, "-C requires a filename as argument.\n"); - exit(EXIT_FAILURE); - } - break; - case 'F': - { - full_sender_name = get_optarg(argv, argc, &arg, &pos); - if (!full_sender_name) { - fprintf(stderr, "-F requires a name as an argument\n"); - exit(EXIT_FAILURE); - } - } - break; - case 'd': - if (getuid() == 0) { - char *lvl = get_optarg(argv, argc, &arg, &pos); - if (lvl) - debug_level = atoi(lvl); - else { - fprintf(stderr, "-d requires a number as an argument.\n"); - exit(EXIT_FAILURE); - } - } else { - fprintf(stderr, "only root may set the debug level.\n"); - exit(EXIT_FAILURE); - } - break; - case 'f': - /* set return path */ - { - gchar *address; - address = get_optarg(argv, argc, &arg, &pos); - if (address) { - f_address = g_strdup(address); - } else { - fprintf(stderr, "-f requires an address as an argument\n"); - exit(EXIT_FAILURE); - } - } - break; - case 'i': - if (argv[arg][pos] == 0) { - opt_i = TRUE; - exit_failure = FALSE; /* may override -oem */ - } else { - fprintf(stderr, "unrecognized option '%s'\n", argv[arg]); - exit(EXIT_FAILURE); - } - break; - case 'M': - { - mta_mode = MODE_MCMD; - M_cmd = g_strdup(&(argv[arg][pos])); - } - break; - case 'm': - /* ignore -m (me too) switch (see man page) */ - break; - case 'o': - char* oarg = argv[arg][pos+1]; - if (strcmp(oarg, "oem") == 0) { - if (!opt_i) { - /* FIXME: this check needs to be done after - option processing as -oi may come later */ - exit_failure = TRUE; - } - } else if (strcmp(oarg, "odb") == 0) { - /* ignore ``deliver in background'' switch */ - } else if (strcmp(oarg, "odq") == 0) { - do_queue = TRUE; - } else if (strcmp(oarg, "oi") == 0) { - exit_failure = FALSE; /* may override -oem */ - } else if (strcmp(oarg, "om") == 0) { - /* ignore ``me too'' switch */ - } else { - fprintf(stderr, "ignoring unrecognized option %s\n", - argv[arg]); - } - break; + for (arg=1; arg