aboutsummaryrefslogtreecommitdiff
path: root/sysklogd
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-04 21:22:11 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-04 21:22:11 +0000
commita0e2a0a19272268fc042f159e74f1573a10202cd (patch)
treed274d7a270bdb5347bbb462c65473f2997f6fb40 /sysklogd
parentb8934971516d69086cf693a1a51acf649930ee64 (diff)
downloadbusybox-w32-a0e2a0a19272268fc042f159e74f1573a10202cd.tar.gz
busybox-w32-a0e2a0a19272268fc042f159e74f1573a10202cd.tar.bz2
busybox-w32-a0e2a0a19272268fc042f159e74f1573a10202cd.zip
syslogd: start using bb_common_bufsiz1 instead of stack/malloc
logger: optimize, also use bb_common_bufsiz1 (~40 bytes) tested to eat arbitrarily-sized input at high speed - ok
Diffstat (limited to 'sysklogd')
-rw-r--r--sysklogd/logger.c54
-rw-r--r--sysklogd/syslogd.c63
2 files changed, 54 insertions, 63 deletions
diff --git a/sysklogd/logger.c b/sysklogd/logger.c
index 8901bd79f..3a4f51575 100644
--- a/sysklogd/logger.c
+++ b/sysklogd/logger.c
@@ -8,13 +8,6 @@
8 */ 8 */
9 9
10#include "busybox.h" 10#include "busybox.h"
11#include <stdio.h>
12#include <unistd.h>
13#include <sys/types.h>
14#include <fcntl.h>
15#include <ctype.h>
16#include <string.h>
17#include <stdlib.h>
18 11
19#if !defined CONFIG_SYSLOGD 12#if !defined CONFIG_SYSLOGD
20 13
@@ -93,49 +86,40 @@ int logger_main(int argc, char **argv)
93 char *opt_p, *opt_t; 86 char *opt_p, *opt_t;
94 int pri = LOG_USER | LOG_NOTICE; 87 int pri = LOG_USER | LOG_NOTICE;
95 int option = 0; 88 int option = 0;
96 int c, i; 89 char name[80];
97 char buf[1024], name[128];
98 90
99 /* Fill out the name string early (may be overwritten later) */ 91 /* Fill out the name string early (may be overwritten later) */
100 bb_getpwuid(name, geteuid(), sizeof(name)); 92 bb_getpwuid(name, geteuid(), sizeof(name));
101 93
102 /* Parse any options */ 94 /* Parse any options */
103 opt = getopt32(argc, argv, "p:st:", &opt_p, &opt_t); 95 opt = getopt32(argc, argv, "p:st:", &opt_p, &opt_t);
96 argc -= optind;
97 argv += optind;
104 if (opt & 0x1) pri = pencode(opt_p); // -p 98 if (opt & 0x1) pri = pencode(opt_p); // -p
105 if (opt & 0x2) option |= LOG_PERROR; // -s 99 if (opt & 0x2) option |= LOG_PERROR; // -s
106 if (opt & 0x4) safe_strncpy(name, opt_t, sizeof(name)); // -t 100 if (opt & 0x4) safe_strncpy(name, opt_t, sizeof(name)); // -t
107 101
108 openlog(name, option, 0); 102 openlog(name, option, 0);
109 if (optind == argc) { 103 if (!argc) {
110 do { 104 while (fgets(bb_common_bufsiz1, BUFSIZ, stdin)) {
111 /* read from stdin */ 105 if (bb_common_bufsiz1[0]
112 i = 0; 106 && NOT_LONE_CHAR(bb_common_bufsiz1, '\n')
113 while ((c = getc(stdin)) != EOF && c != '\n' && 107 ) {
114 i < (sizeof(buf)-1)) { 108 /* Neither "" nor "\n" */
115 buf[i++] = c; 109 syslog(pri, "%s", bb_common_bufsiz1);
116 }
117 if (i > 0) {
118 buf[i++] = '\0';
119 syslog(pri, "%s", buf);
120 } 110 }
121 } while (c != EOF); 111 }
122 } else { 112 } else {
123 char *message = NULL; 113 char *message = NULL;
124 int len = argc - optind; /* for the space between the args 114 int len = 1; /* for NUL */
125 and '\0' */ 115 int pos = 0;
126 opt = len; 116 do {
127 argv += optind; 117 len += strlen(*argv) + 1;
128 for (i = 0; i < opt; i++) {
129 len += strlen(*argv);
130 message = xrealloc(message, len); 118 message = xrealloc(message, len);
131 if(!i) 119 sprintf(message + pos, " %s", *argv),
132 message[0] = '\0'; 120 pos = len;
133 else 121 } while (*++argv);
134 strcat(message, " "); 122 syslog(pri, "%s", message + 1); /* skip leading " " */
135 strcat(message, *argv);
136 argv++;
137 }
138 syslog(pri, "%s", message);
139 } 123 }
140 124
141 closelog(); 125 closelog();
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 7edce7a0a..fbb85338a 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -56,13 +56,23 @@ static int remoteFD = -1;
56static struct sockaddr_in remoteAddr; 56static struct sockaddr_in remoteAddr;
57#endif 57#endif
58 58
59 59/* We are using bb_common_bufsiz1 for buffering: */
60/* NB: we may need 2x this amount on stack... */ 60enum { MAX_READ = (BUFSIZ/6) & ~0xf };
61enum { MAX_READ = 1024 }; 61/* We recv into this... (size: MAX_READ ~== BUFSIZ/6) */
62 62#define RECVBUF bb_common_bufsiz1
63 63/* ...then copy here, escaping control chars */
64/* options */ 64/* (can grow x2 + 1 max ~== BUFSIZ/3) */
65/* Correct regardless of combination of CONFIG_xxx */ 65#define PARSEBUF (bb_common_bufsiz1 + MAX_READ)
66/* ...then sprintf into this, adding timestamp (15 chars),
67 * host (64), fac.prio (20) to the message */
68/* (growth by: 15 + 64 + 20 + delims = ~110) */
69#define PRINTBUF (bb_common_bufsiz1 + 3*MAX_READ + 0x10)
70/* totals: BUFSIZ/6 + BUFSIZ/3 + BUFSIZ/3 = BUFSIZ - BUFSIZ/6
71 * -- we have BUFSIZ/6 extra at the ent of PRINTBUF
72 * which covers needed ~110 extra bytes (and much more) */
73
74
75/* Options */
66enum { 76enum {
67 OPTBIT_mark = 0, // -m 77 OPTBIT_mark = 0, // -m
68 OPTBIT_nofork, // -n 78 OPTBIT_nofork, // -n
@@ -175,11 +185,12 @@ static void ipcsyslog_init(void)
175 } 185 }
176} 186}
177 187
178/* write message to buffer */ 188/* Write message to shared mem buffer */
179static void log_to_shmem(const char *msg, int len) 189static void log_to_shmem(const char *msg, int len)
180{ 190{
181 static /*const*/ struct sembuf SMwup[1] = { {1, -1, IPC_NOWAIT} }; 191 /* Why libc insists on these being rw? */
182 static /*const*/ struct sembuf SMwdn[3] = { {0, 0}, {1, 0}, {1, +1} }; 192 static struct sembuf SMwup[1] = { {1, -1, IPC_NOWAIT} };
193 static struct sembuf SMwdn[3] = { {0, 0}, {1, 0}, {1, +1} };
183 194
184 int old_tail, new_tail; 195 int old_tail, new_tail;
185 char *c; 196 char *c;
@@ -362,9 +373,9 @@ static void parse_fac_prio_20(int pri, char *res20)
362 } 373 }
363} 374}
364 375
365/* len parameter is used only for "is there a timestamp?" check 376/* len parameter is used only for "is there a timestamp?" check.
366 * NB: some callers cheat and supply 0 when they know 377 * NB: some callers cheat and supply 0 when they know
367 * that there is no timestamp, short-cutting the test */ 378 * that there is no timestamp, short-cutting the test. */
368static void timestamp_and_log(int pri, char *msg, int len) 379static void timestamp_and_log(int pri, char *msg, int len)
369{ 380{
370 time_t now; 381 time_t now;
@@ -385,31 +396,29 @@ static void timestamp_and_log(int pri, char *msg, int len)
385 if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) { 396 if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
386 if (LOG_PRI(pri) < logLevel) { 397 if (LOG_PRI(pri) < logLevel) {
387 if (option_mask32 & OPT_small) 398 if (option_mask32 & OPT_small)
388 msg = xasprintf("%s %s\n", timestamp, msg); 399 sprintf(PRINTBUF, "%s %s\n", timestamp, msg);
389 else { 400 else {
390 char res[20]; 401 char res[20];
391 parse_fac_prio_20(pri, res); 402 parse_fac_prio_20(pri, res);
392 msg = xasprintf("%s %s %s %s\n", timestamp, localHostName, res, msg); 403 sprintf(PRINTBUF, "%s %s %s %s\n", timestamp, localHostName, res, msg);
393 } 404 }
394 log_locally(msg); 405 log_locally(PRINTBUF);
395 free(msg);
396 } 406 }
397 } 407 }
398} 408}
399 409
400static void split_escape_and_log(char *tmpbuf, int len) 410static void split_escape_and_log(char *tmpbuf, int len)
401{ 411{
402 char line[len * 2 + 1]; /* gcc' cheap alloca */
403 char *p = tmpbuf; 412 char *p = tmpbuf;
404 413
405 tmpbuf += len; 414 tmpbuf += len;
406 while (p < tmpbuf) { 415 while (p < tmpbuf) {
407 char c; 416 char c;
408 char *q = line; 417 char *q = PARSEBUF;
409 int pri = (LOG_USER | LOG_NOTICE); 418 int pri = (LOG_USER | LOG_NOTICE);
410 419
411 if (*p == '<') { 420 if (*p == '<') {
412 /* Parse the magic priority number. */ 421 /* Parse the magic priority number */
413 pri = bb_strtou(p + 1, &p, 10); 422 pri = bb_strtou(p + 1, &p, 10);
414 if (*p == '>') p++; 423 if (*p == '>') p++;
415 if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) { 424 if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) {
@@ -427,8 +436,8 @@ static void split_escape_and_log(char *tmpbuf, int len)
427 *q++ = c; 436 *q++ = c;
428 } 437 }
429 *q = '\0'; 438 *q = '\0';
430 /* now log it */ 439 /* Now log it */
431 timestamp_and_log(pri, line, q - line); 440 timestamp_and_log(pri, PARSEBUF, q - PARSEBUF);
432 } 441 }
433} 442}
434 443
@@ -509,11 +518,10 @@ static void do_syslogd(void)
509 518
510 if (FD_ISSET(sock_fd, &fds)) { 519 if (FD_ISSET(sock_fd, &fds)) {
511 int i; 520 int i;
512#define tmpbuf bb_common_bufsiz1 521 i = recv(sock_fd, RECVBUF, MAX_READ - 1, 0);
513 i = recv(sock_fd, tmpbuf, MAX_READ, 0);
514 if (i <= 0) 522 if (i <= 0)
515 bb_perror_msg_and_die("UNIX socket error"); 523 bb_perror_msg_and_die("UNIX socket error");
516 /* TODO: maybe supress duplicates? */ 524 /* TODO: maybe suppress duplicates? */
517#if ENABLE_FEATURE_REMOTE_LOG 525#if ENABLE_FEATURE_REMOTE_LOG
518 /* We are not modifying log messages in any way before send */ 526 /* We are not modifying log messages in any way before send */
519 /* Remote site cannot trust _us_ anyway and need to do validation again */ 527 /* Remote site cannot trust _us_ anyway and need to do validation again */
@@ -523,15 +531,14 @@ static void do_syslogd(void)
523 } 531 }
524 if (-1 != remoteFD) { 532 if (-1 != remoteFD) {
525 /* send message to remote logger, ignore possible error */ 533 /* send message to remote logger, ignore possible error */
526 sendto(remoteFD, tmpbuf, i, MSG_DONTWAIT, 534 sendto(remoteFD, RECVBUF, i, MSG_DONTWAIT,
527 (struct sockaddr *) &remoteAddr, 535 (struct sockaddr *) &remoteAddr,
528 sizeof(remoteAddr)); 536 sizeof(remoteAddr));
529 } 537 }
530 } 538 }
531#endif 539#endif
532 tmpbuf[i] = '\0'; 540 RECVBUF[i] = '\0';
533 split_escape_and_log(tmpbuf, i); 541 split_escape_and_log(RECVBUF, i);
534#undef tmpbuf
535 } /* FD_ISSET() */ 542 } /* FD_ISSET() */
536 } /* for */ 543 } /* for */
537} 544}