Mercurial > hg > toybox
comparison toys/pending/syslogd.c @ 1024:63b8e54d2c6f
syslogd: cleanup
- remove flag macros
- remove some unecessary gotos
- inline open_udp_socks() and getport()
- simplify resulting open_logfiles()
Now in the syslog.conf the port numbers for remote hosts are no
longer allowed to be hexadecimal. If there is need for hexadecimal
port numbers, one can as well accept octal ones and use base 0
in strtoul.
author | Felix Janda <felix.janda@posteo.de> |
---|---|
date | Wed, 21 Aug 2013 21:24:45 +0200 |
parents | 773e4862e790 |
children | f19286ac3e7f |
comparison
equal
deleted
inserted
replaced
1023:97383e221a4a | 1024:63b8e54d2c6f |
---|---|
53 fd_set rfds; // fds for reading | 53 fd_set rfds; // fds for reading |
54 int sd; // socket for logging remote messeges. | 54 int sd; // socket for logging remote messeges. |
55 int sigfd[2]; | 55 int sigfd[2]; |
56 ) | 56 ) |
57 | 57 |
58 #define flag_get(f,v,d) ((toys.optflags & f) ? v : d) | |
59 #define flag_chk(f) ((toys.optflags & f) ? 1 : 0) | |
60 | |
61 | 58 |
62 // UNIX Sockets for listening | 59 // UNIX Sockets for listening |
63 struct unsocks { | 60 struct unsocks { |
64 char *path; | 61 char *path; |
65 struct sockaddr_un sdu; | 62 struct sockaddr_un sdu; |
68 | 65 |
69 // Log file entry to log into. | 66 // Log file entry to log into. |
70 struct logfile { | 67 struct logfile { |
71 char *filename; | 68 char *filename; |
72 char *config; | 69 char *config; |
73 uint8_t isNetwork; | 70 int isNetwork; |
74 uint32_t facility[8]; | 71 uint32_t facility[8]; |
75 uint8_t level[LOG_NFACILITIES]; | 72 uint8_t level[LOG_NFACILITIES]; |
76 int logfd; | 73 int logfd; |
77 struct sockaddr_in saddr; | 74 struct sockaddr_in saddr; |
78 }; | 75 }; |
125 } | 122 } |
126 chmod(sock->path, 0777); | 123 chmod(sock->path, 0777); |
127 ret++; | 124 ret++; |
128 } | 125 } |
129 return ret; | 126 return ret; |
130 } | |
131 | |
132 /* | |
133 * creates a socket of family INET and protocol UDP | |
134 * if successful then returns SOCK othrwise error | |
135 */ | |
136 static int open_udp_socks(char *host, int port, struct sockaddr_in *sadd) | |
137 { | |
138 struct addrinfo *info, rp; | |
139 | |
140 memset(&rp, 0, sizeof(rp)); | |
141 rp.ai_family = AF_INET; | |
142 rp.ai_socktype = SOCK_DGRAM; | |
143 rp.ai_protocol = IPPROTO_UDP; | |
144 | |
145 if (getaddrinfo(host, NULL, &rp, &info) || !info) | |
146 perror_exit("BAD ADDRESS: can't find : %s ", host); | |
147 ((struct sockaddr_in*)info->ai_addr)->sin_port = htons(port); | |
148 memcpy(sadd, info->ai_addr, info->ai_addrlen); | |
149 freeaddrinfo(info); | |
150 | |
151 return xsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | |
152 } | 127 } |
153 | 128 |
154 // Returns node having filename | 129 // Returns node having filename |
155 static struct arg_list *get_file_node(char *filename, struct arg_list *list) | 130 static struct arg_list *get_file_node(char *filename, struct arg_list *list) |
156 { | 131 { |
259 /* | 234 /* |
260 * if -K then open only /dev/kmsg | 235 * if -K then open only /dev/kmsg |
261 * all other log files are neglected | 236 * all other log files are neglected |
262 * thus no need to open config either. | 237 * thus no need to open config either. |
263 */ | 238 */ |
264 if (flag_chk(FLAG_K)) { | 239 if (toys.optflags & FLAG_K) { |
265 node = xzalloc(sizeof(struct arg_list)); | 240 node = xzalloc(sizeof(struct arg_list)); |
266 file = xzalloc(sizeof(struct logfile)); | 241 file = xzalloc(sizeof(struct logfile)); |
267 file->filename = "/dev/kmsg"; | 242 file->filename = "/dev/kmsg"; |
268 file->config = "*.*"; | 243 file->config = "*.*"; |
269 memset(file->level, 0xFF, sizeof(file->level)); | 244 memset(file->level, 0xFF, sizeof(file->level)); |
276 * if -R then add remote host to log list | 251 * if -R then add remote host to log list |
277 * if -L is not provided all other log | 252 * if -L is not provided all other log |
278 * files are neglected thus no need to | 253 * files are neglected thus no need to |
279 * open config either so just return. | 254 * open config either so just return. |
280 */ | 255 */ |
281 if (flag_chk(FLAG_R)) { | 256 if (toys.optflags & FLAG_R) { |
282 node = xzalloc(sizeof(struct arg_list)); | 257 node = xzalloc(sizeof(struct arg_list)); |
283 file = xzalloc(sizeof(struct logfile)); | 258 file = xzalloc(sizeof(struct logfile)); |
284 file->filename = xmsprintf("@%s",TT.remote_log); | 259 file->filename = xmsprintf("@%s",TT.remote_log); |
285 file->isNetwork = 1; | 260 file->isNetwork = 1; |
286 file->config = "*.*"; | 261 file->config = "*.*"; |
287 memset(file->level, 0xFF, sizeof(file->level)); | 262 memset(file->level, 0xFF, sizeof(file->level)); |
288 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); | 263 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); |
289 node->arg = (char*) file; | 264 node->arg = (char*) file; |
290 TT.lfiles = node; | 265 TT.lfiles = node; |
291 if (!flag_chk(FLAG_L))return 0; | 266 if (!(toys.optflags & FLAG_L))return 0; |
292 } | 267 } |
293 /* | 268 /* |
294 * Read config file and add logfiles to the list | 269 * Read config file and add logfiles to the list |
295 * with their configuration. | 270 * with their configuration. |
296 */ | 271 */ |
297 fp = fopen(TT.config_file, "r"); | 272 fp = fopen(TT.config_file, "r"); |
298 if (!fp && flag_chk(FLAG_f)) | 273 if (!fp && (toys.optflags & FLAG_f)) |
299 perror_exit("can't open '%s'", TT.config_file); | 274 perror_exit("can't open '%s'", TT.config_file); |
300 | 275 |
301 for (len = 0, linelen = 0; fp;) { | 276 for (len = 0, linelen = 0; fp;) { |
302 len = getline(&confline, (size_t*) &linelen, fp); | 277 len = getline(&confline, (size_t*) &linelen, fp); |
303 if (len <= 0) break; | 278 if (len <= 0) break; |
321 if (*tk == '\n') *tk = '\0'; | 296 if (*tk == '\n') *tk = '\0'; |
322 if (*tokens[1] == '\0') { | 297 if (*tokens[1] == '\0') { |
323 error_msg("bad line %d: 1 tokens found, 2 needed", lineno); | 298 error_msg("bad line %d: 1 tokens found, 2 needed", lineno); |
324 return -1; | 299 return -1; |
325 } | 300 } |
326 if (*tokens[1] == '*') goto loop_again; | 301 if (*tokens[1] != '*') { |
327 | 302 node = get_file_node(tokens[1], TT.lfiles); |
328 node = get_file_node(tokens[1], TT.lfiles); | 303 if (!node) { |
329 if (!node) { | 304 node = xzalloc(sizeof(struct arg_list)); |
330 node = xzalloc(sizeof(struct arg_list)); | 305 file = xzalloc(sizeof(struct logfile)); |
331 file = xzalloc(sizeof(struct logfile)); | 306 file->config = xstrdup(tokens[0]); |
332 file->config = xstrdup(tokens[0]); | 307 if (resolve_config(file)==-1) { |
333 if (resolve_config(file)==-1) { | 308 error_msg("error in '%s' at line %d", TT.config_file, lineno); |
334 error_msg("error in '%s' at line %d", TT.config_file, lineno); | 309 return -1; |
335 return -1; | 310 } |
336 } | 311 file->filename = xstrdup(tokens[1]); |
337 file->filename = xstrdup(tokens[1]); | 312 if (*file->filename == '@') file->isNetwork = 1; |
338 if (*file->filename == '@') file->isNetwork = 1; | 313 node->arg = (char*) file; |
339 node->arg = (char*) file; | 314 node->next = TT.lfiles; |
340 node->next = TT.lfiles; | 315 TT.lfiles = node; |
341 TT.lfiles = node; | 316 } else { |
342 } else { | 317 file = (struct logfile*) node->arg; |
343 file = (struct logfile*) node->arg; | 318 int rel = strlen(file->config) + strlen(tokens[0]) + 2; |
344 int rel = strlen(file->config) + strlen(tokens[0]) + 2; | 319 file->config = xrealloc(file->config, rel); |
345 file->config = xrealloc(file->config, rel); | 320 sprintf(file->config, "%s;%s", file->config, tokens[0]); |
346 sprintf(file->config, "%s;%s", file->config, tokens[0]); | 321 } |
347 } | 322 } |
348 loop_again: | |
349 if (tokens[0]) free(tokens[0]); | 323 if (tokens[0]) free(tokens[0]); |
350 if (tokens[1]) free(tokens[1]); | 324 if (tokens[1]) free(tokens[1]); |
351 free(confline); | 325 free(confline); |
352 confline = NULL; | 326 confline = NULL; |
353 } | 327 } |
356 * adding default logfile to the head of list. | 330 * adding default logfile to the head of list. |
357 */ | 331 */ |
358 if (!fp){ | 332 if (!fp){ |
359 node = xzalloc(sizeof(struct arg_list)); | 333 node = xzalloc(sizeof(struct arg_list)); |
360 file = xzalloc(sizeof(struct logfile)); | 334 file = xzalloc(sizeof(struct logfile)); |
361 file->filename = flag_get(FLAG_O, TT.logfile, "/var/log/messages"); //DEFLOGFILE | 335 file->filename = (toys.optflags & FLAG_O) ? |
336 TT.logfile : "/var/log/messages"; //DEFLOGFILE | |
362 file->isNetwork = 0; | 337 file->isNetwork = 0; |
363 file->config = "*.*"; | 338 file->config = "*.*"; |
364 memset(file->level, 0xFF, sizeof(file->level)); | 339 memset(file->level, 0xFF, sizeof(file->level)); |
365 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); | 340 memset(file->facility, 0xFFFFFFFF, sizeof(file->facility)); |
366 node->arg = (char*) file; | 341 node->arg = (char*) file; |
372 fp = NULL; | 347 fp = NULL; |
373 } | 348 } |
374 return 0; | 349 return 0; |
375 } | 350 } |
376 | 351 |
377 static int getport(char *str, char *filename) | |
378 { | |
379 char *endptr = NULL; | |
380 int base = 10; | |
381 errno = 0; | |
382 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) { | |
383 base = 16; | |
384 str += 2; | |
385 } | |
386 long port = strtol(str, &endptr, base); | |
387 if (errno || *endptr!='\0'|| endptr == str | |
388 || port < 0 || port > 65535) error_exit("wrong port no in %s", filename); | |
389 return (int)port; | |
390 } | |
391 | |
392 // open every log file in list. | 352 // open every log file in list. |
393 static void open_logfiles(void) | 353 static void open_logfiles(void) |
394 { | 354 { |
395 struct logfile *tfd; | 355 struct arg_list *node; |
396 char *p, *tmpfile; | 356 |
397 int port = -1; | 357 for (node = TT.lfiles; node; node = node->next) { |
398 struct arg_list *node = TT.lfiles; | 358 struct logfile *tfd = (struct logfile*) node->arg; |
399 | 359 char *p, *tmpfile; |
400 while (node) { | 360 long port = 514; |
401 tfd = (struct logfile*) node->arg; | 361 |
402 if (tfd->isNetwork) { | 362 if (tfd->isNetwork) { |
403 tmpfile = xstrdup(tfd->filename +1); | 363 struct addrinfo *info, rp; |
364 | |
365 tmpfile = xstrdup(tfd->filename + 1); | |
404 if ((p = strchr(tmpfile, ':'))) { | 366 if ((p = strchr(tmpfile, ':'))) { |
367 char *endptr; | |
368 | |
405 *p = '\0'; | 369 *p = '\0'; |
406 port = getport(p + 1, tfd->filename); | 370 port = strtol(++p, &endptr, 10); |
407 } | 371 if (*endptr || endptr == p || port < 0 || port > 65535) |
408 tfd->logfd = open_udp_socks(tmpfile, (port>=0)?port:514, &tfd->saddr); | 372 error_exit("bad port in %s", tfd->filename); |
373 } | |
374 memset(&rp, 0, sizeof(rp)); | |
375 rp.ai_family = AF_INET; | |
376 rp.ai_socktype = SOCK_DGRAM; | |
377 rp.ai_protocol = IPPROTO_UDP; | |
378 | |
379 if (getaddrinfo(tmpfile, NULL, &rp, &info) || !info) | |
380 perror_exit("BAD ADDRESS: can't find : %s ", tmpfile); | |
381 ((struct sockaddr_in*)info->ai_addr)->sin_port = htons(port); | |
382 memcpy(&tfd->saddr, info->ai_addr, info->ai_addrlen); | |
383 freeaddrinfo(info); | |
384 | |
385 tfd->logfd = xsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | |
409 free(tmpfile); | 386 free(tmpfile); |
410 } else tfd->logfd = open(tfd->filename, O_CREAT | O_WRONLY | O_APPEND, 0666); | 387 } else tfd->logfd = open(tfd->filename, O_CREAT | O_WRONLY | O_APPEND, 0666); |
411 if (tfd->logfd < 0) { | 388 if (tfd->logfd < 0) { |
412 tfd->filename = "/dev/console"; | 389 tfd->filename = "/dev/console"; |
413 tfd->logfd = open(tfd->filename, O_APPEND); | 390 tfd->logfd = open(tfd->filename, O_APPEND); |
414 } | 391 } |
415 node = node->next; | |
416 } | 392 } |
417 } | 393 } |
418 | 394 |
419 //write to file with rotation | 395 //write to file with rotation |
420 static int write_rotate(struct logfile *tf, int len) | 396 static int write_rotate(struct logfile *tf, int len) |
422 int size, isreg; | 398 int size, isreg; |
423 struct stat statf; | 399 struct stat statf; |
424 isreg = (!fstat(tf->logfd, &statf) && S_ISREG(statf.st_mode)); | 400 isreg = (!fstat(tf->logfd, &statf) && S_ISREG(statf.st_mode)); |
425 size = statf.st_size; | 401 size = statf.st_size; |
426 | 402 |
427 if (flag_chk(FLAG_s) || flag_chk(FLAG_b)) { | 403 if ((toys.optflags & FLAG_s) || (toys.optflags & FLAG_b)) { |
428 if (TT.rot_size && isreg && (size + len) > (TT.rot_size*1024)) { | 404 if (TT.rot_size && isreg && (size + len) > (TT.rot_size*1024)) { |
429 if (TT.rot_count) { /* always 0..99 */ | 405 if (TT.rot_count) { /* always 0..99 */ |
430 int i = strlen(tf->filename) + 3 + 1; | 406 int i = strlen(tf->filename) + 3 + 1; |
431 char old_file[i]; | 407 char old_file[i]; |
432 char new_file[i]; | 408 char new_file[i]; |
511 } | 487 } |
512 ts[15] = '\0'; | 488 ts[15] = '\0'; |
513 fac = LOG_FAC(pri); | 489 fac = LOG_FAC(pri); |
514 lvl = LOG_PRI(pri); | 490 lvl = LOG_PRI(pri); |
515 | 491 |
516 if (flag_chk(FLAG_K)) { | 492 if (toys.optflags & FLAG_K) len = sprintf(toybuf, "<%d> %s\n", pri, msg); |
517 len = sprintf(toybuf, "<%d> %s\n", pri, msg); | 493 else { |
518 goto do_log; | 494 priority_to_string(pri, &facstr, &lvlstr); |
519 } | 495 |
520 priority_to_string(pri, &facstr, &lvlstr); | 496 p = "local"; |
521 | 497 if (!uname(&uts)) p = uts.nodename; |
522 p = "local"; | 498 if (toys.optflags & FLAG_S) len = sprintf(toybuf, "%s %s\n", ts, msg); |
523 if (!uname(&uts)) p = uts.nodename; | 499 else len = sprintf(toybuf, "%s %s %s.%s %s\n", ts, p, facstr, lvlstr, msg); |
524 if (flag_chk(FLAG_S)) len = sprintf(toybuf, "%s %s\n", ts, msg); | 500 } |
525 else len = sprintf(toybuf, "%s %s %s.%s %s\n", ts, p, facstr, lvlstr, msg); | |
526 | |
527 do_log: | |
528 if (lvl >= TT.log_prio) return; | 501 if (lvl >= TT.log_prio) return; |
529 | 502 |
530 while (lnode) { | 503 while (lnode) { |
531 struct logfile *tf = (struct logfile*) lnode->arg; | 504 struct logfile *tf = (struct logfile*) lnode->arg; |
532 if (tf->logfd > 0) { | 505 if (tf->logfd > 0) { |
533 if ((tf->facility[lvl] & (1 << fac)) && (tf->level[fac] & (1<<lvl))) { | 506 if ((tf->facility[lvl] & (1 << fac)) && (tf->level[fac] & (1<<lvl))) { |
534 int wlen; | 507 int wlen; |
535 if (tf->isNetwork) | 508 if (tf->isNetwork) |
536 wlen = sendto(tf->logfd, omsg, olen, 0, (struct sockaddr*)&tf->saddr, sizeof(tf->saddr)); | 509 wlen = sendto(tf->logfd, omsg, olen, 0, (struct sockaddr*)&tf->saddr, sizeof(tf->saddr)); |
537 else wlen = write_rotate(tf, len); | 510 else wlen = write_rotate(tf, len); |
538 if (wlen < 0) perror_msg("write failed file : %s ", (tf->isNetwork)?(tf->filename+1):tf->filename); | 511 if (wlen < 0) perror_msg("write failed file : %s ", tf->filename + tf->isNetwork); |
539 } | 512 } |
540 } | 513 } |
541 lnode = lnode->next; | 514 lnode = lnode->next; |
542 } | 515 } |
543 } | 516 } |
581 int maxfd, retval, last_len=0; | 554 int maxfd, retval, last_len=0; |
582 struct timeval tv; | 555 struct timeval tv; |
583 struct arg_list *node; | 556 struct arg_list *node; |
584 char *temp, *buffer = (toybuf +2048), *last_buf = (toybuf + 3072); //these two buffs are of 1K each | 557 char *temp, *buffer = (toybuf +2048), *last_buf = (toybuf + 3072); //these two buffs are of 1K each |
585 | 558 |
586 if (flag_chk(FLAG_p) && strlen(TT.unix_socket) > 108) | 559 if ((toys.optflags & FLAG_p) && (strlen(TT.unix_socket) > 108)) |
587 error_exit("Socket path should not be more than 108"); | 560 error_exit("Socket path should not be more than 108"); |
588 | 561 |
589 TT.config_file = flag_get(FLAG_f, TT.config_file, "/etc/syslog.conf"); //DEFCONFFILE | 562 TT.config_file = (toys.optflags & FLAG_f) ? |
563 TT.config_file : "/etc/syslog.conf"; //DEFCONFFILE | |
590 init_jumpin: | 564 init_jumpin: |
591 TT.lsocks = xzalloc(sizeof(struct arg_list)); | 565 TT.lsocks = xzalloc(sizeof(struct arg_list)); |
592 tsd = xzalloc(sizeof(struct unsocks)); | 566 tsd = xzalloc(sizeof(struct unsocks)); |
593 | 567 |
594 tsd->path = flag_get(FLAG_p, TT.unix_socket , "/dev/log"); // DEFLOGSOCK | 568 tsd->path = (toys.optflags & FLAG_p) ? TT.unix_socket : "/dev/log"; // DEFLOGSOCK |
595 TT.lsocks->arg = (char*) tsd; | 569 TT.lsocks->arg = (char*) tsd; |
596 | 570 |
597 if (flag_chk(FLAG_a)) { | 571 if (toys.optflags & FLAG_a) { |
598 for (temp = strtok(TT.socket, ":"); temp; temp = strtok(NULL, ":")) { | 572 for (temp = strtok(TT.socket, ":"); temp; temp = strtok(NULL, ":")) { |
599 struct arg_list *ltemp = xzalloc(sizeof(struct arg_list)); | 573 struct arg_list *ltemp = xzalloc(sizeof(struct arg_list)); |
600 if (strlen(temp) > 107) temp[108] = '\0'; | 574 if (strlen(temp) > 107) temp[108] = '\0'; |
601 tsd = xzalloc(sizeof(struct unsocks)); | 575 tsd = xzalloc(sizeof(struct unsocks)); |
602 tsd->path = temp; | 576 tsd->path = temp; |
622 signal(SIGINT, signal_handler); | 596 signal(SIGINT, signal_handler); |
623 signal(SIGQUIT, signal_handler); | 597 signal(SIGQUIT, signal_handler); |
624 | 598 |
625 if (parse_config_file() == -1) goto clean_and_exit; | 599 if (parse_config_file() == -1) goto clean_and_exit; |
626 open_logfiles(); | 600 open_logfiles(); |
627 if (!flag_chk(FLAG_n)) { | 601 if (!(toys.optflags & FLAG_n)) { |
628 //don't daemonize again if SIGHUP received. | 602 //don't daemonize again if SIGHUP received. |
629 toys.optflags |= FLAG_n; | 603 toys.optflags |= FLAG_n; |
630 } | 604 } |
631 { | 605 { |
632 int pid_fd = open("/var/run/syslogd.pid", O_CREAT | O_WRONLY | O_TRUNC, 0666); | 606 int pid_fd = open("/var/run/syslogd.pid", O_CREAT | O_WRONLY | O_TRUNC, 0666); |
688 int sd = ((struct unsocks*) node->arg)->sd; | 662 int sd = ((struct unsocks*) node->arg)->sd; |
689 if (FD_ISSET(sd, &TT.rfds)) { | 663 if (FD_ISSET(sd, &TT.rfds)) { |
690 int len = read(sd, buffer, 1023); //buffer is of 1K, hence readingonly 1023 bytes, 1 for NUL | 664 int len = read(sd, buffer, 1023); //buffer is of 1K, hence readingonly 1023 bytes, 1 for NUL |
691 if (len > 0) { | 665 if (len > 0) { |
692 buffer[len] = '\0'; | 666 buffer[len] = '\0'; |
693 if(flag_chk(FLAG_D) && (len == last_len)) | 667 if((toys.optflags & FLAG_D) && (len == last_len)) |
694 if (!memcmp(last_buf, buffer, len)) break; | 668 if (!memcmp(last_buf, buffer, len)) break; |
695 | 669 |
696 memcpy(last_buf, buffer, len); | 670 memcpy(last_buf, buffer, len); |
697 last_len = len; | 671 last_len = len; |
698 logmsg(buffer, len); | 672 logmsg(buffer, len); |