diff --git a/src/socket.c b/src/socket.c index bd2c912..0b1eb07 100644 --- a/src/socket.c +++ b/src/socket.c @@ -39,11 +39,10 @@ #include #include #include -#include -#include #include #include "queue.h" +#include "socket.h" #include "syslogd.h" struct sock { diff --git a/src/socket.h b/src/socket.h index 38c00e2..146f332 100644 --- a/src/socket.h +++ b/src/socket.h @@ -31,9 +31,12 @@ #ifndef SYSKLOGD_SOCKET_H_ #define SYSKLOGD_SOCKET_H_ +#include #include #include +#include #include +#include int socket_register(int sd, struct addrinfo *ai, void (*cb)(int, void *), void *arg); int socket_create (struct addrinfo *ai, void (*cb)(int, void *), void *arg); diff --git a/src/syslogd.c b/src/syslogd.c index 7c5fbcf..a1055a7 100644 --- a/src/syslogd.c +++ b/src/syslogd.c @@ -91,6 +91,7 @@ static char sccsid[] __attribute__((unused)) = #define SYSLOG_NAMES #include "syslogd.h" #include "socket.h" +#include "timer.h" #include "compat.h" char *ConfFile = _PATH_LOGCONF; @@ -128,7 +129,6 @@ static int MarkInterval = 20 * 60; /* interval between marks in seconds */ static int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */ static int mask_C1 = 1; /* mask characters from 0x80 - 0x9F */ static int send_to_all; /* send message to all IPv4/IPv6 addresses */ -static int MarkSeq = 0; /* mark sequence number */ static int SecureMode; /* when true, receive only unix domain socks */ static int RemoteAddDate; /* Always set the date on remote messages */ @@ -165,7 +165,8 @@ void wallmsg(struct filed *f, struct iovec *iov, int iovcnt); void reapchild(); const char *cvtaddr(struct sockaddr_storage *f, int len); const char *cvthname(struct sockaddr *f, socklen_t len); -void domark(); +void domark(void *arg); +void doflush(void *arg); void debug_switch(); void die(int sig); void doexit(int sig); @@ -422,15 +423,23 @@ int main(int argc, char *argv[]) (void)signal(SIGINT, Debug ? die : SIG_IGN); (void)signal(SIGQUIT, Debug ? die : SIG_IGN); (void)signal(SIGCHLD, reapchild); - (void)signal(SIGALRM, domark); (void)signal(SIGUSR1, Debug ? debug_switch : SIG_IGN); (void)signal(SIGXFSZ, SIG_IGN); (void)signal(SIGHUP, sighup_handler); - alarm(TIMERINTVL); logit("Starting.\n"); init(); + /* + * Set up timer callbacks for -- MARK -- et al + */ + if (MarkInterval > 0) + timer_add(TIMERINTVL, domark, NULL); + timer_add(FLUSHINTVL, doflush, NULL); + + /* Start 'em */ + timer_start(); + if (Debug) { logit("Debugging disabled, SIGUSR1 to turn on debugging.\n"); debugging_on = 0; @@ -464,16 +473,8 @@ int main(int argc, char *argv[]) continue; } - if (rc == 0) { - logit("No select activity.\n"); - continue; - } - if (rc < 0) { - if (errno != EINTR) - ERR("select()"); - continue; - } - + if (rc < 0 && errno != EINTR) + ERR("select()"); } } @@ -989,7 +990,7 @@ parsemsg_rfc3164(const char *from, int pri, char *msg) * This loop can only run for at most three * iterations before terminating. */ - t_now = time(NULL); + t_now = timer_now(); localtime_r(&t_now, &tm_now); for (year = tm_now.tm_year + 1;; --year) { assert(year >= tm_now.tm_year - 1); @@ -1089,6 +1090,11 @@ parsemsg(const char *from, char *msg) if ((pri & LOG_FACMASK) == LOG_KERN && !KeepKernFac) pri = LOG_MAKEPRI(LOG_USER, LOG_PRI(pri)); + /* + * Message looks OK, update current time and log it + */ + timer_update(); + /* Parse VERSION. */ msg += i + 1; if (msg[0] == '1' && msg[1] == ' ') @@ -1156,7 +1162,22 @@ char *textpri(int pri) return res; } -time_t now; +static void check_timestamp(struct buf_msg *buffer) +{ + struct logtime zero = { 0 }; + struct logtime now; + struct timeval tv; + + if (memcmp(&buffer->timestamp, &zero, sizeof(zero))) + return; + + if (gettimeofday(&tv, NULL) == -1) + return; + + localtime_r(&tv.tv_sec, &now.tm); + now.usec = tv.tv_usec; + buffer->timestamp = now; +} /* * Logs a message to the appropriate log files, users, etc. based on the @@ -1166,9 +1187,6 @@ time_t now; */ static void logmsg(struct buf_msg *buffer) { - struct logtime timestamp_now; - struct logtime zero = { 0 }; - struct timeval tv; struct filed *f; sigset_t mask; size_t savedlen; @@ -1179,13 +1197,8 @@ static void logmsg(struct buf_msg *buffer) textpri(buffer->pri), buffer->flags, buffer->hostname, buffer->app_name, buffer->proc_id, buffer->msgid, buffer->sd, buffer->msg); - (void)gettimeofday(&tv, NULL); - now = tv.tv_sec; - if (!memcmp(&buffer->timestamp, &zero, sizeof(zero))) { - localtime_r(&now, ×tamp_now.tm); - timestamp_now.usec = tv.tv_usec; - buffer->timestamp = timestamp_now; - } + /* Messages generated by syslogd itself may not have a timestamp */ + check_timestamp(buffer); /* extract facility and priority level */ if (buffer->flags & MARK) @@ -1245,8 +1258,19 @@ static void logmsg(struct buf_msg *buffer) continue; /* don't output marks to recently written files */ - if ((buffer->flags & MARK) && (now - f->f_time) < MarkInterval / 2) - continue; + if (buffer->flags & MARK) { + time_t t_now = timer_now(); + + fprintf(stderr, "1) f_time: %zd + MarkInterval: %d => %ld, t_now: %zd\n", + f->f_time, MarkInterval, f->f_time + MarkInterval, t_now); + if (f->f_time + MarkInterval > t_now) + continue; + fprintf(stderr, "2) t_now: %zd - f_time: %zd => %ld < MarkInterval/2 : %d\n", + t_now, f->f_time, t_now - f->f_time, MarkInterval / 2); + if (t_now - f->f_time < MarkInterval / 2) + continue; + fprintf(stderr, "3) f_time: %zd, MarkInterval: %d, t_now: %zd\n", f->f_time, MarkInterval, t_now); + } /* * suppress duplicate lines to this file @@ -1256,7 +1280,7 @@ static void logmsg(struct buf_msg *buffer) f->f_lasttime = buffer->timestamp; f->f_prevcount++; logit("msg repeated %d times, %ld sec of %d.\n", - f->f_prevcount, now - f->f_time, + f->f_prevcount, timer_now() - f->f_time, repeatinterval[f->f_repeatcount]); /* @@ -1265,7 +1289,7 @@ static void logmsg(struct buf_msg *buffer) * but back off so we'll flush less often * in the future. */ - if (now > REPEATTIME(f)) { + if (timer_now() > REPEATTIME(f)) { fprintlog_successive(f, buffer->flags); BACKOFF(f); } @@ -1366,12 +1390,12 @@ void fprintlog_write(struct filed *f, struct iovec *iov, int iovcnt, int flags) switch (f->f_type) { case F_UNUSED: - f->f_time = now; + f->f_time = timer_now(); logit("\n"); break; case F_FORW_SUSP: - fwd_suspend = time(NULL) - f->f_time; + fwd_suspend = timer_now() - f->f_time; if (fwd_suspend >= INET_SUSPEND_TIME) { logit("\nForwarding suspension over, retrying FORW "); f->f_type = F_FORW; @@ -1390,7 +1414,7 @@ void fprintlog_write(struct filed *f, struct iovec *iov, int iovcnt, int flags) case F_FORW: f_forw: logit(" %s:%s\n", f->f_un.f_forw.f_hname, f->f_un.f_forw.f_serv); - f->f_time = now; + f->f_time = timer_now(); memset(&msg, 0, sizeof(msg)); msg.msg_iov = iov; @@ -1444,7 +1468,7 @@ void fprintlog_write(struct filed *f, struct iovec *iov, int iovcnt, int flags) break; case F_CONSOLE: - f->f_time = now; + f->f_time = timer_now(); if (flags & IGN_CONS) { logit(" (ignored).\n"); break; @@ -1454,7 +1478,7 @@ void fprintlog_write(struct filed *f, struct iovec *iov, int iovcnt, int flags) case F_TTY: case F_FILE: case F_PIPE: - f->f_time = now; + f->f_time = timer_now(); logit(" %s\n", f->f_un.f_fname); if (f->f_type == F_TTY || f->f_type == F_CONSOLE) { pushiov(iov, iovcnt, "\r\n"); @@ -1514,7 +1538,7 @@ void fprintlog_write(struct filed *f, struct iovec *iov, int iovcnt, int flags) case F_USERS: case F_WALL: - f->f_time = now; + f->f_time = timer_now(); logit("\n"); pushiov(iov, iovcnt, "\r\n"); wallmsg(f, &iov[1], iovcnt - 1); @@ -1619,25 +1643,15 @@ static int fmt5424(struct buf_msg *buffer, char *fmt, struct iovec *iov, size_t static void fprintlog_first(struct filed *f, struct buf_msg *buffer) { - struct logtime zero = { 0 }; struct iovec iov[20]; int iovcnt; logit("Called fprintlog_first(), "); - if (!memcmp(&buffer->timestamp, &zero, sizeof(zero))) { - struct logtime timestamp_now; - struct timeval tv; + /* Messages generated by syslogd itself may not have a timestamp */ + check_timestamp(buffer); - (void)gettimeofday(&tv, NULL); - now = tv.tv_sec; - - localtime_r(&now, ×tamp_now.tm); - timestamp_now.usec = tv.tv_usec; - buffer->timestamp = timestamp_now; - } - - f->f_time = now; + f->f_time = timer_now(); f->f_prevcount = 0; if (f->f_flags & RFC5424) @@ -1706,12 +1720,14 @@ void wallmsg(struct filed *f, struct iovec *iov, int iovcnt) * and doing notty(). */ if (fork() == 0) { + time_t t_now = timer_now(); + (void)signal(SIGTERM, SIG_DFL); (void)alarm(0); (void)snprintf(greetings, sizeof(greetings), "\r\n\7Message from syslogd@%s at %.24s ...\r\n", - (char *)iov[3].iov_base, ctime(&now)); + (char *)iov[3].iov_base, ctime(&t_now)); len = strlen(greetings); /* scan the user login file */ @@ -1893,7 +1909,7 @@ static void forw_lookup(struct filed *f) /* Called from cfline() for initial lookup? */ init = f->f_type == F_UNUSED ? 1 : 0; - diff = now - f->f_time; + diff = timer_now() - f->f_time; if (!init && diff < INET_SUSPEND_TIME) { logit("Forwarding suspension not over, time left: %d\n", (int)(INET_SUSPEND_TIME - diff)); @@ -1907,7 +1923,7 @@ static void forw_lookup(struct filed *f) if (err) { WARN("Failed resolving '%s:%s': %s", host, serv, gai_strerror(err)); f->f_type = F_FORW_UNKN; - f->f_time = now; + f->f_time = timer_now(); return; } @@ -1919,27 +1935,22 @@ static void forw_lookup(struct filed *f) f->f_prevcount = 0; } -void domark(int signo) +void domark(void *arg) +{ + flog(INTERNAL_MARK | LOG_INFO, "-- MARK --"); +} + +void doflush(void *arg) { struct filed *f; - now = time(NULL); - - if (MarkInterval > 0) { - MarkSeq += TIMERINTVL; - if (MarkSeq >= MarkInterval) { - flog(INTERNAL_MARK | LOG_INFO, "-- MARK --"); - MarkSeq = 0; - } - } - SIMPLEQ_FOREACH(f, &fhead, f_link) { if (f->f_type == F_FORW_UNKN) { forw_lookup(f); continue; } - if (f->f_prevcount && now >= REPEATTIME(f)) { + if (f->f_prevcount && timer_now() >= REPEATTIME(f)) { logit("flush %s: repeated %d times, %d sec.\n", TypeNames[f->f_type], f->f_prevcount, repeatinterval[f->f_repeatcount]); @@ -1947,8 +1958,6 @@ void domark(int signo) BACKOFF(f); } } - - (void)alarm(TIMERINTVL); } void debug_switch(int signo) @@ -2059,6 +2068,10 @@ void init(void) char *p; int i; + /* Set up timer framework */ + if (timer_init()) + err(1, "Failed initializing internal timers"); + /* Get hostname */ (void)gethostname(LocalHostName, sizeof(LocalHostName)); LocalDomain = emptystring; diff --git a/src/syslogd.h b/src/syslogd.h index 26ff0a8..98de174 100644 --- a/src/syslogd.h +++ b/src/syslogd.h @@ -43,7 +43,8 @@ #define MAXSVLINE MAXLINE /* maximum saved line length */ #define DEFUPRI (LOG_USER | LOG_NOTICE) #define DEFSPRI (LOG_KERN | LOG_CRIT) -#define TIMERINTVL 15 /* interval for checking flush, mark */ +#define TIMERINTVL 30 /* interval for checking flush, mark */ +#define FLUSHINTVL 10 /* interval for checking flush, mark */ #define RCVBUF_MINSIZE (80 * MAXLINE) /* minimum size of dgram rcv buffer */ /*