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