Mercurial > hg > toybox
comparison toys/pending/syslogd.c @ 1026:09cc81f6e411 draft
syslogd: stop abusing arg_list
author | Felix Janda <felix.janda at posteo.de> |
---|---|
date | Fri, 23 Aug 2013 22:50:29 +0200 |
parents | f19286ac3e7f |
children | 4b0ad1c7af42 |
comparison
equal
deleted
inserted
replaced
1025:f19286ac3e7f | 1026:09cc81f6e411 |
---|---|
35 #define FOR_syslogd | 35 #define FOR_syslogd |
36 #define SYSLOG_NAMES | 36 #define SYSLOG_NAMES |
37 #include "toys.h" | 37 #include "toys.h" |
38 #include "toynet.h" | 38 #include "toynet.h" |
39 | 39 |
40 // UNIX Sockets for listening | |
41 struct unsocks { | |
42 struct unsocks *next; | |
43 char *path; | |
44 struct sockaddr_un sdu; | |
45 int sd; | |
46 }; | |
47 | |
48 // Log file entry to log into. | |
49 struct logfile { | |
50 struct logfile *next; | |
51 char *filename; | |
52 char *config; | |
53 int isNetwork; | |
54 uint32_t facility[8]; | |
55 uint8_t level[LOG_NFACILITIES]; | |
56 int logfd; | |
57 struct sockaddr_in saddr; | |
58 }; | |
59 | |
40 GLOBALS( | 60 GLOBALS( |
41 char *socket; | 61 char *socket; |
42 char *config_file; | 62 char *config_file; |
43 char *unix_socket; | 63 char *unix_socket; |
44 char *logfile; | 64 char *logfile; |
46 long rot_size; | 66 long rot_size; |
47 long rot_count; | 67 long rot_count; |
48 char *remote_log; | 68 char *remote_log; |
49 long log_prio; | 69 long log_prio; |
50 | 70 |
51 struct arg_list *lsocks; // list of listen sockets | 71 struct unsocks *lsocks; // list of listen sockets |
52 struct arg_list *lfiles; // list of write logfiles | 72 struct logfile *lfiles; // list of write logfiles |
53 fd_set rfds; // fds for reading | 73 fd_set rfds; // fds for reading |
54 int sd; // socket for logging remote messeges. | 74 int sd; // socket for logging remote messeges. |
55 int sigfd[2]; | 75 int sigfd[2]; |
56 ) | 76 ) |
57 | 77 |
58 | |
59 // UNIX Sockets for listening | |
60 struct unsocks { | |
61 char *path; | |
62 struct sockaddr_un sdu; | |
63 int sd; | |
64 }; | |
65 | |
66 // Log file entry to log into. | |
67 struct logfile { | |
68 char *filename; | |
69 char *config; | |
70 int isNetwork; | |
71 uint32_t facility[8]; | |
72 uint8_t level[LOG_NFACILITIES]; | |
73 int logfd; | |
74 struct sockaddr_in saddr; | |
75 }; | |
76 | |
77 // Lookup numerical code from name | 78 // Lookup numerical code from name |
78 // Also used in logger | 79 // Also used in logger |
79 int logger_lookup(int where, char *key) | 80 int logger_lookup(int where, char *key) |
80 { | 81 { |
81 CODE *w = ((CODE *[]){facilitynames, prioritynames})[where]; | 82 CODE *w = ((CODE *[]){facilitynames, prioritynames})[where]; |
95 } | 96 } |
96 | 97 |
97 // Adds opened socks to rfds for select() | 98 // Adds opened socks to rfds for select() |
98 static int addrfds(void) | 99 static int addrfds(void) |
99 { | 100 { |
100 struct unsocks *sock; | 101 struct unsocks *sock = TT.lsocks; |
101 int ret = 0; | 102 int ret = 0; |
102 struct arg_list *node = TT.lsocks; | |
103 FD_ZERO(&TT.rfds); | 103 FD_ZERO(&TT.rfds); |
104 | 104 |
105 while (node) { | 105 for (; sock; sock = sock->next) { |
106 sock = (struct unsocks*) node->arg; | |
107 if (sock->sd > 2) { | 106 if (sock->sd > 2) { |
108 FD_SET(sock->sd, &TT.rfds); | 107 FD_SET(sock->sd, &TT.rfds); |
109 ret = sock->sd; | 108 ret = sock->sd; |
110 } | 109 } |
111 node = node->next; | |
112 } | 110 } |
113 FD_SET(TT.sigfd[0], &TT.rfds); | 111 FD_SET(TT.sigfd[0], &TT.rfds); |
114 return (TT.sigfd[0] > ret) ? TT.sigfd[0] : ret; | 112 return (TT.sigfd[0] > ret) ? TT.sigfd[0] : ret; |
115 } | 113 } |
116 | 114 |
119 * and opens socket for reading | 117 * and opens socket for reading |
120 * and adds to global lsock list. | 118 * and adds to global lsock list. |
121 */ | 119 */ |
122 static int open_unix_socks(void) | 120 static int open_unix_socks(void) |
123 { | 121 { |
124 struct arg_list *node; | |
125 struct unsocks *sock; | 122 struct unsocks *sock; |
126 int ret = 0; | 123 int ret = 0; |
127 | 124 |
128 for(node = TT.lsocks; node; node = node->next) { | 125 for(sock = TT.lsocks; sock; sock = sock->next) { |
129 sock = (struct unsocks*) node->arg; | |
130 sock->sdu.sun_family = AF_UNIX; | 126 sock->sdu.sun_family = AF_UNIX; |
131 strcpy(sock->sdu.sun_path, sock->path); | 127 strcpy(sock->sdu.sun_path, sock->path); |
132 sock->sd = socket(AF_UNIX, SOCK_DGRAM, 0); | 128 sock->sd = socket(AF_UNIX, SOCK_DGRAM, 0); |
133 if (sock->sd < 0) { | 129 if (sock->sd < 0) { |
134 perror_msg("OPEN SOCKS : failed"); | 130 perror_msg("OPEN SOCKS : failed"); |
142 } | 138 } |
143 chmod(sock->path, 0777); | 139 chmod(sock->path, 0777); |
144 ret++; | 140 ret++; |
145 } | 141 } |
146 return ret; | 142 return ret; |
147 } | |
148 | |
149 // Returns node having filename | |
150 static struct arg_list *get_file_node(char *filename, struct arg_list *list) | |
151 { | |
152 while (list) { | |
153 if (!strcmp(((struct logfile*) list->arg)->filename, filename)) return list; | |
154 list = list->next; | |
155 } | |
156 return list; | |
157 } | 143 } |
158 | 144 |
159 /* | 145 /* |
160 * recurses the logfile list and resolves config | 146 * recurses the logfile list and resolves config |
161 * for evry file and updates facilty and log level bits. | 147 * for evry file and updates facilty and log level bits. |
220 struct logfile *file; | 206 struct logfile *file; |
221 FILE *fp; | 207 FILE *fp; |
222 char *confline = NULL, *tk = NULL, *tokens[2] = {NULL, NULL}; | 208 char *confline = NULL, *tk = NULL, *tokens[2] = {NULL, NULL}; |
223 int len, tcount, lineno = 0; | 209 int len, tcount, lineno = 0; |
224 size_t linelen; | 210 size_t linelen; |
225 struct arg_list *node; | |
226 /* | 211 /* |
227 * if -K then open only /dev/kmsg | 212 * if -K then open only /dev/kmsg |
228 * all other log files are neglected | 213 * all other log files are neglected |
229 * thus no need to open config either. | 214 * thus no need to open config either. |
230 */ | 215 */ |
231 if (toys.optflags & FLAG_K) { | 216 if (toys.optflags & FLAG_K) { |
232 node = xzalloc(sizeof(struct arg_list)); | |
233 file = xzalloc(sizeof(struct logfile)); | 217 file = xzalloc(sizeof(struct logfile)); |
234 file->filename = "/dev/kmsg"; | 218 file->filename = "/dev/kmsg"; |
235 file->config = "*.*"; | 219 file->config = "*.*"; |
236 memset(file->level, 0xFF, sizeof(file->level)); | 220 memset(file->level, 0xFF, sizeof(file->level)); |
237 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); | 221 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); |
238 node->arg = (char*) file; | 222 TT.lfiles = file; |
239 TT.lfiles = node; | |
240 return 0; | 223 return 0; |
241 } | 224 } |
242 /* | 225 /* |
243 * if -R then add remote host to log list | 226 * if -R then add remote host to log list |
244 * if -L is not provided all other log | 227 * if -L is not provided all other log |
245 * files are neglected thus no need to | 228 * files are neglected thus no need to |
246 * open config either so just return. | 229 * open config either so just return. |
247 */ | 230 */ |
248 if (toys.optflags & FLAG_R) { | 231 if (toys.optflags & FLAG_R) { |
249 node = xzalloc(sizeof(struct arg_list)); | |
250 file = xzalloc(sizeof(struct logfile)); | 232 file = xzalloc(sizeof(struct logfile)); |
251 file->filename = xmsprintf("@%s",TT.remote_log); | 233 file->filename = xmsprintf("@%s",TT.remote_log); |
252 file->isNetwork = 1; | 234 file->isNetwork = 1; |
253 file->config = "*.*"; | 235 file->config = "*.*"; |
254 memset(file->level, 0xFF, sizeof(file->level)); | 236 memset(file->level, 0xFF, sizeof(file->level)); |
255 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); | 237 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); |
256 node->arg = (char*) file; | 238 TT.lfiles = file; |
257 TT.lfiles = node; | |
258 if (!(toys.optflags & FLAG_L)) return 0; | 239 if (!(toys.optflags & FLAG_L)) return 0; |
259 } | 240 } |
260 /* | 241 /* |
261 * Read config file and add logfiles to the list | 242 * Read config file and add logfiles to the list |
262 * with their configuration. | 243 * with their configuration. |
289 if (*tokens[1] == '\0') { | 270 if (*tokens[1] == '\0') { |
290 error_msg("bad line %d: 1 tokens found, 2 needed", lineno); | 271 error_msg("bad line %d: 1 tokens found, 2 needed", lineno); |
291 return -1; | 272 return -1; |
292 } | 273 } |
293 if (*tokens[1] != '*') { | 274 if (*tokens[1] != '*') { |
294 node = get_file_node(tokens[1], TT.lfiles); | 275 file = TT.lfiles; |
295 if (!node) { | 276 while (file && !strcmp(file->filename, tokens[1])) file = file->next; |
296 node = xzalloc(sizeof(struct arg_list)); | 277 if (!file) { |
297 file = xzalloc(sizeof(struct logfile)); | 278 file = xzalloc(sizeof(struct logfile)); |
298 file->config = xstrdup(tokens[0]); | 279 file->config = xstrdup(tokens[0]); |
299 if (resolve_config(file)==-1) { | 280 if (resolve_config(file)==-1) { |
300 error_msg("error in '%s' at line %d", TT.config_file, lineno); | 281 error_msg("error in '%s' at line %d", TT.config_file, lineno); |
301 return -1; | 282 return -1; |
302 } | 283 } |
303 file->filename = xstrdup(tokens[1]); | 284 file->filename = xstrdup(tokens[1]); |
304 if (*file->filename == '@') file->isNetwork = 1; | 285 if (*file->filename == '@') file->isNetwork = 1; |
305 node->arg = (char*) file; | 286 file->next = TT.lfiles; |
306 node->next = TT.lfiles; | 287 TT.lfiles = file; |
307 TT.lfiles = node; | |
308 } else { | 288 } else { |
309 file = (struct logfile*) node->arg; | |
310 int rel = strlen(file->config) + strlen(tokens[0]) + 2; | 289 int rel = strlen(file->config) + strlen(tokens[0]) + 2; |
311 file->config = xrealloc(file->config, rel); | 290 file->config = xrealloc(file->config, rel); |
312 sprintf(file->config, "%s;%s", file->config, tokens[0]); | 291 sprintf(file->config, "%s;%s", file->config, tokens[0]); |
313 } | 292 } |
314 } | 293 } |
320 /* | 299 /* |
321 * Can't open config file or support is not enabled | 300 * Can't open config file or support is not enabled |
322 * adding default logfile to the head of list. | 301 * adding default logfile to the head of list. |
323 */ | 302 */ |
324 if (!fp){ | 303 if (!fp){ |
325 node = xzalloc(sizeof(struct arg_list)); | |
326 file = xzalloc(sizeof(struct logfile)); | 304 file = xzalloc(sizeof(struct logfile)); |
327 file->filename = (toys.optflags & FLAG_O) ? | 305 file->filename = (toys.optflags & FLAG_O) ? |
328 TT.logfile : "/var/log/messages"; //DEFLOGFILE | 306 TT.logfile : "/var/log/messages"; //DEFLOGFILE |
329 file->config = "*.*"; | 307 file->config = "*.*"; |
330 memset(file->level, 0xFF, sizeof(file->level)); | 308 memset(file->level, 0xFF, sizeof(file->level)); |
331 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); | 309 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); |
332 node->arg = (char*) file; | 310 file->next = TT.lfiles; |
333 node->next = TT.lfiles; | 311 TT.lfiles = file; |
334 TT.lfiles = node; | |
335 } else fclose(fp); | 312 } else fclose(fp); |
336 return 0; | 313 return 0; |
337 } | 314 } |
338 | 315 |
339 // open every log file in list. | 316 // open every log file in list. |
340 static void open_logfiles(void) | 317 static void open_logfiles(void) |
341 { | 318 { |
342 struct arg_list *node; | 319 struct logfile *tfd; |
343 | 320 |
344 for (node = TT.lfiles; node; node = node->next) { | 321 for (tfd = TT.lfiles; tfd; tfd = tfd->next) { |
345 struct logfile *tfd = (struct logfile*) node->arg; | |
346 char *p, *tmpfile; | 322 char *p, *tmpfile; |
347 long port = 514; | 323 long port = 514; |
348 | 324 |
349 if (tfd->isNetwork) { | 325 if (tfd->isNetwork) { |
350 struct addrinfo *info, rp; | 326 struct addrinfo *info, rp; |
416 { | 392 { |
417 time_t now; | 393 time_t now; |
418 char *p, *ts, *lvlstr, *facstr; | 394 char *p, *ts, *lvlstr, *facstr; |
419 struct utsname uts; | 395 struct utsname uts; |
420 int pri = 0; | 396 int pri = 0; |
421 struct arg_list *lnode = TT.lfiles; | 397 struct logfile *tf = TT.lfiles; |
422 | 398 |
423 char *omsg = msg; | 399 char *omsg = msg; |
424 int olen = len, fac, lvl; | 400 int olen = len, fac, lvl; |
425 | 401 |
426 if (*msg == '<') { // Extract the priority no. | 402 if (*msg == '<') { // Extract the priority no. |
453 if (toys.optflags & FLAG_S) len = sprintf(toybuf, "%s %s\n", ts, msg); | 429 if (toys.optflags & FLAG_S) len = sprintf(toybuf, "%s %s\n", ts, msg); |
454 else len = sprintf(toybuf, "%s %s %s.%s %s\n", ts, p, facstr, lvlstr, msg); | 430 else len = sprintf(toybuf, "%s %s %s.%s %s\n", ts, p, facstr, lvlstr, msg); |
455 } | 431 } |
456 if (lvl >= TT.log_prio) return; | 432 if (lvl >= TT.log_prio) return; |
457 | 433 |
458 while (lnode) { | 434 for (; tf; tf = tf->next) { |
459 struct logfile *tf = (struct logfile*) lnode->arg; | |
460 if (tf->logfd > 0) { | 435 if (tf->logfd > 0) { |
461 if ((tf->facility[lvl] & (1 << fac)) && (tf->level[fac] & (1<<lvl))) { | 436 if ((tf->facility[lvl] & (1 << fac)) && (tf->level[fac] & (1<<lvl))) { |
462 int wlen; | 437 int wlen; |
463 if (tf->isNetwork) | 438 if (tf->isNetwork) |
464 wlen = sendto(tf->logfd, omsg, olen, 0, (struct sockaddr*)&tf->saddr, sizeof(tf->saddr)); | 439 wlen = sendto(tf->logfd, omsg, olen, 0, (struct sockaddr*)&tf->saddr, sizeof(tf->saddr)); |
465 else wlen = write_rotate(tf, len); | 440 else wlen = write_rotate(tf, len); |
466 if (wlen < 0) perror_msg("write failed file : %s ", tf->filename + tf->isNetwork); | 441 if (wlen < 0) perror_msg("write failed file : %s ", tf->filename + tf->isNetwork); |
467 } | 442 } |
468 } | 443 } |
469 lnode = lnode->next; | |
470 } | 444 } |
471 } | 445 } |
472 | 446 |
473 /* | 447 /* |
474 * closes all read and write fds | 448 * closes all read and write fds |
475 * and frees all nodes and lists | 449 * and frees all nodes and lists |
476 */ | 450 */ |
477 static void cleanup(void) | 451 static void cleanup(void) |
478 { | 452 { |
479 struct arg_list *fnode; | |
480 while (TT.lsocks) { | 453 while (TT.lsocks) { |
481 fnode = TT.lsocks; | 454 struct unsocks *fnode = TT.lsocks; |
482 if (((struct unsocks*) fnode->arg)->sd >= 0) | 455 |
483 close(((struct unsocks*) fnode->arg)->sd); | 456 if (fnode->sd >= 0) close(fnode->sd); |
484 free(fnode->arg); | |
485 TT.lsocks = fnode->next; | 457 TT.lsocks = fnode->next; |
486 free(fnode); | 458 free(fnode); |
487 } | 459 } |
488 unlink("/dev/log"); | 460 unlink("/dev/log"); |
489 | 461 |
490 while (TT.lfiles) { | 462 while (TT.lfiles) { |
491 fnode = TT.lfiles; | 463 struct logfile *fnode = TT.lfiles; |
492 if (((struct logfile*) fnode->arg)->logfd >= 0) | 464 |
493 close(((struct logfile*) fnode->arg)->logfd); | 465 if (fnode->logfd >= 0) close(fnode->logfd); |
494 free(fnode->arg); | |
495 TT.lfiles = fnode->next; | 466 TT.lfiles = fnode->next; |
496 free(fnode); | 467 free(fnode); |
497 } | 468 } |
498 } | 469 } |
499 | 470 |
506 void syslogd_main(void) | 477 void syslogd_main(void) |
507 { | 478 { |
508 struct unsocks *tsd; | 479 struct unsocks *tsd; |
509 int maxfd, retval, last_len=0; | 480 int maxfd, retval, last_len=0; |
510 struct timeval tv; | 481 struct timeval tv; |
511 struct arg_list *node; | |
512 char *temp, *buffer = (toybuf +2048), *last_buf = (toybuf + 3072); //these two buffs are of 1K each | 482 char *temp, *buffer = (toybuf +2048), *last_buf = (toybuf + 3072); //these two buffs are of 1K each |
513 | 483 |
514 if ((toys.optflags & FLAG_p) && (strlen(TT.unix_socket) > 108)) | 484 if ((toys.optflags & FLAG_p) && (strlen(TT.unix_socket) > 108)) |
515 error_exit("Socket path should not be more than 108"); | 485 error_exit("Socket path should not be more than 108"); |
516 | 486 |
517 TT.config_file = (toys.optflags & FLAG_f) ? | 487 TT.config_file = (toys.optflags & FLAG_f) ? |
518 TT.config_file : "/etc/syslog.conf"; //DEFCONFFILE | 488 TT.config_file : "/etc/syslog.conf"; //DEFCONFFILE |
519 init_jumpin: | 489 init_jumpin: |
520 TT.lsocks = xzalloc(sizeof(struct arg_list)); | |
521 tsd = xzalloc(sizeof(struct unsocks)); | 490 tsd = xzalloc(sizeof(struct unsocks)); |
522 | 491 |
523 tsd->path = (toys.optflags & FLAG_p) ? TT.unix_socket : "/dev/log"; // DEFLOGSOCK | 492 tsd->path = (toys.optflags & FLAG_p) ? TT.unix_socket : "/dev/log"; // DEFLOGSOCK |
524 TT.lsocks->arg = (char*) tsd; | 493 TT.lsocks = tsd; |
525 | 494 |
526 if (toys.optflags & FLAG_a) { | 495 if (toys.optflags & FLAG_a) { |
527 for (temp = strtok(TT.socket, ":"); temp; temp = strtok(NULL, ":")) { | 496 for (temp = strtok(TT.socket, ":"); temp; temp = strtok(NULL, ":")) { |
528 struct arg_list *ltemp = xzalloc(sizeof(struct arg_list)); | |
529 if (strlen(temp) > 107) temp[108] = '\0'; | 497 if (strlen(temp) > 107) temp[108] = '\0'; |
530 tsd = xzalloc(sizeof(struct unsocks)); | 498 tsd = xzalloc(sizeof(struct unsocks)); |
531 tsd->path = temp; | 499 tsd->path = temp; |
532 ltemp->arg = (char*) tsd; | 500 tsd->next = TT.lsocks; |
533 ltemp->next = TT.lsocks; | 501 TT.lsocks = tsd; |
534 TT.lsocks = ltemp; | |
535 } | 502 } |
536 } | 503 } |
537 if (!open_unix_socks()) { | 504 if (!open_unix_socks()) { |
538 error_msg("Can't open single socket for listenning."); | 505 error_msg("Can't open single socket for listenning."); |
539 goto clean_and_exit; | 506 goto clean_and_exit; |
610 goto init_jumpin; | 577 goto init_jumpin; |
611 default: break; | 578 default: break; |
612 } | 579 } |
613 } | 580 } |
614 if (retval > 0) { /* Some activity on listen sockets. */ | 581 if (retval > 0) { /* Some activity on listen sockets. */ |
615 node = TT.lsocks; | 582 for (tsd = TT.lsocks; tsd; tsd = tsd->next) { |
616 while (node) { | 583 int sd = tsd->sd; |
617 int sd = ((struct unsocks*) node->arg)->sd; | |
618 if (FD_ISSET(sd, &TT.rfds)) { | 584 if (FD_ISSET(sd, &TT.rfds)) { |
619 int len = read(sd, buffer, 1023); //buffer is of 1K, hence readingonly 1023 bytes, 1 for NUL | 585 int len = read(sd, buffer, 1023); //buffer is of 1K, hence readingonly 1023 bytes, 1 for NUL |
620 if (len > 0) { | 586 if (len > 0) { |
621 buffer[len] = '\0'; | 587 buffer[len] = '\0'; |
622 if((toys.optflags & FLAG_D) && (len == last_len)) | 588 if((toys.optflags & FLAG_D) && (len == last_len)) |
626 last_len = len; | 592 last_len = len; |
627 logmsg(buffer, len); | 593 logmsg(buffer, len); |
628 } | 594 } |
629 break; | 595 break; |
630 } | 596 } |
631 node = node->next; | |
632 } | 597 } |
633 } | 598 } |
634 } | 599 } |
635 clean_and_exit: | 600 clean_and_exit: |
636 logmsg("<46>syslogd exiting", 19); | 601 logmsg("<46>syslogd exiting", 19); |