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