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: }

Defined functions

IntrHandler defined in line 62; used 2 times
StringToType defined in line 315; used 1 times
hperror defined in line 452; used 2 times
printanswer defined in line 423; used 1 times

Defined variables

nbuf defined in line 372; used 1 times
sccsid defined in line 21; never used
Last modified: 1986-05-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1925
Valid CSS Valid XHTML 1.0 Strict