X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Fvms.c;h=c65eb94da097c8184cd2310264689312b3ecbd20;hp=8104d1377705e431da94eb3eb98eacdbd4e5fa05;hb=3450481772898cb948207635fa3343f7ba56a7f2;hpb=d5361eca21c683bd28d0351cdb9bb7cb0de8d75a diff --git a/src/vms.c b/src/vms.c index 8104d137..c65eb94d 100644 --- a/src/vms.c +++ b/src/vms.c @@ -16,6 +16,18 @@ * *---------------------------------------------------------------------- * + * vms_basename() + * + * Returns the basename from a VMS file spec. + * + *---------------------------------------------------------------------- + * + * vms_getpass(). + * + * VMS-specific substitute for GNU getpass(). + * + *---------------------------------------------------------------------- + * * vms_ver() * * Returns (run-time) VMS version string. @@ -33,7 +45,7 @@ * * Simplifies a fancy URL-derived file name into an ODS2- or * ODS5-compatible file name. - * + * *---------------------------------------------------------------------- * * utime() @@ -64,6 +76,7 @@ #include #include +#include #include #include #include @@ -72,12 +85,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include #include @@ -105,6 +120,55 @@ typedef struct _iosb { #include "wget.h" #include "utils.h" + +/* Define macros for use with either NAM or NAML. */ + +#ifdef NAML$C_MAXRSS /* NAML is available. Use it. */ + +# define NAM_STRUCT NAML + +# define FAB_OR_NAML( fab, nam) nam +# define FAB_OR_NAML_FNA naml$l_long_filename +# define FAB_OR_NAML_FNS naml$l_long_filename_size + +# define CC_RMS_NAM cc$rms_naml +# define FAB_NAM fab$l_naml +# define NAM_ESA naml$l_long_expand +# define NAM_ESL naml$l_long_expand_size +# define NAM_ESS naml$l_long_expand_alloc +# define NAM_RSA naml$l_long_result +# define NAM_RSL naml$l_long_result_size +# define NAM_RSS naml$l_long_result_alloc +# define NAM_MAXRSS NAML$C_MAXRSS +# define NAM_NOP naml$b_nop +# define NAM_M_SYNCHK NAML$M_SYNCHK +# define NAM_B_NAME naml$l_long_name_size +# define NAM_L_NAME naml$l_long_name + +#else /* def NAML$C_MAXRSS */ /* NAML is not available. Use NAM. */ + +# define NAM_STRUCT NAM + +# define FAB_OR_NAML( fab, nam) fab +# define FAB_OR_NAML_FNA fab$l_fna +# define FAB_OR_NAML_FNS fab$b_fns + +# define CC_RMS_NAM cc$rms_nam +# define FAB_NAM fab$l_nam +# define NAM_ESA nam$l_esa +# define NAM_ESL nam$b_esl +# define NAM_ESS nam$b_ess +# define NAM_RSA nam$l_rsa +# define NAM_RSL nam$b_rsl +# define NAM_RSS nam$b_rss +# define NAM_MAXRSS NAM$C_MAXRSS +# define NAM_NOP nam$b_nop +# define NAM_M_SYNCHK NAM$M_SYNCHK +# define NAM_B_NAME nam$b_name +# define NAM_L_NAME nam$l_name + +#endif /* def NAML$C_MAXRSS */ + /*--------------------------------------------------------------------*/ /* Global storage. */ @@ -235,7 +299,7 @@ int dmy_lib$initialize = (int) lib$initialize; /*--------------------------------------------------------------------*/ /* vms_arch() - + Returns (run-time) VMS architecture string. */ @@ -269,8 +333,235 @@ return arch; /*--------------------------------------------------------------------*/ -/* vms_vers() +/* vms_basename() + * + * Extract the basename from a VMS file spec. + */ + +char *vms_basename( char *file_spec) +{ + /* Static storage for NAM[L], and so on. */ + + static struct NAM_STRUCT nam; + static char exp_name[ NAM_MAXRSS+ 1]; + static char res_name[ NAM_MAXRSS+ 1]; + + struct FAB fab; + int status; + + /* Set up the FAB and NAM[L] blocks. */ + + fab = cc$rms_fab; /* Initialize FAB. */ + nam = CC_RMS_NAM; /* Initialize NAM[L]. */ + + fab.FAB_NAM = &nam; /* FAB -> NAM[L] */ + +#ifdef NAML$C_MAXRSS + + fab.fab$l_dna = (char *) -1; /* Using NAML for default name. */ + fab.fab$l_fna = (char *) -1; /* Using NAML for file name. */ + +#endif /* def NAML$C_MAXRSS */ + + /* Arg name and length. */ + FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = file_spec; + FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = strlen( file_spec); + + nam.NAM_ESA = exp_name; /* Expanded name. */ + nam.NAM_ESS = NAM_MAXRSS; /* Max length. */ + nam.NAM_RSA = res_name; /* Resulting name. */ + nam.NAM_RSS = NAM_MAXRSS; /* Max length. */ + + nam.NAM_NOP = NAM_M_SYNCHK; /* Syntax-only analysis. */ + + /* Parse the file name. */ + status = sys$parse( &fab); /* What could go wrong? */ + + nam.NAM_L_NAME[ nam.NAM_B_NAME] = '\0'; + + return nam.NAM_L_NAME; +} + +/*--------------------------------------------------------------------*/ + +/* 2009-09-07 SMS. + * + * vms_getpass(). + * + * VMS-specific substitute for GNU getpass(). + * + * Returns passpord in locally allocated string. + */ + +/* Terminal characteristics buffer structure. */ +typedef struct +{ + char class; + char type; + short page_width; + int basic_chars; /* (The high eight bits are page length.) */ + int extended_chars; +} term_chars_t; + +/* Enable/disable terminal echo. */ + +int vms_set_term_echo( int able) +{ + int sts; + int sts2; + short term_chan; + $DESCRIPTOR( term_dscr, "SYS$COMMAND"); + term_chars_t term_chars; + static int initial_echo = -1; + + /* Open a channel to the terminal device. */ + sts = sys$assign( &term_dscr, /* Terminal device name. */ + &term_chan, /* Channel. */ + 0, /* Access mode. */ + 0); /* Mailbox. */ + + /* Return immediately on failure. */ + if ((sts& STS$M_SEVERITY) != STS$K_SUCCESS) + { + errno = EVMSERR; + vaxc$errno = sts; + return -1; + } + + /* Get the current terminal characteristics (mode). */ + sts = sys$qiow( 0, /* Event flag. */ + term_chan, /* Channel. */ + IO$_SENSEMODE, /* Function. */ + 0, /* IOSB. */ + 0, /* AST address. */ + 0, /* AST parameter. */ + &term_chars, /* P1 = Buffer address. */ + sizeof term_chars, /* P2 = Buffer size. */ + 0, 0, 0, 0); /* P3-P6 not used. */ + + if ((sts& STS$M_SEVERITY) != STS$K_SUCCESS) + { + errno = EVMSERR; + vaxc$errno = sts; + } + else if (term_chars.class != DC$_TERM) + { + errno = ENOTTY; + } + else + { + /* Save the initial echo state, to allow proper restoration. */ + if (initial_echo < 0) + { + initial_echo = ((term_chars.basic_chars& TT$M_NOECHO) == 0); + } + + if (able < 0) + { + if (initial_echo) + { + /* Was initially enabled. */ + able = 1; + } + else + { + /* Was initially disabled. */ + able = 0; + } + } + if (able == 0) + { + /* Disable. Set the no-echo bit. */ + term_chars.basic_chars |= TT$M_NOECHO; + } + else + { + /* Enable. Clear the no-echo bit. */ + term_chars.basic_chars &= ~TT$M_NOECHO; + } + + /* Set the terminal characteristics (mode). */ + sts = sys$qiow( 0, /* Event flag. */ + term_chan, /* Channel. */ + IO$_SETMODE, /* Function. */ + 0, /* IOSB. */ + 0, /* AST address. */ + 0, /* AST parameter. */ + &term_chars, /* P1 = Buffer address. */ + sizeof term_chars, /* P2 = Buffer size. */ + 0, 0, 0, 0); /* P3-P6 not used. */ + + if ((sts& STS$M_SEVERITY) != STS$K_SUCCESS) + { + errno = EVMSERR; + vaxc$errno = sts; + } + else + { + /* All is well. */ + sts = 0; + } + } + + /* Close the channel to the terminal device. */ + sts2 = sys$dassgn( term_chan); /* Channel. */ + if ((sts2& STS$M_SEVERITY) != STS$K_SUCCESS) + { + /* If all was not well, leave the old error codes as were. */ + if (sts == 0) + { + /* All was well, but DASSGN failed. */ + errno = EVMSERR; + vaxc$errno = sts2; + sts = sts2; + } + } + return sts; +} + +static char pw_buf[ PASS_MAX+ 1]; + +char *vms_getpass( const char *prompt) +{ + char *ret; + int sts; + FILE *sdc; + + ret = NULL; + + sdc = fopen( "SYS$COMMAND", "r"); + if (sdc != NULL) + { + sts = vms_set_term_echo( 0); + if (sts == 0) + { + /* Read password string. */ + if (sts == 0) + { + fprintf( stdout, "%s", prompt); + sts = fread( pw_buf, 1, PASS_MAX, sdc); + if ((sts > 0) && (pw_buf[ sts- 1]) == '\n') + { + pw_buf[ --sts] = '\0'; + } + else + { + pw_buf[ sts = '\0']; + } + ret = pw_buf; + } + sts = vms_set_term_echo( -1); + } + fclose( sdc); + } + return ret; +} + +/*--------------------------------------------------------------------*/ + +/* vms_vers() + Returns (run-time) VMS version string. */ @@ -1048,3 +1339,15 @@ localtime_r (t, tp) #endif /* __CRTL_VER < 70000000 */ +/*--------------------------------------------------------------------*/ + +/* + * "version.c" information. + */ + +const char *compilation_string = NULL; +const char *link_string = NULL; +const char *version_string = VERSION; + +/*--------------------------------------------------------------------*/ +