113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci#include "tool_setup.h" 2513498266Sopenharmony_ci 2613498266Sopenharmony_ci#ifdef __VMS 2713498266Sopenharmony_ci 2813498266Sopenharmony_ci#if defined(__DECC) && !defined(__VAX) && \ 2913498266Sopenharmony_ci defined(__CRTL_VER) && (__CRTL_VER >= 70301000) 3013498266Sopenharmony_ci#include <unixlib.h> 3113498266Sopenharmony_ci#endif 3213498266Sopenharmony_ci 3313498266Sopenharmony_ci#define ENABLE_CURLX_PRINTF 3413498266Sopenharmony_ci#include "curlx.h" 3513498266Sopenharmony_ci 3613498266Sopenharmony_ci#include "curlmsg_vms.h" 3713498266Sopenharmony_ci#include "tool_vms.h" 3813498266Sopenharmony_ci 3913498266Sopenharmony_ci#include "memdebug.h" /* keep this as LAST include */ 4013498266Sopenharmony_ci 4113498266Sopenharmony_civoid decc$__posix_exit(int __status); 4213498266Sopenharmony_civoid decc$exit(int __status); 4313498266Sopenharmony_ci 4413498266Sopenharmony_cistatic int vms_shell = -1; 4513498266Sopenharmony_ci 4613498266Sopenharmony_ci/* VMS has a DCL shell and also has Unix shells ported to it. 4713498266Sopenharmony_ci * When curl is running under a Unix shell, we want it to be as much 4813498266Sopenharmony_ci * like Unix as possible. 4913498266Sopenharmony_ci */ 5013498266Sopenharmony_ciint is_vms_shell(void) 5113498266Sopenharmony_ci{ 5213498266Sopenharmony_ci char *shell; 5313498266Sopenharmony_ci 5413498266Sopenharmony_ci /* Have we checked the shell yet? */ 5513498266Sopenharmony_ci if(vms_shell >= 0) 5613498266Sopenharmony_ci return vms_shell; 5713498266Sopenharmony_ci 5813498266Sopenharmony_ci shell = getenv("SHELL"); 5913498266Sopenharmony_ci 6013498266Sopenharmony_ci /* No shell, means DCL */ 6113498266Sopenharmony_ci if(!shell) { 6213498266Sopenharmony_ci vms_shell = 1; 6313498266Sopenharmony_ci return 1; 6413498266Sopenharmony_ci } 6513498266Sopenharmony_ci 6613498266Sopenharmony_ci /* Have to make sure some one did not set shell to DCL */ 6713498266Sopenharmony_ci if(strcmp(shell, "DCL") == 0) { 6813498266Sopenharmony_ci vms_shell = 1; 6913498266Sopenharmony_ci return 1; 7013498266Sopenharmony_ci } 7113498266Sopenharmony_ci 7213498266Sopenharmony_ci vms_shell = 0; 7313498266Sopenharmony_ci return 0; 7413498266Sopenharmony_ci} 7513498266Sopenharmony_ci 7613498266Sopenharmony_ci/* 7713498266Sopenharmony_ci * VMS has two exit() routines. When running under a Unix style shell, then 7813498266Sopenharmony_ci * Unix style and the __posix_exit() routine is used. 7913498266Sopenharmony_ci * 8013498266Sopenharmony_ci * When running under the DCL shell, then the VMS encoded codes and decc$exit() 8113498266Sopenharmony_ci * is used. 8213498266Sopenharmony_ci * 8313498266Sopenharmony_ci * We can not use exit() or return a code from main() because the actual 8413498266Sopenharmony_ci * routine called depends on both the compiler version, compile options, and 8513498266Sopenharmony_ci * feature macro settings, and one of the exit routines is hidden at compile 8613498266Sopenharmony_ci * time. 8713498266Sopenharmony_ci * 8813498266Sopenharmony_ci * Since we want Curl to work properly under the VMS DCL shell and Unix 8913498266Sopenharmony_ci * shells under VMS, this routine should compile correctly regardless of 9013498266Sopenharmony_ci * the settings. 9113498266Sopenharmony_ci */ 9213498266Sopenharmony_ci 9313498266Sopenharmony_civoid vms_special_exit(int code, int vms_show) 9413498266Sopenharmony_ci{ 9513498266Sopenharmony_ci int vms_code; 9613498266Sopenharmony_ci 9713498266Sopenharmony_ci /* The Posix exit mode is only available after VMS 7.0 */ 9813498266Sopenharmony_ci#if __CRTL_VER >= 70000000 9913498266Sopenharmony_ci if(is_vms_shell() == 0) { 10013498266Sopenharmony_ci decc$__posix_exit(code); 10113498266Sopenharmony_ci } 10213498266Sopenharmony_ci#endif 10313498266Sopenharmony_ci 10413498266Sopenharmony_ci if(code > CURL_LAST) { /* If CURL_LAST exceeded then */ 10513498266Sopenharmony_ci vms_code = CURL_LAST; /* curlmsg.h is out of sync. */ 10613498266Sopenharmony_ci } 10713498266Sopenharmony_ci else { 10813498266Sopenharmony_ci vms_code = vms_cond[code] | vms_show; 10913498266Sopenharmony_ci } 11013498266Sopenharmony_ci decc$exit(vms_code); 11113498266Sopenharmony_ci} 11213498266Sopenharmony_ci 11313498266Sopenharmony_ci#if defined(__DECC) && !defined(__VAX) && \ 11413498266Sopenharmony_ci defined(__CRTL_VER) && (__CRTL_VER >= 70301000) 11513498266Sopenharmony_ci 11613498266Sopenharmony_ci/* 11713498266Sopenharmony_ci * 2004-09-19 SMS. 11813498266Sopenharmony_ci * 11913498266Sopenharmony_ci * decc_init() 12013498266Sopenharmony_ci * 12113498266Sopenharmony_ci * On non-VAX systems, use LIB$INITIALIZE to set a collection of C 12213498266Sopenharmony_ci * RTL features without using the DECC$* logical name method, nor 12313498266Sopenharmony_ci * requiring the user to define the corresponding logical names. 12413498266Sopenharmony_ci */ 12513498266Sopenharmony_ci 12613498266Sopenharmony_ci/* Structure to hold a DECC$* feature name and its desired value. */ 12713498266Sopenharmony_cistruct decc_feat_t { 12813498266Sopenharmony_ci char *name; 12913498266Sopenharmony_ci int value; 13013498266Sopenharmony_ci}; 13113498266Sopenharmony_ci 13213498266Sopenharmony_ci/* Array of DECC$* feature names and their desired values. */ 13313498266Sopenharmony_cistatic const struct decc_feat_t decc_feat_array[] = { 13413498266Sopenharmony_ci /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */ 13513498266Sopenharmony_ci { "DECC$ARGV_PARSE_STYLE", 1 }, 13613498266Sopenharmony_ci /* Preserve case for file names on ODS5 disks. */ 13713498266Sopenharmony_ci { "DECC$EFS_CASE_PRESERVE", 1 }, 13813498266Sopenharmony_ci /* Enable multiple dots (and most characters) in ODS5 file names, 13913498266Sopenharmony_ci while preserving VMS-ness of ";version". */ 14013498266Sopenharmony_ci { "DECC$EFS_CHARSET", 1 }, 14113498266Sopenharmony_ci /* List terminator. */ 14213498266Sopenharmony_ci { (char *)NULL, 0 } 14313498266Sopenharmony_ci}; 14413498266Sopenharmony_ci 14513498266Sopenharmony_ci/* Flag to sense if decc_init() was called. */ 14613498266Sopenharmony_cistatic int decc_init_done = -1; 14713498266Sopenharmony_ci 14813498266Sopenharmony_ci/* LIB$INITIALIZE initialization function. */ 14913498266Sopenharmony_cistatic void decc_init(void) 15013498266Sopenharmony_ci{ 15113498266Sopenharmony_ci int feat_index; 15213498266Sopenharmony_ci int feat_value; 15313498266Sopenharmony_ci int feat_value_max; 15413498266Sopenharmony_ci int feat_value_min; 15513498266Sopenharmony_ci int i; 15613498266Sopenharmony_ci int sts; 15713498266Sopenharmony_ci 15813498266Sopenharmony_ci /* Set the global flag to indicate that LIB$INITIALIZE worked. */ 15913498266Sopenharmony_ci decc_init_done = 1; 16013498266Sopenharmony_ci 16113498266Sopenharmony_ci /* Loop through all items in the decc_feat_array[]. */ 16213498266Sopenharmony_ci for(i = 0; decc_feat_array[i].name != NULL; i++) { 16313498266Sopenharmony_ci 16413498266Sopenharmony_ci /* Get the feature index. */ 16513498266Sopenharmony_ci feat_index = decc$feature_get_index(decc_feat_array[i].name); 16613498266Sopenharmony_ci 16713498266Sopenharmony_ci if(feat_index >= 0) { 16813498266Sopenharmony_ci /* Valid item. Collect its properties. */ 16913498266Sopenharmony_ci feat_value = decc$feature_get_value(feat_index, 1); 17013498266Sopenharmony_ci feat_value_min = decc$feature_get_value(feat_index, 2); 17113498266Sopenharmony_ci feat_value_max = decc$feature_get_value(feat_index, 3); 17213498266Sopenharmony_ci 17313498266Sopenharmony_ci if((decc_feat_array[i].value >= feat_value_min) && 17413498266Sopenharmony_ci (decc_feat_array[i].value <= feat_value_max)) { 17513498266Sopenharmony_ci /* Valid value. Set it if necessary. */ 17613498266Sopenharmony_ci if(feat_value != decc_feat_array[i].value) { 17713498266Sopenharmony_ci sts = decc$feature_set_value(feat_index, 1, 17813498266Sopenharmony_ci decc_feat_array[i].value); 17913498266Sopenharmony_ci } 18013498266Sopenharmony_ci } 18113498266Sopenharmony_ci else { 18213498266Sopenharmony_ci /* Invalid DECC feature value. */ 18313498266Sopenharmony_ci printf(" INVALID DECC FEATURE VALUE, %d: %d <= %s <= %d.\n", 18413498266Sopenharmony_ci feat_value, 18513498266Sopenharmony_ci feat_value_min, decc_feat_array[i].name, feat_value_max); 18613498266Sopenharmony_ci } 18713498266Sopenharmony_ci } 18813498266Sopenharmony_ci else { 18913498266Sopenharmony_ci /* Invalid DECC feature name. */ 19013498266Sopenharmony_ci printf(" UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[i].name); 19113498266Sopenharmony_ci } 19213498266Sopenharmony_ci 19313498266Sopenharmony_ci } 19413498266Sopenharmony_ci} 19513498266Sopenharmony_ci 19613498266Sopenharmony_ci/* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */ 19713498266Sopenharmony_ci 19813498266Sopenharmony_ci#pragma nostandard 19913498266Sopenharmony_ci 20013498266Sopenharmony_ci/* Establish the LIB$INITIALIZE PSECTs, with proper alignment and 20113498266Sopenharmony_ci other attributes. Note that "nopic" is significant only on VAX. */ 20213498266Sopenharmony_ci#pragma extern_model save 20313498266Sopenharmony_ci#pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt 20413498266Sopenharmony_ciconst int spare[8] = {0}; 20513498266Sopenharmony_ci#pragma extern_model strict_refdef "LIB$INITIALIZE" 2, nopic, nowrt 20613498266Sopenharmony_civoid (*const x_decc_init)() = decc_init; 20713498266Sopenharmony_ci#pragma extern_model restore 20813498266Sopenharmony_ci 20913498266Sopenharmony_ci/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */ 21013498266Sopenharmony_ci#pragma extern_model save 21113498266Sopenharmony_ciint LIB$INITIALIZE(void); 21213498266Sopenharmony_ci#pragma extern_model strict_refdef 21313498266Sopenharmony_ciint dmy_lib$initialize = (int) LIB$INITIALIZE; 21413498266Sopenharmony_ci#pragma extern_model restore 21513498266Sopenharmony_ci 21613498266Sopenharmony_ci#pragma standard 21713498266Sopenharmony_ci 21813498266Sopenharmony_ci#endif /* __DECC && !__VAX && __CRTL_VER && __CRTL_VER >= 70301000 */ 21913498266Sopenharmony_ci 22013498266Sopenharmony_ci#endif /* __VMS */ 221