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 { unsigned max_concurrency; smallint alarm_armed; uid_t real_uid; /* user ID who ran us */ - unsigned config_lineno; const char *config_filename; - FILE *fconfig; + parser_t *parser; char *default_local_hostname; #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN char *end_ring; @@ -327,9 +326,8 @@ struct BUG_G_too_big { #define max_concurrency (G.max_concurrency) #define alarm_armed (G.alarm_armed ) #define real_uid (G.real_uid ) -#define config_lineno (G.config_lineno ) #define config_filename (G.config_filename) -#define fconfig (G.fconfig ) +#define parser (G.parser ) #define default_local_hostname (G.default_local_hostname) #define first_ps_byte (G.first_ps_byte ) #define last_ps_byte (G.last_ps_byte ) @@ -543,61 +541,20 @@ static int reopen_config_file(void) { free(default_local_hostname); default_local_hostname = xstrdup("*"); - if (fconfig != NULL) - fclose(fconfig); - config_lineno = 0; - fconfig = fopen_or_warn(config_filename, "r"); - return (fconfig != NULL); + if (parser != NULL) + config_close(parser); + parser = config_open(config_filename); + return (parser != NULL); } static void close_config_file(void) { - if (fconfig) { - fclose(fconfig); - fconfig = NULL; + if (parser) { + config_close(parser); + parser = NULL; } } -static char *next_line(void) -{ - if (fgets(line, LINE_SIZE, fconfig) == NULL) - return NULL; - config_lineno++; - *strchrnul(line, '\n') = '\0'; - return line; -} - -static char *next_word(char **cpp) -{ - char *start; - char *cp = *cpp; - - if (cp == NULL) - return NULL; - again: - while (*cp == ' ' || *cp == '\t') - cp++; - if (*cp == '\0') { - int c = getc(fconfig); - ungetc(c, fconfig); - if (c == ' ' || c == '\t') { - cp = next_line(); - if (cp) - goto again; - } - *cpp = NULL; - return NULL; - } - start = cp; - while (*cp && *cp != ' ' && *cp != '\t') - cp++; - if (*cp != '\0') - *cp++ = '\0'; - - *cpp = cp; - return start; -} - static void free_servtab_strings(servtab_t *cp) { int i; @@ -643,55 +600,49 @@ static servtab_t *dup_servtab(servtab_t *sep) } /* gcc generates much more code if this is inlined */ -static NOINLINE servtab_t *parse_one_line(void) +static servtab_t *parse_one_line(void) { int argc; - char *p, *cp, *arg; + char *token[6+MAXARGV]; + char *p, *arg; char *hostdelim; servtab_t *sep; servtab_t *nsep; new: sep = new_servtab(); more: - while ((cp = next_line()) && *cp == '#') - continue; /* skip comment lines */ - if (cp == NULL) { + argc = config_read(parser, token, 6+MAXARGV, 1, "# \t", PARSE_NORMAL); + if (!argc) { free(sep); return NULL; } - arg = next_word(&cp); - if (arg == NULL) /* a blank line. */ - goto more; - /* [host:]service socktype proto wait user[:group] prog [args] */ /* Check for "host:...." line */ + arg = token[0]; hostdelim = strrchr(arg, ':'); if (hostdelim) { *hostdelim = '\0'; sep->se_local_hostname = xstrdup(arg); arg = hostdelim + 1; - if (*arg == '\0') { - arg = next_word(&cp); - if (arg == NULL) { - /* Line has just "host:", change the - * default host for the following lines. */ - free(default_local_hostname); - default_local_hostname = sep->se_local_hostname; - goto more; - } + if (*arg == '\0' && argc == 1) { + /* Line has just "host:", change the + * default host for the following lines. */ + free(default_local_hostname); + default_local_hostname = sep->se_local_hostname; + goto more; } } else sep->se_local_hostname = xstrdup(default_local_hostname); /* service socktype proto wait user[:group] prog [args] */ sep->se_service = xstrdup(arg); + /* socktype proto wait user[:group] prog [args] */ - arg = next_word(&cp); - if (arg == NULL) { + if (argc < 6) { parse_err: bb_error_msg("parse error on line %u, line is ignored", - config_lineno); + parser->lineno); free_servtab_strings(sep); /* Just "goto more" can make sep to carry over e.g. * "rpc"-ness (by having se_rpcver_lo != 0). @@ -699,6 +650,7 @@ static NOINLINE servtab_t *parse_one_line(void) free(sep); goto new; } + { static int8_t SOCK_xxx[] ALIGN1 = { -1, @@ -708,13 +660,11 @@ static NOINLINE servtab_t *parse_one_line(void) sep->se_socktype = SOCK_xxx[1 + index_in_strings( "stream""\0" "dgram""\0" "rdm""\0" "seqpacket""\0" "raw""\0" - , arg)]; + , token[1])]; } /* {unix,[rpc/]{tcp,udp}[6]} wait user[:group] prog [args] */ - sep->se_proto = arg = xstrdup(next_word(&cp)); - if (arg == NULL) - goto parse_err; + sep->se_proto = arg = xstrdup(token[2]); if (strcmp(arg, "unix") == 0) { sep->se_family = AF_UNIX; } else { @@ -773,9 +723,7 @@ static NOINLINE servtab_t *parse_one_line(void) } /* [no]wait[.max] user[:group] prog [args] */ - arg = next_word(&cp); - if (arg == NULL) - goto parse_err; + arg = token[3]; sep->se_max = max_concurrency; p = strchr(arg, '.'); if (p) { @@ -791,9 +739,7 @@ static NOINLINE servtab_t *parse_one_line(void) goto parse_err; /* user[:group] prog [args] */ - sep->se_user = xstrdup(next_word(&cp)); - if (sep->se_user == NULL) - goto parse_err; + sep->se_user = xstrdup(token[4]); arg = strchr(sep->se_user, '.'); if (arg == NULL) arg = strchr(sep->se_user, ':'); @@ -803,9 +749,7 @@ static NOINLINE servtab_t *parse_one_line(void) } /* prog [args] */ - sep->se_program = xstrdup(next_word(&cp)); - if (sep->se_program == NULL) - goto parse_err; + sep->se_program = xstrdup(token[5]); #ifdef INETD_BUILTINS_ENABLED if (strcmp(sep->se_program, "internal") == 0 && strlen(sep->se_service) <= 7 @@ -826,7 +770,7 @@ static NOINLINE servtab_t *parse_one_line(void) } #endif argc = 0; - while ((arg = next_word(&cp)) != NULL && argc < MAXARGV) + while ((arg = token[6+argc]) != NULL && argc < MAXARGV) sep->se_argv[argc++] = xstrdup(arg); /* catch mixups. " stream udp ..." == wtf */ @@ -839,6 +783,11 @@ static NOINLINE servtab_t *parse_one_line(void) goto parse_err; } +// bb_info_msg( +// "ENTRY[%s][%s][%s][%d][%d][%d][%d][%d][%s][%s][%s]", +// sep->se_local_hostname, sep->se_service, sep->se_proto, sep->se_wait, sep->se_proto_no, +// sep->se_max, sep->se_count, sep->se_time, sep->se_user, sep->se_group, sep->se_program); + /* check if the hostname specifier is a comma separated list * of hostnames. we'll make new entries for each address. */ while ((hostdelim = strrchr(sep->se_local_hostname, ',')) != NULL) {