aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/inetd.c123
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
553static void close_config_file(void) 550static 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
561static 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
570static 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
601static void free_servtab_strings(servtab_t *cp) 558static 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 */
646static NOINLINE servtab_t *parse_one_line(void) 603static 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) {