-const char errlog_rcs[] = "$Id: errlog.c,v 1.94 2009/05/19 17:47:22 fabiankeil Exp $";
+const char errlog_rcs[] = "$Id: errlog.c,v 1.110 2010/07/26 12:11:51 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/errlog.c,v $
* Purpose : Log errors to a designated destination in an elegant,
* printf-like fashion.
*
- * Copyright : Written by and Copyright (C) 2001-2009 the SourceForge
+ * Copyright : Written by and Copyright (C) 2001-2010 the
* Privoxy team. http://www.privoxy.org/
*
* Based on the Internet Junkbuster originally written
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
+#include <ctype.h>
#include "config.h"
#include "miscutil.h"
* Currently we reopen it every time the config file
* has been reloaded, but actually we only have to
* reopen it if the file name changed or if the
- * configuration reloas was caused by a SIGHUP.
+ * configuration reload was caused by a SIGHUP.
*/
log_error(LOG_LEVEL_INFO, "Failed to reopen logfile: \'%s\'. "
"Retrying after closing the old file descriptor first. If that "
{
fclose(logfp);
}
+#ifdef unix
+ if (daemon_mode && (logfp == stderr))
+ {
+ if (dup2(1, 2) == -1)
+ {
+ /*
+ * We only use fatal_error() to clear the pid
+ * file and to exit. Given that stderr has just
+ * been closed, the user will not see the error
+ * message.
+ */
+ fatal_error("Failed to reserve fd 2.");
+ }
+ }
+#endif
logfp = fp;
unlock_logfile();
gettimeofday(&tv_now, NULL);
msecs = tv_now.tv_usec / 1000;
-
- time(&now);
+ now = tv_now.tv_sec;
#ifdef HAVE_LOCALTIME_R
tm_now = *localtime_r(&now, &tm_now);
-#elif def MUTEX_LOCKS_AVAILABLE
+#elif defined(MUTEX_LOCKS_AVAILABLE)
privoxy_mutex_lock(&localtime_mutex);
tm_now = *localtime(&now);
privoxy_mutex_unlock(&localtime_mutex);
tm_now = *localtime(&now);
#endif
- length = strftime(buffer, buffer_size, "%b %d %H:%M:%S", &tm_now);
+ length = strftime(buffer, buffer_size, "%Y-%m-%d %H:%M:%S", &tm_now);
if (length > (size_t)0)
{
msecs_length = snprintf(buffer+length, buffer_size - length, ".%.3ld", msecs);
time (&now);
#ifdef HAVE_GMTIME_R
gmt = *gmtime_r(&now, &gmt);
-#elif def MUTEX_LOCKS_AVAILABLE
+#elif defined(MUTEX_LOCKS_AVAILABLE)
privoxy_mutex_lock(&gmtime_mutex);
gmt = *gmtime(&now);
privoxy_mutex_unlock(&gmtime_mutex);
#endif
#ifdef HAVE_LOCALTIME_R
tm_now = localtime_r(&now, &dummy);
-#elif def MUTEX_LOCKS_AVAILABLE
+#elif defined(MUTEX_LOCKS_AVAILABLE)
privoxy_mutex_lock(&localtime_mutex);
tm_now = localtime(&now);
privoxy_mutex_unlock(&localtime_mutex);
case LOG_LEVEL_CONNECT:
log_level_string = "Connect";
break;
- case LOG_LEVEL_LOG:
+ case LOG_LEVEL_WRITING:
log_level_string = "Writing";
break;
+ case LOG_LEVEL_RECEIVED:
+ log_level_string = "Received";
+ break;
case LOG_LEVEL_HEADER:
log_level_string = "Header";
break;
log_level_string = "Force";
break;
#endif /* def FEATURE_FORCE_LOAD */
-#ifdef FEATURE_FAST_REDIRECTS
case LOG_LEVEL_REDIRECTS:
log_level_string = "Redirect";
break;
-#endif /* def FEATURE_FAST_REDIRECTS */
case LOG_LEVEL_DEANIMATE:
log_level_string = "Gif-Deanimate";
break;
break;
case 'N':
/*
- * Non-standard: Print a counted unterminated string.
+ * Non-standard: Print a counted unterminated string,
+ * replacing unprintable bytes with their hex value.
* Takes 2 parameters: int length, const char * string.
*/
ival = va_arg(ap, int);
+ assert(ival >= 0);
sval = va_arg(ap, char *);
- if (sval == NULL)
- {
- format_string = "[null]";
- }
- else if (ival <= 0)
+ assert(sval != NULL);
+
+ while ((ival-- > 0) && (length < log_buffer_size - 6))
{
- if (0 == ival)
+ if (isprint((int)*sval) && (*sval != '\\'))
{
- /* That's ok (but stupid) */
- tempbuf[0] = '\0';
+ outbuf[length++] = *sval;
+ outbuf[length] = '\0';
}
else
{
- /*
- * That's not ok (and even more stupid)
- */
- assert(ival >= 0);
- format_string = "[counted string lenght < 0]";
+ int ret = snprintf(outbuf + length,
+ log_buffer_size - length - 2, "\\x%.2x", (unsigned char)*sval);
+ assert(ret == 4);
+ length += 4;
}
+ sval++;
}
- else if ((size_t)ival >= sizeof(tempbuf))
- {
- /*
- * String is too long, copy as much as possible.
- * It will be further truncated later.
- */
- memcpy(tempbuf, sval, sizeof(tempbuf)-1);
- tempbuf[sizeof(tempbuf)-1] = '\0';
- }
- else
- {
- memcpy(tempbuf, sval, (size_t) ival);
- tempbuf[ival] = '\0';
- }
+ /*
+ * XXX: In case of printable characters at the end of
+ * the %N string, we're not using the whole buffer.
+ */
+ format_string = (length < log_buffer_size - 6) ? "" : "[too long]";
break;
case 'E':
/* Non-standard: Print error code from errno */
snprintf(tempbuf, sizeof(tempbuf), "Bad format string: \"%s\"", fmt);
loglevel = LOG_LEVEL_FATAL;
break;
- } /* switch( p ) */
+ }
assert(length < log_buffer_size);
length += strlcpy(outbuf + length, format_string, log_buffer_size - length);
if (length >= log_buffer_size-2)
{
- static char warning[] = "... [too long, truncated]";
+ static const char warning[] = "... [too long, truncated]";
length = log_buffer_size - sizeof(warning) - 1;
length += strlcpy(outbuf + length, warning, log_buffer_size - length);
break;
}
- } /* for( p ... ) */
+ }
/* done with var. args */
va_end(ap);
* visible to all files that include errlog.h.
*
* Parameters :
- * 1 : error = a valid jb_err code
+ * 1 : jb_error = a valid jb_err code
*
* Returns : A string with the jb_err translation
*
*********************************************************************/
-const char *jb_err_to_string(int error)
+const char *jb_err_to_string(int jb_error)
{
- switch (error)
+ switch (jb_error)
{
case JB_ERR_OK:
return "Success, no error";