2 * Copyright (c) 1985, 1989
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
35 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
37 * Permission to use, copy, modify, and distribute this software for any
38 * purpose with or without fee is hereby granted, provided that the above
39 * copyright notice and this permission notice appear in all copies, and that
40 * the name of Digital Equipment Corporation not be used in advertising or
41 * publicity pertaining to distribution of the document or software without
42 * specific, written prior permission.
44 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
45 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
46 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
47 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
48 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
49 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
50 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
55 static const char sccsid[] = "@(#)subr.c 5.24 (Berkeley) 3/2/91";
56 static const char rcsid[] = "$Id: subr.c,v 8.13 1999/10/13 16:39:20 vixie Exp $";
60 *******************************************************************************
64 * Miscellaneous subroutines for the name server
72 *******************************************************************************
75 #include "port_before.h"
77 #include <sys/types.h>
78 #include <sys/param.h>
79 #include <sys/socket.h>
81 #include <netinet/in.h>
82 #include <arpa/nameser.h>
83 #include <arpa/inet.h>
92 #include "port_after.h"
98 *******************************************************************************
102 * This routine is called whenever a control-C is typed.
103 * It performs three main functions:
104 * - closes an open socket connection,
105 * - closes an open output file (used by LookupHost, et al.),
106 * - jumps back to the main read-eval loop.
108 * If a user types a ^C in the middle of a routine that uses a socket,
109 * the routine would not be able to close the socket. To prevent an
110 * overflow of the process's open file table, the socket and output
111 * file descriptors are closed by the interrupt handler.
114 * Open file descriptors are closed.
115 * If filePtr is valid, it is closed.
116 * Flow of control returns to the main() routine.
118 *******************************************************************************
125 #if defined(BSD) && BSD >= 199006 && !defined(RISCOS_BSD) && !defined(__osf__)
126 extern FILE *yyin; /* scanner input file */
127 extern void yyrestart(); /* routine to restart scanner after interrupt */
129 extern void ListHost_close(void);
133 if (filePtr != NULL && filePtr != stdout) {
138 #if defined(BSD) && BSD >= 199006 && !defined(RISCOS_BSD) && !defined(__osf__)
146 *******************************************************************************
151 * Calls the malloc library routine with SIGINT blocked to prevent
152 * corruption of malloc's data structures. We need to do this because
153 * a control-C doesn't kill the program -- it causes a return to the
156 * NOTE: This method doesn't prevent the pointer returned by malloc
157 * from getting lost, so it is possible to get "core leaks".
159 * If malloc fails, the program exits.
162 * (address) - address of new buffer.
164 *******************************************************************************
174 #if defined(SVR3) || defined(SVR4)
176 ptr = malloc((unsigned) size);
180 old = signal(SIGINT, SIG_IGN);
181 ptr = malloc((unsigned) size);
189 sigaddset(&sset,SIGINT);
190 sigprocmask(SIG_BLOCK,&sset,NULL);
191 ptr = malloc((unsigned) size);
192 sigprocmask(SIG_UNBLOCK,&sset,NULL);
196 saveMask = sigblock(sigmask(SIGINT));
197 ptr = malloc((unsigned) size);
198 (void) sigsetmask(saveMask);
204 fprintf(stderr, "*** Can't allocate memory\n");
214 register int num, size;
216 char *ptr = Malloc(num*size);
217 memset(ptr, 0, num*size);
223 *******************************************************************************
227 * Prints out the HostInfo structure for a host.
229 *******************************************************************************
233 PrintHostInfo(file, title, hp)
236 register HostInfo *hp;
239 register ServerInfo **sp;
243 fprintf(file, "%-7s %s", title, hp->name);
245 if (hp->addrList != NULL) {
246 if (hp->addrList[1] != NULL) {
247 fprintf(file, "\nAddresses:");
249 fprintf(file, "\nAddress:");
253 for (cp = hp->addrList; cp && *cp; cp++) {
256 fprintf(file, "\n\t");
260 fprintf(file,"%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
265 if (hp->aliases != NULL) {
266 fprintf(file, "\nAliases:");
269 for (cp = hp->aliases; cp && *cp && **cp; cp++) {
270 i += strlen(*cp) + 2;
272 fprintf(file, "\n\t");
276 fprintf(file, "%c %s", comma, *cp);
281 if (hp->servers != NULL) {
282 fprintf(file, "\nServed by:\n");
283 for (sp = hp->servers; *sp != NULL ; sp++) {
285 fprintf(file, "- %s\n\t", (*sp)->name);
289 for (cp = (*sp)->addrList; cp && *cp && **cp; cp++) {
292 fprintf(file, "\n\t");
297 "%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
300 fprintf(file, "\n\t");
304 for (cp = (*sp)->domains; cp && *cp && **cp; cp++) {
305 i += strlen(*cp) + 2;
307 fprintf(file, "\n\t");
311 fprintf(file, "%c %s", comma, *cp);
318 fprintf(file, "\n\n");
322 *******************************************************************************
326 * Parses a command string for a file name and opens
327 * the file. The file name is copued to the argument FILE. The
328 * parameter SIZE parameter includes space for a null byte.
331 * file pointer - the open was successful.
332 * NULL - there was an error opening the file or
333 * the input string was invalid.
335 *******************************************************************************
339 OpenFile(string, file, size)
349 * Open an output file if we see '>' or >>'.
350 * Check for overwrite (">") or concatenation (">>").
353 redirect = strchr(string, '>');
354 if (redirect == NULL) {
359 if (redirect[1] == '>') {
360 i = pickString(redirect + 2, file, size);
362 tmpPtr = fopen(file, "a+");
365 i = pickString(redirect + 1, file, size);
367 tmpPtr = fopen(file, "w");
371 if (tmpPtr != NULL) {
379 *******************************************************************************
383 * Converts an error code into a character string.
385 *******************************************************************************
388 const struct res_sym error_syms[] = {
389 { NOERROR, "Success" },
390 { FORMERR, "Format error" },
391 { SERVFAIL, "Server failed" },
392 { NXDOMAIN, "Non-existent host/domain" },
393 { NOTIMP, "Not implemented" },
394 { REFUSED, "Query refused" },
396 { NOCHANGE, "No change" },
398 { TIME_OUT, "Timed out" },
399 { NO_INFO, "No information" },
400 { ERROR, "Unspecified error" },
401 { NONAUTH, "Non-authoritative answer" },
402 { NO_RESPONSE, "No response from server" },
413 string = sym_ntos(error_syms, result, &success);
416 return ("BAD ERROR VALUE");
421 StringToClass(class, dflt, errorfile)
428 result = sym_ston(__p_class_syms, class, &success);
433 fprintf(errorfile, "unknown query class: %s\n", class);
439 *******************************************************************************
443 * Converts a string form of a query type name to its
444 * corresponding integer value.
446 *******************************************************************************
450 StringToType(type, dflt, errorfile)
457 result = sym_ston(__p_type_syms, type, &success);
462 fprintf(errorfile, "unknown query type: %s\n", type);
467 *******************************************************************************
471 * Converts a query type to a descriptive name.
472 * (A more verbose form of p_type.)
475 *******************************************************************************
483 return (sym_ntop(__p_type_syms, type, (int *)0));
490 * Skip over leading white space in SRC and then copy the next sequence of
491 * non-whitespace characters into DEST. No more than (DEST_SIZE - 1)
492 * characters are copied. DEST is always null-terminated. Returns 0 if no
493 * characters could be copied into DEST. Returns the number of characters
494 * in SRC that were processed (i.e. the count of characters in the leading
495 * white space and the first non-whitespace sequence).
498 * char *p = " foo bar ", *q;
501 * q = p + pickString(p, buf, sizeof buff);
502 * assert (strcmp (q, " bar ") == 0) ;
507 pickString(const char *src, char *dest, size_t dest_size) {
512 if (dest_size == 0 || dest == NULL || src == NULL)
515 for (start = src ; isspace(*start) ; start++)
518 for (end = start ; *end != '\0' && !isspace(*end) ; end++)
521 sublen = end - start ;
523 if (sublen == 0 || sublen > (dest_size - 1))
526 strncpy (dest, start, sublen);
528 dest[sublen] = '\0' ;
537 * match the string FORMAT against the string SRC. Leading whitespace in
538 * FORMAT will match any amount of (including no) leading whitespace in
539 * SRC. Any amount of whitespace inside FORMAT matches any non-zero amount
540 * of whitespace in SRC. Value returned is 0 if match didn't occur, or the
541 * amount of characters in SRC that did match
545 * i = matchString(" a b c", "a b c") ;
547 * i = matchString("a b c", " a b c");
548 * assert (i == 0) ; becasue no leading white space in format
549 * i = matchString(" a b c", " a b c");
551 * i = matchString("aa bb ", "aa bb ddd sd");
555 matchString (const char *format, const char *src) {
556 const char *f = format;
559 if (f == NULL || s == NULL)
575 /* any amount of whitespace in the format string
576 will match any amount of space in the source
580 } else if (*f == '\0') {
582 } else if (*f != *s) {