6 eval { require Archive::Tar; };
7 *Archive::Tar::new = sub {die("Archive::Tar is not available\n")} unless defined &Archive::Tar::new;
10 # Archlinux support, based on the GSoC work of Nikolay Rysev <mad.f3ka@gmail.com>
12 # parse a PKGBUILD file
16 $str =~ s/([ \t\"\'])/sprintf("%%%02X", ord($1))/ge;
24 while ($str =~ /([\"\'])/) {
26 $str =~ s/$q(.*?)$q/quote($1)/e;
28 my @args = split(/[ \t]+/, $str);
30 s/%([a-fA-F0-9]{2})/chr(hex($1))/ge
36 my ($config, $pkgbuild) = @_;
39 if (!open(PKG, '<', $pkgbuild)) {
40 $ret->{'error'} = "$pkgbuild: $!";
48 last unless /^([a-zA-Z0-9_]*)=(\(?)(.*?)$/;
52 while ($val !~ s/\)\s*$//s) {
54 last unless defined $nextline;
56 $val .= ' ' . $nextline;
59 $vars{$var} = [ unquotesplit($val) ];
62 $ret->{'name'} = $vars{'pkgname'}->[0] if $vars{'pkgname'};
63 $ret->{'version'} = $vars{'pkgver'}->[0] if $vars{'pkgver'};
64 $ret->{'deps'} = $vars{'makedepends'} || [];
71 return 0 unless open(F, '<', $fn);
73 return 0 unless read(F, $h, 5) == 5;
75 return $h eq "\3757zXZ";
81 my $pid = open($nh, '-|');
82 return undef unless defined $pid;
84 $SIG{'PIPE'} = 'DEFAULT';
85 exec('xzdec', '-dc', $fn);
95 die("arch pkg query not implemented for file handles\n");
97 if ($handle =~ /\.xz$/ || islzma($handle)) {
98 $handle = lzmadec($handle);
100 my $tar = Archive::Tar->new;
101 my @read = $tar->read($handle, 1, {'filter' => '^\.PKGINFO$', 'limit' => 1});
102 die("$handle: not an arch package file\n") unless @read == 1;
103 my $pkginfo = $read[0]->get_content;
104 die("$handle: not an arch package file\n") unless $pkginfo;
106 $vars{'_pkginfo'} = $pkginfo;
107 for my $l (split('\n', $pkginfo)) {
108 next unless $l =~ /^(.*?) = (.*)$/;
109 push @{$vars{$1}}, $2;
117 die("arch pkg query not implemented for file handles\n");
119 if ($handle =~ /\.xz$/ || islzma($handle)) {
120 $handle = lzmadec($handle);
123 my $tar = Archive::Tar->new;
124 # we use filter_cb here so that Archive::Tar skips the file contents
125 $tar->read($handle, 1, {'filter_cb' => sub {
127 push @files, $entry->name unless $entry->is_longlink || (@files && $files[-1] eq $entry->name);
130 shift @files if @files && $files[0] eq '.PKGINFO';
135 my ($handle, %opts) = @_;
136 my $vars = queryvars($handle);
138 $ret->{'name'} = $vars->{'pkgname'}->[0] if $vars->{'pkgname'};
139 $ret->{'hdrmd5'} = Digest::MD5::md5_hex($vars->{'_pkginfo'});
140 $ret->{'provides'} = $vars->{'provides'} || [];
141 $ret->{'requires'} = $vars->{'depend'} || [];
142 if ($vars->{'pkgname'}) {
143 my $selfprovides = $vars->{'pkgname'}->[0];
144 $selfprovides .= "=$vars->{'pkgver'}->[0]" if $vars->{'pkgver'};
145 push @{$ret->{'provides'}}, $selfprovides unless @{$ret->{'provides'} || []} && $ret->{'provides'}->[-1] eq $selfprovides;
148 if ($vars->{'pkgver'}) {
149 my $evr = $vars->{'pkgver'}->[0];
150 if ($evr =~ /^([0-9]+):(.*)$/) {
151 $ret->{'epoch'} = $1;
154 $ret->{'version'} = $evr;
155 if ($evr =~ /^(.*)-(.*?)$/) {
156 $ret->{'version'} = $1;
157 $ret->{'release'} = $2;
160 $ret->{'arch'} = $vars->{'arch'}->[0] if $vars->{'arch'};
162 if ($opts{'description'}) {
163 $ret->{'description'} = $vars->{'pkgdesc'}->[0] if $vars->{'pkgdesc'};
165 # arch packages don't seem to have a source :(
166 # fake it so that the package isn't confused with a src package
167 $ret->{'source'} = $ret->{'name'} if defined $ret->{'name'};
174 die("arch pkg query not implemented for file handles\n");
176 if ($handle =~ /\.xz$/ || islzma($handle)) {
177 $handle = lzmadec($handle);
179 my $tar = Archive::Tar->new;
180 my @read = $tar->read($handle, 1, {'filter' => '^\.PKGINFO$', 'limit' => 1});
181 die("$handle: not an arch package file\n") unless @read == 1;
182 my $pkginfo = $read[0]->get_content;
183 die("$handle: not an arch package file\n") unless $pkginfo;
184 return Digest::MD5::md5_hex($pkginfo);
191 my @parts = split(/\n\n+/s, $data);
192 for my $part (@parts) {
193 my @p = split("\n", $part);
195 if ($p eq '%NAME%') {
196 $d->{'name'} = $p[0];
197 } elsif ($p eq '%VERSION%') {
198 $d->{'version'} = $p[0];
199 } elsif ($p eq '%ARCH%') {
200 $d->{'arch'} = $p[0];
201 } elsif ($p eq '%BUILDDATE%') {
202 $d->{'buildtime'} = $p[0];
203 } elsif ($p eq '%FILENAME%') {
204 $d->{'filename'} = $p[0];
205 } elsif ($p eq '%PROVIDES%') {
206 push @{$d->{'provides'}}, @p;
207 } elsif ($p eq '%DEPENDS%') {
208 push @{$d->{'requires'}}, @p;