home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / bin / foomatic-ppdfile < prev    next >
Encoding:
Text File  |  2006-08-29  |  8.2 KB  |  285 lines

  1. #!/usr/bin/perl
  2. # -*- perl -*-
  3.  
  4. # Foomatic PPD file generator for manual PPD generation (via "-p",
  5. # "-d", "-A", and "-P" command line options) or for automatic
  6. # on-the-fly PPD generation by CUPS 1.2 or newer (via "cat" and "list"
  7. # command line options).
  8.  
  9. use Foomatic::Defaults;
  10. use Foomatic::DB;
  11. use Getopt::Std;
  12. use Data::Dumper;
  13. #use strict;
  14.  
  15. my $debug = 0;
  16.  
  17. # Use program name as the first part of the PPD URI for CUPS (should be 
  18. # "foomatic").
  19. $0 =~ m!/([^/]+)\s*$!;
  20. my $progname = ($1 || $0);
  21.  
  22. # Default settings for listing PPDs by cups-driverd
  23.  
  24. # List only the PPD file with the reconmmended driver for each printer
  25. # and do not show "(recommended)" in the CUPS web interface. This mode
  26. # makes CUPS setup with the web interface very easy for beginners.
  27. # This can be set by "OnlyRecommended Yes" or "OnlyRecommended No" in
  28. # /etc/cups/foomatic.conf
  29. my $onlyrecommended = 0;
  30.  
  31. help() if !@ARGV;
  32. #my ($opt_h, $opt_d, $opt_p, $opt_A, $opt_P, $opt_w);
  33. getopts("AP:d:p:hwt:");
  34. help() if $opt_h;
  35. my $drv = $opt_d;
  36. my $poid   = $opt_p;
  37. my $showall   = $opt_A;
  38. my $showmatch   = $opt_P;
  39. help() if ($#ARGV > 1) && !($poid);
  40.  
  41. if ($ARGV[0] =~ /^list$/i) {
  42.     # List all available PPD files (format for cups-driverd)
  43.     cupslistppds();
  44. } elsif ($ARGV[0] =~ /^cat$/i) {
  45.     # Generate and return the selected PPD file (cups-driverd command line)
  46.     generateppd($ARGV[1]);
  47. } elsif ($showall or $showmatch) {
  48.     # List all PPD files or files matching regexp (manual operation)
  49.     foomaticlistppds($showmatch);
  50. } elsif ($poid) {
  51.     # Generate and return the selected PPD file (manual operation)
  52.     generateppd($poid, $drv);
  53. } else {
  54.     help();
  55. }
  56.  
  57. exit(0);
  58.  
  59. sub cupslistppds {
  60.     my $db = Foomatic::DB->new();
  61.     $db->get_overview();
  62.  
  63.     # Read configuration in /etc/cups/foomatic.conf
  64.     my $conffilename;
  65.     if (my $cupsserverroot = $ENV{CUPS_SERVERROOT}) {
  66.         $conffilename = "$cupsserverroot/foomatic.conf";
  67.     } else {
  68.         $conffilename = "/etc/cups/foomatic.conf";
  69.     }
  70.     if (-r $conffilename and
  71.     open CONF, "< $conffilename") {
  72.     while (my $line = <CONF>) {
  73.         chomp $line;
  74.         if ($line =~
  75.         /^\s*OnlyRecommended\s+(Yes|On|True|1)\s*$/i) {
  76.         $onlyrecommended = 1;
  77.         } elsif ($line =~
  78.              /^\s*OnlyRecommended\s+(No|Off|False|0)\s*$/i) {
  79.         $onlyrecommended = 0;
  80.         }
  81.     }
  82.     close CONF;
  83.     }
  84.  
  85.     for my $printer (@{$db->{'overview'}}) {
  86.     my $poid = $printer->{'id'};
  87.     my $make = $printer->{'make'};
  88.     my $model = $printer->{'model'};
  89.     my $recdriver = $printer->{'driver'};
  90.     my @drivers = @{$printer->{'drivers'}};
  91.     my $id = $printer->{'ieee'};
  92.  
  93.     # No drivers => No PPDs
  94.     next if $#drivers < 0;
  95.  
  96.     # Put the reconmmended driver to the beginning of list, as CUPS
  97.     # probably will take the first PPD which matches the printer model
  98.     my @sorteddrivers;
  99.     if (Foomatic::DB::member($recdriver, @drivers)) {
  100.         # Valid entry for the recommended driver
  101.         push(@sorteddrivers, $recdriver);
  102.         if (!$onlyrecommended) {
  103.         foreach my $driver (@drivers) {
  104.             push(@sorteddrivers, $driver) if $driver ne $recdriver;
  105.         }
  106.         }
  107.     } else {
  108.         # Invalid entry for the recommended driver
  109.         next if $onlyrecommended;
  110.         undef $recdriver;
  111.         @sorteddrivers = @drivers;
  112.     }
  113.  
  114.     # Go through all the drivers and list the PPD entries
  115.     foreach my $driver (@sorteddrivers) {
  116.         # Get PPD header data from the PPD file generator
  117.         my ($ieee1284,$pnpmake,$pnpmodel,$filename,$longname,
  118.         $drivername,$nickname,$modelname) =
  119.             Foomatic::DB::getppdheaderdata($printer, $driver, 
  120.                            ($onlyrecommended ? '' :
  121.                             $printer->{'driver'}));
  122.         print "\"$progname:$longname\" en \"$make\" \"$nickname\" \"$ieee1284\"\n";
  123.     }
  124.     }
  125. }
  126.  
  127. sub foomaticlistppds {
  128.  
  129.     my ($match) = @_;
  130.  
  131.     my $db = Foomatic::DB->new();
  132.     $db->get_overview();
  133.     my @drivers = $db->get_driverlist();
  134.  
  135.     for my $printer (@{$db->{'overview'}}) {
  136.     my $pr = $printer->{'make'};
  137.     my $model = $printer->{'model'};
  138.     my $name = "$pr $model";
  139.     my $driver = ($printer->{'driver'} || "No Default Driver");
  140.     my $dlist = "";
  141.     my $dcount = 0;
  142.     if( $printer->{'drivers'} ){
  143.         $dcount = @{$printer->{'drivers'}};
  144.         for my $d (@{$printer->{'drivers'}}) {
  145.         $dlist .= "$d ";
  146.         }
  147.     }
  148.     if (not $match or "$name" =~ m{$match}o) {
  149.         print "$name Id='$printer->{'id'}' Driver='$driver'";
  150.         if ($dcount > 1){
  151.         print " CompatibleDrivers='$dlist'";
  152.         }
  153.         print "\n";
  154.     }
  155.     }
  156. }
  157.  
  158. sub generateppd {
  159.  
  160.     my ($ppduri, $driver) = @_;
  161.     my $poid;
  162.  
  163.     my $db = Foomatic::DB->new();
  164.     $db->get_overview();
  165.     my $printer;
  166.     my @drivers = $db->get_driverlist();
  167.  
  168.     if ($ppduri =~ /^$progname:(.*)\.ppd$/) {
  169.     # cups-driverd operation
  170.     # We try to split between printer name and driver name at all
  171.     # dashes in the PPD file name, as some drivers (ex. Gutenprint)
  172.     # have dashes in their names.
  173.     my $ppdname = $1;
  174.     my @poidcomponents = split(/-/, $ppdname);
  175.     my @drivercomponents = ();
  176.     while ($#poidcomponents > 1) {
  177.         unshift(@drivercomponents, pop(@poidcomponents));
  178.         $driver = join('-', @drivercomponents);
  179.         next if !Foomatic::DB::member($driver, @drivers);
  180.         $poid = join('-', @poidcomponents);
  181.         last;
  182.     }
  183.     die "ERROR: Could not determine driver name for $ppdname.ppd!\n"
  184.         if( !$poid );
  185.     } else {
  186.     # manual operation
  187.     $poid = $ppduri;
  188.     }
  189.  
  190.     # If the user supplies an old numerical printer ID, translate it to
  191.     # a new clear-text ID
  192.     $poid = Foomatic::DB::translate_printer_id($poid);
  193.  
  194.     my $lcname = lc( $poid );
  195.     my $pentry;
  196.     for $printer (@{$db->{'overview'}}) {
  197.     my $name = lc( $printer->{'id'} );
  198.     print STDERR "DEBUG2: $progname: compare '$lcname' to '$name'\n" if $debug;
  199.     if( $name eq $lcname ){
  200.         $pentry = $printer;
  201.         last;
  202.     }
  203.     }
  204.  
  205.     die "ERROR: Printer '$poid' not found!\n" if( not defined $pentry );
  206.     print STDERR "DEBUG: $progname: Found $pentry->{id}\nDEBUG2: $progname: " .
  207.     join ("\nDEBUG2: $progname: ", split(/\n/, Dumper($pentry))) .
  208.     "\n" if $debug;
  209.     
  210.     if (!$driver || ($driver =~ /(default|recommended)/i)) {
  211.     $driver = $pentry->{'driver'};
  212.     if( not defined( $driver ) ){
  213.         die "ERROR: $progname: Printer '$poid' does not have default driver!\n";
  214.     }
  215.     }
  216.     
  217.     my $found = 0;
  218.     for my $d (@{$pentry->{'drivers'}}) {
  219.     last if ($found = ($driver eq $d));
  220.     }
  221.     if ( not $found ) {
  222.     warn "ERROR: $progname: Printer '$poid' and driver '$driver' are not compatible\n";
  223.     }
  224.     $found = 0;
  225.     for my $d (@drivers) {
  226.     last if ($found = ($driver eq $d));
  227.     }
  228.     if ( not $found ) {
  229.     die "ERROR: $progname: Driver '$driver' not in database!\n";
  230.     }
  231.  
  232.     # Get all the data about this driver/printer pair
  233.     my $possible = $db->getdat($driver, $poid);
  234.     # Stop if the printer is not supported by the given driver
  235.     die "ERROR: $progname: That printer and driver combination is not possible.\n"
  236.     if (!$possible);
  237.     # Stop if the driver entry has an empty command line prototype or if there 
  238.     # is no custom PPD file
  239.     die "ERROR: $progname: There is neither a custom PPD file nor the driver database entry contains sufficient data to build a PPD file.\n"
  240.     if (!$db->{'dat'}{'cmd'}) && (!$db->{'dat'}{'ppdfile'});
  241.     
  242.     my @data;
  243.  
  244.     @data = $db->getppd($opt_w);
  245.     die "ERROR: $progname: No PPD file for printer '$poid' and driver '$driver'!\n"
  246.     if not @data;
  247.  
  248.     print @data;
  249.  
  250. }
  251.  
  252. sub help {
  253.     print <<HELP;
  254.  
  255. $progname -A
  256. $progname -P <regexpr>
  257. $progname -p <printerid> [-d <driver>] [-w]
  258. $progname list
  259. $progname cat <CUPS PPD URI> [-w]
  260. $progname -h
  261.  
  262.  -A             : show all Printer ID's and compatible drivers
  263.  -P <regexpr>   : show all Printer ID's whose names and model
  264.                   matched by the RE.  For example:
  265.                    -P HP will match all names with HP in them
  266.  -p <printerid> : Printer ID
  267.  -d <driver>    : Driver name
  268.                   If the driver is not specified then the default driver 
  269.                   for the <printerid> is used.
  270.  list           : List all possible PPDs in the format needed by the
  271.                   cups-driverd
  272.  cat <CUPS PPD URI> : Generate PPD file appropriate to the <CUPS PPD URI>.
  273.                   Available CUPS PPD URIs are listed by 
  274.                   "$progname list".
  275.  -w             : Generate PPD which is compatible with the CUPS PostScript
  276.                   driver for Windows (GUI strings are limited to 39 
  277.                   characters).
  278.  -h             : show help information
  279.  
  280.  
  281. HELP
  282.     exit 1;
  283.  
  284. }
  285.