summaryrefslogtreecommitdiff
path: root/resolv
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-11-19 06:41:14 +0000
committerRoland McGrath <roland@gnu.org>2002-11-19 06:41:14 +0000
commit0bf5c0507e1db5e551a9681533592c8829a12f9d (patch)
tree98a94b0992788213881ff276401df39d2895dd8e /resolv
parentc27af28ef2e5eeb23cf894dfd8b35de6cfa69a32 (diff)
* 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.c105
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);