From: Micah Cowan Date: Sat, 4 Jul 2009 22:32:57 +0000 (-0700) Subject: Automated merge. X-Git-Tag: v1.13~319 X-Git-Url: http://sjero.net/git/?p=wget;a=commitdiff_plain;h=d5e283b1a75c5f8249300b465b4e7b55130bec49 Automated merge. --- d5e283b1a75c5f8249300b465b4e7b55130bec49 diff --cc src/ftp.c index 8e05a796,9bc92a89..827e597e --- a/src/ftp.c +++ b/src/ftp.c @@@ -547,11 -592,97 +596,97 @@@ Error in server response, closing contr DEBUGP ((" Unix: '%s'\n VMS: '%s'\n", target, ntarget)); target = ntarget; } + #endif /* 0 */ + + /* 2004-09-20 SMS. + A relative directory is relative to the initial directory. + Thus, what _is_ useful on VMS (and probably elsewhere) is + to CWD to the initial directory (ideally, whatever the + server reports, _exactly_, NOT badly UNIX-ixed), and then + CWD to the (new) relative directory. This should probably + be restructured as a function, called once or twice, but + I'm lazy enough to take the badly indented loop short-cut + for now. + */ + + /* Decide on one pass (absolute) or two (relative). + The VMS restriction may be relaxed when the squirrely code + above is reformed. + */ + if ((con->rs == ST_VMS) && (target[0] != '/')) + { + cwd_start = 0; + DEBUGP (("Using two-step CWD for relative path.\n")); + } + else + { + /* Go straight to the target. */ + cwd_start = 1; + } + + /* At least one VMS FTP server (TCPware V5.6-2) can switch to + a UNIX emulation mode when given a UNIX-like directory + specification (like "a/b/c"). If allowed to continue this + way, LIST interpretation will be confused, because the + system type (SYST response) will not be re-checked, and + future UNIX-format directory listings (for multiple URLs or + "-r") will be horribly misinterpreted. + + The cheap and nasty work-around is to do a "CWD []" after a + UNIX-like directory specification is used. (A single-level + directory is harmless.) This puts the TCPware server back + into VMS mode, and does no harm on other servers. + + Unlike the rest of this block, this particular behavior + _is_ VMS-specific, so it gets its own VMS test. + */ + if ((con->rs == ST_VMS) && (strchr( target, '/') != NULL)) + { + cwd_end = 3; + DEBUGP (("Using extra \"CWD []\" step for VMS server.\n")); + } + else + { + cwd_end = 2; + } + + /* 2004-09-20 SMS. */ + /* Sorry about the deviant indenting. Laziness. */ + + for (cwd_count = cwd_start; cwd_count < cwd_end; cwd_count++) + { + switch (cwd_count) + { + case 0: + /* Step one (optional): Go to the initial directory, + exactly as reported by the server. + */ + targ = con->id; + break; + + case 1: + /* Step two: Go to the target directory. (Absolute or + relative will work now.) + */ + targ = target; + break; + + case 2: + /* Step three (optional): "CWD []" to restore server + VMS-ness. + */ + targ = "[]"; + break; + + default: + /* Can't happen. */ + assert (1); + } if (!opt.server_response) - logprintf (LOG_VERBOSE, "==> CWD %s ... ", - logprintf (LOG_VERBOSE, "==> CWD (%d) %s ... ", - cwd_count, escnonprint (target)); - err = ftp_cwd (csock, targ); ++ logprintf (LOG_VERBOSE, "==> CWD (%d) %s ... ", cwd_count, + quotearg_style (escape_quoting_style, target)); + err = ftp_cwd (csock, target); /* FTPRERR, WRITEFAILED, FTPNSFOD */ switch (err) { @@@ -1127,15 -1319,26 +1357,28 @@@ ftp_loop_internal (struct url *u, struc uerr_t err; struct_stat st; - if (!con->target) - con->target = url_file_name (u); + /* Get the target, and set the name for the message accordingly. */ + if ((f == NULL) && (con->target)) + { + /* Explicit file (like ".listing"). */ + locf = con->target; + } + else + { + /* URL-derived file. Consider "-O file" name. */ + con->target = url_file_name (u); + if (!opt.output_document) + locf = con->target; + else + locf = opt.output_document; + } - if (opt.noclobber && file_exists_p (con->target)) + /* If the output_document was given, then this check was already done and + the file didn't exist. Hence the !opt.output_document */ + if (opt.noclobber && !opt.output_document && file_exists_p (con->target)) { logprintf (LOG_VERBOSE, - _("File `%s' already there; not retrieving.\n"), con->target); + _("File %s already there; not retrieving.\n"), quote (con->target)); /* If the file is there, we suppose it's retrieved OK. */ return RETROK; } @@@ -1585,29 -1770,51 +1825,41 @@@ Already have correct symlink %s -> %s\n break; } /* switch */ - /* Set the time-stamp information to the local file. Symlinks - are not to be stamped because it sets the stamp on the - original. :( */ - if (!(f->type == FT_SYMLINK && !opt.retr_symlinks) - && f->tstamp != -1 - && dlthis - && file_exists_p (con->target)) + + /* 2004-12-15 SMS. + * Set permissions _before_ setting the times, as setting the + * permissions changes the modified-time, at least on VMS. + * Also, use the opt.output_document name here, too, as + * appropriate. (Do the test once, and save the result.) + */ + - /* #### This code repeats in http.c and ftp.c. Move it to a - function! */ - actual_target = NULL; - if (opt.output_document) - { - if (output_stream_regular) - actual_target = opt.output_document; - } - else - actual_target = con->target; ++ set_local_file (&actual_target, con->target); + + /* If downloading a plain file, set valid (non-zero) permissions. */ + if (dlthis && (actual_target != NULL) && (f->type == FT_PLAINFILE)) { - const char *fl = NULL; - set_local_file (&fl, con->target); - if (fl) - touch (fl, f->tstamp); + if (f->perms) + chmod (actual_target, f->perms); + else + DEBUGP (("Unrecognized permissions for %s.\n", actual_target)); } - else if (f->tstamp == -1) - logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), con->target); - if (f->perms && f->type == FT_PLAINFILE && dlthis) + /* Set the time-stamp information to the local file. Symlinks + are not to be stamped because it sets the stamp on the + original. :( */ - + if (actual_target != NULL) { - if (opt.preserve_perm) - chmod (con->target, f->perms); + if (!(f->type == FT_SYMLINK && !opt.retr_symlinks) + && f->tstamp != -1 + && dlthis + && file_exists_p (con->target)) + { + touch (actual_target, f->tstamp); + } + else if (f->tstamp == -1) + logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), - actual_target); ++ actual_target); } - else - DEBUGP (("Unrecognized permissions for %s.\n", con->target)); xfree (con->target); con->target = old_target; @@@ -1822,10 -2028,10 +2074,10 @@@ ftp_retrieve_glob (struct url *u, ccon /* No luck. */ /* #### This message SUCKS. We should see what was the reason that nothing was retrieved. */ - logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), - escnonprint (u->file)); + logprintf (LOG_VERBOSE, _("No matches on pattern %s.\n"), + quote (u->file)); } - else /* GLOB_GETONE or GLOB_GETALL */ + else if (action == GLOB_GETONE) /* GLOB_GETONE or GLOB_GETALL */ { /* Let's try retrieving it anyway. */ con->st |= ON_YOUR_OWN; diff --cc src/http.c index ae89c46d,d9c85ed3..4e49ed4f --- a/src/http.c +++ b/src/http.c @@@ -66,10 -66,13 +66,14 @@@ as that of the covered work. * #include "test.h" #endif - extern char *version_string; + #include "version.h" + + #ifdef __VMS + # include "vms.h" + #endif /* def __VMS */ /* Forward decls. */ +struct http_stat; static char *create_authorization_line (const char *, const char *, const char *, const char *, const char *, bool *); diff --cc src/init.c index 23f8cb2c,43a0f95e..879d3aac --- a/src/init.c +++ b/src/init.c @@@ -404,68 -395,40 +407,75 @@@ wgetrc_env_file_name (void } return xstrdup (env); } + return NULL; +} +/* Check for the existance of '$HOME/.wgetrc' and return it's path + if it exists and is set. */ +char * +wgetrc_user_file_name (void) +{ + char *home = home_dir (); + char *file = NULL; + /* If that failed, try $HOME/.wgetrc (or equivalent). */ + + #ifdef __VMS + file = "SYS$LOGIN:.wgetrc"; + #else /* def __VMS */ + home = home_dir (); if (home) file = aprintf ("%s/.wgetrc", home); xfree_null (home); + #endif /* def __VMS [else] */ + + if (!file) + return NULL; + if (!file_exists_p (file)) + { + xfree (file); + return NULL; + } + return file; +} + +/* Return the path to the user's .wgetrc. This is either the value of + `WGETRC' environment variable, or `$HOME/.wgetrc'. + + Additionally, for windows, look in the directory where wget.exe + resides. */ +char * +wgetrc_file_name (void) +{ - char *home = NULL; + char *file = wgetrc_env_file_name (); + if (file && *file) + return file; + + file = wgetrc_user_file_name (); + #ifdef WINDOWS /* Under Windows, if we still haven't found .wgetrc, look for the file `wget.ini' in the directory where `wget.exe' resides; we do this for backward compatibility with previous versions of Wget. SYSTEM_WGETRC should not be defined under WINDOWS. */ - home = home_dir (); -- if (!file || !file_exists_p (file)) ++ if (!file) { ++ char *home = home_dir (); xfree_null (file); file = NULL; home = ws_mypath (); if (home) -- file = aprintf ("%s/wget.ini", home); ++ { ++ file = aprintf ("%s/wget.ini", home); ++ if (!file_exists_p (file)) ++ { ++ xfree (file); ++ file = NULL; ++ } ++ xfree (home); ++ } } - xfree_null (home); #endif /* WINDOWS */ -- if (!file) -- return NULL; -- if (!file_exists_p (file)) -- { -- xfree (file); -- return NULL; -- } return file; } diff --cc src/log.c index b62bf9dd,cbdf59fb..9ee06211 --- a/src/log.c +++ b/src/log.c @@@ -43,7 -43,20 +43,20 @@@ as that of the covered work. * #include "utils.h" #include "log.h" - /* This file implement support for "logging". Logging means printing + /* 2005-10-25 SMS. + VMS log files are often VFC record format, not stream, so fputs() can + produce multiple records, even when there's no newline terminator in + the buffer. The result is unsightly output with spurious newlines. + Using fprintf() instead of fputs(), along with inhibiting some + fflush() activity below, seems to solve the problem. + */ + #ifdef __VMS + # define FPUTS( s, f) fprintf( (f), "%s", (s)) + #else /* def __VMS */ + # define FPUTS( s, f) fputs( (s), (f)) + #endif /* def __VMS [else] */ + -/* This file impplement support for "logging". Logging means printing ++/* This file implements support for "logging". Logging means printing output, plus several additional features: - Cataloguing output by importance. You can specify that a log diff --cc src/main.c index 85d7ff49,3e32c409..5898a198 --- a/src/main.c +++ b/src/main.c @@@ -56,9 -56,13 +56,15 @@@ as that of the covered work. * #include "http.h" /* for save_cookies */ #include +#include +#include + #ifdef __VMS + #include "vms.h" + #endif /* __VMS */ + + #include "version.h" + #ifndef PATH_SEPARATOR # define PATH_SEPARATOR '/' #endif @@@ -617,10 -606,14 +630,15 @@@ Recursive download:\n") N_("\ --delete-after delete files locally after downloading them.\n"), N_("\ - -k, --convert-links make links in downloaded HTML point to local files.\n"), + -k, --convert-links make links in downloaded HTML or CSS point to\n\ + local files.\n"), + #ifdef __VMS + N_("\ + -K, --backup-converted before converting file X, back up as X_orig.\n"), + #else /* def __VMS */ N_("\ -K, --backup-converted before converting file X, back up as X.orig.\n"), + #endif /* def __VMS [else] */ N_("\ -m, --mirror shortcut for -N -r -l inf --no-remove-listing.\n"), N_("\ @@@ -660,10 -653,10 +678,10 @@@ Recursive accept/reject:\n") N_("Mail bug reports and suggestions to .\n") }; - int i; + size_t i; printf (_("GNU Wget %s, a non-interactive network retriever.\n"), - version_string); + VERSION_STRING); print_usage (); for (i = 0; i < countof (help); i++) @@@ -754,62 -694,12 +772,68 @@@ format_and_print_line (const char *pref static void print_version (void) { + const char *wgetrc_title = _("Wgetrc: "); + const char *locale_title = _("Locale: "); + const char *compile_title = _("Compile: "); + const char *link_title = _("Link: "); + char *line; + char *env_wgetrc, *user_wgetrc; + int i; + + printf (_("GNU Wget %s\n\n"), version_string); + #ifdef __VMS + printf ("GNU Wget %s built on VMS %s %s.\n\n", + VERSION_STRING, vms_arch(), vms_vers()); + #else /* def __VMS */ - printf ("GNU Wget %s built on %s.\n\n", VERSION_STRING, OS_TYPE); ++ printf ("GNU Wget %s built on %s.\n\n", version_string, OS_TYPE); + #endif /* def __VMS */ + /* compiled_features is a char*[]. We limit the characters per + line to MAX_CHARS_PER_LINE and prefix each line with a constant + number of spaces for proper alignment. */ + for (i = 0; compiled_features[i] != NULL; ) + { + int line_length = MAX_CHARS_PER_LINE; + while ((line_length > 0) && (compiled_features[i] != NULL)) + { + printf ("%s ", compiled_features[i]); + line_length -= strlen (compiled_features[i]) + 2; + i++; + } + printf ("\n"); + } + printf ("\n"); + /* Handle the case when $WGETRC is unset and $HOME/.wgetrc is + absent. */ + printf ("%s\n", wgetrc_title); + env_wgetrc = wgetrc_env_file_name (); + if (env_wgetrc && *env_wgetrc) + { + printf (" %s (env)\n", env_wgetrc); + xfree (env_wgetrc); + } + user_wgetrc = wgetrc_user_file_name (); + if (user_wgetrc) + { + printf (" %s (user)\n", user_wgetrc); + xfree (user_wgetrc); + } +#ifdef SYSTEM_WGETRC + printf (" %s (system)\n", SYSTEM_WGETRC); +#endif + + format_and_print_line (locale_title, + LOCALEDIR, + MAX_CHARS_PER_LINE); + + format_and_print_line (compile_title, + compilation_string, + MAX_CHARS_PER_LINE); + + format_and_print_line (link_title, + link_string, + MAX_CHARS_PER_LINE); + + printf ("\n"); /* TRANSLATORS: When available, an actual copyright character (cirle-c) should be used in preference to "(C)". */ fputs (_("\ diff --cc src/options.h index 8dc7fee2,e0d7521d..382fe312 --- a/src/options.h +++ b/src/options.h @@@ -234,11 -235,12 +234,16 @@@ struct option bool content_disposition; /* Honor HTTP Content-Disposition header. */ bool auth_without_challenge; /* Issue Basic authentication creds without - waiting for a challenge. */ + waiting for a challenge. */ + + bool enable_iri; + char *encoding_remote; + char *locale; + + #ifdef __VMS + int ftp_stmlf; /* Force Stream_LF format for binary FTP. */ + #endif /* def __VMS */ + }; extern struct options opt; diff --cc src/utils.c index 15e3f89b,8c5c8dc3..7a93376a --- a/src/utils.c +++ b/src/utils.c @@@ -88,32 -92,87 +92,113 @@@ as that of the covered work. * #include "test.h" #endif +static void +memfatal (const char *context, long attempted_size) +{ + /* Make sure we don't try to store part of the log line, and thus + call malloc. */ + log_set_save_context (false); + + /* We have different log outputs in different situations: + 1) output without bytes information + 2) output with bytes information */ + if (attempted_size == UNKNOWN_ATTEMPTED_SIZE) + { + logprintf (LOG_ALWAYS, + _("%s: %s: Failed to allocate enough memory; memory exhausted.\n"), + exec_name, context); + } + else + { + logprintf (LOG_ALWAYS, + _("%s: %s: Failed to allocate %ld bytes; memory exhausted.\n"), + exec_name, context, 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 *