diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-20 20:03:03 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-20 20:03:03 +0000 |
| commit | 4f93cde77f6a048e9ff91ad6323cffc5e35fe97a (patch) | |
| tree | 7e49e43694ce03995712205e5eeb14495dfc85d4 /sysklogd | |
| parent | f36306502108c35c574c3f2eb0b7b6d93a0a483e (diff) | |
| download | busybox-w32-4f93cde77f6a048e9ff91ad6323cffc5e35fe97a.tar.gz busybox-w32-4f93cde77f6a048e9ff91ad6323cffc5e35fe97a.tar.bz2 busybox-w32-4f93cde77f6a048e9ff91ad6323cffc5e35fe97a.zip | |
syslogd: fix it for small BUFSIZ case
Diffstat (limited to 'sysklogd')
| -rw-r--r-- | sysklogd/syslogd.c | 138 |
1 files changed, 67 insertions, 71 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 @@ | |||
| 37 | 37 | ||
| 38 | #define DEBUG 0 | 38 | #define DEBUG 0 |
| 39 | 39 | ||
| 40 | // Semaphore operation structures | 40 | /* MARK code is not very useful, is bloat, and broken: |
| 41 | struct shbuf_ds { | 41 | * can deadlock if alarmed to make MARK while writing to IPC buffer |
| 42 | int32_t size; // size of data written | 42 | * (semaphores are down but do_mark routine tries to down them again) */ |
| 43 | int32_t head; // start of message list | 43 | #undef SYSLOGD_MARK |
| 44 | int32_t tail; // end of message list | ||
| 45 | char data[1]; // data/messages | ||
| 46 | }; // shared memory pointer | ||
| 47 | |||
| 48 | struct globals { | ||
| 49 | |||
| 50 | const char *logFilePath; | ||
| 51 | int logFD; | ||
| 52 | |||
| 53 | /* This is not very useful, is bloat, and broken: | ||
| 54 | * can deadlock if alarmed to make MARK while writing to IPC buffer | ||
| 55 | * (semaphores are down but do_mark routine tries to down them again) */ | ||
| 56 | #ifdef SYSLOGD_MARK | ||
| 57 | /* interval between marks in seconds */ | ||
| 58 | int markInterval; | ||
| 59 | #endif | ||
| 60 | 44 | ||
| 61 | /* level of messages to be locally logged */ | 45 | enum { MAX_READ = 256 }; |
| 62 | int logLevel; | ||
| 63 | 46 | ||
| 64 | #if ENABLE_FEATURE_ROTATE_LOGFILE | 47 | /* Semaphore operation structures */ |
| 65 | /* max size of message file before being rotated */ | 48 | struct shbuf_ds { |
| 66 | unsigned logFileSize; | 49 | int32_t size; /* size of data written */ |
| 67 | /* number of rotated message files */ | 50 | int32_t head; /* start of message list */ |
| 68 | unsigned logFileRotate; | 51 | int32_t tail; /* end of message list */ |
| 69 | unsigned curFileSize; | 52 | char data[1]; /* data/messages */ |
| 70 | smallint isRegular; | 53 | }; |
| 71 | #endif | ||
| 72 | 54 | ||
| 73 | #if ENABLE_FEATURE_REMOTE_LOG | 55 | /* Allows us to have smaller initializer. Ugly. */ |
| 74 | /* udp socket for logging to remote host */ | 56 | #define GLOBALS \ |
| 75 | int remoteFD; | 57 | const char *logFilePath; \ |
| 76 | len_and_sockaddr* remoteAddr; | 58 | int logFD; \ |
| 77 | #endif | 59 | /* interval between marks in seconds */ \ |
| 60 | /*int markInterval;*/ \ | ||
| 61 | /* level of messages to be logged */ \ | ||
| 62 | int logLevel; \ | ||
| 63 | USE_FEATURE_ROTATE_LOGFILE( \ | ||
| 64 | /* max size of file before rotation */ \ | ||
| 65 | unsigned logFileSize; \ | ||
| 66 | /* number of rotated message files */ \ | ||
| 67 | unsigned logFileRotate; \ | ||
| 68 | unsigned curFileSize; \ | ||
| 69 | smallint isRegular; \ | ||
| 70 | ) \ | ||
| 71 | USE_FEATURE_REMOTE_LOG( \ | ||
| 72 | /* udp socket for remote logging */ \ | ||
| 73 | int remoteFD; \ | ||
| 74 | len_and_sockaddr* remoteAddr; \ | ||
| 75 | ) \ | ||
| 76 | USE_FEATURE_IPC_SYSLOG( \ | ||
| 77 | int shmid; /* ipc shared memory id */ \ | ||
| 78 | int s_semid; /* ipc semaphore id */ \ | ||
| 79 | int shm_size; \ | ||
| 80 | struct sembuf SMwup[1]; \ | ||
| 81 | struct sembuf SMwdn[3]; \ | ||
| 82 | ) | ||
| 83 | |||
| 84 | struct init_globals { | ||
| 85 | GLOBALS | ||
| 86 | }; | ||
| 78 | 87 | ||
| 88 | struct globals { | ||
| 89 | GLOBALS | ||
| 79 | #if ENABLE_FEATURE_IPC_SYSLOG | 90 | #if ENABLE_FEATURE_IPC_SYSLOG |
| 80 | int shmid; // ipc shared memory id | ||
| 81 | int s_semid; // ipc semaphore id | ||
| 82 | int shm_size; | ||
| 83 | struct sembuf SMwup[1]; | ||
| 84 | struct sembuf SMwdn[3]; | ||
| 85 | struct shbuf_ds *shbuf; | 91 | struct shbuf_ds *shbuf; |
| 86 | #endif | 92 | #endif |
| 87 | |||
| 88 | time_t last_log_time; | 93 | time_t last_log_time; |
| 89 | /* localhost's name */ | 94 | /* localhost's name */ |
| 90 | char localHostName[64]; | 95 | char localHostName[64]; |
| 91 | 96 | ||
| 92 | }; /* struct globals */ | 97 | /* We recv into recvbuf... */ |
| 98 | char recvbuf[MAX_READ]; | ||
| 99 | /* ...then copy to parsebuf, escaping control chars */ | ||
| 100 | /* (can grow x2 max) */ | ||
| 101 | char parsebuf[MAX_READ*2]; | ||
| 102 | /* ...then sprintf into printbuf, adding timestamp (15 chars), | ||
| 103 | * host (64), fac.prio (20) to the message */ | ||
| 104 | /* (growth by: 15 + 64 + 20 + delims = ~110) */ | ||
| 105 | char printbuf[MAX_READ*2 + 128]; | ||
| 106 | }; | ||
| 93 | 107 | ||
| 94 | static const struct globals init_globals = { | 108 | static const struct init_globals init_data = { |
| 95 | .logFilePath = "/var/log/messages", | 109 | .logFilePath = "/var/log/messages", |
| 96 | .logFD = -1, | 110 | .logFD = -1, |
| 97 | #ifdef SYSLOGD_MARK | 111 | #ifdef SYSLOGD_MARK |
| @@ -112,28 +126,11 @@ static const struct globals init_globals = { | |||
| 112 | .SMwup = { {1, -1, IPC_NOWAIT} }, | 126 | .SMwup = { {1, -1, IPC_NOWAIT} }, |
| 113 | .SMwdn = { {0, 0}, {1, 0}, {1, +1} }, | 127 | .SMwdn = { {0, 0}, {1, 0}, {1, +1} }, |
| 114 | #endif | 128 | #endif |
| 115 | // FIXME: hidden tail with lotsa zeroes is here.... | ||
| 116 | }; | 129 | }; |
| 117 | 130 | ||
| 118 | #define G (*ptr_to_globals) | 131 | #define G (*ptr_to_globals) |
| 119 | 132 | ||
| 120 | 133 | ||
| 121 | /* We are using bb_common_bufsiz1 for buffering: */ | ||
| 122 | enum { MAX_READ = (BUFSIZ/6) & ~0xf }; | ||
| 123 | /* We recv into RECVBUF... (size: MAX_READ ~== BUFSIZ/6) */ | ||
| 124 | #define RECVBUF bb_common_bufsiz1 | ||
| 125 | /* ...then copy to PARSEBUF, escaping control chars */ | ||
| 126 | /* (can grow x2 max ~== BUFSIZ/3) */ | ||
| 127 | #define PARSEBUF (bb_common_bufsiz1 + MAX_READ) | ||
| 128 | /* ...then sprintf into PRINTBUF, adding timestamp (15 chars), | ||
| 129 | * host (64), fac.prio (20) to the message */ | ||
| 130 | /* (growth by: 15 + 64 + 20 + delims = ~110) */ | ||
| 131 | #define PRINTBUF (bb_common_bufsiz1 + 3*MAX_READ) | ||
| 132 | /* totals: BUFSIZ == BUFSIZ/6 + BUFSIZ/3 + (BUFSIZ/3+BUFSIZ/6) | ||
| 133 | * -- we have BUFSIZ/6 extra at the ent of PRINTBUF | ||
| 134 | * which covers needed ~110 extra bytes (and much more) */ | ||
| 135 | |||
| 136 | |||
| 137 | /* Options */ | 134 | /* Options */ |
| 138 | enum { | 135 | enum { |
| 139 | OPTBIT_mark = 0, // -m | 136 | OPTBIT_mark = 0, // -m |
| @@ -437,13 +434,13 @@ static void timestamp_and_log(int pri, char *msg, int len) | |||
| 437 | if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) { | 434 | if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) { |
| 438 | if (LOG_PRI(pri) < G.logLevel) { | 435 | if (LOG_PRI(pri) < G.logLevel) { |
| 439 | if (option_mask32 & OPT_small) | 436 | if (option_mask32 & OPT_small) |
| 440 | sprintf(PRINTBUF, "%s %s\n", timestamp, msg); | 437 | sprintf(G.printbuf, "%s %s\n", timestamp, msg); |
| 441 | else { | 438 | else { |
| 442 | char res[20]; | 439 | char res[20]; |
| 443 | parse_fac_prio_20(pri, res); | 440 | parse_fac_prio_20(pri, res); |
| 444 | sprintf(PRINTBUF, "%s %s %s %s\n", timestamp, G.localHostName, res, msg); | 441 | sprintf(G.printbuf, "%s %s %s %s\n", timestamp, G.localHostName, res, msg); |
| 445 | } | 442 | } |
| 446 | log_locally(PRINTBUF); | 443 | log_locally(G.printbuf); |
| 447 | } | 444 | } |
| 448 | } | 445 | } |
| 449 | } | 446 | } |
| @@ -455,7 +452,7 @@ static void split_escape_and_log(char *tmpbuf, int len) | |||
| 455 | tmpbuf += len; | 452 | tmpbuf += len; |
| 456 | while (p < tmpbuf) { | 453 | while (p < tmpbuf) { |
| 457 | char c; | 454 | char c; |
| 458 | char *q = PARSEBUF; | 455 | char *q = G.parsebuf; |
| 459 | int pri = (LOG_USER | LOG_NOTICE); | 456 | int pri = (LOG_USER | LOG_NOTICE); |
| 460 | 457 | ||
| 461 | if (*p == '<') { | 458 | if (*p == '<') { |
| @@ -478,7 +475,7 @@ static void split_escape_and_log(char *tmpbuf, int len) | |||
| 478 | } | 475 | } |
| 479 | *q = '\0'; | 476 | *q = '\0'; |
| 480 | /* Now log it */ | 477 | /* Now log it */ |
| 481 | timestamp_and_log(pri, PARSEBUF, q - PARSEBUF); | 478 | timestamp_and_log(pri, G.parsebuf, q - G.parsebuf); |
| 482 | } | 479 | } |
| 483 | } | 480 | } |
| 484 | 481 | ||
| @@ -572,7 +569,7 @@ static void do_syslogd(void) | |||
| 572 | 569 | ||
| 573 | if (FD_ISSET(sock_fd, &fds)) { | 570 | if (FD_ISSET(sock_fd, &fds)) { |
| 574 | int i; | 571 | int i; |
| 575 | i = recv(sock_fd, RECVBUF, MAX_READ - 1, 0); | 572 | i = recv(sock_fd, G.recvbuf, MAX_READ - 1, 0); |
| 576 | if (i <= 0) | 573 | if (i <= 0) |
| 577 | bb_perror_msg_and_die("UNIX socket error"); | 574 | bb_perror_msg_and_die("UNIX socket error"); |
| 578 | /* TODO: maybe suppress duplicates? */ | 575 | /* TODO: maybe suppress duplicates? */ |
| @@ -585,13 +582,13 @@ static void do_syslogd(void) | |||
| 585 | } | 582 | } |
| 586 | if (-1 != G.remoteFD) { | 583 | if (-1 != G.remoteFD) { |
| 587 | /* send message to remote logger, ignore possible error */ | 584 | /* send message to remote logger, ignore possible error */ |
| 588 | sendto(G.remoteFD, RECVBUF, i, MSG_DONTWAIT, | 585 | sendto(G.remoteFD, G.recvbuf, i, MSG_DONTWAIT, |
| 589 | &G.remoteAddr->sa, G.remoteAddr->len); | 586 | &G.remoteAddr->sa, G.remoteAddr->len); |
| 590 | } | 587 | } |
| 591 | } | 588 | } |
| 592 | #endif | 589 | #endif |
| 593 | RECVBUF[i] = '\0'; | 590 | G.recvbuf[i] = '\0'; |
| 594 | split_escape_and_log(RECVBUF, i); | 591 | split_escape_and_log(G.recvbuf, i); |
| 595 | } /* FD_ISSET() */ | 592 | } /* FD_ISSET() */ |
| 596 | } /* for */ | 593 | } /* for */ |
| 597 | } | 594 | } |
| @@ -602,8 +599,7 @@ int syslogd_main(int argc, char **argv) | |||
| 602 | char OPTION_DECL; | 599 | char OPTION_DECL; |
| 603 | char *p; | 600 | char *p; |
| 604 | 601 | ||
| 605 | PTR_TO_GLOBALS = xzalloc(sizeof(G)); | 602 | PTR_TO_GLOBALS = memcpy(xzalloc(sizeof(G)), &init_data, sizeof(init_data)); |
| 606 | memcpy(ptr_to_globals, &init_globals, sizeof(init_globals)); | ||
| 607 | 603 | ||
| 608 | /* do normal option parsing */ | 604 | /* do normal option parsing */ |
| 609 | opt_complementary = "=0"; /* no non-option params */ | 605 | opt_complementary = "=0"; /* no non-option params */ |
