2 # Debian.pl: Frontend to debian contents and packages files
4 # Version: v0.8 (20000918)
12 # format: "alias=real".
14 my $defaultdist = "sid";
15 my $refresh = &::getChanConfDefault("debianRefreshInterval",7)
18 my $debian_dir = "$::bot_state_dir/debian";
22 # "sid" => "unstable",
23 # "woody" => "testing", # new since 20001219.
24 # "potato" => "stable",
25 # "incoming" => "incoming",
28 ### new... the right way.
31 "testing" => "sarge", # new since 20020719.
33 "old-stable" => "potato",
34 "incoming" => "incoming",
38 "Contents-##DIST-i386.gz" =>
39 "ftp://ftp.us.debian.org".
40 "/debian/dists/##DIST/Contents-i386.gz",
41 "Contents-##DIST-i386-non-US.gz" =>
42 "ftp://non-us.debian.org".
43 "/debian-non-US/dists/##DIST/non-US/Contents-i386.gz",
47 "Packages-##DIST-main-i386.gz" =>
48 "ftp://ftp.us.debian.org".
49 "/debian/dists/##DIST/main/binary-i386/Packages.gz",
50 "Packages-##DIST-contrib-i386.gz" =>
51 "ftp://ftp.us.debian.org".
52 "/debian/dists/##DIST/contrib/binary-i386/Packages.gz",
53 "Packages-##DIST-non-free-i386.gz" =>
54 "ftp://ftp.us.debian.org".
55 "/debian/dists/##DIST/non-free/binary-i386/Packages.gz",
57 "Packages-##DIST-non-US-main-i386.gz" =>
58 "ftp://non-us.debian.org".
59 "/debian-non-US/dists/##DIST/non-US/main/binary-i386/Packages.gz",
60 "Packages-##DIST-non-US-contrib-i386.gz" =>
61 "ftp://non-us.debian.org".
62 "/debian-non-US/dists/##DIST/non-US/contrib/binary-i386/Packages.gz",
63 "Packages-##DIST-non-US-non-free-i386.gz" =>
64 "ftp://non-us.debian.org".
65 "/debian-non-US/dists/##DIST/non-US/non-free/binary-i386/Packages.gz",
69 ### COMMON FUNCTION....
70 #######################
73 # Usage: &DebianDownload($dist, %hash);
75 my ($dist, %urls) = @_;
79 if (! -d $debian_dir) {
80 &::status("Debian: creating debian dir.");
81 mkdir($debian_dir, 0755);
87 foreach $file (keys %urls) {
88 my $url = $urls{$file};
89 $url =~ s/##DIST/$dist/g;
90 $file =~ s/##DIST/$dist/g;
94 my $last_refresh = (stat $file)[9];
95 $update++ if (time() - $last_refresh > $refresh);
100 next unless ($update);
102 &::DEBUG("announce == $announce.") if ($debug);
103 if ($good + $bad == 0 and !$announce) {
104 &::status("Debian: Downloading files for '$dist'.");
105 &::msg($::who, "Updating debian files... please wait.");
109 if (exists $::debian{$url}) {
110 &::DEBUG("2: ".(time - $::debian{$url})." <= $refresh") if ($debug);
111 next if (time() - $::debian{$url} <= $refresh);
112 &::DEBUG("stale for url $url; updating!") if ($debug);
115 if ($url =~ /^ftp:\/\/(.*?)\/(\S+)\/(\S+)$/) {
116 my ($host,$path,$thisfile) = ($1,$2,$3);
119 # if ($file =~ /Contents-woody-i386-non-US/) {
120 # &::DEBUG("Skipping Contents-woody-i386-non-US.");
121 # $file =~ s/woody/potato/;
122 # $path =~ s/woody/potato/;
126 if (!&::ftpGet($host,$path,$thisfile,$file)) {
127 &::WARN("deb: down: $file == BAD.");
133 &::WARN("deb: down: ftpGet: !file");
139 # if ($file =~ /Contents-potato-i386-non-US/) {
140 # &::DEBUG("hack: using potato's non-US contents for woody.");
141 # system("cp debian/Contents-potato-i386-non-US.gz debian/Contents-woody-i386-non-US.gz");
144 my $exit = CORE::system("/bin/gzip -t $file >/dev/null 2>&1");
146 &::WARN("deb: $file is corrupted :/");
151 &::DEBUG("deb: download: good.") if ($debug);
154 &::ERROR("Debian: invalid format of url => ($url).");
160 # ok... lets just run this.
161 &::miscCheck() if (&::whatInterface() =~ /IRC/);
164 &generateIndex($dist);
167 return -1 unless ($bad); # no download.
168 &::DEBUG("DD: !good and bad($bad). :(");
173 ###########################
174 # DEBIAN CONTENTS SEARCH FUNCTIONS.
178 # Usage: &searchContents($query);
180 my ($dist, $query) = &getDistroFromStr($_[0]);
181 &::status("Debian: Contents search for '$query' in '$dist'.");
184 $dccsend++ if ($query =~ s/^dcc\s+//i);
186 $query =~ s/\\([\^\$])/$1/g; # hrm?
187 $query =~ s/^\s+|\s+$//g;
189 if (!&::validExec($query)) {
190 &::msg($::who, "search string looks fuzzy.");
194 if ($dist eq "incoming") { # nothing yet.
195 &::DEBUG("sC: dist = 'incoming'. no contents yet.");
198 my %urls = &fixDist($dist, %urlcontents);
199 # download contents file.
200 &::DEBUG("deb: download 1.") if ($debug);
201 if (!&DebianDownload($dist, %urls)) {
202 &::WARN("Debian: could not download files.");
207 my $start_time = &::timeget();
213 ### TODO: search properly if /usr/bin/blah is done.
214 if ($query =~ s/\$$//) {
215 &::DEBUG("deb: search-regex found.") if ($debug);
216 $grepRE = "$query\[ \t]";
217 } elsif ($query =~ s/^\^//) {
218 &::DEBUG("deb: front marker regex found.") if ($debug);
222 $grepRE = "$query*\[ \t]";
225 # fix up grepRE for "*".
226 $grepRE =~ s/\*/.*/g;
229 foreach (keys %urlcontents) {
232 next unless ( -f "$debian_dir/$_" );
233 push(@files, "$debian_dir/$_");
236 if (!scalar @files) {
237 &::ERROR("sC: no files?");
238 &::msg($::who, "failed.");
242 my $files = join(' ', @files);
245 $regex =~ s/\./\\./g;
246 $regex =~ s/\*/\\S*/g;
249 open(IN,"zegrep -h '$grepRE' $files |");
250 # wonderful abuse of last and next and unless ;)
252 last if ($found > 100);
254 next unless (/^\.?\/?(.*?)[\t\s]+(\S+)\n$/);
255 my ($file,$package) = ("/".$1,$2);
257 if ($query =~ /[\/\*\\]/) {
258 next unless (eval { $file =~ /$regex/ });
259 return unless &checkEval($@);
261 my ($basename) = $file =~ /^.*\/(.*)$/;
262 next unless (eval { $basename =~ /$regex/ });
263 return unless &checkEval($@);
265 next if ($query !~ /\.\d\.gz/ and $file =~ /\/man\//);
266 next if ($front and eval { $file !~ /^\/$query/ });
267 return unless &checkEval($@);
269 $contents{$package}{$file} = 1;
276 ### send results with dcc.
278 if (exists $::dcc{'SEND'}{$::who}) {
279 &::msg($::who, "DCC already active!");
283 if (!scalar %contents) {
284 &::msg($::who,"search returned no results.");
288 my $file = "$::param{tempDir}/$::who.txt";
289 if (!open OUT, ">$file") {
290 &::ERROR("Debian: cannot write file for dcc send.");
294 foreach $pkg (keys %contents) {
295 foreach (keys %{ $contents{$pkg} }) {
296 # TODO: correct padding.
297 print OUT "$_\t\t\t$pkg\n";
302 &::shmWrite($::shm, "DCC SEND $::who $file");
307 &::status("Debian: $found contents results found.");
310 foreach $pkg (keys %contents) {
311 my @tmplist = &::fixFileList(keys %{ $contents{$pkg} });
312 my @sublist = sort { length $a <=> length $b } @tmplist;
314 pop @sublist while (scalar @sublist > 3);
316 $pkg =~ s/\,/\037\,\037/g; # underline ','.
317 push(@list, "(". join(', ',@sublist) .") in $pkg");
319 # sort the total list from shortest to longest...
320 @list = sort { length $a <=> length $b } @list;
322 # show how long it took.
323 my $delta_time = &::timedelta($start_time);
324 &::status(sprintf("Debian: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0);
326 my $prefix = "Debian Search of '$query' ";
327 if (scalar @list) { # @list.
328 &::pSReply( &::formListReply(0, $prefix, @list) );
331 &::DEBUG("deb: ok, !\@list, searching desc for '$query'.") if ($debug);
332 my @list = &searchDesc($query);
335 my $prefix = "Debian Package/File/Desc Search of '$query' ";
336 &::pSReply( &::formListReply(0, $prefix, ) );
338 } elsif (scalar @list == 1) { # list = 1.
339 &::DEBUG("deb: list == 1; showing package info of '$list[0]'.");
340 &infoPackages("info", $list[0]);
343 my $prefix = "Debian Desc Search of '$query' ";
344 &::pSReply( &::formListReply(0, $prefix, @list) );
350 # Usage: &searchAuthor($query);
352 my ($dist, $query) = &getDistroFromStr($_[0]);
353 &::DEBUG("deb: searchAuthor: dist => '$dist', query => '$query'.") if ($debug);
354 $query =~ s/^\s+|\s+$//g;
357 my $start_time = &::timeget();
358 &::status("Debian: starting author search.");
361 my ($bad,$good) = (0,0);
362 my %urls = %urlpackages;
364 foreach (keys %urlpackages) {
367 if (! -f "$debian_dir/$_" ) {
376 &::DEBUG("deb: good = $good, bad = $bad...") if ($debug);
378 if ($good == 0 and $bad != 0) {
379 my %urls = &fixDist($dist, %urlpackages);
380 &::DEBUG("deb: download 2.");
382 if (!&DebianDownload($dist, %urls)) {
383 &::ERROR("Debian(sA): could not download files.");
388 my (%maint, %pkg, $package);
389 open(IN,"zegrep -h '^Package|^Maintainer' $files |");
391 if (/^Package: (\S+)$/) {
394 } elsif (/^Maintainer: (.*) \<(\S+)\>$/) {
395 my($name,$email) = ($1,$2);
396 if ($package eq "") {
397 &::DEBUG("deb: sA: package == NULL.");
400 $maint{$name}{$email} = 1;
401 $pkg{$name}{$package} = 1;
406 &::WARN("debian: invalid line: '$_' (1).");
412 # TODO: can we use 'map' here?
413 foreach (grep /\Q$query\E/i, keys %maint) {
417 # TODO: should we only search email if '@' is used?
418 if (scalar keys %hash < 15) {
421 foreach $name (keys %maint) {
424 foreach $email (keys %{ $maint{$name} }) {
425 next unless ($email =~ /\Q$query\E/i);
426 next if (exists $hash{$name});
432 my @list = keys %hash;
433 if (scalar @list != 1) {
434 my $prefix = "Debian Author Search of '$query' ";
435 &::pSReply( &::formListReply(0, $prefix, @list) );
439 &::DEBUG("deb: showing all packages by '$list[0]'...") if ($debug);
441 my @pkg = sort keys %{ $pkg{$list[0]} };
443 # show how long it took.
444 my $delta_time = &::timedelta($start_time);
445 &::status(sprintf("Debian: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0);
447 my $email = join(', ', keys %{ $maint{$list[0]} });
448 my $prefix = "Debian Packages by $list[0] \002<\002$email\002>\002 ";
449 &::pSReply( &::formListReply(0, $prefix, @pkg) );
453 # Usage: &searchDesc($query);
455 my ($dist, $query) = &getDistroFromStr($_[0]);
456 &::DEBUG("deb: searchDesc: dist => '$dist', query => '$query'.") if ($debug);
457 $query =~ s/^\s+|\s+$//g;
460 my $start_time = &::timeget();
461 &::status("Debian: starting desc search.");
464 my ($bad,$good) = (0,0);
465 my %urls = %urlpackages;
467 foreach (keys %urlpackages) {
470 if (! -f "$debian_dir/$_" ) {
476 $files .= " $debian_dir/$_";
479 &::DEBUG("deb(2): good = $good, bad = $bad...") if ($debug);
481 if ($good == 0 and $bad != 0) {
482 my %urls = &fixDist($dist, %urlpackages);
483 &::DEBUG("deb: download 2c.") if ($debug);
485 if (!&DebianDownload($dist, %urls)) {
486 &::ERROR("deb: sD: could not download files.");
492 $regex =~ s/\./\\./g;
493 $regex =~ s/\*/\\S*/g;
496 my (%desc, $package);
497 open(IN,"zegrep -h '^Package|^Description' $files |");
499 if (/^Package: (\S+)$/) {
501 } elsif (/^Description: (.*)$/) {
503 next unless (eval { $desc =~ /$regex/i });
504 return unless &checkEval($@);
506 if ($package eq "") {
507 &::WARN("sD: package == NULL?");
511 $desc{$package} = $desc;
516 &::WARN("debian: invalid line: '$_'. (2)");
521 # show how long it took.
522 my $delta_time = &::timedelta($start_time);
523 &::status(sprintf("Debian: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0);
529 # Usage: &generateIncoming();
530 sub generateIncoming {
531 my $pkgfile = $debian_dir."/Packages-incoming";
532 my $idxfile = $pkgfile.".idx";
534 $stale++ if (&::isStale($pkgfile.".gz", $refresh));
535 $stale++ if (&::isStale($idxfile, $refresh));
536 &::DEBUG("deb: gI: stale => '$stale'.") if ($debug);
537 return 0 unless ($stale);
540 my %ftp = &::ftpList("llug.sep.bnl.gov", "/pub/debian/Incoming/");
542 if (!open PKG, ">$pkgfile") {
543 &::ERROR("cannot write to pkg $pkgfile.");
546 if (!open IDX, ">$idxfile") {
547 &::ERROR("cannot write to idx $idxfile.");
551 print IDX "*$pkgfile.gz\n";
553 foreach $file (sort keys %ftp) {
554 next unless ($file =~ /deb$/);
556 if ($file =~ /^(\S+)\_(\S+)\_(\S+)\.deb$/) {
558 print PKG "Package: $1\n";
559 print PKG "Version: $2\n";
560 print PKG "Architecture: ", (defined $4) ? $4 : "all", "\n";
562 print PKG "Filename: $file\n";
563 print PKG "Size: $ftp{$file}\n";
569 system("gzip -9fv $pkgfile"); # lame fix.
571 &::status("Debian: generateIncoming() complete.");
575 ##############################
576 # DEBIAN PACKAGE INFO FUNCTIONS.
579 # Usage: &getPackageInfo($query,$file);
581 my ($package, $file) = @_;
584 &::status("gPI: file $file does not exist?");
591 open(IN, "zcat $file 2>&1 |");
597 next if (/^ \S+/); # package long description.
600 if (/^Package: (.*)\n$/) {
602 if ($pkg =~ /^\Q$package\E$/i) {
603 $found++; # we can use pkg{'package'} instead.
604 $pkg{'package'} = $pkg;
613 if (/^Version: (.*)$/) {
614 $pkg{'version'} = $1;
615 } elsif (/^Priority: (.*)$/) {
616 $pkg{'priority'} = $1;
617 } elsif (/^Section: (.*)$/) {
618 $pkg{'section'} = $1;
619 } elsif (/^Size: (.*)$/) {
621 } elsif (/^Installed-Size: (.*)$/i) {
622 $pkg{'installed'} = $1;
623 } elsif (/^Description: (.*)$/) {
625 } elsif (/^Filename: (.*)$/) {
627 } elsif (/^Pre-Depends: (.*)$/) {
628 $pkg{'depends'} = "pre-depends on $1";
629 } elsif (/^Depends: (.*)$/) {
630 if (exists $pkg{'depends'}) {
631 $pkg{'depends'} .= "; depends on $1";
633 $pkg{'depends'} = "depends on $1";
635 } elsif (/^Maintainer: (.*)$/) {
637 } elsif (/^Provides: (.*)$/) {
638 $pkg{'provides'} = $1;
639 } elsif (/^Suggests: (.*)$/) {
640 $pkg{'suggests'} = $1;
641 } elsif (/^Conflicts: (.*)$/) {
642 $pkg{'conflicts'} = $1;
645 ### &::DEBUG("=> '$_'.");
655 next if (defined $pkg);
663 # Usage: &infoPackages($query,$package);
665 my ($query,$dist,$package) = ($_[0], &getDistroFromStr($_[1]));
667 &::status("Debian: Searching for package '$package' in '$dist'.");
669 # download packages file.
671 my %urls = &fixDist($dist, %urlpackages);
672 if ($dist ne "incoming") {
673 &::DEBUG("deb: download 3.") if ($debug);
675 if (!&DebianDownload($dist, %urls)) { # no good download.
676 &::WARN("Debian(iP): could not download ANY files.");
680 # check if the package is valid.
682 my @files = &validPackage($package, $dist);
683 if (!scalar @files) {
684 &::status("Debian: no valid package found; checking incoming.");
685 @files = &validPackage($package, "incoming");
687 &::status("Debian: cool, it exists in incoming.");
690 &::msg($::who, "Package '$package' does not exist.");
695 if (scalar @files > 1) {
696 &::WARN("same package in more than one file; random.");
697 &::DEBUG("THIS SHOULD BE FIXED SOMEHOW!!!");
698 $files[0] = &::getRandom(@files);
701 if (! -f $files[0]) {
702 &::WARN("files[0] ($files[0]) doesn't exist.");
703 &::msg($::who, "WARNING: $files[0] does not exist? FIXME");
707 ### TODO: if specific package is requested, note down that a version
708 ### exists in incoming.
711 my $file = $files[0];
714 ### TODO: use fe, dump to a hash. if only one version of the package
715 ### exists. do as normal otherwise list all versions.
717 &::ERROR("D:iP: file '$file' DOES NOT EXIST!!! should never happen.");
720 my %pkg = &getPackageInfo($package, $file);
723 if ($query eq "info") {
724 if (scalar keys %pkg > 5) {
725 $pkg{'info'} = "\002(\002". $pkg{'desc'} ."\002)\002";
726 $pkg{'info'} .= ", section ".$pkg{'section'};
727 $pkg{'info'} .= ", is ".$pkg{'priority'};
728 # $pkg{'info'} .= ". Version: \002$pkg{'version'}\002";
729 $pkg{'info'} .= ". Version: \002$pkg{'version'}\002 ($dist)";
730 $pkg{'info'} .= ", Packaged size: \002". int($pkg{'size'}/1024) ."\002 kB";
731 $pkg{'info'} .= ", Installed size: \002$pkg{'installed'}\002 kB";
734 &::status("iP: info requested and pkg is in incoming, too.");
735 my %incpkg = &getPackageInfo($query, $debian_dir ."/Packages-incoming");
737 if (scalar keys %incpkg) {
738 $pkg{'info'} .= ". Is in incoming ($incpkg{'file'}).";
740 &::ERROR("iP: pkg $query is in incoming but we couldn't get any info?");
744 &::DEBUG("deb: running debianCheck() due to problems (".scalar(keys %pkg).").");
746 &::DEBUG("deb: end of debianCheck()");
748 &::msg($::who,"Debian: Package appears to exist but I could not retrieve info about it...");
753 if ($dist eq "incoming") {
754 $pkg{'info'} .= "Version: \002$pkg{'version'}\002";
755 $pkg{'info'} .= ", Packaged size: \002". int($pkg{'size'}/1024) ."\002 kB";
756 $pkg{'info'} .= ", is in incoming!!!";
759 if (!exists $pkg{$query}) {
760 if ($query eq "suggests") {
761 $pkg{$query} = "has no suggestions";
762 } elsif ($query eq "conflicts") {
763 $pkg{$query} = "does not conflict with any other package";
764 } elsif ($query eq "depends") {
765 $pkg{$query} = "does not depend on anything";
766 } elsif ($query eq "maint") {
767 $pkg{$query} = "has no maintainer";
769 $pkg{$query} = "has nothing about $query";
773 &::pSReply("$package: $pkg{$query}");
776 # Usage: &infoStats($dist);
779 $dist = &getDistro($dist);
780 return unless (defined $dist);
782 &::DEBUG("deb: infoS: dist => '$dist'.");
784 # download packages file if needed.
785 my %urls = &fixDist($dist, %urlpackages);
786 &::DEBUG("deb: download 4.");
787 if (!&DebianDownload($dist, %urls)) {
788 &::WARN("Debian(iS): could not download ANY files.");
789 &::msg($::who, "Debian(iS): internal error.");
796 foreach $file (keys %urlpackages) {
797 $file =~ s/##DIST/$dist/g; # won't work for incoming.
798 &::DEBUG("deb: file => '$file'.");
799 if (exists $stats{$file}{'count'}) {
800 &::DEBUG("deb: hrm... duplicate open with $file???");
804 open(IN, "zcat $file 2>&1 |");
807 &::DEBUG("deb: iS: $file does not exist.");
814 next if (/^ \S+/); # package long description.
816 if (/^Package: (.*)\n$/) { # counter.
817 $stats{$file}{'count'}++;
819 } elsif (/^Maintainer: .* <(\S+)>$/) {
820 $stats{$file}{'maint'}{$1}++;
821 $total{'maint'}{$1}++;
822 } elsif (/^Size: (.*)$/) { # compressed size.
823 $stats{$file}{'csize'} += $1;
824 $total{'csize'} += $1;
825 } elsif (/^i.*size: (.*)$/i) { # installed size.
826 $stats{$file}{'isize'} += $1;
827 $total{'isize'} += $1;
830 ### &::DEBUG("=> '$_'.");
835 ### TODO: don't count ppl with multiple email addresses.
838 "Debian Distro Stats on $dist... ".
839 "\002$total{'count'}\002 packages, ".
840 "\002".scalar(keys %{ $total{'maint'} })."\002 maintainers, ".
841 "\002". int($total{'isize'}/1024)."\002 MB installed size, ".
842 "\002". int($total{'csize'}/1024/1024)."\002 MB compressed size."
845 ### TODO: do individual stats? if so, we need _another_ arg.
846 # foreach $file (keys %stats) {
847 # foreach (keys %{ $stats{$file} }) {
848 # &::DEBUG(" '$file' '$_' '$stats{$file}{$_}'.");
856 # HELPER FUNCTIONS FOR INFOPACKAGES...
859 # Usage: &generateIndex();
862 &::DEBUG("D: generateIndex($dists[0]) called!");
863 if (!scalar @dists or $dists[0] eq '') {
864 &::ERROR("gI: no dists to generate index.");
869 my $dist = &getDistro($_); # incase the alias is returned, possible?
870 my $idx = $debian_dir."/Packages-$dist.idx";
872 # TODO: check if any of the Packages file have been updated then
873 # regenerate it, even if it's not stale.
874 # TODO: also, regenerate the index if the packages file is newer
876 next unless (&::isStale($idx, $refresh));
879 &::DEBUG("deb: gIndex: calling generateIncoming()!");
885 &::DEBUG("deb: Copying old index of woody to -old");
886 system("cp $idx $idx-old");
889 &::DEBUG("deb: gIndex: calling DebianDownload($dist, ...).") if ($debug);
890 &DebianDownload($dist, &fixDist($dist, %urlpackages) );
892 &::status("Debian: generating index for '$dist'.");
893 if (!open OUT, ">$idx") {
894 &::ERROR("cannot write to $idx.");
899 foreach $packages (keys %urlpackages) {
900 $packages =~ s/##DIST/$dist/;
901 $packages = "$debian_dir/$packages";
903 if (! -e $packages) {
904 &::ERROR("gIndex: '$packages' does not exist?");
908 print OUT "*$packages\n";
909 open(IN,"zcat $packages |");
912 next unless (/^Package: (.*)\n$/);
923 # Usage: &validPackage($package, $dist);
925 my ($package,$dist) = @_;
929 ### this majorly sucks, we need some standard in place.
930 # why is this needed... need to investigate later.
932 $dist = &getDistro($dist);
934 &::DEBUG("deb: validPackage($package, $dist) called.") if ($debug);
937 while (!open IN, $debian_dir."/Packages-$dist.idx") {
939 &::ERROR("Packages-$dist.idx does not exist (#1).");
943 &generateIndex($dist);
955 if (/^\Q$package\E\n$/) {
962 &::VERB("vP: scanned $count items in index.",2);
968 my ($dist, $query) = &getDistroFromStr($_[0]);
969 my $file = $debian_dir."/Packages-$dist.idx";
972 my $warn = ($query =~ tr/A-Z/a-z/) ? 1 : 0;
974 &::status("Debian: Search package matching '$query' in '$dist'.");
975 unlink $file if ( -z $file );
977 while (!open IN, $file) {
978 if ($dist eq "incoming") {
979 &::DEBUG("deb: sP: dist == incoming; calling gI().");
984 &::ERROR("could not generate index ($file)!");
989 &::DEBUG("deb: should we be doing this?");
990 &generateIndex(($dist));
999 if (&::isStale($file, $refresh)) {
1000 &::DEBUG("deb: STALE $file! regen.") if ($debug);
1001 &generateIndex(($dist));
1002 ### @files = searchPackage("$query $dist");
1003 &::DEBUG("deb: EVIL HACK HACK HACK.") if ($debug);
1016 if (scalar @files and $warn) {
1017 &::msg($::who, "searching for package name should be fully lowercase!");
1026 if (!defined $dist or $dist eq "") {
1027 &::DEBUG("deb: gD: dist == NULL; dist = defaultdist.");
1028 $dist = $defaultdist;
1031 if ($dist =~ /^(slink|hamm|rex|bo)$/i) {
1032 &::DEBUG("deb: deprecated version ($dist).");
1033 &::msg($::who, "Debian: deprecated distribution version.");
1037 if (exists $dists{$dist}) {
1038 &::VERB("gD: returning dists{$dist} ($dists{$dist})",2);
1039 return $dists{$dist};
1042 if (!grep /^\Q$dist\E$/i, %dists) {
1043 &::msg($::who, "invalid dist '$dist'.");
1047 &::VERB("gD: returning $dist (no change or conversion)",2);
1052 sub getDistroFromStr {
1054 my $dists = join '|', %dists;
1055 my $dist = $defaultdist;
1057 if ($str =~ s/\s+($dists)$//i) {
1058 $dist = &getDistro(lc $1);
1061 $str =~ s/\\([\$\^])/$1/g;
1067 my ($dist, %urls) = @_;
1071 while (($key,$val) = each %urls) {
1072 $key =~ s/##DIST/$dist/;
1073 $val =~ s/##DIST/$dist/;
1074 ### TODO: what should we do if the sar wasn't done.
1075 $new{$debian_dir."/".$key} = $val;
1084 my ($dist, $query) = &getDistroFromStr($str);
1085 my @results = sort &searchPackage($str);
1087 if (!scalar @results) {
1088 &::Forker("debian", sub { &searchContents($str); } );
1089 } elsif (scalar @results == 1) {
1090 &::status("searchPackage returned one result; getting info of package instead!");
1091 &::Forker("debian", sub { &infoPackages("info", "$results[0] $dist"); } );
1093 my $prefix = "Debian Package Listing of '$query' ";
1094 &::pSReply( &::formListReply(0, $prefix, @results) );
1101 &::status("debianCheck() called.");
1103 ### TODO: remove the following loop (check if dir exists before)
1105 last if (opendir(DEBIAN, $debian_dir));
1108 &::ERROR("dC: cannot opendir debian.");
1112 mkdir $debian_dir, 0755;
1118 while (defined($file = readdir DEBIAN)) {
1119 next unless ($file =~ /(gz|bz2)$/);
1121 my $exit = system("gzip -t '$debian_dir/$file'");
1122 next unless ($exit);
1123 &::DEBUG("deb: hmr... => ".(time() - (stat($file))[8])."'.");
1124 next unless (time() - (stat($file))[8] > 3600);
1126 &::DEBUG("deb: dC: exit => '$exit'.");
1127 &::WARN("dC: '$debian_dir/$file' corrupted? deleting!");
1128 unlink $debian_dir."/".$file;
1139 &::WARN("cE: $str");
1147 # &::DEBUG("deb: FE called for searchDesc");
1149 my @list = &searchDesc($query);
1151 if (!scalar @list) {
1152 my $prefix = "Debian Desc Search of '$query' ";
1153 &::pSReply( &::formListReply(0, $prefix, ) );
1154 } elsif (scalar @list == 1) { # list = 1.
1155 &::DEBUG("deb: list == 1; showing package info of '$list[0]'.");
1156 &infoPackages("info", $list[0]);
1157 } else { # list > 1.
1158 my $prefix = "Debian Desc Search of '$query' ";
1159 &::pSReply( &::formListReply(0, $prefix, @list) );