Wed Jun 5 02:11:30 1996 Ulrich Drepper <drepper@cygnus.com>
authorroland <roland>
Wed, 5 Jun 1996 01:04:11 +0000 (01:04 +0000)
committerroland <roland>
Wed, 5 Jun 1996 01:04:11 +0000 (01:04 +0000)
* resolv/res_debug.c, resolv/resolv.h: Update from bind-4.3.4-T4A.

resolv/res_debug.c
resolv/resolv.h

index 4f55804..c2fefb4 100644 (file)
@@ -596,6 +596,15 @@ __p_rr(cp, msg, file)
                char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
 
                fprintf(file, "\t%s\n", inet_ntop(AF_INET6, cp, t, sizeof t));
+               cp += dlen;
+               break;
+       }
+
+       case T_LOC: {
+               char t[255];
+
+               (void) fprintf(file, "\t%s\n", loc_ntoa(cp, t));
+               cp += dlen;
                break;
        }
 
@@ -831,3 +840,385 @@ __p_time(value)
        }
        return (nbuf);
 }
+
+/*
+ * routines to convert between on-the-wire RR format and zone file format.
+ * Does not contain conversion to/from decimal degrees; divide or multiply
+ * by 60*60*1000 for that.
+ */
+
+static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
+                                     1000000,10000000,100000000,1000000000};
+
+/* takes an XeY precision/size value, returns a string representation. */
+static const char *
+precsize_ntoa(prec)
+       u_int8_t prec;
+{
+       static char retbuf[sizeof("90000000.00")];
+       unsigned long val;
+       int mantissa, exponent;
+
+       mantissa = (int)((prec >> 4) & 0x0f) % 10;
+       exponent = (int)((prec >> 0) & 0x0f) % 10;
+
+       val = mantissa * poweroften[exponent];
+
+       (void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);
+       return (retbuf);
+}
+
+/* converts ascii size/precision X * 10**Y(cm) to 0xXY.  moves pointer. */
+static u_int8_t
+precsize_aton(strptr)
+       char **strptr;
+{
+       unsigned int mval = 0, cmval = 0;
+       u_int8_t retval = 0;
+       register char *cp;
+       register int exponent;
+       register int mantissa;
+
+       cp = *strptr;
+
+       while (isdigit(*cp))
+               mval = mval * 10 + (*cp++ - '0');
+
+       if (*cp == '.') {               /* centimeters */
+               cp++;
+               if (isdigit(*cp)) {
+                       cmval = (*cp++ - '0') * 10;
+                       if (isdigit(*cp)) {
+                               cmval += (*cp++ - '0');
+                       }
+               }
+       }
+       cmval = (mval * 100) + cmval;
+
+       for (exponent = 0; exponent < 9; exponent++)
+               if (cmval < poweroften[exponent+1])
+                       break;
+
+       mantissa = cmval / poweroften[exponent];
+       if (mantissa > 9)
+               mantissa = 9;
+
+       retval = (mantissa << 4) | exponent;
+
+       *strptr = cp;
+
+       return (retval);
+}
+
+/* converts ascii lat/lon to unsigned encoded 32-bit number.  moves pointer. */
+static u_int32_t
+latlon2ul(latlonstrptr,which)
+       char **latlonstrptr;
+       int *which;
+{
+       register char *cp;
+       u_int32_t retval;
+       int deg = 0, min = 0, secs = 0, secsfrac = 0;
+
+       cp = *latlonstrptr;
+
+       while (isdigit(*cp))
+               deg = deg * 10 + (*cp++ - '0');
+
+       while (isspace(*cp))
+               cp++;
+
+       if (!(isdigit(*cp)))
+               goto fndhemi;
+
+       while (isdigit(*cp))
+               min = min * 10 + (*cp++ - '0');
+
+       while (isspace(*cp))
+               cp++;
+
+       if (!(isdigit(*cp)))
+               goto fndhemi;
+
+       while (isdigit(*cp))
+               secs = secs * 10 + (*cp++ - '0');
+
+       if (*cp == '.') {               /* decimal seconds */
+               cp++;
+               if (isdigit(*cp)) {
+                       secsfrac = (*cp++ - '0') * 100;
+                       if (isdigit(*cp)) {
+                               secsfrac += (*cp++ - '0') * 10;
+                               if (isdigit(*cp)) {
+                                       secsfrac += (*cp++ - '0');
+                               }
+                       }
+               }
+       }
+
+       while (!isspace(*cp))   /* if any trailing garbage */
+               cp++;
+
+       while (isspace(*cp))
+               cp++;
+
+ fndhemi:
+       switch (*cp) {
+       case 'N': case 'n':
+       case 'E': case 'e':
+               retval = ((unsigned)1<<31)
+                       + (((((deg * 60) + min) * 60) + secs) * 1000)
+                       + secsfrac;
+               break;
+       case 'S': case 's':
+       case 'W': case 'w':
+               retval = ((unsigned)1<<31)
+                       - (((((deg * 60) + min) * 60) + secs) * 1000)
+                       - secsfrac;
+               break;
+       default:
+               retval = 0;     /* invalid value -- indicates error */
+               break;
+       }
+
+       switch (*cp) {
+       case 'N': case 'n':
+       case 'S': case 's':
+               *which = 1;     /* latitude */
+               break;
+       case 'E': case 'e':
+       case 'W': case 'w':
+               *which = 2;     /* longitude */
+               break;
+       default:
+               *which = 0;     /* error */
+               break;
+       }
+
+       cp++;                   /* skip the hemisphere */
+
+       while (!isspace(*cp))   /* if any trailing garbage */
+               cp++;
+
+       while (isspace(*cp))    /* move to next field */
+               cp++;
+
+       *latlonstrptr = cp;
+
+       return (retval);
+}
+
+/* converts a zone file representation in a string to an RDATA on-the-wire
+ * representation. */
+int
+loc_aton(ascii, binary)
+       const char *ascii;
+       u_char *binary;
+{
+       const char *cp, *maxcp;
+       u_char *bcp;
+
+       u_int32_t latit = 0, longit = 0, alt = 0;
+       u_int32_t lltemp1 = 0, lltemp2 = 0;
+       int altmeters = 0, altfrac = 0, altsign = 1;
+       u_int8_t hp = 0x16;     /* default = 1e6 cm = 10000.00m = 10km */
+       u_int8_t vp = 0x13;     /* default = 1e3 cm = 10.00m */
+       u_int8_t siz = 0x12;    /* default = 1e2 cm = 1.00m */
+       int which1 = 0, which2 = 0;
+
+       cp = ascii;
+       maxcp = cp + strlen(ascii);
+
+       lltemp1 = latlon2ul(&cp, &which1);
+
+       lltemp2 = latlon2ul(&cp, &which2);
+
+       switch (which1 + which2) {
+       case 3:                 /* 1 + 2, the only valid combination */
+               if ((which1 == 1) && (which2 == 2)) { /* normal case */
+                       latit = lltemp1;
+                       longit = lltemp2;
+               } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
+                       longit = lltemp1;
+                       latit = lltemp2;
+               } else {        /* some kind of brokenness */
+                       return 0;
+               }
+               break;
+       default:                /* we didn't get one of each */
+               return 0;
+       }
+
+       /* altitude */
+       if (*cp == '-') {
+               altsign = -1;
+               cp++;
+       }
+
+       if (*cp == '+')
+               cp++;
+
+       while (isdigit(*cp))
+               altmeters = altmeters * 10 + (*cp++ - '0');
+
+       if (*cp == '.') {               /* decimal meters */
+               cp++;
+               if (isdigit(*cp)) {
+                       altfrac = (*cp++ - '0') * 10;
+                       if (isdigit(*cp)) {
+                               altfrac += (*cp++ - '0');
+                       }
+               }
+       }
+
+       alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
+
+       while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
+               cp++;
+
+       while (isspace(*cp) && (cp < maxcp))
+               cp++;
+
+       if (cp >= maxcp)
+               goto defaults;
+
+       siz = precsize_aton(&cp);
+
+       while (!isspace(*cp) && (cp < maxcp))   /* if trailing garbage or m */
+               cp++;
+
+       while (isspace(*cp) && (cp < maxcp))
+               cp++;
+
+       if (cp >= maxcp)
+               goto defaults;
+
+       hp = precsize_aton(&cp);
+
+       while (!isspace(*cp) && (cp < maxcp))   /* if trailing garbage or m */
+               cp++;
+
+       while (isspace(*cp) && (cp < maxcp))
+               cp++;
+
+       if (cp >= maxcp)
+               goto defaults;
+
+       vp = precsize_aton(&cp);
+
+ defaults:
+
+       bcp = binary;
+       *bcp++ = (u_int8_t) 0;  /* version byte */
+       *bcp++ = siz;
+       *bcp++ = hp;
+       *bcp++ = vp;
+       PUTLONG(latit,bcp);
+       PUTLONG(longit,bcp);
+       PUTLONG(alt,bcp);
+
+       return (16);            /* size of RR in octets */
+}
+
+/* takes an on-the-wire LOC RR and formats it in a human readable format. */
+char *
+loc_ntoa(binary, ascii)
+       const u_char *binary;
+       char *ascii;
+{
+       static char *error = "?";
+       register const u_char *cp = binary;
+
+       int latdeg, latmin, latsec, latsecfrac;
+       int longdeg, longmin, longsec, longsecfrac;
+       char northsouth, eastwest;
+       int altmeters, altfrac, altsign;
+
+       const int referencealt = 100000 * 100;
+
+       int32_t latval, longval, altval;
+       u_int32_t templ;
+       u_int8_t sizeval, hpval, vpval, versionval;
+
+       char *sizestr, *hpstr, *vpstr;
+
+       versionval = *cp++;
+
+       if (versionval) {
+               sprintf(ascii, "; error: unknown LOC RR version");
+               return (ascii);
+       }
+
+       sizeval = *cp++;
+
+       hpval = *cp++;
+       vpval = *cp++;
+
+       GETLONG(templ, cp);
+       latval = (templ - ((unsigned)1<<31));
+
+       GETLONG(templ, cp);
+       longval = (templ - ((unsigned)1<<31));
+
+       GETLONG(templ, cp);
+       if (templ < referencealt) { /* below WGS 84 spheroid */
+               altval = referencealt - templ;
+               altsign = -1;
+       } else {
+               altval = templ - referencealt;
+               altsign = 1;
+       }
+
+       if (latval < 0) {
+               northsouth = 'S';
+               latval = -latval;
+       } else
+               northsouth = 'N';
+
+       latsecfrac = latval % 1000;
+       latval = latval / 1000;
+       latsec = latval % 60;
+       latval = latval / 60;
+       latmin = latval % 60;
+       latval = latval / 60;
+       latdeg = latval;
+
+       if (longval < 0) {
+               eastwest = 'W';
+               longval = -longval;
+       } else
+               eastwest = 'E';
+
+       longsecfrac = longval % 1000;
+       longval = longval / 1000;
+       longsec = longval % 60;
+       longval = longval / 60;
+       longmin = longval % 60;
+       longval = longval / 60;
+       longdeg = longval;
+
+       altfrac = altval % 100;
+       altmeters = (altval / 100) * altsign;
+
+       if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
+               sizestr = error;
+       if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
+               hpstr = error;
+       if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
+               vpstr = error;
+
+       sprintf(ascii,
+             "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
+               latdeg, latmin, latsec, latsecfrac, northsouth,
+               longdeg, longmin, longsec, longsecfrac, eastwest,
+               altmeters, altfrac, sizestr, hpstr, vpstr);
+
+       if (sizestr != error)
+               free(sizestr);
+       if (hpstr != error)
+               free(hpstr);
+       if (vpstr != error)
+               free(vpstr);
+
+       return (ascii);
+}
index f4320ff..a0afb2c 100644 (file)
@@ -189,6 +189,8 @@ extern struct __res_state _res;
 #define        res_ownok       __res_ownok
 #define        res_mailok      __res_mailok
 #define        res_dnok        __res_dnok
+#define        loc_ntoa        __loc_ntoa
+#define        loc_aton        __loc_aton
 #define        dn_skipname     __dn_skipname
 #define        fp_query        __fp_query
 #define        fp_nquery       __fp_nquery
@@ -212,6 +214,8 @@ int  __res_hnok __P((const char *));
 int     __res_ownok __P((const char *));
 int     __res_mailok __P((const char *));
 int     __res_dnok __P((const char *));
+int     __loc_aton __P((const char *ascii, u_char *binary));
+char *  __loc_ntoa __P((const u_char *binary, char *ascii));
 int     __dn_skipname __P((const u_char *, const u_char *));
 void    __fp_resstat __P((struct __res_state *, FILE *));
 void    __fp_query __P((const u_char *, FILE *));