|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that this notice is preserved and that due credit is given ! 7: * to the University of California at Berkeley. The name of the University ! 8: * may not be used to endorse or promote products derived from this ! 9: * software without specific prior written permission. This software ! 10: * is provided ``as is'' without express or implied warranty. ! 11: */ ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)getinfo.c 5.16 (Berkeley) 3/11/88"; ! 15: #endif /* not lint */ ! 16: ! 17: /* ! 18: ******************************************************************************* ! 19: * ! 20: * getinfo.c -- ! 21: * ! 22: * Routines to create requests to name servers ! 23: * and interpret the answers. ! 24: * ! 25: * Adapted from 4.3BSD BIND gethostnamadr.c ! 26: * ! 27: ******************************************************************************* ! 28: */ ! 29: ! 30: #include <sys/types.h> ! 31: #include <sys/socket.h> ! 32: #include <netinet/in.h> ! 33: #include <stdio.h> ! 34: #include <ctype.h> ! 35: #include <arpa/nameser.h> ! 36: #include <resolv.h> ! 37: #include "res.h" ! 38: ! 39: extern char *_res_resultcodes[]; ! 40: extern char *res_skip(); ! 41: ! 42: #define MAXALIASES 35 ! 43: #define MAXADDRS 35 ! 44: #define MAXDOMAINS 35 ! 45: #define MAXSERVERS 10 ! 46: ! 47: static char *addr_list[MAXADDRS + 1]; ! 48: ! 49: static char *host_aliases[MAXALIASES]; ! 50: static int host_aliases_len[MAXALIASES]; ! 51: static char hostbuf[BUFSIZ+1]; ! 52: ! 53: typedef struct { ! 54: char *name; ! 55: char *domain[MAXDOMAINS]; ! 56: int numDomains; ! 57: char *address[MAXADDRS]; ! 58: int numAddresses; ! 59: } ServerTable; ! 60: ! 61: ServerTable server[MAXSERVERS]; ! 62: ! 63: typedef union { ! 64: HEADER qb1; ! 65: char qb2[PACKETSZ]; ! 66: } querybuf; ! 67: ! 68: static union { ! 69: long al; ! 70: char ac; ! 71: } align; ! 72: ! 73: ! 74: /* ! 75: ******************************************************************************* ! 76: * ! 77: * GetAnswer -- ! 78: * ! 79: * Interprets an answer packet and retrieves the following ! 80: * information: ! 81: * ! 82: * Results: ! 83: * SUCCESS the info was retrieved. ! 84: * NO_INFO the packet did not contain an answer. ! 85: * NONAUTH non-authoritative information was found. ! 86: * ERROR the answer was malformed. ! 87: * Other errors returned in the packet header. ! 88: * ! 89: ******************************************************************************* ! 90: */ ! 91: ! 92: static int ! 93: GetAnswer(nsAddrPtr, queryType, msg, msglen, iquery, hostPtr, isserver) ! 94: struct in_addr *nsAddrPtr; ! 95: char *msg; ! 96: int queryType; ! 97: int msglen; ! 98: int iquery; ! 99: register HostInfo *hostPtr; ! 100: int isserver; ! 101: { ! 102: register HEADER *headerPtr; ! 103: register char *cp; ! 104: querybuf answer; ! 105: char *eom, *bp, **aliasPtr; ! 106: char **addrPtr; ! 107: char *namePtr; ! 108: char *dnamePtr; ! 109: int type, class; ! 110: int qdcount, ancount, arcount, nscount, buflen; ! 111: int haveanswer, getclass; ! 112: int numAliases = 0; ! 113: int numAddresses = 0; ! 114: int n, i, j; ! 115: int len; ! 116: int dlen; ! 117: int status; ! 118: int numServers; ! 119: int found; ! 120: ! 121: ! 122: /* ! 123: * If the hostPtr was used before, free up ! 124: * the calloc'd areas. ! 125: */ ! 126: FreeHostInfoPtr(hostPtr); ! 127: ! 128: status = SendRequest(nsAddrPtr, msg, msglen, (char *) &answer, ! 129: sizeof(answer), &n, !isserver); ! 130: ! 131: if (status != SUCCESS) { ! 132: if (_res.options & RES_DEBUG2) ! 133: printf("SendRequest failed\n"); ! 134: return (status); ! 135: } ! 136: eom = (char *) &answer + n; ! 137: ! 138: headerPtr = (HEADER *) &answer; ! 139: qdcount = ntohs(headerPtr->qdcount); ! 140: ancount = ntohs(headerPtr->ancount); ! 141: arcount = ntohs(headerPtr->arcount); ! 142: nscount = ntohs(headerPtr->nscount); ! 143: ! 144: if (headerPtr->rcode != NOERROR) { ! 145: if (_res.options & RES_DEBUG && !isserver) { ! 146: printf( ! 147: "Failed: %s, num. answers = %d, ns = %d, additional = %d\n", ! 148: _res_resultcodes[headerPtr->rcode], ancount, nscount, ! 149: arcount); ! 150: } ! 151: return (headerPtr->rcode); ! 152: } ! 153: ! 154: /* ! 155: * If there are no answer, n.s. or additional records ! 156: * then return with an error. ! 157: */ ! 158: if (ancount == 0 && nscount == 0 && arcount == 0) { ! 159: return (NO_INFO); ! 160: } ! 161: ! 162: ! 163: bp = hostbuf; ! 164: buflen = sizeof(hostbuf); ! 165: cp = (char *) &answer + sizeof(HEADER); ! 166: ! 167: /* ! 168: * For inverse queries, the desired information is returned ! 169: * in the question section. If there are no question records, ! 170: * return with an error. ! 171: * ! 172: */ ! 173: if (qdcount) { ! 174: if (iquery) { ! 175: if ((n = dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0) { ! 176: return (ERROR); ! 177: } ! 178: cp += n + QFIXEDSZ; ! 179: len = strlen(bp) + 1; ! 180: hostPtr->name = Calloc((unsigned)1, (unsigned)len); ! 181: bcopy(bp, hostPtr->name, len); ! 182: } else { ! 183: cp += dn_skipname(cp, eom) + QFIXEDSZ; ! 184: } ! 185: while (--qdcount > 0) { ! 186: cp += dn_skipname(cp, eom) + QFIXEDSZ; ! 187: } ! 188: } else if (iquery) { ! 189: return (NO_INFO); ! 190: } ! 191: ! 192: aliasPtr = host_aliases; ! 193: addrPtr = addr_list; ! 194: haveanswer = 0; ! 195: ! 196: /* ! 197: * Scan through the answer resource records. ! 198: * Answers for address query types are saved. ! 199: * Other query type answers are just printed. ! 200: */ ! 201: if (isserver == 0 && !headerPtr->aa && headerPtr->ancount) ! 202: printf("Non-authoritative answer:\n"); ! 203: while (--ancount >= 0 && cp < eom) { ! 204: if (queryType != T_A) { ! 205: if ((cp = Print_rr(cp, (char *) &answer, eom, stdout)) == NULL) { ! 206: return(ERROR); ! 207: } ! 208: continue; ! 209: } else { ! 210: if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) { ! 211: return(ERROR); ! 212: } ! 213: cp += n; ! 214: type = _getshort(cp); ! 215: cp += sizeof(u_short); ! 216: class = _getshort(cp); ! 217: cp += sizeof(u_short) + sizeof(u_long); ! 218: dlen = _getshort(cp); ! 219: cp += sizeof(u_short); ! 220: if (type == T_CNAME) { ! 221: /* ! 222: * Found an alias. ! 223: */ ! 224: cp += dlen; ! 225: if (aliasPtr >= &host_aliases[MAXALIASES-1]) ! 226: continue; ! 227: *aliasPtr++ = bp; ! 228: n = strlen(bp) + 1; ! 229: host_aliases_len[numAliases] = n; ! 230: numAliases++; ! 231: bp += n; ! 232: buflen -= n; ! 233: continue; ! 234: } else if (type == T_PTR) { ! 235: /* ! 236: * Found a "pointer" to the real name. ! 237: */ ! 238: if((n= dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0){ ! 239: cp += n; ! 240: continue; ! 241: } ! 242: cp += n; ! 243: len = strlen(bp) + 1; ! 244: hostPtr->name = Calloc((unsigned)1, (unsigned)len); ! 245: bcopy(bp, hostPtr->name, len); ! 246: haveanswer = 1; ! 247: break; ! 248: } else if (type != T_A) { ! 249: cp += dlen; ! 250: continue; ! 251: } ! 252: if (haveanswer) { ! 253: if (n != hostPtr->addrLen) { ! 254: cp += dlen; ! 255: continue; ! 256: } ! 257: if (class != getclass) { ! 258: cp += dlen; ! 259: continue; ! 260: } ! 261: } else { ! 262: hostPtr->addrLen = dlen; ! 263: getclass = class; ! 264: hostPtr->addrType = (class == C_IN) ? AF_INET : AF_UNSPEC; ! 265: if (!iquery) { ! 266: len = strlen(bp) + 1; ! 267: hostPtr->name = Calloc((unsigned)1, (unsigned)len); ! 268: bcopy(bp, hostPtr->name, len); ! 269: } ! 270: } ! 271: bp += (((u_long)bp) % sizeof(align)); ! 272: ! 273: if (bp + dlen >= &hostbuf[sizeof(hostbuf)]) { ! 274: if (_res.options & RES_DEBUG) ! 275: printf("Size (%d) too big\n", dlen); ! 276: break; ! 277: } ! 278: bcopy(cp, *addrPtr++ = bp, dlen); ! 279: bp +=dlen; ! 280: cp += dlen; ! 281: numAddresses++; ! 282: haveanswer = 1; ! 283: } ! 284: } ! 285: ! 286: if (queryType == T_A && haveanswer) { ! 287: ! 288: /* ! 289: * Go through the alias and address lists and return them ! 290: * in the hostPtr variable. ! 291: */ ! 292: ! 293: if (numAliases > 0) { ! 294: hostPtr->aliases = (char **) Calloc((unsigned)1+numAliases, ! 295: sizeof(char *)); ! 296: for (i = 0; i < numAliases; i++) { ! 297: hostPtr->aliases[i] = Calloc((unsigned)1, (unsigned)host_aliases_len[i]); ! 298: bcopy(host_aliases[i], hostPtr->aliases[i], ! 299: host_aliases_len[i]); ! 300: } ! 301: hostPtr->aliases[i] = NULL; ! 302: } ! 303: if (numAddresses > 0) { ! 304: hostPtr->addrList = (char **) Calloc((unsigned)1+numAddresses, ! 305: sizeof(char *)); ! 306: for (i = 0; i < numAddresses; i++) { ! 307: hostPtr->addrList[i] = Calloc((unsigned)1, (unsigned)hostPtr->addrLen); ! 308: bcopy(addr_list[i], hostPtr->addrList[i], ! 309: hostPtr->addrLen); ! 310: } ! 311: hostPtr->addrList[i] = NULL; ! 312: } ! 313: hostPtr->servers= NULL; ! 314: return (SUCCESS); ! 315: } ! 316: ! 317: /* ! 318: * At this point, for the T_A query type, only empty answers remain. ! 319: * For other query types, additional information might be found ! 320: * in the additional resource records part. ! 321: */ ! 322: ! 323: cp = res_skip((char *) &answer, 2, eom); ! 324: ! 325: numServers = 0; ! 326: while (--nscount >= 0 && cp < eom) { ! 327: /* ! 328: * Go through the NS records and retrieve the ! 329: * names of hosts that server the requested domain, ! 330: * their addresses and other domains they might serve. ! 331: */ ! 332: ! 333: if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) { ! 334: return(ERROR); ! 335: } ! 336: cp += n; ! 337: len = strlen(bp) + 1; ! 338: dnamePtr = Calloc((unsigned)1, (unsigned)len); /* domain name */ ! 339: bcopy(bp, dnamePtr, len); ! 340: ! 341: type = _getshort(cp); ! 342: cp += sizeof(u_short); ! 343: class = _getshort(cp); ! 344: cp += sizeof(u_short) + sizeof(u_long); ! 345: dlen = _getshort(cp); ! 346: cp += sizeof(u_short); ! 347: ! 348: if (type != T_NS) { ! 349: cp += dlen; ! 350: } else { ! 351: if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) { ! 352: return(ERROR); ! 353: } ! 354: cp += n; ! 355: len = strlen(bp) + 1; ! 356: namePtr = Calloc((unsigned)1, (unsigned)len); /* server host name */ ! 357: bcopy(bp, namePtr, len); ! 358: ! 359: /* ! 360: * Store the information keyed by the server host name. ! 361: */ ! 362: found = FALSE; ! 363: for (j = 0; j < numServers; j++) { ! 364: if (strcmp(namePtr, server[j].name) == 0) { ! 365: found = TRUE; ! 366: free(namePtr); ! 367: break; ! 368: } ! 369: } ! 370: if (found) { ! 371: server[j].numDomains++; ! 372: if (server[j].numDomains <= MAXDOMAINS) { ! 373: server[j].domain[server[j].numDomains-1] = dnamePtr; ! 374: } ! 375: } else { ! 376: if (numServers > MAXSERVERS) { ! 377: break; ! 378: } ! 379: numServers++; ! 380: server[numServers -1].name = namePtr; ! 381: server[numServers -1].domain[0] = dnamePtr; ! 382: server[numServers -1].numDomains = 1; ! 383: server[numServers -1].numAddresses = 0; ! 384: } ! 385: } ! 386: } ! 387: ! 388: if (!headerPtr->aa && (queryType != T_A) && arcount > 0) { ! 389: printf("Authoritative answers can be found from:\n"); ! 390: } ! 391: ! 392: /* ! 393: * Additional resource records contain addresses of ! 394: * servers. ! 395: */ ! 396: cp = res_skip((char *) &answer, 3, eom); ! 397: while (--arcount >= 0 && cp < eom) { ! 398: /* ! 399: * If we don't need to save the record, just print it. ! 400: */ ! 401: if (queryType != T_A) { ! 402: if ((cp = Print_rr(cp, (char *) &answer, eom, stdout)) == NULL) { ! 403: return(ERROR); ! 404: } ! 405: continue; ! 406: ! 407: } else { ! 408: if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) ! 409: break; ! 410: cp += n; ! 411: type = _getshort(cp); ! 412: cp += sizeof(u_short); ! 413: class = _getshort(cp); ! 414: cp += sizeof(u_short) + sizeof(u_long); ! 415: dlen = _getshort(cp); ! 416: cp += sizeof(u_short); ! 417: ! 418: if (type != T_A) { ! 419: cp += dlen; ! 420: continue; ! 421: } else { ! 422: for (j = 0; j < numServers; j++) { ! 423: if (strcmp(bp, server[j].name) == 0) { ! 424: server[j].numAddresses++; ! 425: if (server[j].numAddresses <= MAXADDRS) { ! 426: server[j].address[server[j].numAddresses-1]=Calloc((unsigned)1,(unsigned)dlen); ! 427: bcopy(cp,server[j].address[server[j].numAddresses-1],dlen); ! 428: break; ! 429: } ! 430: } ! 431: } ! 432: cp += dlen; ! 433: } ! 434: } ! 435: } ! 436: ! 437: /* ! 438: * If we are returning name server info, transfer it to ! 439: * the hostPtr. ! 440: * ! 441: */ ! 442: if (numServers > 0) { ! 443: hostPtr->servers = (ServerInfo **) Calloc((unsigned)numServers+1, ! 444: sizeof(ServerInfo *)); ! 445: for (i = 0; i < numServers; i++) { ! 446: hostPtr->servers[i] = (ServerInfo *) Calloc((unsigned)1, sizeof(ServerInfo)); ! 447: hostPtr->servers[i]->name = server[i].name; ! 448: ! 449: ! 450: hostPtr->servers[i]->domains = (char **) ! 451: Calloc((unsigned)server[i].numDomains+1,sizeof(char *)); ! 452: for (j = 0; j < server[i].numDomains; j++) { ! 453: hostPtr->servers[i]->domains[j] = server[i].domain[j]; ! 454: } ! 455: hostPtr->servers[i]->domains[j] = NULL; ! 456: ! 457: ! 458: hostPtr->servers[i]->addrList = (char **) ! 459: Calloc((unsigned)server[i].numAddresses+1,sizeof(char *)); ! 460: for (j = 0; j < server[i].numAddresses; j++) { ! 461: hostPtr->servers[i]->addrList[j] = server[i].address[j]; ! 462: } ! 463: hostPtr->servers[i]->addrList[j] = NULL; ! 464: ! 465: } ! 466: hostPtr->servers[i] = NULL; ! 467: } ! 468: ! 469: ! 470: if (queryType != T_A) { ! 471: return(SUCCESS); ! 472: } else { ! 473: return(NONAUTH); ! 474: } ! 475: } ! 476: ! 477: /* ! 478: ******************************************************************************* ! 479: * ! 480: * GetHostInfo -- ! 481: * ! 482: * Retrieves host name, address and alias information ! 483: * for a domain. ! 484: * ! 485: * Results: ! 486: * ERROR - res_mkquery failed. ! 487: * + return values from GetAnswer() ! 488: * ! 489: ******************************************************************************* ! 490: */ ! 491: ! 492: int ! 493: GetHostInfo(nsAddrPtr, queryClass, queryType, name, hostPtr, isserver) ! 494: struct in_addr *nsAddrPtr; ! 495: int queryClass; ! 496: int queryType; ! 497: char *name; ! 498: HostInfo *hostPtr; ! 499: int isserver; ! 500: { ! 501: int n; ! 502: int result; ! 503: register char *cp, **domain; ! 504: querybuf buf; ! 505: extern char *Calloc(), *hostalias(); ! 506: ! 507: /* catch explicit addresses */ ! 508: if (isdigit(*name) && (queryType == T_A)) { ! 509: long ina; ! 510: ! 511: ina = inet_addr(name); ! 512: ! 513: if (ina == -1) ! 514: return(ERROR); ! 515: ! 516: hostPtr->name = Calloc((unsigned)strlen(name)+3,1); ! 517: (void)sprintf(hostPtr->name,"[%s]",name); ! 518: hostPtr->aliases = 0; ! 519: hostPtr->servers = 0; ! 520: hostPtr->addrType = AF_INET; ! 521: hostPtr->addrLen = 4; ! 522: hostPtr->addrList = (char **)Calloc((unsigned)2,sizeof(char *)); ! 523: hostPtr->addrList[0] = Calloc(sizeof(long),sizeof(char)); ! 524: bcopy((char *)&ina,hostPtr->addrList[0],sizeof(ina)); ! 525: hostPtr->addrList[1] = 0; ! 526: ! 527: return(SUCCESS); ! 528: } ! 529: ! 530: for (cp = name, n = 0; *cp; cp++) ! 531: if (*cp == '.') ! 532: n++; ! 533: if ((n && *--cp == '.') || ! 534: (isserver == 0 && (_res.options & RES_DEFNAMES) == 0)) { ! 535: int defflag = _res.options & RES_DEFNAMES; ! 536: ! 537: _res.options &= ~RES_DEFNAMES; ! 538: if (n && *cp == '.') ! 539: *cp = 0; ! 540: result = GetHostDomain(nsAddrPtr, queryClass, queryType, ! 541: name, (char *)NULL, hostPtr, isserver); ! 542: if (n && *cp == 0) ! 543: *cp = '.'; ! 544: if (defflag) ! 545: _res.options |= RES_DEFNAMES; ! 546: return (result); ! 547: } ! 548: if (n == 0 && (cp = hostalias(name))) ! 549: return (GetHostDomain(nsAddrPtr, queryClass, queryType, ! 550: cp, (char *)NULL, hostPtr, isserver)); ! 551: for (domain = _res.dnsrch; *domain; domain++) { ! 552: result = GetHostDomain(nsAddrPtr, queryClass, queryType, ! 553: name, *domain, hostPtr, isserver); ! 554: if ((result != NXDOMAIN && result != NO_INFO) || ! 555: (_res.options & RES_DNSRCH) == 0) ! 556: return (result); ! 557: } ! 558: if (n) ! 559: return (GetHostDomain(nsAddrPtr, queryClass, queryType, ! 560: name, (char *)NULL, hostPtr, isserver)); ! 561: return (result); ! 562: } ! 563: ! 564: GetHostDomain(nsAddrPtr, queryClass, queryType, name, domain, hostPtr, isserver) ! 565: struct in_addr *nsAddrPtr; ! 566: int queryClass; ! 567: int queryType; ! 568: char *name, *domain; ! 569: HostInfo *hostPtr; ! 570: int isserver; ! 571: { ! 572: querybuf buf; ! 573: char nbuf[2*MAXDNAME+2]; ! 574: int n; ! 575: ! 576: if (domain) { ! 577: (void)sprintf(nbuf, "%.*s.%.*s", ! 578: MAXDNAME, name, MAXDNAME, domain); ! 579: name = nbuf; ! 580: } ! 581: n = res_mkquery(QUERY, name, queryClass, queryType, ! 582: (char *)0, 0, (char *)0, (char *) &buf, sizeof(buf)); ! 583: if (n < 0) { ! 584: if (_res.options & RES_DEBUG) { ! 585: printf("Res_mkquery failed\n"); ! 586: } ! 587: return (ERROR); ! 588: } ! 589: ! 590: n = GetAnswer(nsAddrPtr, queryType, (char *) &buf, n, 0, hostPtr, ! 591: isserver); ! 592: ! 593: /* ! 594: * GetAnswer didn't find a name, so set it to the specified one. ! 595: */ ! 596: if (n == NONAUTH) { ! 597: if (hostPtr->name == NULL) { ! 598: int len = strlen(name) + 1; ! 599: hostPtr->name = Calloc((unsigned)len, sizeof(char)); ! 600: bcopy(name, hostPtr->name, len); ! 601: } ! 602: } ! 603: return(n); ! 604: } ! 605: ! 606: ! 607: /* ! 608: ******************************************************************************* ! 609: * ! 610: * FindHostInfo -- ! 611: * ! 612: * Performs an inverse query to find the host name ! 613: * that corresponds to the given address. ! 614: * ! 615: * Results: ! 616: * ERROR - res_mkquery failed. ! 617: * + return values from GetAnswer() ! 618: * ! 619: ******************************************************************************* ! 620: */ ! 621: ! 622: int ! 623: FindHostInfo(nsAddrPtr, address, len, hostPtr) ! 624: struct in_addr *nsAddrPtr; ! 625: struct in_addr *address; ! 626: int len; ! 627: HostInfo *hostPtr; ! 628: { ! 629: int n; ! 630: querybuf buf; ! 631: ! 632: n = res_mkquery(IQUERY, (char *)0, C_IN, T_A, ! 633: (char *)address, len, (char *)0, (char *) &buf, sizeof(buf)); ! 634: if (n < 0) { ! 635: if (_res.options & RES_DEBUG) { ! 636: printf("Res_mkquery failed\n"); ! 637: } ! 638: return (ERROR); ! 639: } ! 640: return(GetAnswer(nsAddrPtr, T_A, (char *) &buf, n, 1, hostPtr, 1)); ! 641: } ! 642: ! 643: /* ! 644: ******************************************************************************* ! 645: * ! 646: * FreeHostInfoPtr -- ! 647: * ! 648: * Deallocates all the calloc'd areas for a HostInfo ! 649: * variable. ! 650: * ! 651: ******************************************************************************* ! 652: */ ! 653: ! 654: void ! 655: FreeHostInfoPtr(hostPtr) ! 656: HostInfo *hostPtr; ! 657: { ! 658: int i, j; ! 659: ! 660: if (hostPtr->name != NULL) { ! 661: free(hostPtr->name); ! 662: hostPtr->name = NULL; ! 663: } ! 664: ! 665: if (hostPtr->aliases != NULL) { ! 666: i = 0; ! 667: while (hostPtr->aliases[i] != NULL) { ! 668: free(hostPtr->aliases[i]); ! 669: i++; ! 670: } ! 671: free((char *)hostPtr->aliases); ! 672: hostPtr->aliases = NULL; ! 673: } ! 674: ! 675: if (hostPtr->addrList != NULL) { ! 676: i = 0; ! 677: while (hostPtr->addrList[i] != NULL) { ! 678: free(hostPtr->addrList[i]); ! 679: i++; ! 680: } ! 681: free((char *)hostPtr->addrList); ! 682: hostPtr->addrList = NULL; ! 683: } ! 684: ! 685: if (hostPtr->servers != NULL) { ! 686: i = 0; ! 687: while (hostPtr->servers[i] != NULL) { ! 688: ! 689: if (hostPtr->servers[i]->name != NULL) { ! 690: free(hostPtr->servers[i]->name); ! 691: } ! 692: ! 693: if (hostPtr->servers[i]->domains != NULL) { ! 694: j = 0; ! 695: while (hostPtr->servers[i]->domains[j] != NULL) { ! 696: free(hostPtr->servers[i]->domains[j]); ! 697: j++; ! 698: } ! 699: free((char *)hostPtr->servers[i]->domains); ! 700: } ! 701: ! 702: if (hostPtr->servers[i]->addrList != NULL) { ! 703: j = 0; ! 704: while (hostPtr->servers[i]->addrList[j] != NULL) { ! 705: free(hostPtr->servers[i]->addrList[j]); ! 706: j++; ! 707: } ! 708: free((char *)hostPtr->servers[i]->addrList); ! 709: } ! 710: free((char *)hostPtr->servers[i]); ! 711: i++; ! 712: } ! 713: free((char *)hostPtr->servers); ! 714: hostPtr->servers = NULL; ! 715: } ! 716: } ! 717: ! 718: /* ! 719: ******************************************************************************* ! 720: * ! 721: * GetHostList -- ! 722: * ! 723: * Performs a completion query when given an incomplete ! 724: * name. ! 725: * ! 726: * Still under development. ! 727: * ! 728: ******************************************************************************* ! 729: */ ! 730: ! 731: #if notdef ! 732: ! 733: int ! 734: GetHostList(nsAddrPtr, queryType, name, defaultName, hostPtr) ! 735: struct in_addr *nsAddrPtr; ! 736: int queryType; ! 737: char *name, *defaultName; ! 738: HostInfo *hostPtr; ! 739: { ! 740: int n; ! 741: querybuf buf; ! 742: ! 743: n = res_mkquery(CQUERYM, name, C_IN, T_A, defaultName, 0, (char *)0, ! 744: (char *) &buf, sizeof(buf)); ! 745: if (n < 0) { ! 746: if (_res.options & RES_DEBUG) ! 747: printf("Res_mkquery failed\n"); ! 748: return (ERROR); ! 749: } ! 750: return(GetAnswer(nsAddrPtr, queryType, (char *)&buf, n, 0, hostPtr, 1)); ! 751: } ! 752: #endif notdef
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.