From 4f93cde77f6a048e9ff91ad6323cffc5e35fe97a Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Tue, 20 Mar 2007 20:03:03 +0000 Subject: [PATCH] syslogd: fix it for small BUFSIZ case --- sysklogd/syslogd.c | 140 ++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 72 deletions(-) diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 8ae75c974..2a2b20c8b 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -37,61 +37,75 @@ #define DEBUG 0 -// Semaphore operation structures +/* MARK code is not very useful, is bloat, and broken: + * can deadlock if alarmed to make MARK while writing to IPC buffer + * (semaphores are down but do_mark routine tries to down them again) */ +#undef SYSLOGD_MARK + +enum { MAX_READ = 256 }; + +/* Semaphore operation structures */ struct shbuf_ds { - int32_t size; // size of data written - int32_t head; // start of message list - int32_t tail; // end of message list - char data[1]; // data/messages -}; // shared memory pointer + int32_t size; /* size of data written */ + int32_t head; /* start of message list */ + int32_t tail; /* end of message list */ + char data[1]; /* data/messages */ +}; + +/* Allows us to have smaller initializer. Ugly. */ +#define GLOBALS \ + const char *logFilePath; \ + int logFD; \ + /* interval between marks in seconds */ \ + /*int markInterval;*/ \ + /* level of messages to be logged */ \ + int logLevel; \ +USE_FEATURE_ROTATE_LOGFILE( \ + /* max size of file before rotation */ \ + unsigned logFileSize; \ + /* number of rotated message files */ \ + unsigned logFileRotate; \ + unsigned curFileSize; \ + smallint isRegular; \ +) \ +USE_FEATURE_REMOTE_LOG( \ + /* udp socket for remote logging */ \ + int remoteFD; \ + len_and_sockaddr* remoteAddr; \ +) \ +USE_FEATURE_IPC_SYSLOG( \ + int shmid; /* ipc shared memory id */ \ + int s_semid; /* ipc semaphore id */ \ + int shm_size; \ + struct sembuf SMwup[1]; \ + struct sembuf SMwdn[3]; \ +) + +struct init_globals { + GLOBALS +}; struct globals { - - const char *logFilePath; - int logFD; - - /* This is not very useful, is bloat, and broken: - * can deadlock if alarmed to make MARK while writing to IPC buffer - * (semaphores are down but do_mark routine tries to down them again) */ -#ifdef SYSLOGD_MARK - /* interval between marks in seconds */ - int markInterval; -#endif - - /* level of messages to be locally logged */ - int logLevel; - -#if ENABLE_FEATURE_ROTATE_LOGFILE - /* max size of message file before being rotated */ - unsigned logFileSize; - /* number of rotated message files */ - unsigned logFileRotate; - unsigned curFileSize; - smallint isRegular; -#endif - -#if ENABLE_FEATURE_REMOTE_LOG - /* udp socket for logging to remote host */ - int remoteFD; - len_and_sockaddr* remoteAddr; -#endif - + GLOBALS #if ENABLE_FEATURE_IPC_SYSLOG - int shmid; // ipc shared memory id - int s_semid; // ipc semaphore id - int shm_size; - struct sembuf SMwup[1]; - struct sembuf SMwdn[3]; struct shbuf_ds *shbuf; #endif - time_t last_log_time; /* localhost's name */ char localHostName[64]; -}; /* struct globals */ + /* We recv into recvbuf... */ + char recvbuf[MAX_READ]; + /* ...then copy to parsebuf, escaping control chars */ + /* (can grow x2 max) */ + char parsebuf[MAX_READ*2]; + /* ...then sprintf into printbuf, adding timestamp (15 chars), + * host (64), fac.prio (20) to the message */ + /* (growth by: 15 + 64 + 20 + delims = ~110) */ + char printbuf[MAX_READ*2 + 128]; +}; -static const struct globals init_globals = { +static const struct init_globals init_data = { .logFilePath = "/var/log/messages", .logFD = -1, #ifdef SYSLOGD_MARK @@ -112,28 +126,11 @@ static const struct globals init_globals = { .SMwup = { {1, -1, IPC_NOWAIT} }, .SMwdn = { {0, 0}, {1, 0}, {1, +1} }, #endif - // FIXME: hidden tail with lotsa zeroes is here.... }; #define G (*ptr_to_globals) -/* We are using bb_common_bufsiz1 for buffering: */ -enum { MAX_READ = (BUFSIZ/6) & ~0xf }; -/* We recv into RECVBUF... (size: MAX_READ ~== BUFSIZ/6) */ -#define RECVBUF bb_common_bufsiz1 -/* ...then copy to PARSEBUF, escaping control chars */ -/* (can grow x2 max ~== BUFSIZ/3) */ -#define PARSEBUF (bb_common_bufsiz1 + MAX_READ) -/* ...then sprintf into PRINTBUF, adding timestamp (15 chars), - * host (64), fac.prio (20) to the message */ -/* (growth by: 15 + 64 + 20 + delims = ~110) */ -#define PRINTBUF (bb_common_bufsiz1 + 3*MAX_READ) -/* totals: BUFSIZ == BUFSIZ/6 + BUFSIZ/3 + (BUFSIZ/3+BUFSIZ/6) - * -- we have BUFSIZ/6 extra at the ent of PRINTBUF - * which covers needed ~110 extra bytes (and much more) */ - - /* Options */ enum { OPTBIT_mark = 0, // -m @@ -437,13 +434,13 @@ static void timestamp_and_log(int pri, char *msg, int len) if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) { if (LOG_PRI(pri) < G.logLevel) { if (option_mask32 & OPT_small) - sprintf(PRINTBUF, "%s %s\n", timestamp, msg); + sprintf(G.printbuf, "%s %s\n", timestamp, msg); else { char res[20]; parse_fac_prio_20(pri, res); - sprintf(PRINTBUF, "%s %s %s %s\n", timestamp, G.localHostName, res, msg); + sprintf(G.printbuf, "%s %s %s %s\n", timestamp, G.localHostName, res, msg); } - log_locally(PRINTBUF); + log_locally(G.printbuf); } } } @@ -455,7 +452,7 @@ static void split_escape_and_log(char *tmpbuf, int len) tmpbuf += len; while (p < tmpbuf) { char c; - char *q = PARSEBUF; + char *q = G.parsebuf; int pri = (LOG_USER | LOG_NOTICE); if (*p == '<') { @@ -478,7 +475,7 @@ static void split_escape_and_log(char *tmpbuf, int len) } *q = '\0'; /* Now log it */ - timestamp_and_log(pri, PARSEBUF, q - PARSEBUF); + timestamp_and_log(pri, G.parsebuf, q - G.parsebuf); } } @@ -572,7 +569,7 @@ static void do_syslogd(void) if (FD_ISSET(sock_fd, &fds)) { int i; - i = recv(sock_fd, RECVBUF, MAX_READ - 1, 0); + i = recv(sock_fd, G.recvbuf, MAX_READ - 1, 0); if (i <= 0) bb_perror_msg_and_die("UNIX socket error"); /* TODO: maybe suppress duplicates? */ @@ -585,13 +582,13 @@ static void do_syslogd(void) } if (-1 != G.remoteFD) { /* send message to remote logger, ignore possible error */ - sendto(G.remoteFD, RECVBUF, i, MSG_DONTWAIT, + sendto(G.remoteFD, G.recvbuf, i, MSG_DONTWAIT, &G.remoteAddr->sa, G.remoteAddr->len); } } #endif - RECVBUF[i] = '\0'; - split_escape_and_log(RECVBUF, i); + G.recvbuf[i] = '\0'; + split_escape_and_log(G.recvbuf, i); } /* FD_ISSET() */ } /* for */ } @@ -602,8 +599,7 @@ int syslogd_main(int argc, char **argv) char OPTION_DECL; char *p; - PTR_TO_GLOBALS = xzalloc(sizeof(G)); - memcpy(ptr_to_globals, &init_globals, sizeof(init_globals)); + PTR_TO_GLOBALS = memcpy(xzalloc(sizeof(G)), &init_data, sizeof(init_data)); /* do normal option parsing */ opt_complementary = "=0"; /* no non-option params */