]> sjero.net Git - wget/blob - src/log.c
Fix compiler warnings
[wget] / src / log.c
1 /* Messages logging.
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3    2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4
5 This file is part of GNU Wget.
6
7 GNU Wget is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU Wget is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
19
20 Additional permission under GNU GPL version 3 section 7
21
22 If you modify this program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a
24 modified version of that library), containing parts covered by the
25 terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
26 grants you additional permission to convey the resulting work.
27 Corresponding Source for a non-source form of such a combination
28 shall include the source code for the parts of OpenSSL used as well
29 as that of the covered work.  */
30
31 #include "wget.h"
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <unistd.h>
38 #include <assert.h>
39 #include <errno.h>
40
41 #include "utils.h"
42 #include "log.h"
43
44 /* 2005-10-25 SMS.
45    VMS log files are often VFC record format, not stream, so fputs() can
46    produce multiple records, even when there's no newline terminator in
47    the buffer.  The result is unsightly output with spurious newlines.
48    Using fprintf() instead of fputs(), along with inhibiting some
49    fflush() activity below, seems to solve the problem.
50 */
51 #ifdef __VMS
52 # define FPUTS( s, f) fprintf( (f), "%s", (s))
53 #else /* def __VMS */
54 # define FPUTS( s, f) fputs( (s), (f))
55 #endif /* def __VMS [else] */
56
57 /* This file implements support for "logging".  Logging means printing
58    output, plus several additional features:
59
60    - Cataloguing output by importance.  You can specify that a log
61    message is "verbose" or "debug", and it will not be printed unless
62    in verbose or debug mode, respectively.
63
64    - Redirecting the log to the file.  When Wget's output goes to the
65    terminal, and Wget receives SIGHUP, all further output is
66    redirected to a log file.  When this is the case, Wget can also
67    print the last several lines of "context" to the log file so that
68    it does not begin in the middle of a line.  For this to work, the
69    logging code stores the last several lines of context.  Callers may
70    request for certain output not to be stored.
71
72    - Inhibiting output.  When Wget receives SIGHUP, but redirecting
73    the output fails, logging is inhibited.  */
74
75 \f
76 /* The file descriptor used for logging.  This is NULL before log_init
77    is called; logging functions log to stderr then.  log_init sets it
78    either to stderr or to a file pointer obtained from fopen().  If
79    logging is inhibited, logfp is set back to NULL. */
80 static FILE *logfp;
81
82 /* A second file descriptor pointing to the temporary log file for the
83    WARC writer.  If WARC writing is disabled, this is NULL.  */
84 static FILE *warclogfp;
85
86 /* If true, it means logging is inhibited, i.e. nothing is printed or
87    stored.  */
88 static bool inhibit_logging;
89
90 /* Whether the last output lines are stored for use as context.  */
91 static bool save_context_p;
92
93 /* Whether the log is flushed after each command. */
94 static bool flush_log_p = true;
95
96 /* Whether any output has been received while flush_log_p was 0. */
97 static bool needs_flushing;
98
99 /* In the event of a hang-up, and if its output was on a TTY, Wget
100    redirects its output to `wget-log'.
101
102    For the convenience of reading this newly-created log, we store the
103    last several lines ("screenful", hence the choice of 24) of Wget
104    output, and dump them as context when the time comes.  */
105 #define SAVED_LOG_LINES 24
106
107 /* log_lines is a circular buffer that stores SAVED_LOG_LINES lines of
108    output.  log_line_current always points to the position in the
109    buffer that will be written to next.  When log_line_current reaches
110    SAVED_LOG_LINES, it is reset to zero.
111
112    The problem here is that we'd have to either (re)allocate and free
113    strings all the time, or limit the lines to an arbitrary number of
114    characters.  Instead of settling for either of these, we do both:
115    if the line is smaller than a certain "usual" line length (128
116    chars by default), a preallocated memory is used.  The rare lines
117    that are longer than 128 characters are malloc'ed and freed
118    separately.  This gives good performance with minimum memory
119    consumption and fragmentation.  */
120
121 #define STATIC_LENGTH 128
122
123 static struct log_ln {
124   char static_line[STATIC_LENGTH + 1]; /* statically allocated
125                                           line. */
126   char *malloced_line;          /* malloc'ed line, for lines of output
127                                    larger than 80 characters. */
128   char *content;                /* this points either to malloced_line
129                                    or to the appropriate static_line.
130                                    If this is NULL, it means the line
131                                    has not yet been used. */
132 } log_lines[SAVED_LOG_LINES];
133
134 /* The current position in the ring. */
135 static int log_line_current = -1;
136
137 /* Whether the most recently written line was "trailing", i.e. did not
138    finish with \n.  This is an important piece of information because
139    the code is always careful to append data to trailing lines, rather
140    than create new ones.  */
141 static bool trailing_line;
142
143 static void check_redirect_output (void);
144 \f
145 #define ROT_ADVANCE(num) do {                   \
146   if (++num >= SAVED_LOG_LINES)                 \
147     num = 0;                                    \
148 } while (0)
149
150 /* Free the log line index with NUM.  This calls free on
151    ln->malloced_line if it's non-NULL, and it also resets
152    ln->malloced_line and ln->content to NULL.  */
153
154 static void
155 free_log_line (int num)
156 {
157   struct log_ln *ln = log_lines + num;
158   if (ln->malloced_line)
159     {
160       xfree (ln->malloced_line);
161       ln->malloced_line = NULL;
162     }
163   ln->content = NULL;
164 }
165
166 /* Append bytes in the range [start, end) to one line in the log.  The
167    region is not supposed to contain newlines, except for the last
168    character (at end[-1]).  */
169
170 static void
171 saved_append_1 (const char *start, const char *end)
172 {
173   int len = end - start;
174   if (!len)
175     return;
176
177   /* First, check whether we need to append to an existing line or to
178      create a new one.  */
179   if (!trailing_line)
180     {
181       /* Create a new line. */
182       struct log_ln *ln;
183
184       if (log_line_current == -1)
185         log_line_current = 0;
186       else
187         free_log_line (log_line_current);
188       ln = log_lines + log_line_current;
189       if (len > STATIC_LENGTH)
190         {
191           ln->malloced_line = strdupdelim (start, end);
192           ln->content = ln->malloced_line;
193         }
194       else
195         {
196           memcpy (ln->static_line, start, len);
197           ln->static_line[len] = '\0';
198           ln->content = ln->static_line;
199         }
200     }
201   else
202     {
203       /* Append to the last line.  If the line is malloc'ed, we just
204          call realloc and append the new string.  If the line is
205          static, we have to check whether appending the new string
206          would make it exceed STATIC_LENGTH characters, and if so,
207          convert it to malloc(). */
208       struct log_ln *ln = log_lines + log_line_current;
209       if (ln->malloced_line)
210         {
211           /* Resize malloc'ed line and append. */
212           int old_len = strlen (ln->malloced_line);
213           ln->malloced_line = xrealloc (ln->malloced_line, old_len + len + 1);
214           memcpy (ln->malloced_line + old_len, start, len);
215           ln->malloced_line[old_len + len] = '\0';
216           /* might have changed due to realloc */
217           ln->content = ln->malloced_line;
218         }
219       else
220         {
221           int old_len = strlen (ln->static_line);
222           if (old_len + len > STATIC_LENGTH)
223             {
224               /* Allocate memory and concatenate the old and the new
225                  contents. */
226               ln->malloced_line = xmalloc (old_len + len + 1);
227               memcpy (ln->malloced_line, ln->static_line,
228                       old_len);
229               memcpy (ln->malloced_line + old_len, start, len);
230               ln->malloced_line[old_len + len] = '\0';
231               ln->content = ln->malloced_line;
232             }
233           else
234             {
235               /* Just append to the old, statically allocated
236                  contents.  */
237               memcpy (ln->static_line + old_len, start, len);
238               ln->static_line[old_len + len] = '\0';
239               ln->content = ln->static_line;
240             }
241         }
242     }
243   trailing_line = !(end[-1] == '\n');
244   if (!trailing_line)
245     ROT_ADVANCE (log_line_current);
246 }
247
248 /* Log the contents of S, as explained above.  If S consists of
249    multiple lines, they are logged separately.  If S does not end with
250    a newline, it will form a "trailing" line, to which things will get
251    appended the next time this function is called.  */
252
253 static void
254 saved_append (const char *s)
255 {
256   while (*s)
257     {
258       const char *end = strchr (s, '\n');
259       if (!end)
260         end = s + strlen (s);
261       else
262         ++end;
263       saved_append_1 (s, end);
264       s = end;
265     }
266 }
267 \f
268 /* Check X against opt.verbose and opt.quiet.  The semantics is as
269    follows:
270
271    * LOG_ALWAYS - print the message unconditionally;
272
273    * LOG_NOTQUIET - print the message if opt.quiet is non-zero;
274
275    * LOG_NONVERBOSE - print the message if opt.verbose is zero;
276
277    * LOG_VERBOSE - print the message if opt.verbose is non-zero.  */
278 #define CHECK_VERBOSE(x)                        \
279   switch (x)                                    \
280     {                                           \
281     case LOG_PROGRESS:                          \
282       if (!opt.show_progress)                   \
283         return;                                 \
284       break;                                    \
285     case LOG_ALWAYS:                            \
286       break;                                    \
287     case LOG_NOTQUIET:                          \
288       if (opt.quiet)                            \
289         return;                                 \
290       break;                                    \
291     case LOG_NONVERBOSE:                        \
292       if (opt.verbose || opt.quiet)             \
293         return;                                 \
294       break;                                    \
295     case LOG_VERBOSE:                           \
296       if (!opt.verbose)                         \
297         return;                                 \
298     }
299
300 /* Returns the file descriptor for logging.  This is LOGFP, except if
301    called before log_init, in which case it returns stderr.  This is
302    useful in case someone calls a logging function before log_init.
303
304    If logging is inhibited, return NULL.  */
305
306 static FILE *
307 get_log_fp (void)
308 {
309   if (inhibit_logging)
310     return NULL;
311   if (logfp)
312     return logfp;
313   return stderr;
314 }
315
316 /* Returns the file descriptor for the secondary log file. This is
317    WARCLOGFP, except if called before log_init, in which case it
318    returns stderr.  This is useful in case someone calls a logging
319    function before log_init.
320
321    If logging is inhibited, return NULL.  */
322
323 static FILE *
324 get_warc_log_fp (void)
325 {
326   if (inhibit_logging)
327     return NULL;
328   if (warclogfp)
329     return warclogfp;
330   return NULL;
331 }
332
333 /* Sets the file descriptor for the secondary log file.  */
334
335 void
336 log_set_warc_log_fp (FILE * fp)
337 {
338   warclogfp = fp;
339 }
340 \f
341 /* Log a literal string S.  The string is logged as-is, without a
342    newline appended.  */
343
344 void
345 logputs (enum log_options o, const char *s)
346 {
347   FILE *fp;
348   FILE *warcfp;
349
350   check_redirect_output ();
351   if ((fp = get_log_fp ()) == NULL)
352     return;
353   warcfp = get_warc_log_fp ();
354   CHECK_VERBOSE (o);
355
356   FPUTS (s, fp);
357   if (warcfp != NULL)
358     FPUTS (s, warcfp);
359   if (save_context_p)
360     saved_append (s);
361   if (flush_log_p)
362     logflush ();
363   else
364     needs_flushing = true;
365 }
366
367 struct logvprintf_state {
368   char *bigmsg;
369   int expected_size;
370   int allocated;
371 };
372
373 /* Print a message to the log.  A copy of message will be saved to
374    saved_log, for later reusal by log_dump_context().
375
376    Normally we'd want this function to loop around vsnprintf until
377    sufficient room is allocated, as the Linux man page recommends.
378    However each call to vsnprintf() must be preceded by va_start and
379    followed by va_end.  Since calling va_start/va_end is possible only
380    in the function that contains the `...' declaration, we cannot call
381    vsnprintf more than once.  Therefore this function saves its state
382    to logvprintf_state and signals the parent to call it again.
383
384    (An alternative approach would be to use va_copy, but that's not
385    portable.)  */
386
387 static bool
388 log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
389                       va_list args)
390 {
391   char smallmsg[128];
392   char *write_ptr = smallmsg;
393   int available_size = sizeof (smallmsg);
394   int numwritten;
395   FILE *fp = get_log_fp ();
396   FILE *warcfp = get_warc_log_fp ();
397
398   if (!save_context_p && warcfp == NULL)
399     {
400       /* In the simple case just call vfprintf(), to avoid needless
401          allocation and games with vsnprintf(). */
402       vfprintf (fp, fmt, args);
403       goto flush;
404     }
405
406   if (state->allocated != 0)
407     {
408       write_ptr = state->bigmsg;
409       available_size = state->allocated;
410     }
411
412   /* The GNU coding standards advise not to rely on the return value
413      of sprintf().  However, vsnprintf() is a relatively new function
414      missing from legacy systems.  Therefore I consider it safe to
415      assume that its return value is meaningful.  On the systems where
416      vsnprintf() is not available, we use the implementation from
417      snprintf.c which does return the correct value.  */
418   numwritten = vsnprintf (write_ptr, available_size, fmt, args);
419
420   /* vsnprintf() will not step over the limit given by available_size.
421      If it fails, it returns either -1 (older implementations) or the
422      number of characters (not counting the terminating \0) that
423      *would have* been written if there had been enough room (C99).
424      In the former case, we double available_size and malloc to get a
425      larger buffer, and try again.  In the latter case, we use the
426      returned information to build a buffer of the correct size.  */
427
428   if (numwritten == -1)
429     {
430       /* Writing failed, and we don't know the needed size.  Try
431          again with doubled size. */
432       int newsize = available_size << 1;
433       state->bigmsg = xrealloc (state->bigmsg, newsize);
434       state->allocated = newsize;
435       return false;
436     }
437   else if (numwritten >= available_size)
438     {
439       /* Writing failed, but we know exactly how much space we
440          need. */
441       int newsize = numwritten + 1;
442       state->bigmsg = xrealloc (state->bigmsg, newsize);
443       state->allocated = newsize;
444       return false;
445     }
446
447   /* Writing succeeded. */
448   if (save_context_p)
449     saved_append (write_ptr);
450   FPUTS (write_ptr, fp);
451   if (warcfp != NULL)
452     FPUTS (write_ptr, warcfp);
453   if (state->bigmsg)
454     xfree (state->bigmsg);
455
456  flush:
457   if (flush_log_p)
458     logflush ();
459   else
460     needs_flushing = true;
461
462   return true;
463 }
464
465 /* Flush LOGFP.  Useful while flushing is disabled.  */
466 void
467 logflush (void)
468 {
469   FILE *fp = get_log_fp ();
470   FILE *warcfp = get_warc_log_fp ();
471   if (fp)
472     {
473 /* 2005-10-25 SMS.
474    On VMS, flush only for a terminal.  See note at FPUTS macro, above.
475 */
476 #ifdef __VMS
477       if (isatty( fileno( fp)))
478         {
479           fflush (fp);
480         }
481 #else /* def __VMS */
482       fflush (fp);
483 #endif /* def __VMS [else] */
484     }
485
486   if (warcfp != NULL)
487     fflush (warcfp);
488
489   needs_flushing = false;
490 }
491
492 /* Enable or disable log flushing. */
493 void
494 log_set_flush (bool flush)
495 {
496   if (flush == flush_log_p)
497     return;
498
499   if (flush == false)
500     {
501       /* Disable flushing by setting flush_log_p to 0. */
502       flush_log_p = false;
503     }
504   else
505     {
506       /* Reenable flushing.  If anything was printed in no-flush mode,
507          flush the log now.  */
508       if (needs_flushing)
509         logflush ();
510       flush_log_p = true;
511     }
512 }
513
514 /* (Temporarily) disable storing log to memory.  Returns the old
515    status of storing, with which this function can be called again to
516    reestablish storing. */
517
518 bool
519 log_set_save_context (bool savep)
520 {
521   bool old = save_context_p;
522   save_context_p = savep;
523   return old;
524 }
525
526 /* Print a message to the screen or to the log.  The first argument
527    defines the verbosity of the message, and the rest are as in
528    printf(3).  */
529
530 void
531 logprintf (enum log_options o, const char *fmt, ...)
532 {
533   va_list args;
534   struct logvprintf_state lpstate;
535   bool done;
536
537   check_redirect_output ();
538   if (inhibit_logging)
539     return;
540   CHECK_VERBOSE (o);
541
542   xzero (lpstate);
543   do
544     {
545       va_start (args, fmt);
546       done = log_vprintf_internal (&lpstate, fmt, args);
547       va_end (args);
548
549       if (done && errno == EPIPE)
550         exit (1);
551     }
552   while (!done);
553 }
554
555 #ifdef ENABLE_DEBUG
556 /* The same as logprintf(), but does anything only if opt.debug is
557    true.  */
558 void
559 debug_logprintf (const char *fmt, ...)
560 {
561   if (opt.debug)
562     {
563       va_list args;
564       struct logvprintf_state lpstate;
565       bool done;
566
567       check_redirect_output ();
568       if (inhibit_logging)
569         return;
570
571       xzero (lpstate);
572       do
573         {
574           va_start (args, fmt);
575           done = log_vprintf_internal (&lpstate, fmt, args);
576           va_end (args);
577         }
578       while (!done);
579     }
580 }
581 #endif /* ENABLE_DEBUG */
582 \f
583 /* Open FILE and set up a logging stream.  If FILE cannot be opened,
584    exit with status of 1.  */
585 void
586 log_init (const char *file, bool appendp)
587 {
588   if (file)
589     {
590       logfp = fopen (file, appendp ? "a" : "w");
591       if (!logfp)
592         {
593           fprintf (stderr, "%s: %s: %s\n", exec_name, file, strerror (errno));
594           exit (1);
595         }
596     }
597   else
598     {
599       /* The log goes to stderr to avoid collisions with the output if
600          the user specifies `-O -'.  #### Francois Pinard suggests
601          that it's a better idea to print to stdout by default, and to
602          stderr only if the user actually specifies `-O -'.  He says
603          this inconsistency is harder to document, but is overall
604          easier on the user.  */
605       logfp = stderr;
606
607       if (1
608 #ifdef HAVE_ISATTY
609           && isatty (fileno (logfp))
610 #endif
611           )
612         {
613           /* If the output is a TTY, enable save context, i.e. store
614              the most recent several messages ("context") and dump
615              them to a log file in case SIGHUP or SIGUSR1 is received
616              (or Ctrl+Break is pressed under Windows).  */
617           save_context_p = true;
618         }
619     }
620 }
621
622 /* Close LOGFP (only if we opened it, not if it's stderr), inhibit
623    further logging and free the memory associated with it.  */
624 void
625 log_close (void)
626 {
627   int i;
628
629   if (logfp && (logfp != stderr))
630     fclose (logfp);
631   logfp = NULL;
632   inhibit_logging = true;
633   save_context_p = false;
634
635   for (i = 0; i < SAVED_LOG_LINES; i++)
636     free_log_line (i);
637   log_line_current = -1;
638   trailing_line = false;
639 }
640
641 /* Dump saved lines to logfp. */
642 static void
643 log_dump_context (void)
644 {
645   int num = log_line_current;
646   FILE *fp = get_log_fp ();
647   FILE *warcfp = get_warc_log_fp ();
648   if (!fp)
649     return;
650
651   if (num == -1)
652     return;
653   if (trailing_line)
654     ROT_ADVANCE (num);
655   do
656     {
657       struct log_ln *ln = log_lines + num;
658       if (ln->content)
659         {
660           FPUTS (ln->content, fp);
661           if (warcfp != NULL)
662             FPUTS (ln->content, warcfp);
663         }
664       ROT_ADVANCE (num);
665     }
666   while (num != log_line_current);
667   if (trailing_line)
668     if (log_lines[log_line_current].content)
669       {
670         FPUTS (log_lines[log_line_current].content, fp);
671         if (warcfp != NULL)
672           FPUTS (log_lines[log_line_current].content, warcfp);
673       }
674   fflush (fp);
675   fflush (warcfp);
676 }
677 \f
678 /* String escape functions. */
679
680 /* Return the number of non-printable characters in SOURCE.
681    Non-printable characters are determined as per c-ctype.c.  */
682
683 static int
684 count_nonprint (const char *source)
685 {
686   const char *p;
687   int cnt;
688   for (p = source, cnt = 0; *p; p++)
689     if (!c_isprint (*p))
690       ++cnt;
691   return cnt;
692 }
693
694 /* Copy SOURCE to DEST, escaping non-printable characters.
695
696    Non-printable refers to anything outside the non-control ASCII
697    range (32-126) which means that, for example, CR, LF, and TAB are
698    considered non-printable along with ESC, BS, and other control
699    chars.  This is by design: it makes sure that messages from remote
700    servers cannot be easily used to deceive the users by mimicking
701    Wget's output.  Disallowing non-ASCII characters is another
702    necessary security measure, which makes sure that remote servers
703    cannot garble the screen or guess the local charset and perform
704    homographic attacks.
705
706    Of course, the above mandates that escnonprint only be used in
707    contexts expected to be ASCII, such as when printing host names,
708    URL components, HTTP headers, FTP server messages, and the like.
709
710    ESCAPE is the leading character of the escape sequence.  BASE
711    should be the base of the escape sequence, and must be either 8 for
712    octal or 16 for hex.
713
714    DEST must point to a location with sufficient room to store an
715    encoded version of SOURCE.  */
716
717 static void
718 copy_and_escape (const char *source, char *dest, char escape, int base)
719 {
720   const char *from = source;
721   char *to = dest;
722   unsigned char c;
723
724   /* Copy chars from SOURCE to DEST, escaping non-printable ones. */
725   switch (base)
726     {
727     case 8:
728       while ((c = *from++) != '\0')
729         if (c_isprint (c))
730           *to++ = c;
731         else
732           {
733             *to++ = escape;
734             *to++ = '0' + (c >> 6);
735             *to++ = '0' + ((c >> 3) & 7);
736             *to++ = '0' + (c & 7);
737           }
738       break;
739     case 16:
740       while ((c = *from++) != '\0')
741         if (c_isprint (c))
742           *to++ = c;
743         else
744           {
745             *to++ = escape;
746             *to++ = XNUM_TO_DIGIT (c >> 4);
747             *to++ = XNUM_TO_DIGIT (c & 0xf);
748           }
749       break;
750     default:
751       abort ();
752     }
753   *to = '\0';
754 }
755
756 #define RING_SIZE 3
757 struct ringel {
758   char *buffer;
759   int size;
760 };
761 static struct ringel ring[RING_SIZE];   /* ring data */
762
763 static const char *
764 escnonprint_internal (const char *str, char escape, int base)
765 {
766   static int ringpos;                   /* current ring position */
767   int nprcnt;
768
769   assert (base == 8 || base == 16);
770
771   nprcnt = count_nonprint (str);
772   if (nprcnt == 0)
773     /* If there are no non-printable chars in STR, don't bother
774        copying anything, just return STR.  */
775     return str;
776
777   {
778     /* Set up a pointer to the current ring position, so we can write
779        simply r->X instead of ring[ringpos].X. */
780     struct ringel *r = ring + ringpos;
781
782     /* Every non-printable character is replaced with the escape char
783        and three (or two, depending on BASE) *additional* chars.  Size
784        must also include the length of the original string and one
785        additional char for the terminating \0. */
786     int needed_size = strlen (str) + 1 + (base == 8 ? 3 * nprcnt : 2 * nprcnt);
787
788     /* If the current buffer is uninitialized or too small,
789        (re)allocate it.  */
790     if (r->buffer == NULL || r->size < needed_size)
791       {
792         r->buffer = xrealloc (r->buffer, needed_size);
793         r->size = needed_size;
794       }
795
796     copy_and_escape (str, r->buffer, escape, base);
797     ringpos = (ringpos + 1) % RING_SIZE;
798     return r->buffer;
799   }
800 }
801
802 /* Return a pointer to a static copy of STR with the non-printable
803    characters escaped as \ooo.  If there are no non-printable
804    characters in STR, STR is returned.  See copy_and_escape for more
805    information on which characters are considered non-printable.
806
807    DON'T call this function on translated strings because escaping
808    will break them.  Don't call it on literal strings from the source,
809    which are by definition trusted.  If newlines are allowed in the
810    string, escape and print it line by line because escaping the whole
811    string will convert newlines to \012.  (This is so that expectedly
812    single-line messages cannot use embedded newlines to mimic Wget's
813    output and deceive the user.)
814
815    escnonprint doesn't quote its escape character because it is notf
816    meant as a general and reversible quoting mechanism, but as a quick
817    way to defang binary junk sent by malicious or buggy servers.
818
819    NOTE: since this function can return a pointer to static data, be
820    careful to copy its result before calling it again.  However, to be
821    more useful with printf, it maintains an internal ring of static
822    buffers to return.  Currently the ring size is 3, which means you
823    can print up to three values in the same printf; if more is needed,
824    bump RING_SIZE.  */
825
826 const char *
827 escnonprint (const char *str)
828 {
829   return escnonprint_internal (str, '\\', 8);
830 }
831
832 /* Return a pointer to a static copy of STR with the non-printable
833    characters escaped as %XX.  If there are no non-printable
834    characters in STR, STR is returned.
835
836    See escnonprint for usage details.  */
837
838 const char *
839 escnonprint_uri (const char *str)
840 {
841   return escnonprint_internal (str, '%', 16);
842 }
843
844 void
845 log_cleanup (void)
846 {
847   size_t i;
848   for (i = 0; i < countof (ring); i++)
849     xfree_null (ring[i].buffer);
850 }
851 \f
852 /* When SIGHUP or SIGUSR1 are received, the output is redirected
853    elsewhere.  Such redirection is only allowed once. */
854 static enum { RR_NONE, RR_REQUESTED, RR_DONE } redirect_request = RR_NONE;
855 static const char *redirect_request_signal_name;
856
857 /* Redirect output to `wget-log'.  */
858
859 static void
860 redirect_output (void)
861 {
862   char *logfile;
863   logfp = unique_create (DEFAULT_LOGFILE, false, &logfile);
864   if (logfp)
865     {
866       fprintf (stderr, _("\n%s received, redirecting output to %s.\n"),
867                redirect_request_signal_name, quote (logfile));
868       xfree (logfile);
869       /* Dump the context output to the newly opened log.  */
870       log_dump_context ();
871     }
872   else
873     {
874       /* Eek!  Opening the alternate log file has failed.  Nothing we
875          can do but disable printing completely. */
876       fprintf (stderr, _("\n%s received.\n"), redirect_request_signal_name);
877       fprintf (stderr, _("%s: %s; disabling logging.\n"),
878                (logfile) ? logfile : DEFAULT_LOGFILE, strerror (errno));
879       inhibit_logging = true;
880     }
881   save_context_p = false;
882 }
883
884 /* Check whether a signal handler requested the output to be
885    redirected. */
886
887 static void
888 check_redirect_output (void)
889 {
890   if (redirect_request == RR_REQUESTED)
891     {
892       redirect_request = RR_DONE;
893       redirect_output ();
894     }
895 }
896
897 /* Request redirection at a convenient time.  This may be called from
898    a signal handler. */
899
900 void
901 log_request_redirect_output (const char *signal_name)
902 {
903   if (redirect_request == RR_NONE && save_context_p)
904     /* Request output redirection.  The request will be processed by
905        check_redirect_output(), which is called from entry point log
906        functions. */
907     redirect_request = RR_REQUESTED;
908   redirect_request_signal_name = signal_name;
909 }