home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / bin / foomatic-compiledb < prev    next >
Encoding:
Text File  |  2007-03-07  |  5.2 KB  |  219 lines

  1. #!/usr/bin/perl
  2. # -*- perl -*-
  3.  
  4. use Foomatic::Defaults;
  5. use Foomatic::DB;
  6. use Cwd;
  7.  
  8. my ($db) = new Foomatic::DB;
  9.  
  10. use Getopt::Std;
  11. getopts('ft:j:hd:') || help();
  12. my $force = ($opt_f ? 1 : 0);
  13. my $debug = 0;
  14.  
  15. # Do the whole world
  16.  
  17. sub help {
  18.     print STDERR <<EOF;
  19. compile_db [ -f ] [ -t type ] [ -d destdir] [ -j n ] [driver1] [driver2] ...
  20.  -f       force: proceed even if the destination directory exists
  21.  -t type  output file type: ppd or xml
  22.  -j n     n==number of work processes to run at the same time
  23.  -d destdir  put PPD files in this directory
  24.  driver1 driver2 ...  
  25.           only compile the database for these drivers
  26. EOF
  27.  
  28.     exit 1;
  29. }
  30.  
  31. help() if ($opt_h);
  32.  
  33. # Default file type are PPD files
  34. if (!$opt_t) {
  35.     $opt_t = "ppd";
  36. }
  37. my $destdir;
  38. if( $opt_d ){
  39.     $destdir = $destdir;
  40. }
  41.  
  42. print STDERR "\n";
  43. # Destination directory
  44. my $pwd = cwd;
  45.  
  46. if (($opt_t eq "ppd") || ($opt_t eq "cups") || ($opt_t eq "ppr")) {
  47.     # Generic PPDs
  48.     $filetype = "ppd";
  49.     $destdir = "$pwd/ppd" if not defined( $destdir );
  50.     $suffix = ".ppd";
  51.     print STDERR "Generating Foomatic PPD files ...\n";
  52. } elsif ($opt_t eq "xml") {
  53.     $filetype = "xml";
  54.     $destdir = "$pwd/combo-xml" if not defined( $destdir );
  55.     $suffix = ".xml";
  56.     print STDERR "Generating Foomatic printer/driver combo XML files ...\n";
  57. } else {
  58.     die "Unknown file type: $opt_t!\n";
  59. }
  60.  
  61. print STDERR "\nStoring files in directory $destdir.\n";
  62. mkdir $destdir, 0777 or $force or die "\nCannot make destination directory (If the directory already exists and you\nwant to proceed anyway, use the \"-f\" option)!\n";
  63.  
  64. # Compute the overview
  65. $db->get_overview();
  66.  
  67. # Which drivers should be processed?
  68. my @driverlist;
  69. if (@ARGV) {
  70.     @driverlist = grep {isdrivervalid($_)} @ARGV;
  71. } else {
  72.     @driverlist = grep {isdrivervalid($_)} $db->get_driverlist();
  73. }
  74.  
  75. # Subprocess to compute all p/d combinations
  76. my @combos;
  77. if (open COMB, '-|') {
  78.     while(<COMB>) {
  79.     push (@combos, $_);
  80.     }
  81.     close COMB;            # wait for child end
  82. } else {
  83.     my $driver;
  84.     for $driver (@driverlist) {
  85.     my $printer;
  86.     for $printer ($db->get_printers_for_driver($driver)) {
  87.         # Note this combo...
  88.         print STDOUT "$printer,$driver\n";
  89.     }
  90.     }
  91.     exit 0;            # end of subprocessing
  92. }
  93.  
  94. # OK, spawn n manager processes
  95. # create lists to process
  96. $opt_j = 0 if( not defined $opt_j );
  97. $opt_j += 0;
  98. $opt_j = 1 if( not $opt_j or $opt_j < 0 );
  99.  
  100. my $n = 0;
  101. my $rcombos = [];
  102. my @rcombos;
  103. for( $n = 0; $n < $opt_j; ++$n ){
  104.     $rcombos->[$n] = [];
  105. }
  106. $n = 0;
  107. while( @combos ){
  108.     my $pos = int(rand(scalar(@combos)));
  109.     my $j = $n % $opt_j;
  110.     print "$n: combos " . scalar(@combos) . ", pos $pos, id $j\n" if $debug;
  111.     push( @{$rcombos->[$n % $opt_j]}, splice( @combos, $pos, 1 ) );
  112.     ++$n;
  113. }
  114. my (@pids, $pid );
  115. for( $n = 0; $n < $opt_j; ++$n ){
  116.     $pid = fork();
  117.     if( ! defined( $pid ) ){
  118.     warn( "cannot fork child process" );
  119.     break;
  120.     } elsif( ! $pid ){
  121.         # Child, go on immediately
  122.     @rcombos = @{$rcombos->[$n]};
  123.         last;
  124.     }
  125.     print "process $pid\n" if $debug;
  126. }
  127. if( $pid ){
  128.     # we wait for the processes
  129.     while( ($pid = wait()) > 0 ){ print "DONE $pid\n" if $debug };
  130.     print "ALL DONE" if $debug;
  131. }
  132.  
  133. print "Monitor process $$\n";
  134.  
  135. # Now, the processing loop:
  136. my $combo;
  137. my $pcount=0;
  138. my $fileh=spawn_child();
  139. while($combo=pop(@rcombos)) {
  140.     print "PROCESS $n - $$, $combo" if $debug;;
  141.     print $fileh $combo;
  142.     if ($pcount++ > 25) {
  143.     close $fileh or die "\nError in child...\n";
  144.     $fileh = spawn_child();
  145.     $pcount=0;
  146.     }
  147. }
  148. close $fileh;
  149.  
  150. print STDERR "Done.\n";
  151.  
  152. exit (0);
  153.  
  154. # Form a combo-computing child process to handle a flock of combos
  155. sub spawn_child {
  156.     if (open CHILD, '|-') {
  157.     return \*CHILD;
  158.     } else {
  159.     while ($line=<STDIN>) {
  160.  
  161.         my ($printer,$driver) = split(',',$line);
  162.         chomp $driver;
  163.  
  164.         # Determine file name for the output file
  165.         my $printer = Foomatic::DB::translate_printer_id($printer);
  166.         my $filename = "$destdir/$printer-$driver$suffix";
  167.  
  168.         # Skip on bad file name
  169.         if ($filename =~ /^\-/) {
  170.         print STDERR "WARNING: $printer with $driver gives a bad PPD file name: $filename\n\n";
  171.         next;
  172.         }
  173.  
  174.         # Skip on non-existing printer XML file (happens if in the
  175.         # list of supported printers of a driver is a printer
  176.         # which does not exist in the Foomatic database)
  177.         next if !defined($db->get_printer($printer));
  178.  
  179.         ## Skip entirely if we can
  180.         #next if (-f $filename);
  181.         
  182.         print STDERR "  Worker $$ ...printer $printer, driver $driver\n";
  183.         
  184.         # Generate the file ...
  185.         if ($filetype eq 'xml') {
  186.         @data = $db->get_combo_data_xml($driver, $printer);
  187.         } else {
  188.         my $possible = $db->getdat($driver, $printer);
  189.         # Do not create a PPD file if the printer/driver combo
  190.         # is not possible or if the renderer command line is
  191.         # empty and no custom PPD file is available
  192.         next if ((!$possible) or 
  193.              ((!$db->{'dat'}{'cmd'}) and 
  194.               (!$db->{'dat'}{'ppdfile'})));
  195.         @data = $db->getppd();
  196.         }
  197.         open OUTPUT, "> $filename" ||
  198.         die "Cannot write $filename!";
  199.         print OUTPUT join('', @data);
  200.         close OUTPUT;
  201.     }
  202.  
  203.     # No more input!
  204.     exit (0);
  205.     }    
  206. }
  207.  
  208. sub isdrivervalid {
  209.     my ($driver) = @_;
  210.     # Check whether the driver has a valid command line
  211.     if ($filetype ne 'xml') {
  212.     my $driverentry = $db->get_driver($driver);
  213.     if ($driverentry->{'cmd'}) {return 1;}
  214.     return 0;
  215.     } else {
  216.     return 1;
  217.     }
  218. }
  219.