#!/usr/bin/perl -w # # Copyright 1999 Raphaël Hertzog # See the README file for the license. # # This script will dispatch the source packages on different CD. # It will include all the sources corresponding to the binary # packages that are included in the binary CDs. # # In general, I'll follow the same rules than list2cds ... use strict; my $deflimit = $ENV{'SRCSIZELIMIT'} || $ENV{'SIZELIMIT'} || shift || 629145600; my $limit = $ENV{'SRCSIZELIMIT1'} || $deflimit; my $nonfree = $ENV{'NONFREE'} || 0; my $extranonfree = $ENV{'EXTRANONFREE'} || 0; my $nonus = $ENV{'NONUS'} || 0; my $forcenonusoncd1 = $ENV{'FORCENONUSONCD1'} || 0; my $contrib = $ENV{'CONTRIB'} || 0; my $complete = $ENV{'COMPLETE'} || 0; my $local = $ENV{'LOCAL'} || 0; my $bdir = "$ENV{'TDIR'}/$ENV{'CODENAME'}-$ENV{'ARCH'}"; my $sdir = "$ENV{'TDIR'}/$ENV{'CODENAME'}-src"; my $verbose = $ENV{'VERBOSE'} || 0; my $mirror = $ENV{'MIRROR'}; my $localdebs = $ENV{'LOCALDEBS'} || $mirror; my $codename = $ENV{'CODENAME'}; $| = 1; open(LOG, ">$sdir/log.cds2src") || die "Can't write in $sdir/log.cds2src !\n"; sub msg { my $level= shift; if ($verbose >= $level) { print @_; } print LOG @_; } my %bin2src; my %sources; my %included; my %excluded; my @nonuslist=(); my %includesrc; # Get the information from the good Sources.gz files my @SOURCES = ("$mirror/dists/$codename/main/source/Sources.gz"); if ($contrib) { push @SOURCES, "$mirror/dists/$codename/contrib/source/Sources.gz"; } if ($nonus) { push @SOURCES, "$nonus/dists/$codename/non-US/main/source/Sources.gz"; if ($contrib) { push @SOURCES, "$nonus/dists/$codename/non-US/contrib/source/Sources.gz"; } } if ($nonfree or $extranonfree) { push @SOURCES, "$mirror/dists/$codename/non-free/source/Sources.gz"; if ($nonus) { push @SOURCES, "$nonus/dists/$codename/non-US/non-free/source/Sources.gz"; } } if ($local and -e "$localdebs/dists/$codename/local/source/Sources.gz") { push @SOURCES, "$localdebs/dists/$codename/local/source/Sources.gz"; } foreach (@SOURCES) { die "File `$_' cannot be found ..." if not -f; } my $oldrs = $/; $/ = ''; my ($re, $p, $bin, $file, $size); open (SOURCES, "zcat @SOURCES |") || die "Can't fork: $!\n"; while (defined($_ = )) { # General information about the source package next if not m/^Package: (\S+)\s*$/m; $p = $1; $included{$p} = 0; $sources{$p}{"Package"} = $p; foreach $re (qw/Binary Version Section Directory/) { (m/^$re: (.*?)\s*$/m and $sources{$p}{$re} = $1) || msg(1, "Header field '$re' missing for source '$p'\n"); } # Avoid a perl warning for sources packages without section header if (! exists $sources{$p}{"Section"}) { $sources{$p}{"Section"} = "No section"; } # Generate the list of non-free source packages to exclude if ((! $nonfree) and ($sources{$p}{"Section"} =~ /non-free/)) { $excluded{$p} = "nonfree"; } else { $excluded{$p} = 0; } # Generate the list of non-US source packages if (($sources{$p}{"Directory"} =~ /non-US/)) { push @nonuslist, $p; } # Match between source & binary packages foreach $bin (split (/,\s+/, $sources{$p}{"Binary"})) { $bin2src{$bin} = $p; } $sources{$p}{"Files"} = []; # Get the file list with the size if (not m/^Files:\s*\n/mgc) { msg(0,"ERROR: Cannot found Files field ...\n"); } while (m/\G^\s+([\da-fA-F]+)\s+(\d+)\s+(\S+)\s*\n/mgc) { $file = $3; $size = $2; $file = "$sources{$p}{'Directory'}/$file"; push @{$sources{$p}{"Files"}}, [ $file, $size ]; } if (not @{$sources{$p}{"Files"}}) { msg(0, "ERROR: Source package $p has no files ...\n"); } } $/ = $oldrs; # Get the list of excluded packages my $exclude = $ENV{'SRCEXCLUDE'} || "sorry-no-srcexclude"; if (-e $exclude) { open (EXCL, "< $exclude") || die "Can't open $exclude : $!\n"; while (defined($_=)) { chomp; if (not exists $sources{$_}) { msg(1, "INIT: Source '$_' is in srcexcluded but " . "doesn't exist. Ignored.\n"); next; } $excluded{$_} = 'user choice'; } close EXCL; } # Get the list of included packages my @list = (); my $i = 1; my $infile; while (-e "$bdir/$i.packages") { my $nonusfile = sprintf("%s/%d_NONUS.packages", $bdir, $i); if(-e "$nonusfile") { $infile = $nonusfile; } else { $infile = "$bdir/$i.packages"; } print "Using package file $infile\n"; open (LIST, "< $infile") || die "Can't open $infile ...\n"; while (defined($_ = )) { chomp; push @list, $_; } close LIST; $i++; } msg(0, "ERROR: No source packages for the CD !\n") if not @list; # Calculate what files go on which CD my (%cds); my ($cd, $cd_size, $total_size, $src) = (1, 0, 0); # Add non-US stuff to CD#1 first if we have been asked to... # "complete" means also add non-US sources that don't have binary packages... if($forcenonusoncd1) { if(!$complete) { foreach (@list) { if(not exists $bin2src{$_}) { next; } $includesrc{$bin2src{$_}} = 1; } } foreach $src (@nonuslist) { if (! ($complete or $includesrc{$src})) { msg(1, "Non-US source package $src doesn't need to be included !\n"); next; } msg(1, "Asked to add non-US source $src to source CD#1\n"); if (not exists $included{$src}) { msg(0, "ERROR: Non-US source `$src' does not exist ... (ignored)\n"); next; } if ($excluded{$src}) { msg(1, "...but not doing so - $excluded{$src}\n"); next; } next if $included{$src}; add_src ($src); } } # And then the rest foreach $p (@list) { if (not exists $bin2src{$p}) { msg(1, "WARNING: Package `$p' has no sources ... (ignored)\n"); next; } $src = $bin2src{$p}; if (not exists $included{$src}) { msg(0, "ERROR: Source `$src' does not exist ... (ignored)\n"); next; } next if $excluded{$src}; next if $included{$src}; add_src ($src); } # And now any remaining sources that don't have binary packages if ($complete) { msg(0, "Now we'll add the sources not yet included ...\n"); foreach $p (sort { ($sources{$a}{"Section"} cmp $sources{$b}{"Section"}) || ($a cmp $b) } grep { not ($included{$_} or $excluded{$_}) } keys %sources) { if ($p eq "ia32-libs") { msg(0, "Leaving ia32-libs to the end\n"); } else { add_src ($p); } } msg(0, "Now adding ia32-libs\n"); add_src("ia32-libs"); } msg(0, "CD $cd will only be filled with $cd_size bytes ...\n"); # Now generate the extra non-free CD if ($extranonfree and (! $nonfree)) { my ($p, @toinclude); # Finally accept non-free packages foreach $p (grep { $excluded{$_} eq "nonfree" } (keys %sources)) { $excluded{$p} = 0; push @toinclude, $p; } # Start a new CD $cd++; $cd_size = 0; $limit = $ENV{"SRCSIZELIMIT$cd"} || $deflimit; msg(0, "Limit for non-free source CD $cd is $limit.\n"); # Include non-free source packages foreach $p (@toinclude) { add_src ($p); } msg(0, "CD $cd will only be filled with $cd_size bytes ...\n"); } # Now write the lists down foreach (sort {$a <=> $b} keys %cds) { my $count = 0; open(CDLIST, "> $sdir/$_.sources") || die "Can't write in $sdir/$_.sources: $!\n"; foreach (@{$cds{$_}}) { print CDLIST "$_\n"; $count++; } close CDLIST; msg(0, "CD $_ will have $count files from source packages.\n"); } close LOG; ## END OF MAIN sub add_src { my $src = shift; my @files = (); $size = 0; msg(2, "+ Trying to add $src ...\n"); foreach (@{$sources{$src}{"Files"}}) { $size += $_->[1]; push @files, $_->[0]; } if ($cd_size + $size > $limit) { msg(0, "Source CD $cd filled with $cd_size bytes ...", " (limit was $limit)\n"); $cd++; $cd_size = 0; # New limit $limit = $ENV{"SRCSIZELIMIT$cd"} || $deflimit; msg(1, "Limit for CD $cd is $limit\n"); } $cd_size += $size; $total_size += $size; add_to_cd ($cd, \@files); msg(1, " size: $size\n"); $included{$src} = $cd; } sub add_to_cd { my $cd = shift; my $tab = shift; $cds{$cd} = [] if not ref $cds{$cd}; msg(1, "Adding to CD $cd : @{$tab}\n"); push (@{$cds{$cd}}, @{$tab}); }