#!/usr/bin/perl
# -*- perl -*-
use Foomatic::Defaults;
use Foomatic::DB;
use Cwd;
my ($db) = new Foomatic::DB;
use Getopt::Std;
getopts('ft:j:hd:') || help();
my $force = ($opt_f ? 1 : 0);
my $debug = 0;
# Do the whole world
sub help {
print STDERR <get_overview(1, ($filetype eq "ppd" ? 2 : 0));
# Find all printer/driver combinations
my @combos;
for my $printer (@{$db->{"overview"}}) {
my $poid = $printer->{'id'};
for my $driver (@{$printer->{'drivers'}}) {
if (!@ARGV || Foomatic::DB::member($driver, @ARGV)) {
push (@combos, "$poid,$driver\n");
}
}
}
# OK, spawn n manager processes
# create lists to process
$opt_j = 0 if( not defined $opt_j );
$opt_j += 0;
$opt_j = 1 if( not $opt_j or $opt_j < 0 );
my $n = 0;
my $rcombos = [];
my @rcombos;
for( $n = 0; $n < $opt_j; ++$n ){
$rcombos->[$n] = [];
}
$n = 0;
while( @combos ){
my $pos = int(rand(scalar(@combos)));
my $j = $n % $opt_j;
print "$n: combos " . scalar(@combos) . ", pos $pos, id $j\n" if $debug;
push( @{$rcombos->[$n % $opt_j]}, splice( @combos, $pos, 1 ) );
++$n;
}
my (@pids, $pid );
for( $n = 0; $n < $opt_j; ++$n ){
$pid = fork();
if( ! defined( $pid ) ){
warn( "cannot fork child process" );
break;
} elsif( ! $pid ){
# Child, go on immediately
@rcombos = @{$rcombos->[$n]};
last;
}
print "process $pid\n" if $debug;
}
if( $pid ){
# we wait for the processes
while( ($pid = wait()) > 0 ){ print "DONE $pid\n" if $debug };
print "ALL DONE" if $debug;
}
print "Monitor process $$\n";
# Now, the processing loop:
my $combo;
my $pcount=0;
my $fileh=spawn_child();
while($combo=pop(@rcombos)) {
print "PROCESS $n - $$, $combo" if $debug;;
print $fileh $combo;
if ($pcount++ > 25) {
close $fileh or die "\nError in child...\n";
$fileh = spawn_child();
$pcount=0;
}
}
close $fileh;
print STDERR "Done.\n";
exit (0);
# Form a combo-computing child process to handle a flock of combos
sub spawn_child {
if (open CHILD, '|-') {
return \*CHILD;
} else {
while ($line=) {
my ($printer,$driver) = split(',',$line);
chomp $driver;
# Determine file name for the output file
my $printer = Foomatic::DB::translate_printer_id($printer);
my $filename = "$destdir/$printer-$driver$suffix";
# Skip on bad file name
if ($filename =~ /^\-/) {
print STDERR "WARNING: $printer with $driver gives a bad PPD file name: $filename\n\n";
next;
}
## Skip entirely if we can
#next if (-f $filename);
print STDERR " Worker $$ ...printer $printer, driver $driver\n";
# Generate the file ...
if ($filetype eq 'xml') {
@data = $db->get_combo_data_xml($driver, $printer);
} else {
my $possible = $db->getdat($driver, $printer);
# Do not create a PPD file if the printer/driver combo
# is not possible or if the renderer command line is
# empty and no custom PPD file is available
next if ((!$possible) or
((!$db->{'dat'}{'cmd'}) and
(!$db->{'dat'}{'ppdfile'})));
@data = $db->getppd();
}
open OUTPUT, "> $filename" ||
die "Cannot write $filename!";
print OUTPUT join('', @data);
close OUTPUT;
}
# No more input!
exit (0);
}
}