/*
- * Copyright 2015-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (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"
+
+/*
+ * This file is also used by the test suite. Do not #include "apps.h".
+ */
+#include "opt.h"
+#include "fmt.h"
+#include "internal/nelem.h"
#include <string.h>
#if !defined(OPENSSL_SYS_MSDOS)
# include OPENSSL_UNISTD
/* Store state. */
argc = ac;
argv = av;
- opt_index = 1;
+ opt_begin();
opts = o;
opt_progname(av[0]);
unknown = NULL;
i = o->valtype;
/* Make sure options are legit. */
- assert(o->name[0] != '-');
- assert(o->retval > 0);
+ OPENSSL_assert(o->name[0] != '-');
+ OPENSSL_assert(o->retval > 0);
switch (i) {
case 0: case '-': case '/': case '<': case '>': case 'E': case 'F':
case 'M': case 'U': case 'f': case 'l': case 'n': case 'p': case 's':
case 'u': case 'c':
break;
default:
- assert(0);
+ OPENSSL_assert(0);
}
/* Make sure there are no duplicates. */
* Some compilers inline strcmp and the assert string is too long.
*/
duplicated = strcmp(o->name, next->name) == 0;
- assert(!duplicated);
+ OPENSSL_assert(!duplicated);
}
#endif
if (o->name[0] == '\0') {
- assert(unknown == NULL);
+ OPENSSL_assert(unknown == NULL);
unknown = o;
- assert(unknown->valtype == 0 || unknown->valtype == '-');
+ OPENSSL_assert(unknown->valtype == 0 || unknown->valtype == '-');
}
}
return prog;
{"smime", OPT_FMT_SMIME},
{"engine", OPT_FMT_ENGINE},
{"msblob", OPT_FMT_MSBLOB},
- {"netscape", OPT_FMT_NETSCAPE},
{"nss", OPT_FMT_NSS},
{"text", OPT_FMT_TEXT},
{"http", OPT_FMT_HTTP},
OPT_PAIR *ap;
if (flags == OPT_FMT_PEMDER) {
- BIO_printf(bio_err, "%s: Bad format \"%s\"; must be pem or der\n",
- prog, s);
+ opt_printf_stderr("%s: Bad format \"%s\"; must be pem or der\n",
+ prog, s);
} else {
- BIO_printf(bio_err, "%s: Bad format \"%s\"; must be one of:\n",
- prog, s);
+ opt_printf_stderr("%s: Bad format \"%s\"; must be one of:\n",
+ prog, s);
for (ap = formats; ap->name; ap++)
if (flags & ap->retval)
- BIO_printf(bio_err, " %s\n", ap->name);
+ opt_printf_stderr(" %s\n", ap->name);
}
return 0;
}
*cipherp = EVP_get_cipherbyname(name);
if (*cipherp != NULL)
return 1;
- BIO_printf(bio_err, "%s: Unrecognized flag %s\n", prog, name);
+ opt_printf_stderr("%s: Unrecognized flag %s\n", prog, name);
return 0;
}
*mdp = EVP_get_digestbyname(name);
if (*mdp != NULL)
return 1;
- BIO_printf(bio_err, "%s: Unrecognized flag %s\n", prog, name);
+ opt_printf_stderr("%s: Unrecognized flag %s\n", prog, name);
return 0;
}
*result = pp->retval;
return 1;
}
- BIO_printf(bio_err, "%s: Value must be one of:\n", prog);
+ opt_printf_stderr("%s: Value must be one of:\n", prog);
for (pp = pairs; pp->name; pp++)
- BIO_printf(bio_err, "\t%s\n", pp->name);
+ opt_printf_stderr("\t%s\n", pp->name);
return 0;
}
return 0;
*result = (int)l;
if (*result != l) {
- BIO_printf(bio_err, "%s: Value \"%s\" outside integer range\n",
- prog, value);
+ opt_printf_stderr("%s: Value \"%s\" outside integer range\n",
+ prog, value);
return 0;
}
return 1;
for (i = 0; i < OSSL_NELEM(b); i++) {
if (strncmp(v, b[i].prefix, strlen(b[i].prefix)) == 0) {
- BIO_printf(bio_err,
- "%s: Can't parse \"%s\" as %s number\n",
- prog, v, b[i].name);
+ opt_printf_stderr("%s: Can't parse \"%s\" as %s number\n",
+ prog, v, b[i].name);
return;
}
}
- BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n", prog, v);
+ opt_printf_stderr("%s: Can't parse \"%s\" as a number\n", prog, v);
return;
}
X509_PURPOSE *xptmp;
const X509_VERIFY_PARAM *vtmp;
- assert(vpm != NULL);
- assert(opt > OPT_V__FIRST);
- assert(opt < OPT_V__LAST);
+ OPENSSL_assert(vpm != NULL);
+ OPENSSL_assert(opt > OPT_V__FIRST);
+ OPENSSL_assert(opt < OPT_V__LAST);
switch ((enum range)opt) {
case OPT_V__FIRST:
case OPT_V_POLICY:
otmp = OBJ_txt2obj(opt_arg(), 0);
if (otmp == NULL) {
- BIO_printf(bio_err, "%s: Invalid Policy %s\n", prog, opt_arg());
+ opt_printf_stderr("%s: Invalid Policy %s\n", prog, opt_arg());
return 0;
}
X509_VERIFY_PARAM_add0_policy(vpm, otmp);
/* purpose name -> purpose index */
i = X509_PURPOSE_get_by_sname(opt_arg());
if (i < 0) {
- BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg());
+ opt_printf_stderr("%s: Invalid purpose %s\n", prog, opt_arg());
return 0;
}
i = X509_PURPOSE_get_id(xptmp);
if (!X509_VERIFY_PARAM_set_purpose(vpm, i)) {
- BIO_printf(bio_err,
- "%s: Internal error setting purpose %s\n",
- prog, opt_arg());
+ opt_printf_stderr("%s: Internal error setting purpose %s\n",
+ prog, opt_arg());
return 0;
}
break;
case OPT_V_VERIFY_NAME:
vtmp = X509_VERIFY_PARAM_lookup(opt_arg());
if (vtmp == NULL) {
- BIO_printf(bio_err, "%s: Invalid verify name %s\n",
- prog, opt_arg());
+ opt_printf_stderr("%s: Invalid verify name %s\n",
+ prog, opt_arg());
return 0;
}
X509_VERIFY_PARAM_set1(vpm, vtmp);
if (!opt_imax(opt_arg(), &t))
return 0;
if (t != (time_t)t) {
- BIO_printf(bio_err, "%s: epoch time out of range %s\n",
- prog, opt_arg());
+ opt_printf_stderr("%s: epoch time out of range %s\n",
+ prog, opt_arg());
return 0;
}
X509_VERIFY_PARAM_set_time(vpm, (time_t)t);
}
+void opt_begin(void)
+{
+ opt_index = 1;
+ arg = NULL;
+ flag = NULL;
+}
+
/*
* Parse the next flag (and value if specified), return 0 if done, -1 on
* error, otherwise the flag's retval.
/* 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);
+ opt_printf_stderr("%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);
+ opt_printf_stderr("%s: Option -%s needs a value\n",
+ prog, o->name);
return -1;
}
arg = argv[opt_index++];
/* Just a string. */
break;
case '/':
- if (app_isdir(arg) >= 0)
+ if (opt_isdir(arg) > 0)
break;
- BIO_printf(bio_err, "%s: Not a directory: %s\n", prog, arg);
+ opt_printf_stderr("%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;
+ break;
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;
+ break;
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);
+ opt_printf_stderr("%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);
+ opt_printf_stderr("%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);
+ opt_printf_stderr("%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);
+ opt_printf_stderr("%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);
+ opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n",
+ prog, arg, o->name);
return -1;
}
break;
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);
+ opt_printf_stderr("%s: Invalid format \"%s\" for -%s\n",
+ prog, arg, o->name);
return -1;
}
dunno = p;
return unknown->retval;
}
- BIO_printf(bio_err, "%s: Option unknown option -%s\n", prog, p);
+ opt_printf_stderr("%s: Option unknown option -%s\n", prog, p);
return -1;
}
i += 1 + strlen(valtype2param(o));
if (i < MAX_OPT_HELP_WIDTH && i > width)
width = i;
- assert(i < (int)sizeof(start));
+ OPENSSL_assert(i < (int)sizeof(start));
}
if (standard_prolog)
- BIO_printf(bio_err, "Usage: %s [options]\nValid options are:\n",
- prog);
+ opt_printf_stderr("Usage: %s [options]\nValid options are:\n", prog);
/* Now let's print. */
for (o = list; o->name; o++) {
help = o->helpstr ? o->helpstr : "(No additional info)";
if (o->name == OPT_HELP_STR) {
- BIO_printf(bio_err, help, prog);
+ opt_printf_stderr(help, prog);
continue;
}
if (o->name == OPT_MORE_STR) {
/* Continuation of previous line; pad and print. */
start[width] = '\0';
- BIO_printf(bio_err, "%s %s\n", start, help);
+ opt_printf_stderr("%s %s\n", start, help);
continue;
}
*p = ' ';
if ((int)(p - start) >= MAX_OPT_HELP_WIDTH) {
*p = '\0';
- BIO_printf(bio_err, "%s\n", start);
+ opt_printf_stderr("%s\n", start);
memset(start, ' ', sizeof(start));
}
start[width] = '\0';
- BIO_printf(bio_err, "%s %s\n", start, help);
+ opt_printf_stderr("%s %s\n", start, help);
}
}
+
+/* opt_isdir section */
+#ifdef _WIN32
+# include <windows.h>
+int opt_isdir(const char *name)
+{
+ DWORD attr;
+# if defined(UNICODE) || defined(_UNICODE)
+ size_t i, len_0 = strlen(name) + 1;
+ WCHAR tempname[MAX_PATH];
+
+ if (len_0 > MAX_PATH)
+ return -1;
+
+# if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+ if (!MultiByteToWideChar(CP_ACP, 0, name, len_0, tempname, MAX_PATH))
+# endif
+ for (i = 0; i < len_0; i++)
+ tempname[i] = (WCHAR)name[i];
+
+ attr = GetFileAttributes(tempname);
+# else
+ attr = GetFileAttributes(name);
+# endif
+ if (attr == INVALID_FILE_ATTRIBUTES)
+ return -1;
+ return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0);
+}
+#else
+# include <sys/stat.h>
+# ifndef S_ISDIR
+# if defined(_S_IFMT) && defined(_S_IFDIR)
+# define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR)
+# else
+# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
+# endif
+# endif
+
+int opt_isdir(const char *name)
+{
+# if defined(S_ISDIR)
+ struct stat st;
+
+ if (stat(name, &st) == 0)
+ return S_ISDIR(st.st_mode);
+ else
+ return -1;
+# else
+ return -1;
+# endif
+}
+#endif