docs/logging_and_backgrounding.txt: new mini-doc
authorDenis Vlasenko <vda.linux@googlemail.com>
Wed, 11 Mar 2009 14:40:00 +0000 (14:40 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Wed, 11 Mar 2009 14:40:00 +0000 (14:40 -0000)
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 [new file with mode: 0644]
miscutils/crond.c
networking/dnsd.c
networking/inetd.c
networking/nameif.c
networking/udhcp/dhcpc.c
networking/udhcp/dhcpd.c
networking/udhcp/socket.c

diff --git a/docs/logging_and_backgrounding.txt b/docs/logging_and_backgrounding.txt
new file mode 100644 (file)
index 0000000..39f0158
--- /dev/null
@@ -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)
index 767aa12..2e158bc 100644 (file)
@@ -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);
                }
index 434903f..f95ba6b 100644 (file)
@@ -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);
index bf018d7..72d5101 100644 (file)
@@ -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)
index 4d68c8d..fb31fbf 100644 (file)
@@ -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;
index 903f3d3..e9f99e3 100644 (file)
@@ -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) {
index 15b31eb..a82fd8c 100644 (file)
@@ -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;
index fdb558d..edf4355 100644 (file)
@@ -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) {