Redo getconfigent, save 150 bytes, still small memory leak when

parsing invalid entries.
This commit is contained in:
Glenn L McGrath 2004-01-20 15:32:39 +00:00
parent 348672d46d
commit eaf5bc0038

View File

@ -285,116 +285,110 @@ syslog_err_and_discard_dg(int se_socktype, const char *msg, ...)
_exit(1); _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 *getconfigent(void)
{ {
static struct servtab serv; static struct servtab serv;
struct servtab *sep = &serv; struct servtab *sep = &serv;
int argc; int argc;
char *cp = NULL; char *cp = NULL;
char *arg; char *cp_ptr;
more: char *cp_ptr_ptr = NULL;
do {
if (feof(fconfig)) {
return ((struct servtab *)0);
}
free(cp);
cp = bb_get_chomped_line_from_file(fconfig);
} while ((cp == NULL) || (*cp == '#'));
memset((char *)sep, 0, sizeof *sep); more:
sep->se_service = newstr(skip(&cp)); free(cp);
arg = skip(&cp); cp = bb_get_chomped_line_from_file(fconfig);
if (arg == NULL) { if (feof(fconfig)) {
free(cp);
return (NULL);
}
if ((cp == NULL) || (*cp == '#')) {
goto more; goto more;
} }
printf("line is %s\n", cp);
if (strcmp(arg, "stream") == 0) 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);
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; sep->se_socktype = SOCK_STREAM;
else if (strcmp(arg, "dgram") == 0) else if (strcmp(cp_ptr, "dgram") == 0)
sep->se_socktype = SOCK_DGRAM; sep->se_socktype = SOCK_DGRAM;
else if (strcmp(arg, "rdm") == 0) else if (strcmp(cp_ptr, "rdm") == 0)
sep->se_socktype = SOCK_RDM; sep->se_socktype = SOCK_RDM;
else if (strcmp(arg, "seqpacket") == 0) else if (strcmp(cp_ptr, "seqpacket") == 0)
sep->se_socktype = SOCK_SEQPACKET; sep->se_socktype = SOCK_SEQPACKET;
else if (strcmp(arg, "raw") == 0) else if (strcmp(cp_ptr, "raw") == 0)
sep->se_socktype = SOCK_RAW; sep->se_socktype = SOCK_RAW;
else else
sep->se_socktype = -1; sep->se_socktype = -1;
sep->se_proto = newstr(skip(&cp)); cp_ptr = strtok_r(NULL, " \t", &cp_ptr_ptr);
if (strcmp(sep->se_proto, "unix") == 0) { if (cp_ptr == NULL) {
printf("error\n");
/* error */
goto more;
}
if (strcmp(cp_ptr, "unix") == 0) {
sep->se_family = AF_UNIX; sep->se_family = AF_UNIX;
} else { } else {
sep->se_family = AF_INET; if (strncmp(cp_ptr, "rpc/", 4) == 0) {
if (strncmp(sep->se_proto, "rpc/", 4) == 0) {
syslog(LOG_ERR, "%s: rpc services not suported", syslog(LOG_ERR, "%s: rpc services not suported",
sep->se_service); sep->se_service);
goto more; goto more;
} }
sep->se_family = AF_INET;
} }
arg = skip(&cp); sep->se_proto = bb_xstrdup(cp_ptr);
if (arg == NULL) {
cp_ptr = strtok_r(NULL, " \t", &cp_ptr_ptr);
if (cp_ptr == NULL) {
printf("error\n");
/* error */
goto more; goto more;
} }
{ {
char *s = strchr(arg, '.'); char *s = strchr(cp_ptr, '.');
if (s) { if (s) {
*s++ = '\0'; *s++ = '\0';
sep->se_max = atoi(s); sep->se_max = atoi(s);
} else } else
sep->se_max = TOOMANY; sep->se_max = TOOMANY;
} }
sep->se_wait = strcmp(arg, "wait") == 0; sep->se_wait = strcmp(cp_ptr, "wait") == 0;
sep->se_user = newstr(skip(&cp));
sep->se_group = strchr(sep->se_user, '.'); cp_ptr = strtok_r(NULL, " \t", &cp_ptr_ptr);
if (sep->se_group) { if (cp_ptr == NULL) {
*sep->se_group++ = '\0'; printf("error\n");
/* error */
goto more;
} }
sep->se_server = newstr(skip(&cp)); {
if (strcmp(sep->se_server, "internal") == 0) { char *cp_ptr2 = strchr(cp_ptr, '.');
if (cp_ptr2) {
*cp_ptr2++ = '\0';
sep->se_group = bb_xstrdup(cp_ptr2);
}
}
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 #ifdef INETD_FEATURE_ENABLED
const struct biltin *bi; const struct biltin *bi;
@ -405,16 +399,14 @@ more:
} }
} }
if (bi->bi_service == 0) { if (bi->bi_service == 0) {
syslog(LOG_ERR, "internal service %s unknown", syslog(LOG_ERR, "internal service %s unknown", sep->se_service);
sep->se_service);
goto more; goto more;
} }
sep->se_bi = bi; sep->se_bi = bi;
sep->se_wait = bi->bi_wait; sep->se_wait = bi->bi_wait;
#else #else
syslog(LOG_ERR, "internal service %s unknown", syslog(LOG_ERR, "internal service %s unknown", cp_ptr);
sep->se_service); goto more;
goto more;
#endif #endif
} }
#ifdef INETD_FEATURE_ENABLED #ifdef INETD_FEATURE_ENABLED
@ -422,16 +414,19 @@ more:
sep->se_bi = NULL; sep->se_bi = NULL;
} }
#endif #endif
sep->se_server = bb_xstrdup(cp_ptr);
argc = 0; 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) { if (argc < MAXARGV) {
sep->se_argv[argc++] = newstr(arg); sep->se_argv[argc++] = cp_ptr;
} }
} }
while (argc <= MAXARGV) { while (argc <= MAXARGV) {
sep->se_argv[argc++] = NULL; sep->se_argv[argc++] = NULL;
} }
free(cp);
return (sep); return (sep);
} }