madison-lite-0.19/0000755000000000000000000000000012263035737010726 5ustar madison-lite-0.19/madison-lite0000755000000000000000000005470512263035303013241 0ustar #! /usr/bin/perl # # Copyright (C) Colin Watson 2003, 2004, 2005, 2006, 2007, 2008, 2010. # # Version comparison algorithm code based on Dpkg::Version: # Copyright (C) Ian Jackson. # Copyright (C) Colin Watson. # Copyright (C) Don Armstrong 2007. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. use warnings; use strict; use feature qw(say state); use Fcntl qw(:flock); use File::Path; use Getopt::Long; use constant VERSION => '0.19'; use constant USER_CONFIG => "$ENV{HOME}/.madison-lite"; use constant SYSTEM_CONFIG => '/etc/madison-lite'; use constant CACHE_FORMAT => 2; my $configfile; my $simplemirror; my $caching = 1; my $update_cache = 0; my $source_and_binary = 0; my $regex = 0; my ($architectures, %architectures); my ($components, %components); my ($suites, @suites); my %config; my (@packages, %packages); ############################################################################ # Utility functions ############################################################################ # Print a usage message to FILEHANDLE and exit with status EXITCODE. sub usage (*$) { my ($filehandle, $exitcode) = @_; print $filehandle <) { chomp; next if /^#/; if (/^mirror\s+(.*)/) { $config{mirror} = $1; } elsif (/^suite\s+(.*?) # name \s+(.*?) # directory ((?: \s+(.*?) )*) # optional components $/x) { my ($name, $directory, $components) = ($1, $2, $3); $config{suites}{$name} = $directory; push @{$config{suiteorder}}, $name; $components =~ s/^\s+//; $config{suitecomponents}{$name} = [split ' ', $components]; } else { say STDERR "$0: $filename:$.: unrecognized directive '$_'"; } } return 1; } # Compare two architecture names. Normal comparison except that 'source' # always compares earlier. sub archcmp ($$) { if ($_[0] eq 'source') { if ($_[1] eq 'source') { return 0; } else { return -1; } } else { if ($_[1] eq 'source') { return 1; } else { return $_[0] cmp $_[1]; } } } # Parse a Debian version number into its component parts. sub parseversion ($) { my $ver = shift; my %verhash; if ($ver =~ /:/) { $ver =~ /^(\d+):(.+)/ or die "bad version number '$ver'"; $verhash{epoch} = $1; $ver = $2; } else { $verhash{epoch} = 0; } if ($ver =~ /(.+)-(.+)$/) { $verhash{version} = $1; $verhash{revision} = $2; } else { $verhash{version} = $ver; $verhash{revision} = 0; } return %verhash; } # Compare upstream-version or Debian-revision components of a Debian version # number. sub verrevcmp ($$) { sub order ($) { my ($x) = @_; # #define order(x) ((x) == '~' ? -1 \ # : cisdigit((x)) ? 0 \ # : !(x) ? 0 \ # : cisalpha((x)) ? (x) \ # : (x) + 256) # This comparison is out of dpkg's order to avoid # comparing things to undef and triggering warnings. if (not defined $x) { return 0; } elsif ($x eq '~') { return -1; } elsif ($x =~ /^\d$/) { return 0; } elsif ($x =~ /^[A-Z]$/i) { return ord($x); } else { return ord($x) + 256; } } sub next_elem (\@) { my $a = shift; return @{$a} ? shift @{$a} : undef; } my ($val, $ref) = @_; $val = "" if not defined $val; $ref = "" if not defined $ref; my @val = split //, $val; my @ref = split //, $ref; my $vc = next_elem @val; my $rc = next_elem @ref; while (defined $vc or defined $rc) { my $first_diff = 0; while ((defined $vc and $vc !~ /^\d$/) or (defined $rc and $rc !~ /^\d$/)) { my $vo = order($vc); my $ro = order($rc); # Unlike dpkg's verrevcmp, we only return 1 or -1 here. return (($vo - $ro > 0) ? 1 : -1) if $vo != $ro; $vc = next_elem @val; $rc = next_elem @ref; } while (defined $vc and $vc eq '0') { $vc = next_elem @val; } while (defined $rc and $rc eq '0') { $rc = next_elem @ref; } while (defined $vc and $vc =~ /^\d$/ and defined $rc and $rc =~ /^\d$/) { $first_diff = ord($vc) - ord($rc) if !$first_diff; $vc = next_elem @val; $rc = next_elem @ref; } return 1 if defined $vc and $vc =~ /^\d$/; return -1 if defined $rc and $rc =~ /^\d$/; return $first_diff if $first_diff; } return 0; } # Compare the two arguments as dpkg-style version numbers. Returns -1 if the # first argument represents a lower version number than the second, 1 if the # first argument represents a higher version number than the second, and 0 # if the two arguments represent equal version numbers. sub vercmp ($$) { my %version = parseversion $_[0]; my %refversion = parseversion $_[1]; return 1 if $version{epoch} > $refversion{epoch}; return -1 if $version{epoch} < $refversion{epoch}; my $r = verrevcmp $version{version}, $refversion{version}; return $r if $r; return verrevcmp $version{revision}, $refversion{revision}; } # Find the first of FILENAME, FILENAME.gz, or FILENAME.bz2 that exists. sub find_list_file ($) { my $filename = shift; if (-f $filename) { return $filename; } elsif (-f "$filename.gz") { return "$filename.gz"; } elsif (-f "$filename.bz2") { return "$filename.bz2"; } else { return undef; } } # Open a Packages or Sources file FILENAME, decompressing it if necessary. # Return a filehandle associated with that (uncompressed) file, or undef if # it could not be opened successfully. sub open_list_file ($) { my $filename = shift; return undef unless defined $filename; my $fh; if ($filename =~ /\.gz$/) { open my $fh, "zcat \Q$filename\E |" or return undef; return $fh; } elsif ($filename =~ /\.bz2$/) { open my $fh, "bzcat \Q$filename\E |" or return undef; return $fh; } else { open my $fh, "< $filename" or return undef; return $fh; } } # Print a warning about caching being disabled, unless it has been printed # before. sub caching_disabled ($) { state $cache_warning_printed = 0; return if $cache_warning_printed; my $why = shift; say STDERR "$0: caching disabled because $why"; $cache_warning_printed = 1; } my $cache_dir_created = 0; sub ensure_cache_dir () { my $cache_dir = USER_CONFIG . '/cache'; return $cache_dir if $cache_dir_created; eval { mkpath ($cache_dir); }; die "$0: can't create cache directory '$cache_dir': $@" if $@; $cache_dir_created = 1; unless (-f "$cache_dir/CACHEDIR.TAG") { if (open TAG, "> $cache_dir/CACHEDIR.TAG") { print TAG <', "$cache_dir/lock") { die "Unable to open lock-file $cache_dir/lock"; } flock $cache_lock_fh, LOCK_SH; return 1; } # Upgrade to a write-lock (blocking) sub upgrade_cache_lock () { flock $cache_lock_fh, LOCK_EX; } # Encode FILENAME into a cache filename. sub cache_filename ($) { my $filename = shift; eval { require Digest::MD5; import Digest::MD5 qw(md5_hex); }; if ($@) { caching_disabled 'Digest::MD5 cannot be loaded'; return undef; } my $cache_dir = ensure_cache_dir; return "$cache_dir/" . md5_hex ($filename); } # Print the cache format to FILEHANDLE. sub cache_print_format (*) { my $filehandle = shift; print $filehandle 'Format: ', CACHE_FORMAT, "\n"; } # Check the cache format in FILEHANDLE. Return true if it's OK, otherwise # false. sub cache_check_format (*) { my $filehandle = shift; my $line = <$filehandle>; return 0 unless defined $line; chomp $line; if ($line eq ('Format: ' . CACHE_FORMAT)) { return 1; } else { return 0; } } # Convert a list file FILENAME into cached form. The package cache contains: # # The source cache contains: # (space-separated) # Return true if a cached form is now available, otherwise false. sub cache_list_file ($$$) { my ($filename, $what, $is_packages) = @_; my $real_filename = find_list_file $filename; unless (defined $real_filename) { warn "$0: can't find $what\n"; return 0; } my $listtime = (stat $real_filename)[9]; my $cache_filename = cache_filename $filename; return 0 unless defined $cache_filename; # Already cached? if (not $update_cache and (-f "$cache_filename.pkg" and (stat "$cache_filename.pkg")[9] >= $listtime) and (-f "$cache_filename.src" and (stat "$cache_filename.src")[9] >= $listtime)) { local (*PCACHE, *SCACHE); if ((open PCACHE, "< $cache_filename.pkg") and (open SCACHE, "< $cache_filename.src") and cache_check_format (*PCACHE) and cache_check_format (*SCACHE)) { return 1; } } upgrade_cache_lock; my $fh = open_list_file $real_filename; unless (open PCACHE, "> $cache_filename.pkg") { caching_disabled "'$cache_filename.pkg' cannot be opened: $!"; return 0; } cache_print_format *PCACHE; print PCACHE "Original: $filename\n"; my %sources; local $/ = ''; # paragraph mode local $_; while (<$fh>) { if (/^Package:\s+(.*)/m) { my $package = $1; next if $package =~ /\s/; if (/^Version:\s+(.*)/m) { my $version = $1; if ($is_packages and /^Architecture: all$/m) { print PCACHE "$package $version all\n"; } else { print PCACHE "$package $version\n"; } } if (/^Source:\s+(.*)/m) { # Packages file push @{$sources{$1}}, $package; } # Don't bother with Binary: entries in Sources files. There # should always be corresponding Package: and Source: pairs in # Packages, and if there aren't we won't be able to do anything # useful with the source-to-binary mapping anyway. } } close PCACHE; unless (open SCACHE, "> $cache_filename.src") { caching_disabled "'$cache_filename.src' cannot be opened: $!"; return 0; } cache_print_format *SCACHE; print SCACHE "Original: $filename\n"; for my $source (sort keys %sources) { print SCACHE "$source ", (join ' ', @{$sources{$source}}), "\n"; } close SCACHE; return 1; # $fh is auto-closed } # Search a list file for %packages, given a FILEHANDLE and a precompiled # regex FIELD matching the desired field names. sub search_list_file ($$$$) { my ($fh, $field, $is_packages, $arch) = @_; my @results; # Precompile search pattern. my $packlist; if ($regex) { $packlist = join '|', map "(?:$_)", keys %packages; } else { $packlist = join '|', map "\Q$_\E\$", keys %packages; } my $search = qr/^$field:\s+(?:$packlist)/; local $/ = ''; # paragraph mode local $_; while (<$fh>) { if (/$search/m) { next unless /^Package: (.*)/m; # might have been Package|Source my $foundpackage = $1; next unless /^Version: (.*)/m; my $foundversion = $1; my $foundsource; # If the source isn't in our list of packages to search for, # then it doesn't matter for sorting purposes, so just pretend # it's $foundpackage. if (/^Source: (.*)/m and exists $packages{$1}) { $foundsource = $1; } else { $foundsource = $foundpackage; } # not necessarily already set for source packages matched by regex unless (exists $packages{$foundsource}) { $packages{$foundsource} = $foundsource; push @packages, $foundsource; } if ($is_packages and /^Architecture: all/m) { push @results, [$foundsource, $foundpackage, $foundversion, 'all']; } else { push @results, [$foundsource, $foundpackage, $foundversion, $arch]; } } } return @results; } # Search the cache file corresponding to FILENAME for %packages. sub search_cache ($$) { my ($filename, $arch) = @_; my $cache_filename = cache_filename $filename; return () unless defined $cache_filename; my @results; my $pkglist; my $match; if ($regex) { $pkglist = join '|', map "(?:$_)", keys %packages; } else { $pkglist = join '|', map "\Q$_\E\$", keys %packages; } $match = qr/^(?:$pkglist)/; if (($source_and_binary or $regex) and open SCACHE, "< $cache_filename.src") { # Look for source cache entries, indicating additional packages we # need to find. local $_; while () { next if /^\S+: /; my ($key, @values) = split; if (($source_and_binary and $key =~ /$match/) or ($regex and grep /$match/, @values)) { $packages{$_} = $key foreach @values; } } close SCACHE; } if ($regex) { $pkglist = join '|', map "(?:$_)", keys %packages; } else { $pkglist = join '|', map "\Q$_\E\$", keys %packages; } $match = qr/^(?:$pkglist)/; open PCACHE, "< $cache_filename.pkg" or return (); local $_; while () { next if /^\S+: /; my ($key, $value, $is_all) = split; if ($key =~ /$match/) { # not necessarily already set for source packages matched by regex unless (exists $packages{$key}) { $packages{$key} = $key; push @packages, $key; } if (defined $is_all and $is_all eq 'all') { push @results, [$packages{$key}, $key, $value, 'all']; } else { push @results, [$packages{$key}, $key, $value, $arch]; } } } close PCACHE; return @results; } # Search the Packages file in a directory, if any, for %packages. sub search_packages ($$) { my ($dir, $arch) = @_; if ($caching and take_cache_read_lock and cache_list_file "$dir/Packages", "Packages list file in '$dir'", 1) { return search_cache "$dir/Packages", $arch; } else { my $fh = open_list_file (find_list_file "$dir/Packages"); unless (defined $fh) { warn "$0: can't find Packages list file in '$dir'\n"; return; } my $field; if ($source_and_binary) { $field = qr/(?:Package|Source)/; } else { $field = qr/Package/; } return search_list_file $fh, $field, 1, $arch; # $fh is auto-closed } } # Search the Sources file in a directory, if any, for %packages. sub search_sources ($$) { my ($dir, $arch) = @_; if ($caching and take_cache_read_lock and cache_list_file "$dir/Sources", "Sources list file in '$dir'", 0) { return search_cache "$dir/Sources", $arch; } else { my $fh = open_list_file (find_list_file "$dir/Sources"); unless (defined $fh) { warn "$0: can't find Sources list file in '$dir'\n"; return; } my $field = qr/Package/; return search_list_file $fh, $field, 0, $arch; # $fh is auto-closed } } ############################################################################ # Read configuration ############################################################################ Getopt::Long::Configure qw(no_ignore_case); my $optresult = GetOptions ( 'help|h|?' => sub { usage *STDOUT, 0 }, 'version' => \&showversion, 'config-file=s' => \$configfile, 'mirror=s' => \$simplemirror, 'cache!' => \$caching, 'update!' => \$update_cache, 'source-and-binary|S' => \$source_and_binary, 'regex|r' => \$regex, 'architecture|a=s' => \$architectures, 'component|c=s' => \$components, 'suite|s=s' => \$suites, ); if (!$optresult) { usage *STDERR, 1; } elsif (!@ARGV) { usage *STDERR, 1; } if ($configfile) { unless (read_config $configfile) { say STDERR "$0: can't find configuration file '$configfile'"; } } else { unless (read_config (USER_CONFIG . '/config')) { read_config (SYSTEM_CONFIG . '/config'); } } $config{mirror} = $simplemirror if defined $simplemirror; # Apply default configuration if necessary. unless (exists $config{mirror}) { $config{mirror} = '.'; } unless (exists $config{suites}) { opendir MIRROR, "$config{mirror}/dists" or die "$0: can't open mirror directory '$config{mirror}/dists'\n"; my @dirents = sort grep { !/^\.\.?$/ } readdir MIRROR; for my $dirent (@dirents) { # Ignore symlinks to other suites in the same directory (e.g. # unstable -> sid). if (-l "$config{mirror}/dists/$dirent" and (readlink "$config{mirror}/dists/$dirent") !~ m[/]) { next; } if (-d "$config{mirror}/dists/$dirent") { $config{suites}{$dirent} = "dists/$dirent"; push @{$config{suiteorder}}, $dirent; $config{suitecomponents}{$dirent} = []; } } closedir MIRROR; die "$0: no suites found in $config{mirror}/dists\n" unless exists $config{suites}; } ############################################################################ # Main search loop ############################################################################ @packages = @ARGV; %packages = map { $_ => $_ } @packages; %architectures = map { $_ => 1 } split /[, ]+/, $architectures if defined $architectures; %components = map { $_ => 1 } split /[ ,]+/, $components if defined $components; # Find the list of suites we're looking at. my @allsuites; if (defined $suites) { @suites = split /[, ]+/, $suites if defined $suites; for my $cursuite (@suites) { die "$0: unknown suite '$cursuite'\n" unless exists $config{suites}{$cursuite}; } } else { @suites = @{$config{suiteorder}}; } # Compare two suite names in configured suite order. sub suitecmp ($$) { for my $suite (@suites) { if ($_[0] eq $suite) { if ($_[1] eq $suite) { return 0; } else { return -1; } } elsif ($_[1] eq $suite) { return 1; } } return $_[0] cmp $_[1]; } # Search through all Packages and Sources files for %packages. my %results; for my $cursuite (@suites) { my $cursuitedir = $config{suites}{$cursuite}; $cursuitedir = "$config{mirror}/$cursuitedir" if $cursuitedir !~ m[^/]; # e.g. /debian/dists/stable # Find the list of components we're looking at; might be listed # explicitly in the configuration file and/or on the command line. my @components = @{$config{suitecomponents}{$cursuite}}; unless (@components) { unless (opendir SUITE, $cursuitedir) { warn "$0: can't open suite directory '$cursuitedir'\n"; next; } my @dirents = sort grep { !/^\.\.?$/ } readdir SUITE; for my $dirent (@dirents) { push @components, $dirent if -d "$cursuitedir/$dirent"; } closedir SUITE; } @components = grep { $components{$_} } @components if %components; for my $curcomp (@components) { next if $curcomp =~ /^\.\.?$/; # e.g. /debian/dists/stable/main my $curcompdir = "$cursuitedir/$curcomp"; unless (opendir COMPONENT, "$curcompdir") { warn "$0: can't open component directory '$curcompdir'\n"; next; } while (my $curarch = readdir COMPONENT) { my @archresults; my $curarchdir = "$curcompdir/$curarch"; if ($curarch =~ /^binary-(.*)$/) { # e.g. /debian/dists/stable/main/binary-i386 $curarch = $1; next if defined $architectures and not $architectures{$curarch}; @archresults = search_packages $curarchdir, $curarch; } elsif ($curarch eq 'source') { # e.g. /debian/dists/stable/main/source next if defined $architectures and not $architectures{'source'}; @archresults = search_sources $curarchdir, $curarch; } else { next; } for my $result (@archresults) { my ($ressource, $respackage, $resversion, $resarch) = @$result; $results{$ressource}{$respackage}{$resversion}{$cursuite}{$curcomp}{$resarch} = 1; } } closedir COMPONENT; } } # Calculate optimal column sizes. my @sizes = (0, 0, 0); for my $package (@packages) { next unless exists $results{$package}; for my $binpkg (sort keys %{$results{$package}}) { for my $version (sort vercmp keys %{$results{$package}{$binpkg}}) { for my $suite (sort suitecmp keys %{$results{$package}{$binpkg}{$version}}) { for my $comp (sort keys %{$results{$package}{$binpkg}{$version}{$suite}}) { my $dispsuite = $suite; if ($comp ne 'main') { $dispsuite = "$suite/$comp"; } my $pkglen = length $binpkg; my $verlen = length $version; my $suitelen = length $dispsuite; $sizes[0] = $pkglen if $pkglen > $sizes[0]; $sizes[1] = $verlen if $verlen > $sizes[1]; $sizes[2] = $suitelen if $suitelen > $sizes[2]; } } } } } # Print out the results. for my $package (@packages) { next unless exists $results{$package}; for my $binpkg (sort keys %{$results{$package}}) { for my $version (sort vercmp keys %{$results{$package}{$binpkg}}) { for my $suite (sort suitecmp keys %{$results{$package}{$binpkg}{$version}}) { for my $comp (sort keys %{$results{$package}{$binpkg}{$version}{$suite}}) { my $dispsuite = $suite; if ($comp ne 'main') { $dispsuite = "$suite/$comp"; } printf " %-*s | %-*s | %-*s | %s\n", $sizes[0], $binpkg, $sizes[1], $version, $sizes[2], $dispsuite, (join ', ', sort archcmp keys %{$results{$package}{$binpkg}{$version}{$suite}{$comp}}); } } } } } madison-lite-0.19/debian/0000755000000000000000000000000012263035777012154 5ustar madison-lite-0.19/debian/rules0000755000000000000000000000003612250370053013214 0ustar #! /usr/bin/make -f %: dh $@ madison-lite-0.19/debian/install0000644000000000000000000000002512250370053013523 0ustar madison-lite usr/bin madison-lite-0.19/debian/examples0000644000000000000000000000001312250370053013670 0ustar examples/* madison-lite-0.19/debian/copyright0000644000000000000000000000261712263035735014107 0ustar Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: madison-lite Upstream-Contact: Colin Watson Files: madison-lite Copyright: 2003, 2004, 2005, 2006, 2007, 2008 Colin Watson Ian Jackson 2007 Don Armstrong License: GPL-2+ On Debian and Debian-based systems, a copy of the GNU General Public License version 2 is available in /usr/share/common-licenses/GPL-2. Files: madison-lite.1 Copyright: 2003, 2004, 2005, 2006, 2007, 2008 Colin Watson License: GPL-2+ Files: examples/* Copyright: 2004, 2006, 2008 Colin Watson 2006 Adam D. Barratt 2006 Reinhard Tartler License: BSD-2 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Files: debian/* Copyright: 2003, 2004, 2005, 2006, 2007, 2008 Colin Watson License: GPL-2+ License: GPL-2+ On Debian and Debian-based systems, a copy of the GNU General Public License version 2 is available in /usr/share/common-licenses/GPL-2. madison-lite-0.19/debian/source/0000755000000000000000000000000012250370053013435 5ustar madison-lite-0.19/debian/source/format0000644000000000000000000000001512250370053014644 0ustar 3.0 (native) madison-lite-0.19/debian/compat0000644000000000000000000000000212250370053013333 0ustar 7 madison-lite-0.19/debian/control0000644000000000000000000000207412263035104013542 0ustar Source: madison-lite Section: admin Priority: optional Maintainer: Colin Watson Standards-Version: 3.9.5 Build-Depends: debhelper (>= 7.0.0) Vcs-Git: git://anonscm.debian.org/users/cjwatson/madison-lite.git Vcs-Browser: http://anonscm.debian.org/gitweb/?p=users/cjwatson/madison-lite.git Package: madison-lite Architecture: all Depends: perl (>= 5.10), ${misc:Depends} Recommends: libdigest-md5-perl Suggests: wget Description: display versions of Debian packages in an archive This program inspects a local Debian package archive and displays the versions of the given packages found in each suite (for example, stable, testing, or unstable) in a brief but easily human-readable form. It aims to be a drop-in replacement for the madison utility from the da-katie archive management suite that runs on the central Debian archive systems, but one which can run without access to the archive's SQL database. . For simple queries, you can use http://packages.debian.org/ instead, which does not require you to have access to a system with a local mirror. madison-lite-0.19/debian/changelog0000644000000000000000000001567512263035777014044 0ustar madison-lite (0.19) unstable; urgency=low * Switch to git; adjust Vcs-* fields. * Convert debian/copyright to copyright-format 1.0. * Policy version 3.9.5. -- Colin Watson Tue, 07 Jan 2014 17:40:14 +0000 madison-lite (0.18) unstable; urgency=low * Calculate optimal column sizes in the same way as Debian's madison.cgi, and otherwise tweak output formatting to match (LP: #315833). -- Colin Watson Tue, 26 Nov 2013 10:20:59 +0000 madison-lite (0.17) unstable; urgency=low * make-local-mirror: Use 'set -e' rather than '#! /bin/sh -e', to avoid accidents when debugging with 'sh -x'. * Ensure that the cache directory exists before creating the lock. * Print lock file name in the error message emitted if we fail to open it. -- Colin Watson Tue, 24 Sep 2013 09:50:47 +0100 madison-lite (0.16) unstable; urgency=low [ Colin Watson ] * Update Vcs-Bzr field for Alioth changes. * Add Vcs-Browser field. [ Stefano Rivera ] * Avoid multiple madison-lites updating the same cache file at the same time, by having a cache-wide lock file. -- Colin Watson Wed, 28 Nov 2012 12:05:14 +0000 madison-lite (0.15) unstable; urgency=low * Convert to source format 3.0 (native). * Use the 'say' feature from Perl 5.10. * Use the 'state' feature to simplify caching_disabled. * Convert from 'perl -w' to 'use warnings'. * Make regex searches actually produce some output (closes: #576941). * Policy version 3.9.1: no changes required. -- Colin Watson Fri, 05 Nov 2010 16:02:25 +0000 madison-lite (0.14) unstable; urgency=low * Moved to bzr.debian.org; add Vcs-Bzr control field. * Convert to debhelper 7. -- Colin Watson Sun, 26 Jul 2009 11:25:14 +0100 madison-lite (0.13) unstable; urgency=low * Update version comparison code from Dpkg::Version in dpkg-dev 1.14.20; adds ~ (low-sorting character) support. * Policy version 3.8.0: no changes required. * Relicense to GPLv2+. I'm using a decent chunk of Dpkg::Version, which is also GPLv2+, and dealing with a mixed-licence file is just too annoying. I don't know of anyone this will adversely affect; if it does, e-mail me and I'll be willing to discuss the matter. (The examples are still 2-clause BSD.) * Convert to machine-readable copyright format, wiki revision 179. -- Colin Watson Fri, 04 Jul 2008 22:33:48 +0100 madison-lite (0.12) unstable; urgency=low * Update copyright years and manual page revision date. * Only try to create the cache directory once, to save on stat calls. * Create a cache directory tag, per http://www.brynosaurus.com/cachedir/ ("Cache Directory Tagging Standard"). * Policy version 3.7.3: no changes required. * Update example Ubuntu configuration for current release names. -- Colin Watson Thu, 28 Feb 2008 10:44:08 +0000 madison-lite (0.11) unstable; urgency=low * Fix --nocache mode handling of binary packages whose source packages aren't also in the list of packages to search for. * Note that madison proper has been renamed to 'dak ls'. Refer to dak rather than da-katie. -- Colin Watson Wed, 01 Aug 2007 16:02:12 +0100 madison-lite (0.10) unstable; urgency=low * Put debhelper in Build-Depends rather than in Build-Depends-Indep. -- Colin Watson Wed, 28 Jun 2006 18:38:31 +0100 madison-lite (0.9) unstable; urgency=low * Remove special handling for experimental in make-local-mirror (thanks, Adam D. Barratt; closes: #354223). * Add amd64 support to make-local-mirror for testing, unstable, and experimental (thanks, Adam D. Barratt; closes: #354224). * Add hurd-i386 support to make-local-mirror for unstable and experimental (thanks, Adam D. Barratt; closes: #354225). * Add an example configuration for ubuntu.com hosts. * Add support for Ubuntu and Ubuntu ports archives to make-local-mirror, which can be enabled by including 'ubuntu ubuntu-ports' in the ARCHIVES environment variable; add an example configuration that works with make-local-mirror's default output (thanks, Reinhard Tartler; closes: #354104). * Remove proposed-updates, testing, testing-proposed-updates, unstable, and experimental from default non-US components in make-local-mirror; none of them exist any more. * Fix --config-file option. * If a Packages file can't be found, continue with a warning rather than dying. -- Colin Watson Fri, 31 Mar 2006 10:46:18 +0100 madison-lite (0.8) unstable; urgency=low * Display the component if it's not "main". -- Colin Watson Tue, 7 Feb 2006 20:01:20 +0000 madison-lite (0.7) unstable; urgency=low * Fix missing binary packages in --source-and-binary output (closes: #344803). * Adjust sorting again in --source-and-binary mode to sort by binary package name within the listing for each source package. -- Colin Watson Tue, 7 Feb 2006 19:42:45 +0000 madison-lite (0.6) unstable; urgency=low * Sort output by packages in the order specified on the command-line (to match madison) rather than interleaving results for different packages. -- Colin Watson Fri, 9 Dec 2005 11:34:27 +0000 madison-lite (0.5) unstable; urgency=low * If a suite/component/architecture is missing from the mirror, just warn rather than dying. -- Colin Watson Thu, 27 Oct 2005 13:26:32 +0100 madison-lite (0.4) unstable; urgency=low * Update publication years in copyright notices. * Fix regex searches to match those of madison, which are only anchored at the start of the package name, not the end. * Upgrade to debhelper v4. * Policy version 3.6.2. No changes required. -- Colin Watson Mon, 8 Aug 2005 01:12:32 +0100 madison-lite (0.3) unstable; urgency=low * make-local-mirror fetches proposed-updates and testing-proposed-updates too. * Sort versions (pure-Perl version comparison code from Debbugs::Versions::Dpkg) and architectures (source always comes first) the same way madison does (closes: #230169). -- Colin Watson Thu, 10 Feb 2005 00:04:15 +0000 madison-lite (0.2) unstable; urgency=low * Add example configuration for debian.org hosts with complete local mirrors. * Make --help output more like madison's and more readable. * When guessing available suites in the absence of 'suite' configuration directives, ignore symlinks to other suites in the same directory (e.g. unstable -> sid). * Mention packages.debian.org in the package description. * Add an example script to build a local index-only mirror. -- Colin Watson Sat, 24 Jan 2004 17:16:40 +0000 madison-lite (0.1) unstable; urgency=low * Initial release. -- Colin Watson Sat, 24 Jan 2004 14:50:03 +0000 madison-lite-0.19/debian/manpages0000644000000000000000000000001712250370053013651 0ustar madison-lite.1 madison-lite-0.19/examples/0000755000000000000000000000000012263035534012537 5ustar madison-lite-0.19/examples/ubuntu.com.config0000644000000000000000000000630412250370053016022 0ustar # This madison-lite configuration is suitable for a typical ubuntu.com host # with a complete mirror. suite dapper dists/dapper main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite dapper-security dists/dapper-security main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite dapper-proposed dists/dapper-proposed main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite dapper-updates dists/dapper-updates main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite dapper-backports dists/dapper-backports main main/debian-installer restricted universe multiverse suite edgy dists/edgy main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite edgy-security dists/edgy-security main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite edgy-proposed dists/edgy-proposed main main/debian-installer restricted universe multiverse suite edgy-updates dists/edgy-updates main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite edgy-backports dists/edgy-backports main main/debian-installer restricted universe universe/debian-installer multiverse suite feisty dists/feisty main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite feisty-security dists/feisty-security main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite feisty-proposed dists/feisty-proposed main main/debian-installer restricted universe multiverse suite feisty-updates dists/feisty-updates main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite feisty-backports dists/feisty-backports main main/debian-installer restricted universe universe/debian-installer multiverse suite gutsy dists/gutsy main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite gutsy-security dists/gutsy-security main main/debian-installer restricted universe universe/debian-installer multiverse suite gutsy-proposed dists/gutsy-proposed main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite gutsy-updates dists/gutsy-updates main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite gutsy-backports dists/gutsy-backports main main/debian-installer restricted universe multiverse suite hardy dists/hardy main main/debian-installer restricted restricted/debian-installer universe universe/debian-installer multiverse suite hardy-security dists/hardy-security main restricted universe multiverse suite hardy-proposed dists/hardy-proposed main restricted universe multiverse suite hardy-updates dists/hardy-updates main restricted universe multiverse suite hardy-backports dists/hardy-backports main restricted universe multiverse madison-lite-0.19/examples/debian.org.config0000644000000000000000000000106112250370015015724 0ustar # This madison-lite configuration is suitable for a typical debian.org host # with a complete mirror. mirror /org/ftp.debian.org/ftp suite stable dists/stable main contrib non-free suite proposed-updates dists/proposed-updates main contrib non-free suite testing dists/testing main contrib non-free main/debian-installer suite testing-proposed-updates dists/testing-proposed-updates main contrib non-free main/debian-installer suite unstable dists/unstable main contrib non-free main/debian-installer suite experimental dists/experimental main contrib non-free madison-lite-0.19/examples/local-mirror.config0000644000000000000000000000206412250370015016322 0ustar # This madison-lite configuration is suitable for a mirror built with # make-local-mirror. If you change the default value of MIRROR, change the # 'mirror' line too. mirror /tmp/mirror suite stable dists/stable main contrib non-free suite proposed-updates dists/proposed-updates main contrib non-free suite testing dists/testing main contrib non-free suite testing-proposed-updates dists/testing-proposed-updates main contrib non-free suite unstable dists/unstable main contrib non-free suite experimental dists/experimental main contrib non-free suite stable/non-US dists/stable-non-US main contrib non-free suite stable/updates dists/stable-security main contrib non-free suite testing/updates dists/testing-security main contrib non-free # Uncomment the following lines if you are mirroring Ubuntu index files as # well. # suite warty dists/warty main restricted universe multiverse # suite hoary dists/hoary main restricted universe multiverse # suite breezy dists/breezy main restricted universe multiverse # suite dapper dists/dapper main restricted universe multiverse madison-lite-0.19/examples/make-local-mirror0000755000000000000000000000671512250370053016005 0ustar #! /bin/sh set -e # This is an example of how to build a local mirror containing only the # index files, not the packages themselves. If you put something similar to # this in a cron job, then you can run madison-lite locally. Be sure to # change the various hostnames to appropriate mirrors, set MIRROR to a # suitable directory, and fill the mirror directory into your madison-lite # configuration file. # # If you are reading this after the release of sarge, then you may need to # change the lists of distributions and architectures. HOST_MAIN=${HOST_MAIN:-'ftp://ftp.debian.org/debian'} HOST_NONUS=${HOST_NONUS:-'ftp://non-us.debian.org/debian-non-US'} HOST_SECURITY=${HOST_SECURITY:-'ftp://security.debian.org/debian-security'} HOST_UBUNTU=${HOST_UBUNTU:-'http://archive.ubuntu.com/ubuntu'} HOST_UBUNTU_PORTS=${HOST_UBUNTU_PORTS:-'http://ports.ubuntu.com/ubuntu-ports'} MIRROR=${MIRROR:-/tmp/mirror} WGET_OPTS=${WGET_OPTS-'-q -N --passive-ftp'} umask 002 mkdir -p "$MIRROR" cd "$MIRROR" mkdir -p dists cd dists # To mirror Ubuntu index files as well, run this script with: # ARCHIVES='main non-US security ubuntu ubuntu-ports' # set in the environment. archives=${ARCHIVES:-'main non-US security'} for archive in $archives; do case $archive in main) host="$HOST_MAIN" suitesuffix='' suites='stable proposed-updates testing testing-proposed-updates unstable experimental' components='main contrib non-free' ;; non-US) host="$HOST_NONUS" suitesuffix='/non-US' suites='stable' components='main contrib non-free' ;; security) host="$HOST_SECURITY" suitesuffix='/updates' suites='stable testing' components='main contrib non-free' ;; ubuntu) host="$HOST_UBUNTU" suitesuffix='' suites='warty hoary breezy dapper' components='main restricted universe multiverse' ;; ubuntu-ports) host="$HOST_UBUNTU_PORTS" suitesuffix='' suites='hoary breezy dapper' components='main restricted universe multiverse' ;; *) echo "Internal error: archive '$archive'?" >&2 exit 1 esac for suite in $suites; do case $archive in main|ubuntu*) suitehere="$suite" ;; *) suitehere="$suite-$archive" ;; esac mkdir -p "$suitehere" root=dists case $suite in oldstable) arches='alpha arm i386 m68k powerpc sparc' ;; stable) arches='alpha arm hppa i386 ia64 m68k mips mipsel powerpc s390 sparc' ;; testing) arches='alpha amd64 arm hppa i386 ia64 m68k mips mipsel powerpc s390 sparc' ;; unstable|experimental) arches='alpha amd64 arm hppa hurd-i386 i386 ia64 m68k mips mipsel powerpc s390 sparc' ;; warty) arches='amd64 i386 powerpc' ;; hoary) case $archive in ubuntu) arches='amd64 i386 powerpc' ;; ubuntu-ports) arches='ia64 sparc' ;; esac ;; breezy|dapper) case $archive in ubuntu) arches='amd64 i386 powerpc' ;; ubuntu-ports) arches='hppa ia64 sparc' ;; esac ;; esac for component in $components; do mkdir -p "$suitehere/$component" for arch in $arches; do mkdir -p "$suitehere/$component/binary-$arch" wget $WGET_OPTS -O "$suitehere/$component/binary-$arch/Packages.gz" "$host/$root/$suite$suitesuffix/$component/binary-$arch/Packages.gz" done mkdir -p "$suite/$component/source" wget $WGET_OPTS -O "$suite/$component/source/Sources.gz" "$host/$root/$suite$suitesuffix/$component/source/Sources.gz" done done done exit 0 madison-lite-0.19/madison-lite.10000644000000000000000000001136112250370053013364 0ustar .Dd August 1, 2007 .Os Debian .ds volume-operating-system Debian .Dt MADISON\-LITE 1 .Sh NAME .Nm madison\-lite .Nd display versions of Debian packages in an archive .Sh SYNOPSIS .Nm .Op Fl Fl config\-file Ar file .Op Fl Fl mirror Ar directory .Op Fl Fl nocache .Op Fl Fl update .Op Fl S .Op Fl r .Op Fl a Ar architecture Ns Op , Ns Ar ... .Op Fl c Ar component Ns Op , Ns Ar ... .Op Fl s Ar suite Ns Op , Ns Ar ... .Ar package .Op Ar ... .Sh DESCRIPTION .Nm inspects a local Debian package archive and displays the versions of the given packages found in each .Ar suite (for example, .Li stable , .Li testing , or .Li unstable ) in a brief but easily human-readable form. It aims to be a drop-in replacement for the .Ic madison utility (since renamed to .Ic dak ls ) , from the .Ic dak archive management suite that runs on the central Debian archive systems, but one which can run without access to the archive's .Tn SQL database. .Pp The following options are available: .Bl -tag -width 4n .It Fl Fl config\-file Ar file Read configuration from .Ar file , and ignore the system configuration file (see .Sx CONFIGURATION below). .It Fl Fl mirror Ar directory Quick configuration: use .Ar directory as the top level of the Debian mirror. .It Fl Fl nocache Normally, parts of the .Pa Packages and .Pa Sources files in the archive are cached in .Pa ~/.madison\-lite/cache for speed. This option disables that behaviour. .It Fl Fl update Force caches of .Pa Packages and .Pa Sources files to be updated. .It Fl S , Fl Fl source\-and\-binary Interpret .Ar package as a source package name, and display versions of any associated binary packages as well as of the source package. .It Fl r , Fl Fl regex Interpret .Ar package as a Perl regular expression anchored at the start of the package name rather than as an exact name. Make sure to quote any shell metacharacters such as .Sq * or .Sq \&? if necessary. .It Fl a , Fl Fl architecture Ar architecture Ns Op , Ns Ar ... Display only entries for packages built for these architectures. Separate multiple architectures with commas or spaces. .It Fl c , Fl Fl component Ar component Ns Op , Ns Ar ... Display only entries in the given components. Separate multiple components with commas or spaces. .It Fl s , Fl Fl suite Ar suite Ns Op , Ns Ar ... Display only entries in the given suites. Separate multiple suites with commas or spaces. .El .Sh CONFIGURATION .Nm reads configuration information from the file named by .Fl Fl config\-file , or, if that is not supplied, from the first of .Pa ~/.madison\-lite/config and .Pa /etc/madison\-lite/config that exists. .Pp The following configuration directives are recognized: .Bl -tag -width 4n .It Li mirror Ar directory Set the top-level directory of the local Debian mirror. Relative directories in the .Li suite directive are interpreted relative to this directory. Defaults to the current directory. .It Li suite Ar name Ar directory Op Ar component Op Ar ... Defines the suite .Ar name based at .Ar directory , containing the specified components (defaulting to all subdirectories of .Ar directory ) . Output is displayed following the order of .Li suite directives in the configuration file. If no .Li suite directives are present, then every subdirectory of the .Pa dists directory under .Ar mirror is treated as a suite, with all of their subdirectories as components. .Pp The Debian archive is structured such that the subdirectories of each suite directory identify components (such as .Pa main ) . Each of those in turn has subdirectories for each architecture .Pf ( Pa binary\-i386 , and so on), each of which contains any or all of .Pa Packages , .Pa Packages.gz , and .Pa Packages.bz2 files listing binary packages; it also has a subdirectory called .Pa source which contains any or all of .Pa Sources , .Pa Sources.gz , and .Pa Sources.bz2 files listing source packages. .El .Pp The configuration file may contain comment lines, which start with a .Sq # character. .Sh EXAMPLES Show versions of the .Li coreutils package: .Pp .Dl $ madison\-lite coreutils .Pp Show versions of all binary packages on .Li powerpc produced by the .Li glibc source package: .Pp .Dl $ madison\-lite \-S \-a powerpc glibc .Pp Show versions of all packages in the .Li unstable suite whose names begin with .Sq man : .Pp .Dl $ madison\-lite \-s unstable \-r \(aqman.*\(aq .Pp An example configuration file for a simple local mirror: .Bd -literal -offset indent mirror /mirror/debian suite unstable dists/unstable main suite unstable\-non\-US non\-US/dists/unstable non\-US/main .Ed .Sh SEE ALSO .Xr dpkg\-scanpackages 8 , .Xr dpkg\-scansources 8 , .Xr apt\-ftparchive 1 .Sh AUTHORS .An -nosplit .Nm was written by .An "Colin Watson" Aq cjwatson@debian.org . The interface mirrors that of .Ic madison (since renamed to .Ic dak ls ) , written by .An "James Troup" .