1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
#! /usr/bin/perl
use Foomatic::Defaults;
use Foomatic::DB;
my ($db) = new Foomatic::DB;
use Getopt::Std;
getopts('ft:j:h');
my $force = ($opt_f ? 1 : 0);
# Do the whole world
if ($opt_h) {
print STDERR <<EOF;
compile_db [ -f ] [ -t type ] [ -j n ] [driver1] [driver2] ...
-f force: proceed even if the destination directory exists
-t type output file type: ppd, cups, lprng, lpd, ppr, pdq, direct,
oldcups, xml
Note: "oldcups" are the old-style CUPS-O-Matic PPDs.
-j n n==number of work processes to run at the same time
driver1 driver2 ...
only compile the database for these drivers
EOF
exit 0;
}
# Default file type are generic PPD files
if (!$opt_t) {
$opt_t = "ppd";
}
print STDERR "\n";
if (($opt_t eq "ppd") || ($opt_t eq "cups") || ($opt_t eq "ppr")) {
# Generic PPDs
$filetype = "ppd";
$destdir = "ppd";
$suffix = ".ppd";
print STDERR "Generating generic PPD files (PPD-O-Matic)...\n";
} elsif ($opt_t eq "oldcups") {
$filetype = "oldcups";
$destdir = "cups-ppd";
$suffix = "-cups.ppd";
print STDERR "Generating old CUPS PPD files (CUPS-O-Matic)...\n";
} elsif (($opt_t eq "lpd") || ($opt_t eq "lprng")) {
$filetype = "lpd";
$destdir = "lpd-descr";
$suffix = ".foo";
print STDERR "Generating LPD printer description files (LPD-O-Matic)...\n";
} elsif ($opt_t eq "pdq") {
$filetype = "pdq";
$destdir = "pdq-config";
$suffix = ".pdq";
print STDERR "Generating PDQ configuration files (PDQ-O-Matic)...\n";
} elsif ($opt_t eq "direct") {
$filetype = "direct";
$destdir = "direct-descr";
$suffix = ".foo";
print STDERR "Generating printer description files for spooler-less printing\n(Direct-O-Matic)...\n";
} elsif ($opt_t eq "xml") {
$filetype = "xml";
$destdir = "combo-xml";
$suffix = ".xml";
print STDERR "Generating Foomatic printer/driver combo XML files ...\n";
} else {
die "Unknown file type: $opt_t!\n";
}
# Destination directory
my $pwd = `pwd`;
chomp $pwd;
print STDERR "\nStoring files in directory $pwd/$destdir.\n";
mkdir $destdir or $opt_f or die "\nCannot make destination directory (If the directory already exists and you\nwant to proceed anyway, use the \"-f\" option)!\n";
# Compute the overview
$db->get_overview();
# Which drivers should be processed?
my @driverlist;
if (@ARGV) {
@driverlist = grep {isdrivervalid($_)} @ARGV;
} else {
@driverlist = grep {isdrivervalid($_)} $db->get_driverlist();
}
# Subprocess to compute all p/d combinations
my @combos;
if (open COMB, '-|') {
while(<COMB>) {
push (@combos, $_);
}
close COMB; # wait for child end
} else {
my $driver;
for $driver (@driverlist) {
my $printer;
for $printer ($db->get_printers_for_driver($driver)) {
# Note this combo...
print STDOUT "$printer,$driver\n";
}
}
exit 0; # end of subprocessing
}
# OK, spawn n manager processes
if ($opt_j > 1) {
while ($opt_j-- > 1) {
if (!fork()) {
# Child, go on immediately
last;
}
}
}
# Reorder combos randomly:
my $ct = scalar(@combos);
my @rcombos;
while ($ct) {
my $idx = int(rand($ct--));
my $next = splice(@combos, $idx, 1);
push (@rcombos, $next);
}
# Now, the processing loop:
my $combo;
my $pcount=0;
my $fileh=spawn_child();
while($combo=pop(@rcombos)) {
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=<STDIN>) {
my ($printer,$driver) = split(',',$line);
chomp $driver;
# Determine file name for the output file
my $printerentry = $db->get_printer($printer);
my $make = $printerentry->{'make'};
$make =~ s/[\s\(\)\/]/_/g;
$make =~ s/\+/plus/g;
$make =~ s/__/_/g;
my $model = $printerentry->{'model'};
$model =~ s/[\s\(\)\/]/_/g;
$model =~ s/\+/plus/g;
$model =~ s/__/_/g;
my $filename = "$destdir/$make-$model-$driver$suffix";
#my $filename = "$destdir/$printer-$driver$suffix";
# Skip entirely if we can
next if (-f $filename);
print STDERR " ...printer $printer, driver $driver\n";
# Generate the file ...
if ($filetype eq 'xml') {
@data = $db->get_combo_data_xml($driver, $printer);
} else {
$db->getdat($driver, $printer);
if ($filetype eq 'oldcups') {
@data = $db->getcupsppd();
} elsif ($filetype eq 'pdq') {
@data = $db->getpdqdata();
} elsif ($filetype eq 'lpd') {
@data = $db->getlpddata();
} elsif ($filetype eq 'ppd') {
@data = $db->getgenericppd();
} elsif ($filetype eq 'direct') {
@data = $db->getlpddata();
}
}
open OUTPUT, "> $filename" ||
die "Cannot write $filename!";
print OUTPUT join('', @data);
close OUTPUT;
}
# No more input!
exit (0);
}
}
sub isdrivervalid {
my ($driver) = @_;
# Check whether the driver has a valid command line
if ($filetype ne 'xml') {
my $driverentry = $db->get_driver($driver);
if ($driverentry->{'cmd'}) {return 1;}
return 0;
} else {
return 1;
}
}
|