]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
"unchanged" options for ldns-compare-zones
authorWillem Toorop <willem@nlnetlabs.nl>
Wed, 28 Feb 2018 15:01:30 +0000 (16:01 +0100)
committerWillem Toorop <willem@nlnetlabs.nl>
Wed, 28 Feb 2018 15:01:30 +0000 (16:01 +0100)
-u Prints the unchanged names (+ unchanged RRs in changed names when requested)
-U Prints only the unchanged RRs in changed names

Both will output the total number of unchanged names in the end

examples/ldns-compare-zones.1
examples/ldns-compare-zones.c

index 6bcb61b11183c28428533eb77ad7fb4f3162836e..bd5eb786c37ae5400c027822b0b4808a16af166c 100644 (file)
@@ -4,6 +4,8 @@ ldns-compare-zones \- read and compare two zonefiles and print differences
 .SH SYNOPSIS
 .B ldns-compare-zones
 .IR [-c]
+.IR [-U]
+.IR [-u]
 .IR [-i]
 .IR [-d]
 .IR [-z]
@@ -16,6 +18,9 @@ ldns-compare-zones \- read and compare two zonefiles and print differences
 Output is formatted to:
         +NUM_INS        \-NUM_DEL        ~NUM_CHG
 
+Except with the \fI-U\fR or \fI-u\fR option.  Then the output is formatted to:
+        +NUM_INS        \-NUM_DEL        ~NUM_CHG        =NUM_EQ
+
 .fi
 The major comparison is based on the owner name. If an owner name is present in zonefile 1, but not in zonefile 2, the resource records with this owner name are considered deleted, and counted as NUM_DEL. If an owner name is present in zonefile 2, but not in zonefile 1, the resource records with this owner name are considered inserted, and counted as NUM_INS. If an owner name is present in both, but there is a difference in the amount or content of the records, these are considered changed, and counted as NUM_CHG.
 .SH OPTIONS
@@ -23,6 +28,12 @@ The major comparison is based on the owner name. If an owner name is present in
 \fB-c\fR
 Print resource records whose owner names are in both zone files, but with different resource records. (a.k.a. changed)
 .TP
+\fB-U\fR
+From resource records whose owner names are in both zone files, but with different resource records, print the unchanged records too (a.k.a. changed++).
+.TP
+\fB-u\fR
+Print resource records whose owner names are in both zone files, and which resource records are the same. (a.k.a. unchaged)
+.TP
 \fB-i\fR
 Print resource records whose owner names are present only in ZONEFILE2 (a.k.a. inserted)
 .TP
@@ -30,7 +41,7 @@ Print resource records whose owner names are present only in ZONEFILE2 (a.k.a. i
 Print resource records whose owner names are present only in ZONEFILE1 (a.k.a. deleted)
 .TP
 \fB-a\fR
-Print all changes. Specifying this option is the same as specifying \-c \-i
+Print all changes (except unchanged). Specifying this option is the same as specifying \-c \-i
 amd \-d.
 .TP
 \fB-z\fR
index 514bcb258d843f1b5b8b7560e9536acc43e56a66..3fa88b495369555153ca4f2fe9cca4072f8bafcf 100644 (file)
 #define OP_INS '+'
 #define OP_DEL '-'
 #define OP_CHG '~'
+#define OP_EQ  '='
 
 static void 
 usage(char *prog)
 {
-       printf("Usage: %s [-v] [-i] [-d] [-c] [-s] [-e] "
+       printf("Usage: %s [-v] [-i] [-d] [-c] [-u] [-s] [-e] "
               "<zonefile1> <zonefile2>\n", prog);
        printf("       -i - print inserted\n");
        printf("       -d - print deleted\n");
        printf("       -c - print changed\n");
+       printf("       -u - print unchanged\n");
+       printf("       -U - print unchanged records in changed names\n");
        printf("       -a - print all differences (-i -d -c)\n");
        printf("       -s - do not exclude SOA record from comparison\n");
        printf("       -z - do not sort zones\n");
@@ -46,19 +49,22 @@ main(int argc, char **argv)
        ldns_zone      *z1, *z2;
        ldns_status     s;
        size_t          i      , j;
+       size_t          k      , l;
+       size_t          nc1    , nc2;
        ldns_rr_list   *rrl1, *rrl2;
        int             rr_cmp, rr_chg = 0;
        ldns_rr        *rr1 = NULL, *rr2 = NULL, *rrx = NULL;
        int             line_nr1 = 0, line_nr2 = 0;
        size_t          rrc1   , rrc2;
-       size_t          num_ins = 0, num_del = 0, num_chg = 0;
+       size_t          num_ins = 0, num_del = 0, num_chg = 0, num_eq = 0;
        int             c;
-       bool            opt_deleted = false, opt_inserted = false, opt_changed = false;
+       bool            opt_deleted = false, opt_inserted  = false;
+       bool            opt_changed = false, opt_unchanged = false, opt_Unchanged = false;
         bool           sort = true, inc_soa = false;
        bool            opt_exit_status = false;
        char            op = 0;
 
-       while ((c = getopt(argc, argv, "ahvdicesz")) != -1) {
+       while ((c = getopt(argc, argv, "ahvdicuUesz")) != -1) {
                switch (c) {
                case 'h':
                        usage(argv[0]);
@@ -89,6 +95,17 @@ main(int argc, char **argv)
                case 'c':
                        opt_changed = true;
                        break;
+
+               case 'u':
+                       opt_unchanged = true;
+                       opt_Unchanged = true;
+                       break;
+
+               case 'U':
+                       opt_Unchanged = true;
+                       opt_changed = true;
+                       break;
+
                case 'a':
                        opt_deleted = true;
                        opt_inserted = true;
@@ -198,12 +215,6 @@ main(int argc, char **argv)
                        rr2 = ldns_rr_list_rr(rrl2, j);
                        rr_cmp = ldns_rr_compare(rr1, rr2);
 
-                       /* Completely skip if the rrs are equal */
-                       if (rr_cmp == 0) {
-                               i++;
-                               j++;
-                               continue;
-                       }
                        rr_chg = ldns_dname_compare(ldns_rr_owner(rr1),
                                                                   ldns_rr_owner(rr2));
                } else if (i >= rrc1) {
@@ -267,16 +278,76 @@ main(int argc, char **argv)
                                printf("%c+", op);
                                ldns_rr_print(stdout, rr2);
                        }
+               } else {
+                       i++;
+                       j++;
+                       if ((rrx != NULL) && (ldns_dname_compare(ldns_rr_owner(rr1),
+                                                                                        ldns_rr_owner(rrx)
+                                                                                        ) != 0)) {
+                               rrx = NULL;
+                       }
+                       if (rrx == NULL) {
+                               rrx = rr1;
+
+                               /* Are all rrs with this name equal? */
+                               for ( k = i + 1
+                                   ; k < rrc1 &&
+                                     ldns_dname_compare(ldns_rr_owner(rr1), 
+                                                        ldns_rr_owner(ldns_rr_list_rr(rrl1, k))) == 0
+                                   ; k++);
+
+                               for ( l = j + 1
+                                   ; l < rrc2 &&
+                                     ldns_dname_compare(ldns_rr_owner(rr2), 
+                                                        ldns_rr_owner(ldns_rr_list_rr(rrl2, l))) == 0
+                                   ; l++);
+
+                               if ((k - i) != (l - j)) {
+                                       op = OP_CHG;
+                                       num_chg++;
+                               } else {
+                                       nc1 = k - i;
+                                       nc2 = l - j;
+                                       for ( k = i + 1, l = j + 1
+                                           ; k < nc1 && l < nc2 &&
+                                             ldns_rr_compare(ldns_rr_list_rr(rrl1, k),
+                                                             ldns_rr_list_rr(rrl2, l)) == 0
+                                           ; k++, l++);
+                                       if (k < nc1) {
+                                               op = OP_CHG;
+                                               num_chg++;
+                                       } else {
+                                               op = OP_EQ;
+                                               num_eq++;
+                                       }
+                               }
+                       }
+                       if (((op == OP_EQ ) && opt_unchanged) ||
+                           ((op == OP_CHG) && opt_Unchanged && opt_changed)) {
+                               printf("%c=", op);
+                               ldns_rr_print(stdout, rr1);
+                       }
                }
        }
 
-       printf("\t%c%u\t%c%u\t%c%u\n", 
-                 OP_INS, 
-                 (unsigned int) num_ins, 
-                 OP_DEL,
-                 (unsigned int) num_del, 
-                 OP_CHG, 
-                 (unsigned int) num_chg);
+       if (opt_unchanged || opt_Unchanged)
+               printf("\t%c%u\t%c%u\t%c%u\t%c%u\n", 
+                         OP_INS, 
+                         (unsigned int) num_ins, 
+                         OP_DEL,
+                         (unsigned int) num_del, 
+                         OP_CHG, 
+                         (unsigned int) num_chg,
+                         OP_EQ,
+                         (unsigned int) num_eq);
+       else
+               printf("\t%c%u\t%c%u\t%c%u\n", 
+                         OP_INS, 
+                         (unsigned int) num_ins, 
+                         OP_DEL,
+                         (unsigned int) num_del, 
+                         OP_CHG, 
+                         (unsigned int) num_chg);
 
        /* Free resources */
        if(inc_soa) {