aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-02-13 09:19:14 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-02-13 09:19:14 +0000
commit75cddd8eb514082c8f9945ae1976f97c4b0413b4 (patch)
treed83dfad188c25d4765ec3ba1156c697e2442cdb3
parent0a4624aece9e46b0580dd2d5867b41f6d06ef160 (diff)
downloadbusybox-w32-75cddd8eb514082c8f9945ae1976f97c4b0413b4.tar.gz
busybox-w32-75cddd8eb514082c8f9945ae1976f97c4b0413b4.tar.bz2
busybox-w32-75cddd8eb514082c8f9945ae1976f97c4b0413b4.zip
syslogd: send '\n'-terminated messages over the network.
fully closes bug 1574. +8 bytes.
-rw-r--r--sysklogd/syslogd.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index f3ebf9392..457f38103 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -370,13 +370,15 @@ static void parse_fac_prio_20(int pri, char *res20)
370 c_fac = facilitynames; 370 c_fac = facilitynames;
371 while (c_fac->c_name) { 371 while (c_fac->c_name) {
372 if (c_fac->c_val != (LOG_FAC(pri) << 3)) { 372 if (c_fac->c_val != (LOG_FAC(pri) << 3)) {
373 c_fac++; continue; 373 c_fac++;
374 continue;
374 } 375 }
375 /* facility is found, look for prio */ 376 /* facility is found, look for prio */
376 c_pri = prioritynames; 377 c_pri = prioritynames;
377 while (c_pri->c_name) { 378 while (c_pri->c_name) {
378 if (c_pri->c_val != LOG_PRI(pri)) { 379 if (c_pri->c_val != LOG_PRI(pri)) {
379 c_pri++; continue; 380 c_pri++;
381 continue;
380 } 382 }
381 snprintf(res20, 20, "%s.%s", 383 snprintf(res20, 20, "%s.%s",
382 c_fac->c_name, c_pri->c_name); 384 c_fac->c_name, c_pri->c_name);
@@ -428,6 +430,9 @@ static void timestamp_and_log_internal(const char *msg)
428 timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)msg, 0); 430 timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)msg, 0);
429} 431}
430 432
433/* tmpbuf[len] is a NUL byte (set by caller), but there can be other,
434 * embedded NULs. Split messages on each of these NULs, parse prio,
435 * escape control chars and log each locally. */
431static void split_escape_and_log(char *tmpbuf, int len) 436static void split_escape_and_log(char *tmpbuf, int len)
432{ 437{
433 char *p = tmpbuf; 438 char *p = tmpbuf;
@@ -556,30 +561,24 @@ static void do_syslogd(void)
556 size_t sz; 561 size_t sz;
557 read_again: 562 read_again:
558 sz = safe_read(sock_fd, G.recvbuf, MAX_READ - 1); 563 sz = safe_read(sock_fd, G.recvbuf, MAX_READ - 1);
559 if (sz < 0) { 564 if (sz < 0)
560 bb_perror_msg_and_die("read from /dev/log"); 565 bb_perror_msg_and_die("read from /dev/log");
561 }
562 566
563 /* Drop trailing NULs (typically there is one NUL) */ 567 /* Drop trailing '\n' and NULs (typically there is one NUL) */
564 while (1) { 568 while (1) {
565 if (sz == 0) 569 if (sz == 0)
566 goto read_again; 570 goto read_again;
567 /* man 3 syslog says: "A trailing newline is added when needed". 571 /* man 3 syslog says: "A trailing newline is added when needed".
568 * However, neither glibc nor uclibc do this: 572 * However, neither glibc nor uclibc do this:
569 * syslog(prio, "test") sends "test\0" to /dev/log, 573 * syslog(prio, "test") sends "test\0" to /dev/log,
570 * syslog(prio, "test\n") sends "test\n\0", 574 * syslog(prio, "test\n") sends "test\n\0".
571 * IOW: newline is passed verbatim! 575 * IOW: newline is passed verbatim!
572 * I take it to mean that it's syslogd's job 576 * I take it to mean that it's syslogd's job
573 * to make those look identical in the log files */ 577 * to make those look identical in the log files. */
574 if (G.recvbuf[sz-1] && G.recvbuf[sz-1] != '\n') 578 if (G.recvbuf[sz-1] != '\0' && G.recvbuf[sz-1] != '\n')
575 break; 579 break;
576 sz--; 580 sz--;
577 } 581 }
578 /* Maybe we need to add '\n' here, not later?
579 * It looks like stock syslogd does send '\n' over network,
580 * but we do not (see sendto below) */
581 G.recvbuf[sz] = '\0'; /* make sure it *is* NUL terminated */
582
583 /* TODO: maybe suppress duplicates? */ 582 /* TODO: maybe suppress duplicates? */
584#if ENABLE_FEATURE_REMOTE_LOG 583#if ENABLE_FEATURE_REMOTE_LOG
585 /* We are not modifying log messages in any way before send */ 584 /* We are not modifying log messages in any way before send */
@@ -590,14 +589,21 @@ static void do_syslogd(void)
590 if (-1 == G.remoteFD) 589 if (-1 == G.remoteFD)
591 goto no_luck; 590 goto no_luck;
592 } 591 }
592 /* Stock syslogd sends it '\n'-terminated
593 * over network, mimic that */
594 G.recvbuf[sz] = '\n';
593 /* send message to remote logger, ignore possible error */ 595 /* send message to remote logger, ignore possible error */
594 sendto(G.remoteFD, G.recvbuf, sz, MSG_DONTWAIT, 596 /* TODO: on some errors, close and set G.remoteFD to -1
597 * so that DNS resolution and connect is retried? */
598 sendto(G.remoteFD, G.recvbuf, sz+1, MSG_DONTWAIT,
595 &G.remoteAddr->u.sa, G.remoteAddr->len); 599 &G.remoteAddr->u.sa, G.remoteAddr->len);
596 no_luck: ; 600 no_luck: ;
597 } 601 }
598#endif 602#endif
599 if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) 603 if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
604 G.recvbuf[sz] = '\0'; /* ensure it *is* NUL terminated */
600 split_escape_and_log(G.recvbuf, sz); 605 split_escape_and_log(G.recvbuf, sz);
606 }
601 } /* for (;;) */ 607 } /* for (;;) */
602} 608}
603 609