summaryrefslogtreecommitdiffstats
path: root/contrib/zkt/domaincmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/zkt/domaincmp.c')
-rw-r--r--contrib/zkt/domaincmp.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/contrib/zkt/domaincmp.c b/contrib/zkt/domaincmp.c
new file mode 100644
index 0000000..7d2486f
--- /dev/null
+++ b/contrib/zkt/domaincmp.c
@@ -0,0 +1,190 @@
+/*****************************************************************
+**
+** @(#) domaincmp.c -- compare two domain names
+**
+** Copyright (c) Aug 2005, Karle Boss, Holger Zuleger (kaho).
+** All rights reserved.
+**
+** This software is open source.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions
+** are met:
+**
+** Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** Neither the name of Karle Boss or Holger Zuleger (kaho) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+** POSSIBILITY OF SUCH DAMAGE.
+**
+*****************************************************************/
+# include <stdio.h>
+# include <string.h>
+# include <assert.h>
+# include <ctype.h>
+#define extern
+# include "domaincmp.h"
+#undef extern
+
+
+#define goto_labelstart(str, p) while ( (p) > (str) && *((p)-1) != '.' ) \
+ (p)--
+
+/*****************************************************************
+** int domaincmp (a, b)
+** compare a and b as fqdns.
+** return <0 | 0 | >0 as in strcmp
+** A subdomain is less than the corresponding parent domain,
+** thus domaincmp ("z.example.net", "example.net") return < 0 !!
+*****************************************************************/
+int domaincmp (const char *a, const char *b)
+{
+ register const char *pa;
+ register const char *pb;
+
+ if ( a == NULL ) return -1;
+ if ( b == NULL ) return 1;
+
+ if ( *a == '.' ) /* skip a leading dot */
+ a++;
+ if ( *b == '.' ) /* same at the other string */
+ b++;
+
+ /* let pa and pb point to the last non dot char */
+ pa = a + strlen (a);
+ do
+ pa--;
+ while ( pa > a && *pa == '.' );
+
+ pb = b + strlen (b);
+ do
+ pb--;
+ while ( pb > b && *pb == '.' );
+
+ /* cmp both domains starting at the end */
+ while ( *pa == *pb && pa > a && pb > b )
+ pa--, pb--;
+
+ if ( *pa != *pb ) /* both domains are different ? */
+ {
+ if ( *pa == '.' )
+ pa++; /* set to beginning of next label */
+ else
+ goto_labelstart (a, pa); /* find begin of current label */
+ if ( *pb == '.' )
+ pb++; /* set to beginning of next label */
+ else
+ goto_labelstart (b, pb); /* find begin of current label */
+ }
+ else /* maybe one of them has a subdomain */
+ {
+ if ( pa > a )
+ if ( pa[-1] == '.' )
+ return -1;
+ else
+ goto_labelstart (a, pa);
+ else if ( pb > b )
+ if ( pb[-1] == '.' )
+ return 1;
+ else
+ goto_labelstart (b, pb);
+ else
+ return 0; /* both are at the beginning, so they are equal */
+ }
+
+ /* both domains are definitly unequal */
+ while ( *pa == *pb ) /* so we have to look at the point where they differ */
+ pa++, pb++;
+
+ return *pa - *pb;
+}
+
+#ifdef DOMAINCMP_TEST
+static struct {
+ char *a;
+ char *b;
+ int res;
+} ex[] = {
+ { ".", ".", 0 },
+ { "test", "", 1 },
+ { "", "test2", -1 },
+ { "", "", 0 },
+ { "de", "de", 0 },
+ { ".de", "de", 0 },
+ { "de.", "de.", 0 },
+ { ".de", ".de", 0 },
+ { ".de.", ".de.", 0 },
+ { ".de", "zde", -1 },
+ { ".de", "ade", 1 },
+ { "zde", ".de", 1 },
+ { "ade", ".de", -1 },
+ { "a.de", ".de", -1 },
+ { ".de", "a.de", 1 },
+ { "a.de", "b.de", -1 },
+ { "a.de.", "b.de", -1 },
+ { "a.de", "b.de.", -1 },
+ { "a.de", "a.de.", 0 },
+ { "aa.de", "b.de", -1 },
+ { "ba.de", "b.de", 1 },
+ { "a.de", "a.dk", -1 },
+ { "anna.example.de", "anna.example.de", 0 },
+ { "anna.example.de", "annamirl.example.de", -1 },
+ { "anna.example.de", "ann.example.de", 1 },
+ { "example.de.", "xy.example.de.", 1 },
+ { "example.de.", "ab.example.de.", 1 },
+ { "example.de", "ab.example.de", 1 },
+ { "ab.example.de", "example.de", -1 },
+ { "ab.mast.de", "axt.de", 1 },
+ { "ab.mast.de", "obt.de", -1 },
+ { "abc.example.de.", "xy.example.de.", -1 },
+ { NULL, NULL, 0 }
+};
+
+const char *progname;
+main (int argc, char *argv[])
+{
+
+ int expect;
+ int res;
+ int c;
+ int i;
+
+ progname = *argv;
+
+ for ( i = 0; ex[i].a; i++ )
+ {
+ expect = ex[i].res;
+ if ( expect < 0 )
+ c = '<';
+ else if ( expect > 0 )
+ c = '>';
+ else
+ c = '=';
+ printf ("%-20s %-20s ==> %c 0 ", ex[i].a, ex[i].b, c);
+ fflush (stdout);
+ res = domaincmp (ex[i].a, ex[i].b);
+ printf ("%3d ", res);
+ if ( res < 0 && expect < 0 || res > 0 && expect > 0 || res == 0 && expect == 0 )
+ puts ("ok");
+ else
+ puts ("not ok");
+ }
+}
+#endif