diff options
author | Roland McGrath <roland@gnu.org> | 2002-11-19 06:41:14 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2002-11-19 06:41:14 +0000 |
commit | 0bf5c0507e1db5e551a9681533592c8829a12f9d (patch) | |
tree | 98a94b0992788213881ff276401df39d2895dd8e /resolv | |
parent | c27af28ef2e5eeb23cf894dfd8b35de6cfa69a32 (diff) | |
download | glibc-0bf5c0507e1db5e551a9681533592c8829a12f9d.tar.gz |
* sysdeps/hppa/fpu/libm-test-ulps: New file (generated).
* sysdeps/hppa/Makefile (CFLAGS-rtld.c): New variable.
Set -mdisable-fpregs for this file.
2002-11-11 Carlos O'Donell <carlos@baldric.uwo.ca>
* sysdeps/unix/sysv/linux/configure.in:
Make 2.4.19 minimum linux kernel for hppa, and add unwind symbols
from gcc-3.0 era for backwards compatibility.
* sysdeps/unix/sysv/linux/configure: Regenerate.
* sysdeps/unix/sysv/linux/hppa/sys/ucontext.h:
Define mcontext_t as a sigcontext.
* dlfcn/dlerror.c (fini): New function, __attribute__ ((destructor)).
Free memory in `last_result' if it was used.
* resolv/nss_dns/dns-network.c (getanswer_r): In BYNAME case, search
all aliases for one that matches the "<dotted-quad>.IN-ADDR.ARPA" form.
Do the parsing inline instead of copying strings and calling
inet_network, and properly skip all alias names not matching the form.
Diffstat (limited to 'resolv')
-rw-r--r-- | resolv/nss_dns/dns-network.c | 105 |
1 files changed, 66 insertions, 39 deletions
diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c index fdab996837..6ba66bac97 100644 --- a/resolv/nss_dns/dns-network.c +++ b/resolv/nss_dns/dns-network.c @@ -366,53 +366,80 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, if (have_answer) { - char *tmp; - int len; - char *in, *cp, *rp, *wp; - int cnt, first_flag; - *alias_pointer = NULL; switch (net_i) { case BYADDR: - result->n_name = result->n_aliases[0]; + result->n_name = *result->n_aliases++; result->n_net = 0L; - break; - case BYNAME: - len = strlen (result->n_aliases[0]); - tmp = (char *) alloca (len + 1); - tmp[len] = 0; - wp = &tmp[len - 1]; - - rp = in = result->n_aliases[0]; - result->n_name = ans; - - first_flag = 1; - for (cnt = 0; cnt < 4; ++cnt) - { - char *startp; + return NSS_STATUS_SUCCESS; - startp = rp; - while (*rp != '.') - ++rp; - if (rp - startp > 1 || *startp != '0' || !first_flag) - { - first_flag = 0; - if (cnt > 0) - *wp-- = '.'; - cp = rp; - while (cp > startp) - *wp-- = *--cp; - } - in = rp + 1; - } - - result->n_net = inet_network (wp); + case BYNAME: + { + char **ap = result->n_aliases++; + while (*ap != NULL) + { + /* Check each alias name for being of the forms: + 4.3.2.1.in-addr.arpa = net 1.2.3.4 + 3.2.1.in-addr.arpa = net 0.1.2.3 + 2.1.in-addr.arpa = net 0.0.1.2 + 1.in-addr.arpa = net 0.0.0.1 + */ + uint32_t val = 0; /* Accumulator for n_net value. */ + unsigned int shift = 0; /* Which part we are parsing now. */ + const char *p = *ap; /* Consuming the string. */ + do + { + /* Match the leading 0 or 0[xX] base indicator. */ + unsigned int base = 10; + if (*p == '0' && p[1] != '.') + { + base = 8; + ++p; + if (*p == 'x' || *p == 'X') + { + base = 16; + ++p; + if (*p == '.') + break; /* No digit here. Give up on alias. */ + } + if (*p == '\0') + break; + } + + uint32_t part = 0; /* Accumulates this part's number. */ + do + { + if (isdigit (*p) && (*p - '0' < base)) + part = (part * base) + (*p - '0'); + else if (base == 16 && isxdigit (*p)) + part = (part << 4) + 10 + (tolower (*p) - 'a'); + ++p; + } while (*p != '\0' && *p != '.'); + + if (*p != '.') + break; /* Bad form. Give up on this name. */ + + /* Install this as the next more significant byte. */ + val |= part << shift; + shift += 8; + ++p; + + /* If we are out of digits now, there are two cases: + 1. We are done with digits and now see "in-addr.arpa". + 2. This is not the droid we are looking for. */ + if (!isdigit (*p) && !strcasecmp (p, "in-addr.arpa")) + { + result->n_net = val; + return NSS_STATUS_SUCCESS; + } + + /* Keep going when we have seen fewer than 4 parts. */ + } while (shift < 32); + } + } break; } - - ++result->n_aliases; - return NSS_STATUS_SUCCESS; } __set_h_errno (TRY_AGAIN); |