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