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