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