2 # Debian.pl: Frontend to debian contents and packages files
4 # Version: v0.8 (20000918)
12 # format: "alias=real".
14 my $defaultdist = "unstable";
17 "testing" => "woody", # new since 20001219.
19 "incoming" => "incoming",
20 ### the following don't work. too much effort to get 3 types of distros
21 ### to work harmoniously :-)
22 "slink" => "archive-2.1",
23 "hamm" => "archive-2.0",
24 "rex" => "archive-1.?",
25 "bo" => "archive-1.?",
29 "debian/Contents-##DIST-i386.gz" =>
30 "ftp://ftp.us.debian.org".
31 "/debian/dists/##DIST/Contents-i386.gz",
32 ### APPEARS TO BE FIXED?
33 # => strip control chars just to be safe.
34 "debian/Contents-##DIST-i386-non-US.gz" =>
35 "ftp://non-us.debian.org".
36 "/debian-non-US/dists/##DIST/non-US/Contents-i386.gz",
40 "debian/Packages-##DIST-main-i386.gz" =>
41 "ftp://ftp.us.debian.org".
42 "/debian/dists/##DIST/main/binary-i386/Packages.gz",
43 "debian/Packages-##DIST-contrib-i386.gz" =>
44 "ftp://ftp.us.debian.org".
45 "/debian/dists/##DIST/contrib/binary-i386/Packages.gz",
46 "debian/Packages-##DIST-non-free-i386.gz" =>
47 "ftp://ftp.us.debian.org".
48 "/debian/dists/##DIST/non-free/binary-i386/Packages.gz",
50 "debian/Packages-##DIST-non-US-main-i386.gz" =>
51 "ftp://non-us.debian.org".
52 "/debian-non-US/dists/##DIST/non-US/main/binary-i386/Packages.gz",
53 "debian/Packages-##DIST-non-US-contrib-i386.gz" =>
54 "ftp://non-us.debian.org".
55 "/debian-non-US/dists/##DIST/non-US/contrib/binary-i386/Packages.gz",
56 "debian/Packages-##DIST-non-US-non-free-i386.gz" =>
57 "ftp://non-us.debian.org".
58 "/debian-non-US/dists/##DIST/non-US/non-free/binary-i386/Packages.gz",
62 ### COMMON FUNCTION....
63 #######################
66 # Usage: &DebianDownload(%hash);
68 my ($dist, %urls) = @_;
69 my $refresh = &::getChanConfDefault("debianRefreshInterval",
70 undef, 7) * 60 * 60 * 24;
75 &::status("Debian: creating debian dir.");
76 mkdir("debian/",0755);
83 foreach $file (keys %urls) {
84 my $url = $urls{$file};
85 $url =~ s/##DIST/$dist/g;
86 $file =~ s/##DIST/$dist/g;
90 my $last_refresh = (stat($file))[9];
91 $update++ if (time() - $last_refresh > $refresh);
96 next unless ($update);
98 &::DEBUG("announce == $announce.");
99 if ($good + $bad == 0 and !$announce) {
100 &::status("Debian: Downloading files for '$dist'.");
101 &::msg($::who, "Updating debian files... please wait.");
105 if (exists $::debian{$url}) {
106 &::DEBUG("2: ".(time - $::debian{$url})." <= $refresh");
107 next if (time() - $::debian{$url} <= $refresh);
108 &::DEBUG("stale for url $url; updating!");
111 if ($url =~ /^ftp:\/\/(.*?)\/(\S+)\/(\S+)$/) {
112 my ($host,$path,$thisfile) = ($1,$2,$3);
114 # error internally to ftp.
115 # hope it doesn't do anything bad.
116 if ($file =~ /Contents-woody-i386-non-US/) {
117 &::DEBUG("Skipping Contents-woody-i386-non-US.");
118 # $file =~ s/woody/potato/;
119 # $path =~ s/woody/potato/;
123 if (!&::ftpGet($host,$path,$thisfile,$file)) {
124 &::WARN("deb: down: $file == BAD.");
130 &::DEBUG("deb: down: ftpGet: !file");
135 if ($file =~ /Contents-potato-i386-non-US/) {
136 &::DEBUG("hack: using potato's non-US contents for woody.");
137 system("cp debian/Contents-potato-i386-non-US.gz debian/Contents-woody-i386-non-US.gz");
140 &::DEBUG("deb: download: good.");
144 &::ERROR("Debian: invalid format of url => ($url).");
151 &generateIndex($dist);
154 return -1 unless ($bad); # no download.
155 &::DEBUG("DD: !good and bad($bad). :(");
160 ###########################
161 # DEBIAN CONTENTS SEARCH FUNCTIONS.
165 # Usage: &searchContents($query);
167 my ($dist, $query) = &getDistroFromStr($_[0]);
168 &::status("Debian: Contents search for '$query' on $dist.");
171 $dccsend++ if ($query =~ s/^dcc\s+//i);
173 # $query = $query.'(\.so\.)?([.[[:digit:]]+\.]+)?$';
175 $query =~ s/\\([\^\$])/$1/g; # hrm?
176 $query =~ s/^\s+|\s+$//g;
178 if (!&::validExec($query)) {
179 &::msg($::who, "search string looks fuzzy.");
183 if ($dist eq "incoming") { # nothing yet.
184 &::DEBUG("sC: dist = 'incoming'. no contents yet.");
187 my %urls = &fixDist($dist, %urlcontents);
188 # download contents file.
189 &::DEBUG("deb: download 1.");
190 if (!&DebianDownload($dist, %urls)) {
191 &::WARN("Debian: could not download files.");
196 my $start_time = &::timeget();
202 ### TODO: search properly if /usr/bin/blah is done.
203 if ($query =~ s/\$$//) {
204 &::DEBUG("search-regex found.");
205 $grepRE = "$query\[ \t]";
206 } elsif ($query =~ s/^\^//) {
207 &::DEBUG("front marker regex found.");
211 $grepRE = "$query*\[ \t]";
214 ### fix up grepRE for "*".
215 $grepRE =~ s/\*/.*/g;
218 foreach (keys %urlcontents) {
221 next unless ( -f $_);
225 if (!scalar @files) {
226 &::ERROR("sC: no files?");
227 &::msg($::who, "failed.");
231 my $files = join(' ', @files);
233 open(IN,"zegrep -h '$grepRE' $files |");
235 if (/^\.?\/?(.*?)[\t\s]+(\S+)\n$/) {
236 my ($file,$package) = ("/".$1,$2);
237 if ($query =~ /\//) {
238 next unless ($file =~ /\Q$query\E/);
240 my ($basename) = $file =~ /^.*\/(.*)$/;
241 next unless ($basename =~ /\Q$query\E/);
243 next if ($query !~ /\.\d\.gz/ and $file =~ /\/man\//);
244 next if ($front and $file !~ /^\/\Q$query\E/);
246 $contents{$package}{$file} = 1;
250 last if ($found > 100);
256 ### send results with dcc.
258 if (exists $::dcc{'SEND'}{$::who}) {
259 &::msg($::who, "DCC already active!");
263 if (!scalar %contents) {
264 &::msg($::who,"search returned no results.");
268 my $file = "$::param{tempDir}/$::who.txt";
269 if (!open(OUT,">$file")) {
270 &::ERROR("Debian: cannot write file for dcc send.");
274 foreach $pkg (keys %contents) {
275 foreach (keys %{$contents{$pkg}}) {
276 # TODO: correct padding.
277 print OUT "$_\t\t\t$pkg\n";
282 &::shmWrite($::shm, "DCC SEND $::who $file");
287 &::status("Debian: $found contents results found.");
290 foreach $pkg (keys %contents) {
291 my @tmplist = &::fixFileList(keys %{$contents{$pkg}});
292 my @sublist = sort { length $a <=> length $b } @tmplist;
294 pop @sublist while (scalar @sublist > 3);
296 $pkg =~ s/\,/\037\,\037/g; # underline ','.
297 push(@list, "(". join(', ',@sublist) .") in $pkg");
299 # sort the total list from shortest to longest...
300 @list = sort { length $a <=> length $b } @list;
302 # show how long it took.
303 my $delta_time = &::timedelta($start_time);
304 &::status(sprintf("Debian: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0);
306 my $prefix = "Debian Search of '$query' ";
307 if (scalar @list) { # @list.
308 &::pSReply( &::formListReply(0, $prefix, @list) );
310 &::DEBUG("ok, !\@list, searching desc for '$query'.");
316 # Usage: &searchAuthor($query);
318 my ($dist, $query) = &getDistroFromStr($_[0]);
319 &::DEBUG("searchAuthor: dist => '$dist', query => '$query'.");
320 $query =~ s/^\s+|\s+$//g;
323 my $start_time = &::timeget();
324 &::status("Debian: starting author search.");
327 my ($bad,$good) = (0,0);
328 my %urls = %urlpackages;
330 foreach (keys %urlpackages) {
342 &::DEBUG("good = $good, bad = $bad...");
344 if ($good == 0 and $bad != 0) {
345 my %urls = &fixDist($dist, %urlpackages);
346 &::DEBUG("deb: download 2.");
347 if (!&DebianDownload($dist, %urls)) {
348 &::ERROR("Debian(sA): could not download files.");
353 my (%maint, %pkg, $package);
354 open(IN,"zegrep -h '^Package|^Maintainer' $files |");
356 if (/^Package: (\S+)$/) {
358 } elsif (/^Maintainer: (.*) \<(\S+)\>$/) {
359 my($name,$email) = ($1,$2);
360 if ($package eq "") {
361 &::DEBUG("sA: package == NULL.");
364 $maint{$name}{$email} = 1;
365 $pkg{$name}{$package} = 1;
368 &::WARN("invalid line: '$_'.");
374 # TODO: can we use 'map' here?
375 foreach (grep /\Q$query\E/i, keys %maint) {
379 # TODO: should we only search email if '@' is used?
380 if (scalar keys %hash < 15) {
382 foreach $name (keys %maint) {
384 foreach $email (keys %{$maint{$name}}) {
385 next unless ($email =~ /\Q$query\E/i);
386 next if (exists $hash{$name});
392 my @list = keys %hash;
393 if (scalar @list != 1) {
394 my $prefix = "Debian Author Search of '$query' ";
395 &::pSReply( &::formListReply(0, $prefix, @list) );
399 &::DEBUG("showing all packages by '$list[0]'...");
401 my @pkg = sort keys %{$pkg{$list[0]}};
403 # show how long it took.
404 my $delta_time = &::timedelta($start_time);
405 &::status(sprintf("Debian: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0);
407 my $email = join(', ', keys %{$maint{$list[0]}});
408 my $prefix = "Debian Packages by $list[0] \002<\002$email\002>\002 ";
409 &::pSReply( &::formListReply(0, $prefix, @pkg) );
413 # Usage: &searchDesc($query);
415 my ($dist, $query) = &getDistroFromStr($_[0]);
416 &::DEBUG("searchDesc: dist => '$dist', query => '$query'.");
417 $query =~ s/^\s+|\s+$//g;
420 my $start_time = &::timeget();
421 &::status("Debian: starting desc search.");
424 my ($bad,$good) = (0,0);
425 my %urls = %urlpackages;
427 foreach (keys %urlpackages) {
439 &::DEBUG("good = $good, bad = $bad...");
441 if ($good == 0 and $bad != 0) {
442 my %urls = &fixDist($dist, %urlpackages);
443 &::DEBUG("deb: download 2c.");
444 if (!&DebianDownload($dist, %urls)) {
445 &::ERROR("Debian(sD): could not download files.");
450 my (%desc, $package);
451 open(IN,"zegrep -h '^Package|^Description' $files |");
453 if (/^Package: (\S+)$/) {
455 } elsif (/^Description: (.*)$/) {
457 next unless ($desc =~ /\Q$query\E/i);
458 if ($package eq "") {
459 &::WARN("sD: package == NULL?");
462 $desc{$package} = $desc;
465 &::WARN("invalid line: '$_'.");
470 my @list = keys %desc;
472 my $prefix = "Debian Desc Search of '$query' ";
473 &::pSReply( &::formListReply(0, $prefix, ) );
474 } elsif (scalar @list == 1) { # list = 1.
475 &::DEBUG("list == 1; showing package info of '$list[0]'.");
476 &infoPackages("info", $list[0]);
478 my $prefix = "Debian Desc Search of '$query' ";
479 &::pSReply( &::formListReply(0, $prefix, @list) );
482 # show how long it took.
483 my $delta_time = &::timedelta($start_time);
484 &::status(sprintf("Debian: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0);
488 # Usage: &generateIncoming();
489 sub generateIncoming {
490 my $interval = $::param{'debianRefreshInterval'};
491 my $pkgfile = "debian/Packages-incoming";
492 my $idxfile = $pkgfile.".idx";
494 $stale++ if (&::isStale($pkgfile.".gz", $interval));
495 $stale++ if (&::isStale($idxfile, $interval));
496 &::DEBUG("gI: stale => '$stale'.");
497 return 0 unless ($stale);
500 my %ftp = &::ftpList("llug.sep.bnl.gov", "/pub/debian/Incoming/");
502 if (!open(PKG,">$pkgfile")) {
503 &::ERROR("cannot write to pkg $pkgfile.");
506 if (!open(IDX,">$idxfile")) {
507 &::ERROR("cannot write to idx $idxfile.");
511 print IDX "*$pkgfile.gz\n";
513 foreach $file (sort keys %ftp) {
514 next unless ($file =~ /deb$/);
516 if ($file =~ /^(\S+)\_(\S+)\_(\S+)\.deb$/) {
518 print PKG "Package: $1\n";
519 print PKG "Version: $2\n";
520 print PKG "Architecture: ", (defined $4) ? $4 : "all", "\n";
522 print PKG "Filename: $file\n";
523 print PKG "Size: $ftp{$file}\n";
529 system("gzip -9fv $pkgfile"); # lame fix.
531 &::status("Debian: generateIncoming() complete.");
535 ##############################
536 # DEBIAN PACKAGE INFO FUNCTIONS.
539 # Usage: &getPackageInfo($query,$file);
541 my ($package, $file) = @_;
544 &::status("gPI: file $file does not exist?");
551 open(IN, "zcat $file 2>&1 |");
557 next if (/^ \S+/); # package long description.
560 if (/^Package: (.*)\n$/) {
562 if ($pkg =~ /^$package$/i) {
563 $found++; # we can use pkg{'package'} instead.
564 $pkg{'package'} = $pkg;
573 if (/^Version: (.*)$/) {
574 $pkg{'version'} = $1;
575 } elsif (/^Priority: (.*)$/) {
576 $pkg{'priority'} = $1;
577 } elsif (/^Section: (.*)$/) {
578 $pkg{'section'} = $1;
579 } elsif (/^Size: (.*)$/) {
581 } elsif (/^Installed-Size: (.*)$/i) {
582 $pkg{'installed'} = $1;
583 } elsif (/^Description: (.*)$/) {
585 } elsif (/^Filename: (.*)$/) {
587 } elsif (/^Pre-Depends: (.*)$/) {
588 $pkg{'depends'} = "pre-depends on $1";
589 } elsif (/^Depends: (.*)$/) {
590 if (exists $pkg{'depends'}) {
591 $pkg{'depends'} .= "; depends on $1";
593 $pkg{'depends'} = "depends on $1";
595 } elsif (/^Maintainer: (.*)$/) {
597 } elsif (/^Provides: (.*)$/) {
598 $pkg{'provides'} = $1;
599 } elsif (/^Suggests: (.*)$/) {
600 $pkg{'suggests'} = $1;
601 } elsif (/^Conflicts: (.*)$/) {
602 $pkg{'conflicts'} = $1;
605 ### &::DEBUG("=> '$_'.");
615 next if (defined $pkg);
623 # Usage: &infoPackages($query,$package);
625 my ($query,$dist,$package) = ($_[0], &getDistroFromStr($_[1]));
626 my $interval = $::param{'debianRefreshInterval'} || 7;
628 &::status("Debian: Searching for package '$package' in '$dist'.");
630 # download packages file.
632 my %urls = &fixDist($dist, %urlpackages);
633 if ($dist ne "incoming") {
634 &::DEBUG("deb: download 3.");
635 if (!&DebianDownload($dist, %urls)) { # no good download.
636 &::WARN("Debian(iP): could not download ANY files.");
640 # check if the package is valid.
642 my @files = &validPackage($package, $dist);
643 if (!scalar @files) {
644 &::status("Debian: no valid package found; checking incoming.");
645 @files = &validPackage($package, "incoming");
647 &::status("Debian: cool, it exists in incoming.");
650 &::msg($::who, "Package '$package' does not exist.");
655 if (scalar @files > 1) {
656 &::WARN("same package in more than one file; random.");
657 &::DEBUG("THIS SHOULD BE FIXED SOMEHOW!!!");
658 $files[0] = &::getRandom(@files);
661 if (! -f $files[0]) {
662 &::WARN("files[0] ($files[0]) doesn't exist.");
663 &::msg($::who, "WARNING: $files[0] does not exist? FIXME");
667 ### TODO: if specific package is requested, note down that a version
668 ### exists in incoming.
671 my $file = $files[0];
674 ### TODO: use fe, dump to a hash. if only one version of the package
675 ### exists. do as normal otherwise list all versions.
677 &::ERROR("D:iP: file '$file' DOES NOT EXIST!!! should never happen.");
680 my %pkg = &getPackageInfo($package, $file);
683 if ($query eq "info") {
684 if (scalar keys %pkg > 5) {
685 $pkg{'info'} = "\002(\002". $pkg{'desc'} ."\002)\002";
686 $pkg{'info'} .= ", section ".$pkg{'section'};
687 $pkg{'info'} .= ", is ".$pkg{'priority'};
688 $pkg{'info'} .= ". Version: \002$pkg{'version'}\002";
689 $pkg{'info'} .= ", Packaged size: \002". int($pkg{'size'}/1024) ."\002 kB";
690 $pkg{'info'} .= ", Installed size: \002$pkg{'installed'}\002 kB";
693 &::status("iP: info requested and pkg is in incoming, too.");
694 my %incpkg = &getPackageInfo($query, "debian/Packages-incoming");
696 if (scalar keys %incpkg) {
697 $pkg{'info'} .= ". Is in incoming ($incpkg{'file'}).";
699 &::ERROR("iP: pkg $query is in incoming but we couldn't get any info?");
703 &::DEBUG("running debianCheck() due to problems (".scalar(keys %pkg).").");
705 &::DEBUG("end of debianCheck()");
707 &::msg($::who,"Debian: Package appears to exist but I could not retrieve info about it...");
712 if ($dist eq "incoming") {
713 $pkg{'info'} .= "Version: \002$pkg{'version'}\002";
714 $pkg{'info'} .= ", Packaged size: \002". int($pkg{'size'}/1024) ."\002 kB";
715 $pkg{'info'} .= ", is in incoming!!!";
718 if (!exists $pkg{$query}) {
719 if ($query eq "suggests") {
720 $pkg{$query} = "has no suggestions";
721 } elsif ($query eq "conflicts") {
722 $pkg{$query} = "does not conflict with any other package";
723 } elsif ($query eq "depends") {
724 $pkg{$query} = "does not depend on anything";
725 } elsif ($query eq "maint") {
726 $pkg{$query} = "has no maintainer";
728 $pkg{$query} = "has nothing about $query";
732 &::pSReply("$package: $pkg{$query}");
735 # Usage: &infoStats($dist);
738 $dist = &getDistro($dist);
739 return unless (defined $dist);
741 &::DEBUG("infoS: dist => '$dist'.");
742 my $interval = $::param{'debianRefreshInterval'} || 7;
744 # download packages file if needed.
745 my %urls = &fixDist($dist, %urlpackages);
746 &::DEBUG("deb: download 4.");
747 if (!&DebianDownload($dist, %urls)) {
748 &::WARN("Debian(iS): could not download ANY files.");
749 &::msg($::who, "Debian(iS): internal error.");
756 foreach $file (keys %urlpackages) {
757 $file =~ s/##DIST/$dist/g; # won't work for incoming.
758 &::DEBUG("file => '$file'.");
759 if (exists $stats{$file}{'count'}) {
760 &::DEBUG("hrm... duplicate open with $file???");
764 open(IN,"zcat $file 2>&1 |");
767 &::DEBUG("iS: $file does not exist.");
774 next if (/^ \S+/); # package long description.
776 if (/^Package: (.*)\n$/) { # counter.
777 $stats{$file}{'count'}++;
779 } elsif (/^Maintainer: .* <(\S+)>$/) {
780 $stats{$file}{'maint'}{$1}++;
781 $total{'maint'}{$1}++;
782 } elsif (/^Size: (.*)$/) { # compressed size.
783 $stats{$file}{'csize'} += $1;
784 $total{'csize'} += $1;
785 } elsif (/^i.*size: (.*)$/i) { # installed size.
786 $stats{$file}{'isize'} += $1;
787 $total{'isize'} += $1;
790 ### &::DEBUG("=> '$_'.");
795 ### TODO: don't count ppl with multiple email addresses.
798 "Debian Distro Stats on $dist... ".
799 "\002$total{'count'}\002 packages, ".
800 "\002".scalar(keys %{$total{'maint'}})."\002 maintainers, ".
801 "\002". int($total{'isize'}/1024)."\002 MB installed size, ".
802 "\002". int($total{'csize'}/1024/1024)."\002 MB compressed size."
805 ### TODO: do individual stats? if so, we need _another_ arg.
806 # foreach $file (keys %stats) {
807 # foreach (keys %{$stats{$file}}) {
808 # &::DEBUG(" '$file' '$_' '$stats{$file}{$_}'.");
818 # HELPER FUNCTIONS FOR INFOPACKAGES...
821 # Usage: &generateIndex();
824 &::status("Debian: !!! generateIndex() called !!!");
825 if (!scalar @dists or $dists[0] eq '') {
826 &::ERROR("gI: no dists to generate index.");
831 my $dist = &getDistro($_); # incase the alias is returned, possible?
832 my $idx = "debian/Packages-$dist.idx";
834 # TODO: check if any of the Packages file have been updated then
835 # regenerate it, even if it's not stale.
836 # TODO: also, regenerate the index if the packages file is newer
838 next unless (&::isStale($idx, $::param{'debianRefreshInterval'}));
840 &::DEBUG("gIndex: calling generateIncoming()!");
846 &::DEBUG("Copying old index of woody to -old");
847 system("cp $idx $idx-old");
850 &::DEBUG("gIndeX: calling DebianDownload($dist, ...).");
851 &DebianDownload($dist, %urlpackages);
853 &::status("Debian: generating index for '$dist'.");
854 if (!open(OUT,">$idx")) {
855 &::ERROR("cannot write to $idx.");
860 foreach $packages (keys %urlpackages) {
861 $packages =~ s/##DIST/$dist/;
863 if (! -e $packages) {
864 &::ERROR("gIndex: '$packages' does not exist?");
868 print OUT "*$packages\n";
869 open(IN,"zcat $packages |");
872 next unless (/^Package: (.*)\n$/);
883 # Usage: &validPackage($package, $dist);
885 my ($package,$dist) = @_;
889 &::DEBUG("D: validPackage($package, $dist) called.");
892 while (!open(IN, "debian/Packages-$dist.idx")) {
894 &::ERROR("Packages-$dist.idx does not exist (#1).");
898 &generateIndex($dist);
910 if (/^\Q$package\E\n$/) {
917 &::DEBUG("vP: scanned $count items in index.");
923 my ($dist, $query) = &getDistroFromStr($_[0]);
924 my $file = "debian/Packages-$dist.idx";
929 if ($query =~ tr/A-Z/a-z/) {
933 &::status("Debian: Search package matching '$query' in '$dist'.");
934 unlink $file if ( -z $file);
936 while (!open(IN, $file)) {
937 if ($dist eq "incoming") {
938 &::DEBUG("sP: dist == incoming; calling gI().");
943 &::ERROR("could not generate index!!!");
948 &::DEBUG("should we be doing this?");
949 &generateIndex(($dist));
958 if (&::isStale($file, $::param{'debianRefreshInterval'})) {
959 &::DEBUG("STALE $file! regen.");
960 &generateIndex(($dist));
961 ### @files = searchPackage("$query $dist");
962 &::DEBUG("EVIL HACK HACK HACK.");
975 if (scalar @files and $warn) {
976 &::msg($::who, "searching for package name should be fully lowercase!");
985 if (!defined $dist or $dist eq "") {
986 &::DEBUG("gD: dist == NULL; dist = defaultdist.");
987 $dist = $defaultdist;
990 if ($dist =~ /^(slink|hamm|rex|bo)$/i) {
991 &::DEBUG("Debian: deprecated version ($dist).");
992 &::msg($::who, "Debian: deprecated distribution version.");
996 if (exists $dists{$dist}) {
997 return $dists{$dist};
999 if (!grep /^\Q$dist\E$/i, %dists) {
1000 &::msg($::who, "invalid dist '$dist'.");
1008 sub getDistroFromStr {
1010 my $dists = join '|', %dists;
1011 my $dist = $defaultdist;
1013 if ($str =~ s/\s+($dists)$//i) {
1014 $dist = &getDistro(lc $1);
1017 $str =~ s/\\([\$\^])/$1/g;
1023 my ($dist, %urls) = @_;
1027 while (($key,$val) = each %urls) {
1028 $key =~ s/##DIST/$dist/;
1029 $val =~ s/##DIST/$dist/;
1030 ### TODO: what should we do if the sar wasn't done.
1037 ### H-H-H-HACK HACK HACK :)
1039 my ($dist, $query) = &getDistroFromStr($str);
1040 my @results = sort &searchPackage($str);
1042 if (!scalar @results) {
1043 &::Forker("debian", sub { &searchContents($str); } );
1044 } elsif (scalar @results == 1) {
1045 &::status("searchPackage returned one result; getting info of package instead!");
1046 &::Forker("debian", sub { &infoPackages("info", "$results[0] $dist"); } );
1048 my $prefix = "Debian Package Listing of '$str' ";
1049 &::pSReply( &::formListReply(0, $prefix, @results) );
1054 my $dir = "debian/";
1057 &::status("debianCheck() called.");
1059 ### TODO: remove the following loop (check if dir exists before)
1061 last if (opendir(DEBIAN, $dir));
1063 &::ERROR("dC: cannot opendir debian.");
1072 while (defined($file = readdir DEBIAN)) {
1073 next unless ($file =~ /(gz|bz2)$/);
1075 my $exit = system("gzip -t '$dir/$file'");
1076 next unless ($exit);
1077 &::DEBUG("hmr... => ".(time() - (stat($file))[8])."'.");
1078 next unless (time() - (stat($file))[8] > 3600);
1080 &::DEBUG("dC: exit => '$exit'.");
1081 &::WARN("dC: '$dir/$file' corrupted? deleting!");
1082 unlink $dir."/".$file;