xref: /netbsd-src/crypto/external/bsd/openssl.old/dist/apps/vms_decc_argv.c (revision 4724848cf0da353df257f730694b7882798e5daf)
1*4724848cSchristos /*
2*4724848cSchristos  * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved.
3*4724848cSchristos  *
4*4724848cSchristos  * Licensed under the Apache License 2.0 (the "License").  You may not use
5*4724848cSchristos  * this file except in compliance with the License.  You can obtain a copy
6*4724848cSchristos  * in the file LICENSE in the source distribution or at
7*4724848cSchristos  * https://www.openssl.org/source/license.html
8*4724848cSchristos  */
9*4724848cSchristos 
10*4724848cSchristos #include <stdlib.h>
11*4724848cSchristos #include <openssl/crypto.h>
12*4724848cSchristos #include "apps.h"                /* for app_malloc() and copy_argv() */
13*4724848cSchristos 
14*4724848cSchristos char **newargv = NULL;
15*4724848cSchristos 
cleanup_argv(void)16*4724848cSchristos static void cleanup_argv(void)
17*4724848cSchristos {
18*4724848cSchristos     OPENSSL_free(newargv);
19*4724848cSchristos     newargv = NULL;
20*4724848cSchristos }
21*4724848cSchristos 
copy_argv(int * argc,char * argv[])22*4724848cSchristos char **copy_argv(int *argc, char *argv[])
23*4724848cSchristos {
24*4724848cSchristos     /*-
25*4724848cSchristos      * The note below is for historical purpose.  On VMS now we always
26*4724848cSchristos      * copy argv "safely."
27*4724848cSchristos      *
28*4724848cSchristos      * 2011-03-22 SMS.
29*4724848cSchristos      * If we have 32-bit pointers everywhere, then we're safe, and
30*4724848cSchristos      * we bypass this mess, as on non-VMS systems.
31*4724848cSchristos      * Problem 1: Compaq/HP C before V7.3 always used 32-bit
32*4724848cSchristos      * pointers for argv[].
33*4724848cSchristos      * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers
34*4724848cSchristos      * everywhere else, we always allocate and use a 64-bit
35*4724848cSchristos      * duplicate of argv[].
36*4724848cSchristos      * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed
37*4724848cSchristos      * to NULL-terminate a 64-bit argv[].  (As this was written, the
38*4724848cSchristos      * compiler ECO was available only on IA64.)
39*4724848cSchristos      * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a
40*4724848cSchristos      * 64-bit argv[argc] for NULL, and, if necessary, use a
41*4724848cSchristos      * (properly) NULL-terminated (64-bit) duplicate of argv[].
42*4724848cSchristos      * The same code is used in either case to duplicate argv[].
43*4724848cSchristos      * Some of these decisions could be handled in preprocessing,
44*4724848cSchristos      * but the code tends to get even uglier, and the penalty for
45*4724848cSchristos      * deciding at compile- or run-time is tiny.
46*4724848cSchristos      */
47*4724848cSchristos 
48*4724848cSchristos     int i, count = *argc;
49*4724848cSchristos     char **p = newargv;
50*4724848cSchristos 
51*4724848cSchristos     cleanup_argv();
52*4724848cSchristos 
53*4724848cSchristos     newargv = app_malloc(sizeof(*newargv) * (count + 1), "argv copy");
54*4724848cSchristos     if (newargv == NULL)
55*4724848cSchristos         return NULL;
56*4724848cSchristos 
57*4724848cSchristos     /* Register automatic cleanup on first use */
58*4724848cSchristos     if (p == NULL)
59*4724848cSchristos         OPENSSL_atexit(cleanup_argv);
60*4724848cSchristos 
61*4724848cSchristos     for (i = 0; i < count; i++)
62*4724848cSchristos         newargv[i] = argv[i];
63*4724848cSchristos     newargv[i] = NULL;
64*4724848cSchristos     *argc = i;
65*4724848cSchristos     return newargv;
66*4724848cSchristos }
67