3 /*****************************************************************
5 ** @(#) domaincmp.c -- compare two domain names
7 ** Copyright (c) Aug 2005, Karle Boss, Holger Zuleger (kaho).
8 ** All rights reserved.
10 ** This software is open source.
12 ** Redistribution and use in source and binary forms, with or without
13 ** modification, are permitted provided that the following conditions
16 ** Redistributions of source code must retain the above copyright notice,
17 ** this list of conditions and the following disclaimer.
19 ** Redistributions in binary form must reproduce the above copyright notice,
20 ** this list of conditions and the following disclaimer in the documentation
21 ** and/or other materials provided with the distribution.
23 ** Neither the name of Karle Boss or Holger Zuleger (kaho) nor the
24 ** names of its contributors may be used to endorse or promote products
25 ** derived from this software without specific prior written permission.
27 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
31 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 ** POSSIBILITY OF SUCH DAMAGE.
39 *****************************************************************/
45 # include "domaincmp.h"
49 #define goto_labelstart(str, p) while ( (p) > (str) && *((p)-1) != '.' ) \
52 /*****************************************************************
53 ** int domaincmp (a, b)
54 ** compare a and b as fqdns.
55 ** return <0 | 0 | >0 as in strcmp
56 ** A subdomain is less than the corresponding parent domain,
57 ** thus domaincmp ("z.example.net", "example.net") return < 0 !!
58 *****************************************************************/
59 int domaincmp (const char *a
, const char *b
)
61 register const char *pa
;
62 register const char *pb
;
64 if ( a
== NULL
) return -1;
65 if ( b
== NULL
) return 1;
67 if ( *a
== '.' ) /* skip a leading dot */
69 if ( *b
== '.' ) /* same at the other string */
72 /* let pa and pb point to the last non dot char */
76 while ( pa
> a
&& *pa
== '.' );
81 while ( pb
> b
&& *pb
== '.' );
83 /* cmp both domains starting at the end */
84 while ( *pa
== *pb
&& pa
> a
&& pb
> b
)
87 if ( *pa
!= *pb
) /* both domains are different ? */
90 pa
++; /* set to beginning of next label */
92 goto_labelstart (a
, pa
); /* find begin of current label */
94 pb
++; /* set to beginning of next label */
96 goto_labelstart (b
, pb
); /* find begin of current label */
98 else /* maybe one of them has a subdomain */
104 goto_labelstart (a
, pa
);
109 goto_labelstart (b
, pb
);
111 return 0; /* both are at the beginning, so they are equal */
114 /* both domains are definitly unequal */
115 while ( *pa
== *pb
) /* so we have to look at the point where they differ */
121 #ifdef DOMAINCMP_TEST
135 { ".de.", ".de.", 0 },
136 { ".de", "zde", -1 },
139 { "ade", ".de", -1 },
140 { "a.de", ".de", -1 },
141 { ".de", "a.de", 1 },
142 { "a.de", "b.de", -1 },
143 { "a.de.", "b.de", -1 },
144 { "a.de", "b.de.", -1 },
145 { "a.de", "a.de.", 0 },
146 { "aa.de", "b.de", -1 },
147 { "ba.de", "b.de", 1 },
148 { "a.de", "a.dk", -1 },
149 { "anna.example.de", "anna.example.de", 0 },
150 { "anna.example.de", "annamirl.example.de", -1 },
151 { "anna.example.de", "ann.example.de", 1 },
152 { "example.de.", "xy.example.de.", 1 },
153 { "example.de.", "ab.example.de.", 1 },
154 { "example.de", "ab.example.de", 1 },
155 { "ab.example.de", "example.de", -1 },
156 { "ab.mast.de", "axt.de", 1 },
157 { "ab.mast.de", "obt.de", -1 },
158 { "abc.example.de.", "xy.example.de.", -1 },
162 const char *progname
;
163 main (int argc
, char *argv
[])
173 for ( i
= 0; ex
[i
].a
; i
++ )
178 else if ( expect
> 0 )
182 printf ("%-20s %-20s ==> %c 0 ", ex
[i
].a
, ex
[i
].b
, c
);
184 res
= domaincmp (ex
[i
].a
, ex
[i
].b
);
185 printf ("%3d ", res
);
186 if ( res
< 0 && expect
< 0 || res
> 0 && expect
> 0 || res
== 0 && expect
== 0 )