r8102 - /man-cgi/extractor/manpage-extractor.pl
Author: jfs
Date: Tue Jan 11 22:26:54 2011
New Revision: 8102
URL: http://svn.debian.org/wsvn/?sc=1&rev=8102
Log:
Changes introduced in paganin while debugging an issue with the manpage regeneration
of the archive (was failing due to a "too many links" error when mv'ing).
- Changes to extract_package():
* generate the directories for packages following the mirror pool subdirectory
structure instead of putting all the package+version subdirectories within
a single location (which leads to the location having just too many subdirs)
* Use 'mkpath' instead of 'mkdir' in order to replicate the pool directory
structure
- Changes to extract_manpages():
* Abort if the 'mv' fails when moving the files from the package to the
extracted manpages directory
* Only remove the mandir if it exists (this is how the above issues were
detected but now the 'mv' call is checked, as it should have been before)
* Use a variable to hold the return value and exit at the end instead of
in the middle of the function to ensure that we remove properly the files
* in order to facilitate debugging of system commands' failure as well
as error handling execute dpkg and tar independently and use a temporary
file instead of a pipe
Modified:
man-cgi/extractor/manpage-extractor.pl
Modified: man-cgi/extractor/manpage-extractor.pl
URL: http://svn.debian.org/wsvn/man-cgi/extractor/manpage-extractor.pl?rev=8102&op=diff
==============================================================================
--- man-cgi/extractor/manpage-extractor.pl (original)
+++ man-cgi/extractor/manpage-extractor.pl Tue Jan 11 22:26:54 2011
@@ -3,7 +3,7 @@
# Scan a Debian pool archive and extract the manpages
# of all binary packages.
#
-# (c) 2006 Javier Fernandez-Sanguino
+# (c) 2006-2011 Javier Fernandez-Sanguino
#
# 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
@@ -25,6 +25,8 @@
use strict;
use File::Basename;
use Getopt::Std;
+use File::Temp qw/tempfile/;
+use File::Path;
# Options
# -d - debug
# -f - force extraction
@@ -71,12 +73,10 @@
chomp($package);
# Obtaint a list of all packages
print "Looking for package $package\n" if $opt_d;
- # TODO: hardcoded mirror location fix
open (PACK, '|', "find $mirror -name \"${package}_*${EXTENSION}\" -a -type f" );
while ( my $file = <PACK> ) {
chomp $file;
extract_package($file);
- extract_manpages($file);
}
close PACK;
print "Finished extraction.\n";
@@ -119,6 +119,7 @@
# The file is a deb file, extract the name of the source files
my @sources;
my $basedir = dirname($file);
+ my $pooldir = $basedir; $pooldir =~ s|^.*pool/||;
my $debfile = basename($file);
my $sourcedir = "";
my $mandir = "";
@@ -138,9 +139,9 @@
$version = $1;
}
if ( $version ne "undefined" ) {
- $mandir = "${OUTPUTDIR}/${packagename}_${version}";
+ $mandir = "${OUTPUTDIR}/${pooldir}/${packagename}_${version}";
} else {
- $mandir = "${OUTPUTDIR}/${packagename}";
+ $mandir = "${OUTPUTDIR}/${pooldir}/${packagename}";
}
if ( -e $mandir && ! $opt_f) {
# Note, this means that we will only analyse one binary package
@@ -148,15 +149,18 @@
print "Skipping package $packagename (version '$version' already extracted)\n";
return 0;
}
- mkdir $mandir || die ("Could not create $mandir: $!");
+ mkpath "$mandir" || die ("Could not create $mandir: $!");
print "Extracting manpages of $packagename version '$version' in $mandir\n";
# You can either do a search in the binary files:
if ( $EXTENSION eq "deb" ) {
- if ( extract_manpages($WORKDIR, $file, $mandir) ) {
+ if ( extract_manpages($WORKDIR, $file, $mandir) ) {
# Remove the directory, there were no manpages there
- rmdir $mandir || die ("Could not remove $mandir: $!");
- }
+ print "WARNING: No manpages found.\n";
+ if ( -e "$mandir" ) {
+ rmdir $mandir || die ("Could not remove $mandir: $!");
+ }
+ }
}
# Now we are done, cleanup
system "/bin/chmod", "u+rwX", "-R", "$WORKDIR"; # Just in case
@@ -168,15 +172,44 @@
sub extract_manpages {
my ($wdir, $package, $dstdir) = @_;
# Looks for manpages in the sources
+ my $result = 1;
+ # Temporary file for dpkg
+ my $tempfileh = new File::Temp ( Template => "TEMPLATE.XXXXXX", DIR => File::Spec->tmpdir, SUFFIX => ".suf" ) or die "Cannot create temporary file: $!" ;
+
+ my $tempfile = $tempfileh->filename;
+
# TODO: notice that this is _NOT_ secure there are multiple entry
# points for command injection, rewrite this in Perl?
- system "dpkg-deb --fsys-tarfile $package | tar -C $wdir -xf - usr/share/man ./usr/share/man usr/X11R6/man ./usr/X11R6/man 2>/dev/null";
- # If we have a directory then move all the files in it
- if ( -e "$wdir/usr/" ) {
- system "mv $wdir/* $dstdir";
- return 0;
- }
- # Return with error if there were no directories
- return 1;
-}
-
+ my $command="dpkg-deb --fsys-tarfile $package >$tempfile";
+ system "$command";
+ if ( $? != 0 ) {
+ if ($? == -1) {
+ print STDERR "failed to execute: $!\n";
+ } elsif ($? & 127) {
+ printf STDERR "child died with signal %d, %s coredump\n",
+ ($? & 127), ($? & 128) ? 'with' : 'without';
+ } else {
+ printf STDERR "child exited with value %d\n", $? >> 8;
+ }
+ die "Error running '$command'";
+ }
+ $command="tar -C $wdir -xf $tempfile usr/share/man ./usr/share/man usr/X11R6/man ./usr/X11R6/man 2>/dev/null";
+ system "$command";
+ printf STDERR "tar exited with value %d\n", $? >> 8 if $? != 0 && $? != ( 2 << 8 );
+# Note we skip exit value '2' which happens when tar does not find any file according to specification
+
+# If we have a directory then move all the files in it
+# otherwise, we will return with an error
+ if ( -e "$wdir/usr/" ) {
+ system "mv $wdir/* $dstdir" || die "Error moving directory: $?";
+ $result = 0;
+ }
+
+# Clean up temporary files
+ unlink $tempfile;
+ close $tempfileh;
+
+# And return
+ return $result;
+}
+
Reply to: