xref: /curl/packages/vms/curl_crtl_init.c (revision 99ba50d9)
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 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.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  * SPDX-License-Identifier: curl
22  *
23  ***************************************************************************/
24 /* File: curl_crtl_init.c
25  *
26  * This file makes sure that the DECC Unix settings are correct for
27  * the mode the program is run in.
28  *
29  * The CRTL has not been initialized at the time that these routines
30  * are called, so many routines can not be called.
31  *
32  * This is a module that provides a LIB$INITIALIZE routine that
33  * will turn on some CRTL features that are not enabled by default.
34  *
35  * The CRTL features can also be turned on via logical names, but that
36  * impacts all programs and some aren't ready, willing, or able to handle
37  * those settings.
38  *
39  * On VMS versions that are too old to use the feature setting API, this
40  * module falls back to using logical names.
41  *
42  * Copyright (C) John Malmberg
43  *
44  * Permission to use, copy, modify, and/or distribute this software for any
45  * purpose with or without fee is hereby granted, provided that the above
46  * copyright notice and this permission notice appear in all copies.
47  *
48  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
49  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
50  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
51  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
52  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
53  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
54  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
55  *
56  */
57 
58 /* Unix headers */
59 #include <stdio.h>
60 #include <string.h>
61 
62 /* VMS specific headers */
63 #include <descrip.h>
64 #include <lnmdef.h>
65 #include <stsdef.h>
66 
67 #pragma member_alignment save
68 #pragma nomember_alignment longword
69 #pragma message save
70 #pragma message disable misalgndmem
71 struct itmlst_3 {
72   unsigned short int buflen;
73   unsigned short int itmcode;
74   void *bufadr;
75   unsigned short int *retlen;
76 };
77 #pragma message restore
78 #pragma member_alignment restore
79 
80 #ifdef __VAX
81 #define ENABLE "ENABLE"
82 #define DISABLE "DISABLE"
83 #else
84 
85 #define ENABLE TRUE
86 #define DISABLE 0
87 int   decc$feature_get_index (const char *name);
88 int   decc$feature_set_value (int index, int mode, int value);
89 #endif
90 
91 int   SYS$TRNLNM(
92     const unsigned long *attr,
93     const struct dsc$descriptor_s *table_dsc,
94     struct dsc$descriptor_s *name_dsc,
95     const unsigned char *acmode,
96     const struct itmlst_3 *item_list);
97 int   SYS$CRELNM(
98     const unsigned long *attr,
99     const struct dsc$descriptor_s *table_dsc,
100     const struct dsc$descriptor_s *name_dsc,
101     const unsigned char *acmode,
102     const struct itmlst_3 *item_list);
103 
104 
105 /* Take all the fun out of simply looking up a logical name */
sys_trnlnm(const char * logname,char * value,int value_len)106 static int sys_trnlnm(const char *logname,
107                       char *value,
108                       int value_len)
109 {
110   const $DESCRIPTOR(table_dsc, "LNM$FILE_DEV");
111   const unsigned long attr = LNM$M_CASE_BLIND;
112   struct dsc$descriptor_s name_dsc;
113   int status;
114   unsigned short result;
115   struct itmlst_3 itlst[2];
116 
117   itlst[0].buflen = value_len;
118   itlst[0].itmcode = LNM$_STRING;
119   itlst[0].bufadr = value;
120   itlst[0].retlen = &result;
121 
122   itlst[1].buflen = 0;
123   itlst[1].itmcode = 0;
124 
125   name_dsc.dsc$w_length = strlen(logname);
126   name_dsc.dsc$a_pointer = (char *)logname;
127   name_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
128   name_dsc.dsc$b_class = DSC$K_CLASS_S;
129 
130   status = SYS$TRNLNM(&attr, &table_dsc, &name_dsc, 0, itlst);
131 
132   if($VMS_STATUS_SUCCESS(status)) {
133 
134     /* Null terminate and return the string */
135     /*--------------------------------------*/
136     value[result] = '\0';
137   }
138 
139   return status;
140 }
141 
142 /* How to simply create a logical name */
sys_crelnm(const char * logname,const char * value)143 static int sys_crelnm(const char *logname,
144                       const char *value)
145 {
146   int ret_val;
147   const char *proc_table = "LNM$PROCESS_TABLE";
148   struct dsc$descriptor_s proc_table_dsc;
149   struct dsc$descriptor_s logname_dsc;
150   struct itmlst_3 item_list[2];
151 
152   proc_table_dsc.dsc$a_pointer = (char *) proc_table;
153   proc_table_dsc.dsc$w_length = strlen(proc_table);
154   proc_table_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
155   proc_table_dsc.dsc$b_class = DSC$K_CLASS_S;
156 
157   logname_dsc.dsc$a_pointer = (char *) logname;
158   logname_dsc.dsc$w_length = strlen(logname);
159   logname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
160   logname_dsc.dsc$b_class = DSC$K_CLASS_S;
161 
162   item_list[0].buflen = strlen(value);
163   item_list[0].itmcode = LNM$_STRING;
164   item_list[0].bufadr = (char *)value;
165   item_list[0].retlen = NULL;
166 
167   item_list[1].buflen = 0;
168   item_list[1].itmcode = 0;
169 
170   ret_val = SYS$CRELNM(NULL, &proc_table_dsc, &logname_dsc, NULL, item_list);
171 
172   return ret_val;
173 }
174 
175 
176  /* Start of DECC RTL Feature handling */
177 
178 /*
179 ** Sets default value for a feature
180 */
181 #ifdef __VAX
set_feature_default(const char * name,const char * value)182 static void set_feature_default(const char *name, const char *value)
183 {
184   sys_crelnm(name, value);
185 }
186 #else
set_feature_default(const char * name,int value)187 static void set_feature_default(const char *name, int value)
188 {
189   int index;
190 
191   index = decc$feature_get_index(name);
192 
193   if(index > 0)
194     decc$feature_set_value (index, 0, value);
195 }
196 #endif
197 
set_features(void)198 static void set_features(void)
199 {
200   int status;
201   char unix_shell_name[255];
202   int use_unix_settings = 1;
203 
204   status = sys_trnlnm("GNV$UNIX_SHELL",
205                       unix_shell_name, sizeof(unix_shell_name) -1);
206   if(!$VMS_STATUS_SUCCESS(status)) {
207     use_unix_settings = 0;
208   }
209 
210   /* ACCESS should check ACLs or it is lying. */
211   set_feature_default("DECC$ACL_ACCESS_CHECK", ENABLE);
212 
213   /* We always want the new parse style */
214   set_feature_default("DECC$ARGV_PARSE_STYLE", ENABLE);
215 
216 
217   /* Unless we are in POSIX compliant mode, we want the old POSIX root
218    * enabled.
219    */
220   set_feature_default("DECC$DISABLE_POSIX_ROOT", DISABLE);
221 
222   /* EFS charset, means UTF-8 support */
223   /* VTF-7 support is controlled by a feature setting called UTF8 */
224   set_feature_default("DECC$EFS_CHARSET", ENABLE);
225   set_feature_default("DECC$EFS_CASE_PRESERVE", ENABLE);
226 
227   /* Support timestamps when available */
228   set_feature_default("DECC$EFS_FILE_TIMESTAMPS", ENABLE);
229 
230   /* Cache environment variables - performance improvements */
231   set_feature_default("DECC$ENABLE_GETENV_CACHE", ENABLE);
232 
233   /* Start out with new file attribute inheritance */
234 #ifdef __VAX
235   set_feature_default("DECC$EXEC_FILEATTR_INHERITANCE", "2");
236 #else
237   set_feature_default("DECC$EXEC_FILEATTR_INHERITANCE", 2);
238 #endif
239 
240   /* Don't display trailing dot after files without type */
241   set_feature_default("DECC$READDIR_DROPDOTNOTYPE", ENABLE);
242 
243   /* For standard output channels buffer output until terminator */
244   /* Gets rid of output logs with single character lines in them. */
245   set_feature_default("DECC$STDIO_CTX_EOL", ENABLE);
246 
247   /* Fix mv aa.bb aa  */
248   set_feature_default("DECC$RENAME_NO_INHERIT", ENABLE);
249 
250   if(use_unix_settings) {
251 
252     /* POSIX requires that open files be able to be removed */
253     set_feature_default("DECC$ALLOW_REMOVE_OPEN_FILES", ENABLE);
254 
255     /* Default to outputting Unix filenames in VMS routines */
256     set_feature_default("DECC$FILENAME_UNIX_ONLY", ENABLE);
257     /* FILENAME_UNIX_ONLY Implicitly sets */
258     /* decc$disable_to_vms_logname_translation */
259 
260     set_feature_default("DECC$FILE_PERMISSION_UNIX", ENABLE);
261 
262     set_feature_default("DECC$FILE_SHARING", ENABLE);
263 
264     set_feature_default("DECC$FILE_OWNER_UNIX", ENABLE);
265     set_feature_default("DECC$POSIX_SEEK_STREAM_FILE", ENABLE);
266 
267   }
268   else {
269     set_feature_default("DECC$FILENAME_UNIX_REPORT", ENABLE);
270   }
271 
272   /* When reporting Unix filenames, glob the same way */
273   set_feature_default("DECC$GLOB_UNIX_STYLE", ENABLE);
274 
275   /* The VMS version numbers on Unix filenames is incompatible with most */
276   /* ported packages. */
277   set_feature_default("DECC$FILENAME_UNIX_NO_VERSION", ENABLE);
278 
279   /* The VMS version numbers on Unix filenames is incompatible with most */
280   /* ported packages. */
281   set_feature_default("DECC$UNIX_PATH_BEFORE_LOGNAME", ENABLE);
282 
283   /* Set strtol to proper behavior */
284   set_feature_default("DECC$STRTOL_ERANGE", ENABLE);
285 
286   /* Commented here to prevent future bugs:  A program or user should */
287   /* never ever enable DECC$POSIX_STYLE_UID. */
288   /* It will probably break all code that accesses UIDs */
289   /*  do_not_set_default ("DECC$POSIX_STYLE_UID", TRUE); */
290 }
291 
292 
293 /* Some boilerplate to force this to be a proper LIB$INITIALIZE section */
294 
295 #pragma nostandard
296 #pragma extern_model save
297 #ifdef __VAX
298 #pragma extern_model strict_refdef "LIB$INITIALIZE" nowrt, long, nopic
299 #else
300 #pragma extern_model strict_refdef "LIB$INITIALIZE" nowrt, long
301 #    if __INITIAL_POINTER_SIZE
302 #        pragma __pointer_size __save
303 #        pragma __pointer_size 32
304 #    else
305 #        pragma __required_pointer_size __save
306 #        pragma __required_pointer_size 32
307 #    endif
308 #endif
309 /* Set our contribution to the LIB$INITIALIZE array */
310 void (* const iniarray[])(void) = {set_features };
311 #ifndef __VAX
312 #    if __INITIAL_POINTER_SIZE
313 #        pragma __pointer_size __restore
314 #    else
315 #        pragma __required_pointer_size __restore
316 #    endif
317 #endif
318 
319 
320 /*
321 ** Force a reference to LIB$INITIALIZE to ensure it
322 ** exists in the image.
323 */
324 int LIB$INITIALIZE(void);
325 #ifdef __DECC
326 #pragma extern_model strict_refdef
327 #endif
328     int lib_init_ref = (int) LIB$INITIALIZE;
329 #ifdef __DECC
330 #pragma extern_model restore
331 #pragma standard
332 #endif
333