summaryrefslogtreecommitdiffstats
path: root/perl-install/printer.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/printer.pm')
-rw-r--r--perl-install/printer.pm213
1 files changed, 187 insertions, 26 deletions
diff --git a/perl-install/printer.pm b/perl-install/printer.pm
index fa64ca1f8..2947e3c75 100644
--- a/perl-install/printer.pm
+++ b/perl-install/printer.pm
@@ -150,7 +150,10 @@ sub read_configured_queues($) {
}
sub read_printer_db(;$) {
- my $dbpath = $prefix . ($_[0] || $PRINTER_DB_FILE);
+
+ my $spooler = $_[0];
+
+ my $dbpath = $prefix . $PRINTER_DB_FILE;
local $_; #- use of while (<...
@@ -213,7 +216,7 @@ sub read_printer_db(;$) {
$entry->{id} = $1;
} elsif (m!^\s*<make>(.+)</make>\s*$!) {
# Printer manufacturer
- $entry->{make} = $1;
+ $entry->{make} = uc($1);
} elsif (m!^\s*<model>(.+)</model>\s*$!) {
# Printer model
$entry->{model} = $1;
@@ -233,6 +236,18 @@ sub read_printer_db(;$) {
}
}
}
+
+ #- Load CUPS driver database if CUPS is used as spooler
+ if (($spooler) && ($spooler eq "cups")) {
+ #&$install('cups-drivers') unless $::testing;
+ #my $w;
+ #if ($in) {
+ # $w = $in->wait_message(_("CUPS starting"),
+ # _("Reading CUPS drivers database..."));
+ #}
+ poll_ppd_base();
+ }
+
@entries_db_short = sort keys %printer::thedb;
#%descr_to_db = map { $printer::thedb{$_}{DESCR}, $_ } @entries_db_short;
#%descr_to_help = map { $printer::thedb{$_}{DESCR}, $printer::thedb{$_}{ABOUT} } @entries_db_short;
@@ -258,6 +273,93 @@ sub read_foomatic_options ($) {
return $COMBODATA->{'args'};
}
+sub read_cups_options ($) {
+ my ($queue_or_file) = @_;
+ # Generate the option data from a CUPS PPD file/a CUPS queue
+ # Use the same Perl data structure as Foomatic uses to be able to
+ # reuse the dialog
+ local *F;
+ if ($queue_or_file =~ /.ppd.gz$/) { # compressed PPD file
+ open F, ($::testing ? "$prefix" : "chroot $prefix/ ") .
+ "gunzip -cd $queue_or_file | lphelp - |" ||
+ die "Could not run lphelp";
+ } else { # PPD file not compressed or queue
+ open F, ($::testing ? "$prefix" : "chroot $prefix/ ") .
+ "lphelp $queue_or_file |" ||
+ die "Could not run lphelp";
+ }
+ my $i;
+ my $j;
+ my @args = ();
+ my $line;
+ my $inoption = 0;
+ my $inchoices = 0;
+# my $innumerical = 0;
+ while ($line = <F>) {
+ chomp $line;
+ if ($inoption) {
+ if ($inchoices) {
+ if ($line =~ /^\s*(\S+)\s+(\S.*)$/) {
+ push(@{$args[$i]{vals}}, {});
+ $j = $#{$args[$i]{vals}};
+ $args[$i]{vals}[$j]{value} = $1;
+ my $comment = $2;
+ # Did we find the default setting?
+ if ($comment =~ /default\)\s*$/) {
+ $args[$i]{default} = $args[$i]{vals}[$j]{value};
+ $comment =~ s/,\s*default\)\s*$//;
+ } else {
+ $comment =~ s/\)\s*$//;
+ }
+ # Remove opening paranthese
+ $comment =~ s/^\(//;
+ # Remove page size info
+ $comment =~ s/,\s*size:\s*[0-9\.]+x[0-9\.]+in$//;
+ $args[$i]{vals}[$j]{comment} = $comment;
+ } elsif (($line =~ /^\s*$/) && ($#{$args[$i]{vals}} > -1)) {
+ $inchoices = 0;
+ $inoption = 0;
+ }
+# } elsif ($innumerical == 1) {
+# if ($line =~ /^\s*The default value is ([0-9\.]+)\s*$/) {
+# $args[$i]{default} = $1;
+# $innumerical = 0;
+# $inoption = 0;
+# }
+ } else {
+ if ($line =~ /^\s*<choice>/) {
+ $inchoices = 1;
+# } elsif ($line =~ /^\s*<value> must be a(.*) number in the range ([0-9\.]+)\.\.([0-9\.]+)\s*$/) {
+# delete($args[$i]{vals});
+# $args[$i]{min} = $2;
+# $args[$i]{max} = $3;
+# my $type = $1;
+# if ($type =~ /integer/) {
+# $args[$i]{type} = 'int';
+# } else {
+# $args[$i]{type} = 'float';
+# }
+# $innumerical = 1;
+ }
+ }
+ } else {
+ if ($line =~ /^\s*([^\s:][^:]*):\s+-o\s+([^\s=]+)=<choice>\s*$/) {
+# if ($line =~ /^\s*([^\s:][^:]*):\s+-o\s+([^\s=]+)=<.*>\s*$/) {
+ $inoption = 1;
+ push(@args, {});
+ $i = $#args;
+ $args[$i]{comment} = $1;
+ $args[$i]{name} = $2;
+ $args[$i]{type} = 'enum';
+ @{$args[$i]{vals}} = ();
+ }
+ }
+ }
+ close F;
+ # Return the arguments field
+ return \@args;
+}
+
#------------------------------------------------------------------------------
sub read_cupsd_conf {
my @cupsd_conf;
@@ -297,7 +399,7 @@ sub read_printers_conf {
while (<PRINTERS>) {
chomp;
/^\s*#/ and next;
- if (/^\s*<(?:DefaultPrinter|Printer)\s+([^>]*)>/) { $current = { mode => 'CUPS', QUEUE => $1, } }
+ if (/^\s*<(?:DefaultPrinter|Printer)\s+([^>]*)>/) { $current = { mode => 'cups', QUEUE => $1, } }
elsif (/\s*<\/Printer>/) { $current->{QUEUE} && $current->{DeviceURI} or next; #- minimal check of synthax.
add2hash($printer->{configured}{$current->{QUEUE}} ||= {}, $current); $current = undef }
elsif (/\s*(\S*)\s+(.*)/) { $current->{$1} = $2 }
@@ -305,7 +407,7 @@ sub read_printers_conf {
close PRINTERS;
#- assume this printing system.
- $printer->{SPOOLER} ||= 'CUPS';
+ $printer->{SPOOLER} ||= 'cups';
}
sub get_direct_uri {
@@ -325,7 +427,7 @@ sub get_descr_from_ppd {
my %ppd;
#- if there is no ppd, this means this is the PostScript generic filter.
- local *F; open F, "$prefix/etc/cups/ppd/$printer->{QUEUE}.ppd" or return "POSTSCRIPT|Generic PostScript printer (en)";
+ local *F; open F, "$prefix/etc/cups/ppd/$printer->{OLD_QUEUE}.ppd" or return "OTHERS|Generic PostScript printer|PostScript (en)";
local $_;
while (<F>) {
/^\*([^\s:]*)\s*:\s*\"([^\"]*)\"/ and do { $ppd{$1} = $2; next };
@@ -333,35 +435,91 @@ sub get_descr_from_ppd {
}
close F;
- $ppd{Manufacturer} . '|' . ($ppd{NickName} || $ppd{ShortNickName} || $ppd{ModelName}) .
- ($ppd{LanguageVersion} && (" (" . lc(substr($ppd{LanguageVersion}, 0, 2)) . ")"));
+ my $descr = ($ppd{NickName} || $ppd{ShortNickName} || $ppd{ModelName});
+ # Apply the beautifying rules of poll_ppd_base
+ if ($descr =~ /Foomatic \+ Postscript/) {
+ $descr =~ s/Foomatic \+ Postscript/PostScript/;
+ } elsif ($descr =~ /Foomatic/) {
+ $descr =~ s/Foomatic/GhostScript/;
+ } elsif ($descr =~ /CUPS\+GIMP-print/) {
+ $descr =~ s/CUPS\+GIMP-print/CUPS \+ GIMP-Print/;
+ } elsif ($descr =~ /Series CUPS/) {
+ $descr =~ s/Series CUPS/Series, CUPS/;
+ } elsif (!(uc($descr) =~ /POSTSCRIPT/)) {
+ $descr .= ", PostScript";
+ }
+
+ # Split the $descr into model and driver
+ my $model;
+ my $driver;
+ if ($descr =~ /^([^,]+), (.*)$/) {
+ $model = $1;
+ $driver = $2;
+ } else {
+ # Some PPDs do not have the ", <driver>" part.
+ $model = $descr;
+ $driver = "PostScript";
+ }
+ my $make = $ppd{Manufacturer};
+ my $lang = $ppd{LanguageVersion};
+
+ # Remove manufacturer's name from the beginning of the model name
+ if (($make) && ($model =~ /^$make[\s\-]+([^\s\-].*)$/)) {
+ $model = $1;
+ }
+
+ # Put out the resulting description string
+ uc($make) . '|' . $model . '|' . $driver .
+ ($lang && (" (" . lc(substr($lang, 0, 2)) . ")"));
}
sub poll_ppd_base {
+
#- before trying to poll the ppd database available to cups, we have to make sure
#- the file /etc/cups/ppds.dat is no more modified.
#- if cups continue to modify it (because it reads the ppd files available), the
#- poll_ppd_base program simply cores :-)
run_program::rooted($prefix, "ifup lo"); #- else cups will not be happy!
run_program::rooted($prefix, "/etc/rc.d/init.d/cups start");
-
+ my $driversthere = scalar(keys %thedb);
foreach (1..60) {
local *PPDS; open PPDS, ($::testing ? "$prefix" : "chroot $prefix/ ") . "/usr/bin/poll_ppd_base -a |";
local $_;
while (<PPDS>) {
chomp;
my ($ppd, $mf, $descr, $lang) = split /\|/;
- $ppd && $mf && $descr and $descr_to_ppd{"$mf|$descr" . ($lang && " ($lang)")} = $ppd;
+ my ($model, $driver);
+ if ($descr) {
+ if ($descr =~ /^([^,]+), (.*)$/) {
+ $model = $1;
+ $driver = $2;
+ } else {
+ # Some PPDs do not have the ", <driver>" part.
+ $model = $descr;
+ $driver = "PostScript";
+ }
+ }
+ # Rename Canon "BJC XXXX" models into "BJC-XXXX" so that the models
+ # do not appear twice
+ if ($mf eq "CANON") {
+ $model =~ s/BJC\s+/BJC-/;
+ }
+ $ppd && $mf && $descr and do {
+ my $key = "$mf|$model|$driver" . ($lang && " ($lang)");
+ $thedb{$key}{ppd} = $ppd;
+ $thedb{$key}{driver} = $driver;
+ $thedb{$key}{make} = $mf;
+ $thedb{$key}{model} = $model;
+ }
}
close PPDS;
- scalar(keys %descr_to_ppd) > 5 and last;
- sleep 1; #- we have to try again running the program, wait here a little before.
+ scalar(keys %thedb) - $driversthere > 5 and last;
+ #- we have to try again running the program, wait here a little before.
+ sleep 1;
}
- scalar(keys %descr_to_ppd) > 5 or die "unable to connect to cups server";
+ #scalar(keys %descr_to_ppd) > 5 or die "unable to connect to cups server";
- #- assume a default printer not using any ppd at all.
- $descr_to_ppd{"No driver (raw queue)"} = '';
}
@@ -385,18 +543,21 @@ sub configure_queue($) {
"-L", $printer->{currentqueue}{'loc'},
@{$printer->{OPTIONS}}
) or die "foomatic-configure failed";
- } elsif (0) {
- #- #### For later CUPS+PPD support
- #- at this level, we are using lpadmin to create a local printer (only local
- #- printer are supported with printerdrake).
+ } elsif ($printer->{currentqueue}{ppd}) {
+ #- If the chosen driver is a PPD file from /usr/share/cups/model,
+ #- we use lpadmin to set up the queue
run_program::rooted($prefix, "lpadmin",
- "-p", $printer->{QUEUE},
- $printer->{State} eq 'Idle' && $printer->{Accepting} eq 'Yes' ? ("-E") : (),
- "-v", $printer->{DeviceURI},
- $printer->{cupsPPD} ? ("-m", $printer->{cupsPPD}) : (),
- $printer->{Info} ? ("-D", $printer->{Info}) : (),
- $printer->{Location} ? ("-L", $printer->{Location}) : (),
- if_($printer->{CUPSOPTIONS}, $printer->{CUPSOPTIONS}), #- use it if available, only for auto_install
+ "-p", $printer->{currentqueue}{'queue'},
+# $printer->{State} eq 'Idle' &&
+# $printer->{Accepting} eq 'Yes' ? ("-E") : (),
+ "-E",
+ "-v", $printer->{currentqueue}{'connect'},
+ "-m", $printer->{currentqueue}{'ppd'},
+ $printer->{currentqueue}{'desc'} ?
+ ("-D", $printer->{currentqueue}{'desc'}) : (),
+ $printer->{currentqueue}{'loc'} ?
+ ("-L", $printer->{currentqueue}{'loc'}) : (),
+ @{$printer->{OPTIONS}}
) or die "lpadmin failed";
}
@@ -428,7 +589,7 @@ sub restart_queue($) {
# Restart the daemon(s)
for ($printer->{SPOOLER}) {
- /CUPS/ && do {
+ /cups/ && do {
#- restart cups.
run_program::rooted($prefix, "/etc/rc.d/init.d/cups start"); sleep 1;
last };