From a19e64933c600b7f05232ad80bb5db85c115e42d Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Wed, 11 Mar 2009 14:40:00 +0000 Subject: docs/logging_and_backgrounding.txt: new mini-doc dnsd: remove statics, remove nerly-useless SIGINT handler crond: correct more of logfile to 0666 (as usual, umask allows user to remove unwanted bits). nameif: print errors to stderr too, not just to syslog function old new delta udhcp_read_interface 308 306 -2 ttl 4 - -4 fileconf 4 - -4 dnsentry 4 - -4 interrupt 19 - -19 dnsd_main 1463 1394 -69 ------------------------------------------------------------------------------ (add/remove: 0/4 grow/shrink: 0/2 up/down: 0/-102) Total: -102 bytes text data bss dec hex filename 808161 476 7864 816501 c7575 busybox_old 807994 468 7856 816318 c74be busybox_unstripped --- docs/logging_and_backgrounding.txt | 89 +++++++++++++++++++++++++++++++++++ miscutils/crond.c | 2 +- networking/dnsd.c | 96 ++++++++++++++++++-------------------- networking/inetd.c | 2 +- networking/nameif.c | 4 +- networking/udhcp/dhcpc.c | 2 +- networking/udhcp/dhcpd.c | 4 +- networking/udhcp/socket.c | 2 +- 8 files changed, 143 insertions(+), 58 deletions(-) create mode 100644 docs/logging_and_backgrounding.txt diff --git a/docs/logging_and_backgrounding.txt b/docs/logging_and_backgrounding.txt new file mode 100644 index 000000000..39f015883 --- /dev/null +++ b/docs/logging_and_backgrounding.txt @@ -0,0 +1,89 @@ + Logging and backgrounding + +By default, bb_[p]error_msg[_and_die] messages go to stderr, +and of course, usually applets do not auto-background. :) + +Historically, daemons and inetd services are different. + +Busybox is trying to provide compatible behavior, thus if an applet +is emulating an existing utility, it should mimic it. If utility +auto-backgrounds itself, busybox applet should do the same. +If utility normally logs to syslog, busybox applet should do +the same too. + +However, busybox should not needlessly restrict the freedom +of the users. And users have different needs and different preferences. +Some might like logging everything from daemons to syslog. +Others prefer running stuff under runsv/svlogd and thus would like +logging to stderr and no daemonization. + +To help with that, busybox applets should have options to override +default behavior, whatever that is for a given applet. + + +Current sutiation is a bit of a mess: + +acpid - auto-backgrounds unless -d +crond - auto-backgrounds unless -f, logs to syslog unless -d or -L. + option -d logs to stderr, -L FILE logs to FILE +devfsd - (obsolete) +dnsd - option -d makes it auto-background and log to syslog +fakeidentd - inetd service. Auto-backgrounds and logs to syslog + if no -f and no -i and no -w (-i is "inetd service" flag, + -w is "inetd-wait service" flag) +ftpd - inetd service. Logs to syslog always, with -v logs to strerr too +httpd - auto-backgrounds unless -f or -i + (-i is "inetd service" flag) +inetd - auto-backgrounds unless -f, logs to syslog unless -e +klogd - auto-backgrounds unless -n +syslogd - auto-backgrounds unless -n +telnetd - auto-backgrounds unless -f or -i + (-i is "inetd service" flag) +udhcpc - auto-backgrounds unless -f after lease is obtained, + option -b makes it background sooner (when lease attempt + fails and retries start), + after backgrounding it stops logging to stderr; + logs to stderr, but option -S makes it log *also* to syslog +udhcpd - auto-backgrounds and do not log to stderr unless -f, + otherwise logs to stderr, but option -S makes it log *also* to syslog +zcip - auto-backgrounds and logs *also* to syslog unless -f + +miscutils/crond.c: logmode = LOGMODE_SYSLOG; +networking/dnsd.c: logmode = LOGMODE_SYSLOG; +networking/ftpd.c: logmode = LOGMODE_SYSLOG; +networking/ftpd.c: logmode |= LOGMODE_SYSLOG; +networking/inetd.c: logmode = LOGMODE_SYSLOG; +networking/isrv_identd.c: logmode = LOGMODE_SYSLOG; +networking/telnetd.c: logmode = LOGMODE_SYSLOG; +networking/udhcp/dhcpc.c: logmode = LOGMODE_NONE; +networking/udhcp/dhcpc.c: logmode |= LOGMODE_SYSLOG; +networking/udhcp/dhcpc.c: logmode &= ~LOGMODE_STDIO; +networking/udhcp/dhcpd.c: logmode = LOGMODE_NONE; +networking/udhcp/dhcpd.c: logmode |= LOGMODE_SYSLOG; +networking/zcip.c: logmode |= LOGMODE_SYSLOG; + + +These daemons seem to never auto-background/log to syslog: + +lpd - inetd service. Has nothing to log so far, though +dhcprelay - standard behavior +inotifyd - standard behavior +runsv - standard behavior +runsvdir - standard behavior +svlogd - standard behavior +tcpsvd, udpsvd - standard behavior +tftpd - standard behavior + + +Non-daemons (seems to be use syslog for a good reason): + +networking/nameif.c: logmode |= LOGMODE_SYSLOG; +loginutils/chpasswd.c: logmode = LOGMODE_BOTH; +loginutils/chpasswd.c: logmode = LOGMODE_STDIO; +loginutils/getty.c: logmode = LOGMODE_BOTH; +loginutils/getty.c: logmode = LOGMODE_NONE; +loginutils/passwd.c: logmode = LOGMODE_STDIO; +loginutils/passwd.c: logmode = LOGMODE_BOTH; +loginutils/sulogin.c: logmode = LOGMODE_SYSLOG; (used if stdio isn't a tty) +loginutils/sulogin.c: logmode = LOGMODE_BOTH; +util-linux/mount.c: logmode = LOGMODE_SYSLOG; (used in a backgrounded NFS mount helper) diff --git a/miscutils/crond.c b/miscutils/crond.c index 767aa120a..2e158bcf0 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c @@ -142,7 +142,7 @@ static void crondlog(const char *ctl, ...) /* Syslog mode: all to syslog (logmode = LOGMODE_SYSLOG), */ if (!DebugOpt && LogFile) { /* Otherwise (log to file): we reopen log file at every write: */ - int logfd = open3_or_warn(LogFile, O_WRONLY | O_CREAT | O_APPEND, 0600); + int logfd = open3_or_warn(LogFile, O_WRONLY | O_CREAT | O_APPEND, 0666); if (logfd >= 0) xmove_fd(logfd, STDERR_FILENO); } diff --git a/networking/dnsd.c b/networking/dnsd.c index 434903fe1..f95ba6b40 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c @@ -63,14 +63,7 @@ struct dns_entry { // element of known name, ip address and reversed ip address char name[MAX_HOST_LEN]; }; -static struct dns_entry *dnsentry; -static uint32_t ttl = DEFAULT_TTL; - -static const char *fileconf = "/etc/dnsd.conf"; - -// Must match getopt32 call -#define OPT_daemon (option_mask32 & 0x10) -#define OPT_verbose (option_mask32 & 0x20) +#define OPT_verbose (option_mask32) /* @@ -88,7 +81,7 @@ static void convname(char *a, uint8_t *q) /* * Insert length of substrings instead of dots */ -static void undot(uint8_t * rip) +static void undot(uint8_t *rip) { int i = 0, s = 0; while (rip[i]) @@ -104,13 +97,13 @@ static void undot(uint8_t * rip) /* * Read hostname/IP records from file */ -static void dnsentryinit(void) +static struct dns_entry *parse_conf_file(const char *fileconf) { char *token[2]; parser_t *parser; - struct dns_entry *m, *prev; + struct dns_entry *m, *prev, *conf_data; - prev = dnsentry = NULL; + prev = conf_data = NULL; parser = config_open(fileconf); while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { unsigned a, b, c, d; @@ -132,50 +125,54 @@ static void dnsentryinit(void) convname(m->name, (uint8_t*)token[0]); if (OPT_verbose) - fprintf(stderr, "\tname:%s, ip:%s\n", &(m->name[1]), m->ip); + bb_error_msg("name:%s, ip:%s", &(m->name[1]), m->ip); if (prev == NULL) - dnsentry = m; + conf_data = m; else prev->next = m; prev = m; } config_close(parser); + return conf_data; } /* * Look query up in dns records and return answer if found * qs is the query string, first byte the string length */ -static int table_lookup(uint16_t type, uint8_t * as, uint8_t * qs) +static int table_lookup(struct dns_entry *d, uint16_t type, uint8_t *as, uint8_t *qs) { int i; - struct dns_entry *d = dnsentry; do { #if DEBUG - char *p,*q; + char *p, *q; q = (char *)&(qs[1]); p = &(d->name[1]); fprintf(stderr, "\n%s: %d/%d p:%s q:%s %d", __FUNCTION__, (int)strlen(p), (int)(d->name[0]), p, q, (int)strlen(q)); #endif - if (type == REQ_A) { /* search by host name */ + if (type == REQ_A) { + /* search by host name */ for (i = 1; i <= (int)(d->name[0]); i++) if (tolower(qs[i]) != d->name[i]) break; - if (i > (int)(d->name[0]) || - (d->name[0] == 1 && d->name[1] == '*')) { + if (i > (int)(d->name[0]) + || (d->name[0] == 1 && d->name[1] == '*') + ) { strcpy((char *)as, d->ip); #if DEBUG fprintf(stderr, " OK as:%s\n", as); #endif return 0; } - } else if (type == REQ_PTR) { /* search by IP-address */ - if ((d->name[0] != 1 || d->name[1] != '*') && - !strncmp((char*)&d->rip[1], (char*)&qs[1], strlen(d->rip)-1)) { + } else if (type == REQ_PTR) { + /* search by IP-address */ + if ((d->name[0] != 1 || d->name[1] != '*') + && !strncmp(d->rip + 1, (char*)qs + 1, strlen(d->rip)-1) + ) { strcpy((char *)as, d->name); return 0; } @@ -188,7 +185,7 @@ static int table_lookup(uint16_t type, uint8_t * as, uint8_t * qs) /* * Decode message and generate answer */ -static int process_packet(uint8_t *buf) +static int process_packet(struct dns_entry *conf_data, uint32_t conf_ttl, uint8_t *buf) { uint8_t answstr[MAX_NAME_LEN + 1]; struct dns_head *head; @@ -240,7 +237,7 @@ static int process_packet(uint8_t *buf) // We have a standard query bb_info_msg("%s", (char *)from); - lookup_result = table_lookup(type, answstr, from); + lookup_result = table_lookup(conf_data, type, answstr, from); if (lookup_result != 0) { outr_flags = 3 | 0x0400; // name do not exist and auth goto empty_packet; @@ -267,7 +264,7 @@ static int process_packet(uint8_t *buf) // and append answer rr // FIXME: unaligned accesses?? - *(uint32_t *) answb = htonl(ttl); + *(uint32_t *) answb = htonl(conf_ttl); answb += 4; *(uint16_t *) answb = htons(outr_rlen); answb += 2; @@ -290,49 +287,48 @@ static int process_packet(uint8_t *buf) /* * Exit on signal */ -static void interrupt(int sig) -{ - /* unlink("/var/run/dnsd.lock"); */ - bb_error_msg("interrupt, exiting\n"); - kill_myself_with_sig(sig); -} +//static void interrupt(int sig) +//{ +// /* unlink("/var/run/dnsd.lock"); */ +// bb_error_msg("interrupt, exiting\n"); +// kill_myself_with_sig(sig); +//} int dnsd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int dnsd_main(int argc UNUSED_PARAM, char **argv) { const char *listen_interface = "0.0.0.0"; + const char *fileconf = "/etc/dnsd.conf"; + struct dns_entry *conf_data; + uint32_t conf_ttl = DEFAULT_TTL; char *sttl, *sport; len_and_sockaddr *lsa, *from, *to; unsigned lsa_size; - int udps; + int udps, opts; uint16_t port = 53; /* Paranoid sizing: querystring x2 + ttl + outr_rlen + answstr */ /* I'd rather see process_packet() fixed instead... */ uint8_t buf[MAX_PACK_LEN * 2 + 4 + 2 + (MAX_NAME_LEN+1)]; - getopt32(argv, "i:c:t:p:dv", &listen_interface, &fileconf, &sttl, &sport); - //if (option_mask32 & 0x1) // -i - //if (option_mask32 & 0x2) // -c - if (option_mask32 & 0x4) // -t - ttl = xatou_range(sttl, 1, 0xffffffff); - if (option_mask32 & 0x8) // -p + opts = getopt32(argv, "vi:c:t:p:d", &listen_interface, &fileconf, &sttl, &sport); + //if (opts & 0x1) // -v + //if (opts & 0x2) // -i + //if (opts & 0x4) // -c + if (opts & 0x8) // -t + conf_ttl = xatou_range(sttl, 1, 0xffffffff); + if (opts & 0x10) // -p port = xatou_range(sport, 1, 0xffff); - - if (OPT_verbose) { - bb_info_msg("listen_interface: %s", listen_interface); - bb_info_msg("ttl: %d, port: %d", ttl, port); - bb_info_msg("fileconf: %s", fileconf); - } - - if (OPT_daemon) { + if (opts & 0x20) { // -d bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv); openlog(applet_name, LOG_PID, LOG_DAEMON); logmode = LOGMODE_SYSLOG; } + /* Clear all except "verbose" bit */ + option_mask32 &= 1; - dnsentryinit(); + conf_data = parse_conf_file(fileconf); - signal(SIGINT, interrupt); +// signal(SIGINT, interrupt); - just for one message? bb_signals(0 /* why? + (1 << SIGPIPE) */ + (1 << SIGHUP) @@ -371,7 +367,7 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv) if (OPT_verbose) bb_info_msg("Got UDP packet"); buf[r] = '\0'; /* paranoia */ - r = process_packet(buf); + r = process_packet(conf_data, conf_ttl, buf); if (r <= 0) continue; send_to_from(udps, buf, r, 0, &from->u.sa, &to->u.sa, lsa->len); diff --git a/networking/inetd.c b/networking/inetd.c index bf018d774..72d51010e 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -1299,7 +1299,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) if (sep->se_builtin) { if (pid) { /* "pid" is -1: we did vfork */ close(sep->se_fd); /* listening socket */ - logmode = 0; /* make xwrite etc silent */ + logmode = LOGMODE_NONE; /* make xwrite etc silent */ } restore_sigmask(&omask); if (sep->se_socktype == SOCK_STREAM) diff --git a/networking/nameif.c b/networking/nameif.c index 4d68c8d63..fb31fbfff 100644 --- a/networking/nameif.c +++ b/networking/nameif.c @@ -144,7 +144,9 @@ int nameif_main(int argc, char **argv) if (1 & getopt32(argv, "sc:", &fname)) { openlog(applet_name, 0, LOG_LOCAL0); - logmode = LOGMODE_SYSLOG; + /* Why not just "="? I assume logging to stderr + * can't hurt. 2>/dev/null if you don't like it: */ + logmode |= LOGMODE_SYSLOG; } argc -= optind; argv += optind; diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 903f3d326..e9f99e39c 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -280,7 +280,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* on NOMMU reexec (i.e., background) early */ if (!(opt & OPT_f)) { bb_daemonize_or_rexec(0 /* flags */, argv); - logmode = 0; + logmode = LOGMODE_NONE; } #endif if (opt & OPT_S) { diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 15b31eb3d..a82fd8c47 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -46,12 +46,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) opt = getopt32(argv, "fS" USE_FEATURE_UDHCP_PORT("P:", &str_P)); argv += optind; - if (!(opt & 1)) { /* no -f */ bb_daemonize_or_rexec(0, argv); - logmode &= ~LOGMODE_STDIO; + logmode = LOGMODE_NONE; } - if (opt & 2) { /* -S */ openlog(applet_name, LOG_PID, LOG_DAEMON); logmode |= LOGMODE_SYSLOG; diff --git a/networking/udhcp/socket.c b/networking/udhcp/socket.c index fdb558db4..edf4355b5 100644 --- a/networking/udhcp/socket.c +++ b/networking/udhcp/socket.c @@ -57,7 +57,7 @@ int FAST_FUNC udhcp_read_interface(const char *interface, int *ifindex, uint32_t } our_ip = (struct sockaddr_in *) &ifr.ifr_addr; *addr = our_ip->sin_addr.s_addr; - DEBUG("%s (our ip) = %s", ifr.ifr_name, inet_ntoa(our_ip->sin_addr)); + DEBUG("ip of %s = %s", interface, inet_ntoa(our_ip->sin_addr)); } if (ifindex) { -- cgit v1.2.3