]> git.sur5r.net Git - bacula/bacula/blob - regress/scripts/diff.pl
regress: Add function to compute ISO time in future
[bacula/bacula] / regress / scripts / diff.pl
1 #!/usr/bin/perl -w
2
3 =head1 NAME
4
5     diff.pl -- Helper to diff files (rights, acl and content)
6
7 =head2 USAGE
8
9     diff.pl -s source -d dest [--acl | --attr]
10
11 =cut
12
13 use strict;
14 use Cwd 'chdir';
15 use File::Find;
16 no warnings 'File::Find';
17 use Digest::MD5;
18 use Getopt::Long ;
19 use Pod::Usage;
20 use Data::Dumper;
21 use Cwd;
22
23 my ($src, $dst, $help, $acl, $attr);
24 my %src_attr; 
25 my %dst_attr;
26 my $hash;
27 my $ret=0;
28
29 GetOptions("src=s"   => \$src,
30            "dst=s"   => \$dst,
31            "acl"     => \$acl,
32            "attr"    => \$attr,
33            "help"    => \$help,
34     ) or pod2usage(-verbose => 1, 
35                    -exitval => 1);
36 if (!$src or !$dst) {
37    pod2usage(-verbose => 1, 
38              -exitval => 1); 
39 }
40
41 if ($help) {
42     pod2usage(-verbose => 2, 
43               -exitval => 0);
44 }
45 my $md5 = Digest::MD5->new;
46
47 my $dir = getcwd;
48
49 chdir($src);
50 $hash = \%src_attr;
51 find(\&wanted_src, '.');
52
53 chdir ($dir);
54
55 chdir($dst);
56 $hash = \%dst_attr;
57 find(\&wanted_src, '.');
58
59 #print Data::Dumper::Dumper(\%src_attr);
60 #print Data::Dumper::Dumper(\%dst_attr);
61
62 foreach my $f (keys %src_attr)
63 {
64     if (!defined $dst_attr{$f}) {
65         $ret++;
66         print "E: Can't find $f in dst\n";
67
68     } else {
69         compare($src_attr{$f}, $dst_attr{$f});
70     }
71     delete $src_attr{$f};
72     delete $dst_attr{$f};
73 }
74
75 foreach my $f (keys %dst_attr)
76 {
77     $ret++;
78     print "E: Can't find $f in src\n";
79 }
80
81 exit $ret;
82
83 sub compare
84 {
85     my ($h1, $h2) = @_;
86     my ($f1, $f2) = ($h1->{file}, $h2->{file});
87     foreach my $k (keys %$h1) {
88         if (!exists $h2->{$k}) {
89             $ret++;
90             print "E: Can't find $k for dest $f2 ($k=$h1->{$k})\n";
91         }
92         if ($h2->{$k} ne $h1->{$k}) {
93             $ret++;
94             print "E: src and dst $f2 differ on $k ($h1->{$k} != $h2->{$k})\n";
95         }
96         delete $h1->{$k};
97         delete $h2->{$k};
98     }
99
100     foreach my $k (keys %$h2) {
101         $ret++;
102         print "E: Found $k on dst file and not on src ($k=$h2->{$k})\n";
103     }
104 }
105
106 sub wanted_src
107 {
108     my $f = $_;
109     my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
110         $atime,$mtime,$ctime,$blksize,$blocks) = stat($f);
111  
112     if (-l $f) {
113         my $target = readlink($f);
114         $hash->{$File::Find::name} = {
115             nlink => $nlink,
116             uid => $uid,
117             gid => $gid,
118             atime => $atime,
119             mtime => $mtime,
120             ctime => $ctime,
121             target => $target,
122             type => 'l',
123             file => $File::Find::name,
124         };
125
126     } elsif (-f $f)  {
127         $hash->{$File::Find::name} = {
128             mode => $mode,
129             nlink => $nlink,
130             uid => $uid,
131             gid => $gid,
132             size => $size,
133             atime => $atime,
134             mtime => $mtime,
135             ctime => $ctime,
136             type => 'f',
137             file => $File::Find::name,
138         };
139         $md5->reset;
140         open(FILE, $f) or die "Can't open '$f': $!";
141         binmode(FILE);
142         $hash->{$File::Find::name}->{md5} = $md5->addfile(*FILE)->hexdigest;
143         close(FILE);
144
145         if ($acl) {
146             $hash->{$File::Find::name}->{acl} = `getfacl $f 2>/dev/null`;
147         }
148         if ($attr) {
149             $hash->{$File::Find::name}->{attr} = `getfattr $f 2>/dev/null`;
150         }
151
152     } elsif (-d $f) {
153         $hash->{$File::Find::name} = {
154             mode => $mode,
155             uid => $uid,
156             gid => $gid,
157             atime => $atime,
158             mtime => $mtime,
159             ctime => $ctime,
160             type => 'd',
161             file =>  $File::Find::name,
162         };
163         if ($acl) {
164             $hash->{$File::Find::name}->{acl} = `getfacl $f 2>/dev/null`;
165         }
166         if ($attr) {
167             $hash->{$File::Find::name}->{attr} = `getfattr $f 2>/dev/null`;
168         }
169
170     } else {
171
172     }
173 }