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 71struct 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 87int decc$feature_get_index (const char *name); 88int decc$feature_set_value (int index, int mode, int value); 89#endif 90 91int 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); 97int 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 */ 106static int sys_trnlnm 107 (const char * logname, 108 char * value, 109 int value_len) 110{ 111 const $DESCRIPTOR(table_dsc, "LNM$FILE_DEV"); 112 const unsigned long attr = LNM$M_CASE_BLIND; 113 struct dsc$descriptor_s name_dsc; 114 int status; 115 unsigned short result; 116 struct itmlst_3 itlst[2]; 117 118 itlst[0].buflen = value_len; 119 itlst[0].itmcode = LNM$_STRING; 120 itlst[0].bufadr = value; 121 itlst[0].retlen = &result; 122 123 itlst[1].buflen = 0; 124 itlst[1].itmcode = 0; 125 126 name_dsc.dsc$w_length = strlen(logname); 127 name_dsc.dsc$a_pointer = (char *)logname; 128 name_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 129 name_dsc.dsc$b_class = DSC$K_CLASS_S; 130 131 status = SYS$TRNLNM(&attr, &table_dsc, &name_dsc, 0, itlst); 132 133 if($VMS_STATUS_SUCCESS(status)) { 134 135 /* Null terminate and return the string */ 136 /*--------------------------------------*/ 137 value[result] = '\0'; 138 } 139 140 return status; 141} 142 143/* How to simply create a logical name */ 144static int sys_crelnm 145 (const char * logname, 146 const char * value) 147{ 148 int ret_val; 149 const char * proc_table = "LNM$PROCESS_TABLE"; 150 struct dsc$descriptor_s proc_table_dsc; 151 struct dsc$descriptor_s logname_dsc; 152 struct itmlst_3 item_list[2]; 153 154 proc_table_dsc.dsc$a_pointer = (char *) proc_table; 155 proc_table_dsc.dsc$w_length = strlen(proc_table); 156 proc_table_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 157 proc_table_dsc.dsc$b_class = DSC$K_CLASS_S; 158 159 logname_dsc.dsc$a_pointer = (char *) logname; 160 logname_dsc.dsc$w_length = strlen(logname); 161 logname_dsc.dsc$b_dtype = DSC$K_DTYPE_T; 162 logname_dsc.dsc$b_class = DSC$K_CLASS_S; 163 164 item_list[0].buflen = strlen(value); 165 item_list[0].itmcode = LNM$_STRING; 166 item_list[0].bufadr = (char *)value; 167 item_list[0].retlen = NULL; 168 169 item_list[1].buflen = 0; 170 item_list[1].itmcode = 0; 171 172 ret_val = SYS$CRELNM(NULL, &proc_table_dsc, &logname_dsc, NULL, item_list); 173 174 return ret_val; 175} 176 177 178 /* Start of DECC RTL Feature handling */ 179 180/* 181** Sets default value for a feature 182*/ 183#ifdef __VAX 184static void set_feature_default(const char *name, const char *value) 185{ 186 sys_crelnm(name, value); 187} 188#else 189static void set_feature_default(const char *name, int value) 190{ 191 int index; 192 193 index = decc$feature_get_index(name); 194 195 if(index > 0) 196 decc$feature_set_value (index, 0, value); 197} 198#endif 199 200static void set_features(void) 201{ 202 int status; 203 char unix_shell_name[255]; 204 int use_unix_settings = 1; 205 206 status = sys_trnlnm("GNV$UNIX_SHELL", 207 unix_shell_name, sizeof unix_shell_name -1); 208 if(!$VMS_STATUS_SUCCESS(status)) { 209 use_unix_settings = 0; 210 } 211 212 /* ACCESS should check ACLs or it is lying. */ 213 set_feature_default("DECC$ACL_ACCESS_CHECK", ENABLE); 214 215 /* We always want the new parse style */ 216 set_feature_default ("DECC$ARGV_PARSE_STYLE" , ENABLE); 217 218 219 /* Unless we are in POSIX compliant mode, we want the old POSIX root 220 * enabled. 221 */ 222 set_feature_default("DECC$DISABLE_POSIX_ROOT", DISABLE); 223 224 /* EFS charset, means UTF-8 support */ 225 /* VTF-7 support is controlled by a feature setting called UTF8 */ 226 set_feature_default ("DECC$EFS_CHARSET", ENABLE); 227 set_feature_default ("DECC$EFS_CASE_PRESERVE", ENABLE); 228 229 /* Support timestamps when available */ 230 set_feature_default ("DECC$EFS_FILE_TIMESTAMPS", ENABLE); 231 232 /* Cache environment variables - performance improvements */ 233 set_feature_default ("DECC$ENABLE_GETENV_CACHE", ENABLE); 234 235 /* Start out with new file attribute inheritance */ 236#ifdef __VAX 237 set_feature_default ("DECC$EXEC_FILEATTR_INHERITANCE", "2"); 238#else 239 set_feature_default ("DECC$EXEC_FILEATTR_INHERITANCE", 2); 240#endif 241 242 /* Don't display trailing dot after files without type */ 243 set_feature_default ("DECC$READDIR_DROPDOTNOTYPE", ENABLE); 244 245 /* For standard output channels buffer output until terminator */ 246 /* Gets rid of output logs with single character lines in them. */ 247 set_feature_default ("DECC$STDIO_CTX_EOL", ENABLE); 248 249 /* Fix mv aa.bb aa */ 250 set_feature_default ("DECC$RENAME_NO_INHERIT", ENABLE); 251 252 if(use_unix_settings) { 253 254 /* POSIX requires that open files be able to be removed */ 255 set_feature_default ("DECC$ALLOW_REMOVE_OPEN_FILES", ENABLE); 256 257 /* Default to outputting Unix filenames in VMS routines */ 258 set_feature_default ("DECC$FILENAME_UNIX_ONLY", ENABLE); 259 /* FILENAME_UNIX_ONLY Implicitly sets */ 260 /* decc$disable_to_vms_logname_translation */ 261 262 set_feature_default ("DECC$FILE_PERMISSION_UNIX", ENABLE); 263 264 set_feature_default ("DECC$FILE_SHARING", ENABLE); 265 266 set_feature_default ("DECC$FILE_OWNER_UNIX", ENABLE); 267 set_feature_default ("DECC$POSIX_SEEK_STREAM_FILE", ENABLE); 268 269 } else { 270 set_feature_default("DECC$FILENAME_UNIX_REPORT", ENABLE); 271 } 272 273 /* When reporting Unix filenames, glob the same way */ 274 set_feature_default ("DECC$GLOB_UNIX_STYLE", ENABLE); 275 276 /* The VMS version numbers on Unix filenames is incompatible with most */ 277 /* ported packages. */ 278 set_feature_default("DECC$FILENAME_UNIX_NO_VERSION", ENABLE); 279 280 /* The VMS version numbers on Unix filenames is incompatible with most */ 281 /* ported packages. */ 282 set_feature_default("DECC$UNIX_PATH_BEFORE_LOGNAME", ENABLE); 283 284 /* Set strtol to proper behavior */ 285 set_feature_default("DECC$STRTOL_ERANGE", ENABLE); 286 287 /* Commented here to prevent future bugs: A program or user should */ 288 /* never ever enable DECC$POSIX_STYLE_UID. */ 289 /* It will probably break all code that accesses UIDs */ 290 /* do_not_set_default ("DECC$POSIX_STYLE_UID", TRUE); */ 291} 292 293 294/* Some boilerplate to force this to be a proper LIB$INITIALIZE section */ 295 296#pragma nostandard 297#pragma extern_model save 298#ifdef __VAX 299#pragma extern_model strict_refdef "LIB$INITIALIZE" nowrt, long, nopic 300#else 301#pragma extern_model strict_refdef "LIB$INITIALIZE" nowrt, long 302# if __INITIAL_POINTER_SIZE 303# pragma __pointer_size __save 304# pragma __pointer_size 32 305# else 306# pragma __required_pointer_size __save 307# pragma __required_pointer_size 32 308# endif 309#endif 310/* Set our contribution to the LIB$INITIALIZE array */ 311void (* const iniarray[])(void) = {set_features, } ; 312#ifndef __VAX 313# if __INITIAL_POINTER_SIZE 314# pragma __pointer_size __restore 315# else 316# pragma __required_pointer_size __restore 317# endif 318#endif 319 320 321/* 322** Force a reference to LIB$INITIALIZE to ensure it 323** exists in the image. 324*/ 325int LIB$INITIALIZE(void); 326#ifdef __DECC 327#pragma extern_model strict_refdef 328#endif 329 int lib_init_ref = (int) LIB$INITIALIZE; 330#ifdef __DECC 331#pragma extern_model restore 332#pragma standard 333#endif 334