1*00b67f09SDavid van Moolenbroek /*	$NetBSD: domaincmp.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*****************************************************************
4*00b67f09SDavid van Moolenbroek **
5*00b67f09SDavid van Moolenbroek **	@(#) domaincmp.c -- compare two domain names
6*00b67f09SDavid van Moolenbroek **
7*00b67f09SDavid van Moolenbroek **	Copyright (c) Aug 2005, Karle Boss, Holger Zuleger (kaho).
8*00b67f09SDavid van Moolenbroek **	isparentdomain() (c) Mar 2010 by Holger Zuleger
9*00b67f09SDavid van Moolenbroek **	All rights reserved.
10*00b67f09SDavid van Moolenbroek **
11*00b67f09SDavid van Moolenbroek **	This software is open source.
12*00b67f09SDavid van Moolenbroek **
13*00b67f09SDavid van Moolenbroek **	Redistribution and use in source and binary forms, with or without
14*00b67f09SDavid van Moolenbroek **	modification, are permitted provided that the following conditions
15*00b67f09SDavid van Moolenbroek **	are met:
16*00b67f09SDavid van Moolenbroek **
17*00b67f09SDavid van Moolenbroek **	Redistributions of source code must retain the above copyright notice,
18*00b67f09SDavid van Moolenbroek **	this list of conditions and the following disclaimer.
19*00b67f09SDavid van Moolenbroek **
20*00b67f09SDavid van Moolenbroek **	Redistributions in binary form must reproduce the above copyright notice,
21*00b67f09SDavid van Moolenbroek **	this list of conditions and the following disclaimer in the documentation
22*00b67f09SDavid van Moolenbroek **	and/or other materials provided with the distribution.
23*00b67f09SDavid van Moolenbroek **
24*00b67f09SDavid van Moolenbroek **	Neither the name of Karle Boss or Holger Zuleger (kaho) nor the
25*00b67f09SDavid van Moolenbroek **	names of its contributors may be used to endorse or promote products
26*00b67f09SDavid van Moolenbroek **	derived from this software without specific prior written permission.
27*00b67f09SDavid van Moolenbroek **
28*00b67f09SDavid van Moolenbroek **	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29*00b67f09SDavid van Moolenbroek **	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30*00b67f09SDavid van Moolenbroek **	TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31*00b67f09SDavid van Moolenbroek **	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
32*00b67f09SDavid van Moolenbroek **	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33*00b67f09SDavid van Moolenbroek **	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34*00b67f09SDavid van Moolenbroek **	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35*00b67f09SDavid van Moolenbroek **	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36*00b67f09SDavid van Moolenbroek **	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37*00b67f09SDavid van Moolenbroek **	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38*00b67f09SDavid van Moolenbroek **	POSSIBILITY OF SUCH DAMAGE.
39*00b67f09SDavid van Moolenbroek **
40*00b67f09SDavid van Moolenbroek *****************************************************************/
41*00b67f09SDavid van Moolenbroek # include <stdio.h>
42*00b67f09SDavid van Moolenbroek # include <string.h>
43*00b67f09SDavid van Moolenbroek # include <assert.h>
44*00b67f09SDavid van Moolenbroek # include <ctype.h>
45*00b67f09SDavid van Moolenbroek #define extern
46*00b67f09SDavid van Moolenbroek # include "domaincmp.h"
47*00b67f09SDavid van Moolenbroek #undef extern
48*00b67f09SDavid van Moolenbroek 
49*00b67f09SDavid van Moolenbroek 
50*00b67f09SDavid van Moolenbroek #define	goto_labelstart(str, p)	while ( (p) > (str) && *((p)-1) != '.' ) \
51*00b67f09SDavid van Moolenbroek 					(p)--
52*00b67f09SDavid van Moolenbroek 
53*00b67f09SDavid van Moolenbroek /*****************************************************************
54*00b67f09SDavid van Moolenbroek **      int domaincmp (a, b)
55*00b67f09SDavid van Moolenbroek **      compare a and b as fqdns.
56*00b67f09SDavid van Moolenbroek **      return <0 | 0 | >0 as in strcmp
57*00b67f09SDavid van Moolenbroek **      A subdomain is less than the corresponding parent domain,
58*00b67f09SDavid van Moolenbroek **      thus domaincmp ("z.example.net", "example.net") return < 0 !!
59*00b67f09SDavid van Moolenbroek *****************************************************************/
domaincmp(const char * a,const char * b)60*00b67f09SDavid van Moolenbroek int     domaincmp (const char *a, const char *b)
61*00b67f09SDavid van Moolenbroek {
62*00b67f09SDavid van Moolenbroek 	return domaincmp_dir (a, b, 1);
63*00b67f09SDavid van Moolenbroek }
64*00b67f09SDavid van Moolenbroek 
65*00b67f09SDavid van Moolenbroek /*****************************************************************
66*00b67f09SDavid van Moolenbroek **      int domaincmp_dir (a, b, subdomain_above)
67*00b67f09SDavid van Moolenbroek **      compare a and b as fqdns.
68*00b67f09SDavid van Moolenbroek **      return <0 | 0 | >0 as in strcmp
69*00b67f09SDavid van Moolenbroek **      A subdomain is less than the corresponding parent domain,
70*00b67f09SDavid van Moolenbroek **      thus domaincmp ("z.example.net", "example.net") return < 0 !!
71*00b67f09SDavid van Moolenbroek *****************************************************************/
domaincmp_dir(const char * a,const char * b,int subdomain_above)72*00b67f09SDavid van Moolenbroek int     domaincmp_dir (const char *a, const char *b, int subdomain_above)
73*00b67f09SDavid van Moolenbroek {
74*00b67f09SDavid van Moolenbroek 	register const  char    *pa;
75*00b67f09SDavid van Moolenbroek 	register const  char    *pb;
76*00b67f09SDavid van Moolenbroek 	int	dir;
77*00b67f09SDavid van Moolenbroek 
78*00b67f09SDavid van Moolenbroek 	if ( a == NULL ) return -1;
79*00b67f09SDavid van Moolenbroek 	if ( b == NULL ) return 1;
80*00b67f09SDavid van Moolenbroek 
81*00b67f09SDavid van Moolenbroek 	if ( subdomain_above )
82*00b67f09SDavid van Moolenbroek 		dir = 1;
83*00b67f09SDavid van Moolenbroek 	else
84*00b67f09SDavid van Moolenbroek 		dir = -1;
85*00b67f09SDavid van Moolenbroek 
86*00b67f09SDavid van Moolenbroek 	if ( *a == '.' )	/* skip a leading dot */
87*00b67f09SDavid van Moolenbroek 		a++;
88*00b67f09SDavid van Moolenbroek 	if ( *b == '.' )	/* same at the other string */
89*00b67f09SDavid van Moolenbroek 		b++;
90*00b67f09SDavid van Moolenbroek 
91*00b67f09SDavid van Moolenbroek 	/* let pa and pb point to the last non dot char */
92*00b67f09SDavid van Moolenbroek 	pa = a + strlen (a);
93*00b67f09SDavid van Moolenbroek 	do
94*00b67f09SDavid van Moolenbroek 		pa--;
95*00b67f09SDavid van Moolenbroek 	while ( pa > a && *pa == '.' );
96*00b67f09SDavid van Moolenbroek 
97*00b67f09SDavid van Moolenbroek 	pb = b + strlen (b);
98*00b67f09SDavid van Moolenbroek 	do
99*00b67f09SDavid van Moolenbroek 		pb--;
100*00b67f09SDavid van Moolenbroek 	while ( pb > b && *pb == '.' );
101*00b67f09SDavid van Moolenbroek 
102*00b67f09SDavid van Moolenbroek 	/* cmp  both domains starting at the end */
103*00b67f09SDavid van Moolenbroek 	while ( *pa == *pb && pa > a && pb > b )
104*00b67f09SDavid van Moolenbroek 		pa--, pb--;
105*00b67f09SDavid van Moolenbroek 
106*00b67f09SDavid van Moolenbroek 	if ( *pa != *pb )	/* both domains are different ? */
107*00b67f09SDavid van Moolenbroek 	{
108*00b67f09SDavid van Moolenbroek 		if ( *pa == '.' )
109*00b67f09SDavid van Moolenbroek 			pa++;			/* set to beginning of next label */
110*00b67f09SDavid van Moolenbroek 		else
111*00b67f09SDavid van Moolenbroek 			goto_labelstart (a, pa);	/* find begin of current label */
112*00b67f09SDavid van Moolenbroek 		if ( *pb == '.' )
113*00b67f09SDavid van Moolenbroek 			pb++;			/* set to beginning of next label */
114*00b67f09SDavid van Moolenbroek 		else
115*00b67f09SDavid van Moolenbroek 			goto_labelstart (b, pb);	/* find begin of current label */
116*00b67f09SDavid van Moolenbroek 	}
117*00b67f09SDavid van Moolenbroek 	else		/* maybe one of them has a subdomain */
118*00b67f09SDavid van Moolenbroek 	{
119*00b67f09SDavid van Moolenbroek 		if ( pa > a )
120*00b67f09SDavid van Moolenbroek 			if ( pa[-1] == '.' )
121*00b67f09SDavid van Moolenbroek 				return -1 * dir;
122*00b67f09SDavid van Moolenbroek 			else
123*00b67f09SDavid van Moolenbroek 				goto_labelstart (a, pa);
124*00b67f09SDavid van Moolenbroek 		else if ( pb > b )
125*00b67f09SDavid van Moolenbroek 			if ( pb[-1] == '.' )
126*00b67f09SDavid van Moolenbroek 				return 1 * dir;
127*00b67f09SDavid van Moolenbroek 			else
128*00b67f09SDavid van Moolenbroek 				goto_labelstart (b, pb);
129*00b67f09SDavid van Moolenbroek 		else
130*00b67f09SDavid van Moolenbroek 			return 0;	/* both are at the beginning, so they are equal */
131*00b67f09SDavid van Moolenbroek 	}
132*00b67f09SDavid van Moolenbroek 
133*00b67f09SDavid van Moolenbroek 	/* both domains are definitly unequal */
134*00b67f09SDavid van Moolenbroek 	while ( *pa == *pb )	/* so we have to look at the point where they differ */
135*00b67f09SDavid van Moolenbroek 		pa++, pb++;
136*00b67f09SDavid van Moolenbroek 
137*00b67f09SDavid van Moolenbroek 	return *pa - *pb;
138*00b67f09SDavid van Moolenbroek }
139*00b67f09SDavid van Moolenbroek 
140*00b67f09SDavid van Moolenbroek /*****************************************************************
141*00b67f09SDavid van Moolenbroek **
142*00b67f09SDavid van Moolenbroek **	int	issubdomain ("child", "parent")
143*00b67f09SDavid van Moolenbroek **
144*00b67f09SDavid van Moolenbroek **	"child" and "parent" are standardized domain names in such
145*00b67f09SDavid van Moolenbroek **	a way that even both domain names are ending with a dot,
146*00b67f09SDavid van Moolenbroek **	or none of them.
147*00b67f09SDavid van Moolenbroek **
148*00b67f09SDavid van Moolenbroek **	returns 1 if "child" is a subdomain of "parent"
149*00b67f09SDavid van Moolenbroek **	returns 0 if "child" is not a subdomain of "parent"
150*00b67f09SDavid van Moolenbroek **
151*00b67f09SDavid van Moolenbroek *****************************************************************/
issubdomain(const char * child,const char * parent)152*00b67f09SDavid van Moolenbroek int	issubdomain (const char *child, const char *parent)
153*00b67f09SDavid van Moolenbroek {
154*00b67f09SDavid van Moolenbroek 	const	char	*p;
155*00b67f09SDavid van Moolenbroek 	const	char	*cdot;
156*00b67f09SDavid van Moolenbroek 	int	ccnt;
157*00b67f09SDavid van Moolenbroek 	int	pcnt;
158*00b67f09SDavid van Moolenbroek 
159*00b67f09SDavid van Moolenbroek 	if ( !child || !parent || *child == '\0' || *parent == '\0' )
160*00b67f09SDavid van Moolenbroek 		return 0;
161*00b67f09SDavid van Moolenbroek 
162*00b67f09SDavid van Moolenbroek 	cdot = NULL;
163*00b67f09SDavid van Moolenbroek 	pcnt = 0;
164*00b67f09SDavid van Moolenbroek 	for ( p = parent; *p; p++ )
165*00b67f09SDavid van Moolenbroek 		if ( *p == '.' )
166*00b67f09SDavid van Moolenbroek 			pcnt++;
167*00b67f09SDavid van Moolenbroek 
168*00b67f09SDavid van Moolenbroek 	ccnt = 0;
169*00b67f09SDavid van Moolenbroek 	for ( p = child; *p; p++ )
170*00b67f09SDavid van Moolenbroek 		if ( *p == '.' )
171*00b67f09SDavid van Moolenbroek 		{
172*00b67f09SDavid van Moolenbroek 			if ( ccnt == 0 )
173*00b67f09SDavid van Moolenbroek 				cdot = p;
174*00b67f09SDavid van Moolenbroek 			ccnt++;
175*00b67f09SDavid van Moolenbroek 		}
176*00b67f09SDavid van Moolenbroek 	if ( ccnt == 0 )	/* child is not a fqdn or is not deep enough ? */
177*00b67f09SDavid van Moolenbroek 		return 0;
178*00b67f09SDavid van Moolenbroek 	if ( pcnt == 0 )	/* parent is not a fqdn ? */
179*00b67f09SDavid van Moolenbroek 		return 0;
180*00b67f09SDavid van Moolenbroek 
181*00b67f09SDavid van Moolenbroek 	if ( pcnt >= ccnt )	/* parent has more levels than child ? */
182*00b67f09SDavid van Moolenbroek 		return 0;
183*00b67f09SDavid van Moolenbroek 
184*00b67f09SDavid van Moolenbroek 	/* is child a (one level) subdomain of parent ? */
185*00b67f09SDavid van Moolenbroek 	if ( strcmp (cdot+1, parent) == 0 )	/* the domains are equal ? */
186*00b67f09SDavid van Moolenbroek 		return 1;
187*00b67f09SDavid van Moolenbroek 
188*00b67f09SDavid van Moolenbroek 	return 0;
189*00b67f09SDavid van Moolenbroek }
190*00b67f09SDavid van Moolenbroek 
191*00b67f09SDavid van Moolenbroek /*****************************************************************
192*00b67f09SDavid van Moolenbroek **
193*00b67f09SDavid van Moolenbroek **	int	isparentdomain ("child", "parent", level)
194*00b67f09SDavid van Moolenbroek **
195*00b67f09SDavid van Moolenbroek **	"child" and "parent" are standardized domain names in such
196*00b67f09SDavid van Moolenbroek **	a way that even both domain names are ending with a dot,
197*00b67f09SDavid van Moolenbroek **	or none of them.
198*00b67f09SDavid van Moolenbroek **
199*00b67f09SDavid van Moolenbroek **	returns 1 if "child" is a subdomain of "parent"
200*00b67f09SDavid van Moolenbroek **	returns 0 if "child" is not a subdomain of "parent"
201*00b67f09SDavid van Moolenbroek **	returns -1 if "child" and "parent" are the same domain
202*00b67f09SDavid van Moolenbroek **
203*00b67f09SDavid van Moolenbroek *****************************************************************/
isparentdomain(const char * child,const char * parent,int level)204*00b67f09SDavid van Moolenbroek int	isparentdomain (const char *child, const char *parent, int level)
205*00b67f09SDavid van Moolenbroek {
206*00b67f09SDavid van Moolenbroek 	const	char	*p;
207*00b67f09SDavid van Moolenbroek 	const	char	*cdot;
208*00b67f09SDavid van Moolenbroek 	const	char	*pdot;
209*00b67f09SDavid van Moolenbroek 	int	ccnt;
210*00b67f09SDavid van Moolenbroek 	int	pcnt;
211*00b67f09SDavid van Moolenbroek 
212*00b67f09SDavid van Moolenbroek 	if ( !child || !parent || *child == '\0' || *parent == '\0' )
213*00b67f09SDavid van Moolenbroek 		return 0;
214*00b67f09SDavid van Moolenbroek 
215*00b67f09SDavid van Moolenbroek 	pdot = cdot = NULL;
216*00b67f09SDavid van Moolenbroek 	pcnt = 0;
217*00b67f09SDavid van Moolenbroek 	for ( p = parent; *p; p++ )
218*00b67f09SDavid van Moolenbroek 		if ( *p == '.' )
219*00b67f09SDavid van Moolenbroek 		{
220*00b67f09SDavid van Moolenbroek 			if ( pcnt == 0 )
221*00b67f09SDavid van Moolenbroek 				pdot = p;
222*00b67f09SDavid van Moolenbroek 			pcnt++;
223*00b67f09SDavid van Moolenbroek 		}
224*00b67f09SDavid van Moolenbroek 
225*00b67f09SDavid van Moolenbroek 	ccnt = 0;
226*00b67f09SDavid van Moolenbroek 	for ( p = child; *p; p++ )
227*00b67f09SDavid van Moolenbroek 		if ( *p == '.' )
228*00b67f09SDavid van Moolenbroek 		{
229*00b67f09SDavid van Moolenbroek 			if ( ccnt == 0 )
230*00b67f09SDavid van Moolenbroek 				cdot = p;
231*00b67f09SDavid van Moolenbroek 			ccnt++;
232*00b67f09SDavid van Moolenbroek 		}
233*00b67f09SDavid van Moolenbroek 	if ( ccnt == 0 || ccnt < level )	/* child is not a fqdn or is not deep enough ? */
234*00b67f09SDavid van Moolenbroek 		return 0;
235*00b67f09SDavid van Moolenbroek 	if ( pcnt == 0 )	/* parent is not a fqdn ? */
236*00b67f09SDavid van Moolenbroek 		return 0;
237*00b67f09SDavid van Moolenbroek 
238*00b67f09SDavid van Moolenbroek 	if ( pcnt > ccnt )	/* parent has more levels than child ? */
239*00b67f09SDavid van Moolenbroek 		return 0;
240*00b67f09SDavid van Moolenbroek 
241*00b67f09SDavid van Moolenbroek 	if ( pcnt == ccnt )	/* both are at the same level ? */
242*00b67f09SDavid van Moolenbroek 	{
243*00b67f09SDavid van Moolenbroek 		/* let's check the domain part */
244*00b67f09SDavid van Moolenbroek 		if ( strcmp (cdot, pdot) == 0 )	/* the domains are equal ? */
245*00b67f09SDavid van Moolenbroek 			return -1;
246*00b67f09SDavid van Moolenbroek 		return 0;
247*00b67f09SDavid van Moolenbroek 	}
248*00b67f09SDavid van Moolenbroek 
249*00b67f09SDavid van Moolenbroek 	if ( pcnt > ccnt )	/* parent has more levels than child ? */
250*00b67f09SDavid van Moolenbroek 		return 0;
251*00b67f09SDavid van Moolenbroek 
252*00b67f09SDavid van Moolenbroek 	/* is child a (one level) subdomain of parent ? */
253*00b67f09SDavid van Moolenbroek 	if ( strcmp (cdot+1, parent) == 0 )	/* the domains are equal ? */
254*00b67f09SDavid van Moolenbroek 		return 1;
255*00b67f09SDavid van Moolenbroek 
256*00b67f09SDavid van Moolenbroek 	return 0;
257*00b67f09SDavid van Moolenbroek }
258*00b67f09SDavid van Moolenbroek 
259*00b67f09SDavid van Moolenbroek #ifdef DOMAINCMP_TEST
260*00b67f09SDavid van Moolenbroek static  struct {
261*00b67f09SDavid van Moolenbroek          char    *a;
262*00b67f09SDavid van Moolenbroek          char    *b;
263*00b67f09SDavid van Moolenbroek          int     res;
264*00b67f09SDavid van Moolenbroek } ex[] = {
265*00b67f09SDavid van Moolenbroek          { ".",          ".",    0 },
266*00b67f09SDavid van Moolenbroek          { "test",       "",   1 },
267*00b67f09SDavid van Moolenbroek          { "",			 "test2", -1 },
268*00b67f09SDavid van Moolenbroek          { "",			 "",     0 },
269*00b67f09SDavid van Moolenbroek          { "de",         "de",   0 },
270*00b67f09SDavid van Moolenbroek          { ".de",         "de",   0 },
271*00b67f09SDavid van Moolenbroek          { "de.",        "de.",  0 },
272*00b67f09SDavid van Moolenbroek          { ".de",        ".de",  0 },
273*00b67f09SDavid van Moolenbroek          { ".de.",       ".de.", 0 },
274*00b67f09SDavid van Moolenbroek          { ".de",        "zde",  -1 },
275*00b67f09SDavid van Moolenbroek          { ".de",        "ade",  1 },
276*00b67f09SDavid van Moolenbroek          { "zde",        ".de",  1 },
277*00b67f09SDavid van Moolenbroek          { "ade",        ".de",  -1 },
278*00b67f09SDavid van Moolenbroek          { "a.de",       ".de",  -1 },
279*00b67f09SDavid van Moolenbroek          { ".de",        "a.de",  1 },
280*00b67f09SDavid van Moolenbroek          { "a.de",       "b.de", -1 },
281*00b67f09SDavid van Moolenbroek          { "a.de.",       "b.de", -1 },
282*00b67f09SDavid van Moolenbroek          { "a.de",       "b.de.", -1 },
283*00b67f09SDavid van Moolenbroek          { "a.de",       "a.de.", 0 },
284*00b67f09SDavid van Moolenbroek          { "aa.de",      "b.de", -1 },
285*00b67f09SDavid van Moolenbroek          { "ba.de",      "b.de", 1 },
286*00b67f09SDavid van Moolenbroek          { "a.de",       "a.dk", -1 },
287*00b67f09SDavid van Moolenbroek          { "anna.example.de",    "anna.example.de",      0 },
288*00b67f09SDavid van Moolenbroek          { "anna.example.de",    "annamirl.example.de",  -1 },
289*00b67f09SDavid van Moolenbroek          { "anna.example.de",    "ann.example.de",       1 },
290*00b67f09SDavid van Moolenbroek          { "example.de.",        "xy.example.de.",       1 },
291*00b67f09SDavid van Moolenbroek          { "example.de.",        "ab.example.de.",       1 },
292*00b67f09SDavid van Moolenbroek          { "example.de",        "ab.example.de",       1 },
293*00b67f09SDavid van Moolenbroek          { "xy.example.de.",        "example.de.",       -1 },
294*00b67f09SDavid van Moolenbroek          { "ab.example.de.",        "example.de.",       -1 },
295*00b67f09SDavid van Moolenbroek          { "ab.example.de",        "example.de",       -1 },
296*00b67f09SDavid van Moolenbroek          { "ab.mast.de",          "axt.de",             1 },
297*00b67f09SDavid van Moolenbroek          { "ab.mast.de",          "obt.de",             -1 },
298*00b67f09SDavid van Moolenbroek          { "abc.example.de.",    "xy.example.de.",       -1 },
299*00b67f09SDavid van Moolenbroek          { NULL, NULL,   0 }
300*00b67f09SDavid van Moolenbroek };
301*00b67f09SDavid van Moolenbroek 
302*00b67f09SDavid van Moolenbroek const char	*progname;
main(int argc,char * argv[])303*00b67f09SDavid van Moolenbroek main (int argc, char *argv[])
304*00b67f09SDavid van Moolenbroek {
305*00b67f09SDavid van Moolenbroek 
306*00b67f09SDavid van Moolenbroek 	int	expect;
307*00b67f09SDavid van Moolenbroek 	int	res;
308*00b67f09SDavid van Moolenbroek 	int	c;
309*00b67f09SDavid van Moolenbroek 	int	i;
310*00b67f09SDavid van Moolenbroek 
311*00b67f09SDavid van Moolenbroek 	progname = *argv;
312*00b67f09SDavid van Moolenbroek 
313*00b67f09SDavid van Moolenbroek 	for ( i = 0; ex[i].a; i++ )
314*00b67f09SDavid van Moolenbroek 	{
315*00b67f09SDavid van Moolenbroek 		expect = ex[i].res;
316*00b67f09SDavid van Moolenbroek 		if ( expect < 0 )
317*00b67f09SDavid van Moolenbroek 			c = '<';
318*00b67f09SDavid van Moolenbroek 		else if ( expect > 0 )
319*00b67f09SDavid van Moolenbroek 			c = '>';
320*00b67f09SDavid van Moolenbroek 		else
321*00b67f09SDavid van Moolenbroek 			c = '=';
322*00b67f09SDavid van Moolenbroek 		printf ("%-20s %-20s ", ex[i].a, ex[i].b);
323*00b67f09SDavid van Moolenbroek 		printf ("%3d  ", issubdomain (ex[i].a, ex[i].b));
324*00b67f09SDavid van Moolenbroek 		printf ("\t==> 0 %c ", c);
325*00b67f09SDavid van Moolenbroek 		fflush (stdout);
326*00b67f09SDavid van Moolenbroek 		res = domaincmp (ex[i].a, ex[i].b);
327*00b67f09SDavid van Moolenbroek 		printf ("%3d  ", res);
328*00b67f09SDavid van Moolenbroek 		if ( res < 0 && expect < 0 || res > 0 && expect > 0 || res == 0 && expect == 0 )
329*00b67f09SDavid van Moolenbroek 			puts ("ok");
330*00b67f09SDavid van Moolenbroek 		else
331*00b67f09SDavid van Moolenbroek 			puts ("not ok");
332*00b67f09SDavid van Moolenbroek 	}
333*00b67f09SDavid van Moolenbroek }
334*00b67f09SDavid van Moolenbroek #endif
335