X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Futils.c;fp=src%2Futils.c;h=7a93376a46d36a0bd246f4ae0ef057b3151c7300;hp=15e3f89ba392b726050e6ba7dccc4af502bca4a7;hb=d5e283b1a75c5f8249300b465b4e7b55130bec49;hpb=8e9a3e805fd758eadfc1bad6a4ef3e971de35ec4 diff --git a/src/utils.c b/src/utils.c index 15e3f89b..7a93376a 100644 --- a/src/utils.c +++ b/src/utils.c @@ -84,6 +84,10 @@ as that of the covered work. */ #include "utils.h" #include "hash.h" +#ifdef __VMS +#include "vms.h" +#endif /* def __VMS */ + #ifdef TESTING #include "test.h" #endif @@ -114,6 +118,87 @@ memfatal (const char *context, long attempted_size) exit (1); } +/* Character property table for (re-)escaping VMS ODS5 extended file + names. Note that this table ignores Unicode. + + ODS2 valid characters: 0-9 A-Z a-z $ - _ ~ + + ODS5 Invalid characters: + C0 control codes (0x00 to 0x1F inclusive) + Asterisk (*) + Question mark (?) + + ODS5 Invalid characters only in VMS V7.2 (which no one runs, right?): + Double quotation marks (") + Backslash (\) + Colon (:) + Left angle bracket (<) + Right angle bracket (>) + Slash (/) + Vertical bar (|) + + Characters escaped by "^": + SP ! # % & ' ( ) + , . ; = @ [ ] ^ ` { } ~ + + Either "^_" or "^ " is accepted as a space. Period (.) is a special + case. Note that un-escaped < and > can also confuse a directory + spec. + + Characters put out as ^xx: + 7F (DEL) + 80-9F (C1 control characters) + A0 (nonbreaking space) + FF (Latin small letter y diaeresis) + + Other cases: + Unicode: "^Uxxxx", where "xxxx" is four hex digits. + + Property table values: + Normal escape: 1 + Space: 2 + Dot: 4 + Hex-hex escape: 8 + ODS2 normal: 16 + ODS2 lower case: 32 + Hex digit: 64 +*/ + +unsigned char char_prop[ 256] = { + +/* NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +/* DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +/* SP ! " # $ % & ' ( ) * + , - . / */ + 2, 1, 0, 1, 16, 1, 1, 1, 1, 1, 0, 1, 1, 16, 4, 0, + +/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 1, 1, 1, 1, 1, + +/* @ A B C D E F G H I J K L M N O */ + 1, 80, 80, 80, 80, 80, 80, 16, 16, 16, 16, 16, 16, 16, 16, 16, + +/* P Q R S T U V W X Y Z [ \ ] ^ _ */ + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 0, 1, 1, 16, + +/* ` a b c d e f g h i j k l m n o */ + 1, 96, 96, 96, 96, 96, 96, 32, 32, 32, 32, 32, 32, 32, 32, 32, + +/* p q r s t u v w x y z { | } ~ DEL */ + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 1, 0, 1, 17, 8, + + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 +}; + /* Utility function: like xstrdup(), but also lowercases S. */ char * @@ -340,6 +425,16 @@ datetime_str (time_t t) /* The Windows versions of the following two functions are defined in mswindows.c. On MSDOS this function should never be called. */ +#ifdef __VMS + +void +fork_to_background (void) +{ + return; +} + +#else /* def __VMS */ + #if !defined(WINDOWS) && !defined(MSDOS) void fork_to_background (void) @@ -385,6 +480,9 @@ fork_to_background (void) freopen ("/dev/null", "w", stderr); } #endif /* !WINDOWS && !MSDOS */ + +#endif /* def __VMS [else] */ + /* "Touch" FILE, i.e. make its mtime ("modified time") equal the time specified with TM. The atime ("access time") is set to the current @@ -483,6 +581,14 @@ file_size (const char *filename) #endif } +/* 2005-02-19 SMS. + If no UNIQ_SEP is defined (as on VMS), have unique_name() return the + original name. With the VMS file systems' versioning, everything + should be fine, and appending ".NN" just causes trouble. +*/ + +#ifdef UNIQ_SEP + /* stat file names named PREFIX.1, PREFIX.2, etc., until one that doesn't exist is found. Return a freshly allocated copy of the unused file name. */ @@ -496,7 +602,7 @@ unique_name_1 (const char *prefix) char *template_tail = template + plen; memcpy (template, prefix, plen); - *template_tail++ = '.'; + *template_tail++ = UNIQ_SEP; do number_to_string (template_tail, count++); @@ -511,6 +617,8 @@ unique_name_1 (const char *prefix) If not, FILE.1 is tried, then FILE.2, etc. The first FILE. file name that doesn't exist is returned. + 2005-02-19 SMS. "." is now UNIQ_SEP, and may be different. + The resulting file is not created, only verified that it didn't exist at the point in time when the function was called. Therefore, where security matters, don't rely that the file created @@ -534,6 +642,20 @@ unique_name (const char *file, bool allow_passthrough) return unique_name_1 (file); } +#else /* def UNIQ_SEP */ + +/* Dummy unique_name() for VMS. Return the original name as easily as + possible. +*/ +char * +unique_name (const char *file, bool allow_passthrough) +{ + /* Return the FILE itself, without modification, irregardful. */ + return allow_passthrough ? (char *)file : xstrdup (file); +} + +#endif /* def UNIQ_SEP [else] */ + /* Create a file based on NAME, except without overwriting an existing file with that name. Providing O_EXCL is correctly implemented, this function does not have the race condition associated with @@ -580,12 +702,61 @@ fopen_excl (const char *fname, bool binary) { int fd; #ifdef O_EXCL + +/* 2005-04-14 SMS. + VMS lacks O_BINARY, but makes up for it in weird and wonderful ways. + It also has file versions which obviate all the O_EXCL effort. + O_TRUNC (something of a misnomer) requests a new version. +*/ +# ifdef __VMS +/* Common open() optional arguments: + sequential access only, access callback function. +*/ +# define OPEN_OPT_ARGS "fop=sqo", "acc", acc_cb, &open_id + + int open_id; + int flags = O_WRONLY | O_CREAT | O_TRUNC; + + if (binary > 1) + { + open_id = 11; + fd = open( fname, /* File name. */ + flags, /* Flags. */ + 0777, /* Mode for default protection. */ + "ctx=bin,stm", /* Binary, stream access. */ + "rfm=stmlf", /* Stream_LF. */ + OPEN_OPT_ARGS); /* Access callback. */ + } + else if (binary) + { + open_id = 12; + fd = open( fname, /* File name. */ + flags, /* Flags. */ + 0777, /* Mode for default protection. */ + "ctx=bin,stm", /* Binary, stream access. */ + "rfm=fix", /* Fixed-length, */ + "mrs=512", /* 512-byte records. */ + OPEN_OPT_ARGS); /* Access callback. */ + } + else + { + open_id = 13; + fd = open( fname, /* File name. */ + flags, /* Flags. */ + 0777, /* Mode for default protection. +*/ + "rfm=stmlf", /* Stream_LF. */ + OPEN_OPT_ARGS); /* Access callback. */ + } +# else /* def __VMS */ int flags = O_WRONLY | O_CREAT | O_EXCL; # ifdef O_BINARY if (binary) flags |= O_BINARY; # endif fd = open (fname, flags, 0666); +# endif /* def __VMS [else] */ + if (fd < 0) return NULL; return fdopen (fd, binary ? "wb" : "w");