Big apps cleanup (option-parsing, etc)

This is merges the old "rsalz-monolith" branch over to master.  The biggest
change is that option parsing switch from cascasding 'else if strcmp("-foo")'
to a utility routine and somethin akin to getopt.  Also, an error in the
command line no longer prints the full summary; use -help (or --help :)
for that.  There have been many other changes and code-cleanup, see
bullet list below.

Special thanks to Matt for the long and detailed code review.

TEMPORARY:
        For now, comment out CRYPTO_mem_leaks() at end of main

Tickets closed:
        RT3515: Use 3DES in pkcs12 if built with no-rc2
        RT1766: s_client -reconnect and -starttls broke
        RT2932: Catch write errors
        RT2604: port should be 'unsigned short'
        RT2983: total_bytes undeclared #ifdef RENEG
        RT1523: Add -nocert to fix output in x509 app
        RT3508: Remove unused variable introduced by b09eb24
        RT3511: doc fix; req default serial is random
        RT1325,2973: Add more extensions to c_rehash
        RT2119,3407: Updated to dgst.pod
        RT2379: Additional typo fix
        RT2693: Extra include of string.h
        RT2880: HFS is case-insensitive filenames
        RT3246: req command prints version number wrong

Other changes; incompatibilities marked with *:
        Add SCSV support
        Add -misalign to speed command
        Make dhparam, dsaparam, ecparam, x509 output C in proper style
        Make some internal ocsp.c functions void
        Only display cert usages with -help in verify
        Use global bio_err, remove "BIO*err" parameter from functions
        For filenames, - always means stdin (or stdout as appropriate)
        Add aliases for -des/aes "wrap" ciphers.
        *Remove support for IISSGC (server gated crypto)
        *The undocumented OCSP -header flag is now "-header name=value"
        *Documented the OCSP -header flag

Reviewed-by: Matt Caswell <matt@openssl.org>
diff --git a/apps/errstr.c b/apps/errstr.c
index 668c5f3..960815d 100644
--- a/apps/errstr.c
+++ b/apps/errstr.c
@@ -1,4 +1,3 @@
-/* apps/errstr.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -65,56 +64,60 @@
 #include <openssl/err.h>
 #include <openssl/ssl.h>
 
-#undef PROG
-#define PROG    errstr_main
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_STATS
+} OPTION_CHOICE;
 
-int MAIN(int, char **);
+OPTIONS errstr_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] errnum...\n"},
+    {OPT_HELP_STR, 1, '-', "  errnum  Error number\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"stats", OPT_STATS, '-',
+     "Print internal hashtable statistics (long!)"},
+    {NULL}
+};
 
-int MAIN(int argc, char **argv)
+int errstr_main(int argc, char **argv)
 {
-    int i, ret = 0;
-    char buf[256];
+    OPTION_CHOICE o;
+    char buf[256], *prog;
+    int ret = 1;
     unsigned long l;
 
-    apps_startup();
-
-    if (bio_err == NULL)
-        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
-            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
-
-    SSL_load_error_strings();
-
-    if ((argc > 1) && (strcmp(argv[1], "-stats") == 0)) {
-        BIO *out = NULL;
-
-        out = BIO_new(BIO_s_file());
-        if ((out != NULL) && BIO_set_fp(out, stdout, BIO_NOCLOSE)) {
-#ifdef OPENSSL_SYS_VMS
-            {
-                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
-                out = BIO_push(tmpbio, out);
-            }
-#endif
-            lh_ERR_STRING_DATA_node_stats_bio(ERR_get_string_table(), out);
-            lh_ERR_STRING_DATA_stats_bio(ERR_get_string_table(), out);
+    prog = opt_init(argc, argv, errstr_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(errstr_options);
+            ret = 0;
+            goto end;
+        case OPT_STATS:
+            lh_ERR_STRING_DATA_node_stats_bio(ERR_get_string_table(),
+                                              bio_out);
+            lh_ERR_STRING_DATA_stats_bio(ERR_get_string_table(), bio_out);
             lh_ERR_STRING_DATA_node_usage_stats_bio(ERR_get_string_table(),
-                                                    out);
+                                                    bio_out);
+            ret = 0;
+            goto end;
         }
-        BIO_free_all(out);
-        argc--;
-        argv++;
     }
+    argc = opt_num_rest();
+    argv = opt_rest();
 
-    for (i = 1; i < argc; i++) {
-        if (sscanf(argv[i], "%lx", &l)) {
-            ERR_error_string_n(l, buf, sizeof buf);
-            printf("%s\n", buf);
-        } else {
-            printf("%s: bad error code\n", argv[i]);
-            printf("usage: errstr [-stats] <errno> ...\n");
+    ret = 0;
+    for (argv = opt_rest(); *argv; argv++) {
+        if (!opt_ulong(*argv, &l))
             ret++;
+        else {
+            ERR_error_string_n(l, buf, sizeof buf);
+            BIO_printf(bio_out, "%s\n", buf);
         }
     }
-    apps_shutdown();
-    OPENSSL_EXIT(ret);
+ end:
+    return (ret);
 }