- this_thread = abs(this_thread % 1000);
-#endif /* def __MACH__ */
-#elif defined(_WIN32)
- this_thread = GetCurrentThreadId();
-#elif defined(__OS2__)
- ulrc = DosGetInfoBlocks(&ptib, NULL);
- if (ulrc == 0)
- this_thread = ptib -> tib_ptib2 -> tib2_ultid;
-#endif /* def FEATURE_PTHREAD */
-
- if ( !outbuf_save )
- {
- outbuf_save = outbuf = (char*)malloc(BUFFER_SIZE);
- if (NULL == outbuf_save)
- {
- fatal_error("Privoxy failed to allocate log buffer.");
- }
- }
- outbuf = outbuf_save;
-
- {
- /*
- * Write timestamp into tempbuf.
- *
- * Complex because not all OSs have tm_gmtoff or
- * the %z field in strftime()
- */
- time_t now;
- struct tm tm_now;
- time (&now);
-#ifdef HAVE_LOCALTIME_R
- tm_now = *localtime_r(&now, &tm_now);
-#elif FEATURE_PTHREAD
- pthread_mutex_lock(&localtime_mutex);
- tm_now = *localtime (&now);
- pthread_mutex_unlock(&localtime_mutex);
-#else
- tm_now = *localtime (&now);
-#endif
- strftime(outbuf, BUFFER_SIZE-6, "%b %d %H:%M:%S ", &tm_now);
- outbuf += strlen( outbuf );
- }
- switch (loglevel)
- {
- case LOG_LEVEL_ERROR:
- outc = sprintf(outbuf, "Privoxy(%08lx) Error: ", this_thread);
- break;
- case LOG_LEVEL_FATAL:
- outc = sprintf(outbuf, "Privoxy(%08lx) Fatal error: ", this_thread);
- break;
- case LOG_LEVEL_GPC:
- outc = sprintf(outbuf, "Privoxy(%08lx) Request: ", this_thread);
- break;
- case LOG_LEVEL_CONNECT:
- outc = sprintf(outbuf, "Privoxy(%08lx) Connect: ", this_thread);
- break;
- case LOG_LEVEL_LOG:
- outc = sprintf(outbuf, "Privoxy(%08lx) Writing: ", this_thread);
- break;
- case LOG_LEVEL_HEADER:
- outc = sprintf(outbuf, "Privoxy(%08lx) Header: ", this_thread);
- break;
- case LOG_LEVEL_INFO:
- outc = sprintf(outbuf, "Privoxy(%08lx) Info: ", this_thread);
- break;
- case LOG_LEVEL_RE_FILTER:
- outc = sprintf(outbuf, "Privoxy(%08lx) Re-Filter: ", this_thread);
- break;
-#ifdef FEATURE_FORCE_LOAD
- case LOG_LEVEL_FORCE:
- outc = sprintf(outbuf, "Privoxy(%08lx) Force: ", this_thread);
- break;
-#endif /* def FEATURE_FORCE_LOAD */
-#ifdef FEATURE_FAST_REDIRECTS
- case LOG_LEVEL_REDIRECTS:
- outc = sprintf(outbuf, "Privoxy(%08lx) Redirect: ", this_thread);
- break;
-#endif /* def FEATURE_FAST_REDIRECTS */
- case LOG_LEVEL_DEANIMATE:
- outc = sprintf(outbuf, "Privoxy(%08lx) Gif-Deanimate: ", this_thread);
- break;
- case LOG_LEVEL_CLF:
- outbuf = outbuf_save;
- outc = 0;
- outbuf[0] = '\0';
- break;
-#ifdef FEATURE_KILL_POPUPS
- case LOG_LEVEL_POPUPS:
- outc = sprintf(outbuf, "Privoxy(%08lx) Kill-Popups: ", this_thread);
- break;
-#endif /* def FEATURE_KILL_POPUPS */
- case LOG_LEVEL_CGI:
- outc = sprintf(outbuf, "Privoxy(%08lx) CGI: ", this_thread);
- break;
- default:
- outc = sprintf(outbuf, "Privoxy(%08lx) UNKNOWN LOG TYPE(%d): ", this_thread, loglevel);
- break;
- }
-
- /* get ready to scan var. args. */
- va_start( ap, fmt );
-
- /* build formatted message from fmt and var-args */
- while ((*src) && (outc < BUFFER_SIZE-2))
- {
- char tempbuf[BUFFER_SIZE];
- char *sval = NULL;
- int ival;
- unsigned uval;
- long lval;
- unsigned long ulval;
- int oldoutc;
- char ch;
-
- ch = *src++;
- if( ch != '%' )
- {
- outbuf[outc++] = ch;
- continue;
- }
-
- ch = *src++;
- switch (ch) {
- case '%':
- outbuf[outc++] = '%';
- break;
- case 'd':
- ival = va_arg( ap, int );
- oldoutc = outc;
- outc += sprintf(tempbuf, "%d", ival);
- if (outc < BUFFER_SIZE-1)
- {
- strcpy(outbuf + oldoutc, tempbuf);
- }
- else
- {
- outbuf[oldoutc] = '\0';
- }
- break;
- case 'u':
- uval = va_arg( ap, unsigned );
- oldoutc = outc;
- outc += sprintf(tempbuf, "%u", uval);
- if (outc < BUFFER_SIZE-1)
- {
- strcpy(outbuf + oldoutc, tempbuf);
- }
- else
- {
- outbuf[oldoutc] = '\0';
- }
- break;
- case 'l':
- /* this is a modifier that must be followed by u or d */
- ch = *src++;
- if (ch == 'd')
- {
- lval = va_arg( ap, long );
- oldoutc = outc;
- outc += sprintf(tempbuf, "%ld", lval);
- }
- else if (ch == 'u')
- {
- ulval = va_arg( ap, unsigned long );
- oldoutc = outc;
- outc += sprintf(tempbuf, "%lu", ulval);
- }
- else
- {
- /* Error */
- sprintf(outbuf, "Privoxy(%08lx) Error: log_error(): Bad format string:\n"
- "Format = \"%s\"\n"
- "Exiting.", this_thread, fmt);
- if( !logfp )
- {
- logfp = stderr;
- }
- fputs(outbuf, logfp);
- fatal_error(outbuf);
- /* Never get here */
- break;
- }
- if (outc < BUFFER_SIZE-1)
- {
- strcpy(outbuf + oldoutc, tempbuf);
- }
- else
- {
- outbuf[oldoutc] = '\0';
- }
- break;
- case 'c':
- /*
- * Note that char paramaters are converted to int, so we need to
- * pass "int" to va_arg. (See K&R, 2nd ed, section A7.3.2, page 202)
- */
- outbuf[outc++] = (char) va_arg( ap, int );
- break;
- case 's':
- sval = va_arg( ap, char * );
- if (sval == NULL)
- {
- sval = "[null]";
- }
- oldoutc = outc;
- outc += strlen(sval);
- if (outc < BUFFER_SIZE-1)
- {
- strcpy(outbuf + oldoutc, sval);
- }
- else
- {
- outbuf[oldoutc] = '\0';
- }
- break;
- case 'N':
- /* Non-standard: Print a counted string. Takes 2 parameters:
- * int length, const char * string
- */
- ival = va_arg( ap, int );
- sval = va_arg( ap, char * );
- if (sval == NULL)
- {
- sval = "[null]";
- }
- if (ival < 0)
- {
- ival = 0;
- }
- oldoutc = outc;
- outc += ival;
- if (outc < BUFFER_SIZE-1)
- {
- memcpy(outbuf + oldoutc, sval, (size_t) ival);
- }
- else
- {
- outbuf[oldoutc] = '\0';
- }
- break;
- case 'E':
- /* Non-standard: Print error code from errno */
-#ifdef _WIN32
- ival = WSAGetLastError();
- sval = w32_socket_strerr(ival, tempbuf);
-#elif __OS2__
- ival = sock_errno();
- if (ival != 0)
- sval = os2_socket_strerr(ival, tempbuf);
- else
- {
- ival = errno;
- sval = strerror(ival);
- }
-#else /* ifndef _WIN32 */
- ival = errno;
-#ifdef HAVE_STRERROR
- sval = strerror(ival);
-#else /* ifndef HAVE_STRERROR */
- sval = NULL;
-#endif /* ndef HAVE_STRERROR */
- if (sval == NULL)
- {
- sprintf(tempbuf, "(errno = %d)", ival);
- sval = tempbuf;
- }
-#endif /* ndef _WIN32 */
- oldoutc = outc;
- outc += strlen(sval);
- if (outc < BUFFER_SIZE-1)
- {
- strcpy(outbuf + oldoutc, sval);
- }
- else
- {
- outbuf[oldoutc] = '\0';
- }
- break;
- case 'T':
- /* Non-standard: Print a Common Log File timestamp */
- {
- /*
- * Write timestamp into tempbuf.
- *
- * Complex because not all OSs have tm_gmtoff or
- * the %z field in strftime()
- */
- time_t now;
- struct tm *tm_now;
- struct tm gmt;
-#ifdef HAVE_LOCALTIME_R
- struct tm dummy;
-#endif
- int days, hrs, mins;
- time (&now);
-#ifdef HAVE_GMTIME_R
- gmt = *gmtime_r(&now, &gmt);
-#elif FEATURE_PTHREAD
- pthread_mutex_lock(&gmtime_mutex);
- gmt = *gmtime(&now);
- pthread_mutex_unlock(&gmtime_mutex);
-#else
- gmt = *gmtime(&now);
-#endif
-#ifdef HAVE_LOCALTIME_R
- tm_now = localtime_r(&now, &dummy);
-#elif FEATURE_PTHREAD
- pthread_mutex_lock(&localtime_mutex);
- tm_now = localtime (&now);
- pthread_mutex_unlock(&localtime_mutex);
-#else
- tm_now = localtime (&now);