Initial import, 0.1 + pk 0.2.4-B1
[unix-history] / usr.sbin / named / tools / nslookup / subr.c
CommitLineData
15637ed4
RG
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, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)subr.c 5.24 (Berkeley) 3/2/91";
36#endif /* not lint */
37
38/*
39 *******************************************************************************
40 *
41 * subr.c --
42 *
43 * Miscellaneous subroutines for the name server
44 * lookup program.
45 *
46 * Copyright (c) 1985
47 * Andrew Cherenson
48 * U.C. Berkeley
49 * CS298-26 Fall 1985
50 *
51 *******************************************************************************
52 */
53
54#include <sys/types.h>
55#include <sys/param.h>
56#include <netdb.h>
57#include <sys/socket.h>
58#include <netinet/in.h>
59#include <arpa/nameser.h>
60#include <arpa/inet.h>
61#include <signal.h>
62#include <setjmp.h>
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66#include "res.h"
67
68
69\f
70/*
71 *******************************************************************************
72 *
73 * IntrHandler --
74 *
75 * This routine is called whenever a control-C is typed.
76 * It performs three main functions:
77 * - closes an open socket connection,
78 * - closes an open output file (used by LookupHost, et al.),
79 * - jumps back to the main read-eval loop.
80 *
81 * If a user types a ^C in the middle of a routine that uses a socket,
82 * the routine would not be able to close the socket. To prevent an
83 * overflow of the process's open file table, the socket and output
84 * file descriptors are closed by the interrupt handler.
85 *
86 * Side effects:
87 * Open file descriptors are closed.
88 * If filePtr is valid, it is closed.
89 * Flow of control returns to the main() routine.
90 *
91 *******************************************************************************
92 */
93
94void
95IntrHandler()
96{
97 extern jmp_buf env;
98#if defined(BSD) && BSD >= 199006
99 extern FILE *yyin; /* scanner input file */
100 extern void yyrestart(); /* routine to restart scanner after interrupt */
101#endif
102
103 SendRequest_close();
104 ListHost_close();
105 if (filePtr != NULL && filePtr != stdout) {
106 fclose(filePtr);
107 filePtr = NULL;
108 }
109 printf("\n");
110#if defined(BSD) && BSD >= 199006
111 yyrestart(yyin);
112#endif
113 longjmp(env, 1);
114}
115\f
116
117/*
118 *******************************************************************************
119 *
120 * Malloc --
121 * Calloc --
122 *
123 * Calls the malloc library routine with SIGINT blocked to prevent
124 * corruption of malloc's data structures. We need to do this because
125 * a control-C doesn't kill the program -- it causes a return to the
126 * main command loop.
127 *
128 * NOTE: This method doesn't prevent the pointer returned by malloc
129 * from getting lost, so it is possible to get "core leaks".
130 *
131 * If malloc fails, the program exits.
132 *
133 * Results:
134 * (address) - address of new buffer.
135 *
136 *******************************************************************************
137 */
138
139char *
140Malloc(size)
141 int size;
142{
143 char *ptr;
144
145#ifdef SYSV
146#ifdef SVR3
147 sighold(SIGINT);
148 ptr = malloc((unsigned) size);
149 sigrelse(SIGINT);
150#else
151 { int (*old)();
152 old = signal(SIGINT, SIG_IGN);
153 ptr = malloc((unsigned) size);
154 signal(SIGINT, old);
155 }
156#endif
157#else
158 { int saveMask;
159 saveMask = sigblock(sigmask(SIGINT));
160 ptr = malloc((unsigned) size);
161 (void) sigsetmask(saveMask);
162 }
163#endif
164 if (ptr == NULL) {
165 fflush(stdout);
166 fprintf(stderr, "*** Can't allocate memory\n");
167 fflush(stderr);
168 abort();
169 /*NOTREACHED*/
170 } else {
171 return(ptr);
172 }
173}
174
175char *
176Calloc(num, size)
177 register int num, size;
178{
179 char *ptr = Malloc(num*size);
180 bzero(ptr, num*size);
181 return(ptr);
182}
183
184\f
185/*
186 *******************************************************************************
187 *
188 * PrintHostInfo --
189 *
190 * Prints out the HostInfo structure for a host.
191 *
192 *******************************************************************************
193 */
194
195void
196PrintHostInfo(file, title, hp)
197 FILE *file;
198 char *title;
199 register HostInfo *hp;
200{
201 register char **cp;
202 register ServerInfo **sp;
203 char comma;
204 int i;
205
206 fprintf(file, "%-7s %s", title, hp->name);
207
208 if (hp->addrList != NULL) {
209 if (hp->addrList[1] != NULL) {
210 fprintf(file, "\nAddresses:");
211 } else {
212 fprintf(file, "\nAddress:");
213 }
214 comma = ' ';
215 i = 0;
216 for (cp = hp->addrList; cp && *cp; cp++) {
217 i++;
218 if (i > 4) {
219 fprintf(file, "\n\t");
220 comma = ' ';
221 i = 0;
222 }
223 fprintf(file,"%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
224 comma = ',';
225 }
226 }
227
228 if (hp->aliases != NULL) {
229 fprintf(file, "\nAliases:");
230 comma = ' ';
231 i = 10;
232 for (cp = hp->aliases; cp && *cp && **cp; cp++) {
233 i += strlen(*cp) + 2;
234 if (i > 75) {
235 fprintf(file, "\n\t");
236 comma = ' ';
237 i = 10;
238 }
239 fprintf(file, "%c %s", comma, *cp);
240 comma = ',';
241 }
242 }
243
244 if (hp->servers != NULL) {
245 fprintf(file, "\nServed by:\n");
246 for (sp = hp->servers; *sp != NULL ; sp++) {
247
248 fprintf(file, "- %s\n\t", (*sp)->name);
249
250 comma = ' ';
251 i = 0;
252 for (cp = (*sp)->addrList; cp && *cp && **cp; cp++) {
253 i++;
254 if (i > 4) {
255 fprintf(file, "\n\t");
256 comma = ' ';
257 i = 0;
258 }
259 fprintf(file,
260 "%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
261 comma = ',';
262 }
263 fprintf(file, "\n\t");
264
265 comma = ' ';
266 i = 10;
267 for (cp = (*sp)->domains; cp && *cp && **cp; cp++) {
268 i += strlen(*cp) + 2;
269 if (i > 75) {
270 fprintf(file, "\n\t");
271 comma = ' ';
272 i = 10;
273 }
274 fprintf(file, "%c %s", comma, *cp);
275 comma = ',';
276 }
277 fprintf(file, "\n");
278 }
279 }
280
281 fprintf(file, "\n\n");
282}
283\f
284/*
285 *******************************************************************************
286 *
287 * OpenFile --
288 *
289 * Parses a command string for a file name and opens
290 * the file.
291 *
292 * Results:
293 * file pointer - the open was successful.
294 * NULL - there was an error opening the file or
295 * the input string was invalid.
296 *
297 *******************************************************************************
298 */
299
300FILE *
301OpenFile(string, file)
302 char *string;
303 char *file;
304{
305 char *redirect;
306 FILE *tmpPtr;
307
308 /*
309 * Open an output file if we see '>' or >>'.
310 * Check for overwrite (">") or concatenation (">>").
311 */
312
313 redirect = strchr(string, '>');
314 if (redirect == NULL) {
315 return(NULL);
316 }
317 if (redirect[1] == '>') {
318 sscanf(redirect, ">> %s", file);
319 tmpPtr = fopen(file, "a+");
320 } else {
321 sscanf(redirect, "> %s", file);
322 tmpPtr = fopen(file, "w");
323 }
324
325 if (tmpPtr != NULL) {
326 redirect[0] = '\0';
327 }
328
329 return(tmpPtr);
330}
331\f
332/*
333 *******************************************************************************
334 *
335 * DecodeError --
336 *
337 * Converts an error code into a character string.
338 *
339 *******************************************************************************
340 */
341
342char *
343DecodeError(result)
344 int result;
345{
346 switch (result) {
347 case NOERROR: return("Success"); break;
348 case FORMERR: return("Format error"); break;
349 case SERVFAIL: return("Server failed"); break;
350 case NXDOMAIN: return("Non-existent domain"); break;
351 case NOTIMP: return("Not implemented"); break;
352 case REFUSED: return("Query refused"); break;
353 case NOCHANGE: return("No change"); break;
354 case TIME_OUT: return("Timed out"); break;
355 case NO_INFO: return("No information"); break;
356 case ERROR: return("Unspecified error"); break;
357 case NONAUTH: return("Non-authoritative answer"); break;
358 case NO_RESPONSE: return("No response from server"); break;
359 default: break;
360 }
361 return("BAD ERROR VALUE");
362}
363\f
364
365int
366StringToClass(class, dflt)
367 char *class;
368 int dflt;
369{
370 if (strcasecmp(class, "IN") == 0)
371 return(C_IN);
372 if (strcasecmp(class, "HESIOD") == 0 ||
373 strcasecmp(class, "HS") == 0)
374 return(C_HS);
375 if (strcasecmp(class, "CHAOS") == 0)
376 return(C_CHAOS);
377 if (strcasecmp(class, "ANY") == 0)
378 return(C_ANY);
379 fprintf(stderr, "unknown query class: %s\n", class);
380 return(dflt);
381}
382\f
383
384/*
385 *******************************************************************************
386 *
387 * StringToType --
388 *
389 * Converts a string form of a query type name to its
390 * corresponding integer value.
391 *
392 *******************************************************************************
393 */
394
395int
396StringToType(type, dflt)
397 char *type;
398 int dflt;
399{
400 if (strcasecmp(type, "A") == 0)
401 return(T_A);
402 if (strcasecmp(type, "NS") == 0)
403 return(T_NS); /* authoritative server */
404 if (strcasecmp(type, "MX") == 0)
405 return(T_MX); /* mail exchanger */
406 if (strcasecmp(type, "CNAME") == 0)
407 return(T_CNAME); /* canonical name */
408 if (strcasecmp(type, "SOA") == 0)
409 return(T_SOA); /* start of authority zone */
410 if (strcasecmp(type, "MB") == 0)
411 return(T_MB); /* mailbox domain name */
412 if (strcasecmp(type, "MG") == 0)
413 return(T_MG); /* mail group member */
414 if (strcasecmp(type, "MR") == 0)
415 return(T_MR); /* mail rename name */
416 if (strcasecmp(type, "WKS") == 0)
417 return(T_WKS); /* well known service */
418 if (strcasecmp(type, "PTR") == 0)
419 return(T_PTR); /* domain name pointer */
420 if (strcasecmp(type, "HINFO") == 0)
421 return(T_HINFO); /* host information */
422 if (strcasecmp(type, "MINFO") == 0)
423 return(T_MINFO); /* mailbox information */
424 if (strcasecmp(type, "AXFR") == 0)
425 return(T_AXFR); /* zone transfer */
426 if (strcasecmp(type, "MAILA") == 0)
427 return(T_MAILA); /* mail agent */
428 if (strcasecmp(type, "MAILB") == 0)
429 return(T_MAILB); /* mail box */
430 if (strcasecmp(type, "ANY") == 0)
431 return(T_ANY); /* matches any type */
432 if (strcasecmp(type, "UINFO") == 0)
433 return(T_UINFO); /* user info */
434 if (strcasecmp(type, "UID") == 0)
435 return(T_UID); /* user id */
436 if (strcasecmp(type, "GID") == 0)
437 return(T_GID); /* group id */
438 if (strcasecmp(type, "TXT") == 0)
439 return(T_TXT); /* text */
440 fprintf(stderr, "unknown query type: %s\n", type);
441 return(dflt);
442}
443\f
444/*
445 *******************************************************************************
446 *
447 * DecodeType --
448 *
449 * Converts a query type to a descriptive name.
450 * (A more verbose form of p_type.)
451 *
452 *
453 *******************************************************************************
454 */
455
456static char nbuf[20];
457
458char *
459DecodeType(type)
460 int type;
461{
462 switch (type) {
463 case T_A:
464 return("address");
465 case T_NS:
466 return("name server");
467 case T_CNAME:
468 return("canonical name");
469 case T_SOA:
470 return("start of authority");
471 case T_MB:
472 return("mailbox");
473 case T_MG:
474 return("mail group member");
475 case T_MR:
476 return("mail rename");
477 case T_NULL:
478 return("null");
479 case T_WKS:
480 return("well-known service");
481 case T_PTR:
482 return("domain name pointer");
483 case T_HINFO:
484 return("host information");
485 case T_MINFO:
486 return("mailbox information");
487 case T_MX:
488 return("mail exchanger");
489 case T_TXT:
490 return("text");
491 case T_UINFO:
492 return("user information");
493 case T_UID:
494 return("user ID");
495 case T_GID:
496 return("group ID");
497 case T_AXFR:
498 return("zone transfer");
499 case T_MAILB:
500 return("mailbox-related data");
501 case T_MAILA:
502 return("mail agent");
503 case T_ANY:
504 return("\"any\"");
505 default:
506 (void) sprintf(nbuf, "%d", type);
507 return (nbuf);
508 }
509}