Various cleanups I made while going through Erik Hovland's patch submissions,
[oweals/busybox.git] / networking / udhcp / common.c
1 /* vi: set sw=4 ts=4: */
2 /* common.c
3  *
4  * Functions for debugging and logging as well as some other
5  * simple helper functions.
6  *
7  * Russ Dill <Russ.Dill@asu.edu> 2001-2003
8  * Rewritten by Vladimir Oleynik <dzo@simtreas.ru> (C) 2003
9  *
10  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
11  */
12
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <errno.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include <signal.h>
19 #include <paths.h>
20 #include <sys/socket.h>
21 #include <stdarg.h>
22
23 #include "common.h"
24 #include "pidfile.h"
25
26
27 static int daemonized;
28
29 long uptime(void)
30 {
31         struct sysinfo info;
32         sysinfo(&info);
33         return info.uptime;
34 }
35
36
37 /*
38  * This function makes sure our first socket calls
39  * aren't going to fd 1 (printf badness...) and are
40  * not later closed by daemon()
41  */
42 static inline void sanitize_fds(void)
43 {
44         int zero;
45         if ((zero = open(bb_dev_null, O_RDWR, 0)) < 0)
46                 return;
47         while (zero < 3)
48                 zero = dup(zero);
49         close(zero);
50 }
51
52
53 void udhcp_background(const char *pidfile)
54 {
55 #ifdef __uClinux__
56         LOG(LOG_ERR, "Cannot background in uclinux (yet)");
57 #else /* __uClinux__ */
58         int pid_fd;
59
60         /* hold lock during fork. */
61         pid_fd = pidfile_acquire(pidfile);
62         if (daemon(0, 0) == -1) { /* bb_xdaemon? */
63                 perror("fork");
64                 exit(1);
65         }
66         daemonized++;
67         pidfile_write_release(pid_fd);
68 #endif /* __uClinux__ */
69 }
70
71
72 #ifdef CONFIG_FEATURE_UDHCP_SYSLOG
73
74 void udhcp_logging(int level, const char *fmt, ...)
75 {
76         va_list p;
77         va_list p2;
78
79         va_start(p, fmt);
80         __va_copy(p2, p);
81         if (!daemonized) {
82                 vprintf(fmt, p);
83                 putchar('\n');
84         }
85         vsyslog(level, fmt, p2);
86         va_end(p);
87 }
88
89 #else
90
91
92 static char *syslog_level_msg[] = {
93         [LOG_EMERG]   = "EMERGENCY!",
94         [LOG_ALERT]   = "ALERT!",
95         [LOG_CRIT]    = "critical!",
96         [LOG_WARNING] = "warning",
97         [LOG_ERR]     = "error",
98         [LOG_INFO]    = "info",
99         [LOG_DEBUG]   = "debug"
100 };
101
102
103 void udhcp_logging(int level, const char *fmt, ...)
104 {
105         va_list p;
106
107         va_start(p, fmt);
108         if (!daemonized) {
109                 printf("%s, ", syslog_level_msg[level]);
110                 vprintf(fmt, p);
111                 putchar('\n');
112         }
113         va_end(p);
114 }
115 #endif
116
117
118 void udhcp_start_log_and_pid(const char *client_server, const char *pidfile)
119 {
120         int pid_fd;
121
122         /* Make sure our syslog fd isn't overwritten */
123         sanitize_fds();
124
125         /* do some other misc startup stuff while we are here to save bytes */
126         pid_fd = pidfile_acquire(pidfile);
127         pidfile_write_release(pid_fd);
128
129         /* equivelent of doing a fflush after every \n */
130         setlinebuf(stdout);
131
132         if (ENABLE_FEATURE_UDHCP_SYSLOG)
133                 openlog(client_server, LOG_PID | LOG_CONS, LOG_LOCAL0);
134
135         udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, BB_VER);
136 }