|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985,1989 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)subr.c 5.21 (Berkeley) 6/24/90"; ! 22: #endif /* not lint */ ! 23: ! 24: /* ! 25: ******************************************************************************* ! 26: * ! 27: * subr.c -- ! 28: * ! 29: * Miscellaneous subroutines for the name server ! 30: * lookup program. ! 31: * ! 32: * Copyright (c) 1985 ! 33: * Andrew Cherenson ! 34: * U.C. Berkeley ! 35: * CS298-26 Fall 1985 ! 36: * ! 37: ******************************************************************************* ! 38: */ ! 39: ! 40: #include <sys/types.h> ! 41: #include <netdb.h> ! 42: #include <sys/socket.h> ! 43: #include <netinet/in.h> ! 44: #include <arpa/nameser.h> ! 45: #include <arpa/inet.h> ! 46: #include <signal.h> ! 47: #include <setjmp.h> ! 48: #include <stdio.h> ! 49: #include <stdlib.h> ! 50: #include <string.h> ! 51: #include "res.h" ! 52: ! 53: ! 54: ! 55: /* ! 56: ******************************************************************************* ! 57: * ! 58: * IntrHandler -- ! 59: * ! 60: * This routine is called whenever a control-C is typed. ! 61: * It performs three main functions: ! 62: * - closes an open socket connection, ! 63: * - closes an open output file (used by LookupHost, et al.), ! 64: * - jumps back to the main read-eval loop. ! 65: * ! 66: * If a user types a ^C in the middle of a routine that uses a socket, ! 67: * the routine would not be able to close the socket. To prevent an ! 68: * overflow of the process's open file table, the socket and output ! 69: * file descriptors are closed by the interrupt handler. ! 70: * ! 71: * Side effects: ! 72: * Open file descriptors are closed. ! 73: * If filePtr is valid, it is closed. ! 74: * Flow of control returns to the main() routine. ! 75: * ! 76: ******************************************************************************* ! 77: */ ! 78: ! 79: #ifdef SVR3 ! 80: void ! 81: #else ! 82: int ! 83: #endif ! 84: IntrHandler() ! 85: { ! 86: extern jmp_buf env; ! 87: extern FILE *yyin; /* scanner input file */ ! 88: extern void yyrestart(); /* routine to restart scanner after interrupt */ ! 89: ! 90: SendRequest_close(); ! 91: ListHost_close(); ! 92: if (filePtr != NULL && filePtr != stdout) { ! 93: fclose(filePtr); ! 94: filePtr = NULL; ! 95: } ! 96: printf("\n"); ! 97: yyrestart(yyin); ! 98: longjmp(env, 1); ! 99: } ! 100: ! 101: ! 102: /* ! 103: ******************************************************************************* ! 104: * ! 105: * Malloc -- ! 106: * Calloc -- ! 107: * ! 108: * Calls the malloc library routine with SIGINT blocked to prevent ! 109: * corruption of malloc's data structures. We need to do this because ! 110: * a control-C doesn't kill the program -- it causes a return to the ! 111: * main command loop. ! 112: * ! 113: * NOTE: This method doesn't prevent the pointer returned by malloc ! 114: * from getting lost, so it is possible to get "core leaks". ! 115: * ! 116: * If malloc fails, the program exits. ! 117: * ! 118: * Results: ! 119: * (address) - address of new buffer. ! 120: * ! 121: ******************************************************************************* ! 122: */ ! 123: ! 124: char * ! 125: Malloc(size) ! 126: int size; ! 127: { ! 128: char *ptr; ! 129: ! 130: #ifdef SYSV ! 131: #ifdef SVR3 ! 132: sighold(SIGINT); ! 133: ptr = malloc((unsigned) size); ! 134: sigrelse(SIGINT); ! 135: #else ! 136: { int (*old)(); ! 137: old = signal(SIGINT, SIG_IGN); ! 138: ptr = malloc((unsigned) size); ! 139: signal(SIGINT, old); ! 140: } ! 141: #endif ! 142: #else ! 143: { int saveMask; ! 144: saveMask = sigblock(sigmask(SIGINT)); ! 145: ptr = malloc((unsigned) size); ! 146: (void) sigsetmask(saveMask); ! 147: } ! 148: #endif ! 149: if (ptr == NULL) { ! 150: fflush(stdout); ! 151: fprintf(stderr, "*** Can't allocate memory\n"); ! 152: fflush(stderr); ! 153: abort(); ! 154: /*NOTREACHED*/ ! 155: } else { ! 156: return(ptr); ! 157: } ! 158: } ! 159: ! 160: char * ! 161: Calloc(num, size) ! 162: register int num, size; ! 163: { ! 164: char *ptr = Malloc(num*size); ! 165: bzero(ptr, num*size); ! 166: return(ptr); ! 167: } ! 168: ! 169: ! 170: /* ! 171: ******************************************************************************* ! 172: * ! 173: * PrintHostInfo -- ! 174: * ! 175: * Prints out the HostInfo structure for a host. ! 176: * ! 177: ******************************************************************************* ! 178: */ ! 179: ! 180: void ! 181: PrintHostInfo(file, title, hp) ! 182: FILE *file; ! 183: char *title; ! 184: register HostInfo *hp; ! 185: { ! 186: register char **cp; ! 187: register ServerInfo **sp; ! 188: char comma; ! 189: int i; ! 190: ! 191: fprintf(file, "%-7s %s", title, hp->name); ! 192: ! 193: if (hp->addrList != NULL) { ! 194: if (hp->addrList[1] != NULL) { ! 195: fprintf(file, "\nAddresses:"); ! 196: } else { ! 197: fprintf(file, "\nAddress:"); ! 198: } ! 199: comma = ' '; ! 200: i = 0; ! 201: for (cp = hp->addrList; cp && *cp; cp++) { ! 202: i++; ! 203: if (i > 4) { ! 204: fprintf(file, "\n\t"); ! 205: comma = ' '; ! 206: i = 0; ! 207: } ! 208: fprintf(file,"%c %s", comma, inet_ntoa(*(struct in_addr *)*cp)); ! 209: comma = ','; ! 210: } ! 211: } ! 212: ! 213: if (hp->aliases != NULL) { ! 214: fprintf(file, "\nAliases:"); ! 215: comma = ' '; ! 216: i = 10; ! 217: for (cp = hp->aliases; cp && *cp && **cp; cp++) { ! 218: i += strlen(*cp) + 2; ! 219: if (i > 75) { ! 220: fprintf(file, "\n\t"); ! 221: comma = ' '; ! 222: i = 10; ! 223: } ! 224: fprintf(file, "%c %s", comma, *cp); ! 225: comma = ','; ! 226: } ! 227: } ! 228: ! 229: if (hp->servers != NULL) { ! 230: fprintf(file, "\nServed by:\n"); ! 231: for (sp = hp->servers; *sp != NULL ; sp++) { ! 232: ! 233: fprintf(file, "- %s\n\t", (*sp)->name); ! 234: ! 235: comma = ' '; ! 236: i = 0; ! 237: for (cp = (*sp)->addrList; cp && *cp && **cp; cp++) { ! 238: i++; ! 239: if (i > 4) { ! 240: fprintf(file, "\n\t"); ! 241: comma = ' '; ! 242: i = 0; ! 243: } ! 244: fprintf(file, ! 245: "%c %s", comma, inet_ntoa(*(struct in_addr *)*cp)); ! 246: comma = ','; ! 247: } ! 248: fprintf(file, "\n\t"); ! 249: ! 250: comma = ' '; ! 251: i = 10; ! 252: for (cp = (*sp)->domains; cp && *cp && **cp; cp++) { ! 253: i += strlen(*cp) + 2; ! 254: if (i > 75) { ! 255: fprintf(file, "\n\t"); ! 256: comma = ' '; ! 257: i = 10; ! 258: } ! 259: fprintf(file, "%c %s", comma, *cp); ! 260: comma = ','; ! 261: } ! 262: fprintf(file, "\n"); ! 263: } ! 264: } ! 265: ! 266: fprintf(file, "\n\n"); ! 267: } ! 268: ! 269: /* ! 270: ******************************************************************************* ! 271: * ! 272: * OpenFile -- ! 273: * ! 274: * Parses a command string for a file name and opens ! 275: * the file. ! 276: * ! 277: * Results: ! 278: * file pointer - the open was successful. ! 279: * NULL - there was an error opening the file or ! 280: * the input string was invalid. ! 281: * ! 282: ******************************************************************************* ! 283: */ ! 284: ! 285: FILE * ! 286: OpenFile(string, file) ! 287: char *string; ! 288: char *file; ! 289: { ! 290: char *redirect; ! 291: FILE *tmpPtr; ! 292: ! 293: /* ! 294: * Open an output file if we see '>' or >>'. ! 295: * Check for overwrite (">") or concatenation (">>"). ! 296: */ ! 297: ! 298: redirect = strchr(string, '>'); ! 299: if (redirect == NULL) { ! 300: return(NULL); ! 301: } ! 302: if (redirect[1] == '>') { ! 303: sscanf(redirect, ">> %s", file); ! 304: tmpPtr = fopen(file, "a+"); ! 305: } else { ! 306: sscanf(redirect, "> %s", file); ! 307: tmpPtr = fopen(file, "w"); ! 308: } ! 309: ! 310: if (tmpPtr != NULL) { ! 311: redirect[0] = '\0'; ! 312: } ! 313: ! 314: return(tmpPtr); ! 315: } ! 316: ! 317: /* ! 318: ******************************************************************************* ! 319: * ! 320: * DecodeError -- ! 321: * ! 322: * Converts an error code into a character string. ! 323: * ! 324: ******************************************************************************* ! 325: */ ! 326: ! 327: char * ! 328: DecodeError(result) ! 329: int result; ! 330: { ! 331: switch (result) { ! 332: case NOERROR: return("Success"); break; ! 333: case FORMERR: return("Format error"); break; ! 334: case SERVFAIL: return("Server failed"); break; ! 335: case NXDOMAIN: return("Non-existent domain"); break; ! 336: case NOTIMP: return("Not implemented"); break; ! 337: case REFUSED: return("Query refused"); break; ! 338: case NOCHANGE: return("No change"); break; ! 339: case TIME_OUT: return("Timed out"); break; ! 340: case NO_INFO: return("No information"); break; ! 341: case ERROR: return("Unspecified error"); break; ! 342: case NONAUTH: return("Non-authoritative answer"); break; ! 343: case NO_RESPONSE: return("No response from server"); break; ! 344: default: break; ! 345: } ! 346: return("BAD ERROR VALUE"); ! 347: } ! 348: ! 349: ! 350: int ! 351: StringToClass(class, dflt) ! 352: char *class; ! 353: int dflt; ! 354: { ! 355: if (strcasecmp(class, "IN") == 0) ! 356: return(C_IN); ! 357: if (strcasecmp(class, "HESIOD") == 0 || ! 358: strcasecmp(class, "HS") == 0) ! 359: return(C_HS); ! 360: if (strcasecmp(class, "CHAOS") == 0) ! 361: return(C_CHAOS); ! 362: if (strcasecmp(class, "ANY") == 0) ! 363: return(C_ANY); ! 364: fprintf(stderr, "unknown query class: %s\n", class); ! 365: return(dflt); ! 366: } ! 367: ! 368: ! 369: /* ! 370: ******************************************************************************* ! 371: * ! 372: * StringToType -- ! 373: * ! 374: * Converts a string form of a query type name to its ! 375: * corresponding integer value. ! 376: * ! 377: ******************************************************************************* ! 378: */ ! 379: ! 380: int ! 381: StringToType(type, dflt) ! 382: char *type; ! 383: int dflt; ! 384: { ! 385: if (strcasecmp(type, "A") == 0) ! 386: return(T_A); ! 387: if (strcasecmp(type, "NS") == 0) ! 388: return(T_NS); /* authoritative server */ ! 389: if (strcasecmp(type, "MX") == 0) ! 390: return(T_MX); /* mail exchanger */ ! 391: if (strcasecmp(type, "CNAME") == 0) ! 392: return(T_CNAME); /* canonical name */ ! 393: if (strcasecmp(type, "SOA") == 0) ! 394: return(T_SOA); /* start of authority zone */ ! 395: if (strcasecmp(type, "MB") == 0) ! 396: return(T_MB); /* mailbox domain name */ ! 397: if (strcasecmp(type, "MG") == 0) ! 398: return(T_MG); /* mail group member */ ! 399: if (strcasecmp(type, "MR") == 0) ! 400: return(T_MR); /* mail rename name */ ! 401: if (strcasecmp(type, "WKS") == 0) ! 402: return(T_WKS); /* well known service */ ! 403: if (strcasecmp(type, "PTR") == 0) ! 404: return(T_PTR); /* domain name pointer */ ! 405: if (strcasecmp(type, "HINFO") == 0) ! 406: return(T_HINFO); /* host information */ ! 407: if (strcasecmp(type, "MINFO") == 0) ! 408: return(T_MINFO); /* mailbox information */ ! 409: if (strcasecmp(type, "AXFR") == 0) ! 410: return(T_AXFR); /* zone transfer */ ! 411: if (strcasecmp(type, "MAILA") == 0) ! 412: return(T_MAILA); /* mail agent */ ! 413: if (strcasecmp(type, "MAILB") == 0) ! 414: return(T_MAILB); /* mail box */ ! 415: if (strcasecmp(type, "ANY") == 0) ! 416: return(T_ANY); /* matches any type */ ! 417: if (strcasecmp(type, "UINFO") == 0) ! 418: return(T_UINFO); /* user info */ ! 419: if (strcasecmp(type, "UID") == 0) ! 420: return(T_UID); /* user id */ ! 421: if (strcasecmp(type, "GID") == 0) ! 422: return(T_GID); /* group id */ ! 423: if (strcasecmp(type, "TXT") == 0) ! 424: return(T_TXT); /* text */ ! 425: fprintf(stderr, "unknown query type: %s\n", type); ! 426: return(dflt); ! 427: } ! 428: ! 429: /* ! 430: ******************************************************************************* ! 431: * ! 432: * DecodeType -- ! 433: * ! 434: * Converts a query type to a descriptive name. ! 435: * (A more verbose form of p_type.) ! 436: * ! 437: * ! 438: ******************************************************************************* ! 439: */ ! 440: ! 441: static char nbuf[20]; ! 442: ! 443: char * ! 444: DecodeType(type) ! 445: int type; ! 446: { ! 447: switch (type) { ! 448: case T_A: ! 449: return("address"); ! 450: case T_NS: ! 451: return("name server"); ! 452: case T_CNAME: ! 453: return("canonical name"); ! 454: case T_SOA: ! 455: return("start of authority"); ! 456: case T_MB: ! 457: return("mailbox"); ! 458: case T_MG: ! 459: return("mail group member"); ! 460: case T_MR: ! 461: return("mail rename"); ! 462: case T_NULL: ! 463: return("null"); ! 464: case T_WKS: ! 465: return("well-known service"); ! 466: case T_PTR: ! 467: return("domain name pointer"); ! 468: case T_HINFO: ! 469: return("host information"); ! 470: case T_MINFO: ! 471: return("mailbox information"); ! 472: case T_MX: ! 473: return("mail exchanger"); ! 474: case T_TXT: ! 475: return("text"); ! 476: case T_UINFO: ! 477: return("user information"); ! 478: case T_UID: ! 479: return("user ID"); ! 480: case T_GID: ! 481: return("group ID"); ! 482: case T_AXFR: ! 483: return("zone transfer"); ! 484: case T_MAILB: ! 485: return("mailbox-related data"); ! 486: case T_MAILA: ! 487: return("mail agent"); ! 488: case T_ANY: ! 489: return("\"any\""); ! 490: default: ! 491: (void) sprintf(nbuf, "%d", type); ! 492: return (nbuf); ! 493: } ! 494: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.