コード例 #1
0
ファイル: errlog.c プロジェクト: durgaprsd04/privoxy
/*********************************************************************
 *
 * Function    :  log_error
 *
 * Description :  This is the error-reporting and logging function.
 *
 * Parameters  :
 *          1  :  loglevel  = the type of message to be logged
 *          2  :  fmt       = the main string we want logged, printf-like
 *          3  :  ...       = arguments to be inserted in fmt (printf-like).
 *
 * Returns     :  N/A
 *
 *********************************************************************/
void log_error(int loglevel, const char *fmt, ...)
{
   va_list ap;
   char *outbuf = NULL;
   static char *outbuf_save = NULL;
   char tempbuf[BUFFER_SIZE];
   size_t length = 0;
   const char * src = fmt;
   long thread_id;
   char timestamp[30];
   /*
    * XXX: Make this a config option,
    * why else do we allocate instead of using
    * an array?
    */
   size_t log_buffer_size = BUFFER_SIZE;

#if defined(_WIN32) && !defined(_WIN_CONSOLE)
   /*
    * Irrespective of debug setting, a GET/POST/CONNECT makes
    * the taskbar icon animate.  (There is an option to disable
    * this but checking that is handled inside LogShowActivity()).
    */
   if ((loglevel == LOG_LEVEL_GPC) || (loglevel == LOG_LEVEL_CRUNCH))
   {
      LogShowActivity();
   }
#endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */

   /*
    * verify that the loglevel applies to current
    * settings and that logging is enabled.
    * Bail out otherwise.
    */
   if ((0 == (loglevel & debug))
#ifndef _WIN32
      || (logfp == NULL)
#endif
      )
   {
      if (loglevel == LOG_LEVEL_FATAL)
      {
         fatal_error("Fatal error. You're not supposed to"
            "see this message. Please file a bug report.");
      }
      return;
   }

   thread_id = get_thread_id();
   get_log_timestamp(timestamp, sizeof(timestamp));

   /* protect the whole function because of the static buffer (outbuf) */
   lock_logfile();

   if (NULL == outbuf_save)
   {
      outbuf_save = (char*)zalloc(log_buffer_size + 1); /* +1 for paranoia */
      if (NULL == outbuf_save)
      {
         snprintf(tempbuf, sizeof(tempbuf),
            "%s %08lx Fatal error: Out of memory in log_error().",
            timestamp, thread_id);
         fatal_error(tempbuf); /* Exit */
         return;
      }
   }
   outbuf = outbuf_save;

   /*
    * Memsetting the whole buffer to zero (in theory)
    * makes things easier later on.
    */
   memset(outbuf, 0, log_buffer_size);

   /* Add prefix for everything but Common Log Format messages */
   if (loglevel != LOG_LEVEL_CLF)
   {
      length = (size_t)snprintf(outbuf, log_buffer_size, "%s %08lx %s: ",
         timestamp, thread_id, get_log_level_string(loglevel));
   }

   /* get ready to scan var. args. */
   va_start(ap, fmt);

   /* build formatted message from fmt and var-args */
   while ((*src) && (length < log_buffer_size-2))
   {
      const char *sval = NULL; /* %N string  */
      int ival;                /* %N string length or an error code */
      unsigned uval;           /* %u value */
      long lval;               /* %l value */
      unsigned long ulval;     /* %ul value */
      char ch;
      const char *format_string = tempbuf;

      ch = *src++;
      if (ch != '%')
      {
         outbuf[length++] = ch;
         /*
          * XXX: Only necessary on platforms where multiple threads
          * can write to the buffer at the same time because we
          * don't support mutexes (OS/2 for example).
          */
         outbuf[length] = '\0';
         continue;
      }
      outbuf[length] = '\0';
      ch = *src++;
      switch (ch) {
         case '%':
            tempbuf[0] = '%';
            tempbuf[1] = '\0';
            break;
         case 'd':
            ival = va_arg(ap, int);
            snprintf(tempbuf, sizeof(tempbuf), "%d", ival);
            break;
         case 'u':
            uval = va_arg(ap, unsigned);
            snprintf(tempbuf, sizeof(tempbuf), "%u", uval);
            break;
         case 'l':
            /* this is a modifier that must be followed by u, lu, or d */
            ch = *src++;
            if (ch == 'd')
            {
               lval = va_arg(ap, long);
               snprintf(tempbuf, sizeof(tempbuf), "%ld", lval);
            }
            else if (ch == 'u')
            {
               ulval = va_arg(ap, unsigned long);
               snprintf(tempbuf, sizeof(tempbuf), "%lu", ulval);
            }
コード例 #2
0
ファイル: errlog.c プロジェクト: killermonk/privoxy-android
/*********************************************************************
 *
 * Function    :  log_error
 *
 * Description :  This is the error-reporting and logging function.
 *
 * Parameters  :
 *          1  :  loglevel  = the type of message to be logged
 *          2  :  fmt       = the main string we want logged, printf-like
 *          3  :  ...       = arguments to be inserted in fmt (printf-like).
 *
 * Returns     :  N/A
 *
 *********************************************************************/
void log_error(int loglevel, char *fmt, ...)
{
   va_list ap;
   char *outbuf= NULL;
   static char *outbuf_save = NULL;
   char * src = fmt;
   int outc = 0;
   long this_thread = 1;  /* was: pthread_t this_thread;*/
#ifdef __OS2__
   PTIB     ptib;
   APIRET   ulrc;
#endif /* __OS2__ */

#if defined(_WIN32) && !defined(_WIN_CONSOLE)
   /*
    * Irrespective of debug setting, a GET/POST/CONNECT makes
    * the taskbar icon animate.  (There is an option to disable
    * this but checking that is handled inside LogShowActivity()).
    */
   if (loglevel == LOG_LEVEL_GPC)
   {
      LogShowActivity();
   }
#endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */

   /* verify if loglevel applies to current settings and bail out if negative */
   if ((loglevel & debug) == 0)
   {
      return;
   }

   /* FIXME get current thread id */
#ifdef FEATURE_PTHREAD
   this_thread = (long)pthread_self();
#ifdef __MACH__
   /*
    * Mac OSX (and perhaps other Mach instances) doesn't have a debuggable
    * value at the first 4 bytes of pthread_self()'s return value, a pthread_t.
    * pthread_t is supposed to be opaque... but it's fairly random, though, so
    * we make it mostly presentable.
    */
   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);
      assert(outbuf);
   }
   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 OSX_DARWIN
       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(%05ld) Error: ", this_thread);
         break;
      case LOG_LEVEL_FATAL:
         outc = sprintf(outbuf, "Privoxy(%05ld) Fatal error: ", this_thread);
         break;
      case LOG_LEVEL_GPC:
         outc = sprintf(outbuf, "Privoxy(%05ld) Request: ", this_thread);
         break;
      case LOG_LEVEL_CONNECT:
         outc = sprintf(outbuf, "Privoxy(%05ld) Connect: ", this_thread);
         break;
      case LOG_LEVEL_LOG:
         outc = sprintf(outbuf, "Privoxy(%05ld) Writing: ", this_thread);
         break;
      case LOG_LEVEL_HEADER:
         outc = sprintf(outbuf, "Privoxy(%05ld) Header: ", this_thread);
         break;
      case LOG_LEVEL_INFO:
         outc = sprintf(outbuf, "Privoxy(%05ld) Info: ", this_thread);
         break;
      case LOG_LEVEL_RE_FILTER:
         outc = sprintf(outbuf, "Privoxy(%05ld) Re-Filter: ", this_thread);
         break;
#ifdef FEATURE_FORCE_LOAD
      case LOG_LEVEL_FORCE:
         outc = sprintf(outbuf, "Privoxy(%05ld) Force: ", this_thread);
         break;
#endif /* def FEATURE_FORCE_LOAD */
#ifdef FEATURE_FAST_REDIRECTS
      case LOG_LEVEL_REDIRECTS:
         outc = sprintf(outbuf, "Privoxy(%05ld) Redirect: ", this_thread);
         break;
#endif /* def FEATURE_FAST_REDIRECTS */
      case LOG_LEVEL_DEANIMATE:
         outc = sprintf(outbuf, "Privoxy(%05ld) 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(%05ld) Kill-Popups: ", this_thread);
         break;
#endif /* def FEATURE_KILL_POPUPS */
      case LOG_LEVEL_CGI:
         outc = sprintf(outbuf, "Privoxy(%05ld) CGI: ", this_thread);
         break;
      default:
         outc = sprintf(outbuf, "Privoxy(%05ld) 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);
            }