|
|
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.