diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-09-30 01:22:25 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-09-30 01:22:25 +0000 |
commit | df6b3ad6bac4af5a954a598436674a5d17bcc719 (patch) | |
tree | 14ddc6cb3a6e30083b6d232dc25e517cfb522cbb | |
parent | 58680706d7f281f9c91afa3917d5b705e61a39ca (diff) | |
download | busybox-w32-df6b3ad6bac4af5a954a598436674a5d17bcc719.tar.gz busybox-w32-df6b3ad6bac4af5a954a598436674a5d17bcc719.tar.bz2 busybox-w32-df6b3ad6bac4af5a954a598436674a5d17bcc719.zip |
inetd: use config parser. by Vladimir
function old new delta
reread_config_file 1092 2154 +1062
next_line 98 33 -65
next_word 197 57 -140
parse_one_line 1202 - -1202
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 1/2 up/down: 1062/-1407) Total: -345 bytes
-rw-r--r-- | networking/inetd.c | 123 |
1 files changed, 36 insertions, 87 deletions
diff --git a/networking/inetd.c b/networking/inetd.c index 9ebec19a5..f80b51052 100644 --- a/networking/inetd.c +++ b/networking/inetd.c | |||
@@ -300,9 +300,8 @@ struct globals { | |||
300 | unsigned max_concurrency; | 300 | unsigned max_concurrency; |
301 | smallint alarm_armed; | 301 | smallint alarm_armed; |
302 | uid_t real_uid; /* user ID who ran us */ | 302 | uid_t real_uid; /* user ID who ran us */ |
303 | unsigned config_lineno; | ||
304 | const char *config_filename; | 303 | const char *config_filename; |
305 | FILE *fconfig; | 304 | parser_t *parser; |
306 | char *default_local_hostname; | 305 | char *default_local_hostname; |
307 | #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN | 306 | #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN |
308 | char *end_ring; | 307 | char *end_ring; |
@@ -327,9 +326,8 @@ struct BUG_G_too_big { | |||
327 | #define max_concurrency (G.max_concurrency) | 326 | #define max_concurrency (G.max_concurrency) |
328 | #define alarm_armed (G.alarm_armed ) | 327 | #define alarm_armed (G.alarm_armed ) |
329 | #define real_uid (G.real_uid ) | 328 | #define real_uid (G.real_uid ) |
330 | #define config_lineno (G.config_lineno ) | ||
331 | #define config_filename (G.config_filename) | 329 | #define config_filename (G.config_filename) |
332 | #define fconfig (G.fconfig ) | 330 | #define parser (G.parser ) |
333 | #define default_local_hostname (G.default_local_hostname) | 331 | #define default_local_hostname (G.default_local_hostname) |
334 | #define first_ps_byte (G.first_ps_byte ) | 332 | #define first_ps_byte (G.first_ps_byte ) |
335 | #define last_ps_byte (G.last_ps_byte ) | 333 | #define last_ps_byte (G.last_ps_byte ) |
@@ -543,61 +541,20 @@ static int reopen_config_file(void) | |||
543 | { | 541 | { |
544 | free(default_local_hostname); | 542 | free(default_local_hostname); |
545 | default_local_hostname = xstrdup("*"); | 543 | default_local_hostname = xstrdup("*"); |
546 | if (fconfig != NULL) | 544 | if (parser != NULL) |
547 | fclose(fconfig); | 545 | config_close(parser); |
548 | config_lineno = 0; | 546 | parser = config_open(config_filename); |
549 | fconfig = fopen_or_warn(config_filename, "r"); | 547 | return (parser != NULL); |
550 | return (fconfig != NULL); | ||
551 | } | 548 | } |
552 | 549 | ||
553 | static void close_config_file(void) | 550 | static void close_config_file(void) |
554 | { | 551 | { |
555 | if (fconfig) { | 552 | if (parser) { |
556 | fclose(fconfig); | 553 | config_close(parser); |
557 | fconfig = NULL; | 554 | parser = NULL; |
558 | } | 555 | } |
559 | } | 556 | } |
560 | 557 | ||
561 | static char *next_line(void) | ||
562 | { | ||
563 | if (fgets(line, LINE_SIZE, fconfig) == NULL) | ||
564 | return NULL; | ||
565 | config_lineno++; | ||
566 | *strchrnul(line, '\n') = '\0'; | ||
567 | return line; | ||
568 | } | ||
569 | |||
570 | static char *next_word(char **cpp) | ||
571 | { | ||
572 | char *start; | ||
573 | char *cp = *cpp; | ||
574 | |||
575 | if (cp == NULL) | ||
576 | return NULL; | ||
577 | again: | ||
578 | while (*cp == ' ' || *cp == '\t') | ||
579 | cp++; | ||
580 | if (*cp == '\0') { | ||
581 | int c = getc(fconfig); | ||
582 | ungetc(c, fconfig); | ||
583 | if (c == ' ' || c == '\t') { | ||
584 | cp = next_line(); | ||
585 | if (cp) | ||
586 | goto again; | ||
587 | } | ||
588 | *cpp = NULL; | ||
589 | return NULL; | ||
590 | } | ||
591 | start = cp; | ||
592 | while (*cp && *cp != ' ' && *cp != '\t') | ||
593 | cp++; | ||
594 | if (*cp != '\0') | ||
595 | *cp++ = '\0'; | ||
596 | |||
597 | *cpp = cp; | ||
598 | return start; | ||
599 | } | ||
600 | |||
601 | static void free_servtab_strings(servtab_t *cp) | 558 | static void free_servtab_strings(servtab_t *cp) |
602 | { | 559 | { |
603 | int i; | 560 | int i; |
@@ -643,55 +600,49 @@ static servtab_t *dup_servtab(servtab_t *sep) | |||
643 | } | 600 | } |
644 | 601 | ||
645 | /* gcc generates much more code if this is inlined */ | 602 | /* gcc generates much more code if this is inlined */ |
646 | static NOINLINE servtab_t *parse_one_line(void) | 603 | static servtab_t *parse_one_line(void) |
647 | { | 604 | { |
648 | int argc; | 605 | int argc; |
649 | char *p, *cp, *arg; | 606 | char *token[6+MAXARGV]; |
607 | char *p, *arg; | ||
650 | char *hostdelim; | 608 | char *hostdelim; |
651 | servtab_t *sep; | 609 | servtab_t *sep; |
652 | servtab_t *nsep; | 610 | servtab_t *nsep; |
653 | new: | 611 | new: |
654 | sep = new_servtab(); | 612 | sep = new_servtab(); |
655 | more: | 613 | more: |
656 | while ((cp = next_line()) && *cp == '#') | 614 | argc = config_read(parser, token, 6+MAXARGV, 1, "# \t", PARSE_NORMAL); |
657 | continue; /* skip comment lines */ | 615 | if (!argc) { |
658 | if (cp == NULL) { | ||
659 | free(sep); | 616 | free(sep); |
660 | return NULL; | 617 | return NULL; |
661 | } | 618 | } |
662 | 619 | ||
663 | arg = next_word(&cp); | ||
664 | if (arg == NULL) /* a blank line. */ | ||
665 | goto more; | ||
666 | |||
667 | /* [host:]service socktype proto wait user[:group] prog [args] */ | 620 | /* [host:]service socktype proto wait user[:group] prog [args] */ |
668 | /* Check for "host:...." line */ | 621 | /* Check for "host:...." line */ |
622 | arg = token[0]; | ||
669 | hostdelim = strrchr(arg, ':'); | 623 | hostdelim = strrchr(arg, ':'); |
670 | if (hostdelim) { | 624 | if (hostdelim) { |
671 | *hostdelim = '\0'; | 625 | *hostdelim = '\0'; |
672 | sep->se_local_hostname = xstrdup(arg); | 626 | sep->se_local_hostname = xstrdup(arg); |
673 | arg = hostdelim + 1; | 627 | arg = hostdelim + 1; |
674 | if (*arg == '\0') { | 628 | if (*arg == '\0' && argc == 1) { |
675 | arg = next_word(&cp); | 629 | /* Line has just "host:", change the |
676 | if (arg == NULL) { | 630 | * default host for the following lines. */ |
677 | /* Line has just "host:", change the | 631 | free(default_local_hostname); |
678 | * default host for the following lines. */ | 632 | default_local_hostname = sep->se_local_hostname; |
679 | free(default_local_hostname); | 633 | goto more; |
680 | default_local_hostname = sep->se_local_hostname; | ||
681 | goto more; | ||
682 | } | ||
683 | } | 634 | } |
684 | } else | 635 | } else |
685 | sep->se_local_hostname = xstrdup(default_local_hostname); | 636 | sep->se_local_hostname = xstrdup(default_local_hostname); |
686 | 637 | ||
687 | /* service socktype proto wait user[:group] prog [args] */ | 638 | /* service socktype proto wait user[:group] prog [args] */ |
688 | sep->se_service = xstrdup(arg); | 639 | sep->se_service = xstrdup(arg); |
640 | |||
689 | /* socktype proto wait user[:group] prog [args] */ | 641 | /* socktype proto wait user[:group] prog [args] */ |
690 | arg = next_word(&cp); | 642 | if (argc < 6) { |
691 | if (arg == NULL) { | ||
692 | parse_err: | 643 | parse_err: |
693 | bb_error_msg("parse error on line %u, line is ignored", | 644 | bb_error_msg("parse error on line %u, line is ignored", |
694 | config_lineno); | 645 | parser->lineno); |
695 | free_servtab_strings(sep); | 646 | free_servtab_strings(sep); |
696 | /* Just "goto more" can make sep to carry over e.g. | 647 | /* Just "goto more" can make sep to carry over e.g. |
697 | * "rpc"-ness (by having se_rpcver_lo != 0). | 648 | * "rpc"-ness (by having se_rpcver_lo != 0). |
@@ -699,6 +650,7 @@ static NOINLINE servtab_t *parse_one_line(void) | |||
699 | free(sep); | 650 | free(sep); |
700 | goto new; | 651 | goto new; |
701 | } | 652 | } |
653 | |||
702 | { | 654 | { |
703 | static int8_t SOCK_xxx[] ALIGN1 = { | 655 | static int8_t SOCK_xxx[] ALIGN1 = { |
704 | -1, | 656 | -1, |
@@ -708,13 +660,11 @@ static NOINLINE servtab_t *parse_one_line(void) | |||
708 | sep->se_socktype = SOCK_xxx[1 + index_in_strings( | 660 | sep->se_socktype = SOCK_xxx[1 + index_in_strings( |
709 | "stream""\0" "dgram""\0" "rdm""\0" | 661 | "stream""\0" "dgram""\0" "rdm""\0" |
710 | "seqpacket""\0" "raw""\0" | 662 | "seqpacket""\0" "raw""\0" |
711 | , arg)]; | 663 | , token[1])]; |
712 | } | 664 | } |
713 | 665 | ||
714 | /* {unix,[rpc/]{tcp,udp}[6]} wait user[:group] prog [args] */ | 666 | /* {unix,[rpc/]{tcp,udp}[6]} wait user[:group] prog [args] */ |
715 | sep->se_proto = arg = xstrdup(next_word(&cp)); | 667 | sep->se_proto = arg = xstrdup(token[2]); |
716 | if (arg == NULL) | ||
717 | goto parse_err; | ||
718 | if (strcmp(arg, "unix") == 0) { | 668 | if (strcmp(arg, "unix") == 0) { |
719 | sep->se_family = AF_UNIX; | 669 | sep->se_family = AF_UNIX; |
720 | } else { | 670 | } else { |
@@ -773,9 +723,7 @@ static NOINLINE servtab_t *parse_one_line(void) | |||
773 | } | 723 | } |
774 | 724 | ||
775 | /* [no]wait[.max] user[:group] prog [args] */ | 725 | /* [no]wait[.max] user[:group] prog [args] */ |
776 | arg = next_word(&cp); | 726 | arg = token[3]; |
777 | if (arg == NULL) | ||
778 | goto parse_err; | ||
779 | sep->se_max = max_concurrency; | 727 | sep->se_max = max_concurrency; |
780 | p = strchr(arg, '.'); | 728 | p = strchr(arg, '.'); |
781 | if (p) { | 729 | if (p) { |
@@ -791,9 +739,7 @@ static NOINLINE servtab_t *parse_one_line(void) | |||
791 | goto parse_err; | 739 | goto parse_err; |
792 | 740 | ||
793 | /* user[:group] prog [args] */ | 741 | /* user[:group] prog [args] */ |
794 | sep->se_user = xstrdup(next_word(&cp)); | 742 | sep->se_user = xstrdup(token[4]); |
795 | if (sep->se_user == NULL) | ||
796 | goto parse_err; | ||
797 | arg = strchr(sep->se_user, '.'); | 743 | arg = strchr(sep->se_user, '.'); |
798 | if (arg == NULL) | 744 | if (arg == NULL) |
799 | arg = strchr(sep->se_user, ':'); | 745 | arg = strchr(sep->se_user, ':'); |
@@ -803,9 +749,7 @@ static NOINLINE servtab_t *parse_one_line(void) | |||
803 | } | 749 | } |
804 | 750 | ||
805 | /* prog [args] */ | 751 | /* prog [args] */ |
806 | sep->se_program = xstrdup(next_word(&cp)); | 752 | sep->se_program = xstrdup(token[5]); |
807 | if (sep->se_program == NULL) | ||
808 | goto parse_err; | ||
809 | #ifdef INETD_BUILTINS_ENABLED | 753 | #ifdef INETD_BUILTINS_ENABLED |
810 | if (strcmp(sep->se_program, "internal") == 0 | 754 | if (strcmp(sep->se_program, "internal") == 0 |
811 | && strlen(sep->se_service) <= 7 | 755 | && strlen(sep->se_service) <= 7 |
@@ -826,7 +770,7 @@ static NOINLINE servtab_t *parse_one_line(void) | |||
826 | } | 770 | } |
827 | #endif | 771 | #endif |
828 | argc = 0; | 772 | argc = 0; |
829 | while ((arg = next_word(&cp)) != NULL && argc < MAXARGV) | 773 | while ((arg = token[6+argc]) != NULL && argc < MAXARGV) |
830 | sep->se_argv[argc++] = xstrdup(arg); | 774 | sep->se_argv[argc++] = xstrdup(arg); |
831 | 775 | ||
832 | /* catch mixups. "<service> stream udp ..." == wtf */ | 776 | /* catch mixups. "<service> stream udp ..." == wtf */ |
@@ -839,6 +783,11 @@ static NOINLINE servtab_t *parse_one_line(void) | |||
839 | goto parse_err; | 783 | goto parse_err; |
840 | } | 784 | } |
841 | 785 | ||
786 | // bb_info_msg( | ||
787 | // "ENTRY[%s][%s][%s][%d][%d][%d][%d][%d][%s][%s][%s]", | ||
788 | // sep->se_local_hostname, sep->se_service, sep->se_proto, sep->se_wait, sep->se_proto_no, | ||
789 | // sep->se_max, sep->se_count, sep->se_time, sep->se_user, sep->se_group, sep->se_program); | ||
790 | |||
842 | /* check if the hostname specifier is a comma separated list | 791 | /* check if the hostname specifier is a comma separated list |
843 | * of hostnames. we'll make new entries for each address. */ | 792 | * of hostnames. we'll make new entries for each address. */ |
844 | while ((hostdelim = strrchr(sep->se_local_hostname, ',')) != NULL) { | 793 | while ((hostdelim = strrchr(sep->se_local_hostname, ',')) != NULL) { |