/*
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include "apps.h"
#include <string.h>
#if !defined(OPENSSL_SYS_MSDOS)
# include OPENSSL_UNISTD
#endif
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <openssl/bio.h>
#include <openssl/x509v3.h>
#define MAX_OPT_HELP_WIDTH 30
const char OPT_HELP_STR[] = "--";
const char OPT_MORE_STR[] = "---";
/* Our state */
static char **argv;
static int argc;
static int opt_index;
static char *arg;
static char *flag;
static char *dunno;
static const OPTIONS *unknown;
static const OPTIONS *opts;
static char prog[40];
/*
* Return the simple name of the program; removing various platform gunk.
*/
#if defined(OPENSSL_SYS_WIN32)
char *opt_progname(const char *argv0)
{
size_t i, n;
const char *p;
char *q;
/* find the last '/', '\' or ':' */
for (p = argv0 + strlen(argv0); --p > argv0;)
if (*p == '/' || *p == '\\' || *p == ':') {
p++;
break;
}
/* Strip off trailing nonsense. */
n = strlen(p);
if (n > 4 &&
(strcmp(&p[n - 4], ".exe") == 0 || strcmp(&p[n - 4], ".EXE") == 0))
n -= 4;
/* Copy over the name, in lowercase. */
if (n > sizeof(prog) - 1)
n = sizeof(prog) - 1;
for (q = prog, i = 0; i < n; i++, p++)
*q++ = tolower((unsigned char)*p);
*q = '\0';
return prog;
}
#elif defined(OPENSSL_SYS_VMS)
char *opt_progname(const char *argv0)
{
const char *p, *q;
/* Find last special character sys:[foo.bar]openssl */
for (p = argv0 + strlen(argv0); --p > argv0;)
if (*p == ':' || *p == ']' || *p == '>') {
p++;
break;
}
q = strrchr(p, '.');
strncpy(prog, p, sizeof(prog) - 1);
prog[sizeof(prog) - 1] = '\0';
if (q != NULL && q - p < sizeof(prog))
prog[q - p] = '\0';
return prog;
}
#else
char *opt_progname(const char *argv0)
{
const char *p;
/* Could use strchr, but this is like the ones above. */
for (p = argv0 + strlen(argv0); --p > argv0;)
if (*p == '/') {
p++;
break;
}
strncpy(prog, p, sizeof(prog) - 1);
prog[sizeof(prog) - 1] = '\0';
return prog;
}
#endif
char *opt_getprog(void)
{
return prog;
}
/* Set up the arg parsing. */
char *opt_init(int ac, char **av, const OPTIONS *o)
{
/* Store state. */
argc = ac;
argv = av;
opt_index = 1;
opts = o;
opt_progname(av[0]);
unknown = NULL;
for (; o->name; ++o) {
#ifndef NDEBUG
const OPTIONS *next;
int duplicated, i;
#endif
if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR)
continue;
#ifndef NDEBUG
i = o->valtype;
/* Make sure options are legit. */
assert(o->name[0] != '-');
assert(o->retval > 0);
switch (i) {
case 0: case '-': case '/': case '<': case '>': case 'E': case 'F':
case