]> sjero.net Git - wget/blobdiff - src/log.c
[svn] Merge of fix for bugs 20341 and 20410.
[wget] / src / log.c
index 2a9d586372ebbc85e5aaa4537ce1662493acc7c8..5de6da7d280597dc072db08c534f1f118a2be166 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -1,11 +1,11 @@
 /* Messages logging.
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 1998-2006 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
 GNU Wget 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 2 of the License, or
+the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version.
 
 GNU Wget is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@ 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 Wget; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+along with Wget.  If not, see <http://www.gnu.org/licenses/>.
 
 In addition, as a special exception, the Free Software Foundation
 gives permission to link the code of its release of Wget with the
@@ -30,17 +29,9 @@ so, delete this exception statement from your version.  */
 #include <config.h>
 
 #include <stdio.h>
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
 #include <stdlib.h>
-#ifdef WGET_USE_STDARG
-# include <stdarg.h>
-#else
-# include <varargs.h>
-#endif
+#include <stdarg.h>
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
@@ -51,10 +42,6 @@ so, delete this exception statement from your version.  */
 #include "utils.h"
 #include "log.h"
 
-#ifndef errno
-extern int errno;
-#endif
-
 /* This file impplement support for "logging".  Logging means printing
    output, plus several additional features:
 
@@ -80,18 +67,18 @@ extern int errno;
    logging is inhibited, logfp is set back to NULL. */
 static FILE *logfp;
 
-/* If non-zero, it means logging is inhibited, i.e. nothing is printed
-   or stored.  */
-static int inhibit_logging;
+/* If true, it means logging is inhibited, i.e. nothing is printed or
+   stored.  */
+static bool inhibit_logging;
 
 /* Whether the last output lines are stored for use as context.  */
-static int save_context_p;
+static bool save_context_p;
 
 /* Whether the log is flushed after each command. */
-static int flush_log_p = 1;
+static bool flush_log_p = true;
 
 /* Whether any output has been received while flush_log_p was 0. */
-static int needs_flushing;
+static bool needs_flushing;
 
 /* In the event of a hang-up, and if its output was on a TTY, Wget
    redirects its output to `wget-log'.
@@ -135,9 +122,9 @@ static int log_line_current = -1;
    finish with \n.  This is an important piece of information because
    the code is always careful to append data to trailing lines, rather
    than create new ones.  */
-static int trailing_line;
+static bool trailing_line;
 
-static void check_redirect_output PARAMS ((void));
+static void check_redirect_output (void);
 \f
 #define ROT_ADVANCE(num) do {                  \
   if (++num >= SAVED_LOG_LINES)                        \
@@ -220,7 +207,7 @@ saved_append_1 (const char *start, const char *end)
            {
              /* Allocate memory and concatenate the old and the new
                  contents. */
-             ln->malloced_line = (char *)xmalloc (old_len + len + 1);
+             ln->malloced_line = xmalloc (old_len + len + 1);
              memcpy (ln->malloced_line, ln->static_line,
                      old_len);
              memcpy (ln->malloced_line + old_len, start, len);
@@ -325,7 +312,7 @@ logputs (enum log_options o, const char *s)
   if (flush_log_p)
     logflush ();
   else
-    needs_flushing = 1;
+    needs_flushing = true;
 }
 
 struct logvprintf_state {
@@ -348,7 +335,7 @@ struct logvprintf_state {
    (An alternative approach would be to use va_copy, but that's not
    portable.)  */
 
-static int
+static bool
 log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
                      va_list args)
 {
@@ -381,12 +368,12 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
   numwritten = vsnprintf (write_ptr, available_size, fmt, args);
 
   /* vsnprintf() will not step over the limit given by available_size.
-     If it fails, it will return either -1 (POSIX?) or the number of
-     characters that *would have* been written, if there had been
-     enough room (C99).  In the former case, we double the
-     available_size and malloc to get a larger buffer, and try again.
-     In the latter case, we use the returned information to build a
-     buffer of the correct size.  */
+     If it fails, it returns either -1 (older implementations) or the
+     number of characters (not counting the terminating \0) that
+     *would have* been written if there had been enough room (C99).
+     In the former case, we double available_size and malloc to get a
+     larger buffer, and try again.  In the latter case, we use the
+     returned information to build a buffer of the correct size.  */
 
   if (numwritten == -1)
     {
@@ -395,7 +382,7 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
       int newsize = available_size << 1;
       state->bigmsg = xrealloc (state->bigmsg, newsize);
       state->allocated = newsize;
-      return 0;
+      return false;
     }
   else if (numwritten >= available_size)
     {
@@ -404,7 +391,7 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
       int newsize = numwritten + 1;
       state->bigmsg = xrealloc (state->bigmsg, newsize);
       state->allocated = newsize;
-      return 0;
+      return false;
     }
 
   /* Writing succeeded. */
@@ -417,9 +404,9 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
   if (flush_log_p)
     logflush ();
   else
-    needs_flushing = 1;
+    needs_flushing = true;
 
-  return 1;
+  return true;
 }
 
 /* Flush LOGFP.  Useful while flushing is disabled.  */
@@ -429,20 +416,20 @@ logflush (void)
   FILE *fp = get_log_fp ();
   if (fp)
     fflush (fp);
-  needs_flushing = 0;
+  needs_flushing = false;
 }
 
 /* Enable or disable log flushing. */
 void
-log_set_flush (int flush)
+log_set_flush (bool flush)
 {
   if (flush == flush_log_p)
     return;
 
-  if (flush == 0)
+  if (flush == false)
     {
       /* Disable flushing by setting flush_log_p to 0. */
-      flush_log_p = 0;
+      flush_log_p = false;
     }
   else
     {
@@ -450,7 +437,7 @@ log_set_flush (int flush)
         flush the log now.  */
       if (needs_flushing)
        logflush ();
-      flush_log_p = 1;
+      flush_log_p = true;
     }
 }
 
@@ -458,24 +445,14 @@ log_set_flush (int flush)
    status of storing, with which this function can be called again to
    reestablish storing. */
 
-int
-log_set_save_context (int savep)
+bool
+log_set_save_context (bool savep)
 {
-  int old = save_context_p;
+  bool old = save_context_p;
   save_context_p = savep;
   return old;
 }
 
-/* Handle difference in va_start between pre-ANSI and ANSI C.  Note
-   that we always use `...' in function definitions and let ansi2knr
-   convert it for us.  */
-
-#ifdef WGET_USE_STDARG
-# define VA_START(args, arg1) va_start (args, arg1)
-#else
-# define VA_START(args, ignored) va_start (args)
-#endif
-
 /* Print a message to the screen or to the log.  The first argument
    defines the verbosity of the message, and the rest are as in
    printf(3).  */
@@ -485,7 +462,7 @@ logprintf (enum log_options o, const char *fmt, ...)
 {
   va_list args;
   struct logvprintf_state lpstate;
-  int done;
+  bool done;
 
   check_redirect_output ();
   if (inhibit_logging)
@@ -495,7 +472,7 @@ logprintf (enum log_options o, const char *fmt, ...)
   xzero (lpstate);
   do
     {
-      VA_START (args, fmt);
+      va_start (args, fmt);
       done = log_vprintf_internal (&lpstate, fmt, args);
       va_end (args);
     }
@@ -504,7 +481,7 @@ logprintf (enum log_options o, const char *fmt, ...)
 
 #ifdef ENABLE_DEBUG
 /* The same as logprintf(), but does anything only if opt.debug is
-   non-zero.  */
+   true.  */
 void
 debug_logprintf (const char *fmt, ...)
 {
@@ -512,7 +489,7 @@ debug_logprintf (const char *fmt, ...)
     {
       va_list args;
       struct logvprintf_state lpstate;
-      int done;
+      bool done;
 
       check_redirect_output ();
       if (inhibit_logging)
@@ -521,7 +498,7 @@ debug_logprintf (const char *fmt, ...)
       xzero (lpstate);
       do
        {
-         VA_START (args, fmt);
+         va_start (args, fmt);
          done = log_vprintf_internal (&lpstate, fmt, args);
          va_end (args);
        }
@@ -533,7 +510,7 @@ debug_logprintf (const char *fmt, ...)
 /* Open FILE and set up a logging stream.  If FILE cannot be opened,
    exit with status of 1.  */
 void
-log_init (const char *file, int appendp)
+log_init (const char *file, bool appendp)
 {
   if (file)
     {
@@ -564,7 +541,7 @@ log_init (const char *file, int appendp)
             the most recent several messages ("context") and dump
             them to a log file in case SIGHUP or SIGUSR1 is received
             (or Ctrl+Break is pressed under Windows).  */
-         save_context_p = 1;
+         save_context_p = true;
        }
     }
 }
@@ -579,13 +556,13 @@ log_close (void)
   if (logfp)
     fclose (logfp);
   logfp = NULL;
-  inhibit_logging = 1;
-  save_context_p = 0;
+  inhibit_logging = true;
+  save_context_p = false;
 
   for (i = 0; i < SAVED_LOG_LINES; i++)
     free_log_line (i);
   log_line_current = -1;
-  trailing_line = 0;
+  trailing_line = false;
 }
 
 /* Dump saved lines to logfp. */
@@ -704,10 +681,11 @@ static const char *
 escnonprint_internal (const char *str, char escape, int base)
 {
   static int ringpos;                  /* current ring position */
+  int nprcnt;
 
   assert (base == 8 || base == 16);
 
-  int nprcnt = count_nonprint (str);
+  nprcnt = count_nonprint (str);
   if (nprcnt == 0)
     /* If there are no non-printable chars in STR, don't bother
        copying anything, just return STR.  */
@@ -743,6 +721,18 @@ escnonprint_internal (const char *str, char escape, int base)
    characters in STR, STR is returned.  See copy_and_escape for more
    information on which characters are considered non-printable.
 
+   DON'T call this function on translated strings because escaping
+   will break them.  Don't call it on literal strings from the source,
+   which are by definition trusted.  If newlines are allowed in the
+   string, escape and print it line by line because escaping the whole
+   string will convert newlines to \012.  (This is so that expectedly
+   single-line messages cannot use embedded newlines to mimic Wget's
+   output and deceive the user.)
+
+   escnonprint doesn't quote its escape character because it is notf
+   meant as a general and reversible quoting mechanism, but as a quick
+   way to defang binary junk sent by malicious or buggy servers.
+
    NOTE: since this function can return a pointer to static data, be
    careful to copy its result before calling it again.  However, to be
    more useful with printf, it maintains an internal ring of static
@@ -758,11 +748,9 @@ escnonprint (const char *str)
 
 /* Return a pointer to a static copy of STR with the non-printable
    characters escaped as %XX.  If there are no non-printable
-   characters in STR, STR is returned.  See copy_and_escape for more
-   information on which characters are considered non-printable.
+   characters in STR, STR is returned.
 
-   This function returns a pointer to static data which will be
-   overwritten by subsequent calls -- see escnonprint for details.  */
+   See escnonprint for usage details.  */
 
 const char *
 escnonprint_uri (const char *str)
@@ -780,7 +768,7 @@ log_cleanup (void)
 \f
 /* When SIGHUP or SIGUSR1 are received, the output is redirected
    elsewhere.  Such redirection is only allowed once. */
-enum { RR_NONE, RR_REQUESTED, RR_DONE } redirect_request = RR_NONE;
+static enum { RR_NONE, RR_REQUESTED, RR_DONE } redirect_request = RR_NONE;
 static const char *redirect_request_signal_name;
 
 /* Redirect output to `wget-log'.  */
@@ -789,7 +777,7 @@ static void
 redirect_output (void)
 {
   char *logfile;
-  logfp = unique_create (DEFAULT_LOGFILE, 0, &logfile);
+  logfp = unique_create (DEFAULT_LOGFILE, false, &logfile);
   if (logfp)
     {
       fprintf (stderr, _("\n%s received, redirecting output to `%s'.\n"),
@@ -805,9 +793,9 @@ redirect_output (void)
       fprintf (stderr, _("\n%s received.\n"), redirect_request_signal_name);
       fprintf (stderr, _("%s: %s; disabling logging.\n"),
               logfile, strerror (errno));
-      inhibit_logging = 1;
+      inhibit_logging = true;
     }
-  save_context_p = 0;
+  save_context_p = false;
 }
 
 /* Check whether a signal handler requested the output to be