digcomp.pl revision 1.1.1.2
1#!/usr/bin/perl
2#
3# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
4#
5# This Source Code Form is subject to the terms of the Mozilla Public
6# License, v. 2.0. If a copy of the MPL was not distributed with this
7# file, You can obtain one at http://mozilla.org/MPL/2.0/.
8#
9# See the COPYRIGHT file distributed with this work for additional
10# information regarding copyright ownership.
11
12# Compare two files, each with the output from dig, for differences.
13# Ignore "unimportant" differences, like ordering of NS lines, TTL's,
14# etc...
15
16$lc = 0;
17if ($ARGV[0] eq "--lc") {
18	$lc = 1;
19	shift;
20}
21$file1 = $ARGV[0];
22$file2 = $ARGV[1];
23
24$count = 0;
25$firstname = "";
26$status = 0;
27$rcode1 = "none";
28$rcode2 = "none";
29
30open(FILE1, $file1) || die("open: $file1: $!\n");
31while (<FILE1>) {
32	~ s/\r\n//g;
33	~ s/\n//g;
34	if (/^;.+status:\s+(\S+).+$/) {
35		$rcode1 = $1;
36	}
37	next if (/^;/);
38	if (/^(\S+)\s+\S+\s+(\S+)\s+(\S+)\s+(.+)$/) {
39		$name = $1;
40		$class = $2;
41		$type = $3;
42		$value = $4;
43		if ($lc) {
44			$name = lc($name);
45			$value = lc($value);
46		}
47		if ($type eq "SOA") {
48			$firstname = $name if ($firstname eq "");
49			if ($name eq $firstname) {
50				$name = "$name$count";
51				$count++;
52			}
53		}
54		if ($entry{"$name ; $class.$type ; $value"} ne "") {
55			$line = $entry{"$name ; $class.$type ; $value"};
56			print("Duplicate entry in $file1:\n> $_\n< $line\n");
57		} else {
58			$entry{"$name ; $class.$type ; $value"} = $_;
59		}
60	} elsif (/^(\S+)\s+\S+\s+(\S+)\s+(\S+)\s*$/) {
61		$name = $1;
62		$class = $2;
63		$type = $3;
64		$value = "";
65		if ($lc) {
66			$name = lc($name);
67			$value = lc($value);
68		}
69		if ($type eq "SOA") {
70			$firstname = $name if ($firstname eq "");
71			if ($name eq $firstname) {
72				$name = "$name$count";
73				$count++;
74			}
75		}
76		if ($entry{"$name ; $class.$type ; $value"} ne "") {
77			$line = $entry{"$name ; $class.$type ; $value"};
78			print("Duplicate entry in $file1:\n> $_\n< $line\n");
79		} else {
80			$entry{"$name ; $class.$type ; $value"} = $_;
81		}
82	}
83}
84close(FILE1);
85
86$printed = 0;
87
88open(FILE2, $file2) || die("open: $file2: $!\n");
89while (<FILE2>) {
90	~ s/\r\n//g;
91	~ s/\n//g;
92	if (/^;.+status:\s+(\S+).+$/) {
93		$rcode2 = $1;
94	}
95	next if (/^;/);
96	if (/^(\S+)\s+\S+\s+(\S+)\s+(\S+)\s+(.+)$/) {
97		$name = $1;
98		$class = $2;
99		$type = $3;
100		$value = $4;
101		if ($lc) {
102			$name = lc($name);
103			$value = lc($value);
104		}
105		if (($name eq $firstname) && ($type eq "SOA")) {
106			$count--;
107			$name = "$name$count";
108		}
109		if ($entry{"$name ; $class.$type ; $value"} ne "") {
110			$entry{"$name ; $class.$type ; $value"} = "";
111		} else {
112			print("Only in $file2 (missing from $file1):\n")
113			    if ($printed == 0);
114			print("> $_\n");
115			$printed++;
116			$status = 1;
117		}
118	} elsif (/^(\S+)\s+\S+\s+(\S+)\s+(\S+)\s*$/) {
119		$name = $1;
120		$class = $2;
121		$type = $3;
122		$value = "";
123		if ($lc) {
124			$name = lc($name);
125			$value = lc($value);
126		}
127		if (($name eq $firstname) && ($type eq "SOA")) {
128			$count--;
129			$name = "$name$count";
130		}
131		if ($entry{"$name ; $class.$type ; $value"} ne "") {
132			$entry{"$name ; $class.$type ; $value"} = "";
133		} else {
134			print("Only in $file2 (missing from $file1):\n")
135			    if ($printed == 0);
136			print("> $_\n");
137			$printed++;
138			$status = 1;
139		}
140	}
141}
142close(FILE2);
143
144$printed = 0;
145
146foreach $key (keys(%entry)) {
147	if ($entry{$key} ne "") {
148		print("Only in $file1 (missing from $file2):\n")
149		    if ($printed == 0);
150		print("< $entry{$key}\n");
151		$status = 1;
152		$printed++;
153	}
154}
155
156if ($rcode1 ne $rcode2) {
157	print("< status: $rcode1\n");
158	print("> status: $rcode2\n");
159	$status = 1;
160}
161
162exit($status);
163