vms_decc_init.c 4.77 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
#if defined( __VMS) && !defined( OPENSSL_NO_DECC_INIT) && \
 defined( __DECC) && !defined( __VAX) && (__CRTL_VER >= 70301000)
# define USE_DECC_INIT 1
#endif

#ifdef USE_DECC_INIT

/*
 * 2010-04-26 SMS.
 *
 *----------------------------------------------------------------------
 *
 *       decc_init()
 *
 *    On non-VAX systems, uses LIB$INITIALIZE to set a collection of C
 *    RTL features without using the DECC$* logical name method.
 *
 *----------------------------------------------------------------------
 */

#include <stdio.h>
#include <stdlib.h>
#include <unixlib.h>


/* Global storage. */

/* Flag to sense if decc_init() was called. */

int decc_init_done = -1;


/* Structure to hold a DECC$* feature name and its desired value. */

typedef struct
{
    char *name;
    int value;
} decc_feat_t;


/* Array of DECC$* feature names and their desired values.
 * Note: DECC$ARGV_PARSE_STYLE is the urgent one.
 */

decc_feat_t decc_feat_array[] =
{
 /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
 { "DECC$ARGV_PARSE_STYLE", 1 },

 /* Preserve case for file names on ODS5 disks. */
 { "DECC$EFS_CASE_PRESERVE", 1 },

 /* Enable multiple dots (and most characters) in ODS5 file names,
  * while preserving VMS-ness of ";version".
  */
 { "DECC$EFS_CHARSET", 1 },

 /* List terminator. */
 { (char *)NULL, 0 }
};


/* LIB$INITIALIZE initialization function. */

static void decc_init( void)
{
    char *openssl_debug_decc_init;
    int verbose = 0;
    int feat_index;
    int feat_value;
    int feat_value_max;
    int feat_value_min;
    int i;
    int sts;

    /* Get debug option. */
    openssl_debug_decc_init = getenv( "OPENSSL_DEBUG_DECC_INIT");
    if (openssl_debug_decc_init != NULL)
    {
        verbose = strtol( openssl_debug_decc_init, NULL, 10);
        if (verbose <= 0)
        {
            verbose = 1;
        }
    }

    /* Set the global flag to indicate that LIB$INITIALIZE worked. */
    decc_init_done = 1;

    /* Loop through all items in the decc_feat_array[]. */

    for (i = 0; decc_feat_array[ i].name != NULL; i++)
    {
        /* Get the feature index. */
        feat_index = decc$feature_get_index( decc_feat_array[ i].name);
        if (feat_index >= 0)
        {
            /* Valid item.  Collect its properties. */
            feat_value = decc$feature_get_value( feat_index, 1);
            feat_value_min = decc$feature_get_value( feat_index, 2);
            feat_value_max = decc$feature_get_value( feat_index, 3);

            /* Check the validity of our desired value. */
            if ((decc_feat_array[ i].value >= feat_value_min) &&
             (decc_feat_array[ i].value <= feat_value_max))
            {
                /* Valid value.  Set it if necessary. */
                if (feat_value != decc_feat_array[ i].value)
                {
                    sts = decc$feature_set_value( feat_index,
                     1,
                     decc_feat_array[ i].value);

                     if (verbose > 1)
                     {
                         fprintf( stderr, " %s = %d, sts = %d.\n",
                          decc_feat_array[ i].name,
                          decc_feat_array[ i].value,
                          sts);
                     }
                }
            }
            else
            {
                /* Invalid DECC feature value. */
                fprintf( stderr,
                 " INVALID DECC$FEATURE VALUE, %d: %d <= %s <= %d.\n",
                 feat_value,
                 feat_value_min, decc_feat_array[ i].name, feat_value_max);
            }
        }
        else
        {
            /* Invalid DECC feature name. */
            fprintf( stderr,
             " UNKNOWN DECC$FEATURE: %s.\n", decc_feat_array[ i].name);
        }
    }

    if (verbose > 0)
    {
        fprintf( stderr, " DECC_INIT complete.\n");
    }
}

/* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */

#pragma nostandard

/* Establish the LIB$INITIALIZE PSECTs, with proper alignment and
 * other attributes.  Note that "nopic" is significant only on VAX.
 */
#pragma extern_model save

#if __INITIAL_POINTER_SIZE == 64
# define PSECT_ALIGN 3
#else
# define PSECT_ALIGN 2
#endif

#pragma extern_model strict_refdef "LIB$INITIALIZ" PSECT_ALIGN, nopic, nowrt
const int spare[ 8] = { 0 };

#pragma extern_model strict_refdef "LIB$INITIALIZE" PSECT_ALIGN, nopic, nowrt
void (*const x_decc_init)() = decc_init;

#pragma extern_model restore

/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */

#pragma extern_model save

int LIB$INITIALIZE( void);

#pragma extern_model strict_refdef
int dmy_lib$initialize = (int) LIB$INITIALIZE;

#pragma extern_model restore

#pragma standard

#else /* def USE_DECC_INIT */

/* Dummy code to avoid a %CC-W-EMPTYFILE complaint. */
int decc_init_dummy( void);

#endif /* def USE_DECC_INIT */