/* * Parse the next flag (and value if specified), return 0 if done, -1 on * error, otherwise the flag's retval. */ int opt_next(void) { char *p; const OPTIONS *o; int ival; long lval; unsigned long ulval; ossl_intmax_t imval; ossl_uintmax_t umval; /* Look at current arg; at end of the list? */ arg = NULL; p = argv[opt_index]; if (p == NULL) return 0; /* If word doesn't start with a -, we're done. */ if (*p != '-') return 0; /* Hit "--" ? We're done. */ opt_index++; if (strcmp(p, "--") == 0) return 0; /* Allow -nnn and --nnn */ if (*++p == '-') p++; flag = p - 1; /* If we have --flag=foo, snip it off */ if ((arg = strchr(p, '=')) != NULL) *arg++ = '\0'; for (o = opts; o->name; ++o) { /* If not this option, move on to the next one. */ if (strcmp(p, o->name) != 0) continue; /* If it doesn't take a value, make sure none was given. */ if (o->valtype == 0 || o->valtype == '-') { if (arg) { BIO_printf(bio_err, "%s: Option -%s does not take a value\n", prog, p); return -1; } return o->retval; } /* Want a value; get the next param if =foo not used. */ if (arg == NULL) { if (argv[opt_index] == NULL) { BIO_printf(bio_err, "%s: Option -%s needs a value\n", prog, o->name); return -1; } arg = argv[opt_index++]; } /* Syntax-check value. */ switch (o->valtype) { default: case 's': /* Just a string. */ break; case '/': if (app_isdir(arg) >= 0) break; BIO_printf(bio_err, "%s: Not a directory: %s\n", prog, arg); return -1; case '<': /* Input file. */ if (strcmp(arg, "-") == 0 || app_access(arg, R_OK) >= 0) break; BIO_printf(bio_err, "%s: Cannot open input file %s, %s\n", prog, arg, strerror(errno)); return -1; case '>': /* Output file. */ if (strcmp(arg, "-") == 0 || app_access(arg, W_OK) >= 0 || errno == ENOENT) break; BIO_printf(bio_err, "%s: Cannot open output file %s, %s\n", prog, arg, strerror(errno)); return -1; case 'p': case 'n': if (!opt_int(arg, &ival) || (o->valtype == 'p' && ival <= 0)) { BIO_printf(bio_err, "%s: Non-positive number \"%s\" for -%s\n", prog, arg, o->name); return -1; } break; case 'M': if (!opt_imax(arg, &imval)) { BIO_printf(bio_err, "%s: Invalid number \"%s\" for -%s\n", prog, arg, o->name); return -1; } break; case 'U': if (!opt_umax(arg, &umval)) { BIO_printf(bio_err, "%s: Invalid number \"%s\" for -%s\n", prog, arg, o->name); return -1; } break; case 'l': if (!opt_long(arg, &lval)) { BIO_printf(bio_err, "%s: Invalid number \"%s\" for -%s\n", prog, arg, o->name); return -1; } break; case 'u': if (!opt_ulong(arg, &ulval)) { BIO_printf(bio_err, "%s: Invalid number \"%s\" for -%s\n", prog, arg, o->name); return -1; } break; case 'E': case 'F': case 'f': if (opt_format(arg, o->valtype == 'E' ? OPT_FMT_PDE : o->valtype == 'F' ? OPT_FMT_PEMDER : OPT_FMT_ANY, &ival)) break; BIO_printf(bio_err, "%s: Invalid format \"%s\" for -%s\n", prog, arg, o->name); return -1; } /* Return the flag value. */ return o->retval; } if (unknown != NULL) { dunno = p; return unknown->retval; } BIO_printf(bio_err, "%s: Option unknown option -%s\n", prog, p); return -1; }
/* * Parse the next flag (and value if specified), return 0 if done, -1 on * error, otherwise the flag's retval. */ int opt_next(void) { char *p; char *endptr; const OPTIONS *o; int dummy; int base; long val; /* Look at current arg; at end of the list? */ arg = NULL; p = argv[opt_index]; if (p == NULL) return 0; /* If word doesn't start with a -, we're done. */ if (*p != '-') return 0; /* Hit "--" ? We're done. */ opt_index++; if (strcmp(p, "--") == 0) return 0; /* Allow -nnn and --nnn */ if (*++p == '-') p++; flag = p - 1; /* If we have --flag=foo, snip it off */ if ((arg = strchr(p, '=')) != NULL) *arg++ = '\0'; for (o = opts; o->name; ++o) { /* If not this option, move on to the next one. */ if (strcmp(p, o->name) != 0) continue; /* If it doesn't take a value, make sure none was given. */ if (o->valtype == 0 || o->valtype == '-') { if (arg) { BIO_printf(bio_err, "%s: Option -%s does not take a value\n", prog, p); return -1; } return o->retval; } /* Want a value; get the next param if =foo not used. */ if (arg == NULL) { if (argv[opt_index] == NULL) { BIO_printf(bio_err, "%s: Option -%s needs a value\n", prog, o->name); return -1; } arg = argv[opt_index++]; } /* Syntax-check value. */ /* * Do some basic syntax-checking on the value. These tests aren't * perfect (ignore range overflow) but they catch common failures. */ switch (o->valtype) { default: case 's': /* Just a string. */ break; case '/': if (app_isdir(arg) >= 0) break; BIO_printf(bio_err, "%s: Not a directory: %s\n", prog, arg); return -1; case '<': /* Input file. */ if (strcmp(arg, "-") == 0 || app_access(arg, R_OK) >= 0) break; BIO_printf(bio_err, "%s: Cannot open input file %s, %s\n", prog, arg, strerror(errno)); return -1; case '>': /* Output file. */ if (strcmp(arg, "-") == 0 || app_access(arg, W_OK) >= 0 || errno == ENOENT) break; BIO_printf(bio_err, "%s: Cannot open output file %s, %s\n", prog, arg, strerror(errno)); return -1; case 'p': case 'n': base = scanforhex(arg); val = strtol(arg, &endptr, base); if (*endptr == '\0') { if (o->valtype == 'p' && val <= 0) { BIO_printf(bio_err, "%s: Non-positive number \"%s\" for -%s\n", prog, arg, o->name); return -1; } break; } BIO_printf(bio_err, "%s: Invalid number \"%s\" for -%s\n", prog, arg, o->name); return -1; case 'u': base = scanforhex(arg); strtoul(arg, &endptr, base); if (*endptr == '\0') break; BIO_printf(bio_err, "%s: Invalid number \"%s\" for -%s\n", prog, arg, o->name); return -1; case 'f': case 'F': if (opt_format(arg, o->valtype == 'F' ? OPT_FMT_PEMDER : OPT_FMT_ANY, &dummy)) break; BIO_printf(bio_err, "%s: Invalid format \"%s\" for -%s\n", prog, arg, o->name); return -1; } /* Return the flag value. */ return o->retval; } if (unknown != NULL) { dunno = p; return unknown->retval; } BIO_printf(bio_err, "%s: Option unknown option -%s\n", prog, p); return -1; }