Home | History | Annotate | Line # | Download | only in apps
      1 /*
      2  * Copyright 2010-2022 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the OpenSSL license (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #if defined( __VMS) && !defined( OPENSSL_NO_DECC_INIT) && \
     11  defined( __DECC) && !defined( __VAX) && (__CRTL_VER >= 70301000)
     12 # define USE_DECC_INIT 1
     13 #endif
     14 
     15 #ifdef USE_DECC_INIT
     16 
     17 /*
     18  * ----------------------------------------------------------------------
     19  * decc_init() On non-VAX systems, uses LIB$INITIALIZE to set a collection
     20  * of C RTL features without using the DECC$* logical name method.
     21  * ----------------------------------------------------------------------
     22  */
     23 
     24 # include <stdio.h>
     25 # include <stdlib.h>
     26 # include <unixlib.h>
     27 
     28 /* Global storage. */
     29 
     30 /* Flag to sense if decc_init() was called. */
     31 
     32 int decc_init_done = -1;
     33 
     34 /* Structure to hold a DECC$* feature name and its desired value. */
     35 
     36 typedef struct {
     37     char *name;
     38     int value;
     39 } decc_feat_t;
     40 
     41 /*
     42  * Array of DECC$* feature names and their desired values. Note:
     43  * DECC$ARGV_PARSE_STYLE is the urgent one.
     44  */
     45 
     46 decc_feat_t decc_feat_array[] = {
     47     /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
     48     {"DECC$ARGV_PARSE_STYLE", 1},
     49 
     50     /* Preserve case for file names on ODS5 disks. */
     51     {"DECC$EFS_CASE_PRESERVE", 1},
     52 
     53     /*
     54      * Enable multiple dots (and most characters) in ODS5 file names, while
     55      * preserving VMS-ness of ";version".
     56      */
     57     {"DECC$EFS_CHARSET", 1},
     58 
     59     /* List terminator. */
     60     {(char *)NULL, 0}
     61 };
     62 
     63 
     64 /* LIB$INITIALIZE initialization function. */
     65 
     66 static void decc_init(void)
     67 {
     68     char *openssl_debug_decc_init;
     69     int verbose = 0;
     70     int feat_index;
     71     int feat_value;
     72     int feat_value_max;
     73     int feat_value_min;
     74     int i;
     75     int sts;
     76 
     77     /* Get debug option. */
     78     openssl_debug_decc_init = getenv("OPENSSL_DEBUG_DECC_INIT");
     79     if (openssl_debug_decc_init != NULL) {
     80         verbose = strtol(openssl_debug_decc_init, NULL, 10);
     81         if (verbose <= 0) {
     82             verbose = 1;
     83         }
     84     }
     85 
     86     /* Set the global flag to indicate that LIB$INITIALIZE worked. */
     87     decc_init_done = 1;
     88 
     89     /* Loop through all items in the decc_feat_array[]. */
     90 
     91     for (i = 0; decc_feat_array[i].name != NULL; i++) {
     92         /* Get the feature index. */
     93         feat_index = decc$feature_get_index(decc_feat_array[i].name);
     94         if (feat_index >= 0) {
     95             /* Valid item.  Collect its properties. */
     96             feat_value = decc$feature_get_value(feat_index, 1);
     97             feat_value_min = decc$feature_get_value(feat_index, 2);
     98             feat_value_max = decc$feature_get_value(feat_index, 3);
     99 
    100             /* Check the validity of our desired value. */
    101             if ((decc_feat_array[i].value >= feat_value_min) &&
    102                 (decc_feat_array[i].value <= feat_value_max)) {
    103                 /* Valid value.  Set it if necessary. */
    104                 if (feat_value != decc_feat_array[i].value) {
    105                     sts = decc$feature_set_value(feat_index,
    106                                                  1, decc_feat_array[i].value);
    107 
    108                     if (verbose > 1) {
    109                         fprintf(stderr, " %s = %d, sts = %d.\n",
    110                                 decc_feat_array[i].name,
    111                                 decc_feat_array[i].value, sts);
    112                     }
    113                 }
    114             } else {
    115                 /* Invalid DECC feature value. */
    116                 fprintf(stderr,
    117                         " INVALID DECC$FEATURE VALUE, %d: %d <= %s <= %d.\n",
    118                         feat_value,
    119                         feat_value_min, decc_feat_array[i].name,
    120                         feat_value_max);
    121             }
    122         } else {
    123             /* Invalid DECC feature name. */
    124             fprintf(stderr,
    125                     " UNKNOWN DECC$FEATURE: %s.\n", decc_feat_array[i].name);
    126         }
    127     }
    128 
    129     if (verbose > 0) {
    130         fprintf(stderr, " DECC_INIT complete.\n");
    131     }
    132 }
    133 
    134 /* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
    135 
    136 # pragma nostandard
    137 
    138 /*
    139  * Establish the LIB$INITIALIZE PSECTs, with proper alignment and other
    140  * attributes.  Note that "nopic" is significant only on VAX.
    141  */
    142 # pragma extern_model save
    143 
    144 # if __INITIAL_POINTER_SIZE == 64
    145 #  define PSECT_ALIGN 3
    146 # else
    147 #  define PSECT_ALIGN 2
    148 # endif
    149 
    150 # pragma extern_model strict_refdef "LIB$INITIALIZ" PSECT_ALIGN, nopic, nowrt
    151 const int spare[8] = { 0 };
    152 
    153 # pragma extern_model strict_refdef "LIB$INITIALIZE" PSECT_ALIGN, nopic, nowrt
    154 void (*const x_decc_init) () = decc_init;
    155 
    156 # pragma extern_model restore
    157 
    158 /* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
    159 
    160 # pragma extern_model save
    161 
    162 int LIB$INITIALIZE(void);
    163 
    164 # pragma extern_model strict_refdef
    165 int dmy_lib$initialize = (int)LIB$INITIALIZE;
    166 
    167 # pragma extern_model restore
    168 
    169 # pragma standard
    170 
    171 #else                           /* def USE_DECC_INIT */
    172 
    173 /* Dummy code to avoid a %CC-W-EMPTYFILE complaint. */
    174 int decc_init_dummy(void);
    175 
    176 #endif                          /* def USE_DECC_INIT */
    177