From eaf5bc003839fd5844db4a827b86b621f7084fad Mon Sep 17 00:00:00 2001 From: Glenn L McGrath Date: Tue, 20 Jan 2004 15:32:39 +0000 Subject: [PATCH] Redo getconfigent, save 150 bytes, still small memory leak when parsing invalid entries. --- networking/inetd.c | 155 ++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 80 deletions(-) diff --git a/networking/inetd.c b/networking/inetd.c index 1f2b339f0..eb61299c2 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -285,116 +285,110 @@ syslog_err_and_discard_dg(int se_socktype, const char *msg, ...) _exit(1); } -static char *skip(char **cpp) -{ - char *cp = *cpp; - char *start; - - if ((cpp == NULL) || (*cpp == NULL) || (**cpp == 0)) { - return (NULL); - } - -again: - while (*cp == ' ' || *cp == '\t') - cp++; - if (*cp == '\0') { - int c; - - c = getc(fconfig); - (void) ungetc(c, fconfig); - if (c == ' ' || c == '\t') - cp = bb_get_chomped_line_from_file(fconfig); - if (cp != NULL) - goto again; - *cpp = NULL; - return NULL; - } - start = cp; - while (*cp && *cp != ' ' && *cp != '\t') - cp++; - if (*cp != '\0') - *cp++ = '\0'; - *cpp = cp; - return (start); -} - -static char *newstr(char *cp) -{ - cp = strdup(cp ? cp : ""); - if (cp) - return(cp); - - syslog_err_and_discard_dg(SOCK_STREAM, "strdup: %m"); -} - - static struct servtab *getconfigent(void) { static struct servtab serv; struct servtab *sep = &serv; int argc; char *cp = NULL; - char *arg; + char *cp_ptr; + char *cp_ptr_ptr = NULL; + more: - do { - if (feof(fconfig)) { - return ((struct servtab *)0); - } + free(cp); + cp = bb_get_chomped_line_from_file(fconfig); + if (feof(fconfig)) { free(cp); - cp = bb_get_chomped_line_from_file(fconfig); - } while ((cp == NULL) || (*cp == '#')); + return (NULL); + } + if ((cp == NULL) || (*cp == '#')) { + goto more; + } + printf("line is %s\n", cp); - memset((char *)sep, 0, sizeof *sep); - sep->se_service = newstr(skip(&cp)); - arg = skip(&cp); - if (arg == NULL) { + cp_ptr = strtok_r(cp, " \t", &cp_ptr_ptr); + if (cp_ptr == NULL) { + printf("error\n"); + /* Error */ goto more; } + sep->se_service = bb_xstrdup(cp_ptr); - if (strcmp(arg, "stream") == 0) + cp_ptr = strtok_r(NULL, " \t", &cp_ptr_ptr); + if (cp_ptr == NULL) { + printf("error\n"); + /* Error */ + goto more; + } + if (strcmp(cp_ptr, "stream") == 0) sep->se_socktype = SOCK_STREAM; - else if (strcmp(arg, "dgram") == 0) + else if (strcmp(cp_ptr, "dgram") == 0) sep->se_socktype = SOCK_DGRAM; - else if (strcmp(arg, "rdm") == 0) + else if (strcmp(cp_ptr, "rdm") == 0) sep->se_socktype = SOCK_RDM; - else if (strcmp(arg, "seqpacket") == 0) + else if (strcmp(cp_ptr, "seqpacket") == 0) sep->se_socktype = SOCK_SEQPACKET; - else if (strcmp(arg, "raw") == 0) + else if (strcmp(cp_ptr, "raw") == 0) sep->se_socktype = SOCK_RAW; else sep->se_socktype = -1; - sep->se_proto = newstr(skip(&cp)); - if (strcmp(sep->se_proto, "unix") == 0) { + cp_ptr = strtok_r(NULL, " \t", &cp_ptr_ptr); + if (cp_ptr == NULL) { + printf("error\n"); + /* error */ + goto more; + } + if (strcmp(cp_ptr, "unix") == 0) { sep->se_family = AF_UNIX; } else { - sep->se_family = AF_INET; - if (strncmp(sep->se_proto, "rpc/", 4) == 0) { + if (strncmp(cp_ptr, "rpc/", 4) == 0) { syslog(LOG_ERR, "%s: rpc services not suported", sep->se_service); goto more; } + sep->se_family = AF_INET; } - arg = skip(&cp); - if (arg == NULL) { + sep->se_proto = bb_xstrdup(cp_ptr); + + cp_ptr = strtok_r(NULL, " \t", &cp_ptr_ptr); + if (cp_ptr == NULL) { + printf("error\n"); + /* error */ goto more; } { - char *s = strchr(arg, '.'); + char *s = strchr(cp_ptr, '.'); if (s) { *s++ = '\0'; sep->se_max = atoi(s); } else sep->se_max = TOOMANY; } - sep->se_wait = strcmp(arg, "wait") == 0; - sep->se_user = newstr(skip(&cp)); - sep->se_group = strchr(sep->se_user, '.'); - if (sep->se_group) { - *sep->se_group++ = '\0'; + sep->se_wait = strcmp(cp_ptr, "wait") == 0; + + cp_ptr = strtok_r(NULL, " \t", &cp_ptr_ptr); + if (cp_ptr == NULL) { + printf("error\n"); + /* error */ + goto more; + } + { + char *cp_ptr2 = strchr(cp_ptr, '.'); + if (cp_ptr2) { + *cp_ptr2++ = '\0'; + sep->se_group = bb_xstrdup(cp_ptr2); + } } - sep->se_server = newstr(skip(&cp)); - if (strcmp(sep->se_server, "internal") == 0) { + sep->se_user = bb_xstrdup(cp_ptr); + + cp_ptr = strtok_r(NULL, " \t", &cp_ptr_ptr); + if (cp_ptr == NULL) { + printf("error\n"); + /* error */ + goto more; + } + if (strcmp(cp_ptr, "internal") == 0) { #ifdef INETD_FEATURE_ENABLED const struct biltin *bi; @@ -405,16 +399,14 @@ more: } } if (bi->bi_service == 0) { - syslog(LOG_ERR, "internal service %s unknown", - sep->se_service); + syslog(LOG_ERR, "internal service %s unknown", sep->se_service); goto more; } sep->se_bi = bi; sep->se_wait = bi->bi_wait; #else - syslog(LOG_ERR, "internal service %s unknown", - sep->se_service); - goto more; + syslog(LOG_ERR, "internal service %s unknown", cp_ptr); + goto more; #endif } #ifdef INETD_FEATURE_ENABLED @@ -422,16 +414,19 @@ more: sep->se_bi = NULL; } #endif + sep->se_server = bb_xstrdup(cp_ptr); + argc = 0; - for (arg = skip(&cp); cp && arg; arg = skip(&cp)) { + while ((cp_ptr = strtok_r(NULL, " \t", &cp_ptr_ptr)) != NULL) { if (argc < MAXARGV) { - sep->se_argv[argc++] = newstr(arg); + sep->se_argv[argc++] = cp_ptr; } } while (argc <= MAXARGV) { sep->se_argv[argc++] = NULL; } + free(cp); return (sep); } -- 2.25.1