* apps/openssl.c: For VMS, take care of copying argv if needed much earlier,
[openssl.git] / apps / openssl.c
index dcfb796176c57c82ca4618d8add12735323ab7b6..950c9c8bf281c9427a23a3669b565f295b1cb389 100644 (file)
@@ -213,7 +213,7 @@ static void lock_dbg_cb(int mode, int type, const char *file, int line)
        }
 
 
-int main(int Argc, char *Argv[])
+int main(int Argc, char *_Argv[])
        {
        ARGS arg;
 #define PROG_NAME_SIZE 39
@@ -227,7 +227,54 @@ int main(int Argc, char *Argv[])
        char **argv,*p;
        LHASH_OF(FUNCTION) *prog=NULL;
        long errline;
+
+#if defined( OPENSSL_SYS_VMS) && !defined( VMS_TRUST_ARGV)
+       /* 2011-03-08 SMS.
+        * "HP C V7.3-009 on OpenVMS Alpha V8.3" with 64-bit
+        * pointers (at least) may not NULL-terminate argv[]
+        * as expected.  If necessary, use a (properly)
+        * NULL-terminated duplicate of argv[].
+        */
+       /* 2011-03-20 RL.
+        * Additionally, when the argument vector is full of
+        * 32-bit pointers and we have a 64-bit pointer size
+        * everywhere else, we need to make a copy of it using
+        * 64-bit pointers.  Hence the odd conditinal.
+        */
+       char **Argv = NULL;
+       int free_Argv = 0;
+
+       if (_Argv[ Argc] != NULL
+# if defined(__INITIAL_POINTER_SIZE)
+               || sizeof(_Argv) < (__INITIAL_POINTER_SIZE / 8)
+# endif
+               )
+               {
+               int i;
+               Argv = OPENSSL_malloc( (Argc+ 1)* sizeof( char *));
+               if (Argv == NULL)
+                       { ret = -1; goto end; }
+               for(i = 0; i < Argc; i++)
+                       Argv[i] = _Argv[i];
+               Argv[ Argc] = NULL;
+               free_Argv = 1;
+               }
+       else
+               {
+               /* 2011-03-20 RL.
+                * If we didn't copy the argument vector, then simply
+                * assign our variable.  This will never happen when
+                * the argument vector pointer size was smaller than
+                * the initial pointer size, so even if the case might
+                * look unsafe, it isn't, it's just there to shut the
+                * compiler up.
+                */
+               Argv = (char **)_Argv;
+               }
+#else
+       char **Argv = _Argv;
+#endif
+
        arg.data=NULL;
        arg.count=0;
 
@@ -272,9 +319,21 @@ int main(int Argc, char *Argv[])
        i=NCONF_load(config,p,&errline);
        if (i == 0)
                {
-               NCONF_free(config);
-               config = NULL;
-               ERR_clear_error();
+               if (ERR_GET_REASON(ERR_peek_last_error())
+                   == CONF_R_NO_SUCH_FILE)
+                       {
+                       BIO_printf(bio_err,
+                                  "WARNING: can't open config file: %s\n",p);
+                       ERR_clear_error();
+                       NCONF_free(config);
+                       config = NULL;
+                       }
+               else
+                       {
+                       ERR_print_errors(bio_err);
+                       NCONF_free(config);
+                       exit(1);
+                       }
                }
 
        prog=prog_init();
@@ -318,7 +377,8 @@ int main(int Argc, char *Argv[])
                        else    prompt="OpenSSL> ";
                        fputs(prompt,stdout);
                        fflush(stdout);
-                       fgets(p,n,stdin);
+                       if (!fgets(p,n,stdin))
+                               goto end;
                        if (p[0] == '\0') goto end;
                        i=strlen(p);
                        if (i <= 1) break;
@@ -360,6 +420,13 @@ end:
                BIO_free(bio_err);
                bio_err=NULL;
                }
+#if defined( OPENSSL_SYS_VMS) && !defined( VMS_TRUST_ARGV)
+       /* Free any duplicate Argv[] storage. */
+       if (free_Argv)
+               {
+               OPENSSL_free(Argv);
+               }
+#endif
        OPENSSL_EXIT(ret);
        }
 
@@ -380,6 +447,21 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
                { ret=0; goto end; }
        f.name=argv[0];
        fp=lh_FUNCTION_retrieve(prog,&f);
+       if (fp == NULL)
+               {
+               if (EVP_get_digestbyname(argv[0]))
+                       {
+                       f.type = FUNC_TYPE_MD;
+                       f.func = dgst_main;
+                       fp = &f;
+                       }
+               else if (EVP_get_cipherbyname(argv[0]))
+                       {
+                       f.type = FUNC_TYPE_CIPHER;
+                       f.func = enc_main;
+                       fp = &f;
+                       }
+               }
        if (fp != NULL)
                {
                ret=fp->func(argc,argv);
@@ -618,7 +700,7 @@ static LHASH_OF(FUNCTION) *prog_init(void)
                return(NULL);
 
        for (f=functions; f->name != NULL; f++)
-               lh_FUNCTION_insert(ret,f);
+               (void)lh_FUNCTION_insert(ret,f);
        return(ret);
        }