blob: c01cd576506421fc1b6a63718f15705a857fe733 [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');
49 errno = e;
50 }
51 vsyslog(level, fmt, p2);
52 va_end(p);
53}
54
55void start_log(const char *client_server)
56{
57 openlog(bb_applet_name, LOG_PID | LOG_CONS, LOG_LOCAL0);
58 udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
59}
60
61#else
62
63static char *syslog_level_msg[] = {
64 [LOG_EMERG] = "EMERGENCY!",
65 [LOG_ALERT] = "ALERT!",
66 [LOG_CRIT] = "critical!",
67 [LOG_WARNING] = "warning",
68 [LOG_ERR] = "error",
69 [LOG_INFO] = "info",
70 [LOG_DEBUG] = "debug"
71};
72
73void udhcp_logging(int level, const char *fmt, ...)
74{
75 int e = errno;
76 va_list p;
77
78 va_start(p, fmt);
79 if(!daemonized) {
80 printf("%s, ", syslog_level_msg[level]);
81 errno = e;
82 vprintf(fmt, p);
83 putchar('\n');
84 }
85 va_end(p);
86}
87
88void start_log(const char *client_server)
89{
90 udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
91}
92#endif
93
94static const char *saved_pidfile;
95
96static void exit_fun(void)
97{
98 if (saved_pidfile) unlink(saved_pidfile);
99}
100
101void background(const char *pidfile)
102{
103 int pid_fd = -1;
104
105 if (pidfile) {
106 pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
107 if (pid_fd < 0) {
108 LOG(LOG_ERR, "Unable to open pidfile %s: %m", pidfile);
109 } else {
110 lockf(pid_fd, F_LOCK, 0);
111 if(!saved_pidfile)
112 atexit(exit_fun); /* set atexit one only */
113 saved_pidfile = pidfile; /* but may be rewrite */
114 }
115 }
116 while (pid_fd >= 0 && pid_fd < 3) pid_fd = dup(pid_fd); /* don't let daemon close it */
117 if (daemon(0, 0) == -1) {
118 perror("fork");
119 exit(1);
120 }
121 daemonized++;
122 if (pid_fd >= 0) {
123 FILE *out;
124
125 if ((out = fdopen(pid_fd, "w")) != NULL) {
126 fprintf(out, "%d\n", getpid());
127 fclose(out);
128 }
129 lockf(pid_fd, F_UNLCK, 0);
130 close(pid_fd);
131 }
132}
133
134/* Signal handler */
135int udhcp_signal_pipe[2];
136static void signal_handler(int sig)
137{
138 if (send(udhcp_signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) {
139 LOG(LOG_ERR, "Could not send signal: %m");
140 }
141}
142
143void udhcp_set_signal_pipe(int sig_add)
144{
145 socketpair(AF_UNIX, SOCK_STREAM, 0, udhcp_signal_pipe);
146 signal(SIGUSR1, signal_handler);
147 signal(SIGTERM, signal_handler);
148 if(sig_add)
149 signal(sig_add, signal_handler);
150}