vms_decc_init.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. #ifdef USE_DECC_INIT
  6. /*-
  7. * 2010-04-26 SMS.
  8. *
  9. *----------------------------------------------------------------------
  10. *
  11. * decc_init()
  12. *
  13. * On non-VAX systems, uses LIB$INITIALIZE to set a collection of C
  14. * RTL features without using the DECC$* logical name method.
  15. *
  16. *----------------------------------------------------------------------
  17. */
  18. # include <stdio.h>
  19. # include <stdlib.h>
  20. # include <unixlib.h>
  21. /* Global storage. */
  22. /* Flag to sense if decc_init() was called. */
  23. int decc_init_done = -1;
  24. /* Structure to hold a DECC$* feature name and its desired value. */
  25. typedef struct {
  26. char *name;
  27. int value;
  28. } decc_feat_t;
  29. /*
  30. * Array of DECC$* feature names and their desired values. Note:
  31. * DECC$ARGV_PARSE_STYLE is the urgent one.
  32. */
  33. decc_feat_t decc_feat_array[] = {
  34. /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
  35. {"DECC$ARGV_PARSE_STYLE", 1},
  36. /* Preserve case for file names on ODS5 disks. */
  37. {"DECC$EFS_CASE_PRESERVE", 1},
  38. /*
  39. * Enable multiple dots (and most characters) in ODS5 file names, while
  40. * preserving VMS-ness of ";version".
  41. */
  42. {"DECC$EFS_CHARSET", 1},
  43. /* List terminator. */
  44. {(char *)NULL, 0}
  45. };
  46. /* LIB$INITIALIZE initialization function. */
  47. static void decc_init(void)
  48. {
  49. char *openssl_debug_decc_init;
  50. int verbose = 0;
  51. int feat_index;
  52. int feat_value;
  53. int feat_value_max;
  54. int feat_value_min;
  55. int i;
  56. int sts;
  57. /* Get debug option. */
  58. openssl_debug_decc_init = getenv("OPENSSL_DEBUG_DECC_INIT");
  59. if (openssl_debug_decc_init != NULL) {
  60. verbose = strtol(openssl_debug_decc_init, NULL, 10);
  61. if (verbose <= 0) {
  62. verbose = 1;
  63. }
  64. }
  65. /* Set the global flag to indicate that LIB$INITIALIZE worked. */
  66. decc_init_done = 1;
  67. /* Loop through all items in the decc_feat_array[]. */
  68. for (i = 0; decc_feat_array[i].name != NULL; i++) {
  69. /* Get the feature index. */
  70. feat_index = decc$feature_get_index(decc_feat_array[i].name);
  71. if (feat_index >= 0) {
  72. /* Valid item. Collect its properties. */
  73. feat_value = decc$feature_get_value(feat_index, 1);
  74. feat_value_min = decc$feature_get_value(feat_index, 2);
  75. feat_value_max = decc$feature_get_value(feat_index, 3);
  76. /* Check the validity of our desired value. */
  77. if ((decc_feat_array[i].value >= feat_value_min) &&
  78. (decc_feat_array[i].value <= feat_value_max)) {
  79. /* Valid value. Set it if necessary. */
  80. if (feat_value != decc_feat_array[i].value) {
  81. sts = decc$feature_set_value(feat_index,
  82. 1, decc_feat_array[i].value);
  83. if (verbose > 1) {
  84. fprintf(stderr, " %s = %d, sts = %d.\n",
  85. decc_feat_array[i].name,
  86. decc_feat_array[i].value, sts);
  87. }
  88. }
  89. } else {
  90. /* Invalid DECC feature value. */
  91. fprintf(stderr,
  92. " INVALID DECC$FEATURE VALUE, %d: %d <= %s <= %d.\n",
  93. feat_value,
  94. feat_value_min, decc_feat_array[i].name,
  95. feat_value_max);
  96. }
  97. } else {
  98. /* Invalid DECC feature name. */
  99. fprintf(stderr,
  100. " UNKNOWN DECC$FEATURE: %s.\n", decc_feat_array[i].name);
  101. }
  102. }
  103. if (verbose > 0) {
  104. fprintf(stderr, " DECC_INIT complete.\n");
  105. }
  106. }
  107. /* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
  108. # pragma nostandard
  109. /*
  110. * Establish the LIB$INITIALIZE PSECTs, with proper alignment and other
  111. * attributes. Note that "nopic" is significant only on VAX.
  112. */
  113. # pragma extern_model save
  114. # if __INITIAL_POINTER_SIZE == 64
  115. # define PSECT_ALIGN 3
  116. # else
  117. # define PSECT_ALIGN 2
  118. # endif
  119. # pragma extern_model strict_refdef "LIB$INITIALIZ" PSECT_ALIGN, nopic, nowrt
  120. const int spare[8] = { 0 };
  121. # pragma extern_model strict_refdef "LIB$INITIALIZE" PSECT_ALIGN, nopic, nowrt
  122. void (*const x_decc_init) () = decc_init;
  123. # pragma extern_model restore
  124. /* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
  125. # pragma extern_model save
  126. int LIB$INITIALIZE(void);
  127. # pragma extern_model strict_refdef
  128. int dmy_lib$initialize = (int)LIB$INITIALIZE;
  129. # pragma extern_model restore
  130. # pragma standard
  131. #else /* def USE_DECC_INIT */
  132. /* Dummy code to avoid a %CC-W-EMPTYFILE complaint. */
  133. int decc_init_dummy(void);
  134. #endif /* def USE_DECC_INIT */