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