1#!/usr/bin/perl
2#
3# Copyright (C) 2004, 2007  Internet Systems Consortium, Inc. ("ISC")
4# Copyright (C) 2000, 2001  Internet Software Consortium.
5#
6# Permission to use, copy, modify, and/or distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16# PERFORMANCE OF THIS SOFTWARE.
17
18# $Id: digcomp.pl,v 1.14 2007/06/19 23:47:00 tbox Exp $
19
20# Compare two files, each with the output from dig, for differences.
21# Ignore "unimportant" differences, like ordering of NS lines, TTL's,
22# etc...
23
24$file1 = $ARGV[0];
25$file2 = $ARGV[1];
26
27$count = 0;
28$firstname = "";
29$status = 0;
30$rcode1 = "none";
31$rcode2 = "none";
32
33open(FILE1, $file1) || die("open: $file1: $!\n");
34while (<FILE1>) {
35	chomp;
36	if (/^;.+status:\s+(\S+).+$/) {
37		$rcode1 = $1;
38	}
39	next if (/^;/);
40	if (/^(\S+)\s+\S+\s+(\S+)\s+(\S+)\s+(.+)$/) {
41		$name = $1;
42		$class = $2;
43		$type = $3;
44		$value = $4;
45		if ($type eq "SOA") {
46			$firstname = $name if ($firstname eq "");
47			if ($name eq $firstname) {
48				$name = "$name$count";
49				$count++;
50			}
51		}
52		if ($entry{"$name ; $class.$type ; $value"} ne "") {
53			$line = $entry{"$name ; $class.$type ; $value"};
54			print("Duplicate entry in $file1:\n> $_\n< $line\n");
55		} else {
56			$entry{"$name ; $class.$type ; $value"} = $_;
57		}
58	}
59}
60close(FILE1);
61
62$printed = 0;
63
64open(FILE2, $file2) || die("open: $file2: $!\n");
65while (<FILE2>) {
66	chomp;
67	if (/^;.+status:\s+(\S+).+$/) {
68		$rcode2 = $1;
69	}
70	next if (/^;/);
71	if (/^(\S+)\s+\S+\s+(\S+)\s+(\S+)\s+(.+)$/) {
72		$name = $1;
73		$class = $2;
74		$type = $3;
75		$value = $4;
76		if (($name eq $firstname) && ($type eq "SOA")) {
77			$count--;
78			$name = "$name$count";
79		}
80		if ($entry{"$name ; $class.$type ; $value"} ne "") {
81			$entry{"$name ; $class.$type ; $value"} = "";
82		} else {
83			print("Only in $file2 (missing from $file1):\n")
84			    if ($printed == 0);
85			print("> $_\n");
86			$printed++;
87			$status = 1;
88		}
89	}
90}
91close(FILE2);
92
93$printed = 0;
94
95foreach $key (keys(%entry)) {
96	if ($entry{$key} ne "") {
97		print("Only in $file1 (missing from $file2):\n")
98		    if ($printed == 0);
99		print("< $entry{$key}\n");
100		$status = 1;
101		$printed++;
102	}
103}
104
105if ($rcode1 ne $rcode2) {
106	print("< status: $rcode1\n");
107	print("> status: $rcode2\n");
108	$status = 1;
109}
110
111exit($status);
112