blob: ab4fa305add9db26eade26cdf09a975183c36e14 [file] [log] [blame]
Eric Andersena8da17a2003-06-14 02:57:53 +00001/* common.c
2 *
3 * Functions to assist in the writing and removing of pidfiles.
4 *
5 * Russ Dill <Russ.Dill@asu.edu> Soptember 2001
6 * Rewrited by Vladimir Oleynik <dzo@simtreas.ru> (C) 2003
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <fcntl.h>
24#include <unistd.h>
25#include <errno.h>
26#include <string.h>
27#include <stdlib.h>
28#include <signal.h>
29#include <sys/socket.h>
30
31#include "common.h"
32
33
34static int daemonized;
35
36#ifdef CONFIG_FEATURE_UDHCP_SYSLOG
37
38void udhcp_logging(int level, const char *fmt, ...)
39{
40 int e = errno;
41 va_list p;
42 va_list p2;
43
44 va_start(p, fmt);
45 __va_copy(p2, p);
46 if(!daemonized) {
47 vprintf(fmt, p);
48 putchar('\n');
Glenn L McGrath29a05f52003-08-30 04:47:36 +000049 fflush(stdout);
Eric Andersena8da17a2003-06-14 02:57:53 +000050 errno = e;
51 }
52 vsyslog(level, fmt, p2);
53 va_end(p);
54}
55
56void start_log(const char *client_server)
57{
58 openlog(bb_applet_name, LOG_PID | LOG_CONS, LOG_LOCAL0);
59 udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
60}
61
62#else
63
64static char *syslog_level_msg[] = {
65 [LOG_EMERG] = "EMERGENCY!",
66 [LOG_ALERT] = "ALERT!",
67 [LOG_CRIT] = "critical!",
68 [LOG_WARNING] = "warning",
69 [LOG_ERR] = "error",
70 [LOG_INFO] = "info",
71 [LOG_DEBUG] = "debug"
72};
73
74void udhcp_logging(int level, const char *fmt, ...)
75{
76 int e = errno;
77 va_list p;
78
79 va_start(p, fmt);
80 if(!daemonized) {
81 printf("%s, ", syslog_level_msg[level]);
82 errno = e;
83 vprintf(fmt, p);
84 putchar('\n');
Glenn L McGrath29a05f52003-08-30 04:47:36 +000085 fflush(stdout);
Eric Andersena8da17a2003-06-14 02:57:53 +000086 }
87 va_end(p);
88}
89
90void start_log(const char *client_server)
91{
92 udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
93}
94#endif
95
96static const char *saved_pidfile;
97
98static void exit_fun(void)
99{
100 if (saved_pidfile) unlink(saved_pidfile);
101}
102
103void background(const char *pidfile)
104{
105 int pid_fd = -1;
106
107 if (pidfile) {
108 pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
109 if (pid_fd < 0) {
110 LOG(LOG_ERR, "Unable to open pidfile %s: %m", pidfile);
111 } else {
112 lockf(pid_fd, F_LOCK, 0);
113 if(!saved_pidfile)
114 atexit(exit_fun); /* set atexit one only */
115 saved_pidfile = pidfile; /* but may be rewrite */
116 }
117 }
118 while (pid_fd >= 0 && pid_fd < 3) pid_fd = dup(pid_fd); /* don't let daemon close it */
119 if (daemon(0, 0) == -1) {
120 perror("fork");
121 exit(1);
122 }
123 daemonized++;
124 if (pid_fd >= 0) {
125 FILE *out;
126
127 if ((out = fdopen(pid_fd, "w")) != NULL) {
128 fprintf(out, "%d\n", getpid());
129 fclose(out);
130 }
131 lockf(pid_fd, F_UNLCK, 0);
132 close(pid_fd);
133 }
134}
135
136/* Signal handler */
137int udhcp_signal_pipe[2];
138static void signal_handler(int sig)
139{
140 if (send(udhcp_signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) {
141 LOG(LOG_ERR, "Could not send signal: %m");
142 }
143}
144
145void udhcp_set_signal_pipe(int sig_add)
146{
147 socketpair(AF_UNIX, SOCK_STREAM, 0, udhcp_signal_pipe);
148 signal(SIGUSR1, signal_handler);
149 signal(SIGTERM, signal_handler);
150 if(sig_add)
151 signal(sig_add, signal_handler);
152}