From 72e1a1ce186c39f07282398e2af9eb0253e60f15 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Thu, 19 Aug 2010 19:06:26 +0200 Subject: getserv: fix reading services lines w > 80 chars e.g. getservbyname() Signed-off-by: Bernhard Reutner-Fischer --- libc/inet/getservice.c | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'libc/inet/getservice.c') diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c index 03f5c29c3..47d26a262 100644 --- a/libc/inet/getservice.c +++ b/libc/inet/getservice.c @@ -35,6 +35,7 @@ __UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); static parser_t *servp = NULL; static struct servent serve; static char *servbuf = NULL; +static size_t servbuf_sz = SBUFSIZE; static smallint serv_stayopen; void setservent(int stayopen) @@ -64,11 +65,11 @@ libc_hidden_def(endservent) int getservent_r(struct servent *result_buf, char *buf, size_t buflen, struct servent **result) { - char **alias, *cp = NULL; + char **alias; char **serv_aliases; char **tok = NULL; const size_t aliaslen = sizeof(*serv_aliases) * MAXALIASES; - int ret = ERANGE; + int ret = ENOENT; *result = NULL; if (buflen < aliaslen @@ -76,31 +77,24 @@ int getservent_r(struct servent *result_buf, goto DONE_NOUNLOCK; __UCLIBC_MUTEX_LOCK(mylock); - ret = ENOENT; + if (servp == NULL) setservent(serv_stayopen); if (servp == NULL) goto DONE; + servp->data = buf; servp->data_len = aliaslen; servp->line_len = buflen - aliaslen; /* [[:space:]]/[[:space:]][] */ - if (!config_read(servp, &tok, 4, 3, "# \t/", PARSE_NORMAL)) { + if (!config_read(servp, &tok, MAXALIASES, 3, "# \t/", PARSE_NORMAL)) { + ret = ERANGE; goto DONE; } result_buf->s_name = *(tok++); result_buf->s_port = htons((u_short) atoi(*(tok++))); result_buf->s_proto = *(tok++); result_buf->s_aliases = alias = serv_aliases = tok; - cp = *alias; - while (cp && *cp) { - if (alias < &serv_aliases[MAXALIASES - 1]) - *alias++ = cp; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - } - *alias = NULL; *result = result_buf; ret = 0; DONE: @@ -113,19 +107,20 @@ libc_hidden_def(getservent_r) static void __initbuf(void) { - if (!servbuf) { - servbuf = malloc(SBUFSIZE); - if (!servbuf) - abort(); - } + if (servbuf) + servbuf_sz += BUFSZ; + servbuf = realloc(servbuf, servbuf_sz); + if (!servbuf) + abort(); } struct servent *getservent(void) { struct servent *result; - __initbuf(); - getservent_r(&serve, servbuf, SBUFSIZE, &result); + do { + __initbuf(); + } while (getservent_r(&serve, servbuf, servbuf_sz, &result) == ERANGE); return result; } @@ -160,8 +155,10 @@ struct servent *getservbyname(const char *name, const char *proto) { struct servent *result; - __initbuf(); - getservbyname_r(name, proto, &serve, servbuf, SBUFSIZE, &result); + do { + __initbuf(); + } while (getservbyname_r(name, proto, &serve, servbuf, servbuf_sz, &result) + == ERANGE); return result; } @@ -191,8 +188,10 @@ struct servent *getservbyport(int port, const char *proto) { struct servent *result; - __initbuf(); - getservbyport_r(port, proto, &serve, servbuf, SBUFSIZE, &result); + do { + __initbuf(); + } while (getservbyport_r(port, proto, &serve, servbuf, servbuf_sz, &result) + == ERANGE); return result; } libc_hidden_def(getservbyport) -- cgit v1.2.3