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