vms_decc_init.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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. #if defined( __VMS) && !defined( OPENSSL_NO_DECC_INIT) && \
  10. defined( __DECC) && !defined( __VAX) && (__CRTL_VER >= 70301000)
  11. # define USE_DECC_INIT 1
  12. #endif
  13. #ifdef USE_DECC_INIT
  14. /*
  15. * ----------------------------------------------------------------------
  16. * decc_init() On non-VAX systems, uses LIB$INITIALIZE to set a collection
  17. * of C RTL features without using the DECC$* logical name method.
  18. * ----------------------------------------------------------------------
  19. */
  20. # include <stdio.h>
  21. # include <stdlib.h>
  22. # include <unixlib.h>
  23. # include "apps.h"
  24. /* Global storage. */
  25. /* Flag to sense if decc_init() was called. */
  26. int decc_init_done = -1;
  27. /* Structure to hold a DECC$* feature name and its desired value. */
  28. typedef struct {
  29. char *name;
  30. int value;
  31. } decc_feat_t;
  32. /*
  33. * Array of DECC$* feature names and their desired values. Note:
  34. * DECC$ARGV_PARSE_STYLE is the urgent one.
  35. */
  36. decc_feat_t decc_feat_array[] = {
  37. /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
  38. {"DECC$ARGV_PARSE_STYLE", 1},
  39. /* Preserve case for file names on ODS5 disks. */
  40. {"DECC$EFS_CASE_PRESERVE", 1},
  41. /*
  42. * Enable multiple dots (and most characters) in ODS5 file names, while
  43. * preserving VMS-ness of ";version".
  44. */
  45. {"DECC$EFS_CHARSET", 1},
  46. /* List terminator. */
  47. {(char *)NULL, 0}
  48. };
  49. char **copy_argv(int *argc, char *argv[])
  50. {
  51. /*-
  52. * The note below is for historical purpose. On VMS now we always
  53. * copy argv "safely."
  54. *
  55. * 2011-03-22 SMS.
  56. * If we have 32-bit pointers everywhere, then we're safe, and
  57. * we bypass this mess, as on non-VMS systems.
  58. * Problem 1: Compaq/HP C before V7.3 always used 32-bit
  59. * pointers for argv[].
  60. * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers
  61. * everywhere else, we always allocate and use a 64-bit
  62. * duplicate of argv[].
  63. * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed
  64. * to NULL-terminate a 64-bit argv[]. (As this was written, the
  65. * compiler ECO was available only on IA64.)
  66. * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a
  67. * 64-bit argv[argc] for NULL, and, if necessary, use a
  68. * (properly) NULL-terminated (64-bit) duplicate of argv[].
  69. * The same code is used in either case to duplicate argv[].
  70. * Some of these decisions could be handled in preprocessing,
  71. * but the code tends to get even uglier, and the penalty for
  72. * deciding at compile- or run-time is tiny.
  73. */
  74. int i, count = *argc;
  75. char **newargv = app_malloc(sizeof(*newargv) * (count + 1), "argv copy");
  76. for (i = 0; i < count; i++)
  77. newargv[i] = argv[i];
  78. newargv[i] = NULL;
  79. *argc = i;
  80. return newargv;
  81. }
  82. /* LIB$INITIALIZE initialization function. */
  83. static void decc_init(void)
  84. {
  85. char *openssl_debug_decc_init;
  86. int verbose = 0;
  87. int feat_index;
  88. int feat_value;
  89. int feat_value_max;
  90. int feat_value_min;
  91. int i;
  92. int sts;
  93. /* Get debug option. */
  94. openssl_debug_decc_init = getenv("OPENSSL_DEBUG_DECC_INIT");
  95. if (openssl_debug_decc_init != NULL) {
  96. verbose = strtol(openssl_debug_decc_init, NULL, 10);
  97. if (verbose <= 0) {
  98. verbose = 1;
  99. }
  100. }
  101. /* Set the global flag to indicate that LIB$INITIALIZE worked. */
  102. decc_init_done = 1;
  103. /* Loop through all items in the decc_feat_array[]. */
  104. for (i = 0; decc_feat_array[i].name != NULL; i++) {
  105. /* Get the feature index. */
  106. feat_index = decc$feature_get_index(decc_feat_array[i].name);
  107. if (feat_index >= 0) {
  108. /* Valid item. Collect its properties. */
  109. feat_value = decc$feature_get_value(feat_index, 1);
  110. feat_value_min = decc$feature_get_value(feat_index, 2);
  111. feat_value_max = decc$feature_get_value(feat_index, 3);
  112. /* Check the validity of our desired value. */
  113. if ((decc_feat_array[i].value >= feat_value_min) &&
  114. (decc_feat_array[i].value <= feat_value_max)) {
  115. /* Valid value. Set it if necessary. */
  116. if (feat_value != decc_feat_array[i].value) {
  117. sts = decc$feature_set_value(feat_index,
  118. 1, decc_feat_array[i].value);
  119. if (verbose > 1) {
  120. fprintf(stderr, " %s = %d, sts = %d.\n",
  121. decc_feat_array[i].name,
  122. decc_feat_array[i].value, sts);
  123. }
  124. }
  125. } else {
  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,
  131. feat_value_max);
  132. }
  133. } else {
  134. /* Invalid DECC feature name. */
  135. fprintf(stderr,
  136. " UNKNOWN DECC$FEATURE: %s.\n", decc_feat_array[i].name);
  137. }
  138. }
  139. if (verbose > 0) {
  140. fprintf(stderr, " DECC_INIT complete.\n");
  141. }
  142. }
  143. /* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
  144. # pragma nostandard
  145. /*
  146. * Establish the LIB$INITIALIZE PSECTs, with proper alignment and other
  147. * attributes. Note that "nopic" is significant only on VAX.
  148. */
  149. # pragma extern_model save
  150. # if __INITIAL_POINTER_SIZE == 64
  151. # define PSECT_ALIGN 3
  152. # else
  153. # define PSECT_ALIGN 2
  154. # endif
  155. # pragma extern_model strict_refdef "LIB$INITIALIZ" PSECT_ALIGN, nopic, nowrt
  156. const int spare[8] = { 0 };
  157. # pragma extern_model strict_refdef "LIB$INITIALIZE" PSECT_ALIGN, nopic, nowrt
  158. void (*const x_decc_init) () = decc_init;
  159. # pragma extern_model restore
  160. /* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
  161. # pragma extern_model save
  162. int LIB$INITIALIZE(void);
  163. # pragma extern_model strict_refdef
  164. int dmy_lib$initialize = (int)LIB$INITIALIZE;
  165. # pragma extern_model restore
  166. # pragma standard
  167. #else /* def USE_DECC_INIT */
  168. /* Dummy code to avoid a %CC-W-EMPTYFILE complaint. */
  169. int decc_init_dummy(void);
  170. #endif /* def USE_DECC_INIT */