Avoid memory leaks if options repeated.
[openssl.git] / apps / opt.c
1 /*
2  * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /* #define COMPILE_STANDALONE_TEST_DRIVER  */
11 #include "apps.h"
12 #include <string.h>
13 #if !defined(OPENSSL_SYS_MSDOS)
14 # include OPENSSL_UNISTD
15 #endif
16
17 #include <stdlib.h>
18 #include <errno.h>
19 #include <ctype.h>
20 #include <limits.h>
21 #include <openssl/bio.h>
22 #include <openssl/x509v3.h>
23
24 #define MAX_OPT_HELP_WIDTH 30
25 const char OPT_HELP_STR[] = "--";
26 const char OPT_MORE_STR[] = "---";
27
28 /* Our state */
29 static char **argv;
30 static int argc;
31 static int opt_index;
32 static char *arg;
33 static char *flag;
34 static char *dunno;
35 static const OPTIONS *unknown;
36 static const OPTIONS *opts;
37 static char prog[40];
38
39 /*
40  * Return the simple name of the program; removing various platform gunk.
41  */
42 #if defined(OPENSSL_SYS_WIN32)
43 char *opt_progname(const char *argv0)
44 {
45     size_t i, n;
46     const char *p;
47     char *q;
48
49     /* find the last '/', '\' or ':' */
50     for (p = argv0 + strlen(argv0); --p > argv0;)
51         if (*p == '/' || *p == '\\' || *p == ':') {
52             p++;
53             break;
54         }
55
56     /* Strip off trailing nonsense. */
57     n = strlen(p);
58     if (n > 4 &&
59         (strcmp(&p[n - 4], ".exe") == 0 || strcmp(&p[n - 4], ".EXE") == 0))
60         n -= 4;
61
62     /* Copy over the name, in lowercase. */
63     if (n > sizeof prog - 1)
64         n = sizeof prog - 1;
65     for (q = prog, i = 0; i < n; i++, p++)
66         *q++ = isupper(*p) ? tolower(*p) : *p;
67     *q = '\0';
68     return prog;
69 }
70
71 #elif defined(OPENSSL_SYS_VMS)
72
73 char *opt_progname(const char *argv0)
74 {
75     const char *p, *q;
76
77     /* Find last special charcter sys:[foo.bar]openssl */
78     for (p = argv0 + strlen(argv0); --p > argv0;)
79         if (*p == ':' || *p == ']' || *p == '>') {
80             p++;
81             break;
82         }
83
84     q = strrchr(p, '.');
85     strncpy(prog, p, sizeof prog - 1);
86     prog[sizeof prog - 1] = '\0';
87     if (q != NULL && q - p < sizeof prog)
88         prog[q - p] = '\0';
89     return prog;
90 }
91
92 #else
93
94 char *opt_progname(const char *argv0)
95 {
96     const char *p;
97
98     /* Could use strchr, but this is like the ones above. */
99     for (p = argv0 + strlen(argv0); --p > argv0;)
100         if (*p == '/') {
101             p++;
102             break;
103         }
104     strncpy(prog, p, sizeof prog - 1);
105     prog[sizeof prog - 1] = '\0';
106     return prog;
107 }
108 #endif
109
110 char *opt_getprog(void)
111 {
112     return prog;
113 }
114
115 /* Set up the arg parsing. */
116 char *opt_init(int ac, char **av, const OPTIONS *o)
117 {
118     /* Store state. */
119     argc = ac;
120     argv = av;
121     opt_index = 1;
122     opts = o;
123     opt_progname(av[0]);
124     unknown = NULL;
125
126     for (; o->name; ++o) {
127 #ifndef NDEBUG
128         const OPTIONS *next;
129         int duplicated, i;
130 #endif
131
132         if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR)
133             continue;
134 #ifndef NDEBUG
135         i = o->valtype;
136
137         /* Make sure options are legit. */
138         assert(o->name[0] != '-');
139         assert(o->retval > 0);
140         switch (i) {
141         case   0: case '-': case '/': case '<': case '>': case 'E': case 'F':
142         case 'M': case 'U': case 'f': case 'l': case 'n': case 'p': case 's':
143         case 'u': case 'c':
144             break;
145         default:
146             assert(0);
147         }
148
149         /* Make sure there are no duplicates. */
150         for (next = o + 1; next->name; ++next) {
151             /*
152              * Some compilers inline strcmp and the assert string is too long.
153              */
154             duplicated = strcmp(o->name, next->name) == 0;
155             assert(!duplicated);
156         }
157 #endif
158         if (o->name[0] == '\0') {
159             assert(unknown == NULL);
160             unknown = o;
161             assert(unknown->valtype == 0 || unknown->valtype == '-');
162         }
163     }
164     return prog;
165 }
166
167 static OPT_PAIR formats[] = {
168     {"PEM/DER", OPT_FMT_PEMDER},
169     {"pkcs12", OPT_FMT_PKCS12},
170     {"smime", OPT_FMT_SMIME},
171     {"engine", OPT_FMT_ENGINE},
172     {"msblob", OPT_FMT_MSBLOB},
173     {"netscape", OPT_FMT_NETSCAPE},
174     {"nss", OPT_FMT_NSS},
175     {"text", OPT_FMT_TEXT},
176     {"http", OPT_FMT_HTTP},
177     {"pvk", OPT_FMT_PVK},
178     {NULL}
179 };
180
181 /* Print an error message about a failed format parse. */
182 int opt_format_error(const char *s, unsigned long flags)
183 {
184     OPT_PAIR *ap;
185
186     if (flags == OPT_FMT_PEMDER)
187         BIO_printf(bio_err, "%s: Bad format \"%s\"; must be pem or der\n",
188                    prog, s);
189     else {
190         BIO_printf(bio_err, "%s: Bad format \"%s\"; must be one of:\n",
191                    prog, s);
192         for (ap = formats; ap->name; ap++)
193             if (flags & ap->retval)
194                 BIO_printf(bio_err, "   %s\n", ap->name);
195     }
196     return 0;
197 }
198
199 /* Parse a format string, put it into *result; return 0 on failure, else 1. */
200 int opt_format(const char *s, unsigned long flags, int *result)
201 {
202     switch (*s) {
203     default:
204         return 0;
205     case 'D':
206     case 'd':
207         if ((flags & OPT_FMT_PEMDER) == 0)
208             return opt_format_error(s, flags);
209         *result = FORMAT_ASN1;
210         break;
211     case 'T':
212     case 't':
213         if ((flags & OPT_FMT_TEXT) == 0)
214             return opt_format_error(s, flags);
215         *result = FORMAT_TEXT;
216         break;
217     case 'N':
218     case 'n':
219         if ((flags & OPT_FMT_NSS) == 0)
220             return opt_format_error(s, flags);
221         if (strcmp(s, "NSS") != 0 && strcmp(s, "nss") != 0)
222             return opt_format_error(s, flags);
223         *result = FORMAT_NSS;
224         break;
225     case 'S':
226     case 's':
227         if ((flags & OPT_FMT_SMIME) == 0)
228             return opt_format_error(s, flags);
229         *result = FORMAT_SMIME;
230         break;
231     case 'M':
232     case 'm':
233         if ((flags & OPT_FMT_MSBLOB) == 0)
234             return opt_format_error(s, flags);
235         *result = FORMAT_MSBLOB;
236         break;
237     case 'E':
238     case 'e':
239         if ((flags & OPT_FMT_ENGINE) == 0)
240             return opt_format_error(s, flags);
241         *result = FORMAT_ENGINE;
242         break;
243     case 'H':
244     case 'h':
245         if ((flags & OPT_FMT_HTTP) == 0)
246             return opt_format_error(s, flags);
247         *result = FORMAT_HTTP;
248         break;
249     case '1':
250         if ((flags & OPT_FMT_PKCS12) == 0)
251             return opt_format_error(s, flags);
252         *result = FORMAT_PKCS12;
253         break;
254     case 'P':
255     case 'p':
256         if (s[1] == '\0' || strcmp(s, "PEM") == 0 || strcmp(s, "pem") == 0) {
257             if ((flags & OPT_FMT_PEMDER) == 0)
258                 return opt_format_error(s, flags);
259             *result = FORMAT_PEM;
260         } else if (strcmp(s, "PVK") == 0 || strcmp(s, "pvk") == 0) {
261             if ((flags & OPT_FMT_PVK) == 0)
262                 return opt_format_error(s, flags);
263             *result = FORMAT_PVK;
264         } else if (strcmp(s, "P12") == 0 || strcmp(s, "p12") == 0
265                    || strcmp(s, "PKCS12") == 0 || strcmp(s, "pkcs12") == 0) {
266             if ((flags & OPT_FMT_PKCS12) == 0)
267                 return opt_format_error(s, flags);
268             *result = FORMAT_PKCS12;
269         } else
270             return 0;
271         break;
272     }
273     return 1;
274 }
275
276 /* Parse a cipher name, put it in *EVP_CIPHER; return 0 on failure, else 1. */
277 int opt_cipher(const char *name, const EVP_CIPHER **cipherp)
278 {
279     *cipherp = EVP_get_cipherbyname(name);
280     if (*cipherp)
281         return 1;
282     BIO_printf(bio_err, "%s: Unknown cipher %s\n", prog, name);
283     return 0;
284 }
285
286 /*
287  * Parse message digest name, put it in *EVP_MD; return 0 on failure, else 1.
288  */
289 int opt_md(const char *name, const EVP_MD **mdp)
290 {
291     *mdp = EVP_get_digestbyname(name);
292     if (*mdp)
293         return 1;
294     BIO_printf(bio_err, "%s: Unknown digest %s\n", prog, name);
295     return 0;
296 }
297
298 /* Look through a list of name/value pairs. */
299 int opt_pair(const char *name, const OPT_PAIR* pairs, int *result)
300 {
301     const OPT_PAIR *pp;
302
303     for (pp = pairs; pp->name; pp++)
304         if (strcmp(pp->name, name) == 0) {
305             *result = pp->retval;
306             return 1;
307         }
308     BIO_printf(bio_err, "%s: Value must be one of:\n", prog);
309     for (pp = pairs; pp->name; pp++)
310         BIO_printf(bio_err, "\t%s\n", pp->name);
311     return 0;
312 }
313
314 /* Parse an int, put it into *result; return 0 on failure, else 1. */
315 int opt_int(const char *value, int *result)
316 {
317     long l;
318
319     if (!opt_long(value, &l))
320         return 0;
321     *result = (int)l;
322     if (*result != l) {
323         BIO_printf(bio_err, "%s: Value \"%s\" outside integer range\n",
324                    prog, value);
325         return 0;
326     }
327     return 1;
328 }
329
330 /* Parse a long, put it into *result; return 0 on failure, else 1. */
331 int opt_long(const char *value, long *result)
332 {
333     int oerrno = errno;
334     long l;
335     char *endp;
336
337     errno = 0;
338     l = strtol(value, &endp, 0);
339     if (*endp
340             || endp == value
341             || ((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE)
342             || (l == 0 && errno != 0)) {
343         BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n",
344                    prog, value);
345         errno = oerrno;
346         return 0;
347     }
348     *result = l;
349     errno = oerrno;
350     return 1;
351 }
352
353 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \
354     defined(INTMAX_MAX) && defined(UINTMAX_MAX)
355
356 /* Parse an intmax_t, put it into *result; return 0 on failure, else 1. */
357 int opt_imax(const char *value, intmax_t *result)
358 {
359     int oerrno = errno;
360     intmax_t m;
361     char *endp;
362
363     errno = 0;
364     m = strtoimax(value, &endp, 0);
365     if (*endp
366             || endp == value
367             || ((m == INTMAX_MAX || m == INTMAX_MIN) && errno == ERANGE)
368             || (m == 0 && errno != 0)) {
369         BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n",
370                    prog, value);
371         errno = oerrno;
372         return 0;
373     }
374     *result = m;
375     errno = oerrno;
376     return 1;
377 }
378
379 /* Parse a uintmax_t, put it into *result; return 0 on failure, else 1. */
380 int opt_umax(const char *value, uintmax_t *result)
381 {
382     int oerrno = errno;
383     uintmax_t m;
384     char *endp;
385
386     errno = 0;
387     m = strtoumax(value, &endp, 0);
388     if (*endp
389             || endp == value
390             || (m == UINTMAX_MAX && errno == ERANGE)
391             || (m == 0 && errno != 0)) {
392         BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n",
393                    prog, value);
394         errno = oerrno;
395         return 0;
396     }
397     *result = m;
398     errno = oerrno;
399     return 1;
400 }
401 #endif
402
403 /*
404  * Parse an unsigned long, put it into *result; return 0 on failure, else 1.
405  */
406 int opt_ulong(const char *value, unsigned long *result)
407 {
408     int oerrno = errno;
409     char *endptr;
410     unsigned long l;
411
412     errno = 0;
413     l = strtoul(value, &endptr, 0);
414     if (*endptr
415             || endptr == value
416             || ((l == ULONG_MAX) && errno == ERANGE)
417             || (l == 0 && errno != 0)) {
418         BIO_printf(bio_err, "%s: Can't parse \"%s\" as an unsigned number\n",
419                    prog, value);
420         errno = oerrno;
421         return 0;
422     }
423     *result = l;
424     errno = oerrno;
425     return 1;
426 }
427
428 /*
429  * We pass opt as an int but cast it to "enum range" so that all the
430  * items in the OPT_V_ENUM enumeration are caught; this makes -Wswitch
431  * in gcc do the right thing.
432  */
433 enum range { OPT_V_ENUM };
434
435 int opt_verify(int opt, X509_VERIFY_PARAM *vpm)
436 {
437     int i;
438     ossl_intmax_t t = 0;
439     ASN1_OBJECT *otmp;
440     X509_PURPOSE *xptmp;
441     const X509_VERIFY_PARAM *vtmp;
442
443     assert(vpm != NULL);
444     assert(opt > OPT_V__FIRST);
445     assert(opt < OPT_V__LAST);
446
447     switch ((enum range)opt) {
448     case OPT_V__FIRST:
449     case OPT_V__LAST:
450         return 0;
451     case OPT_V_POLICY:
452         otmp = OBJ_txt2obj(opt_arg(), 0);
453         if (otmp == NULL) {
454             BIO_printf(bio_err, "%s: Invalid Policy %s\n", prog, opt_arg());
455             return 0;
456         }
457         X509_VERIFY_PARAM_add0_policy(vpm, otmp);
458         break;
459     case OPT_V_PURPOSE:
460         /* purpose name -> purpose index */
461         i = X509_PURPOSE_get_by_sname(opt_arg());
462         if (i < 0) {
463             BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg());
464             return 0;
465         }
466
467         /* purpose index -> purpose object */
468         xptmp = X509_PURPOSE_get0(i);
469
470         /* purpose object -> purpose value */
471         i = X509_PURPOSE_get_id(xptmp);
472
473         if (!X509_VERIFY_PARAM_set_purpose(vpm, i)) {
474             BIO_printf(bio_err,
475                        "%s: Internal error setting purpose %s\n",
476                        prog, opt_arg());
477             return 0;
478         }
479         break;
480     case OPT_V_VERIFY_NAME:
481         vtmp = X509_VERIFY_PARAM_lookup(opt_arg());
482         if (vtmp == NULL) {
483             BIO_printf(bio_err, "%s: Invalid verify name %s\n",
484                        prog, opt_arg());
485             return 0;
486         }
487         X509_VERIFY_PARAM_set1(vpm, vtmp);
488         break;
489     case OPT_V_VERIFY_DEPTH:
490         i = atoi(opt_arg());
491         if (i >= 0)
492             X509_VERIFY_PARAM_set_depth(vpm, i);
493         break;
494     case OPT_V_VERIFY_AUTH_LEVEL:
495         i = atoi(opt_arg());
496         if (i >= 0)
497             X509_VERIFY_PARAM_set_auth_level(vpm, i);
498         break;
499     case OPT_V_ATTIME:
500         if (!opt_imax(opt_arg(), &t))
501             return 0;
502         if (t != (time_t)t) {
503             BIO_printf(bio_err, "%s: epoch time out of range %s\n",
504                        prog, opt_arg());
505             return 0;
506         }
507         X509_VERIFY_PARAM_set_time(vpm, (time_t)t);
508         break;
509     case OPT_V_VERIFY_HOSTNAME:
510         if (!X509_VERIFY_PARAM_set1_host(vpm, opt_arg(), 0))
511             return 0;
512         break;
513     case OPT_V_VERIFY_EMAIL:
514         if (!X509_VERIFY_PARAM_set1_email(vpm, opt_arg(), 0))
515             return 0;
516         break;
517     case OPT_V_VERIFY_IP:
518         if (!X509_VERIFY_PARAM_set1_ip_asc(vpm, opt_arg()))
519             return 0;
520         break;
521     case OPT_V_IGNORE_CRITICAL:
522         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_IGNORE_CRITICAL);
523         break;
524     case OPT_V_ISSUER_CHECKS:
525         /* NOP, deprecated */
526         break;
527     case OPT_V_CRL_CHECK:
528         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK);
529         break;
530     case OPT_V_CRL_CHECK_ALL:
531         X509_VERIFY_PARAM_set_flags(vpm,
532                                     X509_V_FLAG_CRL_CHECK |
533                                     X509_V_FLAG_CRL_CHECK_ALL);
534         break;
535     case OPT_V_POLICY_CHECK:
536         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_POLICY_CHECK);
537         break;
538     case OPT_V_EXPLICIT_POLICY:
539         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXPLICIT_POLICY);
540         break;
541     case OPT_V_INHIBIT_ANY:
542         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_ANY);
543         break;
544     case OPT_V_INHIBIT_MAP:
545         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_MAP);
546         break;
547     case OPT_V_X509_STRICT:
548         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_X509_STRICT);
549         break;
550     case OPT_V_EXTENDED_CRL:
551         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXTENDED_CRL_SUPPORT);
552         break;
553     case OPT_V_USE_DELTAS:
554         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_USE_DELTAS);
555         break;
556     case OPT_V_POLICY_PRINT:
557         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NOTIFY_POLICY);
558         break;
559     case OPT_V_CHECK_SS_SIG:
560         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CHECK_SS_SIGNATURE);
561         break;
562     case OPT_V_TRUSTED_FIRST:
563         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_TRUSTED_FIRST);
564         break;
565     case OPT_V_SUITEB_128_ONLY:
566         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS_ONLY);
567         break;
568     case OPT_V_SUITEB_128:
569         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS);
570         break;
571     case OPT_V_SUITEB_192:
572         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_192_LOS);
573         break;
574     case OPT_V_PARTIAL_CHAIN:
575         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN);
576         break;
577     case OPT_V_NO_ALT_CHAINS:
578         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_ALT_CHAINS);
579         break;
580     case OPT_V_NO_CHECK_TIME:
581         X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_CHECK_TIME);
582         break;
583     }
584     return 1;
585
586 }
587
588 /*
589  * Parse the next flag (and value if specified), return 0 if done, -1 on
590  * error, otherwise the flag's retval.
591  */
592 int opt_next(void)
593 {
594     char *p;
595     const OPTIONS *o;
596     int ival;
597     long lval;
598     unsigned long ulval;
599     ossl_intmax_t imval;
600     ossl_uintmax_t umval;
601
602     /* Look at current arg; at end of the list? */
603     arg = NULL;
604     p = argv[opt_index];
605     if (p == NULL)
606         return 0;
607
608     /* If word doesn't start with a -, we're done. */
609     if (*p != '-')
610         return 0;
611
612     /* Hit "--" ? We're done. */
613     opt_index++;
614     if (strcmp(p, "--") == 0)
615         return 0;
616
617     /* Allow -nnn and --nnn */
618     if (*++p == '-')
619         p++;
620     flag = p - 1;
621
622     /* If we have --flag=foo, snip it off */
623     if ((arg = strchr(p, '=')) != NULL)
624         *arg++ = '\0';
625     for (o = opts; o->name; ++o) {
626         /* If not this option, move on to the next one. */
627         if (strcmp(p, o->name) != 0)
628             continue;
629
630         /* If it doesn't take a value, make sure none was given. */
631         if (o->valtype == 0 || o->valtype == '-') {
632             if (arg) {
633                 BIO_printf(bio_err,
634                            "%s: Option -%s does not take a value\n", prog, p);
635                 return -1;
636             }
637             return o->retval;
638         }
639
640         /* Want a value; get the next param if =foo not used. */
641         if (arg == NULL) {
642             if (argv[opt_index] == NULL) {
643                 BIO_printf(bio_err,
644                            "%s: Option -%s needs a value\n", prog, o->name);
645                 return -1;
646             }
647             arg = argv[opt_index++];
648         }
649
650         /* Syntax-check value. */
651         switch (o->valtype) {
652         default:
653         case 's':
654             /* Just a string. */
655             break;
656         case '/':
657             if (app_isdir(arg) >= 0)
658                 break;
659             BIO_printf(bio_err, "%s: Not a directory: %s\n", prog, arg);
660             return -1;
661         case '<':
662             /* Input file. */
663             if (strcmp(arg, "-") == 0 || app_access(arg, R_OK) >= 0)
664                 break;
665             BIO_printf(bio_err,
666                        "%s: Cannot open input file %s, %s\n",
667                        prog, arg, strerror(errno));
668             return -1;
669         case '>':
670             /* Output file. */
671             if (strcmp(arg, "-") == 0 || app_access(arg, W_OK) >= 0 || errno == ENOENT)
672                 break;
673             BIO_printf(bio_err,
674                        "%s: Cannot open output file %s, %s\n",
675                        prog, arg, strerror(errno));
676             return -1;
677         case 'p':
678         case 'n':
679             if (!opt_int(arg, &ival)
680                     || (o->valtype == 'p' && ival <= 0)) {
681                 BIO_printf(bio_err,
682                            "%s: Non-positive number \"%s\" for -%s\n",
683                            prog, arg, o->name);
684                 return -1;
685             }
686             break;
687         case 'M':
688             if (!opt_imax(arg, &imval)) {
689                 BIO_printf(bio_err,
690                            "%s: Invalid number \"%s\" for -%s\n",
691                            prog, arg, o->name);
692                 return -1;
693             }
694             break;
695         case 'U':
696             if (!opt_umax(arg, &umval)) {
697                 BIO_printf(bio_err,
698                            "%s: Invalid number \"%s\" for -%s\n",
699                            prog, arg, o->name);
700                 return -1;
701             }
702             break;
703         case 'l':
704             if (!opt_long(arg, &lval)) {
705                 BIO_printf(bio_err,
706                            "%s: Invalid number \"%s\" for -%s\n",
707                            prog, arg, o->name);
708                 return -1;
709             }
710             break;
711         case 'u':
712             if (!opt_ulong(arg, &ulval)) {
713                 BIO_printf(bio_err,
714                            "%s: Invalid number \"%s\" for -%s\n",
715                            prog, arg, o->name);
716                 return -1;
717             }
718             break;
719         case 'c':
720         case 'E':
721         case 'F':
722         case 'f':
723             if (opt_format(arg,
724                            o->valtype == 'c' ? OPT_FMT_PDS :
725                            o->valtype == 'E' ? OPT_FMT_PDE :
726                            o->valtype == 'F' ? OPT_FMT_PEMDER
727                            : OPT_FMT_ANY, &ival))
728                 break;
729             BIO_printf(bio_err,
730                        "%s: Invalid format \"%s\" for -%s\n",
731                        prog, arg, o->name);
732             return -1;
733         }
734
735         /* Return the flag value. */
736         return o->retval;
737     }
738     if (unknown != NULL) {
739         dunno = p;
740         return unknown->retval;
741     }
742     BIO_printf(bio_err, "%s: Option unknown option -%s\n", prog, p);
743     return -1;
744 }
745
746 /* Return the most recent flag parameter. */
747 char *opt_arg(void)
748 {
749     return arg;
750 }
751
752 /* Return the most recent flag. */
753 char *opt_flag(void)
754 {
755     return flag;
756 }
757
758 /* Return the unknown option. */
759 char *opt_unknown(void)
760 {
761     return dunno;
762 }
763
764 /* Return the rest of the arguments after parsing flags. */
765 char **opt_rest(void)
766 {
767     return &argv[opt_index];
768 }
769
770 /* How many items in remaining args? */
771 int opt_num_rest(void)
772 {
773     int i = 0;
774     char **pp;
775
776     for (pp = opt_rest(); *pp; pp++, i++)
777         continue;
778     return i;
779 }
780
781 /* Return a string describing the parameter type. */
782 static const char *valtype2param(const OPTIONS *o)
783 {
784     switch (o->valtype) {
785     case 0:
786     case '-':
787         return "";
788     case 's':
789         return "val";
790     case '/':
791         return "dir";
792     case '<':
793         return "infile";
794     case '>':
795         return "outfile";
796     case 'p':
797         return "+int";
798     case 'n':
799         return "int";
800     case 'l':
801         return "long";
802     case 'u':
803         return "ulong";
804     case 'E':
805         return "PEM|DER|ENGINE";
806     case 'F':
807         return "PEM|DER";
808     case 'f':
809         return "format";
810     case 'M':
811         return "intmax";
812     case 'U':
813         return "uintmax";
814     }
815     return "parm";
816 }
817
818 void opt_help(const OPTIONS *list)
819 {
820     const OPTIONS *o;
821     int i;
822     int standard_prolog;
823     int width = 5;
824     char start[80 + 1];
825     char *p;
826     const char *help;
827
828     /* Starts with its own help message? */
829     standard_prolog = list[0].name != OPT_HELP_STR;
830
831     /* Find the widest help. */
832     for (o = list; o->name; o++) {
833         if (o->name == OPT_MORE_STR)
834             continue;
835         i = 2 + (int)strlen(o->name);
836         if (o->valtype != '-')
837             i += 1 + strlen(valtype2param(o));
838         if (i < MAX_OPT_HELP_WIDTH && i > width)
839             width = i;
840         assert(i < (int)sizeof start);
841     }
842
843     if (standard_prolog)
844         BIO_printf(bio_err, "Usage: %s [options]\nValid options are:\n",
845                    prog);
846
847     /* Now let's print. */
848     for (o = list; o->name; o++) {
849         help = o->helpstr ? o->helpstr : "(No additional info)";
850         if (o->name == OPT_HELP_STR) {
851             BIO_printf(bio_err, help, prog);
852             continue;
853         }
854
855         /* Pad out prefix */
856         memset(start, ' ', sizeof(start) - 1);
857         start[sizeof start - 1] = '\0';
858
859         if (o->name == OPT_MORE_STR) {
860             /* Continuation of previous line; padd and print. */
861             start[width] = '\0';
862             BIO_printf(bio_err, "%s  %s\n", start, help);
863             continue;
864         }
865
866         /* Build up the "-flag [param]" part. */
867         p = start;
868         *p++ = ' ';
869         *p++ = '-';
870         if (o->name[0])
871             p += strlen(strcpy(p, o->name));
872         else
873             *p++ = '*';
874         if (o->valtype != '-') {
875             *p++ = ' ';
876             p += strlen(strcpy(p, valtype2param(o)));
877         }
878         *p = ' ';
879         if ((int)(p - start) >= MAX_OPT_HELP_WIDTH) {
880             *p = '\0';
881             BIO_printf(bio_err, "%s\n", start);
882             memset(start, ' ', sizeof(start));
883         }
884         start[width] = '\0';
885         BIO_printf(bio_err, "%s  %s\n", start, help);
886     }
887 }
888
889 #ifdef COMPILE_STANDALONE_TEST_DRIVER
890 # include <sys/stat.h>
891
892 typedef enum OPTION_choice {
893     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
894     OPT_IN, OPT_INFORM, OPT_OUT, OPT_COUNT, OPT_U, OPT_FLAG,
895     OPT_STR, OPT_NOTUSED
896 } OPTION_CHOICE;
897
898 static OPTIONS options[] = {
899     {OPT_HELP_STR, 1, '-', "Usage: %s flags\n"},
900     {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
901     {"help", OPT_HELP, '-', "Display this summary"},
902     {"in", OPT_IN, '<', "input file"},
903     {OPT_MORE_STR, 1, '-', "more detail about input"},
904     {"inform", OPT_INFORM, 'f', "input file format; defaults to pem"},
905     {"out", OPT_OUT, '>', "output file"},
906     {"count", OPT_COUNT, 'p', "a counter greater than zero"},
907     {"u", OPT_U, 'u', "an unsigned number"},
908     {"flag", OPT_FLAG, 0, "just some flag"},
909     {"str", OPT_STR, 's', "the magic word"},
910     {"areallyverylongoption", OPT_HELP, '-', "long way for help"},
911     {NULL}
912 };
913
914 BIO *bio_err;
915
916 int app_isdir(const char *name)
917 {
918     struct stat sb;
919
920     return name != NULL && stat(name, &sb) >= 0 && S_ISDIR(sb.st_mode);
921 }
922
923 int main(int ac, char **av)
924 {
925     OPTION_CHOICE o;
926     char **rest;
927     char *prog;
928
929     bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
930
931     prog = opt_init(ac, av, options);
932     while ((o = opt_next()) != OPT_EOF) {
933         switch (c) {
934         case OPT_NOTUSED:
935         case OPT_EOF:
936         case OPT_ERR:
937             printf("%s: Usage error; try -help.\n", prog);
938             return 1;
939         case OPT_HELP:
940             opt_help(options);
941             return 0;
942         case OPT_IN:
943             printf("in %s\n", opt_arg());
944             break;
945         case OPT_INFORM:
946             printf("inform %s\n", opt_arg());
947             break;
948         case OPT_OUT:
949             printf("out %s\n", opt_arg());
950             break;
951         case OPT_COUNT:
952             printf("count %s\n", opt_arg());
953             break;
954         case OPT_U:
955             printf("u %s\n", opt_arg());
956             break;
957         case OPT_FLAG:
958             printf("flag\n");
959             break;
960         case OPT_STR:
961             printf("str %s\n", opt_arg());
962             break;
963         }
964     }
965     argc = opt_num_rest();
966     argv = opt_rest();
967
968     printf("args = %d\n", argc);
969     if (argc)
970         while (*argv)
971             printf("  %s\n", *argv++);
972     return 0;
973 }
974 #endif