summaryrefslogtreecommitdiffstats
path: root/lib/MDV/Distribconf/Utils.pm
blob: 1551789a1768bbadefc3da6b11f4849b96519cb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package MDV::Distribconf::Utils;

use strict;
use warnings;
use MDV::Packdrakeng;
use Digest::MD5;
use Devel::Peek;

our ($VERSION) = (qq$Revision$ =~ /(\d+)/)[0];

=head1 NAME

MDV::Distribconf::Utils

=head1 DESCRIPTION

Contains basic functions used by Distribconf

=head1 FUNCTIONS

=head2 hdlist_vs_dir($hdlistfile, @dirs)

Return two arrayrefs about rpms included only in hdlist or in directories

=cut

sub hdlist_vs_dir {
    my ($hdlist, @dir) = @_;
    my (@only_pack, @only_dir);
    my @rpms;
    foreach my $dir (@dir) {
        push(@rpms, grep { -e $_ } glob("$dir/*.rpm"));
    }
    @rpms = sort { ($b =~ m:.*/+(.*):)[0] cmp ($a =~ m:([^/]+)$:)[0] } @rpms;
    if (-f $hdlist and my $pack = MDV::Packdrakeng->open(archive => $hdlist)) {
        my $hdlisttime = (stat($hdlist))[9];
        my (undef, $files, undef) = $pack->getcontent();
        my @hdrs = sort { $b cmp $a } map { "$_.rpm" } @{$files || []};
        my ($r, $h) = ("", "");
        do {
            my $base_r = ($r =~ m:([^/]+)$:)[0] || '';
            my $comp = ($base_r cmp $h);
            my $st_d = (stat($r))[9] if ($r);
            if ($comp < 0) { push(@only_pack, $h); }
            elsif ($comp > 0) { push(@only_dir, $base_r); }
            elsif ($r && (!defined($st_d) || $st_d > $hdlisttime)) {
                push(@only_pack, $h);
                push(@only_dir, ($r =~ m:.*/+(.*):)[0]);
            }

            if ($comp <= 0) {
                $h = shift(@hdrs) || '';
            } 
            if ($comp >= 0) {
                $r = shift(@rpms) || '';
            }
        } while (scalar(@rpms) || scalar(@hdrs));
    } else {
        return(undef, [ map { m:.*/+(.*):; $1 } @rpms ]);
    }
    return (\@only_pack, \@only_dir);
}

=head2 checkmd5($md5file, @files)

Return an array ref to unsync file found and a hashref containing
files and their found md5.

=cut

sub checkmd5 {
    my ($md5file, @files) = @_;
    my %foundmd5;
    foreach my $file (@files) {
        my ($basename) = $file =~ m:.*/+([^/]*)$:; #: vi syntax coloring
        if (open(my $hfile, "<", $file)) {
            my $ctx = Digest::MD5->new;
            $ctx->addfile($hfile);
            close($hfile);
            $foundmd5{$basename} = $ctx->hexdigest;
        } else {
            $foundmd5{$basename} = '';
        }
    }
    open(my $hmd5, "<", $md5file) or return([ keys %foundmd5 ], \%foundmd5);
    my %md5;
    while (<$hmd5>) {
        chomp;
        s/#.*//;
        /^(.{32})  (.*)/ or next;
        $md5{$2} = $1;
    }
    close($hmd5);
    my @badfiles = grep { $foundmd5{$_} ne ($md5{$_} || '') } keys %foundmd5;
    return (\@badfiles, \%foundmd5);
}

1;

__END__

=head1 SEE ALSO

L<MDV::Distribconf>

=head1 AUTHOR

Olivier Thauvin <nanardon@mandriva.org>

=head1 LICENSE AND COPYRIGHT

(c) 2005, 2006, 2007 Olivier Thauvin
(c) 2005, 2006, 2007 Mandriva

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

=cut