aboutsummaryrefslogtreecommitdiff
path: root/openssl/apps/openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/apps/openssl.c')
-rw-r--r--openssl/apps/openssl.c64
1 files changed, 62 insertions, 2 deletions
diff --git a/openssl/apps/openssl.c b/openssl/apps/openssl.c
index 851e63973..dab057bbf 100644
--- a/openssl/apps/openssl.c
+++ b/openssl/apps/openssl.c
@@ -212,8 +212,13 @@ static void lock_dbg_cb(int mode, int type, const char *file, int line)
}
}
+#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
+# define ARGV _Argv
+#else
+# define ARGV Argv
+#endif
-int main(int Argc, char *Argv[])
+int main(int Argc, char *ARGV[])
{
ARGS arg;
#define PROG_NAME_SIZE 39
@@ -227,7 +232,55 @@ int main(int Argc, char *Argv[])
char **argv,*p;
LHASH_OF(FUNCTION) *prog=NULL;
long errline;
-
+
+#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
+ /* 2011-03-22 SMS.
+ * If we have 32-bit pointers everywhere, then we're safe, and
+ * we bypass this mess, as on non-VMS systems. (See ARGV,
+ * above.)
+ * Problem 1: Compaq/HP C before V7.3 always used 32-bit
+ * pointers for argv[].
+ * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers
+ * everywhere else, we always allocate and use a 64-bit
+ * duplicate of argv[].
+ * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed
+ * to NULL-terminate a 64-bit argv[]. (As this was written, the
+ * compiler ECO was available only on IA64.)
+ * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a
+ * 64-bit argv[argc] for NULL, and, if necessary, use a
+ * (properly) NULL-terminated (64-bit) duplicate of argv[].
+ * The same code is used in either case to duplicate argv[].
+ * Some of these decisions could be handled in preprocessing,
+ * but the code tends to get even uglier, and the penalty for
+ * deciding at compile- or run-time is tiny.
+ */
+ char **Argv = NULL;
+ int free_Argv = 0;
+
+ if ((sizeof( _Argv) < 8) /* 32-bit argv[]. */
+# if !defined( VMS_TRUST_ARGV)
+ || (_Argv[ Argc] != NULL) /* Untrusted argv[argc] not NULL. */
+# 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; /* Certain NULL termination. */
+ free_Argv = 1;
+ }
+ else
+ {
+ /* Use the known-good 32-bit argv[] (which needs the
+ * type cast to satisfy the compiler), or the trusted or
+ * tested-good 64-bit argv[] as-is. */
+ Argv = (char **)_Argv;
+ }
+#endif /* defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) */
+
arg.data=NULL;
arg.count=0;
@@ -373,6 +426,13 @@ end:
BIO_free(bio_err);
bio_err=NULL;
}
+#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64)
+ /* Free any duplicate Argv[] storage. */
+ if (free_Argv)
+ {
+ OPENSSL_free(Argv);
+ }
+#endif
OPENSSL_EXIT(ret);
}