From: Micah Cowan Date: Fri, 25 Sep 2009 17:14:46 +0000 (-0700) Subject: Backed out changeset b49bb4258818 X-Git-Tag: v1.13~218 X-Git-Url: http://sjero.net/git/?p=wget;a=commitdiff_plain;h=b7cef9f642b9e8f4d89b3489e53893884b6fca9e Backed out changeset b49bb4258818 --- diff --git a/ChangeLog b/ChangeLog index 92d2d869..f1123529 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,16 +1,4 @@ -2009-09-24 Micah Cowan - - From Steven Schweda's description of his changes: - - * vms/vms.c: Moved to src/src.c. - - * vms/getopt.h: Copied from lib/getopt.in.h. - - * vms/alloca.h: Created (empty). - - * vms/stdint.h: Created (single #include ) - -2008-09-22 Micah Cowan +2009-09-22 Micah Cowan * configure.ac: Added "sleep" and "symlink" to AC_CHECK_FUNCS, removing the hard-coded definition of HAVE_SYMLINK. When running diff --git a/src/ChangeLog b/src/ChangeLog index d72cf7ef..2f3de8a0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,7 +1,5 @@ 2009-09-24 Micah Cowan - * vms.c: Moved from vms/vms.c. - * sysdep.h: Use proper prototypes for snprintf, vsnprintf (thanks to Steven Schweda). diff --git a/src/vms.c b/src/vms.c deleted file mode 100644 index 8104d137..00000000 --- a/src/vms.c +++ /dev/null @@ -1,1050 +0,0 @@ -/* - * VMS supplement for "wget". - * - *====================================================================== - * - * vms_init() - * - * On non-VAX systems, uses LIB$INITIALIZE to set a collection of C - * RTL features without using the DECC$* logical name method. - * - *---------------------------------------------------------------------- - * - * vms_arch() - * - * Returns (run-time) VMS architecture string. - * - *---------------------------------------------------------------------- - * - * vms_ver() - * - * Returns (run-time) VMS version string. - * - *---------------------------------------------------------------------- - * - * set_ods5_dest() - * - * Sets a global flag ("ods5_dest") according to the file system type - * of the destination device. - * - *---------------------------------------------------------------------- - * - * ods_conform() - * - * Simplifies a fancy URL-derived file name into an ODS2- or - * ODS5-compatible file name. - * - *---------------------------------------------------------------------- - * - * utime() - * - * VMS C RTL before V7.3 lacks utime(). In V7.3, utime() sets only - * the modified (revised) date, not the created date of a file. - * - * UNIX "ls -l" reports the modified time. VMS "DIRECTORY /DATE" - * reports the creation time. Reconciling these in FTP DIR reports - * is non-trivial. - * - * UNIX utime() sets revision and access times. VMS does not always - * maintain access times, so this utime() replacement sets the - * creation and revision times to the specified revision (or - * creation?) time. Any access time is ignored. - * - *---------------------------------------------------------------------- - * - * getpwuid() - * - * VMS C RTL before V7.0 lacks getpwuid(). - * - *---------------------------------------------------------------------- - * - */ - -#include "vms.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Use if available. Otherwise declare IOSB here. */ - -#if !defined( __VAX) && (__CRTL_VER >= 70000000) -#include -#else /* __CRTL_VER >= 70000000 */ -typedef struct _iosb { - unsigned short int iosb$w_status; /* Final I/O status */ - unsigned short int iosb$w_bcnt; /* 16-bit byte count */ - unsigned int iosb$l_dev_depend; /* 32-bit dev dependent */ - } IOSB; -#endif /* !defined( __VAX) && (__CRTL_VER >= 70000000) */ - -/* Ugly work-around for bad type in VAX . */ - -#ifdef __VAX -#define UWA (unsigned int) -#else /* def __VAX */ -#define UWA -#endif /* def __VAX */ - -#include "config.h" -#include "wget.h" -#include "utils.h" - -/*--------------------------------------------------------------------*/ - -/* Global storage. */ - -/* Flag for an ODS5 destination directory. */ - -int ods5_dest = -1; - -/* Flag to sense if vms_init() was called. */ - -int vms_init_done = -1; - -/*--------------------------------------------------------------------*/ - -#if !defined( __VAX) && (__CRTL_VER >= 70301000) - -/* vms_init() - - Uses LIB$INITIALIZE to set a collection of C RTL features without - requiring the user to define the corresponding logical names. -*/ - -/* Structure to hold a DECC$* feature name and its desired value. */ - -typedef struct - { - char *name; - int value; - } decc_feat_t; - -/* Array of DECC$* feature names and their desired values. */ - -decc_feat_t decc_feat_array[] = { - /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */ - { "DECC$ARGV_PARSE_STYLE", 1 }, - /* Preserve case for file names on ODS5 disks. */ - { "DECC$EFS_CASE_PRESERVE", 1 }, - /* Enable multiple dots (and most characters) in ODS5 file names, - while preserving VMS-ness of ";version". */ - { "DECC$EFS_CHARSET", 1 }, - /* List terminator. */ - { (char *)NULL, 0 } }; - -/* LIB$INITIALIZE initialization function. */ - -static void vms_init( void) -{ -int feat_index; -int feat_value; -int feat_value_max; -int feat_value_min; -int i; -int sts; - -/* Set the global flag to indicate that LIB$INITIALIZE worked. */ - -vms_init_done = 1; - -/* Loop through all items in the decc_feat_array[]. */ - -for (i = 0; decc_feat_array[ i].name != NULL; i++) - { - /* Get the feature index. */ - feat_index = decc$feature_get_index( decc_feat_array[ i].name); - if (feat_index >= 0) - { - /* Valid item. Collect its properties. */ - feat_value = decc$feature_get_value( feat_index, 1); - feat_value_min = decc$feature_get_value( feat_index, 2); - feat_value_max = decc$feature_get_value( feat_index, 3); - - if ((decc_feat_array[ i].value >= feat_value_min) && - (decc_feat_array[ i].value <= feat_value_max)) - { - /* Valid value. Set it if necessary. */ - if (feat_value != decc_feat_array[ i].value) - { - sts = decc$feature_set_value( feat_index, - 1, - decc_feat_array[ i].value); - } - } - else - { - /* Invalid DECC feature value. */ - printf( " INVALID DECC FEATURE VALUE, %d: %d <= %s <= %d.\n", - feat_value, - feat_value_min, decc_feat_array[ i].name, feat_value_max); - } - } - else - { - /* Invalid DECC feature name. */ - printf( " UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[ i].name); - } - } -} - -/* Get "vms_init()" into a valid, loaded LIB$INITIALIZE PSECT. */ - -#pragma nostandard - -/* Establish the LIB$INITIALIZE PSECTs, with proper alignment and - other attributes. Note that "nopic" is significant only on VAX. -*/ -#pragma extern_model save - -#pragma extern_model strict_refdef "LIB$INITIALIZE" 2, nopic, nowrt -void (*const x_vms_init)() = vms_init; - -#pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt -const int spare[ 8] = { 0 }; - -#pragma extern_model restore - -/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */ - -#pragma extern_model save -int lib$initialize(void); -#pragma extern_model strict_refdef -int dmy_lib$initialize = (int) lib$initialize; -#pragma extern_model restore - -#pragma standard - -#endif /* !defined( __VAX) && (__CRTL_VER >= 70301000) */ - -/*--------------------------------------------------------------------*/ - -/* vms_arch() - - Returns (run-time) VMS architecture string. -*/ - -char *vms_arch( void) -{ -#define ARCH_SIZE 15 - -static int sts = 0; -static char arch[ ARCH_SIZE+ 1] = "VAX"; /* Only VAX could fail. */ -unsigned short arch_len; - -struct dsc$descriptor_s arch_descr = - { ARCH_SIZE, DSC$K_DTYPE_T, DSC$K_CLASS_S, arch }; - -if (sts == 0) - { - sts = lib$getsyi( &SYI$_ARCH_NAME, 0, &arch_descr, &arch_len, 0, 0); - if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) - { - arch[ arch_len] = '\0'; - - /* Trim trailing spaces. */ - while ((arch_len > 0) && (arch[ arch_len- 1] == ' ')) - { - arch[ --arch_len] = '\0'; - } - } - } -return arch; -} - -/*--------------------------------------------------------------------*/ - -/* vms_vers() - - Returns (run-time) VMS version string. -*/ - -char *vms_vers( void) -{ -#define VERS_SIZE 8 - -static int sts = 0; -static char vers[ VERS_SIZE+ 1] = ""; -unsigned short vers_len; - -struct dsc$descriptor_s vers_descr = - { VERS_SIZE, DSC$K_DTYPE_T, DSC$K_CLASS_S, vers }; - -if (sts == 0) - { - sts = lib$getsyi( &SYI$_VERSION, 0, &vers_descr, &vers_len, 0, 0); - if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) - { - vers[ vers_len] = '\0'; - - /* Trim trailing spaces. */ - while ((vers_len > 0) && (vers[ vers_len- 1] == ' ')) - { - vers[ --vers_len] = '\0'; - } - } - } -return vers; -} - -/*--------------------------------------------------------------------*/ - -/* set_ods5_dest() - - Sets global "ods5_dest" according to the file system type of the - argument: 0 for ODS2, 1 for ODS5. (No change if other/unknown or - failure.) - - Return value: Status from sys$getdvi(). -*/ - -int set_ods5_dest( char *path) -{ -#ifdef DVI$C_ACP_F11V5 - -/* Should know about ODS5 file system. Do actual check. - (This should be non-VAX with __CRTL_VER >= 70200000.) -*/ - -struct dsc$descriptor_s dev_descr = - { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 }; - -int acp_code; -int sts; - -/* Load path argument into device descriptor. - Default to current default device. -*/ -if (path == NULL) - { - dev_descr.dsc$a_pointer = "SYS$DISK"; - } -else - { - dev_descr.dsc$a_pointer = path; - } -dev_descr.dsc$w_length = strlen( dev_descr.dsc$a_pointer); - -/* Get filesystem type code. - (Text results for this item code have been unreliable.) -*/ -sts = lib$getdvi( &((int) DVI$_ACPTYPE), - 0, - &dev_descr, - &acp_code, - 0, - 0); - -if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) - { - if (acp_code == DVI$C_ACP_F11V2) - { - ods5_dest = 0; - } - else if (acp_code == DVI$C_ACP_F11V5) - { - ods5_dest = 1; - } - } - -return sts; - -#else /* def DVI$C_ACP_F11V5 */ - -/* Too old for ODS5 file system. Do nothing. */ - -return STS$K_SUCCESS; - -#endif /* def DVI$C_ACP_F11V5 */ -} - -/*--------------------------------------------------------------------*/ - -/* ods2_conform() - - Replace ODS2-troublesome characters in the argument, overwriting the - original string. Replace "~" with "-", "@" with "$", and invalid - dots and other characters with "_". (Invalid dots are any in a - directory name, and all but the last in a file name.) - - Return value: path. (Someday this function could be written to leave - the original string unchanged, and to return a freshly allocated - string, possibly of a dfferent length.) - - 2005-02-23 SMS. - Changed to use char_prop[] look-up table, and to convert more invalid - characters to "_". -*/ - -static -char *ods2_conform( char *path) -{ -char *p; -char *prd; -char *prs; -char *prv; -unsigned char uchr; -unsigned char prop; - -/* Locate the last slash. */ -prs = rindex( path, '/'); -if (prs == NULL) - { - prs = path; - } - -/* Locate the last dot after the last slash. */ -prd = rindex( prs, '.'); -if (prd == NULL) - { - prd = prs; - } - -/* Locate the version (after the last slash and dot). */ -for (prv = prs+ strlen( prs) ; (--prv > prs) && isdigit( *prv); ); -if ((*prv != ';') || (*(prv- 1) == '^')) - { - prv = prs+ strlen( prs); - } - -for (p = path ; p < prv; p++) - { - prop = char_prop[ uchr = *p]; - if ((prop& 4)) - { /* Dot. */ - if (p < prd) - { /* Before last dot in name. */ - *p = '_'; /* Convert to "_". */ - } - } - else if ((prop& (32+ 16)) == 0) - { /* ODS2-invalid. */ - if (uchr == '~') - { - *p = '-'; /* Convert to "-". */ - } - else if (uchr == '@') - { - *p = '$'; /* Convert to "$". */ - } - else if (uchr != '/') /* Leave "/" as-is. */ - { - *p = '_'; /* Convert to "_". */ - } - } - } -return path; -} - -/*--------------------------------------------------------------------*/ - -/* ods_conform() - - Replace troublesome characters for the destination file system (ODS2 - or ODS5) with more legal characters. - - For ODS5, this is simply "?" -> "!" and "*" -> "#". - - For ODS2, see ods2_conform(). - - Return value: path. (Someday this function could be written to leave - the original string unchanged, and to return a freshly allocated - string, possibly of a dfferent length.) -*/ - -char *ods_conform( char *path) -{ -char *p; - -/* Replacements for invalid (printing) ODS5 characters. */ -#define ODS5_QUESTION '!' -#define ODS5_ASTERISK '#' - -if (ods5_dest <= 0) - { - /* Return ODS2-conformant file name. */ - return ods2_conform( path); - } -else - { - /* Return ODS5-conformant file name. ("?" -> "!", "*" -> "#".) */ - for (p = path; *p != '\0'; p++) - { - if (*p == '?') - { - *p = ODS5_QUESTION; - } - else if (*p == '*') - { - *p = ODS5_ASTERISK; - } - } - return path; - } -} - -/*--------------------------------------------------------------------*/ - -/* Wget-private utime() code. */ - -/* Use long name (NAML) structure only where available. - (This should be non-VAX with __CRTL_VER >= 70200000.) -*/ - -#ifdef NAML$C_BID - -/* Use long name (NAML) structure. */ - -#define FAB$L_NAMX fab$l_naml -#define NAMX NAML -#define NAMX$C_MAXRSS NAML$C_MAXRSS -#define NAMX$B_DEV naml$l_long_dev_size -#define NAMX$L_DEV naml$l_long_dev -#define NAMX$L_ESA naml$l_long_expand -#define NAMX$B_ESL naml$l_long_expand_size -#define NAMX$B_ESS naml$l_long_expand_alloc -#define NAMX$W_FID naml$w_fid -#define NAMX$L_RSA naml$l_long_result -#define NAMX$B_RSL naml$l_long_result_size -#define NAMX$B_RSS naml$l_long_result_alloc -#define CC$RMS_NAMX cc$rms_naml - -#else /* def NAML$C_BID */ - -/* Use short name (NAM) structure. */ - -#define FAB$L_NAMX fab$l_nam -#define NAMX NAM -#define NAMX$C_MAXRSS NAM$C_MAXRSS -#define NAMX$B_DEV nam$b_dev -#define NAMX$L_DEV nam$l_dev -#define NAMX$L_ESA nam$l_esa -#define NAMX$B_ESL nam$b_esl -#define NAMX$B_ESS nam$b_ess -#define NAMX$W_FID nam$w_fid -#define NAMX$L_RSA nam$l_rsa -#define NAMX$B_RSL nam$b_rsl -#define NAMX$B_RSS nam$b_rss -#define CC$RMS_NAMX cc$rms_nam - -#endif /* def NAML$C_BID */ - -/*--------------------------------------------------------------------*/ - -/* Wget-private utime() code. */ - -/* Action routine for decc$to_vms(), in utime(). */ - -char vms_path[ NAMX$C_MAXRSS+ 1]; - -int set_vms_name( char *name, int type) -{ - strncpy( vms_path, name, NAMX$C_MAXRSS); - vms_path[ NAMX$C_MAXRSS] = '\0'; - return 1; -} - -/*--------------------------------------------------------------------*/ - -/* utime() replacement. */ - -int utime( const char *path, const struct utimbuf *times) -{ -time_t utc_unsigned; - -int chan, i; -int sts, sts2; - -unsigned short int vms_num_vec_time[ 7]; -static unsigned int vms_abs_time[ 2]; -struct tm *tms; -struct _iosb iosb_q; - -/* QIOW item list used to set creation and revision dates. */ - -struct atrdef ut_atr[ 3] = { - {sizeof( vms_abs_time), ATR$C_CREDATE, UWA vms_abs_time}, - {sizeof( vms_abs_time), ATR$C_REVDATE, UWA vms_abs_time}, - {0,0,0}}; - -/* Various RMS structures used for file access. */ - -struct FAB ut_fab = cc$rms_fab; -struct RAB ut_rab = cc$rms_rab; -struct NAMX ut_namx = CC$RMS_NAMX; -static struct fibdef ut_fib; - -/* Device and file name buffers and their descriptors. */ - -static char dev_namx[ NAMX$C_MAXRSS+ 1]; -char esa_namx[ NAMX$C_MAXRSS+ 1]; -char rsa_namx[ NAMX$C_MAXRSS+ 1]; - -struct dsc$descriptor dev_dsc = - {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, dev_namx}; - -struct dsc$descriptor fib_dsc = - {sizeof( ut_fib), DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *) &ut_fib}; - -/* "wget" provides a UNIX-like path name. With "-O", a user may provide - a VMS-like path name. If a slash is found in the name, assume that - it's UNIX-like, and convert it to VMS form. Otherwise, use it as-is. -*/ - -if (strchr( path, '/') != NULL) - { - sts = decc$to_vms( path, set_vms_name, 0, 0); - path = vms_path; - } - -/* Install the VMS file specification into the FAB. */ - -ut_fab.fab$l_fna = (char *) path; -ut_fab.fab$b_fns = (unsigned char) strlen( path); - -ut_fab.fab$l_dna = ""; -ut_fab.fab$b_dns = 0; - -/* Point the FAB to the NAMX. */ - -ut_fab.FAB$L_NAMX = &ut_namx; - -/* Install the name buffers into the NAM. */ - -ut_namx.NAMX$L_ESA = esa_namx; -ut_namx.NAMX$B_ESL = 0; -ut_namx.NAMX$B_ESS = sizeof( esa_namx)- 1; - -ut_namx.NAMX$L_RSA = rsa_namx; -ut_namx.NAMX$B_RSL = 0; -ut_namx.NAMX$B_RSS = sizeof( rsa_namx)- 1; - -/* Convert the modification time (UTC time_t) to local "tm" time. */ - -tms = localtime( &(times-> modtime)); - -/* Move (translate) "tm" structure local time to VMS vector time. */ - -if (tms != NULL) - { - vms_num_vec_time[ 0] = tms-> tm_year+ 1900; - vms_num_vec_time[ 1] = tms-> tm_mon+ 1; - vms_num_vec_time[ 2] = tms-> tm_mday; - vms_num_vec_time[ 3] = tms-> tm_hour; - vms_num_vec_time[ 4] = tms-> tm_min; - vms_num_vec_time[ 5] = tms-> tm_sec; - vms_num_vec_time[ 6] = 0; /* centiseconds */ - -/* Convert VMS vector time to VMS absolute time (quadword). */ - - sts = lib$cvt_vectim( vms_num_vec_time, vms_abs_time); - - if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) - { -/* Parse the file specification. */ - - sts = sys$parse( &ut_fab, 0, 0); - - if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) - { -/* Locate the file. (Gets the FID.) */ - - sts = sys$search( &ut_fab, 0, 0); - - if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) - { -/* Form the device name descriptor. */ - - dev_dsc.dsc$w_length = ut_namx.NAMX$B_DEV; - dev_dsc.dsc$a_pointer = (char *) ut_namx.NAMX$L_DEV; - -/* Assign a channel to the disk device. */ - - sts = sys$assign( &dev_dsc, &chan, 0, 0); - - if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) - { -/* Move the FID (and not the DID) into the FIB. */ - - memset( (void *) &ut_fib, 0, sizeof( ut_fib)); - - for (i = 0; i < 3; i++) - { - ut_fib.fib$w_fid[ i] = ut_namx.NAMX$W_FID[ i]; - ut_fib.fib$w_did[ i] = 0; - } - -/* Prevent this QIOW from setting the revision time to now. */ - - ut_fib.fib$l_acctl = FIB$M_NORECORD; - -/* Set the file dates. */ - - sts = sys$qiow( 0, - chan, - IO$_MODIFY, - &iosb_q, - 0, - 0, - &fib_dsc, - 0, - 0, - 0, - ut_atr, - 0); - - if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) - { - sts = iosb_q.iosb$w_status; - } - sts2 = sys$dassgn( chan); - - if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) - { - sts = sts2; - } - } - } - } - } - } - -/* Convert successful VMS status to zero = success status. - If failure, set errno and vaxc$errno, and return -1 = failure status. -*/ - -if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) - { - sts = 0; - } -else - { - errno = EVMSERR; - vaxc$errno = sts; - sts = -1; - } - -return sts; -} - -/*--------------------------------------------------------------------*/ - -/* 2005-04-14 SMS. - * - * vms_init_diag(). - * - * Get Wget debug option value. - */ - -int vms_init_diag( void) -{ -#ifdef ENABLE_DEBUG -return (opt.debug > 0); -#else /* def ENABLE_DEBUG */ -return 0; -#endif /* def ENABLE_DEBUG */ -} - -/*--------------------------------------------------------------------*/ - -/* 2004-11-23 SMS. - * - * get_rms_defaults(). - * - * Get user-specified values from (DCL) SET RMS_DEFAULT. FAB/RAB - * items of particular interest are: - * - * fab$w_deq default extension quantity (blocks) (write). - * rab$b_mbc multi-block count. - * rab$b_mbf multi-buffer count (used with rah and wbh). - */ - -/* Default RMS parameter values. */ - -#define RMS_DEQ_DEFAULT 16384 /* About 1/4 the max (65535 blocks). */ -#define RMS_MBC_DEFAULT 127 /* The max, */ -#define RMS_MBF_DEFAULT 2 /* Enough to enable rah and wbh. */ - -/* GETJPI item descriptor structure. */ -typedef struct - { - short buf_len; - short itm_cod; - void *buf; - int *ret_len; - } jpi_item_t; - -/* Durable storage */ - -static int rms_defaults_known = 0; - -/* JPI item buffers. */ -static unsigned short rms_ext; -static char rms_mbc; -static unsigned char rms_mbf; - -/* Active RMS item values. */ -unsigned short rms_ext_active; -char rms_mbc_active; -unsigned char rms_mbf_active; - -/* GETJPI item lengths. */ -static int rms_ext_len; /* Should come back 2. */ -static int rms_mbc_len; /* Should come back 1. */ -static int rms_mbf_len; /* Should come back 1. */ - -/* Desperation attempts to define unknown macros. Probably doomed. - * If these get used, expect sys$getjpiw() to return %x00000014 = - * %SYSTEM-F-BADPARAM, bad parameter value. - * They keep compilers with old header files quiet, though. - */ -#ifndef JPI$_RMS_EXTEND_SIZE -# define JPI$_RMS_EXTEND_SIZE 542 -#endif /* ndef JPI$_RMS_EXTEND_SIZE */ - -#ifndef JPI$_RMS_DFMBC -# define JPI$_RMS_DFMBC 535 -#endif /* ndef JPI$_RMS_DFMBC */ - -#ifndef JPI$_RMS_DFMBFSDK -# define JPI$_RMS_DFMBFSDK 536 -#endif /* ndef JPI$_RMS_DFMBFSDK */ - -/* GETJPI item descriptor set. */ - -struct - { - jpi_item_t rms_ext_itm; - jpi_item_t rms_mbc_itm; - jpi_item_t rms_mbf_itm; - int term; - } jpi_itm_lst = - { { 2, JPI$_RMS_EXTEND_SIZE, &rms_ext, &rms_ext_len }, - { 1, JPI$_RMS_DFMBC, &rms_mbc, &rms_mbc_len }, - { 1, JPI$_RMS_DFMBFSDK, &rms_mbf, &rms_mbf_len }, - 0 - }; - -int get_rms_defaults() -{ -int sts; - -/* Get process RMS_DEFAULT values. */ - -sts = sys$getjpiw( 0, 0, 0, &jpi_itm_lst, 0, 0, 0); -if ((sts& STS$M_SEVERITY) != STS$M_SUCCESS) - { - /* Failed. Don't try again. */ - rms_defaults_known = -1; - } -else - { - /* Fine, but don't come back. */ - rms_defaults_known = 1; - } - -/* Limit the active values according to the RMS_DEFAULT values. */ - -if (rms_defaults_known > 0) - { - /* Set the default values. */ - - rms_ext_active = RMS_DEQ_DEFAULT; - rms_mbc_active = RMS_MBC_DEFAULT; - rms_mbf_active = RMS_MBF_DEFAULT; - - /* Default extend quantity. Use the user value, if set. */ - if (rms_ext > 0) - { - rms_ext_active = rms_ext; - } - - /* Default multi-block count. Use the user value, if set. */ - if (rms_mbc > 0) - { - rms_mbc_active = rms_mbc; - } - - /* Default multi-buffer count. Use the user value, if set. */ - if (rms_mbf > 0) - { - rms_mbf_active = rms_mbf; - } - } - -if (vms_init_diag() > 0) - { - fprintf( stderr, - "Get RMS defaults. getjpi sts = %%x%08x.\n", - sts); - - if (rms_defaults_known > 0) - { - fprintf( stderr, - " Default: deq = %6d, mbc = %3d, mbf = %3d.\n", - rms_ext, rms_mbc, rms_mbf); - } - } -return sts; -} - -/*--------------------------------------------------------------------*/ - -/* 2004-11-23 SMS. - * - * acc_cb(), access callback function for DEC C [f]open(). - * - * Set some RMS FAB/RAB items, with consideration of user-specified - * values from (DCL) SET RMS_DEFAULT. Items of particular interest are: - * - * fab$w_deq default extension quantity (blocks). - * rab$b_mbc multi-block count. - * rab$b_mbf multi-buffer count (used with rah and wbh). - * - * See also the FOP* macros in OSDEP.H. Currently, no notice is - * taken of the caller-ID value, but options could be set differently - * for read versus write access. (I assume that specifying fab$w_deq, - * for example, for a read-only file has no ill effects.) - */ - -/* acc_cb() */ - -int acc_cb( int *id_arg, struct FAB *fab, struct RAB *rab) -{ -int sts; - -/* Get process RMS_DEFAULT values, if not already done. */ -if (rms_defaults_known == 0) - { - get_rms_defaults(); - } - -/* If RMS_DEFAULT (and adjusted active) values are available, then set - * the FAB/RAB parameters. If RMS_DEFAULT values are not available, - * suffer with the default parameters. - */ -if (rms_defaults_known > 0) - { - /* Set the FAB/RAB parameters accordingly. */ - fab-> fab$w_deq = rms_ext_active; - rab-> rab$b_mbc = rms_mbc_active; - rab-> rab$b_mbf = rms_mbf_active; - - /* Truncate at EOF on close, as we'll probably over-extend. */ - fab-> fab$v_tef = 1; - - /* If using multiple buffers, enable read-ahead and write-behind. */ - if (rms_mbf_active > 1) - { - rab-> rab$v_rah = 1; - rab-> rab$v_wbh = 1; - } - - if (vms_init_diag() > 0) - { - fprintf( stderr, - "Open callback. ID = %d, deq = %6d, mbc = %3d, mbf = %3d.\n", - *id_arg, fab-> fab$w_deq, rab-> rab$b_mbc, rab-> rab$b_mbf); - } - } - -/* Declare success. */ -return 0; -} - -/*--------------------------------------------------------------------*/ - -/* Added J.Lauret 05-Dec-1999 . Copied from Mosaic distribution */ - -/* - * Here is a replacement for getpwuid for VMS. It returns pointers - * to userid (*pw_name) and owner (*pw_gecos) only. Other fields - * may be added later. - * Note that sys$getuai returns owner as a counted string. - */ - -#if __CRTL_VER < 70000000 - -#include - -static struct passwd vms_passwd; -static char vms_userid[16]; -static char vms_owner[40]; - -struct passwd *getpwuid() -{ -struct dsc$descriptor_s -{ - unsigned short dsc$w_length; - unsigned char dsc$b_dtype; - unsigned char dsc$b_class; - char *dsc$a_pointer; -} user_desc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL}; - - char *t_userid, owner[40]; - int status, length; - struct { - short buffer_length; - short item_code; - int buffer_address; - int return_length_address; - int terminator; - } itmlst; - -#ifdef __GNUC__ - (int)t_userid = cuserid((char *) NULL); -#else - t_userid = cuserid((char *) NULL); -#endif /* GNU C is strange, GEC */ - user_desc.dsc$w_length = strlen(t_userid); - user_desc.dsc$a_pointer = t_userid; - itmlst.buffer_length = sizeof(owner); - itmlst.item_code = UAI$_OWNER; - itmlst.buffer_address = (int)owner; - itmlst.return_length_address = (int)&length; - itmlst.terminator = 0; - status = sys$getuai(0, 0, &user_desc, &itmlst, 0, 0, 0); - if ((stats& STS$M_SEVERITY) == STS$K_SUCCESS) { - length = (int)owner[0]; - owner[length+1] = '\0'; - strcpy(vms_userid, t_userid); - strcpy(vms_owner, &owner[1]); - } else { - vms_userid[0] = '\0'; - vms_owner[0] = '\0'; - } - vms_passwd.pw_name = vms_userid; - vms_passwd.pw_gecos = vms_owner; - return (&vms_passwd); -} - -/* Approximate localtime_r as best we can in its absence. */ -struct tm * -localtime_r (t, tp) - const time_t *t; - struct tm *tp; -{ - struct tm *l = localtime (t); - if (! l) - return 0; - *tp = *l; - return tp; -} - -#endif /* __CRTL_VER < 70000000 */ - diff --git a/vms/alloca.h b/vms/alloca.h deleted file mode 100644 index e69de29b..00000000 diff --git a/vms/getopt.h b/vms/getopt.h deleted file mode 100644 index 6c08a479..00000000 --- a/vms/getopt.h +++ /dev/null @@ -1,226 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, - 1999, 2001, 2003, 2004, 2005, 2006, 2007, 2009 Free Software - Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _GETOPT_H - -#ifndef __need_getopt -# define _GETOPT_H 1 -#endif - -/* Standalone applications should #define __GETOPT_PREFIX to an - identifier that prefixes the external functions and variables - defined in this header. When this happens, include the - headers that might declare getopt so that they will not cause - confusion if included after this file. Then systematically rename - identifiers so that they do not collide with the system functions - and variables. Renaming avoids problems with some compilers and - linkers. */ -#if defined __GETOPT_PREFIX && !defined __need_getopt -# include -# include -# include -# undef __need_getopt -# undef getopt -# undef getopt_long -# undef getopt_long_only -# undef optarg -# undef opterr -# undef optind -# undef optopt -# define __GETOPT_CONCAT(x, y) x ## y -# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) -# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y) -# define getopt __GETOPT_ID (getopt) -# define getopt_long __GETOPT_ID (getopt_long) -# define getopt_long_only __GETOPT_ID (getopt_long_only) -# define optarg __GETOPT_ID (optarg) -# define opterr __GETOPT_ID (opterr) -# define optind __GETOPT_ID (optind) -# define optopt __GETOPT_ID (optopt) -#endif - -/* Standalone applications get correct prototypes for getopt_long and - getopt_long_only; they declare "char **argv". libc uses prototypes - with "char *const *argv" that are incorrect because getopt_long and - getopt_long_only can permute argv; this is required for backward - compatibility (e.g., for LSB 2.0.1). - - This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt', - but it caused redefinition warnings if both unistd.h and getopt.h were - included, since unistd.h includes getopt.h having previously defined - __need_getopt. - - The only place where __getopt_argv_const is used is in definitions - of getopt_long and getopt_long_only below, but these are visible - only if __need_getopt is not defined, so it is quite safe to rewrite - the conditional as follows: -*/ -#if !defined __need_getopt -# if defined __GETOPT_PREFIX -# define __getopt_argv_const /* empty */ -# else -# define __getopt_argv_const const -# endif -#endif - -/* If __GNU_LIBRARY__ is not already defined, either we are being used - standalone, or this is the first header included in the source file. - If we are being used with glibc, we need to include , but - that does not exist if we are standalone. So: if __GNU_LIBRARY__ is - not defined, include , which will pull in for us - if it's from glibc. (Why ctype.h? It's guaranteed to exist and it - doesn't flood the namespace with stuff the way some other headers do.) */ -#if !defined __GNU_LIBRARY__ -# include -#endif - -#ifndef __THROW -# ifndef __GNUC_PREREQ -# define __GNUC_PREREQ(maj, min) (0) -# endif -# if defined __cplusplus && __GNUC_PREREQ (2,8) -# define __THROW throw () -# else -# define __THROW -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -#ifndef __need_getopt -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ - const char *name; - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -# define no_argument 0 -# define required_argument 1 -# define optional_argument 2 -#endif /* need getopt */ - - -/* Get definitions and prototypes for functions to process the - arguments in ARGV (ARGC of them, minus the program name) for - options given in OPTS. - - Return the option character from OPTS just read. Return -1 when - there are no more options. For unrecognized options, or options - missing arguments, `optopt' is set to the option letter, and '?' is - returned. - - The OPTS string is a list of characters which are recognized option - letters, optionally followed by colons, specifying that that letter - takes an argument, to be placed in `optarg'. - - If a letter in OPTS is followed by two colons, its argument is - optional. This behavior is specific to the GNU `getopt'. - - The argument `--' causes premature termination of argument - scanning, explicitly telling `getopt' that there are no more - options. - - If OPTS begins with `-', then non-option arguments are treated as - arguments to the option '\1'. This behavior is specific to the GNU - `getopt'. If OPTS begins with `+', or POSIXLY_CORRECT is set in - the environment, then do not permute arguments. */ - -extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) - __THROW; - -#ifndef __need_getopt -extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW; -extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW; - -#endif - -#ifdef __cplusplus -} -#endif - -/* Make sure we later can get all the definitions and declarations. */ -#undef __need_getopt - -#endif /* getopt.h */ diff --git a/vms/stdint.h b/vms/stdint.h deleted file mode 100644 index 8049f02f..00000000 --- a/vms/stdint.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/vms/vms.c b/vms/vms.c new file mode 100644 index 00000000..8104d137 --- /dev/null +++ b/vms/vms.c @@ -0,0 +1,1050 @@ +/* + * VMS supplement for "wget". + * + *====================================================================== + * + * vms_init() + * + * On non-VAX systems, uses LIB$INITIALIZE to set a collection of C + * RTL features without using the DECC$* logical name method. + * + *---------------------------------------------------------------------- + * + * vms_arch() + * + * Returns (run-time) VMS architecture string. + * + *---------------------------------------------------------------------- + * + * vms_ver() + * + * Returns (run-time) VMS version string. + * + *---------------------------------------------------------------------- + * + * set_ods5_dest() + * + * Sets a global flag ("ods5_dest") according to the file system type + * of the destination device. + * + *---------------------------------------------------------------------- + * + * ods_conform() + * + * Simplifies a fancy URL-derived file name into an ODS2- or + * ODS5-compatible file name. + * + *---------------------------------------------------------------------- + * + * utime() + * + * VMS C RTL before V7.3 lacks utime(). In V7.3, utime() sets only + * the modified (revised) date, not the created date of a file. + * + * UNIX "ls -l" reports the modified time. VMS "DIRECTORY /DATE" + * reports the creation time. Reconciling these in FTP DIR reports + * is non-trivial. + * + * UNIX utime() sets revision and access times. VMS does not always + * maintain access times, so this utime() replacement sets the + * creation and revision times to the specified revision (or + * creation?) time. Any access time is ignored. + * + *---------------------------------------------------------------------- + * + * getpwuid() + * + * VMS C RTL before V7.0 lacks getpwuid(). + * + *---------------------------------------------------------------------- + * + */ + +#include "vms.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Use if available. Otherwise declare IOSB here. */ + +#if !defined( __VAX) && (__CRTL_VER >= 70000000) +#include +#else /* __CRTL_VER >= 70000000 */ +typedef struct _iosb { + unsigned short int iosb$w_status; /* Final I/O status */ + unsigned short int iosb$w_bcnt; /* 16-bit byte count */ + unsigned int iosb$l_dev_depend; /* 32-bit dev dependent */ + } IOSB; +#endif /* !defined( __VAX) && (__CRTL_VER >= 70000000) */ + +/* Ugly work-around for bad type in VAX . */ + +#ifdef __VAX +#define UWA (unsigned int) +#else /* def __VAX */ +#define UWA +#endif /* def __VAX */ + +#include "config.h" +#include "wget.h" +#include "utils.h" + +/*--------------------------------------------------------------------*/ + +/* Global storage. */ + +/* Flag for an ODS5 destination directory. */ + +int ods5_dest = -1; + +/* Flag to sense if vms_init() was called. */ + +int vms_init_done = -1; + +/*--------------------------------------------------------------------*/ + +#if !defined( __VAX) && (__CRTL_VER >= 70301000) + +/* vms_init() + + Uses LIB$INITIALIZE to set a collection of C RTL features without + requiring the user to define the corresponding logical names. +*/ + +/* Structure to hold a DECC$* feature name and its desired value. */ + +typedef struct + { + char *name; + int value; + } decc_feat_t; + +/* Array of DECC$* feature names and their desired values. */ + +decc_feat_t decc_feat_array[] = { + /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */ + { "DECC$ARGV_PARSE_STYLE", 1 }, + /* Preserve case for file names on ODS5 disks. */ + { "DECC$EFS_CASE_PRESERVE", 1 }, + /* Enable multiple dots (and most characters) in ODS5 file names, + while preserving VMS-ness of ";version". */ + { "DECC$EFS_CHARSET", 1 }, + /* List terminator. */ + { (char *)NULL, 0 } }; + +/* LIB$INITIALIZE initialization function. */ + +static void vms_init( void) +{ +int feat_index; +int feat_value; +int feat_value_max; +int feat_value_min; +int i; +int sts; + +/* Set the global flag to indicate that LIB$INITIALIZE worked. */ + +vms_init_done = 1; + +/* Loop through all items in the decc_feat_array[]. */ + +for (i = 0; decc_feat_array[ i].name != NULL; i++) + { + /* Get the feature index. */ + feat_index = decc$feature_get_index( decc_feat_array[ i].name); + if (feat_index >= 0) + { + /* Valid item. Collect its properties. */ + feat_value = decc$feature_get_value( feat_index, 1); + feat_value_min = decc$feature_get_value( feat_index, 2); + feat_value_max = decc$feature_get_value( feat_index, 3); + + if ((decc_feat_array[ i].value >= feat_value_min) && + (decc_feat_array[ i].value <= feat_value_max)) + { + /* Valid value. Set it if necessary. */ + if (feat_value != decc_feat_array[ i].value) + { + sts = decc$feature_set_value( feat_index, + 1, + decc_feat_array[ i].value); + } + } + else + { + /* Invalid DECC feature value. */ + printf( " INVALID DECC FEATURE VALUE, %d: %d <= %s <= %d.\n", + feat_value, + feat_value_min, decc_feat_array[ i].name, feat_value_max); + } + } + else + { + /* Invalid DECC feature name. */ + printf( " UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[ i].name); + } + } +} + +/* Get "vms_init()" into a valid, loaded LIB$INITIALIZE PSECT. */ + +#pragma nostandard + +/* Establish the LIB$INITIALIZE PSECTs, with proper alignment and + other attributes. Note that "nopic" is significant only on VAX. +*/ +#pragma extern_model save + +#pragma extern_model strict_refdef "LIB$INITIALIZE" 2, nopic, nowrt +void (*const x_vms_init)() = vms_init; + +#pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt +const int spare[ 8] = { 0 }; + +#pragma extern_model restore + +/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */ + +#pragma extern_model save +int lib$initialize(void); +#pragma extern_model strict_refdef +int dmy_lib$initialize = (int) lib$initialize; +#pragma extern_model restore + +#pragma standard + +#endif /* !defined( __VAX) && (__CRTL_VER >= 70301000) */ + +/*--------------------------------------------------------------------*/ + +/* vms_arch() + + Returns (run-time) VMS architecture string. +*/ + +char *vms_arch( void) +{ +#define ARCH_SIZE 15 + +static int sts = 0; +static char arch[ ARCH_SIZE+ 1] = "VAX"; /* Only VAX could fail. */ +unsigned short arch_len; + +struct dsc$descriptor_s arch_descr = + { ARCH_SIZE, DSC$K_DTYPE_T, DSC$K_CLASS_S, arch }; + +if (sts == 0) + { + sts = lib$getsyi( &SYI$_ARCH_NAME, 0, &arch_descr, &arch_len, 0, 0); + if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) + { + arch[ arch_len] = '\0'; + + /* Trim trailing spaces. */ + while ((arch_len > 0) && (arch[ arch_len- 1] == ' ')) + { + arch[ --arch_len] = '\0'; + } + } + } +return arch; +} + +/*--------------------------------------------------------------------*/ + +/* vms_vers() + + Returns (run-time) VMS version string. +*/ + +char *vms_vers( void) +{ +#define VERS_SIZE 8 + +static int sts = 0; +static char vers[ VERS_SIZE+ 1] = ""; +unsigned short vers_len; + +struct dsc$descriptor_s vers_descr = + { VERS_SIZE, DSC$K_DTYPE_T, DSC$K_CLASS_S, vers }; + +if (sts == 0) + { + sts = lib$getsyi( &SYI$_VERSION, 0, &vers_descr, &vers_len, 0, 0); + if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) + { + vers[ vers_len] = '\0'; + + /* Trim trailing spaces. */ + while ((vers_len > 0) && (vers[ vers_len- 1] == ' ')) + { + vers[ --vers_len] = '\0'; + } + } + } +return vers; +} + +/*--------------------------------------------------------------------*/ + +/* set_ods5_dest() + + Sets global "ods5_dest" according to the file system type of the + argument: 0 for ODS2, 1 for ODS5. (No change if other/unknown or + failure.) + + Return value: Status from sys$getdvi(). +*/ + +int set_ods5_dest( char *path) +{ +#ifdef DVI$C_ACP_F11V5 + +/* Should know about ODS5 file system. Do actual check. + (This should be non-VAX with __CRTL_VER >= 70200000.) +*/ + +struct dsc$descriptor_s dev_descr = + { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 }; + +int acp_code; +int sts; + +/* Load path argument into device descriptor. + Default to current default device. +*/ +if (path == NULL) + { + dev_descr.dsc$a_pointer = "SYS$DISK"; + } +else + { + dev_descr.dsc$a_pointer = path; + } +dev_descr.dsc$w_length = strlen( dev_descr.dsc$a_pointer); + +/* Get filesystem type code. + (Text results for this item code have been unreliable.) +*/ +sts = lib$getdvi( &((int) DVI$_ACPTYPE), + 0, + &dev_descr, + &acp_code, + 0, + 0); + +if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) + { + if (acp_code == DVI$C_ACP_F11V2) + { + ods5_dest = 0; + } + else if (acp_code == DVI$C_ACP_F11V5) + { + ods5_dest = 1; + } + } + +return sts; + +#else /* def DVI$C_ACP_F11V5 */ + +/* Too old for ODS5 file system. Do nothing. */ + +return STS$K_SUCCESS; + +#endif /* def DVI$C_ACP_F11V5 */ +} + +/*--------------------------------------------------------------------*/ + +/* ods2_conform() + + Replace ODS2-troublesome characters in the argument, overwriting the + original string. Replace "~" with "-", "@" with "$", and invalid + dots and other characters with "_". (Invalid dots are any in a + directory name, and all but the last in a file name.) + + Return value: path. (Someday this function could be written to leave + the original string unchanged, and to return a freshly allocated + string, possibly of a dfferent length.) + + 2005-02-23 SMS. + Changed to use char_prop[] look-up table, and to convert more invalid + characters to "_". +*/ + +static +char *ods2_conform( char *path) +{ +char *p; +char *prd; +char *prs; +char *prv; +unsigned char uchr; +unsigned char prop; + +/* Locate the last slash. */ +prs = rindex( path, '/'); +if (prs == NULL) + { + prs = path; + } + +/* Locate the last dot after the last slash. */ +prd = rindex( prs, '.'); +if (prd == NULL) + { + prd = prs; + } + +/* Locate the version (after the last slash and dot). */ +for (prv = prs+ strlen( prs) ; (--prv > prs) && isdigit( *prv); ); +if ((*prv != ';') || (*(prv- 1) == '^')) + { + prv = prs+ strlen( prs); + } + +for (p = path ; p < prv; p++) + { + prop = char_prop[ uchr = *p]; + if ((prop& 4)) + { /* Dot. */ + if (p < prd) + { /* Before last dot in name. */ + *p = '_'; /* Convert to "_". */ + } + } + else if ((prop& (32+ 16)) == 0) + { /* ODS2-invalid. */ + if (uchr == '~') + { + *p = '-'; /* Convert to "-". */ + } + else if (uchr == '@') + { + *p = '$'; /* Convert to "$". */ + } + else if (uchr != '/') /* Leave "/" as-is. */ + { + *p = '_'; /* Convert to "_". */ + } + } + } +return path; +} + +/*--------------------------------------------------------------------*/ + +/* ods_conform() + + Replace troublesome characters for the destination file system (ODS2 + or ODS5) with more legal characters. + + For ODS5, this is simply "?" -> "!" and "*" -> "#". + + For ODS2, see ods2_conform(). + + Return value: path. (Someday this function could be written to leave + the original string unchanged, and to return a freshly allocated + string, possibly of a dfferent length.) +*/ + +char *ods_conform( char *path) +{ +char *p; + +/* Replacements for invalid (printing) ODS5 characters. */ +#define ODS5_QUESTION '!' +#define ODS5_ASTERISK '#' + +if (ods5_dest <= 0) + { + /* Return ODS2-conformant file name. */ + return ods2_conform( path); + } +else + { + /* Return ODS5-conformant file name. ("?" -> "!", "*" -> "#".) */ + for (p = path; *p != '\0'; p++) + { + if (*p == '?') + { + *p = ODS5_QUESTION; + } + else if (*p == '*') + { + *p = ODS5_ASTERISK; + } + } + return path; + } +} + +/*--------------------------------------------------------------------*/ + +/* Wget-private utime() code. */ + +/* Use long name (NAML) structure only where available. + (This should be non-VAX with __CRTL_VER >= 70200000.) +*/ + +#ifdef NAML$C_BID + +/* Use long name (NAML) structure. */ + +#define FAB$L_NAMX fab$l_naml +#define NAMX NAML +#define NAMX$C_MAXRSS NAML$C_MAXRSS +#define NAMX$B_DEV naml$l_long_dev_size +#define NAMX$L_DEV naml$l_long_dev +#define NAMX$L_ESA naml$l_long_expand +#define NAMX$B_ESL naml$l_long_expand_size +#define NAMX$B_ESS naml$l_long_expand_alloc +#define NAMX$W_FID naml$w_fid +#define NAMX$L_RSA naml$l_long_result +#define NAMX$B_RSL naml$l_long_result_size +#define NAMX$B_RSS naml$l_long_result_alloc +#define CC$RMS_NAMX cc$rms_naml + +#else /* def NAML$C_BID */ + +/* Use short name (NAM) structure. */ + +#define FAB$L_NAMX fab$l_nam +#define NAMX NAM +#define NAMX$C_MAXRSS NAM$C_MAXRSS +#define NAMX$B_DEV nam$b_dev +#define NAMX$L_DEV nam$l_dev +#define NAMX$L_ESA nam$l_esa +#define NAMX$B_ESL nam$b_esl +#define NAMX$B_ESS nam$b_ess +#define NAMX$W_FID nam$w_fid +#define NAMX$L_RSA nam$l_rsa +#define NAMX$B_RSL nam$b_rsl +#define NAMX$B_RSS nam$b_rss +#define CC$RMS_NAMX cc$rms_nam + +#endif /* def NAML$C_BID */ + +/*--------------------------------------------------------------------*/ + +/* Wget-private utime() code. */ + +/* Action routine for decc$to_vms(), in utime(). */ + +char vms_path[ NAMX$C_MAXRSS+ 1]; + +int set_vms_name( char *name, int type) +{ + strncpy( vms_path, name, NAMX$C_MAXRSS); + vms_path[ NAMX$C_MAXRSS] = '\0'; + return 1; +} + +/*--------------------------------------------------------------------*/ + +/* utime() replacement. */ + +int utime( const char *path, const struct utimbuf *times) +{ +time_t utc_unsigned; + +int chan, i; +int sts, sts2; + +unsigned short int vms_num_vec_time[ 7]; +static unsigned int vms_abs_time[ 2]; +struct tm *tms; +struct _iosb iosb_q; + +/* QIOW item list used to set creation and revision dates. */ + +struct atrdef ut_atr[ 3] = { + {sizeof( vms_abs_time), ATR$C_CREDATE, UWA vms_abs_time}, + {sizeof( vms_abs_time), ATR$C_REVDATE, UWA vms_abs_time}, + {0,0,0}}; + +/* Various RMS structures used for file access. */ + +struct FAB ut_fab = cc$rms_fab; +struct RAB ut_rab = cc$rms_rab; +struct NAMX ut_namx = CC$RMS_NAMX; +static struct fibdef ut_fib; + +/* Device and file name buffers and their descriptors. */ + +static char dev_namx[ NAMX$C_MAXRSS+ 1]; +char esa_namx[ NAMX$C_MAXRSS+ 1]; +char rsa_namx[ NAMX$C_MAXRSS+ 1]; + +struct dsc$descriptor dev_dsc = + {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, dev_namx}; + +struct dsc$descriptor fib_dsc = + {sizeof( ut_fib), DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *) &ut_fib}; + +/* "wget" provides a UNIX-like path name. With "-O", a user may provide + a VMS-like path name. If a slash is found in the name, assume that + it's UNIX-like, and convert it to VMS form. Otherwise, use it as-is. +*/ + +if (strchr( path, '/') != NULL) + { + sts = decc$to_vms( path, set_vms_name, 0, 0); + path = vms_path; + } + +/* Install the VMS file specification into the FAB. */ + +ut_fab.fab$l_fna = (char *) path; +ut_fab.fab$b_fns = (unsigned char) strlen( path); + +ut_fab.fab$l_dna = ""; +ut_fab.fab$b_dns = 0; + +/* Point the FAB to the NAMX. */ + +ut_fab.FAB$L_NAMX = &ut_namx; + +/* Install the name buffers into the NAM. */ + +ut_namx.NAMX$L_ESA = esa_namx; +ut_namx.NAMX$B_ESL = 0; +ut_namx.NAMX$B_ESS = sizeof( esa_namx)- 1; + +ut_namx.NAMX$L_RSA = rsa_namx; +ut_namx.NAMX$B_RSL = 0; +ut_namx.NAMX$B_RSS = sizeof( rsa_namx)- 1; + +/* Convert the modification time (UTC time_t) to local "tm" time. */ + +tms = localtime( &(times-> modtime)); + +/* Move (translate) "tm" structure local time to VMS vector time. */ + +if (tms != NULL) + { + vms_num_vec_time[ 0] = tms-> tm_year+ 1900; + vms_num_vec_time[ 1] = tms-> tm_mon+ 1; + vms_num_vec_time[ 2] = tms-> tm_mday; + vms_num_vec_time[ 3] = tms-> tm_hour; + vms_num_vec_time[ 4] = tms-> tm_min; + vms_num_vec_time[ 5] = tms-> tm_sec; + vms_num_vec_time[ 6] = 0; /* centiseconds */ + +/* Convert VMS vector time to VMS absolute time (quadword). */ + + sts = lib$cvt_vectim( vms_num_vec_time, vms_abs_time); + + if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) + { +/* Parse the file specification. */ + + sts = sys$parse( &ut_fab, 0, 0); + + if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) + { +/* Locate the file. (Gets the FID.) */ + + sts = sys$search( &ut_fab, 0, 0); + + if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) + { +/* Form the device name descriptor. */ + + dev_dsc.dsc$w_length = ut_namx.NAMX$B_DEV; + dev_dsc.dsc$a_pointer = (char *) ut_namx.NAMX$L_DEV; + +/* Assign a channel to the disk device. */ + + sts = sys$assign( &dev_dsc, &chan, 0, 0); + + if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) + { +/* Move the FID (and not the DID) into the FIB. */ + + memset( (void *) &ut_fib, 0, sizeof( ut_fib)); + + for (i = 0; i < 3; i++) + { + ut_fib.fib$w_fid[ i] = ut_namx.NAMX$W_FID[ i]; + ut_fib.fib$w_did[ i] = 0; + } + +/* Prevent this QIOW from setting the revision time to now. */ + + ut_fib.fib$l_acctl = FIB$M_NORECORD; + +/* Set the file dates. */ + + sts = sys$qiow( 0, + chan, + IO$_MODIFY, + &iosb_q, + 0, + 0, + &fib_dsc, + 0, + 0, + 0, + ut_atr, + 0); + + if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) + { + sts = iosb_q.iosb$w_status; + } + sts2 = sys$dassgn( chan); + + if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) + { + sts = sts2; + } + } + } + } + } + } + +/* Convert successful VMS status to zero = success status. + If failure, set errno and vaxc$errno, and return -1 = failure status. +*/ + +if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS) + { + sts = 0; + } +else + { + errno = EVMSERR; + vaxc$errno = sts; + sts = -1; + } + +return sts; +} + +/*--------------------------------------------------------------------*/ + +/* 2005-04-14 SMS. + * + * vms_init_diag(). + * + * Get Wget debug option value. + */ + +int vms_init_diag( void) +{ +#ifdef ENABLE_DEBUG +return (opt.debug > 0); +#else /* def ENABLE_DEBUG */ +return 0; +#endif /* def ENABLE_DEBUG */ +} + +/*--------------------------------------------------------------------*/ + +/* 2004-11-23 SMS. + * + * get_rms_defaults(). + * + * Get user-specified values from (DCL) SET RMS_DEFAULT. FAB/RAB + * items of particular interest are: + * + * fab$w_deq default extension quantity (blocks) (write). + * rab$b_mbc multi-block count. + * rab$b_mbf multi-buffer count (used with rah and wbh). + */ + +/* Default RMS parameter values. */ + +#define RMS_DEQ_DEFAULT 16384 /* About 1/4 the max (65535 blocks). */ +#define RMS_MBC_DEFAULT 127 /* The max, */ +#define RMS_MBF_DEFAULT 2 /* Enough to enable rah and wbh. */ + +/* GETJPI item descriptor structure. */ +typedef struct + { + short buf_len; + short itm_cod; + void *buf; + int *ret_len; + } jpi_item_t; + +/* Durable storage */ + +static int rms_defaults_known = 0; + +/* JPI item buffers. */ +static unsigned short rms_ext; +static char rms_mbc; +static unsigned char rms_mbf; + +/* Active RMS item values. */ +unsigned short rms_ext_active; +char rms_mbc_active; +unsigned char rms_mbf_active; + +/* GETJPI item lengths. */ +static int rms_ext_len; /* Should come back 2. */ +static int rms_mbc_len; /* Should come back 1. */ +static int rms_mbf_len; /* Should come back 1. */ + +/* Desperation attempts to define unknown macros. Probably doomed. + * If these get used, expect sys$getjpiw() to return %x00000014 = + * %SYSTEM-F-BADPARAM, bad parameter value. + * They keep compilers with old header files quiet, though. + */ +#ifndef JPI$_RMS_EXTEND_SIZE +# define JPI$_RMS_EXTEND_SIZE 542 +#endif /* ndef JPI$_RMS_EXTEND_SIZE */ + +#ifndef JPI$_RMS_DFMBC +# define JPI$_RMS_DFMBC 535 +#endif /* ndef JPI$_RMS_DFMBC */ + +#ifndef JPI$_RMS_DFMBFSDK +# define JPI$_RMS_DFMBFSDK 536 +#endif /* ndef JPI$_RMS_DFMBFSDK */ + +/* GETJPI item descriptor set. */ + +struct + { + jpi_item_t rms_ext_itm; + jpi_item_t rms_mbc_itm; + jpi_item_t rms_mbf_itm; + int term; + } jpi_itm_lst = + { { 2, JPI$_RMS_EXTEND_SIZE, &rms_ext, &rms_ext_len }, + { 1, JPI$_RMS_DFMBC, &rms_mbc, &rms_mbc_len }, + { 1, JPI$_RMS_DFMBFSDK, &rms_mbf, &rms_mbf_len }, + 0 + }; + +int get_rms_defaults() +{ +int sts; + +/* Get process RMS_DEFAULT values. */ + +sts = sys$getjpiw( 0, 0, 0, &jpi_itm_lst, 0, 0, 0); +if ((sts& STS$M_SEVERITY) != STS$M_SUCCESS) + { + /* Failed. Don't try again. */ + rms_defaults_known = -1; + } +else + { + /* Fine, but don't come back. */ + rms_defaults_known = 1; + } + +/* Limit the active values according to the RMS_DEFAULT values. */ + +if (rms_defaults_known > 0) + { + /* Set the default values. */ + + rms_ext_active = RMS_DEQ_DEFAULT; + rms_mbc_active = RMS_MBC_DEFAULT; + rms_mbf_active = RMS_MBF_DEFAULT; + + /* Default extend quantity. Use the user value, if set. */ + if (rms_ext > 0) + { + rms_ext_active = rms_ext; + } + + /* Default multi-block count. Use the user value, if set. */ + if (rms_mbc > 0) + { + rms_mbc_active = rms_mbc; + } + + /* Default multi-buffer count. Use the user value, if set. */ + if (rms_mbf > 0) + { + rms_mbf_active = rms_mbf; + } + } + +if (vms_init_diag() > 0) + { + fprintf( stderr, + "Get RMS defaults. getjpi sts = %%x%08x.\n", + sts); + + if (rms_defaults_known > 0) + { + fprintf( stderr, + " Default: deq = %6d, mbc = %3d, mbf = %3d.\n", + rms_ext, rms_mbc, rms_mbf); + } + } +return sts; +} + +/*--------------------------------------------------------------------*/ + +/* 2004-11-23 SMS. + * + * acc_cb(), access callback function for DEC C [f]open(). + * + * Set some RMS FAB/RAB items, with consideration of user-specified + * values from (DCL) SET RMS_DEFAULT. Items of particular interest are: + * + * fab$w_deq default extension quantity (blocks). + * rab$b_mbc multi-block count. + * rab$b_mbf multi-buffer count (used with rah and wbh). + * + * See also the FOP* macros in OSDEP.H. Currently, no notice is + * taken of the caller-ID value, but options could be set differently + * for read versus write access. (I assume that specifying fab$w_deq, + * for example, for a read-only file has no ill effects.) + */ + +/* acc_cb() */ + +int acc_cb( int *id_arg, struct FAB *fab, struct RAB *rab) +{ +int sts; + +/* Get process RMS_DEFAULT values, if not already done. */ +if (rms_defaults_known == 0) + { + get_rms_defaults(); + } + +/* If RMS_DEFAULT (and adjusted active) values are available, then set + * the FAB/RAB parameters. If RMS_DEFAULT values are not available, + * suffer with the default parameters. + */ +if (rms_defaults_known > 0) + { + /* Set the FAB/RAB parameters accordingly. */ + fab-> fab$w_deq = rms_ext_active; + rab-> rab$b_mbc = rms_mbc_active; + rab-> rab$b_mbf = rms_mbf_active; + + /* Truncate at EOF on close, as we'll probably over-extend. */ + fab-> fab$v_tef = 1; + + /* If using multiple buffers, enable read-ahead and write-behind. */ + if (rms_mbf_active > 1) + { + rab-> rab$v_rah = 1; + rab-> rab$v_wbh = 1; + } + + if (vms_init_diag() > 0) + { + fprintf( stderr, + "Open callback. ID = %d, deq = %6d, mbc = %3d, mbf = %3d.\n", + *id_arg, fab-> fab$w_deq, rab-> rab$b_mbc, rab-> rab$b_mbf); + } + } + +/* Declare success. */ +return 0; +} + +/*--------------------------------------------------------------------*/ + +/* Added J.Lauret 05-Dec-1999 . Copied from Mosaic distribution */ + +/* + * Here is a replacement for getpwuid for VMS. It returns pointers + * to userid (*pw_name) and owner (*pw_gecos) only. Other fields + * may be added later. + * Note that sys$getuai returns owner as a counted string. + */ + +#if __CRTL_VER < 70000000 + +#include + +static struct passwd vms_passwd; +static char vms_userid[16]; +static char vms_owner[40]; + +struct passwd *getpwuid() +{ +struct dsc$descriptor_s +{ + unsigned short dsc$w_length; + unsigned char dsc$b_dtype; + unsigned char dsc$b_class; + char *dsc$a_pointer; +} user_desc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL}; + + char *t_userid, owner[40]; + int status, length; + struct { + short buffer_length; + short item_code; + int buffer_address; + int return_length_address; + int terminator; + } itmlst; + +#ifdef __GNUC__ + (int)t_userid = cuserid((char *) NULL); +#else + t_userid = cuserid((char *) NULL); +#endif /* GNU C is strange, GEC */ + user_desc.dsc$w_length = strlen(t_userid); + user_desc.dsc$a_pointer = t_userid; + itmlst.buffer_length = sizeof(owner); + itmlst.item_code = UAI$_OWNER; + itmlst.buffer_address = (int)owner; + itmlst.return_length_address = (int)&length; + itmlst.terminator = 0; + status = sys$getuai(0, 0, &user_desc, &itmlst, 0, 0, 0); + if ((stats& STS$M_SEVERITY) == STS$K_SUCCESS) { + length = (int)owner[0]; + owner[length+1] = '\0'; + strcpy(vms_userid, t_userid); + strcpy(vms_owner, &owner[1]); + } else { + vms_userid[0] = '\0'; + vms_owner[0] = '\0'; + } + vms_passwd.pw_name = vms_userid; + vms_passwd.pw_gecos = vms_owner; + return (&vms_passwd); +} + +/* Approximate localtime_r as best we can in its absence. */ +struct tm * +localtime_r (t, tp) + const time_t *t; + struct tm *tp; +{ + struct tm *l = localtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} + +#endif /* __CRTL_VER < 70000000 */ +