1 | package Sophie::Base::Header; |
---|
2 | |
---|
3 | use strict; |
---|
4 | use warnings; |
---|
5 | use base qw(Sophie::Base); |
---|
6 | use File::Temp; |
---|
7 | use File::Copy; |
---|
8 | use Archive::Cpio; |
---|
9 | use Encode::Guess; |
---|
10 | use Encode; |
---|
11 | |
---|
12 | sub new { |
---|
13 | my ($class, $pkgid) = @_; |
---|
14 | |
---|
15 | bless(\$pkgid, $class); |
---|
16 | } |
---|
17 | |
---|
18 | sub rpm_path { |
---|
19 | my ($self) = @_; |
---|
20 | |
---|
21 | my $listrpm = $self->db->prepare_cached( |
---|
22 | q{ |
---|
23 | select * from rpmfile join rpmspath |
---|
24 | on rpmfile.path = rpmspath.path |
---|
25 | where pkgid = ? |
---|
26 | } |
---|
27 | ); |
---|
28 | $listrpm->execute($$self); |
---|
29 | |
---|
30 | return $listrpm->fetchall_hashref({}); |
---|
31 | } |
---|
32 | |
---|
33 | sub addfiles_content { |
---|
34 | my ($self, $rpm) = @_; |
---|
35 | |
---|
36 | my $tmp = File::Temp->new( UNLINK => 1, SUFFIX => '.cpio' ); |
---|
37 | unlink($tmp->filename); |
---|
38 | my $ok = 0; |
---|
39 | foreach ($rpm ? ($rpm) : (@{ $self->rpm_path })) { |
---|
40 | if (open(my $cpioh, "rpm2cpio " . quotemeta($_->{path} . '/' . |
---|
41 | $_->{filename}) . " |")) { |
---|
42 | File::Copy::copy($cpioh, $tmp); |
---|
43 | close($cpioh); |
---|
44 | $ok = 1; |
---|
45 | last; |
---|
46 | } |
---|
47 | } |
---|
48 | $ok or return; |
---|
49 | |
---|
50 | my $list_file = $self->db->prepare_cached(q{ |
---|
51 | select (rpmqueryfiles(header)).* from rpms where pkgid = ? |
---|
52 | }); |
---|
53 | $list_file->execute($$self); |
---|
54 | |
---|
55 | my $files = $list_file->fetchall_hashref([ 'dirname', 'basename' ]); |
---|
56 | |
---|
57 | my $add_content = $self->db->prepare_cached( |
---|
58 | q{ |
---|
59 | UPDATE allfiles set contents = ? where pkgid = ? and count = ? |
---|
60 | } |
---|
61 | ); |
---|
62 | seek($tmp, 0, 0); |
---|
63 | my $cpio = Archive::Cpio->new(); |
---|
64 | eval { |
---|
65 | $cpio->read_with_handler( |
---|
66 | $tmp, |
---|
67 | sub { |
---|
68 | my ($file) = @_; |
---|
69 | my ($dirname, $basename) = $file->name =~ /^(?:\.(.*\/))?([^\/]+)$/; |
---|
70 | $dirname ||= ''; |
---|
71 | my $entry = $files->{$dirname}{$basename}; |
---|
72 | for (1) { |
---|
73 | $entry->{size} > 1024 * 1024 and return 1; |
---|
74 | # Spec files and patch |
---|
75 | $entry->{flags} == 32 and last; |
---|
76 | $dirname eq '' and last; |
---|
77 | # Doc files |
---|
78 | $entry->{flags} & (1 << 1) || $entry->{flags} & (1 << 8) |
---|
79 | and last; |
---|
80 | # Config file |
---|
81 | $entry->{flags} & (1 << 0) and last; |
---|
82 | $basename =~ /\.h$/ and last; |
---|
83 | |
---|
84 | return 1; |
---|
85 | } |
---|
86 | my $content = $file->get_content; |
---|
87 | my $enc = guess_encoding($content, qw/latin1/); |
---|
88 | if ($enc && ref $enc) { |
---|
89 | $content = $enc->decode($content); |
---|
90 | |
---|
91 | $self->db->pg_savepoint('FILECONTENT'); |
---|
92 | $add_content->execute( |
---|
93 | $enc && ref $enc ? encode('utf8', $enc->decode($content)) : $content, |
---|
94 | $$self, |
---|
95 | $entry->{count}) or do { |
---|
96 | $self->db->pg_rollback_to('FILECONTENT'); |
---|
97 | }; |
---|
98 | } else { |
---|
99 | } |
---|
100 | 1; |
---|
101 | } |
---|
102 | ); |
---|
103 | }; |
---|
104 | |
---|
105 | $tmp = undef; |
---|
106 | return 1; |
---|
107 | } |
---|
108 | |
---|
109 | 1; |
---|