#
# Debian.pl: Frontend to debian contents and packages files
-# Author: xk <xk@leguin.openprojects.net>
-# Version: v0.7b (20000527)
+# Author: dms
+# Version: v0.8 (20000918)
# Created: 20000106
#
use strict;
# format: "alias=real".
+my $announce = 0;
my $defaultdist = "woody";
my %dists = (
- "unstable" => "woody",
- "frozen" => "potato",
- "stable" => "slink",
+ "unstable" => "sid",
+ "testing" => "woody, # new since 20001219.
+ "stable" => "potato",
"incoming" => "incoming",
+### the following don't work. too much effort to get 3 types of distros
+### to work harmoniously :-)
+ "slink" => "archive-2.1",
+ "hamm" => "archive-2.0",
+ "rex" => "archive-1.?",
+ "bo" => "archive-1.?",
);
my %urlcontents = (
"debian/Contents-##DIST-i386.gz" =>
"ftp://ftp.us.debian.org".
"/debian/dists/##DIST/Contents-i386.gz",
-
+### APPEARS TO BE FIXED?
+# => strip control chars just to be safe.
"debian/Contents-##DIST-i386-non-US.gz" =>
- "ftp://non-us.debian.org".
+ "ftp://ftp.ca.debian.org".
"/debian-non-US/dists/##DIST/non-US/Contents-i386.gz",
);
"debian/Packages-##DIST-non-free-i386.gz" =>
"ftp://ftp.us.debian.org".
"/debian/dists/##DIST/non-free/binary-i386/Packages.gz",
- "debian/Packages-##DIST-non-US-i386.gz" =>
- "ftp://non-us.debian.org".
- "/debian-non-US/dists/##DIST/non-US/binary-i386/Packages.gz",
+
+ "debian/Packages-##DIST-non-US-main-i386.gz" =>
+ "ftp://ftp.ca.debian.org".
+ "/debian-non-US/dists/##DIST/non-US/main/binary-i386/Packages.gz",
+ "debian/Packages-##DIST-non-US-contrib-i386.gz" =>
+ "ftp://ftp.ca.debian.org".
+ "/debian-non-US/dists/##DIST/non-US/contrib/binary-i386/Packages.gz",
+ "debian/Packages-##DIST-non-US-non-free-i386.gz" =>
+ "ftp://ftp.ca.debian.org".
+ "/debian-non-US/dists/##DIST/non-US/non-free/binary-i386/Packages.gz",
);
#####################
my $bad = 0;
my $good = 0;
- &main::status("Debian: Downloading files for '$dist'.");
-
if (! -d "debian/") {
&main::status("Debian: creating debian dir.");
mkdir("debian/",0755);
}
- %urls = &fixNonUS($dist, %urls);
-
# fe dists.
# Download the files.
my $file;
+## my %ret;
foreach $file (keys %urls) {
my $url = $urls{$file};
$url =~ s/##DIST/$dist/g;
my $last_refresh = (stat($file))[9];
$update++ if (time() - $last_refresh > $refresh);
} else {
- &main::DEBUG("Debian: local '$file' does not exist.");
$update++;
}
next unless ($update);
- if ($good + $bad == 0) {
+ &main::DEBUG("announce == $announce.");
+ if ($good + $bad == 0 and !$announce) {
+ &main::status("Debian: Downloading files for '$dist'.");
&main::msg($main::who, "Updating debian files... please wait.");
+ $announce++;
}
if (exists $main::debian{$url}) {
# error internally to ftp.
# hope it doesn't do anything bad.
+ if ($file =~ /Contents-woody-i386-non-US/) {
+ &main::DEBUG("Skipping Contents-woody-i386-non-US.");
+# $file =~ s/woody/potato/;
+# $path =~ s/woody/potato/;
+### next;
+ }
+
if (!&main::ftpGet($host,$path,$thisfile,$file)) {
- &main::DEBUG("deb: down: ftpGet: bad.");
+ &main::WARN("deb: down: $file == BAD.");
$bad++;
next;
}
next;
}
+ if ($file =~ /Contents-potato-i386-non-US/) {
+ &main::DEBUG("hack: using potato's non-US contents for woody.");
+ system("cp debian/Contents-potato-i386-non-US.gz debian/Contents-woody-i386-non-US.gz");
+ }
+
&main::DEBUG("deb: download: good.");
+## $ret{$
$good++;
} else {
&main::ERROR("Debian: invalid format of url => ($url).");
### larne's regex.
# $query = $query.'(\.so\.)?([.[[:digit:]]+\.]+)?$';
- $query =~ s/\\([\^\$])/$1/g;
+ $query =~ s/\\([\^\$])/$1/g; # hrm?
$query =~ s/^\s+|\s+$//g;
- $query =~ s/\*/\\S*/g; # does it even work?
if (!&main::validExec($query)) {
&main::msg($main::who, "search string looks fuzzy.");
# download contents file.
&main::DEBUG("deb: download 1.");
if (!&DebianDownload($dist, %urls)) {
- &main::ERROR("Debian: could not download files.");
- return;
+ &main::WARN("Debian: could not download files.");
}
}
# start of search.
- my $start_time = &main::gettimeofday();
+ my $start_time = &main::timeget();
my $found = 0;
my %contents;
- my $search = "$query.*\[ \t]";
- my $files = join(' ', keys %urlcontents);
- $files =~ s/##DIST/$dist/g;
+ my $grepRE;
+ my $front = 0;
+ ### TODO: search properly if /usr/bin/blah is done.
+ if ($query =~ s/\$$//) {
+ &main::DEBUG("search-regex found.");
+ $grepRE = "$query\[ \t]";
+ } elsif ($query =~ s/^\^//) {
+ &main::DEBUG("front marker regex found.");
+ $front = 1;
+ $grepRE = $query;
+ } else {
+ $grepRE = "$query*\[ \t]";
+ }
- open(IN,"zegrep -h '$search' $files |");
+ ### fix up grepRE for "*".
+ $grepRE =~ s/\*/.*/g;
+
+ my @files;
+ foreach (keys %urlcontents) {
+ s/##DIST/$dist/g;
+
+ next unless ( -f $_);
+ push(@files,$_);
+ }
+
+ if (!scalar @files) {
+ &main::ERROR("sC: no files?");
+ &main::msg($main::who, "failed.");
+ return;
+ }
+
+ my $files = join(' ', @files);
+
+ open(IN,"zegrep -h '$grepRE' $files |");
while (<IN>) {
if (/^\.?\/?(.*?)[\t\s]+(\S+)\n$/) {
my ($file,$package) = ("/".$1,$2);
next unless ($basename =~ /\Q$query\E/);
}
next if ($query !~ /\.\d\.gz/ and $file =~ /\/man\//);
+ next if ($front and $file !~ /^\/\Q$query\E/);
$contents{$package}{$file} = 1;
$found++;
}
+
+ last if ($found > 100);
}
close IN;
return;
}
- if (! -d "Temp/") {
- mkdir("Temp",0755);
- }
-
- my $file = "temp/$main::who.txt";
+ my $file = "$main::param{tempDir}/$main::who.txt";
if (!open(OUT,">$file")) {
&main::ERROR("Debian: cannot write file for dcc send.");
return;
return;
}
- &main::status("Debian: $found results.");
+ &main::status("Debian: $found contents results found.");
my @list;
foreach $pkg (keys %contents) {
@list = sort { length $a <=> length $b } @list;
# show how long it took.
- my $delta_time = &main::gettimeofday() - $start_time;
+ my $delta_time = &main::timedelta($start_time);
&main::status(sprintf("Debian: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0);
my $prefix = "Debian Search of '$query' ";
- &main::performStrictReply( &main::formListReply(0, $prefix, @list) );
+ if (scalar @list) { # @list.
+ &main::performStrictReply( &main::formListReply(0, $prefix, @list) );
+ } else { # !@list.
+ &main::DEBUG("ok, !\@list, searching desc for '$query'.");
+ &searchDesc($query);
+ }
}
####
$query =~ s/^\s+|\s+$//g;
# start of search.
- my $start_time = &main::gettimeofday();
+ my $start_time = &main::timeget();
&main::status("Debian: starting author search.");
my $files;
my ($bad,$good) = (0,0);
my %urls = %urlpackages;
- ### potato now has the "new" non-US tree like woody does.
- if ($dist =~ /^(woody|potato)$/) {
- %urls = &fixNonUS($dist, %urlpackages);
- }
foreach (keys %urlpackages) {
s/##DIST/$dist/g;
if (/^Package: (\S+)$/) {
$package = $1;
} elsif (/^Maintainer: (.*) \<(\S+)\>$/) {
- $maint{$1}{$2} = 1;
- $pkg{$1}{$package} = 1;
+ my($name,$email) = ($1,$2);
+ if ($package eq "") {
+ &main::DEBUG("sA: package == NULL.");
+ next;
+ }
+ $maint{$name}{$email} = 1;
+ $pkg{$name}{$package} = 1;
+ $package = "";
} else {
&main::WARN("invalid line: '$_'.");
}
my @pkg = sort keys %{$pkg{$list[0]}};
# show how long it took.
- my $delta_time = &main::gettimeofday() - $start_time;
+ my $delta_time = &main::timedelta($start_time);
&main::status(sprintf("Debian: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0);
my $email = join(', ', keys %{$maint{$list[0]}});
&main::performStrictReply( &main::formListReply(0, $prefix, @pkg) );
}
+####
+# Usage: &searchDesc($query);
+sub searchDesc {
+ my ($dist, $query) = &getDistroFromStr($_[0]);
+ &main::DEBUG("searchDesc: dist => '$dist', query => '$query'.");
+ $query =~ s/^\s+|\s+$//g;
+
+ # start of search.
+ my $start_time = &main::timeget();
+ &main::status("Debian: starting desc search.");
+
+ my $files;
+ my ($bad,$good) = (0,0);
+ my %urls = %urlpackages;
+
+ foreach (keys %urlpackages) {
+ s/##DIST/$dist/g;
+
+ if (! -f $_) {
+ $bad++;
+ next;
+ }
+
+ $good++;
+ $files .= " ".$_;
+ }
+
+ &main::DEBUG("good = $good, bad = $bad...");
+
+ if ($good == 0 and $bad != 0) {
+ my %urls = &fixDist($dist, %urlpackages);
+ &main::DEBUG("deb: download 2c.");
+ if (!&DebianDownload($dist, %urls)) {
+ &main::ERROR("Debian(sD): could not download files.");
+ return;
+ }
+ }
+
+ my (%desc, $package);
+ open(IN,"zegrep -h '^Package|^Description' $files |");
+ while (<IN>) {
+ if (/^Package: (\S+)$/) {
+ $package = $1;
+ } elsif (/^Description: (.*)$/) {
+ my $desc = $1;
+ next unless ($desc =~ /\Q$query\E/i);
+ if ($package eq "") {
+ &main::WARN("sD: package == NULL?");
+ next;
+ }
+ $desc{$package} = $desc;
+ $package = "";
+ } else {
+ &main::WARN("invalid line: '$_'.");
+ }
+ }
+ close IN;
+
+ my @list = keys %desc;
+ if (!scalar @list) {
+ my $prefix = "Debian Desc Search of '$query' ";
+ &main::performStrictReply( &main::formListReply(0, $prefix, ) );
+ } elsif (scalar @list == 1) { # list = 1.
+ &main::DEBUG("list == 1; showing package info of '$list[0]'.");
+ &infoPackages("info", $list[0]);
+ } else { # list > 1.
+ my $prefix = "Debian Desc Search of '$query' ";
+ &main::performStrictReply( &main::formListReply(0, $prefix, @list) );
+ }
+
+ # show how long it took.
+ my $delta_time = &main::timedelta($start_time);
+ &main::status(sprintf("Debian: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0);
+}
+
####
# Usage: &generateIncoming();
sub generateIncoming {
my $idxfile = $pkgfile.".idx";
my $stale = 0;
$stale++ if (&main::isStale($pkgfile.".gz", $interval));
- $stale++ if (&main::isStale($idxfile.".gz", $interval));
+ $stale++ if (&main::isStale($idxfile, $interval));
&main::DEBUG("gI: stale => '$stale'.");
return 0 unless ($stale);
$pkg{'section'} = $1;
} elsif (/^Size: (.*)$/) {
$pkg{'size'} = $1;
- } elsif (/^i.*size: (.*)$/) {
+ } elsif (/^Installed-Size: (.*)$/i) {
$pkg{'installed'} = $1;
} elsif (/^Description: (.*)$/) {
$pkg{'desc'} = $1;
} elsif (/^Size: (.*)$/) { # compressed size.
$stats{$file}{'csize'} += $1;
$total{'csize'} += $1;
- } elsif (/^i.*size: (.*)$/) { # installed size.
+ } elsif (/^i.*size: (.*)$/i) { # installed size.
$stats{$file}{'isize'} += $1;
$total{'isize'} += $1;
}
close IN;
}
+ ### TODO: don't count ppl with multiple email addresses.
+
&main::performStrictReply(
"Debian Distro Stats on $dist... ".
"\002$total{'count'}\002 packages, ".
# Usage: &generateIndex();
sub generateIndex {
my (@dists) = @_;
- &main::DEBUG("Debian: generateIndex() called.");
- if (!scalar @dists) {
+ &main::status("Debian: !!! generateIndex() called !!!");
+ if (!scalar @dists or $dists[0] eq '') {
&main::ERROR("gI: no dists to generate index.");
return 1;
}
next;
}
+ if (/^woody$/i) {
+ &main::DEBUG("Copying old index of woody to -old");
+ system("cp $idx $idx-old");
+ }
+
&main::DEBUG("gIndeX: calling DebianDownload($dist, ...).");
&DebianDownload($dist, %urlpackages);
- &main::status("Debian: generating index for '$_'.");
+ &main::status("Debian: generating index for '$dist'.");
if (!open(OUT,">$idx")) {
&main::ERROR("cannot write to $idx.");
return 0;
open(IN,"zcat $packages |");
while (<IN>) {
- if (/^Package: (.*)\n$/) {
- print OUT $1."\n";
- }
+ next unless (/^Package: (.*)\n$/);
+ print OUT $1."\n";
}
close IN;
}
next;
}
- if (/^$package\n$/) {
+ if (/^\Q$package\E\n$/) {
push(@files,$file);
}
$count++;
my ($dist, $query) = &getDistroFromStr($_[0]);
my $file = "debian/Packages-$dist.idx";
my @files;
- my $error = 0;
+ my $error = 0;
+ my $warn = 0;
- &main::status("Debian: Search package matching '$query' in '$dist'.");
- if ( -z $file) {
- &main::DEBUG("sP: $file == NULL; removing, redoing.");
- unlink $file;
+ if ($query =~ tr/A-Z/a-z/) {
+ $warn++;
}
+ &main::status("Debian: Search package matching '$query' in '$dist'.");
+ unlink $file if ( -z $file);
+
while (!open(IN, $file)) {
- &main::ERROR("$file does not exist (#2).");
if ($dist eq "incoming") {
&main::DEBUG("sP: dist == incoming; calling gI().");
&generateIncoming();
&main::ERROR("could not generate index!!!");
return;
}
+
$error++;
+ &main::DEBUG("should we be doing this?");
&generateIndex(($dist));
}
chop;
if (/^\*(.*)$/) {
- &main::DEBUG("sP: hrm => '$1'.");
$file = $1;
+
+ if (&main::isStale($file, $main::param{'debianRefreshInterval'})) {
+ &main::DEBUG("STALE $file! regen.");
+ &generateIndex(($dist));
+### @files = searchPackage("$query $dist");
+ &main::DEBUG("EVIL HACK HACK HACK.");
+ last;
+ }
+
next;
}
}
close IN;
+ if (scalar @files and $warn) {
+ &main::msg($main::who, "searching for package name should be fully lowercase!");
+ }
+
return @files;
}
$dist = $defaultdist;
}
+ if ($dist =~ /^(slink|hamm|rex|bo)$/i) {
+ &main::DEBUG("Debian: deprecated version ($dist).");
+ &main::msg($main::who, "Debian: deprecated distribution version.");
+ return;
+ }
+
if (exists $dists{$dist}) {
return $dists{$dist};
} else {
my $dist = $defaultdist;
if ($str =~ s/\s+($dists)$//i) {
- &main::status("Debian(gDFS): found dist argument!");
$dist = &getDistro(lc $1);
$str =~ s/\\+$//;
}
- &main::DEBUG("gDFS: str => '$str', dist => '$dist'.");
-
$str =~ s/\\([\$\^])/$1/g;
return($dist,$str);
}
}
-### TODO: move DWH to &fixDist() or leave it being called by DD?
-sub fixNonUS {
- my ($dist, %urls) = @_;
-
- foreach (keys %urls) {
- last unless ($dist =~ /^(woody|potato)$/);
- next unless (/non-US/);
- &main::DEBUG("DD: Enabling hack(??) for $dist non-US.");
-
- my $file = $_;
- my $url = $urls{$_};
- delete $urls{$file}; # heh.
-
- foreach ("main","contrib","non-free") {
- my ($newfile,$newurl) = ($file,$url);
- # only needed for Packages for now, not Contents; good.
- $newfile =~ s/non-US/non-US_$_/;
- $newurl =~ s#non-US/bin#non-US/$_/bin#;
- $urls{$newfile} = $newurl;
- }
-
- &main::DEBUG("DD: Files: ".scalar(keys %urls));
- last;
- }
-
- %urls;
-}
-
sub debianCheck {
my $dir = "debian/";
my $error = 0;