1c7da899bSchristos /*
2*b0d17251Schristos * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
3c7da899bSchristos *
4*b0d17251Schristos * Licensed under the Apache License 2.0 (the "License"). You may not use
5c7da899bSchristos * this file except in compliance with the License. You can obtain a copy
6c7da899bSchristos * in the file LICENSE in the source distribution or at
7c7da899bSchristos * https://www.openssl.org/source/license.html
8c7da899bSchristos */
9c7da899bSchristos
104e3dcb23Sspz #if defined( __VMS) && !defined( OPENSSL_NO_DECC_INIT) && \
114e3dcb23Sspz defined( __DECC) && !defined( __VAX) && (__CRTL_VER >= 70301000)
124e3dcb23Sspz # define USE_DECC_INIT 1
134e3dcb23Sspz #endif
144e3dcb23Sspz
154e3dcb23Sspz #ifdef USE_DECC_INIT
164e3dcb23Sspz
17c7da899bSchristos /*
184e3dcb23Sspz * ----------------------------------------------------------------------
19c7da899bSchristos * decc_init() On non-VAX systems, uses LIB$INITIALIZE to set a collection
20c7da899bSchristos * of C RTL features without using the DECC$* logical name method.
214e3dcb23Sspz * ----------------------------------------------------------------------
224e3dcb23Sspz */
234e3dcb23Sspz
244e3dcb23Sspz # include <stdio.h>
254e3dcb23Sspz # include <stdlib.h>
264e3dcb23Sspz # include <unixlib.h>
274e3dcb23Sspz
284e3dcb23Sspz /* Global storage. */
294e3dcb23Sspz
304e3dcb23Sspz /* Flag to sense if decc_init() was called. */
314e3dcb23Sspz
324e3dcb23Sspz int decc_init_done = -1;
334e3dcb23Sspz
344e3dcb23Sspz /* Structure to hold a DECC$* feature name and its desired value. */
354e3dcb23Sspz
36635165faSspz typedef struct {
374e3dcb23Sspz char *name;
384e3dcb23Sspz int value;
394e3dcb23Sspz } decc_feat_t;
404e3dcb23Sspz
41635165faSspz /*
42635165faSspz * Array of DECC$* feature names and their desired values. Note:
43635165faSspz * DECC$ARGV_PARSE_STYLE is the urgent one.
444e3dcb23Sspz */
454e3dcb23Sspz
46635165faSspz decc_feat_t decc_feat_array[] = {
474e3dcb23Sspz /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
484e3dcb23Sspz {"DECC$ARGV_PARSE_STYLE", 1},
494e3dcb23Sspz
504e3dcb23Sspz /* Preserve case for file names on ODS5 disks. */
514e3dcb23Sspz {"DECC$EFS_CASE_PRESERVE", 1},
524e3dcb23Sspz
53635165faSspz /*
54635165faSspz * Enable multiple dots (and most characters) in ODS5 file names, while
55635165faSspz * preserving VMS-ness of ";version".
564e3dcb23Sspz */
574e3dcb23Sspz {"DECC$EFS_CHARSET", 1},
584e3dcb23Sspz
594e3dcb23Sspz /* List terminator. */
604e3dcb23Sspz {(char *)NULL, 0}
614e3dcb23Sspz };
624e3dcb23Sspz
63c7da899bSchristos
644e3dcb23Sspz /* LIB$INITIALIZE initialization function. */
654e3dcb23Sspz
decc_init(void)664e3dcb23Sspz static void decc_init(void)
674e3dcb23Sspz {
684e3dcb23Sspz char *openssl_debug_decc_init;
694e3dcb23Sspz int verbose = 0;
704e3dcb23Sspz int feat_index;
714e3dcb23Sspz int feat_value;
724e3dcb23Sspz int feat_value_max;
734e3dcb23Sspz int feat_value_min;
744e3dcb23Sspz int i;
754e3dcb23Sspz int sts;
764e3dcb23Sspz
774e3dcb23Sspz /* Get debug option. */
784e3dcb23Sspz openssl_debug_decc_init = getenv("OPENSSL_DEBUG_DECC_INIT");
79635165faSspz if (openssl_debug_decc_init != NULL) {
804e3dcb23Sspz verbose = strtol(openssl_debug_decc_init, NULL, 10);
81635165faSspz if (verbose <= 0) {
824e3dcb23Sspz verbose = 1;
834e3dcb23Sspz }
844e3dcb23Sspz }
854e3dcb23Sspz
864e3dcb23Sspz /* Set the global flag to indicate that LIB$INITIALIZE worked. */
874e3dcb23Sspz decc_init_done = 1;
884e3dcb23Sspz
894e3dcb23Sspz /* Loop through all items in the decc_feat_array[]. */
904e3dcb23Sspz
91635165faSspz for (i = 0; decc_feat_array[i].name != NULL; i++) {
924e3dcb23Sspz /* Get the feature index. */
934e3dcb23Sspz feat_index = decc$feature_get_index(decc_feat_array[i].name);
94635165faSspz if (feat_index >= 0) {
954e3dcb23Sspz /* Valid item. Collect its properties. */
964e3dcb23Sspz feat_value = decc$feature_get_value(feat_index, 1);
974e3dcb23Sspz feat_value_min = decc$feature_get_value(feat_index, 2);
984e3dcb23Sspz feat_value_max = decc$feature_get_value(feat_index, 3);
994e3dcb23Sspz
1004e3dcb23Sspz /* Check the validity of our desired value. */
1014e3dcb23Sspz if ((decc_feat_array[i].value >= feat_value_min) &&
102635165faSspz (decc_feat_array[i].value <= feat_value_max)) {
1034e3dcb23Sspz /* Valid value. Set it if necessary. */
104635165faSspz if (feat_value != decc_feat_array[i].value) {
1054e3dcb23Sspz sts = decc$feature_set_value(feat_index,
106635165faSspz 1, decc_feat_array[i].value);
1074e3dcb23Sspz
108635165faSspz if (verbose > 1) {
1094e3dcb23Sspz fprintf(stderr, " %s = %d, sts = %d.\n",
1104e3dcb23Sspz decc_feat_array[i].name,
111635165faSspz decc_feat_array[i].value, sts);
1124e3dcb23Sspz }
1134e3dcb23Sspz }
114635165faSspz } else {
1154e3dcb23Sspz /* Invalid DECC feature value. */
1164e3dcb23Sspz fprintf(stderr,
1174e3dcb23Sspz " INVALID DECC$FEATURE VALUE, %d: %d <= %s <= %d.\n",
1184e3dcb23Sspz feat_value,
119635165faSspz feat_value_min, decc_feat_array[i].name,
120635165faSspz feat_value_max);
1214e3dcb23Sspz }
122635165faSspz } else {
1234e3dcb23Sspz /* Invalid DECC feature name. */
1244e3dcb23Sspz fprintf(stderr,
1254e3dcb23Sspz " UNKNOWN DECC$FEATURE: %s.\n", decc_feat_array[i].name);
1264e3dcb23Sspz }
1274e3dcb23Sspz }
1284e3dcb23Sspz
129635165faSspz if (verbose > 0) {
1304e3dcb23Sspz fprintf(stderr, " DECC_INIT complete.\n");
1314e3dcb23Sspz }
1324e3dcb23Sspz }
1334e3dcb23Sspz
1344e3dcb23Sspz /* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
1354e3dcb23Sspz
1364e3dcb23Sspz # pragma nostandard
1374e3dcb23Sspz
138635165faSspz /*
139635165faSspz * Establish the LIB$INITIALIZE PSECTs, with proper alignment and other
140635165faSspz * attributes. Note that "nopic" is significant only on VAX.
1414e3dcb23Sspz */
1424e3dcb23Sspz # pragma extern_model save
1434e3dcb23Sspz
1444e3dcb23Sspz # if __INITIAL_POINTER_SIZE == 64
1454e3dcb23Sspz # define PSECT_ALIGN 3
1464e3dcb23Sspz # else
1474e3dcb23Sspz # define PSECT_ALIGN 2
1484e3dcb23Sspz # endif
1494e3dcb23Sspz
1504e3dcb23Sspz # pragma extern_model strict_refdef "LIB$INITIALIZ" PSECT_ALIGN, nopic, nowrt
1514e3dcb23Sspz const int spare[8] = { 0 };
1524e3dcb23Sspz
1534e3dcb23Sspz # pragma extern_model strict_refdef "LIB$INITIALIZE" PSECT_ALIGN, nopic, nowrt
1544e3dcb23Sspz void (*const x_decc_init) () = decc_init;
1554e3dcb23Sspz
1564e3dcb23Sspz # pragma extern_model restore
1574e3dcb23Sspz
1584e3dcb23Sspz /* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
1594e3dcb23Sspz
1604e3dcb23Sspz # pragma extern_model save
1614e3dcb23Sspz
1624e3dcb23Sspz int LIB$INITIALIZE(void);
1634e3dcb23Sspz
1644e3dcb23Sspz # pragma extern_model strict_refdef
1654e3dcb23Sspz int dmy_lib$initialize = (int)LIB$INITIALIZE;
1664e3dcb23Sspz
1674e3dcb23Sspz # pragma extern_model restore
1684e3dcb23Sspz
1694e3dcb23Sspz # pragma standard
1704e3dcb23Sspz
1714e3dcb23Sspz #else /* def USE_DECC_INIT */
1724e3dcb23Sspz
1734e3dcb23Sspz /* Dummy code to avoid a %CC-W-EMPTYFILE complaint. */
1744e3dcb23Sspz int decc_init_dummy(void);
1754e3dcb23Sspz
1764e3dcb23Sspz #endif /* def USE_DECC_INIT */
177