• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /***************************************************************************
2   *                                  _   _ ____  _
3   *  Project                     ___| | | |  _ \| |
4   *                             / __| | | | |_) | |
5   *                            | (__| |_| |  _ <| |___
6   *                             \___|\___/|_| \_\_____|
7   *
8   * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
9   *
10   * This software is licensed as described in the file COPYING, which
11   * you should have received as part of this distribution. The terms
12   * are also available at https://curl.haxx.se/docs/copyright.html.
13   *
14   * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15   * copies of the Software, and permit persons to whom the Software is
16   * furnished to do so, under the terms of the COPYING file.
17   *
18   * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19   * KIND, either express or implied.
20   *
21   ***************************************************************************/
22  #include "tool_setup.h"
23  
24  #ifdef __VMS
25  
26  #if defined(__DECC) && !defined(__VAX) && \
27      defined(__CRTL_VER) && (__CRTL_VER >= 70301000)
28  #include <unixlib.h>
29  #endif
30  
31  #define ENABLE_CURLX_PRINTF
32  #include "curlx.h"
33  
34  #include "curlmsg_vms.h"
35  #include "tool_vms.h"
36  
37  #include "memdebug.h" /* keep this as LAST include */
38  
39  void decc$__posix_exit(int __status);
40  void decc$exit(int __status);
41  
42  static int vms_shell = -1;
43  
44  /* VMS has a DCL shell and and also has Unix shells ported to it.
45   * When curl is running under a Unix shell, we want it to be as much
46   * like Unix as possible.
47   */
is_vms_shell(void)48  int is_vms_shell(void)
49  {
50    char *shell;
51  
52    /* Have we checked the shell yet? */
53    if(vms_shell >= 0)
54      return vms_shell;
55  
56    shell = getenv("SHELL");
57  
58    /* No shell, means DCL */
59    if(shell == NULL) {
60      vms_shell = 1;
61      return 1;
62    }
63  
64    /* Have to make sure some one did not set shell to DCL */
65    if(strcmp(shell, "DCL") == 0) {
66      vms_shell = 1;
67      return 1;
68    }
69  
70    vms_shell = 0;
71    return 0;
72  }
73  
74  /*
75   * VMS has two exit() routines.  When running under a Unix style shell, then
76   * Unix style and the __posix_exit() routine is used.
77   *
78   * When running under the DCL shell, then the VMS encoded codes and decc$exit()
79   * is used.
80   *
81   * We can not use exit() or return a code from main() because the actual
82   * routine called depends on both the compiler version, compile options, and
83   * feature macro settings, and one of the exit routines is hidden at compile
84   * time.
85   *
86   * Since we want Curl to work properly under the VMS DCL shell and Unix
87   * shells under VMS, this routine should compile correctly regardless of
88   * the settings.
89   */
90  
vms_special_exit(int code,int vms_show)91  void vms_special_exit(int code, int vms_show)
92  {
93    int vms_code;
94  
95    /* The Posix exit mode is only available after VMS 7.0 */
96  #if __CRTL_VER >= 70000000
97    if(is_vms_shell() == 0) {
98      decc$__posix_exit(code);
99    }
100  #endif
101  
102    if(code > CURL_LAST) {   /* If CURL_LAST exceeded then */
103      vms_code = CURL_LAST;  /* curlmsg.h is out of sync.  */
104    }
105    else {
106      vms_code = vms_cond[code] | vms_show;
107    }
108    decc$exit(vms_code);
109  }
110  
111  #if defined(__DECC) && !defined(__VAX) && \
112      defined(__CRTL_VER) && (__CRTL_VER >= 70301000)
113  
114  /*
115   * 2004-09-19 SMS.
116   *
117   * decc_init()
118   *
119   * On non-VAX systems, use LIB$INITIALIZE to set a collection of C
120   * RTL features without using the DECC$* logical name method, nor
121   * requiring the user to define the corresponding logical names.
122   */
123  
124  /* Structure to hold a DECC$* feature name and its desired value. */
125  typedef struct {
126    char *name;
127    int value;
128  } decc_feat_t;
129  
130  /* Array of DECC$* feature names and their desired values. */
131  static decc_feat_t decc_feat_array[] = {
132    /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
133    { "DECC$ARGV_PARSE_STYLE", 1 },
134    /* Preserve case for file names on ODS5 disks. */
135    { "DECC$EFS_CASE_PRESERVE", 1 },
136    /* Enable multiple dots (and most characters) in ODS5 file names,
137       while preserving VMS-ness of ";version". */
138    { "DECC$EFS_CHARSET", 1 },
139    /* List terminator. */
140    { (char *)NULL, 0 }
141  };
142  
143  /* Flag to sense if decc_init() was called. */
144  static int decc_init_done = -1;
145  
146  /* LIB$INITIALIZE initialization function. */
decc_init(void)147  static void decc_init(void)
148  {
149    int feat_index;
150    int feat_value;
151    int feat_value_max;
152    int feat_value_min;
153    int i;
154    int sts;
155  
156    /* Set the global flag to indicate that LIB$INITIALIZE worked. */
157    decc_init_done = 1;
158  
159    /* Loop through all items in the decc_feat_array[]. */
160    for(i = 0; decc_feat_array[i].name != NULL; i++) {
161  
162      /* Get the feature index. */
163      feat_index = decc$feature_get_index(decc_feat_array[i].name);
164  
165      if(feat_index >= 0) {
166        /* Valid item.  Collect its properties. */
167        feat_value = decc$feature_get_value(feat_index, 1);
168        feat_value_min = decc$feature_get_value(feat_index, 2);
169        feat_value_max = decc$feature_get_value(feat_index, 3);
170  
171        if((decc_feat_array[i].value >= feat_value_min) &&
172           (decc_feat_array[i].value <= feat_value_max)) {
173          /* Valid value.  Set it if necessary. */
174          if(feat_value != decc_feat_array[i].value) {
175            sts = decc$feature_set_value(feat_index, 1,
176                                         decc_feat_array[i].value);
177          }
178        }
179        else {
180          /* Invalid DECC feature value. */
181          printf(" INVALID DECC FEATURE VALUE, %d: %d <= %s <= %d.\n",
182                 feat_value,
183                 feat_value_min, decc_feat_array[i].name, feat_value_max);
184        }
185      }
186      else {
187        /* Invalid DECC feature name. */
188        printf(" UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[i].name);
189      }
190  
191    }
192  }
193  
194  /* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
195  
196  #pragma nostandard
197  
198  /* Establish the LIB$INITIALIZE PSECTs, with proper alignment and
199     other attributes.  Note that "nopic" is significant only on VAX. */
200  #pragma extern_model save
201  #pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt
202  const int spare[8] = {0};
203  #pragma extern_model strict_refdef "LIB$INITIALIZE" 2, nopic, nowrt
204  void (*const x_decc_init)() = decc_init;
205  #pragma extern_model restore
206  
207  /* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
208  #pragma extern_model save
209  int LIB$INITIALIZE(void);
210  #pragma extern_model strict_refdef
211  int dmy_lib$initialize = (int) LIB$INITIALIZE;
212  #pragma extern_model restore
213  
214  #pragma standard
215  
216  #endif /* __DECC && !__VAX && __CRTL_VER && __CRTL_VER >= 70301000 */
217  
218  #endif /* __VMS */
219