aboutsummaryrefslogtreecommitdiff
path: root/src/syslog.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-12-09 13:53:07 +0200
committerSergey Poznyakoff <gray@gnu.org>2020-12-09 13:53:07 +0200
commit1b997f5150094bd7f7405dae9b33722a2eadeded (patch)
tree55a5d3c6519b9df84a812765716201791d79731c /src/syslog.c
parentfb8500cbf8f0bc434e4296dc68bf1b5578676e9e (diff)
downloadpies-1b997f5150094bd7f7405dae9b33722a2eadeded.tar.gz
pies-1b997f5150094bd7f7405dae9b33722a2eadeded.tar.bz2
Emit explicit syslog marks when truncating very long messages.
* src/syslog.c (log_message): New field: trunc. (log_message_in_create): Initialize trunc (log_message_in_format): Raise trunc on buffer overflow. (log_message_enqueue): Emit the "message truncated" diagnostics when needed.
Diffstat (limited to 'src/syslog.c')
-rw-r--r--src/syslog.c135
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 ();
}

Return to:

Send suggestions and report system problems to the System administrator.