X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Futils.c;h=15e3f89ba392b726050e6ba7dccc4af502bca4a7;hp=94b4e3a349bfaa01fdd0fcb5c70972a41e3e205a;hb=766df9d4e9392045a4e5c730ed81e599b509557a;hpb=53d0aff795316dc1a4b785632f0d4d93c861e9cb diff --git a/src/utils.c b/src/utils.c index 94b4e3a3..15e3f89b 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,6 +1,6 @@ /* Various utility functions. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GNU Wget. @@ -17,17 +17,18 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Wget. If not, see . -In addition, as a special exception, the Free Software Foundation -gives permission to link the code of its release of Wget with the -OpenSSL project's "OpenSSL" library (or with modified versions of it -that use the same license as the "OpenSSL" library), and distribute -the linked executables. You must obey the GNU General Public License -in all respects for all of the code used other than "OpenSSL". If you -modify this file, you may extend this exception to your version of the -file, but you are not obligated to do so. If you do not wish to do -so, delete this exception statement from your version. */ +Additional permission under GNU GPL version 3 section 7 -#include +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#include "wget.h" #include #include @@ -42,6 +43,9 @@ so, delete this exception statement from your version. */ #ifdef HAVE_MMAP # include #endif +#ifdef HAVE_PROCESS_H +# include /* getpid() */ +#endif #ifdef HAVE_UTIME_H # include #endif @@ -77,7 +81,6 @@ so, delete this exception statement from your version. */ # define USE_SIGNAL_TIMEOUT #endif -#include "wget.h" #include "utils.h" #include "hash.h" @@ -85,6 +88,32 @@ so, delete this exception statement from your version. */ #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); +} + /* Utility function: like xstrdup(), but also lowercases S. */ char * @@ -93,7 +122,7 @@ xstrdup_lower (const char *s) char *copy = xstrdup (s); char *p = copy; for (; *p; p++) - *p = TOLOWER (*p); + *p = c_tolower (*p); return copy; } @@ -132,7 +161,7 @@ sepstring (const char *s) res[++i] = NULL; ++s; /* Skip the blanks following the ','. */ - while (ISSPACE (*s)) + while (c_isspace (*s)) ++s; p = s; } @@ -156,6 +185,13 @@ sepstring (const char *s) vsnprintf until the correct size is found. Since Wget also ships a fallback implementation of vsnprintf, this should be portable. */ +/* Constant is using for limits memory allocation for text buffer. + Applicable in situation when: vasprintf is not available in the system + and vsnprintf return -1 when long line is truncated (in old versions of + glibc and in other system where C99 doesn`t support) */ + +#define FMT_MAX_LENGTH 1048576 + char * aprintf (const char *fmt, ...) { @@ -168,7 +204,8 @@ aprintf (const char *fmt, ...) ret = vasprintf (&str, fmt, args); va_end (args); if (ret < 0 && errno == ENOMEM) - abort (); /* for consistency with xmalloc/xrealloc */ + memfatal ("aprintf", UNKNOWN_ATTEMPTED_SIZE); /* for consistency + with xmalloc/xrealloc */ else if (ret < 0) return NULL; return str; @@ -198,8 +235,21 @@ aprintf (const char *fmt, ...) /* Else try again with a larger buffer. */ if (n > -1) /* C99 */ size = n + 1; /* precisely what is needed */ + else if (size >= FMT_MAX_LENGTH) /* We have a huge buffer, */ + { /* maybe we have some wrong + format string? */ + logprintf (LOG_ALWAYS, + _("%s: aprintf: text buffer is too big (%ld bytes), " + "aborting.\n"), + exec_name, size); /* printout a log message */ + abort (); /* and abort... */ + } else - size <<= 1; /* twice the old size */ + { + /* else, we continue to grow our + * buffer: Twice the old size. */ + size <<= 1; + } str = xrealloc (str, size); } #endif /* not HAVE_VASPRINTF */ @@ -217,7 +267,7 @@ concat_strings (const char *str0, ...) const char *next_str; int total_length = 0; - int argcount; + size_t argcount; /* Calculate the length of and allocate the resulting string. */ @@ -298,7 +348,7 @@ fork_to_background (void) /* Whether we arrange our own version of opt.lfilename here. */ bool logfile_changed = false; - if (!opt.lfilename) + if (!opt.lfilename && (!opt.quiet || opt.server_response)) { /* We must create the file immediately to avoid either a race condition (which arises from using unique_name and failing to @@ -324,7 +374,7 @@ fork_to_background (void) /* parent, no error */ printf (_("Continuing in background, pid %d.\n"), (int) pid); if (logfile_changed) - printf (_("Output will be written to `%s'.\n"), opt.lfilename); + printf (_("Output will be written to %s.\n"), quote (opt.lfilename)); exit (0); /* #### should we use _exit()? */ } @@ -370,8 +420,8 @@ remove_link (const char *file) DEBUGP (("Unlinking %s (symlink).\n", file)); err = unlink (file); if (err != 0) - logprintf (LOG_VERBOSE, _("Failed to unlink symlink `%s': %s\n"), - file, strerror (errno)); + logprintf (LOG_VERBOSE, _("Failed to unlink symlink %s: %s\n"), + quote (file), strerror (errno)); } return err; } @@ -633,10 +683,10 @@ fnmatch_nocase (const char *pattern, const char *string, int flags) char *strcopy = (char *) alloca (strlen (string) + 1); char *p; for (p = patcopy; *pattern; pattern++, p++) - *p = TOLOWER (*pattern); + *p = c_tolower (*pattern); *p = '\0'; for (p = strcopy; *string; string++, p++) - *p = TOLOWER (*string); + *p = c_tolower (*string); *p = '\0'; return fnmatch (patcopy, strcopy, flags); #endif @@ -674,11 +724,13 @@ acceptable (const char *s) bool subdir_p (const char *d1, const char *d2) { + if (*d1 == '\0') + return true; if (!opt.ignore_case) for (; *d1 && *d2 && (*d1 == *d2); ++d1, ++d2) ; else - for (; *d1 && *d2 && (TOLOWER (*d1) == TOLOWER (*d2)); ++d1, ++d2) + for (; *d1 && *d2 && (c_tolower (*d1) == c_tolower (*d2)); ++d1, ++d2) ; return *d1 == '\0' && (*d2 == '\0' || *d2 == '/'); @@ -763,7 +815,7 @@ match_tail (const char *string, const char *tail, bool fold_case) else { for (i = strlen (string), j = strlen (tail); i >= 0 && j >= 0; i--, j--) - if (TOLOWER (string[i]) != TOLOWER (tail[j])) + if (c_tolower (string[i]) != c_tolower (tail[j])) break; } @@ -1216,6 +1268,12 @@ get_grouping_data (const char **sep, const char **grouping) struct lconv *lconv = localeconv (); cached_sep = lconv->thousands_sep; cached_grouping = lconv->grouping; +#if ! USE_NLS_PROGRESS_BAR + /* We can't count column widths, so ensure that the separator + * is single-byte only (let check below determine what byte). */ + if (strlen(cached_sep) > 1) + cached_sep = ""; +#endif if (!*cached_sep) { /* Many locales (such as "C" or "hr_HR") don't specify @@ -1328,7 +1386,7 @@ human_readable (HR_NUMTYPE n) 'E', /* exabyte, 2^60 bytes */ }; static char buf[8]; - int i; + size_t i; /* If the quantity is smaller than 1K, just print it. */ if (n < 1024) @@ -1937,7 +1995,7 @@ base64_encode (const void *data, int length, char *dest) when end of string is reached. */ #define NEXT_CHAR(c, p) do { \ c = (unsigned char) *p++; \ -} while (ISSPACE (c)) +} while (c_isspace (c)) #define IS_ASCII(c) (((c) & 0x80) == 0) @@ -2164,7 +2222,17 @@ test_dir_matches_p() { { "/somedir", "/someotherdir", NULL }, "anotherdir", false }, { { "/somedir", "/*otherdir", NULL }, "anotherdir", true }, { { "/somedir/d1", "/someotherdir", NULL }, "somedir/d1", true }, + { { "*/*d1", "/someotherdir", NULL }, "somedir/d1", true }, { { "/somedir/d1", "/someotherdir", NULL }, "d1", false }, + { { "!COMPLETE", NULL, NULL }, "!COMPLETE", true }, + { { "*COMPLETE", NULL, NULL }, "!COMPLETE", true }, + { { "*/!COMPLETE", NULL, NULL }, "foo/!COMPLETE", true }, + { { "*COMPLETE", NULL, NULL }, "foo/!COMPLETE", false }, + { { "*/*COMPLETE", NULL, NULL }, "foo/!COMPLETE", true }, + { { "/dir with spaces", NULL, NULL }, "dir with spaces", true }, + { { "/dir*with*spaces", NULL, NULL }, "dir with spaces", true }, + { { "/Tmp/has", NULL, NULL }, "/Tmp/has space", false }, + { { "/Tmp/has", NULL, NULL }, "/Tmp/has,comma", false }, }; for (i = 0; i < countof(test_array); ++i)