diff options
Diffstat (limited to 'packages/vms/curl_crtl_init.c')
-rw-r--r-- | packages/vms/curl_crtl_init.c | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/packages/vms/curl_crtl_init.c b/packages/vms/curl_crtl_init.c new file mode 100644 index 00000000..01a34e55 --- /dev/null +++ b/packages/vms/curl_crtl_init.c @@ -0,0 +1,311 @@ +/* File: curl_crtl_init.c + * + * This file makes sure that the DECC Unix settings are correct for + * the mode the the program is run in. + * + * The CRTL has not been initialized at the time that these routines + * are called, so many routines can not be called. + * + * This is a module that provides a LIB$INITIALIZE routine that + * will turn on some CRTL features that are not enabled by default. + * + * The CRTL features can also be turned on via logical names, but that + * impacts all programs and some aren't ready, willing, or able to handle + * those settings. + * + * On VMS versions that are too old to use the feature setting API, this + * module falls back to using logical names. + * + * Copyright 2013, John Malmberg + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* Unix headers */ +#include <stdio.h> +#include <string.h> + +/* VMS specific headers */ +#include <descrip.h> +#include <lnmdef.h> +#include <stsdef.h> + +#pragma member_alignment save +#pragma nomember_alignment longword +#pragma message save +#pragma message disable misalgndmem +struct itmlst_3 { + unsigned short int buflen; + unsigned short int itmcode; + void *bufadr; + unsigned short int *retlen; +}; +#pragma message restore +#pragma member_alignment restore + +#ifdef __VAX +#define ENABLE "ENABLE" +#define DISABLE "DISABLE" +#else + +#define ENABLE TRUE +#define DISABLE 0 +int decc$feature_get_index (const char *name); +int decc$feature_set_value (int index, int mode, int value); +#endif + +int SYS$TRNLNM( + const unsigned long * attr, + const struct dsc$descriptor_s * table_dsc, + struct dsc$descriptor_s * name_dsc, + const unsigned char * acmode, + const struct itmlst_3 * item_list); +int SYS$CRELNM( + const unsigned long * attr, + const struct dsc$descriptor_s * table_dsc, + const struct dsc$descriptor_s * name_dsc, + const unsigned char * acmode, + const struct itmlst_3 * item_list); + + +/* Take all the fun out of simply looking up a logical name */ +static int sys_trnlnm + (const char * logname, + char * value, + int value_len) +{ + const $DESCRIPTOR(table_dsc, "LNM$FILE_DEV"); + const unsigned long attr = LNM$M_CASE_BLIND; + struct dsc$descriptor_s name_dsc; + int status; + unsigned short result; + struct itmlst_3 itlst[2]; + + itlst[0].buflen = value_len; + itlst[0].itmcode = LNM$_STRING; + itlst[0].bufadr = value; + itlst[0].retlen = &result; + + itlst[1].buflen = 0; + itlst[1].itmcode = 0; + + name_dsc.dsc$w_length = strlen(logname); + name_dsc.dsc$a_pointer = (char *)logname; + name_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + name_dsc.dsc$b_class = DSC$K_CLASS_S; + + status = SYS$TRNLNM(&attr, &table_dsc, &name_dsc, 0, itlst); + + if ($VMS_STATUS_SUCCESS(status)) { + + /* Null terminate and return the string */ + /*--------------------------------------*/ + value[result] = '\0'; + } + + return status; +} + +/* How to simply create a logical name */ +static int sys_crelnm + (const char * logname, + const char * value) +{ + int ret_val; + const char * proc_table = "LNM$PROCESS_TABLE"; + struct dsc$descriptor_s proc_table_dsc; + struct dsc$descriptor_s logname_dsc; + struct itmlst_3 item_list[2]; + + proc_table_dsc.dsc$a_pointer = (char *) proc_table; + proc_table_dsc.dsc$w_length = strlen(proc_table); + proc_table_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + proc_table_dsc.dsc$b_class = DSC$K_CLASS_S; + + logname_dsc.dsc$a_pointer = (char *) logname; + logname_dsc.dsc$w_length = strlen(logname); + logname_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + logname_dsc.dsc$b_class = DSC$K_CLASS_S; + + item_list[0].buflen = strlen(value); + item_list[0].itmcode = LNM$_STRING; + item_list[0].bufadr = (char *)value; + item_list[0].retlen = NULL; + + item_list[1].buflen = 0; + item_list[1].itmcode = 0; + + ret_val = SYS$CRELNM(NULL, &proc_table_dsc, &logname_dsc, NULL, item_list); + + return ret_val; +} + + + /* Start of DECC RTL Feature handling */ + +/* +** Sets default value for a feature +*/ +#ifdef __VAX +static void set_feature_default(const char *name, const char *value) +{ + sys_crelnm(name, value); +} +#else +static void set_feature_default(const char *name, int value) +{ + int index; + + index = decc$feature_get_index(name); + + if (index > 0) + decc$feature_set_value (index, 0, value); +} +#endif + +static void set_features(void) +{ + int status; + char unix_shell_name[255]; + int use_unix_settings = 1; + + status = sys_trnlnm("GNV$UNIX_SHELL", + unix_shell_name, sizeof unix_shell_name -1); + if (!$VMS_STATUS_SUCCESS(status)) { + unix_shell_name[0] = 0; + use_unix_settings = 0; + } + + /* ACCESS should check ACLs or it is lying. */ + set_feature_default("DECC$ACL_ACCESS_CHECK", ENABLE); + + /* We always want the new parse style */ + set_feature_default ("DECC$ARGV_PARSE_STYLE" , ENABLE); + + + /* Unless we are in POSIX compliant mode, we want the old POSIX root + * enabled. + */ + set_feature_default("DECC$DISABLE_POSIX_ROOT", DISABLE); + + /* EFS charset, means UTF-8 support */ + /* VTF-7 support is controlled by a feature setting called UTF8 */ + set_feature_default ("DECC$EFS_CHARSET", ENABLE); + set_feature_default ("DECC$EFS_CASE_PRESERVE", ENABLE); + + /* Support timestamps when available */ + set_feature_default ("DECC$EFS_FILE_TIMESTAMPS", ENABLE); + + /* Cache environment variables - performance improvements */ + set_feature_default ("DECC$ENABLE_GETENV_CACHE", ENABLE); + + /* Start out with new file attribute inheritance */ +#ifdef __VAX + set_feature_default ("DECC$EXEC_FILEATTR_INHERITANCE", "2"); +#else + set_feature_default ("DECC$EXEC_FILEATTR_INHERITANCE", 2); +#endif + + /* Don't display trailing dot after files without type */ + set_feature_default ("DECC$READDIR_DROPDOTNOTYPE", ENABLE); + + /* For standard output channels buffer output until terminator */ + /* Gets rid of output logs with single character lines in them. */ + set_feature_default ("DECC$STDIO_CTX_EOL", ENABLE); + + /* Fix mv aa.bb aa */ + set_feature_default ("DECC$RENAME_NO_INHERIT", ENABLE); + + if (use_unix_settings) { + + /* POSIX requires that open files be able to be removed */ + set_feature_default ("DECC$ALLOW_REMOVE_OPEN_FILES", ENABLE); + + /* Default to outputting Unix filenames in VMS routines */ + set_feature_default ("DECC$FILENAME_UNIX_ONLY", ENABLE); + /* FILENAME_UNIX_ONLY Implicitly sets */ + /* decc$disable_to_vms_logname_translation */ + + set_feature_default ("DECC$FILE_PERMISSION_UNIX", ENABLE); + + set_feature_default ("DECC$FILE_SHARING", ENABLE); + + set_feature_default ("DECC$FILE_OWNER_UNIX", ENABLE); + set_feature_default ("DECC$POSIX_SEEK_STREAM_FILE", ENABLE); + + } else { + set_feature_default("DECC$FILENAME_UNIX_REPORT", ENABLE); + } + + /* When reporting Unix filenames, glob the same way */ + set_feature_default ("DECC$GLOB_UNIX_STYLE", ENABLE); + + /* The VMS version numbers on Unix filenames is incompatible with most */ + /* ported packages. */ + set_feature_default("DECC$FILENAME_UNIX_NO_VERSION", ENABLE); + + /* The VMS version numbers on Unix filenames is incompatible with most */ + /* ported packages. */ + set_feature_default("DECC$UNIX_PATH_BEFORE_LOGNAME", ENABLE); + + /* Set strtol to proper behavior */ + set_feature_default("DECC$STRTOL_ERANGE", ENABLE); + + /* Commented here to prevent future bugs: A program or user should */ + /* never ever enable DECC$POSIX_STYLE_UID. */ + /* It will probably break all code that accesses UIDs */ + /* do_not_set_default ("DECC$POSIX_STYLE_UID", TRUE); */ +} + + +/* Some boilerplate to force this to be a proper LIB$INITIALIZE section */ + +#pragma nostandard +#pragma extern_model save +#ifdef __VAX +#pragma extern_model strict_refdef "LIB$INITIALIZE" nowrt, long, nopic +#else +#pragma extern_model strict_refdef "LIB$INITIALIZE" nowrt, long +# if __INITIAL_POINTER_SIZE +# pragma __pointer_size __save +# pragma __pointer_size 32 +# else +# pragma __required_pointer_size __save +# pragma __required_pointer_size 32 +# endif +#endif +/* Set our contribution to the LIB$INITIALIZE array */ +void (* const iniarray[])(void) = {set_features, } ; +#ifndef __VAX +# if __INITIAL_POINTER_SIZE +# pragma __pointer_size __restore +# else +# pragma __required_pointer_size __restore +# endif +#endif + + +/* +** Force a reference to LIB$INITIALIZE to ensure it +** exists in the image. +*/ +int LIB$INITIALIZE(void); +#ifdef __DECC +#pragma extern_model strict_refdef +#endif + int lib_init_ref = (int) LIB$INITIALIZE; +#ifdef __DECC +#pragma extern_model restore +#pragma standard +#endif |