xref: /minix3/external/bsd/bind/dist/lib/tests/t_api.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: t_api.c,v 1.7 2014/12/10 04:38:02 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004, 2005, 2007-2010, 2013, 2014  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1999-2003  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: t_api.c,v 1.68 2010/12/21 04:20:23 marka Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*! \file */
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <ctype.h>
27*00b67f09SDavid van Moolenbroek #include <errno.h>
28*00b67f09SDavid van Moolenbroek #include <limits.h>
29*00b67f09SDavid van Moolenbroek #include <signal.h>
30*00b67f09SDavid van Moolenbroek #include <stdarg.h>
31*00b67f09SDavid van Moolenbroek #include <stdio.h>
32*00b67f09SDavid van Moolenbroek #include <stdlib.h>
33*00b67f09SDavid van Moolenbroek #include <time.h>
34*00b67f09SDavid van Moolenbroek #include <unistd.h>
35*00b67f09SDavid van Moolenbroek 
36*00b67f09SDavid van Moolenbroek #ifndef WIN32
37*00b67f09SDavid van Moolenbroek #include <sys/wait.h>
38*00b67f09SDavid van Moolenbroek #else
39*00b67f09SDavid van Moolenbroek #include <direct.h>
40*00b67f09SDavid van Moolenbroek #endif
41*00b67f09SDavid van Moolenbroek 
42*00b67f09SDavid van Moolenbroek #include <isc/boolean.h>
43*00b67f09SDavid van Moolenbroek #include <isc/commandline.h>
44*00b67f09SDavid van Moolenbroek #include <isc/print.h>
45*00b67f09SDavid van Moolenbroek #include <isc/string.h>
46*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
47*00b67f09SDavid van Moolenbroek 
48*00b67f09SDavid van Moolenbroek #include <dns/compress.h>
49*00b67f09SDavid van Moolenbroek #include <dns/result.h>
50*00b67f09SDavid van Moolenbroek 
51*00b67f09SDavid van Moolenbroek #include "include/tests/t_api.h"
52*00b67f09SDavid van Moolenbroek 
53*00b67f09SDavid van Moolenbroek static const char *Usage =
54*00b67f09SDavid van Moolenbroek 		"\t-a               : run all tests\n"
55*00b67f09SDavid van Moolenbroek 		"\t-b <dir>         : chdir to dir before running tests"
56*00b67f09SDavid van Moolenbroek 		"\t-c <config_file> : use specified config file\n"
57*00b67f09SDavid van Moolenbroek 		"\t-d <debug_level> : set debug level to debug_level\n"
58*00b67f09SDavid van Moolenbroek 		"\t-h               : print test info\n"
59*00b67f09SDavid van Moolenbroek 		"\t-u               : print usage info\n"
60*00b67f09SDavid van Moolenbroek 		"\t-n <test_name>   : run specified test name\n"
61*00b67f09SDavid van Moolenbroek 		"\t-t <test_number> : run specified test number\n"
62*00b67f09SDavid van Moolenbroek 		"\t-x               : don't execute tests in a subproc\n"
63*00b67f09SDavid van Moolenbroek 		"\t-q <timeout>     : use 'timeout' as the timeout value\n";
64*00b67f09SDavid van Moolenbroek /*!<
65*00b67f09SDavid van Moolenbroek  *		-a		-->	run all tests
66*00b67f09SDavid van Moolenbroek  *		-b dir		-->	chdir to dir before running tests
67*00b67f09SDavid van Moolenbroek  *		-c config	-->	use config file 'config'
68*00b67f09SDavid van Moolenbroek  *		-d		-->	turn on api debugging
69*00b67f09SDavid van Moolenbroek  *		-h		-->	print out available test names
70*00b67f09SDavid van Moolenbroek  *		-u		-->	print usage info
71*00b67f09SDavid van Moolenbroek  *		-n name		-->	run test named name
72*00b67f09SDavid van Moolenbroek  *		-tn		-->	run test n
73*00b67f09SDavid van Moolenbroek  *		-x		-->	don't execute testcases in a subproc
74*00b67f09SDavid van Moolenbroek  *		-q timeout	-->	use 'timeout' as the timeout value
75*00b67f09SDavid van Moolenbroek  */
76*00b67f09SDavid van Moolenbroek 
77*00b67f09SDavid van Moolenbroek #define	T_MAXTESTS		256	/*% must be 0 mod 8 */
78*00b67f09SDavid van Moolenbroek #define	T_MAXENV		256
79*00b67f09SDavid van Moolenbroek #define	T_DEFAULT_CONFIG	"t_config"
80*00b67f09SDavid van Moolenbroek #define	T_BUFSIZ		256
81*00b67f09SDavid van Moolenbroek #define	T_BIGBUF		4096
82*00b67f09SDavid van Moolenbroek 
83*00b67f09SDavid van Moolenbroek #define	T_TCTOUT		60
84*00b67f09SDavid van Moolenbroek 
85*00b67f09SDavid van Moolenbroek int			T_debug;
86*00b67f09SDavid van Moolenbroek int			T_timeout;
87*00b67f09SDavid van Moolenbroek pid_t			T_pid;
88*00b67f09SDavid van Moolenbroek static const char *	T_config;
89*00b67f09SDavid van Moolenbroek static char		T_tvec[T_MAXTESTS / 8];
90*00b67f09SDavid van Moolenbroek static char *		T_env[T_MAXENV + 1];
91*00b67f09SDavid van Moolenbroek static char		T_buf[T_BIGBUF];
92*00b67f09SDavid van Moolenbroek static char *		T_dir;
93*00b67f09SDavid van Moolenbroek #ifdef WIN32
94*00b67f09SDavid van Moolenbroek static testspec_t	T_testlist[T_MAXTESTS];
95*00b67f09SDavid van Moolenbroek #endif
96*00b67f09SDavid van Moolenbroek 
97*00b67f09SDavid van Moolenbroek static int
98*00b67f09SDavid van Moolenbroek t_initconf(const char *path);
99*00b67f09SDavid van Moolenbroek 
100*00b67f09SDavid van Moolenbroek static int
101*00b67f09SDavid van Moolenbroek t_dumpconf(const char *path);
102*00b67f09SDavid van Moolenbroek 
103*00b67f09SDavid van Moolenbroek static int
104*00b67f09SDavid van Moolenbroek t_putinfo(const char *key, const char *info);
105*00b67f09SDavid van Moolenbroek 
106*00b67f09SDavid van Moolenbroek static char *
107*00b67f09SDavid van Moolenbroek t_getdate(char *buf, size_t buflen);
108*00b67f09SDavid van Moolenbroek 
109*00b67f09SDavid van Moolenbroek static void
110*00b67f09SDavid van Moolenbroek printhelp(void);
111*00b67f09SDavid van Moolenbroek 
112*00b67f09SDavid van Moolenbroek static void
113*00b67f09SDavid van Moolenbroek printusage(void);
114*00b67f09SDavid van Moolenbroek 
115*00b67f09SDavid van Moolenbroek static int	T_int;
116*00b67f09SDavid van Moolenbroek 
117*00b67f09SDavid van Moolenbroek static void
t_sighandler(int sig)118*00b67f09SDavid van Moolenbroek t_sighandler(int sig) {
119*00b67f09SDavid van Moolenbroek 	T_int = sig;
120*00b67f09SDavid van Moolenbroek }
121*00b67f09SDavid van Moolenbroek 
122*00b67f09SDavid van Moolenbroek int
123*00b67f09SDavid van Moolenbroek #ifndef WIN32
main(int argc,char ** argv)124*00b67f09SDavid van Moolenbroek main(int argc, char **argv)
125*00b67f09SDavid van Moolenbroek #else
126*00b67f09SDavid van Moolenbroek t_main(int argc, char **argv)
127*00b67f09SDavid van Moolenbroek #endif
128*00b67f09SDavid van Moolenbroek {
129*00b67f09SDavid van Moolenbroek 	int			c;
130*00b67f09SDavid van Moolenbroek 	int			tnum;
131*00b67f09SDavid van Moolenbroek #ifndef WIN32
132*00b67f09SDavid van Moolenbroek 	int			subprocs;
133*00b67f09SDavid van Moolenbroek 	pid_t			deadpid;
134*00b67f09SDavid van Moolenbroek 	int			status;
135*00b67f09SDavid van Moolenbroek #endif
136*00b67f09SDavid van Moolenbroek 	int			len;
137*00b67f09SDavid van Moolenbroek 	isc_boolean_t		first;
138*00b67f09SDavid van Moolenbroek 	testspec_t		*pts;
139*00b67f09SDavid van Moolenbroek #ifndef WIN32
140*00b67f09SDavid van Moolenbroek 	struct sigaction	sa;
141*00b67f09SDavid van Moolenbroek #endif
142*00b67f09SDavid van Moolenbroek 
143*00b67f09SDavid van Moolenbroek 	isc_mem_debugging = ISC_MEM_DEBUGRECORD;
144*00b67f09SDavid van Moolenbroek 	first = ISC_TRUE;
145*00b67f09SDavid van Moolenbroek #ifndef WIN32
146*00b67f09SDavid van Moolenbroek 	subprocs = 1;
147*00b67f09SDavid van Moolenbroek #endif
148*00b67f09SDavid van Moolenbroek 	T_timeout = T_TCTOUT;
149*00b67f09SDavid van Moolenbroek 
150*00b67f09SDavid van Moolenbroek 	/*
151*00b67f09SDavid van Moolenbroek 	 * -a option is now default.
152*00b67f09SDavid van Moolenbroek 	 */
153*00b67f09SDavid van Moolenbroek 	memset(T_tvec, 0xff, sizeof(T_tvec));
154*00b67f09SDavid van Moolenbroek 
155*00b67f09SDavid van Moolenbroek 	/*
156*00b67f09SDavid van Moolenbroek 	 * Parse args.
157*00b67f09SDavid van Moolenbroek 	 */
158*00b67f09SDavid van Moolenbroek 	while ((c = isc_commandline_parse(argc, argv, ":at:c:d:n:huxq:b:"))
159*00b67f09SDavid van Moolenbroek 	       != -1) {
160*00b67f09SDavid van Moolenbroek 		if (c == 'a') {
161*00b67f09SDavid van Moolenbroek 			/*
162*00b67f09SDavid van Moolenbroek 			 * Flag all tests to be run.
163*00b67f09SDavid van Moolenbroek 			 */
164*00b67f09SDavid van Moolenbroek 			memset(T_tvec, 0xff, sizeof(T_tvec));
165*00b67f09SDavid van Moolenbroek 		}
166*00b67f09SDavid van Moolenbroek 		else if (c == 'b') {
167*00b67f09SDavid van Moolenbroek 			T_dir = isc_commandline_argument;
168*00b67f09SDavid van Moolenbroek 		}
169*00b67f09SDavid van Moolenbroek 		else if (c == 't') {
170*00b67f09SDavid van Moolenbroek 			tnum = atoi(isc_commandline_argument);
171*00b67f09SDavid van Moolenbroek 			if ((tnum > 0) && (tnum < T_MAXTESTS)) {
172*00b67f09SDavid van Moolenbroek 				if (first) {
173*00b67f09SDavid van Moolenbroek 					/*
174*00b67f09SDavid van Moolenbroek 					 * Turn off effect of -a default
175*00b67f09SDavid van Moolenbroek 					 * and allow multiple -t and -n
176*00b67f09SDavid van Moolenbroek 					 * options.
177*00b67f09SDavid van Moolenbroek 					 */
178*00b67f09SDavid van Moolenbroek 					memset(T_tvec, 0, sizeof(T_tvec));
179*00b67f09SDavid van Moolenbroek 					first = ISC_FALSE;
180*00b67f09SDavid van Moolenbroek 				}
181*00b67f09SDavid van Moolenbroek 				/*
182*00b67f09SDavid van Moolenbroek 				 * Flag test tnum to be run.
183*00b67f09SDavid van Moolenbroek 				 */
184*00b67f09SDavid van Moolenbroek 				tnum -= 1;
185*00b67f09SDavid van Moolenbroek 				T_tvec[tnum / 8] |= (0x01 << (tnum % 8));
186*00b67f09SDavid van Moolenbroek 			}
187*00b67f09SDavid van Moolenbroek 		}
188*00b67f09SDavid van Moolenbroek 		else if (c == 'c') {
189*00b67f09SDavid van Moolenbroek 			T_config = isc_commandline_argument;
190*00b67f09SDavid van Moolenbroek 		}
191*00b67f09SDavid van Moolenbroek 		else if (c == 'd') {
192*00b67f09SDavid van Moolenbroek 			T_debug = atoi(isc_commandline_argument);
193*00b67f09SDavid van Moolenbroek 		}
194*00b67f09SDavid van Moolenbroek 		else if (c == 'n') {
195*00b67f09SDavid van Moolenbroek 			pts = &T_testlist[0];
196*00b67f09SDavid van Moolenbroek 			tnum = 0;
197*00b67f09SDavid van Moolenbroek 			while (pts->pfv != NULL) {
198*00b67f09SDavid van Moolenbroek 				if (! strcmp(pts->func_name,
199*00b67f09SDavid van Moolenbroek 					     isc_commandline_argument)) {
200*00b67f09SDavid van Moolenbroek 					if (first) {
201*00b67f09SDavid van Moolenbroek 						memset(T_tvec, 0,
202*00b67f09SDavid van Moolenbroek 						       sizeof(T_tvec));
203*00b67f09SDavid van Moolenbroek 						first = ISC_FALSE;
204*00b67f09SDavid van Moolenbroek 					}
205*00b67f09SDavid van Moolenbroek 					T_tvec[tnum/8] |= (0x01 << (tnum%8));
206*00b67f09SDavid van Moolenbroek 					break;
207*00b67f09SDavid van Moolenbroek 				}
208*00b67f09SDavid van Moolenbroek 				++pts;
209*00b67f09SDavid van Moolenbroek 				++tnum;
210*00b67f09SDavid van Moolenbroek 			}
211*00b67f09SDavid van Moolenbroek 			if (pts->pfv == NULL) {
212*00b67f09SDavid van Moolenbroek 				fprintf(stderr, "no such test %s\n",
213*00b67f09SDavid van Moolenbroek 					isc_commandline_argument);
214*00b67f09SDavid van Moolenbroek 				exit(1);
215*00b67f09SDavid van Moolenbroek 			}
216*00b67f09SDavid van Moolenbroek 		}
217*00b67f09SDavid van Moolenbroek 		else if (c == 'h') {
218*00b67f09SDavid van Moolenbroek 			printhelp();
219*00b67f09SDavid van Moolenbroek 			exit(0);
220*00b67f09SDavid van Moolenbroek 		}
221*00b67f09SDavid van Moolenbroek 		else if (c == 'u') {
222*00b67f09SDavid van Moolenbroek 			printusage();
223*00b67f09SDavid van Moolenbroek 			exit(0);
224*00b67f09SDavid van Moolenbroek 		}
225*00b67f09SDavid van Moolenbroek 		else if (c == 'x') {
226*00b67f09SDavid van Moolenbroek #ifndef WIN32
227*00b67f09SDavid van Moolenbroek 			subprocs = 0;
228*00b67f09SDavid van Moolenbroek #endif
229*00b67f09SDavid van Moolenbroek 		}
230*00b67f09SDavid van Moolenbroek 		else if (c == 'q') {
231*00b67f09SDavid van Moolenbroek 			T_timeout = atoi(isc_commandline_argument);
232*00b67f09SDavid van Moolenbroek 		}
233*00b67f09SDavid van Moolenbroek 		else if (c == ':') {
234*00b67f09SDavid van Moolenbroek 			fprintf(stderr, "Option -%c requires an argument\n",
235*00b67f09SDavid van Moolenbroek 						isc_commandline_option);
236*00b67f09SDavid van Moolenbroek 			exit(1);
237*00b67f09SDavid van Moolenbroek 		}
238*00b67f09SDavid van Moolenbroek 		else if (c == '?') {
239*00b67f09SDavid van Moolenbroek 			fprintf(stderr, "Unrecognized option -%c\n",
240*00b67f09SDavid van Moolenbroek 				isc_commandline_option);
241*00b67f09SDavid van Moolenbroek 			exit(1);
242*00b67f09SDavid van Moolenbroek 		}
243*00b67f09SDavid van Moolenbroek 	}
244*00b67f09SDavid van Moolenbroek 
245*00b67f09SDavid van Moolenbroek 	/*
246*00b67f09SDavid van Moolenbroek 	 * Set cwd.
247*00b67f09SDavid van Moolenbroek 	 */
248*00b67f09SDavid van Moolenbroek 
249*00b67f09SDavid van Moolenbroek 	if (T_dir != NULL && chdir(T_dir) != 0) {
250*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "chdir %s failed\n", T_dir);
251*00b67f09SDavid van Moolenbroek 		exit(1);
252*00b67f09SDavid van Moolenbroek 	}
253*00b67f09SDavid van Moolenbroek 
254*00b67f09SDavid van Moolenbroek 	/*
255*00b67f09SDavid van Moolenbroek 	 * We don't want buffered output.
256*00b67f09SDavid van Moolenbroek 	 */
257*00b67f09SDavid van Moolenbroek 
258*00b67f09SDavid van Moolenbroek 	(void)setbuf(stdout, NULL);
259*00b67f09SDavid van Moolenbroek 	(void)setbuf(stderr, NULL);
260*00b67f09SDavid van Moolenbroek 
261*00b67f09SDavid van Moolenbroek 	/*
262*00b67f09SDavid van Moolenbroek 	 * Setup signals.
263*00b67f09SDavid van Moolenbroek 	 */
264*00b67f09SDavid van Moolenbroek 
265*00b67f09SDavid van Moolenbroek #ifndef WIN32
266*00b67f09SDavid van Moolenbroek 	sa.sa_flags = 0;
267*00b67f09SDavid van Moolenbroek 	sigfillset(&sa.sa_mask);
268*00b67f09SDavid van Moolenbroek 
269*00b67f09SDavid van Moolenbroek 	sa.sa_handler = t_sighandler;
270*00b67f09SDavid van Moolenbroek 	(void)sigaction(SIGINT,  &sa, NULL);
271*00b67f09SDavid van Moolenbroek 	(void)sigaction(SIGALRM, &sa, NULL);
272*00b67f09SDavid van Moolenbroek #endif
273*00b67f09SDavid van Moolenbroek 
274*00b67f09SDavid van Moolenbroek 	/*
275*00b67f09SDavid van Moolenbroek 	 * Output start stanza to journal.
276*00b67f09SDavid van Moolenbroek 	 */
277*00b67f09SDavid van Moolenbroek 
278*00b67f09SDavid van Moolenbroek 	snprintf(T_buf, sizeof(T_buf), "%s:", argv[0]);
279*00b67f09SDavid van Moolenbroek 	len = strlen(T_buf);
280*00b67f09SDavid van Moolenbroek 	(void) t_getdate(T_buf + len, T_BIGBUF - len);
281*00b67f09SDavid van Moolenbroek 	t_putinfo("S", T_buf);
282*00b67f09SDavid van Moolenbroek 
283*00b67f09SDavid van Moolenbroek 	/*
284*00b67f09SDavid van Moolenbroek 	 * Setup the test environment using the config file.
285*00b67f09SDavid van Moolenbroek 	 */
286*00b67f09SDavid van Moolenbroek 
287*00b67f09SDavid van Moolenbroek 	if (T_config == NULL)
288*00b67f09SDavid van Moolenbroek 		T_config = T_DEFAULT_CONFIG;
289*00b67f09SDavid van Moolenbroek 
290*00b67f09SDavid van Moolenbroek 	t_initconf(T_config);
291*00b67f09SDavid van Moolenbroek 	if (T_debug)
292*00b67f09SDavid van Moolenbroek 		t_dumpconf(T_config);
293*00b67f09SDavid van Moolenbroek 
294*00b67f09SDavid van Moolenbroek 	/*
295*00b67f09SDavid van Moolenbroek 	 * Now invoke all the test cases.
296*00b67f09SDavid van Moolenbroek 	 */
297*00b67f09SDavid van Moolenbroek 
298*00b67f09SDavid van Moolenbroek 	tnum = 0;
299*00b67f09SDavid van Moolenbroek 	pts = &T_testlist[0];
300*00b67f09SDavid van Moolenbroek 	while (*pts->pfv != NULL) {
301*00b67f09SDavid van Moolenbroek 		if (T_tvec[tnum / 8] & (0x01 << (tnum % 8))) {
302*00b67f09SDavid van Moolenbroek #ifndef WIN32
303*00b67f09SDavid van Moolenbroek 			if (subprocs) {
304*00b67f09SDavid van Moolenbroek 				T_pid = fork();
305*00b67f09SDavid van Moolenbroek 				if (T_pid == 0) {
306*00b67f09SDavid van Moolenbroek 					(*pts->pfv)();
307*00b67f09SDavid van Moolenbroek 					exit(0);
308*00b67f09SDavid van Moolenbroek 				} else if (T_pid > 0) {
309*00b67f09SDavid van Moolenbroek 
310*00b67f09SDavid van Moolenbroek 					T_int = 0;
311*00b67f09SDavid van Moolenbroek 					sa.sa_handler = t_sighandler;
312*00b67f09SDavid van Moolenbroek 					(void)sigaction(SIGALRM, &sa, NULL);
313*00b67f09SDavid van Moolenbroek 					alarm(T_timeout);
314*00b67f09SDavid van Moolenbroek 
315*00b67f09SDavid van Moolenbroek 					deadpid = (pid_t) -1;
316*00b67f09SDavid van Moolenbroek 					while (deadpid != T_pid) {
317*00b67f09SDavid van Moolenbroek 					    deadpid =
318*00b67f09SDavid van Moolenbroek 						    waitpid(T_pid, &status, 0);
319*00b67f09SDavid van Moolenbroek 					    if (deadpid == T_pid) {
320*00b67f09SDavid van Moolenbroek 						    if (WIFSIGNALED(status)) {
321*00b67f09SDavid van Moolenbroek 							if (WTERMSIG(status) ==
322*00b67f09SDavid van Moolenbroek 							    SIGTERM)
323*00b67f09SDavid van Moolenbroek 								t_info(
324*00b67f09SDavid van Moolenbroek 						  "the test case timed out\n");
325*00b67f09SDavid van Moolenbroek 							else
326*00b67f09SDavid van Moolenbroek 								t_info(
327*00b67f09SDavid van Moolenbroek 					 "the test case caused exception %d\n",
328*00b67f09SDavid van Moolenbroek 							     WTERMSIG(status));
329*00b67f09SDavid van Moolenbroek 							t_result(T_UNRESOLVED);
330*00b67f09SDavid van Moolenbroek 						    }
331*00b67f09SDavid van Moolenbroek 					    } else if ((deadpid == -1) &&
332*00b67f09SDavid van Moolenbroek 						       (errno == EINTR) &&
333*00b67f09SDavid van Moolenbroek 						       T_int) {
334*00b67f09SDavid van Moolenbroek 						    kill(T_pid, SIGTERM);
335*00b67f09SDavid van Moolenbroek 						    T_int = 0;
336*00b67f09SDavid van Moolenbroek 					    }
337*00b67f09SDavid van Moolenbroek 					    else if ((deadpid == -1) &&
338*00b67f09SDavid van Moolenbroek 						     ((errno == ECHILD) ||
339*00b67f09SDavid van Moolenbroek 						      (errno == ESRCH)))
340*00b67f09SDavid van Moolenbroek 						    break;
341*00b67f09SDavid van Moolenbroek 					}
342*00b67f09SDavid van Moolenbroek 
343*00b67f09SDavid van Moolenbroek 					alarm(0);
344*00b67f09SDavid van Moolenbroek 					sa.sa_handler = SIG_IGN;
345*00b67f09SDavid van Moolenbroek 					(void)sigaction(SIGALRM, &sa, NULL);
346*00b67f09SDavid van Moolenbroek 				} else {
347*00b67f09SDavid van Moolenbroek 					t_info("fork failed, errno == %d\n",
348*00b67f09SDavid van Moolenbroek 					       errno);
349*00b67f09SDavid van Moolenbroek 					t_result(T_UNRESOLVED);
350*00b67f09SDavid van Moolenbroek 				}
351*00b67f09SDavid van Moolenbroek 			}
352*00b67f09SDavid van Moolenbroek 			else {
353*00b67f09SDavid van Moolenbroek 				(*pts->pfv)();
354*00b67f09SDavid van Moolenbroek 			}
355*00b67f09SDavid van Moolenbroek #else
356*00b67f09SDavid van Moolenbroek 			(*pts->pfv)();
357*00b67f09SDavid van Moolenbroek #endif
358*00b67f09SDavid van Moolenbroek 		}
359*00b67f09SDavid van Moolenbroek 		++pts;
360*00b67f09SDavid van Moolenbroek 		++tnum;
361*00b67f09SDavid van Moolenbroek 	}
362*00b67f09SDavid van Moolenbroek 
363*00b67f09SDavid van Moolenbroek 	snprintf(T_buf, sizeof(T_buf), "%s:", argv[0]);
364*00b67f09SDavid van Moolenbroek 	len = strlen(T_buf);
365*00b67f09SDavid van Moolenbroek 	(void) t_getdate(T_buf + len, T_BIGBUF - len);
366*00b67f09SDavid van Moolenbroek 	t_putinfo("E", T_buf);
367*00b67f09SDavid van Moolenbroek 
368*00b67f09SDavid van Moolenbroek 	return(0);
369*00b67f09SDavid van Moolenbroek }
370*00b67f09SDavid van Moolenbroek 
371*00b67f09SDavid van Moolenbroek void
t_assert(const char * component,int anum,int class,const char * what,...)372*00b67f09SDavid van Moolenbroek t_assert(const char *component, int anum, int class, const char *what, ...) {
373*00b67f09SDavid van Moolenbroek 	va_list	args;
374*00b67f09SDavid van Moolenbroek 	char buf[T_BIGBUF];
375*00b67f09SDavid van Moolenbroek 
376*00b67f09SDavid van Moolenbroek 	(void)printf("T:%s:%d:%s\n", component, anum, class == T_REQUIRED ?
377*00b67f09SDavid van Moolenbroek 		     "A" : "C");
378*00b67f09SDavid van Moolenbroek 
379*00b67f09SDavid van Moolenbroek 	/*
380*00b67f09SDavid van Moolenbroek 	 * Format text to a buffer.
381*00b67f09SDavid van Moolenbroek 	 */
382*00b67f09SDavid van Moolenbroek 	va_start(args, what);
383*00b67f09SDavid van Moolenbroek 	(void)vsnprintf(buf, sizeof(buf), what, args);
384*00b67f09SDavid van Moolenbroek 	va_end(args);
385*00b67f09SDavid van Moolenbroek 
386*00b67f09SDavid van Moolenbroek 	(void)t_putinfo("A", buf);
387*00b67f09SDavid van Moolenbroek 	(void)printf("\n");
388*00b67f09SDavid van Moolenbroek }
389*00b67f09SDavid van Moolenbroek 
390*00b67f09SDavid van Moolenbroek void
t_info(const char * format,...)391*00b67f09SDavid van Moolenbroek t_info(const char *format, ...) {
392*00b67f09SDavid van Moolenbroek 	va_list	args;
393*00b67f09SDavid van Moolenbroek 	char buf[T_BIGBUF];
394*00b67f09SDavid van Moolenbroek 
395*00b67f09SDavid van Moolenbroek 	va_start(args, format);
396*00b67f09SDavid van Moolenbroek 	(void) vsnprintf(buf, sizeof(buf), format, args);
397*00b67f09SDavid van Moolenbroek 	va_end(args);
398*00b67f09SDavid van Moolenbroek 	(void) t_putinfo("I", buf);
399*00b67f09SDavid van Moolenbroek }
400*00b67f09SDavid van Moolenbroek 
401*00b67f09SDavid van Moolenbroek void
t_result(int result)402*00b67f09SDavid van Moolenbroek t_result(int result) {
403*00b67f09SDavid van Moolenbroek 	const char *p;
404*00b67f09SDavid van Moolenbroek 
405*00b67f09SDavid van Moolenbroek 	switch (result) {
406*00b67f09SDavid van Moolenbroek 		case T_PASS:
407*00b67f09SDavid van Moolenbroek 			p = "PASS";
408*00b67f09SDavid van Moolenbroek 			break;
409*00b67f09SDavid van Moolenbroek 		case T_FAIL:
410*00b67f09SDavid van Moolenbroek 			p = "FAIL";
411*00b67f09SDavid van Moolenbroek 			break;
412*00b67f09SDavid van Moolenbroek 		case T_UNRESOLVED:
413*00b67f09SDavid van Moolenbroek 			p = "UNRESOLVED";
414*00b67f09SDavid van Moolenbroek 			break;
415*00b67f09SDavid van Moolenbroek 		case T_SKIPPED:
416*00b67f09SDavid van Moolenbroek 			p = "SKIPPED";
417*00b67f09SDavid van Moolenbroek 			break;
418*00b67f09SDavid van Moolenbroek 		case T_UNTESTED:
419*00b67f09SDavid van Moolenbroek 			p = "UNTESTED";
420*00b67f09SDavid van Moolenbroek 			break;
421*00b67f09SDavid van Moolenbroek 		case T_THREADONLY:
422*00b67f09SDavid van Moolenbroek 			p = "THREADONLY";
423*00b67f09SDavid van Moolenbroek 			break;
424*00b67f09SDavid van Moolenbroek 		case T_PKCS11ONLY:
425*00b67f09SDavid van Moolenbroek 			p = "PKCS11ONLY";
426*00b67f09SDavid van Moolenbroek 			break;
427*00b67f09SDavid van Moolenbroek 		default:
428*00b67f09SDavid van Moolenbroek 			p = "UNKNOWN";
429*00b67f09SDavid van Moolenbroek 			break;
430*00b67f09SDavid van Moolenbroek 	}
431*00b67f09SDavid van Moolenbroek 	printf("R:%s\n", p);
432*00b67f09SDavid van Moolenbroek }
433*00b67f09SDavid van Moolenbroek 
434*00b67f09SDavid van Moolenbroek char *
t_getenv(const char * name)435*00b67f09SDavid van Moolenbroek t_getenv(const char *name) {
436*00b67f09SDavid van Moolenbroek 	char	*n;
437*00b67f09SDavid van Moolenbroek 	char	**p;
438*00b67f09SDavid van Moolenbroek 	size_t	len;
439*00b67f09SDavid van Moolenbroek 
440*00b67f09SDavid van Moolenbroek 	n = NULL;
441*00b67f09SDavid van Moolenbroek 	if (name && *name) {
442*00b67f09SDavid van Moolenbroek 
443*00b67f09SDavid van Moolenbroek 		p = &T_env[0];
444*00b67f09SDavid van Moolenbroek 		len = strlen(name);
445*00b67f09SDavid van Moolenbroek 
446*00b67f09SDavid van Moolenbroek 		while (*p != NULL) {
447*00b67f09SDavid van Moolenbroek 			if (strncmp(*p, name, len) == 0) {
448*00b67f09SDavid van Moolenbroek 				if ( *(*p + len) == '=') {
449*00b67f09SDavid van Moolenbroek 					n = *p + len + 1;
450*00b67f09SDavid van Moolenbroek 					break;
451*00b67f09SDavid van Moolenbroek 				}
452*00b67f09SDavid van Moolenbroek 			}
453*00b67f09SDavid van Moolenbroek 			++p;
454*00b67f09SDavid van Moolenbroek 		}
455*00b67f09SDavid van Moolenbroek 	}
456*00b67f09SDavid van Moolenbroek 	return(n);
457*00b67f09SDavid van Moolenbroek }
458*00b67f09SDavid van Moolenbroek 
459*00b67f09SDavid van Moolenbroek /*
460*00b67f09SDavid van Moolenbroek  *
461*00b67f09SDavid van Moolenbroek  * Read in the config file at path, initializing T_env.
462*00b67f09SDavid van Moolenbroek  *
463*00b67f09SDavid van Moolenbroek  * note: no format checking for now ...
464*00b67f09SDavid van Moolenbroek  *
465*00b67f09SDavid van Moolenbroek  */
466*00b67f09SDavid van Moolenbroek 
467*00b67f09SDavid van Moolenbroek static int
t_initconf(const char * path)468*00b67f09SDavid van Moolenbroek t_initconf(const char *path) {
469*00b67f09SDavid van Moolenbroek 
470*00b67f09SDavid van Moolenbroek 	int	n;
471*00b67f09SDavid van Moolenbroek 	int	rval;
472*00b67f09SDavid van Moolenbroek 	char	**p;
473*00b67f09SDavid van Moolenbroek 	FILE	*fp;
474*00b67f09SDavid van Moolenbroek 
475*00b67f09SDavid van Moolenbroek 	rval = -1;
476*00b67f09SDavid van Moolenbroek 
477*00b67f09SDavid van Moolenbroek 	fp = fopen(path, "r");
478*00b67f09SDavid van Moolenbroek 	if (fp != NULL) {
479*00b67f09SDavid van Moolenbroek 		n = 0;
480*00b67f09SDavid van Moolenbroek 		p = &T_env[0];
481*00b67f09SDavid van Moolenbroek 		while (n < T_MAXENV) {
482*00b67f09SDavid van Moolenbroek 			*p = t_fgetbs(fp);
483*00b67f09SDavid van Moolenbroek 			if (*p == NULL)
484*00b67f09SDavid van Moolenbroek 				break;
485*00b67f09SDavid van Moolenbroek 			if ((**p == '#') || (strchr(*p, '=') == NULL)) {
486*00b67f09SDavid van Moolenbroek 				/*
487*00b67f09SDavid van Moolenbroek 				 * Skip comments and other junk.
488*00b67f09SDavid van Moolenbroek 				 */
489*00b67f09SDavid van Moolenbroek 				(void)free(*p);
490*00b67f09SDavid van Moolenbroek 				continue;
491*00b67f09SDavid van Moolenbroek 			}
492*00b67f09SDavid van Moolenbroek 			++p; ++n;
493*00b67f09SDavid van Moolenbroek 		}
494*00b67f09SDavid van Moolenbroek 		(void)fclose(fp);
495*00b67f09SDavid van Moolenbroek 		rval = 0;
496*00b67f09SDavid van Moolenbroek 	}
497*00b67f09SDavid van Moolenbroek 
498*00b67f09SDavid van Moolenbroek 	return (rval);
499*00b67f09SDavid van Moolenbroek }
500*00b67f09SDavid van Moolenbroek 
501*00b67f09SDavid van Moolenbroek /*
502*00b67f09SDavid van Moolenbroek  *
503*00b67f09SDavid van Moolenbroek  * Dump T_env to stdout.
504*00b67f09SDavid van Moolenbroek  *
505*00b67f09SDavid van Moolenbroek  */
506*00b67f09SDavid van Moolenbroek 
507*00b67f09SDavid van Moolenbroek static int
t_dumpconf(const char * path)508*00b67f09SDavid van Moolenbroek t_dumpconf(const char *path) {
509*00b67f09SDavid van Moolenbroek 	int	rval;
510*00b67f09SDavid van Moolenbroek 	char	**p;
511*00b67f09SDavid van Moolenbroek 	FILE	*fp;
512*00b67f09SDavid van Moolenbroek 
513*00b67f09SDavid van Moolenbroek 	rval = -1;
514*00b67f09SDavid van Moolenbroek 	fp = fopen(path, "r");
515*00b67f09SDavid van Moolenbroek 	if (fp != NULL) {
516*00b67f09SDavid van Moolenbroek 		p = &T_env[0];
517*00b67f09SDavid van Moolenbroek 		while (*p != NULL) {
518*00b67f09SDavid van Moolenbroek 			printf("C:%s\n", *p);
519*00b67f09SDavid van Moolenbroek 			++p;
520*00b67f09SDavid van Moolenbroek 		}
521*00b67f09SDavid van Moolenbroek 		(void) fclose(fp);
522*00b67f09SDavid van Moolenbroek 		rval = 0;
523*00b67f09SDavid van Moolenbroek 	}
524*00b67f09SDavid van Moolenbroek 	return(rval);
525*00b67f09SDavid van Moolenbroek }
526*00b67f09SDavid van Moolenbroek 
527*00b67f09SDavid van Moolenbroek /*
528*00b67f09SDavid van Moolenbroek  *
529*00b67f09SDavid van Moolenbroek  * Read a newline or EOF terminated string from fp.
530*00b67f09SDavid van Moolenbroek  * On success:
531*00b67f09SDavid van Moolenbroek  *	return a malloc'd buf containing the string with
532*00b67f09SDavid van Moolenbroek  *	the newline converted to a '\0'.
533*00b67f09SDavid van Moolenbroek  * On error:
534*00b67f09SDavid van Moolenbroek  *	return NULL.
535*00b67f09SDavid van Moolenbroek  *
536*00b67f09SDavid van Moolenbroek  * Caller is responsible for freeing buf.
537*00b67f09SDavid van Moolenbroek  *
538*00b67f09SDavid van Moolenbroek  */
539*00b67f09SDavid van Moolenbroek 
540*00b67f09SDavid van Moolenbroek char *
t_fgetbs(FILE * fp)541*00b67f09SDavid van Moolenbroek t_fgetbs(FILE *fp) {
542*00b67f09SDavid van Moolenbroek 	int	c;
543*00b67f09SDavid van Moolenbroek 	size_t	n;
544*00b67f09SDavid van Moolenbroek 	size_t	size;
545*00b67f09SDavid van Moolenbroek 	char	*buf, *old;
546*00b67f09SDavid van Moolenbroek 	char	*p;
547*00b67f09SDavid van Moolenbroek 
548*00b67f09SDavid van Moolenbroek 	n = 0;
549*00b67f09SDavid van Moolenbroek 	size = T_BUFSIZ;
550*00b67f09SDavid van Moolenbroek 	old = buf = (char *) malloc(T_BUFSIZ * sizeof(char));
551*00b67f09SDavid van Moolenbroek 
552*00b67f09SDavid van Moolenbroek 	if (buf != NULL) {
553*00b67f09SDavid van Moolenbroek 		p = buf;
554*00b67f09SDavid van Moolenbroek 		while ((c = fgetc(fp)) != EOF) {
555*00b67f09SDavid van Moolenbroek 
556*00b67f09SDavid van Moolenbroek 			if ((c == '\r') || (c == '\n'))
557*00b67f09SDavid van Moolenbroek 				break;
558*00b67f09SDavid van Moolenbroek 
559*00b67f09SDavid van Moolenbroek 			*p++ = c;
560*00b67f09SDavid van Moolenbroek 			++n;
561*00b67f09SDavid van Moolenbroek 			if ( n >= size ) {
562*00b67f09SDavid van Moolenbroek 				size += T_BUFSIZ;
563*00b67f09SDavid van Moolenbroek 				buf = (char *)realloc(buf,
564*00b67f09SDavid van Moolenbroek 						      size * sizeof(char));
565*00b67f09SDavid van Moolenbroek 				if (buf == NULL)
566*00b67f09SDavid van Moolenbroek 					goto err;
567*00b67f09SDavid van Moolenbroek 				old = buf;
568*00b67f09SDavid van Moolenbroek 				p = buf + n;
569*00b67f09SDavid van Moolenbroek 			}
570*00b67f09SDavid van Moolenbroek 		}
571*00b67f09SDavid van Moolenbroek 		*p = '\0';
572*00b67f09SDavid van Moolenbroek 		if (c == EOF && n == 0U) {
573*00b67f09SDavid van Moolenbroek 			free(buf);
574*00b67f09SDavid van Moolenbroek 			return (NULL);
575*00b67f09SDavid van Moolenbroek 		}
576*00b67f09SDavid van Moolenbroek 		return (buf);
577*00b67f09SDavid van Moolenbroek 	} else {
578*00b67f09SDavid van Moolenbroek  err:
579*00b67f09SDavid van Moolenbroek 		if (old != NULL)
580*00b67f09SDavid van Moolenbroek 			free(old);
581*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "malloc/realloc failed %d", errno);
582*00b67f09SDavid van Moolenbroek 		return(NULL);
583*00b67f09SDavid van Moolenbroek 	}
584*00b67f09SDavid van Moolenbroek }
585*00b67f09SDavid van Moolenbroek 
586*00b67f09SDavid van Moolenbroek /*
587*00b67f09SDavid van Moolenbroek  *
588*00b67f09SDavid van Moolenbroek  * Put info to log, using key.
589*00b67f09SDavid van Moolenbroek  * For now, just dump it out.
590*00b67f09SDavid van Moolenbroek  * Later format into pretty lines.
591*00b67f09SDavid van Moolenbroek  *
592*00b67f09SDavid van Moolenbroek  */
593*00b67f09SDavid van Moolenbroek 
594*00b67f09SDavid van Moolenbroek static int
t_putinfo(const char * key,const char * info)595*00b67f09SDavid van Moolenbroek t_putinfo(const char *key, const char *info) {
596*00b67f09SDavid van Moolenbroek 	int	rval;
597*00b67f09SDavid van Moolenbroek 
598*00b67f09SDavid van Moolenbroek 	/*
599*00b67f09SDavid van Moolenbroek 	 * For now.
600*00b67f09SDavid van Moolenbroek 	 */
601*00b67f09SDavid van Moolenbroek 	rval = printf("%s:%s", key, info);
602*00b67f09SDavid van Moolenbroek 	return(rval);
603*00b67f09SDavid van Moolenbroek }
604*00b67f09SDavid van Moolenbroek 
605*00b67f09SDavid van Moolenbroek static char *
t_getdate(char * buf,size_t buflen)606*00b67f09SDavid van Moolenbroek t_getdate(char *buf, size_t buflen) {
607*00b67f09SDavid van Moolenbroek 	size_t		n;
608*00b67f09SDavid van Moolenbroek 	time_t		t;
609*00b67f09SDavid van Moolenbroek 	struct tm	*p;
610*00b67f09SDavid van Moolenbroek 
611*00b67f09SDavid van Moolenbroek 	t = time(NULL);
612*00b67f09SDavid van Moolenbroek 	p = localtime(&t);
613*00b67f09SDavid van Moolenbroek 	n = strftime(buf, buflen - 1, "%A %d %B %H:%M:%S %Y\n", p);
614*00b67f09SDavid van Moolenbroek 	return(n != 0U ? buf : NULL);
615*00b67f09SDavid van Moolenbroek }
616*00b67f09SDavid van Moolenbroek 
617*00b67f09SDavid van Moolenbroek /*
618*00b67f09SDavid van Moolenbroek  * Some generally used utilities.
619*00b67f09SDavid van Moolenbroek  */
620*00b67f09SDavid van Moolenbroek struct dns_errormap {
621*00b67f09SDavid van Moolenbroek 	isc_result_t	result;
622*00b67f09SDavid van Moolenbroek 	const char *text;
623*00b67f09SDavid van Moolenbroek } dns_errormap[] = {
624*00b67f09SDavid van Moolenbroek 	{ ISC_R_SUCCESS,		"ISC_R_SUCCESS"		},
625*00b67f09SDavid van Moolenbroek 	{ ISC_R_EXISTS,			"ISC_R_EXISTS"		},
626*00b67f09SDavid van Moolenbroek 	{ ISC_R_NOTFOUND,		"ISC_R_NOTFOUND"	},
627*00b67f09SDavid van Moolenbroek 	{ ISC_R_NOSPACE,		"ISC_R_NOSPACE"		},
628*00b67f09SDavid van Moolenbroek 	{ ISC_R_UNEXPECTED,		"ISC_R_UNEXPECTED"	},
629*00b67f09SDavid van Moolenbroek 	{ ISC_R_UNEXPECTEDEND,		"ISC_R_UNEXPECTEDEND"	},
630*00b67f09SDavid van Moolenbroek 	{ ISC_R_RANGE,			"ISC_R_RANGE"		},
631*00b67f09SDavid van Moolenbroek 	{ DNS_R_LABELTOOLONG,		"DNS_R_LABELTOOLONG"	},
632*00b67f09SDavid van Moolenbroek 	{ DNS_R_BADESCAPE,		"DNS_R_BADESCAPE"	},
633*00b67f09SDavid van Moolenbroek 	/* { DNS_R_BADBITSTRING,	"DNS_R_BADBITSTRING"	}, */
634*00b67f09SDavid van Moolenbroek 	/* { DNS_R_BITSTRINGTOOLONG,	"DNS_R_BITSTRINGTOOLONG"}, */
635*00b67f09SDavid van Moolenbroek 	{ DNS_R_EMPTYLABEL,		"DNS_R_EMPTYLABEL"	},
636*00b67f09SDavid van Moolenbroek 	{ DNS_R_BADDOTTEDQUAD,		"DNS_R_BADDOTTEDQUAD"	},
637*00b67f09SDavid van Moolenbroek 	{ DNS_R_UNKNOWN,		"DNS_R_UNKNOWN"		},
638*00b67f09SDavid van Moolenbroek 	{ DNS_R_BADLABELTYPE,		"DNS_R_BADLABELTYPE"	},
639*00b67f09SDavid van Moolenbroek 	{ DNS_R_BADPOINTER,		"DNS_R_BADPOINTER"	},
640*00b67f09SDavid van Moolenbroek 	{ DNS_R_TOOMANYHOPS,		"DNS_R_TOOMANYHOPS"	},
641*00b67f09SDavid van Moolenbroek 	{ DNS_R_DISALLOWED,		"DNS_R_DISALLOWED"	},
642*00b67f09SDavid van Moolenbroek 	{ DNS_R_EXTRATOKEN,		"DNS_R_EXTRATOKEN"	},
643*00b67f09SDavid van Moolenbroek 	{ DNS_R_EXTRADATA,		"DNS_R_EXTRADATA"	},
644*00b67f09SDavid van Moolenbroek 	{ DNS_R_TEXTTOOLONG,		"DNS_R_TEXTTOOLONG"	},
645*00b67f09SDavid van Moolenbroek 	{ DNS_R_SYNTAX,			"DNS_R_SYNTAX"		},
646*00b67f09SDavid van Moolenbroek 	{ DNS_R_BADCKSUM,		"DNS_R_BADCKSUM"	},
647*00b67f09SDavid van Moolenbroek 	{ DNS_R_BADAAAA,		"DNS_R_BADAAAA"		},
648*00b67f09SDavid van Moolenbroek 	{ DNS_R_NOOWNER,		"DNS_R_NOOWNER"		},
649*00b67f09SDavid van Moolenbroek 	{ DNS_R_NOTTL,			"DNS_R_NOTTL"		},
650*00b67f09SDavid van Moolenbroek 	{ DNS_R_BADCLASS,		"DNS_R_BADCLASS"	},
651*00b67f09SDavid van Moolenbroek 	{ DNS_R_PARTIALMATCH,		"DNS_R_PARTIALMATCH"	},
652*00b67f09SDavid van Moolenbroek 	{ DNS_R_NEWORIGIN,		"DNS_R_NEWORIGIN"	},
653*00b67f09SDavid van Moolenbroek 	{ DNS_R_UNCHANGED,		"DNS_R_UNCHANGED"	},
654*00b67f09SDavid van Moolenbroek 	{ DNS_R_BADTTL,			"DNS_R_BADTTL"		},
655*00b67f09SDavid van Moolenbroek 	{ DNS_R_NOREDATA,		"DNS_R_NOREDATA"	},
656*00b67f09SDavid van Moolenbroek 	{ DNS_R_CONTINUE,		"DNS_R_CONTINUE"	},
657*00b67f09SDavid van Moolenbroek 	{ DNS_R_DELEGATION,		"DNS_R_DELEGATION"	},
658*00b67f09SDavid van Moolenbroek 	{ DNS_R_GLUE,			"DNS_R_GLUE"		},
659*00b67f09SDavid van Moolenbroek 	{ DNS_R_DNAME,			"DNS_R_DNAME"		},
660*00b67f09SDavid van Moolenbroek 	{ DNS_R_CNAME,			"DNS_R_CNAME"		},
661*00b67f09SDavid van Moolenbroek 	{ DNS_R_NXDOMAIN,		"DNS_R_NXDOMAIN"	},
662*00b67f09SDavid van Moolenbroek 	{ DNS_R_NXRRSET,		"DNS_R_NXRRSET"		},
663*00b67f09SDavid van Moolenbroek 	{ DNS_R_BADDB,			"DNS_R_BADDB"		},
664*00b67f09SDavid van Moolenbroek 	{ DNS_R_ZONECUT,		"DNS_R_ZONECUT"		},
665*00b67f09SDavid van Moolenbroek 	{ DNS_R_NOTZONETOP,		"DNS_R_NOTZONETOP"	},
666*00b67f09SDavid van Moolenbroek 	{ DNS_R_SEENINCLUDE,		"DNS_R_SEENINCLUDE"	},
667*00b67f09SDavid van Moolenbroek 	{ DNS_R_SINGLETON,		"DNS_R_SINGLETON"	},
668*00b67f09SDavid van Moolenbroek 	{ (isc_result_t)0, NULL }
669*00b67f09SDavid van Moolenbroek };
670*00b67f09SDavid van Moolenbroek 
671*00b67f09SDavid van Moolenbroek isc_result_t
t_dns_result_fromtext(char * name)672*00b67f09SDavid van Moolenbroek t_dns_result_fromtext(char *name) {
673*00b67f09SDavid van Moolenbroek 
674*00b67f09SDavid van Moolenbroek 	isc_result_t		result;
675*00b67f09SDavid van Moolenbroek 	struct dns_errormap	*pmap;
676*00b67f09SDavid van Moolenbroek 
677*00b67f09SDavid van Moolenbroek 	result = ISC_R_UNEXPECTED;
678*00b67f09SDavid van Moolenbroek 
679*00b67f09SDavid van Moolenbroek 	pmap = dns_errormap;
680*00b67f09SDavid van Moolenbroek 	while (pmap->text != NULL) {
681*00b67f09SDavid van Moolenbroek 		if (strcmp(name, pmap->text) == 0)
682*00b67f09SDavid van Moolenbroek 			break;
683*00b67f09SDavid van Moolenbroek 		++pmap;
684*00b67f09SDavid van Moolenbroek 	}
685*00b67f09SDavid van Moolenbroek 
686*00b67f09SDavid van Moolenbroek 	if (pmap->text != NULL)
687*00b67f09SDavid van Moolenbroek 		result = pmap->result;
688*00b67f09SDavid van Moolenbroek 
689*00b67f09SDavid van Moolenbroek 	return (result);
690*00b67f09SDavid van Moolenbroek }
691*00b67f09SDavid van Moolenbroek 
692*00b67f09SDavid van Moolenbroek struct dc_method_map {
693*00b67f09SDavid van Moolenbroek 	unsigned int	dc_method;
694*00b67f09SDavid van Moolenbroek 	const char 	*text;
695*00b67f09SDavid van Moolenbroek } dc_method_map[] = {
696*00b67f09SDavid van Moolenbroek 
697*00b67f09SDavid van Moolenbroek 	{	DNS_COMPRESS_NONE,	"DNS_COMPRESS_NONE"	},
698*00b67f09SDavid van Moolenbroek 	{	DNS_COMPRESS_GLOBAL14,	"DNS_COMPRESS_GLOBAL14"	},
699*00b67f09SDavid van Moolenbroek 	{	DNS_COMPRESS_ALL,	"DNS_COMPRESS_ALL"	},
700*00b67f09SDavid van Moolenbroek 	{	0,			NULL			}
701*00b67f09SDavid van Moolenbroek };
702*00b67f09SDavid van Moolenbroek 
703*00b67f09SDavid van Moolenbroek unsigned int
t_dc_method_fromtext(char * name)704*00b67f09SDavid van Moolenbroek t_dc_method_fromtext(char *name) {
705*00b67f09SDavid van Moolenbroek 	unsigned int		dc_method;
706*00b67f09SDavid van Moolenbroek 	struct dc_method_map	*pmap;
707*00b67f09SDavid van Moolenbroek 
708*00b67f09SDavid van Moolenbroek 	dc_method = DNS_COMPRESS_NONE;
709*00b67f09SDavid van Moolenbroek 
710*00b67f09SDavid van Moolenbroek 	pmap = dc_method_map;
711*00b67f09SDavid van Moolenbroek 	while (pmap->text != NULL) {
712*00b67f09SDavid van Moolenbroek 		if (strcmp(name, pmap->text) == 0)
713*00b67f09SDavid van Moolenbroek 			break;
714*00b67f09SDavid van Moolenbroek 		++pmap;
715*00b67f09SDavid van Moolenbroek 	}
716*00b67f09SDavid van Moolenbroek 
717*00b67f09SDavid van Moolenbroek 	if (pmap->text != NULL)
718*00b67f09SDavid van Moolenbroek 		dc_method = pmap->dc_method;
719*00b67f09SDavid van Moolenbroek 
720*00b67f09SDavid van Moolenbroek 	return(dc_method);
721*00b67f09SDavid van Moolenbroek }
722*00b67f09SDavid van Moolenbroek 
723*00b67f09SDavid van Moolenbroek int
t_bustline(char * line,char ** toks)724*00b67f09SDavid van Moolenbroek t_bustline(char *line, char **toks) {
725*00b67f09SDavid van Moolenbroek 	int	cnt;
726*00b67f09SDavid van Moolenbroek 	char	*p;
727*00b67f09SDavid van Moolenbroek 
728*00b67f09SDavid van Moolenbroek 	cnt = 0;
729*00b67f09SDavid van Moolenbroek 	if (line && *line) {
730*00b67f09SDavid van Moolenbroek 		while ((p = strtok(line, "\t")) && (cnt < T_MAXTOKS)) {
731*00b67f09SDavid van Moolenbroek 			*toks++ = p;
732*00b67f09SDavid van Moolenbroek 			line = NULL;
733*00b67f09SDavid van Moolenbroek 			++cnt;
734*00b67f09SDavid van Moolenbroek 		}
735*00b67f09SDavid van Moolenbroek 	}
736*00b67f09SDavid van Moolenbroek 	return(cnt);
737*00b67f09SDavid van Moolenbroek }
738*00b67f09SDavid van Moolenbroek 
739*00b67f09SDavid van Moolenbroek static void
printhelp(void)740*00b67f09SDavid van Moolenbroek printhelp(void) {
741*00b67f09SDavid van Moolenbroek 	int		cnt;
742*00b67f09SDavid van Moolenbroek 	testspec_t	*pts;
743*00b67f09SDavid van Moolenbroek 
744*00b67f09SDavid van Moolenbroek 	cnt = 1;
745*00b67f09SDavid van Moolenbroek 	pts = &T_testlist[0];
746*00b67f09SDavid van Moolenbroek 
747*00b67f09SDavid van Moolenbroek 	printf("Available tests:\n");
748*00b67f09SDavid van Moolenbroek 	while (pts->func_name) {
749*00b67f09SDavid van Moolenbroek 		printf("\t%d\t%s\n", cnt, pts->func_name);
750*00b67f09SDavid van Moolenbroek 		++pts;
751*00b67f09SDavid van Moolenbroek 		++cnt;
752*00b67f09SDavid van Moolenbroek 	}
753*00b67f09SDavid van Moolenbroek }
754*00b67f09SDavid van Moolenbroek 
755*00b67f09SDavid van Moolenbroek static void
printusage(void)756*00b67f09SDavid van Moolenbroek printusage(void) {
757*00b67f09SDavid van Moolenbroek 	printf("Usage:\n%s\n", Usage);
758*00b67f09SDavid van Moolenbroek }
759*00b67f09SDavid van Moolenbroek 
760*00b67f09SDavid van Moolenbroek int
t_eval(const char * filename,int (* func)(char **),int nargs)761*00b67f09SDavid van Moolenbroek t_eval(const char *filename, int (*func)(char **), int nargs) {
762*00b67f09SDavid van Moolenbroek 	FILE		*fp;
763*00b67f09SDavid van Moolenbroek 	char		*p;
764*00b67f09SDavid van Moolenbroek 	int		line;
765*00b67f09SDavid van Moolenbroek 	int		cnt;
766*00b67f09SDavid van Moolenbroek 	int		result;
767*00b67f09SDavid van Moolenbroek 	int		tresult;
768*00b67f09SDavid van Moolenbroek 	int		nfails;
769*00b67f09SDavid van Moolenbroek 	int		nprobs;
770*00b67f09SDavid van Moolenbroek 	int		npass;
771*00b67f09SDavid van Moolenbroek 	char		*tokens[T_MAXTOKS + 1];
772*00b67f09SDavid van Moolenbroek 
773*00b67f09SDavid van Moolenbroek 	tresult = T_UNTESTED;
774*00b67f09SDavid van Moolenbroek 	npass = 0;
775*00b67f09SDavid van Moolenbroek 	nfails = 0;
776*00b67f09SDavid van Moolenbroek 	nprobs = 0;
777*00b67f09SDavid van Moolenbroek 
778*00b67f09SDavid van Moolenbroek 	fp = fopen(filename, "r");
779*00b67f09SDavid van Moolenbroek 	if (fp != NULL) {
780*00b67f09SDavid van Moolenbroek 		line = 0;
781*00b67f09SDavid van Moolenbroek 		while ((p = t_fgetbs(fp)) != NULL) {
782*00b67f09SDavid van Moolenbroek 
783*00b67f09SDavid van Moolenbroek 			++line;
784*00b67f09SDavid van Moolenbroek 
785*00b67f09SDavid van Moolenbroek 			/*
786*00b67f09SDavid van Moolenbroek 			 * Skip comment lines.
787*00b67f09SDavid van Moolenbroek 			 */
788*00b67f09SDavid van Moolenbroek 			if ((isspace((unsigned char)*p)) || (*p == '#')) {
789*00b67f09SDavid van Moolenbroek 				(void)free(p);
790*00b67f09SDavid van Moolenbroek 				continue;
791*00b67f09SDavid van Moolenbroek 			}
792*00b67f09SDavid van Moolenbroek 
793*00b67f09SDavid van Moolenbroek 			cnt = t_bustline(p, tokens);
794*00b67f09SDavid van Moolenbroek 			if (cnt == nargs) {
795*00b67f09SDavid van Moolenbroek 				tresult = func(tokens);
796*00b67f09SDavid van Moolenbroek 				switch (tresult) {
797*00b67f09SDavid van Moolenbroek 				case T_PASS:
798*00b67f09SDavid van Moolenbroek 					++npass;
799*00b67f09SDavid van Moolenbroek 					break;
800*00b67f09SDavid van Moolenbroek 				case T_FAIL:
801*00b67f09SDavid van Moolenbroek 					++nfails;
802*00b67f09SDavid van Moolenbroek 					break;
803*00b67f09SDavid van Moolenbroek 				case T_SKIPPED:
804*00b67f09SDavid van Moolenbroek 				case T_UNTESTED:
805*00b67f09SDavid van Moolenbroek 					break;
806*00b67f09SDavid van Moolenbroek 				default:
807*00b67f09SDavid van Moolenbroek 					++nprobs;
808*00b67f09SDavid van Moolenbroek 					break;
809*00b67f09SDavid van Moolenbroek 				}
810*00b67f09SDavid van Moolenbroek 			} else {
811*00b67f09SDavid van Moolenbroek 				t_info("bad format in %s at line %d\n",
812*00b67f09SDavid van Moolenbroek 						filename, line);
813*00b67f09SDavid van Moolenbroek 				++nprobs;
814*00b67f09SDavid van Moolenbroek 			}
815*00b67f09SDavid van Moolenbroek 
816*00b67f09SDavid van Moolenbroek 			(void)free(p);
817*00b67f09SDavid van Moolenbroek 		}
818*00b67f09SDavid van Moolenbroek 		(void)fclose(fp);
819*00b67f09SDavid van Moolenbroek 	} else {
820*00b67f09SDavid van Moolenbroek 		t_info("Missing datafile %s\n", filename);
821*00b67f09SDavid van Moolenbroek 		++nprobs;
822*00b67f09SDavid van Moolenbroek 	}
823*00b67f09SDavid van Moolenbroek 
824*00b67f09SDavid van Moolenbroek 	result = T_UNRESOLVED;
825*00b67f09SDavid van Moolenbroek 
826*00b67f09SDavid van Moolenbroek 	if (nfails == 0 && nprobs == 0 && npass > 0)
827*00b67f09SDavid van Moolenbroek 		result = T_PASS;
828*00b67f09SDavid van Moolenbroek 	else if (nfails > 0)
829*00b67f09SDavid van Moolenbroek 		result = T_FAIL;
830*00b67f09SDavid van Moolenbroek 	else if (npass == 0)
831*00b67f09SDavid van Moolenbroek 		result = tresult;
832*00b67f09SDavid van Moolenbroek 
833*00b67f09SDavid van Moolenbroek 	return (result);
834*00b67f09SDavid van Moolenbroek }
835*00b67f09SDavid van Moolenbroek 
836*00b67f09SDavid van Moolenbroek #ifdef WIN32
837*00b67f09SDavid van Moolenbroek void
t_settests(const testspec_t list[])838*00b67f09SDavid van Moolenbroek t_settests(const testspec_t list[]) {
839*00b67f09SDavid van Moolenbroek 	int			tnum;
840*00b67f09SDavid van Moolenbroek 	const testspec_t	*pts;
841*00b67f09SDavid van Moolenbroek 
842*00b67f09SDavid van Moolenbroek 	memset(T_testlist, 0, sizeof(T_testlist));
843*00b67f09SDavid van Moolenbroek 
844*00b67f09SDavid van Moolenbroek 	pts = &list[0];
845*00b67f09SDavid van Moolenbroek 	for (tnum = 0; tnum < T_MAXTESTS - 1; pts++, tnum++) {
846*00b67f09SDavid van Moolenbroek 		if (*pts->pfv == NULL)
847*00b67f09SDavid van Moolenbroek 			break;
848*00b67f09SDavid van Moolenbroek 		T_testlist[tnum] = *pts;
849*00b67f09SDavid van Moolenbroek 	}
850*00b67f09SDavid van Moolenbroek }
851*00b67f09SDavid van Moolenbroek #endif
852