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) && \ 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