X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=src%2Flog.c;h=4f93a21cb050446b7325092d5bcf66e9abdbea83;hb=eee1589ef3d198a21635d15c9086df2b99f9013d;hp=ee9f0693e18c61047463b391d3853055f4bba8e3;hpb=83feeb39275a1d00932e3361ec8d598d1276d0ae;p=wget
diff --git a/src/log.c b/src/log.c
index ee9f0693..4f93a21c 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1,11 +1,12 @@
/* Messages logging.
- Copyright (C) 1998-2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+ 2007, 2008, 2009, 2010, 2011 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,36 +15,46 @@ 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.,
-51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+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
#include
#include
-#ifdef HAVE_UNISTD_H
-# include
-#endif
+#include
#include
#include
-#include "wget.h"
#include "utils.h"
#include "log.h"
-/* This file impplement 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 implements support for "logging". Logging means printing
output, plus several additional features:
- Cataloguing output by importance. You can specify that a log
@@ -68,6 +79,10 @@ so, delete this exception statement from your version. */
logging is inhibited, logfp is set back to NULL. */
static FILE *logfp;
+/* A second file descriptor pointing to the temporary log file for the
+ WARC writer. If WARC writing is disabled, this is NULL. */
+static FILE *warclogfp;
+
/* If true, it means logging is inhibited, i.e. nothing is printed or
stored. */
static bool inhibit_logging;
@@ -108,9 +123,9 @@ static bool needs_flushing;
static struct log_ln {
char static_line[STATIC_LENGTH + 1]; /* statically allocated
line. */
- char *malloced_line; /* malloc'ed line, for lines of output
+ char *malloced_line; /* malloc'ed line, for lines of output
larger than 80 characters. */
- char *content; /* this points either to malloced_line
+ char *content; /* this points either to malloced_line
or to the appropriate static_line.
If this is NULL, it means the line
has not yet been used. */
@@ -127,9 +142,9 @@ static bool trailing_line;
static void check_redirect_output (void);
-#define ROT_ADVANCE(num) do { \
- if (++num >= SAVED_LOG_LINES) \
- num = 0; \
+#define ROT_ADVANCE(num) do { \
+ if (++num >= SAVED_LOG_LINES) \
+ num = 0; \
} while (0)
/* Free the log line index with NUM. This calls free on
@@ -167,21 +182,21 @@ saved_append_1 (const char *start, const char *end)
struct log_ln *ln;
if (log_line_current == -1)
- log_line_current = 0;
+ log_line_current = 0;
else
- free_log_line (log_line_current);
+ free_log_line (log_line_current);
ln = log_lines + log_line_current;
if (len > STATIC_LENGTH)
- {
- ln->malloced_line = strdupdelim (start, end);
- ln->content = ln->malloced_line;
- }
+ {
+ ln->malloced_line = strdupdelim (start, end);
+ ln->content = ln->malloced_line;
+ }
else
- {
- memcpy (ln->static_line, start, len);
- ln->static_line[len] = '\0';
- ln->content = ln->static_line;
- }
+ {
+ memcpy (ln->static_line, start, len);
+ ln->static_line[len] = '\0';
+ ln->content = ln->static_line;
+ }
}
else
{
@@ -192,38 +207,38 @@ saved_append_1 (const char *start, const char *end)
convert it to malloc(). */
struct log_ln *ln = log_lines + log_line_current;
if (ln->malloced_line)
- {
- /* Resize malloc'ed line and append. */
- int old_len = strlen (ln->malloced_line);
- ln->malloced_line = xrealloc (ln->malloced_line, old_len + len + 1);
- memcpy (ln->malloced_line + old_len, start, len);
- ln->malloced_line[old_len + len] = '\0';
- /* might have changed due to realloc */
- ln->content = ln->malloced_line;
- }
+ {
+ /* Resize malloc'ed line and append. */
+ int old_len = strlen (ln->malloced_line);
+ ln->malloced_line = xrealloc (ln->malloced_line, old_len + len + 1);
+ memcpy (ln->malloced_line + old_len, start, len);
+ ln->malloced_line[old_len + len] = '\0';
+ /* might have changed due to realloc */
+ ln->content = ln->malloced_line;
+ }
else
- {
- int old_len = strlen (ln->static_line);
- if (old_len + len > STATIC_LENGTH)
- {
- /* Allocate memory and concatenate the old and the new
+ {
+ int old_len = strlen (ln->static_line);
+ if (old_len + len > STATIC_LENGTH)
+ {
+ /* Allocate memory and concatenate the old and the new
contents. */
- 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);
- ln->malloced_line[old_len + len] = '\0';
- ln->content = ln->malloced_line;
- }
- else
- {
- /* Just append to the old, statically allocated
+ 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);
+ ln->malloced_line[old_len + len] = '\0';
+ ln->content = ln->malloced_line;
+ }
+ else
+ {
+ /* Just append to the old, statically allocated
contents. */
- memcpy (ln->static_line + old_len, start, len);
- ln->static_line[old_len + len] = '\0';
- ln->content = ln->static_line;
- }
- }
+ memcpy (ln->static_line + old_len, start, len);
+ ln->static_line[old_len + len] = '\0';
+ ln->content = ln->static_line;
+ }
+ }
}
trailing_line = !(end[-1] == '\n');
if (!trailing_line)
@@ -242,9 +257,9 @@ saved_append (const char *s)
{
const char *end = strchr (s, '\n');
if (!end)
- end = s + strlen (s);
+ end = s + strlen (s);
else
- ++end;
+ ++end;
saved_append_1 (s, end);
s = end;
}
@@ -260,22 +275,22 @@ saved_append (const char *s)
* LOG_NONVERBOSE - print the message if opt.verbose is zero;
* LOG_VERBOSE - print the message if opt.verbose is non-zero. */
-#define CHECK_VERBOSE(x) \
- switch (x) \
- { \
- case LOG_ALWAYS: \
- break; \
- case LOG_NOTQUIET: \
- if (opt.quiet) \
- return; \
- break; \
- case LOG_NONVERBOSE: \
- if (opt.verbose || opt.quiet) \
- return; \
- break; \
- case LOG_VERBOSE: \
- if (!opt.verbose) \
- return; \
+#define CHECK_VERBOSE(x) \
+ switch (x) \
+ { \
+ case LOG_ALWAYS: \
+ break; \
+ case LOG_NOTQUIET: \
+ if (opt.quiet) \
+ return; \
+ break; \
+ case LOG_NONVERBOSE: \
+ if (opt.verbose || opt.quiet) \
+ return; \
+ break; \
+ case LOG_VERBOSE: \
+ if (!opt.verbose) \
+ return; \
}
/* Returns the file descriptor for logging. This is LOGFP, except if
@@ -293,6 +308,31 @@ get_log_fp (void)
return logfp;
return stderr;
}
+
+/* Returns the file descriptor for the secondary log file. This is
+ WARCLOGFP, except if called before log_init, in which case it
+ returns stderr. This is useful in case someone calls a logging
+ function before log_init.
+
+ If logging is inhibited, return NULL. */
+
+static FILE *
+get_warc_log_fp (void)
+{
+ if (inhibit_logging)
+ return NULL;
+ if (warclogfp)
+ return warclogfp;
+ return NULL;
+}
+
+/* Sets the file descriptor for the secondary log file. */
+
+void
+log_set_warc_log_fp (FILE * fp)
+{
+ warclogfp = fp;
+}
/* Log a literal string S. The string is logged as-is, without a
newline appended. */
@@ -301,13 +341,17 @@ void
logputs (enum log_options o, const char *s)
{
FILE *fp;
+ FILE *warcfp;
check_redirect_output ();
if ((fp = get_log_fp ()) == NULL)
return;
+ warcfp = get_warc_log_fp ();
CHECK_VERBOSE (o);
- fputs (s, fp);
+ FPUTS (s, fp);
+ if (warcfp != NULL)
+ FPUTS (s, warcfp);
if (save_context_p)
saved_append (s);
if (flush_log_p)
@@ -338,15 +382,16 @@ struct logvprintf_state {
static bool
log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
- va_list args)
+ va_list args)
{
char smallmsg[128];
char *write_ptr = smallmsg;
int available_size = sizeof (smallmsg);
int numwritten;
FILE *fp = get_log_fp ();
+ FILE *warcfp = get_warc_log_fp ();
- if (!save_context_p)
+ if (!save_context_p && warcfp == NULL)
{
/* In the simple case just call vfprintf(), to avoid needless
allocation and games with vsnprintf(). */
@@ -379,7 +424,7 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
if (numwritten == -1)
{
/* Writing failed, and we don't know the needed size. Try
- again with doubled size. */
+ again with doubled size. */
int newsize = available_size << 1;
state->bigmsg = xrealloc (state->bigmsg, newsize);
state->allocated = newsize;
@@ -388,7 +433,7 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
else if (numwritten >= available_size)
{
/* Writing failed, but we know exactly how much space we
- need. */
+ need. */
int newsize = numwritten + 1;
state->bigmsg = xrealloc (state->bigmsg, newsize);
state->allocated = newsize;
@@ -396,8 +441,11 @@ log_vprintf_internal (struct logvprintf_state *state, const char *fmt,
}
/* Writing succeeded. */
- saved_append (write_ptr);
- fputs (write_ptr, fp);
+ if (save_context_p)
+ saved_append (write_ptr);
+ FPUTS (write_ptr, fp);
+ if (warcfp != NULL)
+ FPUTS (write_ptr, warcfp);
if (state->bigmsg)
xfree (state->bigmsg);
@@ -415,8 +463,25 @@ void
logflush (void)
{
FILE *fp = get_log_fp ();
+ FILE *warcfp = get_warc_log_fp ();
if (fp)
- fflush (fp);
+ {
+/* 2005-10-25 SMS.
+ On VMS, flush only for a terminal. See note at FPUTS macro, above.
+*/
+#ifdef __VMS
+ if (isatty( fileno( fp)))
+ {
+ fflush (fp);
+ }
+#else /* def __VMS */
+ fflush (fp);
+#endif /* def __VMS [else] */
+ }
+
+ if (warcfp != NULL)
+ fflush (warcfp);
+
needs_flushing = false;
}
@@ -435,9 +500,9 @@ log_set_flush (bool flush)
else
{
/* Reenable flushing. If anything was printed in no-flush mode,
- flush the log now. */
+ flush the log now. */
if (needs_flushing)
- logflush ();
+ logflush ();
flush_log_p = true;
}
}
@@ -476,6 +541,9 @@ logprintf (enum log_options o, const char *fmt, ...)
va_start (args, fmt);
done = log_vprintf_internal (&lpstate, fmt, args);
va_end (args);
+
+ if (done && errno == EPIPE)
+ exit (1);
}
while (!done);
}
@@ -494,15 +562,15 @@ debug_logprintf (const char *fmt, ...)
check_redirect_output ();
if (inhibit_logging)
- return;
+ return;
xzero (lpstate);
do
- {
- va_start (args, fmt);
- done = log_vprintf_internal (&lpstate, fmt, args);
- va_end (args);
- }
+ {
+ va_start (args, fmt);
+ done = log_vprintf_internal (&lpstate, fmt, args);
+ va_end (args);
+ }
while (!done);
}
}
@@ -517,10 +585,10 @@ log_init (const char *file, bool appendp)
{
logfp = fopen (file, appendp ? "a" : "w");
if (!logfp)
- {
- fprintf (stderr, "%s: %s: %s\n", exec_name, file, strerror (errno));
- exit (1);
- }
+ {
+ fprintf (stderr, "%s: %s: %s\n", exec_name, file, strerror (errno));
+ exit (1);
+ }
}
else
{
@@ -534,27 +602,27 @@ log_init (const char *file, bool appendp)
if (1
#ifdef HAVE_ISATTY
- && isatty (fileno (logfp))
+ && isatty (fileno (logfp))
#endif
- )
- {
- /* If the output is a TTY, enable save context, i.e. store
- 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 = true;
- }
+ )
+ {
+ /* If the output is a TTY, enable save context, i.e. store
+ 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 = true;
+ }
}
}
-/* Close LOGFP, inhibit further logging and free the memory associated
- with it. */
+/* Close LOGFP (only if we opened it, not if it's stderr), inhibit
+ further logging and free the memory associated with it. */
void
log_close (void)
{
int i;
- if (logfp)
+ if (logfp && (logfp != stderr))
fclose (logfp);
logfp = NULL;
inhibit_logging = true;
@@ -572,6 +640,7 @@ log_dump_context (void)
{
int num = log_line_current;
FILE *fp = get_log_fp ();
+ FILE *warcfp = get_warc_log_fp ();
if (!fp)
return;
@@ -583,20 +652,29 @@ log_dump_context (void)
{
struct log_ln *ln = log_lines + num;
if (ln->content)
- fputs (ln->content, fp);
+ {
+ FPUTS (ln->content, fp);
+ if (warcfp != NULL)
+ FPUTS (ln->content, warcfp);
+ }
ROT_ADVANCE (num);
}
while (num != log_line_current);
if (trailing_line)
if (log_lines[log_line_current].content)
- fputs (log_lines[log_line_current].content, fp);
+ {
+ FPUTS (log_lines[log_line_current].content, fp);
+ if (warcfp != NULL)
+ FPUTS (log_lines[log_line_current].content, warcfp);
+ }
fflush (fp);
+ fflush (warcfp);
}
/* String escape functions. */
/* Return the number of non-printable characters in SOURCE.
- Non-printable characters are determined as per safe-ctype.c. */
+ Non-printable characters are determined as per c-ctype.c. */
static int
count_nonprint (const char *source)
@@ -604,7 +682,7 @@ count_nonprint (const char *source)
const char *p;
int cnt;
for (p = source, cnt = 0; *p; p++)
- if (!ISPRINT (*p))
+ if (!c_isprint (*p))
++cnt;
return cnt;
}
@@ -644,26 +722,26 @@ copy_and_escape (const char *source, char *dest, char escape, int base)
{
case 8:
while ((c = *from++) != '\0')
- if (ISPRINT (c))
- *to++ = c;
- else
- {
- *to++ = escape;
- *to++ = '0' + (c >> 6);
- *to++ = '0' + ((c >> 3) & 7);
- *to++ = '0' + (c & 7);
- }
+ if (c_isprint (c))
+ *to++ = c;
+ else
+ {
+ *to++ = escape;
+ *to++ = '0' + (c >> 6);
+ *to++ = '0' + ((c >> 3) & 7);
+ *to++ = '0' + (c & 7);
+ }
break;
case 16:
while ((c = *from++) != '\0')
- if (ISPRINT (c))
- *to++ = c;
- else
- {
- *to++ = escape;
- *to++ = XNUM_TO_DIGIT (c >> 4);
- *to++ = XNUM_TO_DIGIT (c & 0xf);
- }
+ if (c_isprint (c))
+ *to++ = c;
+ else
+ {
+ *to++ = escape;
+ *to++ = XNUM_TO_DIGIT (c >> 4);
+ *to++ = XNUM_TO_DIGIT (c & 0xf);
+ }
break;
default:
abort ();
@@ -676,12 +754,12 @@ struct ringel {
char *buffer;
int size;
};
-static struct ringel ring[RING_SIZE]; /* ring data */
+static struct ringel ring[RING_SIZE]; /* ring data */
static const char *
escnonprint_internal (const char *str, char escape, int base)
{
- static int ringpos; /* current ring position */
+ static int ringpos; /* current ring position */
int nprcnt;
assert (base == 8 || base == 16);
@@ -707,8 +785,8 @@ escnonprint_internal (const char *str, char escape, int base)
(re)allocate it. */
if (r->buffer == NULL || r->size < needed_size)
{
- r->buffer = xrealloc (r->buffer, needed_size);
- r->size = needed_size;
+ r->buffer = xrealloc (r->buffer, needed_size);
+ r->size = needed_size;
}
copy_and_escape (str, r->buffer, escape, base);
@@ -762,7 +840,7 @@ escnonprint_uri (const char *str)
void
log_cleanup (void)
{
- int i;
+ size_t i;
for (i = 0; i < countof (ring); i++)
xfree_null (ring[i].buffer);
}
@@ -781,8 +859,8 @@ redirect_output (void)
logfp = unique_create (DEFAULT_LOGFILE, false, &logfile);
if (logfp)
{
- fprintf (stderr, _("\n%s received, redirecting output to `%s'.\n"),
- redirect_request_signal_name, logfile);
+ fprintf (stderr, _("\n%s received, redirecting output to %s.\n"),
+ redirect_request_signal_name, quote (logfile));
xfree (logfile);
/* Dump the context output to the newly opened log. */
log_dump_context ();
@@ -793,7 +871,7 @@ redirect_output (void)
can do but disable printing completely. */
fprintf (stderr, _("\n%s received.\n"), redirect_request_signal_name);
fprintf (stderr, _("%s: %s; disabling logging.\n"),
- logfile, strerror (errno));
+ (logfile) ? logfile : DEFAULT_LOGFILE, strerror (errno));
inhibit_logging = true;
}
save_context_p = false;