Mercurial > hg > toybox
annotate toys/pending/syslogd.c @ 1265:0ecfaa7022e8 draft
usage: is lower case (the help generator looks for that, might as well be consistent).
author | Rob Landley <rob@landley.net> |
---|---|
date | Wed, 23 Apr 2014 08:37:07 -0500 |
parents | 0752b2d58909 |
children | 6a06541c090c |
rev | line source |
---|---|
960 | 1 /* syslogd.c - a system logging utility. |
2 * | |
3 * Copyright 2013 Madhur Verma <mad.flexi@gmail.com> | |
997
8b1814e4c987
Ashwini Sharma said that Kyungwan Han should be in the contact info for the commands he sent recently.
Rob Landley <rob@landley.net>
parents:
995
diff
changeset
|
4 * Copyright 2013 Kyungwan Han <asura321@gmail.com> |
960 | 5 * |
6 * No Standard | |
7 | |
8 USE_SYSLOGD(NEWTOY(syslogd,">0l#<1>8=8R:b#<0>99=1s#<0=200m#<0>71582787=20O:p:f:a:nSKLD", TOYFLAG_SBIN|TOYFLAG_STAYROOT)) | |
9 | |
10 config SYSLOGD | |
11 bool "syslogd" | |
12 default n | |
13 help | |
1265
0ecfaa7022e8
usage: is lower case (the help generator looks for that, might as well be consistent).
Rob Landley <rob@landley.net>
parents:
1183
diff
changeset
|
14 usage: syslogd [-a socket] [-O logfile] [-f config file] [-m interval] |
960 | 15 [-p socket] [-s SIZE] [-b N] [-R HOST] [-l N] [-nSLKD] |
16 | |
17 System logging utility | |
18 | |
19 -a Extra unix socket for listen | |
20 -O FILE Default log file <DEFAULT: /var/log/messages> | |
21 -f FILE Config file <DEFAULT: /etc/syslog.conf> | |
22 -p Alternative unix domain socket <DEFAULT : /dev/log> | |
23 -n Avoid auto-backgrounding. | |
24 -S Smaller output | |
25 -m MARK interval <DEFAULT: 20 minutes> (RANGE: 0 to 71582787) | |
26 -R HOST Log to IP or hostname on PORT (default PORT=514/UDP)" | |
27 -L Log locally and via network (default is network only if -R)" | |
28 -s SIZE Max size (KB) before rotation (default:200KB, 0=off) | |
29 -b N rotated logs to keep (default:1, max=99, 0=purge) | |
30 -K Log to kernel printk buffer (use dmesg to read it) | |
31 -l N Log only messages more urgent than prio(default:8 max:8 min:1) | |
32 -D Drop duplicates | |
33 */ | |
34 | |
35 #define FOR_syslogd | |
1019
f9271a80fedc
In logger and syslogd remove duplicated definitions of facilities and priorities
Felix Janda <felix.janda@posteo.de>
parents:
997
diff
changeset
|
36 #define SYSLOG_NAMES |
960 | 37 #include "toys.h" |
38 | |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
39 // UNIX Sockets for listening |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
40 struct unsocks { |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
41 struct unsocks *next; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
42 char *path; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
43 struct sockaddr_un sdu; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
44 int sd; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
45 }; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
46 |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
47 // Log file entry to log into. |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
48 struct logfile { |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
49 struct logfile *next; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
50 char *filename; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
51 uint32_t facility[8]; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
52 uint8_t level[LOG_NFACILITIES]; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
53 int logfd; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
54 struct sockaddr_in saddr; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
55 }; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
56 |
960 | 57 GLOBALS( |
58 char *socket; | |
59 char *config_file; | |
60 char *unix_socket; | |
61 char *logfile; | |
62 long interval; | |
63 long rot_size; | |
64 long rot_count; | |
65 char *remote_log; | |
66 long log_prio; | |
67 | |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
68 struct unsocks *lsocks; // list of listen sockets |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
69 struct logfile *lfiles; // list of write logfiles |
1021 | 70 int sigfd[2]; |
960 | 71 ) |
72 | |
1025 | 73 // Lookup numerical code from name |
74 // Also used in logger | |
75 int logger_lookup(int where, char *key) | |
76 { | |
77 CODE *w = ((CODE *[]){facilitynames, prioritynames})[where]; | |
78 | |
79 for (; w->c_name; w++) | |
80 if (!strcasecmp(key, w->c_name)) return w->c_val; | |
81 | |
82 return -1; | |
83 } | |
84 | |
85 //search the given name and return its value | |
1042
cbc467592b2e
Remove itoa/utoa, let libc do this with sprintf.
Rob Landley <rob@landley.net>
parents:
1028
diff
changeset
|
86 static char *dec(int val, CODE *clist, char *buf) |
1025 | 87 { |
88 for (; clist->c_name; clist++) | |
89 if (val == clist->c_val) return clist->c_name; | |
1042
cbc467592b2e
Remove itoa/utoa, let libc do this with sprintf.
Rob Landley <rob@landley.net>
parents:
1028
diff
changeset
|
90 sprintf(buf, "%u", val); |
cbc467592b2e
Remove itoa/utoa, let libc do this with sprintf.
Rob Landley <rob@landley.net>
parents:
1028
diff
changeset
|
91 |
cbc467592b2e
Remove itoa/utoa, let libc do this with sprintf.
Rob Landley <rob@landley.net>
parents:
1028
diff
changeset
|
92 return buf; |
1025 | 93 } |
94 | |
960 | 95 /* |
96 * recurses the logfile list and resolves config | |
97 * for evry file and updates facilty and log level bits. | |
98 */ | |
1027 | 99 static int resolve_config(struct logfile *file, char *config) |
960 | 100 { |
1027 | 101 char *tk; |
960 | 102 |
1027 | 103 for (tk = strtok(config, "; \0"); tk; tk = strtok(NULL, "; \0")) { |
1025 | 104 char *fac = tk, *lvl; |
105 int i = 0; | |
106 unsigned facval = 0; | |
107 uint8_t set, levval, bits = 0; | |
108 | |
960 | 109 tk = strchr(fac, '.'); |
110 if (!tk) return -1; | |
111 *tk = '\0'; | |
112 lvl = tk + 1; | |
113 | |
1025 | 114 for (;;) { |
115 char *nfac = strchr(fac, ','); | |
116 | |
117 if (nfac) *nfac = '\0'; | |
960 | 118 if (*fac == '*') { |
119 facval = 0xFFFFFFFF; | |
1025 | 120 if (fac[1]) return -1; |
121 } else { | |
122 if ((i = logger_lookup(0, fac)) == -1) return -1; | |
123 facval |= (1 << LOG_FAC(i)); | |
960 | 124 } |
1025 | 125 if (nfac) fac = nfac + 1; |
960 | 126 else break; |
127 } | |
128 | |
129 levval = 0; | |
1027 | 130 for (tk = "!=*"; *tk; tk++, bits <<= 1) { |
1025 | 131 if (*lvl == *tk) { |
132 bits++; | |
133 lvl++; | |
134 } | |
960 | 135 } |
1028 | 136 if (bits & 2) levval = 0xff; |
137 if (*lvl) { | |
1025 | 138 if ((i = logger_lookup(1, lvl)) == -1) return -1; |
1028 | 139 levval |= (bits & 4) ? LOG_MASK(i) : LOG_UPTO(i); |
140 if (bits & 8) levval = ~levval; | |
960 | 141 } |
142 | |
1025 | 143 for (i = 0, set = levval; set; set >>= 1, i++) |
1028 | 144 if (set & 0x1) file->facility[i] |= ~facval; |
1025 | 145 for (i = 0; i < LOG_NFACILITIES; facval >>= 1, i++) |
1028 | 146 if (facval & 0x1) file->level[i] |= ~levval; |
960 | 147 } |
148 | |
149 return 0; | |
150 } | |
151 | |
152 // Parse config file and update the log file list. | |
153 static int parse_config_file(void) | |
154 { | |
1021 | 155 struct logfile *file; |
1025 | 156 FILE *fp; |
1027 | 157 char *confline, *tk[2]; |
158 int len, lineno = 0; | |
1025 | 159 size_t linelen; |
960 | 160 /* |
161 * if -K then open only /dev/kmsg | |
162 * all other log files are neglected | |
163 * thus no need to open config either. | |
164 */ | |
1024 | 165 if (toys.optflags & FLAG_K) { |
1021 | 166 file = xzalloc(sizeof(struct logfile)); |
1028 | 167 file->filename = xstrdup("/dev/kmsg"); |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
168 TT.lfiles = file; |
960 | 169 return 0; |
170 } | |
171 /* | |
172 * if -R then add remote host to log list | |
173 * if -L is not provided all other log | |
174 * files are neglected thus no need to | |
175 * open config either so just return. | |
176 */ | |
1025 | 177 if (toys.optflags & FLAG_R) { |
178 file = xzalloc(sizeof(struct logfile)); | |
1183
0752b2d58909
Rename xmsprintf() to just xmprintf().
Rob Landley <rob@landley.net>
parents:
1104
diff
changeset
|
179 file->filename = xmprintf("@%s",TT.remote_log); |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
180 TT.lfiles = file; |
1025 | 181 if (!(toys.optflags & FLAG_L)) return 0; |
182 } | |
960 | 183 /* |
184 * Read config file and add logfiles to the list | |
185 * with their configuration. | |
186 */ | |
1028 | 187 if (!(fp = fopen(TT.config_file, "r")) && (toys.optflags & FLAG_f)) |
960 | 188 perror_exit("can't open '%s'", TT.config_file); |
189 | |
1027 | 190 for (linelen = 0; fp;) { |
191 confline = NULL; | |
1025 | 192 len = getline(&confline, &linelen, fp); |
960 | 193 if (len <= 0) break; |
194 lineno++; | |
195 for (; *confline == ' '; confline++, len--) ; | |
196 if ((confline[0] == '#') || (confline[0] == '\n')) continue; | |
1027 | 197 tk[0] = confline; |
198 for (; len && !(*tk[0]==' ' || *tk[0]=='\t'); tk[0]++, len--); | |
199 for (tk[1] = tk[0]; len && (*tk[1]==' ' || *tk[1]=='\t'); tk[1]++, len--); | |
200 if (!len || (len == 1 && *tk[1] == '\n')) { | |
201 error_msg("error in '%s' at line %d", TT.config_file, lineno); | |
202 return -1; | |
203 } | |
204 else if (*(tk[1] + len - 1) == '\n') *(tk[1] + len - 1) = '\0'; | |
205 *tk[0] = '\0'; | |
206 if (*tk[1] != '*') { | |
207 file = TT.lfiles; | |
208 while (file && strcmp(file->filename, tk[1])) file = file->next; | |
209 if (!file) { | |
210 file = xzalloc(sizeof(struct logfile)); | |
211 file->filename = xstrdup(tk[1]); | |
212 file->next = TT.lfiles; | |
213 TT.lfiles = file; | |
214 } | |
215 if (resolve_config(file, confline) == -1) { | |
960 | 216 error_msg("error in '%s' at line %d", TT.config_file, lineno); |
217 return -1; | |
218 } | |
219 } | |
220 free(confline); | |
221 } | |
222 /* | |
223 * Can't open config file or support is not enabled | |
224 * adding default logfile to the head of list. | |
225 */ | |
226 if (!fp){ | |
1021 | 227 file = xzalloc(sizeof(struct logfile)); |
1028 | 228 file->filename = xstrdup((toys.optflags & FLAG_O) ? |
229 TT.logfile : "/var/log/messages"); //DEFLOGFILE | |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
230 file->next = TT.lfiles; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
231 TT.lfiles = file; |
1025 | 232 } else fclose(fp); |
960 | 233 return 0; |
234 } | |
235 | |
236 // open every log file in list. | |
237 static void open_logfiles(void) | |
238 { | |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
239 struct logfile *tfd; |
1024 | 240 |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
241 for (tfd = TT.lfiles; tfd; tfd = tfd->next) { |
1024 | 242 char *p, *tmpfile; |
243 long port = 514; | |
244 | |
1028 | 245 if (*tfd->filename == '@') { // network |
1024 | 246 struct addrinfo *info, rp; |
247 | |
248 tmpfile = xstrdup(tfd->filename + 1); | |
249 if ((p = strchr(tmpfile, ':'))) { | |
250 char *endptr; | |
960 | 251 |
252 *p = '\0'; | |
1024 | 253 port = strtol(++p, &endptr, 10); |
254 if (*endptr || endptr == p || port < 0 || port > 65535) | |
255 error_exit("bad port in %s", tfd->filename); | |
960 | 256 } |
1024 | 257 memset(&rp, 0, sizeof(rp)); |
258 rp.ai_family = AF_INET; | |
259 rp.ai_socktype = SOCK_DGRAM; | |
260 rp.ai_protocol = IPPROTO_UDP; | |
261 | |
262 if (getaddrinfo(tmpfile, NULL, &rp, &info) || !info) | |
263 perror_exit("BAD ADDRESS: can't find : %s ", tmpfile); | |
264 ((struct sockaddr_in*)info->ai_addr)->sin_port = htons(port); | |
265 memcpy(&tfd->saddr, info->ai_addr, info->ai_addrlen); | |
266 freeaddrinfo(info); | |
267 | |
268 tfd->logfd = xsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | |
960 | 269 free(tmpfile); |
270 } else tfd->logfd = open(tfd->filename, O_CREAT | O_WRONLY | O_APPEND, 0666); | |
271 if (tfd->logfd < 0) { | |
272 tfd->filename = "/dev/console"; | |
273 tfd->logfd = open(tfd->filename, O_APPEND); | |
274 } | |
275 } | |
276 } | |
277 | |
278 //write to file with rotation | |
1021 | 279 static int write_rotate(struct logfile *tf, int len) |
960 | 280 { |
281 int size, isreg; | |
282 struct stat statf; | |
283 isreg = (!fstat(tf->logfd, &statf) && S_ISREG(statf.st_mode)); | |
284 size = statf.st_size; | |
285 | |
1024 | 286 if ((toys.optflags & FLAG_s) || (toys.optflags & FLAG_b)) { |
960 | 287 if (TT.rot_size && isreg && (size + len) > (TT.rot_size*1024)) { |
288 if (TT.rot_count) { /* always 0..99 */ | |
289 int i = strlen(tf->filename) + 3 + 1; | |
290 char old_file[i]; | |
291 char new_file[i]; | |
292 i = TT.rot_count - 1; | |
293 while (1) { | |
294 sprintf(new_file, "%s.%d", tf->filename, i); | |
295 if (!i) break; | |
296 sprintf(old_file, "%s.%d", tf->filename, --i); | |
297 rename(old_file, new_file); | |
298 } | |
299 rename(tf->filename, new_file); | |
300 unlink(tf->filename); | |
301 close(tf->logfd); | |
302 tf->logfd = open(tf->filename, O_CREAT | O_WRONLY | O_APPEND, 0666); | |
303 } | |
304 ftruncate(tf->logfd, 0); | |
305 } | |
306 } | |
307 return write(tf->logfd, toybuf, len); | |
308 } | |
309 | |
310 //Parse messege and write to file. | |
311 static void logmsg(char *msg, int len) | |
312 { | |
313 time_t now; | |
314 char *p, *ts, *lvlstr, *facstr; | |
315 struct utsname uts; | |
316 int pri = 0; | |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
317 struct logfile *tf = TT.lfiles; |
960 | 318 |
319 char *omsg = msg; | |
320 int olen = len, fac, lvl; | |
321 | |
322 if (*msg == '<') { // Extract the priority no. | |
323 pri = (int) strtoul(msg + 1, &p, 10); | |
324 if (*p == '>') msg = p + 1; | |
325 } | |
326 /* Jan 18 00:11:22 msg... | |
327 * 01234567890123456 | |
328 */ | |
329 if (len < 16 || msg[3] != ' ' || msg[6] != ' ' || msg[9] != ':' | |
330 || msg[12] != ':' || msg[15] != ' ') { | |
331 time(&now); | |
332 ts = ctime(&now) + 4; /* skip day of week */ | |
333 } else { | |
334 now = 0; | |
335 ts = msg; | |
336 msg += 16; | |
337 } | |
338 ts[15] = '\0'; | |
339 fac = LOG_FAC(pri); | |
340 lvl = LOG_PRI(pri); | |
341 | |
1024 | 342 if (toys.optflags & FLAG_K) len = sprintf(toybuf, "<%d> %s\n", pri, msg); |
343 else { | |
1042
cbc467592b2e
Remove itoa/utoa, let libc do this with sprintf.
Rob Landley <rob@landley.net>
parents:
1028
diff
changeset
|
344 char facbuf[12], pribuf[12]; |
cbc467592b2e
Remove itoa/utoa, let libc do this with sprintf.
Rob Landley <rob@landley.net>
parents:
1028
diff
changeset
|
345 |
cbc467592b2e
Remove itoa/utoa, let libc do this with sprintf.
Rob Landley <rob@landley.net>
parents:
1028
diff
changeset
|
346 facstr = dec(pri & LOG_FACMASK, facilitynames, facbuf); |
cbc467592b2e
Remove itoa/utoa, let libc do this with sprintf.
Rob Landley <rob@landley.net>
parents:
1028
diff
changeset
|
347 lvlstr = dec(LOG_PRI(pri), prioritynames, pribuf); |
960 | 348 |
1024 | 349 p = "local"; |
350 if (!uname(&uts)) p = uts.nodename; | |
351 if (toys.optflags & FLAG_S) len = sprintf(toybuf, "%s %s\n", ts, msg); | |
352 else len = sprintf(toybuf, "%s %s %s.%s %s\n", ts, p, facstr, lvlstr, msg); | |
353 } | |
960 | 354 if (lvl >= TT.log_prio) return; |
355 | |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
356 for (; tf; tf = tf->next) { |
960 | 357 if (tf->logfd > 0) { |
1028 | 358 if (!((tf->facility[lvl] & (1 << fac)) || (tf->level[fac] & (1<<lvl)))) { |
359 int wlen, isNetwork = *tf->filename == '@'; | |
360 if (isNetwork) | |
960 | 361 wlen = sendto(tf->logfd, omsg, olen, 0, (struct sockaddr*)&tf->saddr, sizeof(tf->saddr)); |
362 else wlen = write_rotate(tf, len); | |
1028 | 363 if (wlen < 0) perror_msg("write failed file : %s ", tf->filename + isNetwork); |
960 | 364 } |
365 } | |
366 } | |
367 } | |
368 | |
369 /* | |
370 * closes all read and write fds | |
371 * and frees all nodes and lists | |
372 */ | |
373 static void cleanup(void) | |
374 { | |
375 while (TT.lsocks) { | |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
376 struct unsocks *fnode = TT.lsocks; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
377 |
1028 | 378 if (fnode->sd >= 0) { |
379 close(fnode->sd); | |
380 unlink(fnode->path); | |
381 } | |
960 | 382 TT.lsocks = fnode->next; |
383 free(fnode); | |
384 } | |
385 | |
386 while (TT.lfiles) { | |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
387 struct logfile *fnode = TT.lfiles; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
388 |
1028 | 389 free(fnode->filename); |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
390 if (fnode->logfd >= 0) close(fnode->logfd); |
960 | 391 TT.lfiles = fnode->next; |
392 free(fnode); | |
393 } | |
394 } | |
395 | |
396 static void signal_handler(int sig) | |
397 { | |
398 unsigned char ch = sig; | |
1021 | 399 if (write(TT.sigfd[1], &ch, 1) != 1) error_msg("can't send signal"); |
960 | 400 } |
401 | |
402 void syslogd_main(void) | |
403 { | |
1021 | 404 struct unsocks *tsd; |
1028 | 405 int nfds, retval, last_len=0; |
960 | 406 struct timeval tv; |
1028 | 407 fd_set rfds; // fds for reading |
960 | 408 char *temp, *buffer = (toybuf +2048), *last_buf = (toybuf + 3072); //these two buffs are of 1K each |
409 | |
1024 | 410 if ((toys.optflags & FLAG_p) && (strlen(TT.unix_socket) > 108)) |
960 | 411 error_exit("Socket path should not be more than 108"); |
412 | |
1024 | 413 TT.config_file = (toys.optflags & FLAG_f) ? |
414 TT.config_file : "/etc/syslog.conf"; //DEFCONFFILE | |
960 | 415 init_jumpin: |
1021 | 416 tsd = xzalloc(sizeof(struct unsocks)); |
960 | 417 |
1024 | 418 tsd->path = (toys.optflags & FLAG_p) ? TT.unix_socket : "/dev/log"; // DEFLOGSOCK |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
419 TT.lsocks = tsd; |
960 | 420 |
1024 | 421 if (toys.optflags & FLAG_a) { |
960 | 422 for (temp = strtok(TT.socket, ":"); temp; temp = strtok(NULL, ":")) { |
423 if (strlen(temp) > 107) temp[108] = '\0'; | |
1021 | 424 tsd = xzalloc(sizeof(struct unsocks)); |
960 | 425 tsd->path = temp; |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
426 tsd->next = TT.lsocks; |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
427 TT.lsocks = tsd; |
960 | 428 } |
429 } | |
1028 | 430 /* |
431 * initializes unsock_t structure | |
432 * and opens socket for reading | |
433 * and adds to global lsock list. | |
434 */ | |
435 nfds = 0; | |
436 for (tsd = TT.lsocks; tsd; tsd = tsd->next) { | |
437 tsd->sdu.sun_family = AF_UNIX; | |
438 strcpy(tsd->sdu.sun_path, tsd->path); | |
439 tsd->sd = socket(AF_UNIX, SOCK_DGRAM, 0); | |
440 if (tsd->sd < 0) { | |
441 perror_msg("OPEN SOCKS : failed"); | |
442 continue; | |
443 } | |
444 unlink(tsd->sdu.sun_path); | |
445 if (bind(tsd->sd, (struct sockaddr *) &tsd->sdu, sizeof(tsd->sdu))) { | |
446 perror_msg("BIND SOCKS : failed sock : %s", tsd->sdu.sun_path); | |
447 close(tsd->sd); | |
448 continue; | |
449 } | |
450 chmod(tsd->path, 0777); | |
451 nfds++; | |
452 } | |
453 if (!nfds) { | |
960 | 454 error_msg("Can't open single socket for listenning."); |
455 goto clean_and_exit; | |
456 } | |
1021 | 457 |
458 // Setup signals | |
459 if (pipe(TT.sigfd) < 0) error_exit("pipe failed\n"); | |
460 | |
461 fcntl(TT.sigfd[1] , F_SETFD, FD_CLOEXEC); | |
462 fcntl(TT.sigfd[0] , F_SETFD, FD_CLOEXEC); | |
463 int flags = fcntl(TT.sigfd[1], F_GETFL); | |
464 fcntl(TT.sigfd[1], F_SETFL, flags | O_NONBLOCK); | |
465 signal(SIGHUP, signal_handler); | |
466 signal(SIGTERM, signal_handler); | |
467 signal(SIGINT, signal_handler); | |
468 signal(SIGQUIT, signal_handler); | |
469 | |
960 | 470 if (parse_config_file() == -1) goto clean_and_exit; |
471 open_logfiles(); | |
1024 | 472 if (!(toys.optflags & FLAG_n)) { |
1028 | 473 daemonize(); |
995
893c86bbe452
Add daemonize function to lib for klogd and syslogd
Felix Janda <felix.janda@posteo.de>
parents:
960
diff
changeset
|
474 //don't daemonize again if SIGHUP received. |
893c86bbe452
Add daemonize function to lib for klogd and syslogd
Felix Janda <felix.janda@posteo.de>
parents:
960
diff
changeset
|
475 toys.optflags |= FLAG_n; |
893c86bbe452
Add daemonize function to lib for klogd and syslogd
Felix Janda <felix.janda@posteo.de>
parents:
960
diff
changeset
|
476 } |
1028 | 477 xpidfile("syslogd"); |
960 | 478 |
479 logmsg("<46>Toybox: syslogd started", 27); //27 : the length of message | |
480 for (;;) { | |
1028 | 481 // Add opened socks to rfds for select() |
482 FD_ZERO(&rfds); | |
483 for (tsd = TT.lsocks; tsd; tsd = tsd->next) FD_SET(tsd->sd, &rfds); | |
484 FD_SET(TT.sigfd[0], &rfds); | |
960 | 485 tv.tv_usec = 0; |
486 tv.tv_sec = TT.interval*60; | |
487 | |
1028 | 488 retval = select(TT.sigfd[0] + 1, &rfds, NULL, NULL, (TT.interval)?&tv:NULL); |
489 if (retval < 0) { | |
490 if (errno != EINTR) perror_msg("Error in select "); | |
960 | 491 } |
1028 | 492 else if (!retval) logmsg("<46>-- MARK --", 14); |
493 else if (FD_ISSET(TT.sigfd[0], &rfds)) { /* May be a signal */ | |
960 | 494 unsigned char sig; |
495 | |
1021 | 496 if (read(TT.sigfd[0], &sig, 1) != 1) { |
960 | 497 error_msg("signal read failed.\n"); |
498 continue; | |
499 } | |
500 switch(sig) { | |
501 case SIGTERM: /* FALLTHROUGH */ | |
502 case SIGINT: /* FALLTHROUGH */ | |
503 case SIGQUIT: | |
504 logmsg("<46>syslogd exiting", 19); | |
505 if (CFG_TOYBOX_FREE ) cleanup(); | |
506 signal(sig, SIG_DFL); | |
507 sigset_t ss; | |
508 sigemptyset(&ss); | |
509 sigaddset(&ss, sig); | |
510 sigprocmask(SIG_UNBLOCK, &ss, NULL); | |
511 raise(sig); | |
512 _exit(1); /* Should not reach it */ | |
513 break; | |
514 case SIGHUP: | |
515 logmsg("<46>syslogd exiting", 19); | |
516 cleanup(); //cleanup is done, as we restart syslog. | |
517 goto init_jumpin; | |
518 default: break; | |
519 } | |
1028 | 520 } else { /* Some activity on listen sockets. */ |
1026
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
521 for (tsd = TT.lsocks; tsd; tsd = tsd->next) { |
09cc81f6e411
syslogd: stop abusing arg_list
Felix Janda <felix.janda at posteo.de>
parents:
1025
diff
changeset
|
522 int sd = tsd->sd; |
1028 | 523 if (FD_ISSET(sd, &rfds)) { |
960 | 524 int len = read(sd, buffer, 1023); //buffer is of 1K, hence readingonly 1023 bytes, 1 for NUL |
525 if (len > 0) { | |
526 buffer[len] = '\0'; | |
1024 | 527 if((toys.optflags & FLAG_D) && (len == last_len)) |
960 | 528 if (!memcmp(last_buf, buffer, len)) break; |
529 | |
530 memcpy(last_buf, buffer, len); | |
531 last_len = len; | |
532 logmsg(buffer, len); | |
533 } | |
534 break; | |
535 } | |
536 } | |
537 } | |
538 } | |
539 clean_and_exit: | |
540 logmsg("<46>syslogd exiting", 19); | |
541 if (CFG_TOYBOX_FREE ) cleanup(); | |
542 } |