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