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 */ |