[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: