diff options
-rw-r--r-- | src/syslog.c | 135 |
1 files changed, 82 insertions, 53 deletions
diff --git a/src/syslog.c b/src/syslog.c index 6c7f5e7..3171d0c 100644 --- a/src/syslog.c +++ b/src/syslog.c @@ -38,6 +38,7 @@ struct log_message char *text; /* Message text (no terminating nul). */ size_t len; /* Number of bytes in text */ size_t drop_count; /* Count of messages dropped so far (first message only) */ + int trunc; struct log_message *next; }; @@ -212,6 +213,7 @@ log_message_in_create (void) msg->msg.text = msg->buf; msg->msg.len = 0; msg->msg.drop_count = 0; + msg->msg.trunc = 0; msg->msg.next = NULL; } return msg; @@ -226,7 +228,8 @@ log_message_in_format (struct log_message_in *msg, char hostbuf[256]; struct timeval tv; struct tm tm; - + int n; + gettimeofday (&tv, NULL); localtime_r (&tv.tv_sec, &tm); strftime (tbuf, sizeof (tbuf), "%b %d %H:%M:%S", &tm); @@ -239,26 +242,33 @@ log_message_in_format (struct log_message_in *msg, if (log_family == PF_UNIX) { - msg->msg.len = snprintf (msg->buf, sizeof (msg->buf), - "<%d>%s %s[%lu]: %s", - prio, - tbuf, - tag, - (unsigned long)pid, - msgtext); + n = snprintf (msg->buf, sizeof (msg->buf), + "<%d>%s %s[%lu]: %s", + prio, + tbuf, + tag, + (unsigned long)pid, + msgtext); } else { gethostname (hostbuf, sizeof (hostbuf)); - msg->msg.len = snprintf (msg->buf, sizeof (msg->buf), - "<%d>%s %s %s[%lu]: %s", - prio, - tbuf, - hostbuf, - tag, - (unsigned long)pid, - msgtext); + n = snprintf (msg->buf, sizeof (msg->buf), + "<%d>%s %s %s[%lu]: %s", + prio, + tbuf, + hostbuf, + tag, + (unsigned long)pid, + msgtext); + } + if (n >= sizeof (msg->buf)) + { + /* Overflow */ + n = sizeof (msg->buf); + msg->msg.trunc = 1; } + msg->msg.len = n; } static struct log_message * @@ -302,49 +312,68 @@ log_message_dequeue (void) static void log_message_enqueue (struct log_message *inmsg) -{ - if (log_queue_length == pies_log_max_queue) +{ + int truncated = 0; + + do { - struct log_message *msg; - struct log_message_in *tmp; - char buf[PIES_LOG_BUF_SIZE]; + if (log_queue_length == pies_log_max_queue) + { + struct log_message *msg; + struct log_message_in *tmp; + char buf[PIES_LOG_BUF_SIZE]; - /* Dequeue first message */ - msg = log_message_dequeue (); + /* Dequeue first message */ + msg = log_message_dequeue (); - if (msg->drop_count == 0) - { - /* If it is not a drop message, free it and create a new - drop message */ - free (msg); - tmp = log_message_in_create (); - tmp->msg.drop_count = 1; + if (msg->drop_count == 0) + { + /* If it is not a drop message, free it and create a new + drop message */ + free (msg); + tmp = log_message_in_create (); + tmp->msg.drop_count = 1; + } + else + /* Otherwise, cast it to log_message_in */ + tmp = (struct log_message_in *)msg; + + /* Dequeue and drop the first message */ + free (log_message_dequeue ()); + tmp->msg.drop_count++; + + /* Reformat the message text */ + snprintf (buf, sizeof (buf), "%zu messages dropped", + tmp->msg.drop_count); + log_message_in_format (tmp, + pies_log_facility|LOG_CRIT, + buf, + pies_log_tag, + getpid ()); + + log_message_putback (&tmp->msg); } + + if (log_queue_tail) + log_queue_tail->next = inmsg; else - /* Otherwise, cast it to log_message_in */ - tmp = (struct log_message_in *)msg; - - /* Dequeue and drop the first message */ - free (log_message_dequeue ()); - tmp->msg.drop_count++; - - /* Reformat the message text */ - snprintf (buf, sizeof (buf), "%zu messages dropped", tmp->msg.drop_count); - log_message_in_format (tmp, - LOG_DAEMON|LOG_CRIT, - buf, - pies_log_tag, - getpid ()); - - log_message_putback (&tmp->msg); + log_queue_head = inmsg; + log_queue_tail = inmsg; + log_queue_length++; + + if (truncated) + /* Shouldn't happen */ + truncated = 0; + else if (inmsg->trunc) + { + inmsg = log_message_create (pies_log_facility|LOG_CRIT, + "-- message truncated --", + pies_log_tag, getpid ()); + truncated = 1; + } } - - if (log_queue_tail) - log_queue_tail->next = inmsg; - else - log_queue_head = inmsg; - log_queue_tail = inmsg; - log_queue_length++; + while (truncated); + pies_syslog_flush (); } |