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