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);
92 my ($handle, %opts) = @_;
94 die("arch pkg query not implemented for file handles\n");
96 if ($handle =~ /\.xz$/ || islzma($handle)) {
97 $handle = lzmadec($handle);
99 my $tar = Archive::Tar->new;
100 my @read = $tar->read($handle, 1, {'filter' => '^\.PKGINFO$', 'limit' => 1});
101 die("$handle: not an arch package file\n") unless @read == 1;
102 my $pkginfo = $read[0]->get_content;
103 die("$handle: not an arch package file\n") unless $pkginfo;
105 for my $l (split('\n', $pkginfo)) {
106 next unless $l =~ /^(.*?) = (.*)$/;
107 push @{$vars{$1}}, $2;
110 $ret->{'name'} = $vars{'pkgname'}->[0] if $vars{'pkgname'};
111 $ret->{'hdrmd5'} = Digest::MD5::md5_hex($pkginfo);
112 $ret->{'provides'} = $vars{'provides'} || [];
113 $ret->{'requires'} = $vars{'depend'} || [];
114 if ($vars{'pkgname'}) {
115 my $selfprovides = $vars{'pkgname'}->[0];
116 $selfprovides .= "=$vars{'pkgver'}->[0]" if $vars{'pkgver'};
117 push @{$ret->{'provides'}}, $selfprovides unless @{$ret->{'provides'} || []} && $ret->{'provides'}->[-1] eq $selfprovides;
120 if ($vars{'pkgver'}) {
121 my $evr = $vars{'pkgver'}->[0];
122 if ($evr =~ /^([0-9]+):(.*)$/) {
123 $ret->{'epoch'} = $1;
126 $ret->{'version'} = $evr;
127 if ($evr =~ /^(.*)-(.*?)$/) {
128 $ret->{'version'} = $1;
129 $ret->{'release'} = $2;
132 $ret->{'arch'} = $vars{'arch'}->[0] if $vars{'arch'};
134 if ($opts{'description'}) {
135 $ret->{'description'} = $vars{'pkgdesc'}->[0] if $vars{'pkgdesc'};
137 # arch packages don't seem to have a source :(
138 # fake it so that the package isn't confused with a src package
139 $ret->{'source'} = $ret->{'name'} if defined $ret->{'name'};
146 die("arch pkg query not implemented for file handles\n");
148 if ($handle =~ /\.xz$/ || islzma($handle)) {
149 $handle = lzmadec($handle);
151 my $tar = Archive::Tar->new;
152 my @read = $tar->read($handle, 1, {'filter' => '^\.PKGINFO$', 'limit' => 1});
153 die("$handle: not an arch package file\n") unless @read == 1;
154 my $pkginfo = $read[0]->get_content;
155 die("$handle: not an arch package file\n") unless $pkginfo;
156 return Digest::MD5::md5_hex($pkginfo);
163 my @parts = split(/\n\n+/s, $data);
164 for my $part (@parts) {
165 my @p = split("\n", $part);
167 if ($p eq '%NAME%') {
168 $d->{'name'} = $p[0];
169 } elsif ($p eq '%VERSION%') {
170 $d->{'version'} = $p[0];
171 } elsif ($p eq '%ARCH%') {
172 $d->{'arch'} = $p[0];
173 } elsif ($p eq '%BUILDDATE%') {
174 $d->{'buildtime'} = $p[0];
175 } elsif ($p eq '%FILENAME%') {
176 $d->{'filename'} = $p[0];
177 } elsif ($p eq '%PROVIDES%') {
178 push @{$d->{'provides'}}, @p;
179 } elsif ($p eq '%DEPENDS%') {
180 push @{$d->{'requires'}}, @p;