Beispiel #1
0
static void
real_plog(int lvl, char *fmt, va_list vargs)
{
  char msg[1024];
  char efmt[1024];
  char *ptr = msg;
  static char last_msg[1024];
  static int last_count = 0, last_lvl = 0;

  if (!(xlog_level & lvl))
    return;

#ifdef DEBUG_MEM
  checkup_mem();
#endif /* DEBUG_MEM */

  expand_error(fmt, efmt, 1024);

#ifdef HAVE_VSNPRINTF
  vsnprintf(ptr, 1024, efmt, vargs);
#else /* not HAVE_VSNPRINTF */
  /*
   * XXX: ptr is 1024 bytes long.  It is possible to write into it
   * more than 1024 bytes, if efmt is already large, and vargs expand
   * as well.  This is not as safe as using vsnprintf().
   */
  vsprintf(ptr, efmt, vargs);
  msg[1023] = '\0';		/* null terminate, to be sure */
#endif /* not HAVE_VSNPRINTF */

  ptr += strlen(ptr);
  if (ptr[-1] == '\n')
    *--ptr = '\0';

#ifdef HAVE_SYSLOG
  if (syslogging) {
    switch (lvl) {		/* from mike <*****@*****.**> */
    case XLOG_FATAL:
      lvl = LOG_CRIT;
      break;
    case XLOG_ERROR:
      lvl = LOG_ERR;
      break;
    case XLOG_USER:
      lvl = LOG_WARNING;
      break;
    case XLOG_WARNING:
      lvl = LOG_WARNING;
      break;
    case XLOG_INFO:
      lvl = LOG_INFO;
      break;
    case XLOG_DEBUG:
      lvl = LOG_DEBUG;
      break;
    case XLOG_MAP:
      lvl = LOG_DEBUG;
      break;
    case XLOG_STATS:
      lvl = LOG_INFO;
      break;
    default:
      lvl = LOG_ERR;
      break;
    }
    syslog(lvl, "%s", msg);
    return;
  }
#endif /* HAVE_SYSLOG */

  *ptr++ = '\n';
  *ptr = '\0';

  /*
   * mimic syslog behavior: only write repeated strings if they differ
   */
  switch (last_count) {
  case 0:			/* never printed at all */
    last_count = 1;
    strncpy(last_msg, msg, 1024);
    last_lvl = lvl;
    show_time_host_and_name(lvl); /* mimic syslog header */
    fwrite(msg, ptr - msg, 1, logfp);
    fflush(logfp);
    break;

  case 1:			/* item printed once, if same, don't repeat */
    if (STREQ(last_msg, msg)) {
      last_count++;
    } else {			/* last msg printed once, new one differs */
      /* last_count remains at 1 */
      strncpy(last_msg, msg, 1024);
      last_lvl = lvl;
      show_time_host_and_name(lvl); /* mimic syslog header */
      fwrite(msg, ptr - msg, 1, logfp);
      fflush(logfp);
    }
    break;

  case 100:
    /*
     * Don't allow repetitions longer than 100, so you can see when something
     * cycles like crazy.
     */
    show_time_host_and_name(last_lvl);
    sprintf(last_msg, "last message repeated %d times\n", last_count);
    fwrite(last_msg, strlen(last_msg), 1, logfp);
    fflush(logfp);
    last_count = 0;		/* start from scratch */
    break;

  default:			/* item repeated multiple times */
    if (STREQ(last_msg, msg)) {
      last_count++;
    } else {		/* last msg repeated+skipped, new one differs */
      show_time_host_and_name(last_lvl);
      sprintf(last_msg, "last message repeated %d times\n", last_count);
      fwrite(last_msg, strlen(last_msg), 1, logfp);
      strncpy(last_msg, msg, 1024);
      last_count = 1;
      last_lvl = lvl;
      show_time_host_and_name(lvl); /* mimic syslog header */
      fwrite(msg, ptr - msg, 1, logfp);
      fflush(logfp);
    }
    break;
  }

}
Beispiel #2
0
static void
real_plog(int lvl, const char *fmt, va_list vargs)
{
  char msg[1024];
  char efmt[1024];
  char *ptr = msg;
  static char last_msg[1024];
  static int last_count = 0, last_lvl = 0;

  if (!(xlog_level & lvl))
    return;

#ifdef DEBUG_MEM
# if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY)
  checkup_mem();
# endif /* not defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY) */
#endif /* DEBUG_MEM */

  /*
   * Note: xvsnprintf() may call plog() if a truncation happened, but the
   * latter has some code to break out of an infinite loop.  See comment in
   * xsnprintf() below.
   */
  xvsnprintf(ptr, 1023, expand_error(fmt, efmt, 1024), vargs);

  ptr += strlen(ptr);
  if (*(ptr-1) == '\n')
    *--ptr = '\0';

#ifdef HAVE_SYSLOG
  if (syslogging) {
    switch (lvl) {		/* from mike <*****@*****.**> */
    case XLOG_FATAL:
      lvl = LOG_CRIT;
      break;
    case XLOG_ERROR:
      lvl = LOG_ERR;
      break;
    case XLOG_USER:
      lvl = LOG_WARNING;
      break;
    case XLOG_WARNING:
      lvl = LOG_WARNING;
      break;
    case XLOG_INFO:
      lvl = LOG_INFO;
      break;
    case XLOG_DEBUG:
      lvl = LOG_DEBUG;
      break;
    case XLOG_MAP:
      lvl = LOG_DEBUG;
      break;
    case XLOG_STATS:
      lvl = LOG_INFO;
      break;
    default:
      lvl = LOG_ERR;
      break;
    }
    syslog(lvl, "%s", msg);
    return;
  }
#endif /* HAVE_SYSLOG */

  *ptr++ = '\n';
  *ptr = '\0';

  /*
   * mimic syslog behavior: only write repeated strings if they differ
   */
  switch (last_count) {
  case 0:			/* never printed at all */
    last_count = 1;
    if (strlcpy(last_msg, msg, sizeof(last_msg)) >= sizeof(last_msg)) /* don't use xstrlcpy here (recursive!) */
      fprintf(stderr, "real_plog: string \"%s\" truncated to \"%s\"\n", last_msg, msg);
    last_lvl = lvl;
    show_time_host_and_name(lvl); /* mimic syslog header */
    __IGNORE(fwrite(msg, ptr - msg, 1, logfp));
    fflush(logfp);
    break;

  case 1:			/* item printed once, if same, don't repeat */
    if (STREQ(last_msg, msg)) {
      last_count++;
    } else {			/* last msg printed once, new one differs */
      /* last_count remains at 1 */
      if (strlcpy(last_msg, msg, sizeof(last_msg)) >= sizeof(last_msg)) /* don't use xstrlcpy here (recursive!) */
	fprintf(stderr, "real_plog: string \"%s\" truncated to \"%s\"\n", last_msg, msg);
      last_lvl = lvl;
      show_time_host_and_name(lvl); /* mimic syslog header */
      __IGNORE(fwrite(msg, ptr - msg, 1, logfp));
      fflush(logfp);
    }
    break;

  case 100:
    /*
     * Don't allow repetitions longer than 100, so you can see when something
     * cycles like crazy.
     */
    show_time_host_and_name(last_lvl);
    xsnprintf(last_msg, sizeof(last_msg),
	      "last message repeated %d times\n", last_count);
    __IGNORE(fwrite(last_msg, strlen(last_msg), 1, logfp));
    fflush(logfp);
    last_count = 0;		/* start from scratch */
    break;

  default:			/* item repeated multiple times */
    if (STREQ(last_msg, msg)) {
      last_count++;
    } else {		/* last msg repeated+skipped, new one differs */
      show_time_host_and_name(last_lvl);
      xsnprintf(last_msg, sizeof(last_msg),
		"last message repeated %d times\n", last_count);
      __IGNORE(fwrite(last_msg, strlen(last_msg), 1, logfp));
      if (strlcpy(last_msg, msg, 1024) >= 1024) /* don't use xstrlcpy here (recursive!) */
	fprintf(stderr, "real_plog: string \"%s\" truncated to \"%s\"\n", last_msg, msg);
      last_count = 1;
      last_lvl = lvl;
      show_time_host_and_name(lvl); /* mimic syslog header */
      __IGNORE(fwrite(msg, ptr - msg, 1, logfp));
      fflush(logfp);
    }
    break;
  }

}