diff options
Diffstat (limited to 'perl-install/printer/main.pm')
| -rw-r--r-- | perl-install/printer/main.pm | 504 |
1 files changed, 281 insertions, 223 deletions
diff --git a/perl-install/printer/main.pm b/perl-install/printer/main.pm index fdfbdf317..102d42100 100644 --- a/perl-install/printer/main.pm +++ b/perl-install/printer/main.pm @@ -9,9 +9,7 @@ use run_program; use printer::data; use printer::services; use printer::default; -use printer::gimp; use printer::cups; -use printer::office; use printer::detect; use handle_configs; use services; @@ -57,9 +55,9 @@ sub spooler() { # PDQ is not officially supported any more since version 9.1, so # show it only in the spooler menu when it was manually installed. - return map { $spoolers{$_}{long_name} } qw(cups), + return map { $spoolers{$_}{long_name} } ('cups', 'rcups' , if_(files_exist(qw(/usr/bin/pdq)), 'pdq'), - if_(files_exist(qw(/usr/lib/filters/lpf /usr/sbin/lpd)), 'lprng'); + if_(files_exist(qw(/usr/lib/filters/lpf /usr/sbin/lpd)), 'lprng')); } sub printer_type($) { @@ -69,14 +67,15 @@ sub printer_type($) { /lpd/ and return @printer_type_inv{qw(LOCAL LPD SOCKET SMB NCP), if_($printer->{expert}, qw(POSTPIPE URI))}; /lprng/ and return @printer_type_inv{qw(LOCAL LPD SOCKET SMB NCP), if_($printer->{expert}, qw(POSTPIPE URI))}; /pdq/ and return @printer_type_inv{qw(LOCAL LPD SOCKET), if_($printer->{expert}, qw(URI))}; + /rcups/ and return (); } } sub SIGHUP_daemon { my ($service) = @_; if ($service eq "cupsd") { $service = "cups" }; - # PDQ has no daemon, exit. - if ($service eq "pdq") { return 1 }; + # PDQ and remote CUPS have no daemons, exit. + if (($service eq "pdq") || ($service eq "rcups")) { return 1 }; # CUPS needs auto-correction for its configuration run_program::rooted($::prefix, "/usr/sbin/correctcupsconfig") if $service eq "cups"; # Name of the daemon @@ -126,18 +125,17 @@ sub assure_device_is_available_for_cups { } my $maxattempts = 3; for ($i = 0; $i < $maxattempts; $i++) { - local *F; - open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . - '/bin/sh -c "export LC_ALL=C; /usr/sbin/lpinfo -v" |' or + open(my $F, ($::testing ? $::prefix : "chroot $::prefix/ ") . + '/bin/sh -c "export LC_ALL=C; /usr/sbin/lpinfo -v" |') or die 'Could not run "lpinfo"!'; - while (my $line = <F>) { + while (my $line = <$F>) { if ($line =~ /$sdevice/) { # Found a line containing the device # name, so CUPS knows it. - close F; + close $F; return 1; } } - close F; + close $F; $result = printer::services::restart("cups"); } return $result; @@ -151,15 +149,14 @@ sub spooler_in_security_level { $sp = $spooler eq "lpr" || $spooler eq "lprng" ? "lpd" : $spooler; my $file = "$::prefix/etc/security/msec/server.$level"; if (-f $file) { - local *F; - open F, "< $file" or return 0; - while (my $line = <F>) { + open(my $F, "< $file") or return 0; + while (my $line = <$F>) { if ($line =~ /^\s*$sp\s*$/) { - close F; + close $F; return 1; } } - close F; + close $F; } return 0; } @@ -223,24 +220,26 @@ sub read_configured_queues($) { $printer->{SPOOLER} ||= printer::default::get_spooler(); if (!$printer->{SPOOLER}) { #- Find the first spooler where there are queues - foreach my $spooler (qw(cups pdq lprng lpd)) { + foreach my $spooler (qw(rcups cups pdq lprng lpd)) { #- Is the spooler's daemon running? my $service = $spooler; if ($service eq "lprng") { $service = "lpd"; } - if ($service ne "pdq") { + if (($service ne "pdq") && ($service ne "rcups")) { next unless services::is_service_running($service); # daemon is running, spooler found $printer->{SPOOLER} = $spooler; } - #- poll queue info - local *F; - open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . - "foomatic-configure -P -q -s $spooler |" or - die "Could not run foomatic-configure"; - eval join('', <F>); - close F; + #- poll queue info + if ($service ne "rcups") { + open(my $F, ($::testing ? + $::prefix : "chroot $::prefix/ ") . + "foomatic-configure -P -q -s $spooler |") or + die "Could not run foomatic-configure"; + eval join('', <$F>); + close $F; + } if ($service eq "pdq") { #- Have we found queues? PDQ has no damon, so we consider #- it in use when there are defined printer queues @@ -248,6 +247,17 @@ sub read_configured_queues($) { $printer->{SPOOLER} = $spooler; last; } + } elsif ($service eq "rcups") { + #- In daemon-less CUPS mode there are no local queues, + #- we can only recognize it by a server entry in + #- /etc/cups/client.conf + my ($daemonless_cups, $remote_cups_server) = + printer::main::read_client_conf(); + if ($daemonless_cups) { + $printer->{SPOOLER} = $spooler; + $printer->{remote_cups_server} = $remote_cups_server; + last; + } } else { #- For other spoolers we have already found a running #- daemon when we have arrived here @@ -255,13 +265,18 @@ sub read_configured_queues($) { } } } else { - #- Poll the queues of the current default spooler - local *F; - open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . - "foomatic-configure -P -q -s $printer->{SPOOLER} -r |" or - die "Could not run foomatic-configure"; - eval join('', <F>); - close F; + if ($printer->{SPOOLER} ne "rcups") { + #- Poll the queues of the current default spooler + open(my $F, ($::testing ? $::prefix : "chroot $::prefix/ ") . + "foomatic-configure -P -q -s $printer->{SPOOLER} -r |") or + die "Could not run foomatic-configure"; + eval join('', <$F>); + close $F; + } else { + my ($_daemonless_cups, $remote_cups_server) = + printer::main::read_client_conf(); + $printer->{remote_cups_server} = $remote_cups_server; + } } $printer->{configured} = {}; my $i; @@ -286,14 +301,13 @@ sub read_configured_queues($) { } # Read out which PPD file was originally used to set up this # queue - local *F; - if (open F, "< $::prefix/etc/cups/ppd/$QUEUES[$i]{queuedata}{queue}.ppd") { - while (my $line = <F>) { + if (open(my $F, "< $::prefix/etc/cups/ppd/$QUEUES[$i]{queuedata}{queue}.ppd")) { + while (my $line = <$F>) { if ($line =~ /^\*%MDKMODELCHOICE:(.+)$/) { $printer->{configured}{$QUEUES[$i]{queuedata}{queue}}{queuedata}{ppd} = $1; } } - close F; + close $F; } # Mark that we have a CUPS queue but do not know the name # the PPD file in /usr/share/cups/model @@ -357,21 +371,27 @@ sub make_menuentry { $connection = N(", multi-function device"); } } elsif ($connect =~ m!^file:(.+)$!) { - $connection = N(", printing to %s", $1); + my $file = $1; + $connection = N(", printing to %s", $file); } elsif ($connect =~ m!^lpd://([^/]+)/([^/]+)/?$!) { - $connection = N(" on LPD server \"%s\", printer \"%s\"", $1, $2); + my ($server, $printer) = ($1, $2); + $connection = N(" on LPD server \"%s\", printer \"%s\"", $server, $printer); } elsif ($connect =~ m!^socket://([^/:]+):([^/:]+)/?$!) { - $connection = N(", TCP/IP host \"%s\", port %s", $1, $2); + my ($host, $port) = ($1, $2); + $connection = N(", TCP/IP host \"%s\", port %s", $host, $port); } elsif ($connect =~ m!^smb://([^/\@]+)/([^/\@]+)/?$! || $connect =~ m!^smb://.*/([^/\@]+)/([^/\@]+)/?$! || $connect =~ m!^smb://.*\@([^/\@]+)/([^/\@]+)/?$!) { - $connection = N(" on SMB/Windows server \"%s\", share \"%s\"", $1, $2); + my ($server, $share) = ($1, $2); + $connection = N(" on SMB/Windows server \"%s\", share \"%s\"", $server, $share); } elsif ($connect =~ m!^ncp://([^/\@]+)/([^/\@]+)/?$! || $connect =~ m!^ncp://.*/([^/\@]+)/([^/\@]+)/?$! || $connect =~ m!^ncp://.*\@([^/\@]+)/([^/\@]+)/?$!) { - $connection = N(" on Novell server \"%s\", printer \"%s\"", $1, $2); + my ($server, $printer) = ($1, $2); + $connection = N(" on Novell server \"%s\", printer \"%s\"", $server, $printer); } elsif ($connect =~ m!^postpipe:(.+)$!) { - $connection = N(", using command %s", $1); + my $command = $1; + $connection = N(", using command %s", $command); } else { $connection = ($printer->{expert} ? ", URI: $connect" : ""); } @@ -408,21 +428,27 @@ sub connectionstr { $connection = N("Multi-function device"); } } elsif ($connect =~ m!^file:(.+)$!) { - $connection = N("Prints into %s", $1); + my $file = $1; + $connection = N("Prints into %s", $file); } elsif ($connect =~ m!^lpd://([^/]+)/([^/]+)/?$!) { - $connection = N("LPD server \"%s\", printer \"%s\"", $1, $2); + my ($server, $port) = ($1, $2); + $connection = N("LPD server \"%s\", printer \"%s\"", $server, $port); } elsif ($connect =~ m!^socket://([^/:]+):([^/:]+)/?$!) { - $connection = N("TCP/IP host \"%s\", port %s", $1, $2); + my ($host, $port) = ($1, $2); + $connection = N("TCP/IP host \"%s\", port %s", $host, $port); } elsif ($connect =~ m!^smb://([^/\@]+)/([^/\@]+)/?$! || $connect =~ m!^smb://.*/([^/\@]+)/([^/\@]+)/?$! || $connect =~ m!^smb://.*\@([^/\@]+)/([^/\@]+)/?$!) { - $connection = N("SMB/Windows server \"%s\", share \"%s\"", $1, $2); + my ($server, $share) = ($1, $2); + $connection = N("SMB/Windows server \"%s\", share \"%s\"", $server, $share); } elsif ($connect =~ m!^ncp://([^/\@]+)/([^/\@]+)/?$! || $connect =~ m!^ncp://.*/([^/\@]+)/([^/\@]+)/?$! || $connect =~ m!^ncp://.*\@([^/\@]+)/([^/\@]+)/?$!) { - $connection = N("Novell server \"%s\", printer \"%s\"", $1, $2); + my ($server, $share) = ($1, $2); + $connection = N("Novell server \"%s\", printer \"%s\"", $server, $share); } elsif ($connect =~ m!^postpipe:(.+)$!) { - $connection = N("Uses command %s", $1); + my $command = $1; + $connection = N("Uses command %s", $command); } else { $connection = N("URI: %s", $connect); } @@ -433,11 +459,14 @@ sub read_printer_db { my ($printer, $spooler) = @_; - local *DBPATH; #- don't have to do close ... and don't modify globals at least + # No local queues available in daemon-less CUPS mode + return 1 if $spooler eq "rcups"; + + my $DBPATH; #- don't have to do close ... and don't modify globals at least # Generate the Foomatic printer/driver overview, read it from the # appropriate file when it is already generated - open DBPATH, ($::testing ? $::prefix : "chroot $::prefix/ ") . #-# - "foomatic-configure -O -q |" or + open($DBPATH, ($::testing ? $::prefix : "chroot $::prefix/ ") . #-# + "foomatic-configure -O -q |") or die "Could not run foomatic-configure"; my $entry = {}; @@ -446,7 +475,7 @@ sub read_printer_db { my $inautodetect = 0; my $autodetecttype = ""; local $_; - while (<DBPATH>) { + while (<$DBPATH>) { chomp; if ($inentry) { # We are inside a printer entry @@ -566,7 +595,7 @@ sub read_printer_db { } } } - close DBPATH; + close $DBPATH; # Add raw queue $entry->{ENTRY} = N("Raw printer (No driver)"); @@ -592,18 +621,17 @@ sub read_foomatic_options ($) { my ($printer) = @_; # Generate the option data for the chosen printer/driver combo my $COMBODATA; - local *F; - open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . + open(my $F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "foomatic-configure -P -q -p $printer->{currentqueue}{printer}" . " -d $printer->{currentqueue}{driver}" . ($printer->{OLD_QUEUE} ? " -s $printer->{SPOOLER} -n $printer->{OLD_QUEUE}" : "") . ($printer->{SPECIAL_OPTIONS} ? " $printer->{SPECIAL_OPTIONS}" : "") - . " |" or + . " |") or die "Could not run foomatic-configure"; - eval join('', (<F>)); - close F; + eval join('', (<$F>)); + close $F; # Return the arguments field return $COMBODATA->{args}; } @@ -612,18 +640,17 @@ sub read_ppd_options ($) { my ($printer) = @_; # Generate the option data for a given PPD file my $COMBODATA; - local *F; - open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . + open(my $F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "foomatic-configure -P -q" . " --ppd /usr/share/cups/model/$printer->{currentqueue}{ppd}" . ($printer->{OLD_QUEUE} ? " -s $printer->{SPOOLER} -n $printer->{OLD_QUEUE}" : "") . ($printer->{SPECIAL_OPTIONS} ? " $printer->{SPECIAL_OPTIONS}" : "") - . " |" or + . " |") or die "Could not run foomatic-configure"; - eval join('', (<F>)); - close F; + eval join('', (<$F>)); + close $F; # Return the arguments field return $COMBODATA->{args}; } @@ -631,7 +658,7 @@ sub read_ppd_options ($) { my %sysconfig = getVarsFromSh("$::prefix/etc/sysconfig/printing"); sub set_cups_special_options { - my ($queue) = $_[0]; + my ($queue) = @_; # Set some special CUPS options my @lpoptions = chomp_(cat_("$::prefix/etc/cups/lpoptions")); # If nothing is already configured, set text file borders of half an inch @@ -675,6 +702,10 @@ sub get_usermode() { $sysconfig{USER_MODE} eq 'expert' ? 1 : 0 } sub set_jap_textmode { my $textmode = ($_[0] ? 'cjk' : ''); + # Do not write mime.convs if the file does not exist, as then + # CUPS is not installed and the created mime.convs will be broken. + # When installing CUPS later it will not work. + return 1 if (! -r "$::prefix/etc/cups/mime.convs"); substInFile { s!^(\s*text/plain\s+\S+\s+\d+\s+)\S+(\s*$)!$1${textmode}texttops$2! } "$::prefix/etc/cups/mime.convs"; @@ -692,15 +723,45 @@ sub get_jap_textmode() { # Handling of /etc/cups/cupsd.conf sub read_cupsd_conf() { - cat_("$::prefix/etc/cups/cupsd.conf"); + # If /etc/cups/cupsd.conf a default cupsd.conf will be put out to avoid + # writing of a broken cupsd.conf file when we write it back later. + my @cupsd_conf = cat_("$::prefix/etc/cups/cupsd.conf"); + if (!@cupsd_conf) { + @cupsd_conf = map { /\n$/s or "$_\n" } split('\n', +'LogLevel info +TempDir /var/spool/cups/tmp +Port 631 +Browsing On +BrowseAddress @LOCAL +BrowseDeny All +BrowseAllow 127.0.0.1 +BrowseAllow @LOCAL +BrowseOrder deny,allow +<Location /> +Order Deny,Allow +Deny From All +Allow From 127.0.0.1 +Allow From @LOCAL +</Location> +<Location /admin> +AuthType Basic +AuthClass System +Order Deny,Allow +Deny From All +Allow From 127.0.0.1 +</Location> +'); + } + return @cupsd_conf; } + sub write_cupsd_conf { my (@cupsd_conf) = @_; - + # Do not write cupsd.conf if the file does not exist, as then + # CUPS is not installed and the created cupsd.conf will be broken. + # When installing CUPS later it will not start. + return 1 if (! -r "$::prefix/etc/cups/cupsd.conf"); output("$::prefix/etc/cups/cupsd.conf", @cupsd_conf); - - #- restart cups after updating configuration. - printer::services::restart("cups"); } sub read_location { @@ -719,7 +780,7 @@ sub read_location { my $location_end = -1; # Go through all the lines, bail out when start and end line found for (my $i = 0; - $i <= $#{$cupsd_conf_ptr} and $location_end == -1; + $i <= $#{$cupsd_conf_ptr} && $location_end == -1; $i++) { if ($cupsd_conf_ptr->[$i] =~ m!^\s*<\s*Location\s+$path\s*>!) { # Start line of block @@ -740,7 +801,7 @@ sub read_location { # "undef" @result = undef; } - return (@result); + return @result; } sub rip_location { @@ -762,7 +823,7 @@ sub rip_location { if (any { m!^\s*<Location\s+$path\s*>! } @$cupsd_conf_ptr) { # Go through all the lines, bail out when start and end line found for (my $i = 0; - $i <= $#{$cupsd_conf_ptr} and $location_end == -1; + $i <= $#{$cupsd_conf_ptr} && $location_end == -1; $i++) { if ($cupsd_conf_ptr->[$i] =~ m!^\s*<\s*Location\s+$path\s*>!) { # Start line of block @@ -785,7 +846,7 @@ sub rip_location { @location = ("<Location $path>\n", "</Location>\n"); } - return ($location_start, @location); + return $location_start, @location; } sub insert_location { @@ -1069,7 +1130,7 @@ sub clientnetworks { $haveallowedhostwithoutbrowseallow || $havebrowseallowwithoutallowedhost); - return ($configunsupported, @sharehosts); + return $configunsupported, @sharehosts; } sub makesharehostlist { @@ -1359,6 +1420,35 @@ sub clean_cups_config { } #---------------------------------------------------------------------- +# Handling of /etc/cups/client.conf + +sub read_client_conf() { + return (0, undef) if (! -r "$::prefix/etc/cups/client.conf"); + my @client_conf = cat_("$::prefix/etc/cups/client.conf"); + my @servers = handle_configs::read_directives(\@client_conf, + "ServerName"); + return (@servers > 0, + $servers[0]); # If there is more than one entry in client.conf, + # the first one counts. +} + +sub write_client_conf { + my ($daemonless_cups, $remote_cups_server) = @_; + # Create the directory for client.conf if needed + (-d "$::prefix/etc/cups/" ) || mkdir("$::prefix/etc/cups/") || return 1; + my (@client_conf) = cat_("$::prefix/etc/cups/client.conf"); + if ($daemonless_cups) { + handle_configs::set_directive(\@client_conf, + "ServerName $remote_cups_server"); + } else { + handle_configs::comment_directive(\@client_conf, "ServerName"); + } + output("$::prefix/etc/cups/client.conf", @client_conf); +} + + + +#---------------------------------------------------------------------- sub read_printers_conf { my ($printer) = @_; my $current; @@ -1370,9 +1460,9 @@ sub read_printers_conf { #- Location > Location Text #- State > Idle|Stopped #- Accepting > Yes|No - local *PRINTERS; open PRINTERS, "$::prefix/etc/cups/printers.conf" or return; + open(my $PRINTERS, "$::prefix/etc/cups/printers.conf") or return; local $_; - while (<PRINTERS>) { + while (<$PRINTERS>) { chomp; /^\s*#/ and next; if (/^\s*<(?:DefaultPrinter|Printer)\s+([^>]*)>/) { $current = { mode => 'cups', QUEUE => $1, } } @@ -1380,7 +1470,7 @@ sub read_printers_conf { add2hash($printer->{configured}{$current->{QUEUE}} ||= {}, $current); $current = undef } elsif (/\s*(\S*)\s+(.*)/) { $current->{$1} = $2 } } - close PRINTERS; + close $PRINTERS; #- assume this printing system. $printer->{SPOOLER} ||= 'cups'; @@ -1389,12 +1479,12 @@ sub read_printers_conf { sub get_direct_uri() { #- get the local printer to access via a Device URI. my @direct_uri; - local *F; open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "/usr/sbin/lpinfo -v |"; + open(my $F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "/usr/sbin/lpinfo -v |"); local $_; - while (<F>) { + while (<$F>) { /^(direct|usb|serial)\s+(\S*)/ and push @direct_uri, $2; } - close F; + close $F; @direct_uri; } @@ -1414,7 +1504,7 @@ sub installppd { mkdir_p("$::prefix/usr/share/cups/model/printerdrake"); # "cp_f()" is broken, it hangs infinitely # cp_f($ppdfile, "$::prefix/usr/share/cups/model/printerdrake"); - run_program::rooted($::prefix, "cp", "-f", "$ppdfile", + run_program::rooted($::prefix, "cp", "-f", $ppdfile, "$::prefix/usr/share/cups/model/printerdrake"); $ppdfile =~ s!^(.*)(/[^/]+)$!/usr/share/cups/model/printerdrake$2!; chmod 0644, "$::prefix$ppdfile"; @@ -1463,8 +1553,8 @@ sub ppd_entry_str { $descr =~ s/Foomatic \+ Postscript/PostScript/; } elsif ($descr =~ /Foomatic/i) { $descr =~ s/Foomatic/GhostScript/i; - } elsif ($descr =~ /CUPS\+GIMP-print/i) { - $descr =~ s/CUPS\+GIMP-print/CUPS + GIMP-Print/i; + } elsif ($descr =~ /CUPS\+Gimp-Print/i) { + $descr =~ s/CUPS\+Gimp-Print/CUPS + Gimp-Print/i; } elsif ($descr =~ /Series CUPS/i) { $descr =~ s/Series CUPS/Series, CUPS/i; } elsif ($descr !~ /(PostScript|GhostScript|CUPS|Foomatic)/i) { @@ -1520,7 +1610,7 @@ sub ppd_entry_str { $model =~ s/BJC\s+/BJC-/; } # New MF devices from Epson have mis-spelled name in PPD files for - # native CUPS drivers of GIMP-Print + # native CUPS drivers of Gimp-Print if ($mf eq "EPSON") { $model =~ s/Stylus CX\-/Stylus CX/; } @@ -1558,9 +1648,9 @@ sub get_descr_from_ppdfile { local $_; foreach (catMaybeCompressed("$::prefix$ppdfile")) { # "OTHERS|Generic PostScript printer|PostScript (en)"; - /^\*([^\s:]*)\s*:\s*\"([^\"]*)\"/ and + /^\*([^\s:]*)\s*:\s*"([^"]*)"/ and do { $ppd{$1} = $2; next }; - /^\*([^\s:]*)\s*:\s*([^\s\"]*)/ and + /^\*([^\s:]*)\s*:\s*([^\s"]*)/ and do { $ppd{$1} = $2; next }; } }; @@ -1580,19 +1670,19 @@ sub ppd_devid_data { $ppd = "$::prefix/usr/share/cups/model/$ppd"; my @content; if ($ppd =~ /\.gz$/i) { - @content = cat_("$::prefix/bin/zcat $ppd |") or return ("", ""); + @content = cat_("$::prefix/bin/zcat $ppd |") or return "", ""; } else { - @content = cat_($ppd) or return ("", ""); + @content = cat_($ppd) or return "", ""; } my ($devidmake, $devidmodel); - /^\*Manufacturer:\s*\"(.*)\"\s*$/ and $devidmake = $1 + /^\*Manufacturer:\s*"(.*)"\s*$/ and $devidmake = $1 foreach @content; - /^\*Product:\s*\"\(?(.*?)\)?\"\s*$/ and $devidmodel = $1 + /^\*Product:\s*"\(?(.*?)\)?"\s*$/ and $devidmodel = $1 foreach @content; - return ($devidmake, $devidmodel); + return $devidmake, $devidmodel; } -sub poll_ppd_base() { +sub poll_ppd_base { my ($printer) = @_; #- 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. @@ -1603,11 +1693,11 @@ sub poll_ppd_base() { printer::services::start_not_running_service("cups"); my $driversthere = scalar(keys %thedb); foreach (1..60) { - local *PPDS; open PPDS, ($::testing ? $::prefix : - "chroot $::prefix/ ") . - "/usr/bin/poll_ppd_base -a |"; + open(my $PPDS, ($::testing ? $::prefix : + "chroot $::prefix/ ") . + "/usr/bin/poll_ppd_base -a |"); local $_; - while (<PPDS>) { + while (<$PPDS>) { chomp; my ($ppd, $mf, $descr, $lang) = split /\|/; if ($ppd eq "raw") { next } @@ -1633,7 +1723,7 @@ sub poll_ppd_base() { # Native CUPS? my $isnativecups = $driver =~ /CUPS/i; # Native PostScript - my $isnativeps = (!$isfoomatic and !$isnativecups); + my $isnativeps = !$isfoomatic && !$isnativecups; # Key without language tag (key as it was produced for the # entries from the Foomatic XML database) my $keynolang = $key; @@ -1664,13 +1754,15 @@ sub poll_ppd_base() { if (defined($thedb{$key})) { next if lc($thedb{$key}{driver}) eq lc($driver); - next unless $isnativeps && - $thedb{$key}{driver} =~ /^PostScript$/i || - $thedb{$key}{driver} ne "PPD" && $isrecommended || - $thedb{$key}{driver} eq "PPD" && $isrecommended && $driver ne "PostScript"; - - # Remove the old entry - delete $thedb{$key}; + if ($isnativeps && + $thedb{$key}{driver} =~ /^PostScript$/i || + $thedb{$key}{driver} ne "PPD" && $isrecommended || + $thedb{$key}{driver} eq "PPD" && $isrecommended && $driver ne "PostScript") { + # Remove the old entry + delete $thedb{$key}; + } else { + next; + } } } elsif ((defined $thedb{"$mf|$model|$fullfoomaticdriver"} || @@ -1748,7 +1840,7 @@ sub poll_ppd_base() { #$thedb{$key}{devidmodel} = $devidmodel; } } - close PPDS; + close $PPDS; scalar(keys %thedb) - $driversthere > 5 and last; #- we have to try again running the program, wait here a little #- before. @@ -1802,7 +1894,7 @@ sub configure_queue($) { } # Make sure that queue is active - if ($printer->{SPOOLER} ne "pdq") { + if ($printer->{NEW} && ($printer->{SPOOLER} ne "pdq")) { run_program::rooted($::prefix, "foomatic-printjob", "-s", $printer->{currentqueue}{spooler}, "-C", "up", $printer->{currentqueue}{queue}); @@ -1860,9 +1952,19 @@ sub configure_queue($) { return 1; } +sub enable_disable_queue { + my ($printer, $queue, $state) = @_; + + if (($printer->{SPOOLER} ne "pdq") && + ($printer->{SPOOLER} ne "rcups")) { + run_program::rooted($::prefix, "foomatic-printjob", + "-s", $printer->{SPOOLER}, + "-C", ($state ? "start" : "stop"), $queue); + } +} + sub remove_queue($$) { - my ($printer) = $_[0]; - my ($queue) = $_[1]; + my ($printer, $queue) = @_; run_program::rooted($::prefix, "foomatic-configure", "-R", "-q", "-s", $printer->{SPOOLER}, "-n", $queue); @@ -1874,7 +1976,6 @@ sub remove_queue($$) { $printer->{ARGS} = {}; $printer->{DBENTRY} = ""; $printer->{currentqueue} = {}; - removeprinterfromapplications($printer, $queue); } sub restart_queue($) { @@ -1909,38 +2010,39 @@ sub print_pages($@) { my $queue = $printer->{QUEUE}; my $lpr = "/usr/bin/foomatic-printjob"; my $lpq = "$lpr -Q"; + my $spooler = $printer->{SPOOLER}; + $spooler = "cups" if $spooler eq "rcups"; # Print the pages foreach (@pages) { my $page = $_; - # Only text and PostScript can be printed directly with all spoolers, - # images must be treated seperately + # Only text and PostScript can be printed directly with all + # spoolers, images must be treated seperately if ($page =~ /\.jpg$/) { - if ($printer->{SPOOLER} ne "cups") { + if ($spooler ne "cups") { # Use "convert" from ImageMagick for non-CUPS spoolers system(($::testing ? $::prefix : "chroot $::prefix/ ") . "/usr/bin/convert $page -page 427x654+100+65 PS:- | " . ($::testing ? $::prefix : "chroot $::prefix/ ") . - "$lpr -s $printer->{SPOOLER} -P $queue"); + "$lpr -s $spooler -P $queue"); } else { # Use CUPS's internal image converter with CUPS, tell it # to let the image occupy 90% of the page size (so nothing # gets cut off by unprintable borders) - run_program::rooted($::prefix, $lpr, "-s", $printer->{SPOOLER}, + run_program::rooted($::prefix, $lpr, "-s", $spooler, "-P", $queue, "-o", "scaling=90", $page); } } else { - run_program::rooted($::prefix, $lpr, "-s", $printer->{SPOOLER}, + run_program::rooted($::prefix, $lpr, "-s", $spooler, "-P", $queue, $page); } } sleep 5; #- allow lpr to send pages. # Check whether the job is queued - local *F; - open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "$lpq -s $printer->{SPOOLER} -P $queue |"; + open(my $F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "$lpq -s $spooler -P $queue |"); my @lpq_output = - grep { !/^no entries/ && !(/^Rank\s+Owner/ .. /^\s*$/) } <F>; - close F; + grep { !/^no entries/ && !(/^Rank\s+Owner/ .. /^\s*$/) } <$F>; + close $F; @lpq_output; } @@ -1948,10 +2050,9 @@ sub help_output { my ($printer, $spooler) = @_; my $queue = $printer->{QUEUE}; - local *F; - open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . sprintf($spoolers{$spooler}{help}, $queue); - my $helptext = join("", <F>); - close F; + open(my $F, ($::testing ? $::prefix : "chroot $::prefix/ ") . sprintf($spoolers{$spooler}{help}, $queue)); + my $helptext = join("", <$F>); + close $F; $helptext ||= "Option list not available!\n"; return $helptext; } @@ -1983,17 +2084,19 @@ sub print_optionlist { sub get_copiable_queues { my ($oldspooler, $newspooler) = @_; + # No local queues available in daemon-less CUPS mode + return () if ($oldspooler eq "rcups") or ($newspooler eq "rcups"); + my @queuelist; #- here we will list all Foomatic-generated queues # Get queue list with foomatic-configure - local *QUEUEOUTPUT; - open QUEUEOUTPUT, ($::testing ? $::prefix : "chroot $::prefix/ ") . - "foomatic-configure -Q -q -s $oldspooler |" or + open(my $QUEUEOUTPUT, ($::testing ? $::prefix : "chroot $::prefix/ ") . + "foomatic-configure -Q -q -s $oldspooler |") or die "Could not run foomatic-configure"; my $entry = {}; my $inentry = 0; local $_; - while (<QUEUEOUTPUT>) { + while (<$QUEUEOUTPUT>) { chomp; if ($inentry) { # We are inside a queue entry @@ -2018,7 +2121,7 @@ sub get_copiable_queues { $entry->{connect} = $1; } } else { - if (m!^\s*<queue\s+foomatic\s*=\s*\"?(\d+)\"?\s*spooler\s*=\s*\"?(\w+)\"?\s*>\s*$!) { + if (m!^\s*<queue\s+foomatic\s*=\s*"?(\d+)"?\s*spooler\s*=\s*"?(\w+)"?\s*>\s*$!) { # new entry $inentry = 1; $entry->{foomatic} = $1; @@ -2026,8 +2129,8 @@ sub get_copiable_queues { } } } - close QUEUEOUTPUT; - + close $QUEUEOUTPUT; + return @queuelist; } @@ -2131,16 +2234,15 @@ sub configure_hpoj { # It's only necessary to read it at the first call of this subroutine, # the subroutine definitions stay valid after leaving this subroutine. if (!$ptalinitread) { - local *PTALINIT; - open PTALINIT, "$::prefix/usr/sbin/ptal-init" or do { + open(my $PTALINIT, "$::prefix/usr/sbin/ptal-init") or do { die "unable to open $::prefix/usr/sbin/ptal-init"; }; my @ptalinitfunctions; # subroutine definitions in /usr/sbin/ptal-init local $_; - while (<PTALINIT>) { + while (<$PTALINIT>) { if (m!sub main!) { last; - } elsif ((m!^[^\#]!) && !(m!^\s*exec\b!)){ + } elsif (m!^[^#]! && !(m!^\s*exec\b!)) { # Comment lines and the "exec" line (probably obsolete # Red Hat workaround) are skipped. @@ -2164,7 +2266,7 @@ sub configure_hpoj { push @ptalinitfunctions, $_; } } - close PTALINIT; + close $PTALINIT; eval "package printer::hpoj; @ptalinitfunctions @@ -2230,10 +2332,8 @@ sub configure_hpoj { } }; } - my $devdata; foreach (@autodetected) { $device eq $_->{port} or next; - $devdata = $_; # $model is for the PTAL device name, so make sure that it is unique # so in the case of the model name auto-detection having failed leave # the port number or the host name as model name. @@ -2244,12 +2344,12 @@ sub configure_hpoj { $model = $_->{val}{MODEL}; } $serialnumber = $_->{val}{SERIALNUMBER}; - services::stop("hpoj") if ($bus ne "hpjd"); + services::stop("hpoj") if $bus ne "hpjd"; # Check if the device is really an HP multi-function device #my $libusb = 0; foreach my $libusb (0, 1) { # Do access via libusb/user mode only if we have a USB device - next if ($libusb && ($bus ne "usb")); + next if $libusb && $bus ne "usb"; # Preliminary workaround to make the user-mode USB devices # (LIDIL devices) installable as verification of the HPOJ # settings of these devices does not work yet. The workaround @@ -2277,7 +2377,7 @@ sub configure_hpoj { my $usbdev = usbdevice($_->{val}); if (defined($usbdev)) { # Unload kernel module "printer"/"usblp" - if (modules::get_probeall("usb-interface")) { + if (modules::any_conf->read->get_probeall("usb-interface")) { eval(modules::unload($usbprintermodule)); $printermoduleunloaded = 1; } @@ -2294,16 +2394,14 @@ sub configure_hpoj { } $device_ok = 0; my $ptalprobedevice = $bus eq "hpjd" ? "hpjd:$hostname" : "mlc:$bus:probe"; - local *F; - if (open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "/usr/bin/ptal-devid $ptalprobedevice |") { - my $devid = join("", <F>); - close F; + if (open(my $F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "/usr/bin/ptal-devid $ptalprobedevice |")) { + my $devid = join("", <$F>); + close $F; if ($devid) { $device_ok = 1; - local *F; - if (open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "/usr/bin/ptal-devid $ptalprobedevice -long -mdl 2>/dev/null |") { - $model_long = join("", <F>); - close F; + if (open(my $F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "/usr/bin/ptal-devid $ptalprobedevice -long -mdl 2>/dev/null |")) { + $model_long = join("", <$F>); + close $F; chomp $model_long; # If SNMP or local port auto-detection failed but # HPOJ auto-detection succeeded, fill in model name @@ -2318,9 +2416,9 @@ sub configure_hpoj { } } } - if (open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "/usr/bin/ptal-devid $ptalprobedevice -long -sern 2>/dev/null |") { #-# - $serialnumber_long = join("", <F>); - close F; + if (open(my $F, ($::testing ? $::prefix : "chroot $::prefix/ ") . "/usr/bin/ptal-devid $ptalprobedevice -long -sern 2>/dev/null |")) { #-# + $serialnumber_long = join("", <$F>); + close $F; chomp $serialnumber_long; } $cardreader = 1 if printer::hpoj::cardReaderDetected($ptalprobedevice); @@ -2328,21 +2426,20 @@ sub configure_hpoj { } if ($bus ne "hpjd") { # Stop ptal-mlcd daemon for locally connected devices - local *F; - if (open F, ($::testing ? $::prefix : "chroot $::prefix/ ") . qq(ps auxwww | grep "ptal-mlcd $bus:probe" | grep -v grep | )) { - my $line = <F>; + if (open(my $F, ($::testing ? $::prefix : "chroot $::prefix/ ") . qq(ps auxwww | grep "ptal-mlcd $bus:probe" | grep -v grep | ))) { + my $line = <$F>; if ($line =~ /^\s*\S+\s+(\d+)\s+/) { my $pid = $1; kill 15, $pid; } - close F; + close $F; } $printermoduleunloaded && eval(modules::load($usbprintermodule)); } last if $device_ok; } - printer::services::start("hpoj") if ($bus ne "hpjd"); + printer::services::start("hpoj") if $bus ne "hpjd"; last; } # No, it is not an HP multi-function device. @@ -2384,13 +2481,12 @@ sub configure_hpoj { # Configure the device # Open configuration file - local *CONFIG; - open(CONFIG, "> $::prefix/etc/ptal/$ptaldevice") or + open(my $CONFIG, "> $::prefix/etc/ptal/$ptaldevice") or die "Could not open /etc/ptal/$ptaldevice for writing!\n"; # Write file header. my $date = chomp_(`date`); - print CONFIG + print $CONFIG qq( # Added $date by "printerdrake" @@ -2412,56 +2508,56 @@ init.version=2 # Write model string. if ($model_long !~ /\S/) { - print CONFIG + print $CONFIG "\n" . qq(# "printerdrake" couldn't read the model but added this device anyway:\n) . "# "; } else { - print CONFIG + print $CONFIG "\n" . "# The device model that was originally detected on this port:\n" . qq(# If this ever changes, then you should re-run "printerdrake"\n) . "# to delete and re-configure this device.\n"; if ($bus eq "par") { - print CONFIG + print $CONFIG "# Comment out if you don't care what model is really connected to this\n" . "# parallel port.\n"; } } - print CONFIG + print $CONFIG qq(init.mlcd.append+=-devidmatch "$model_long"\n); # Write serial-number string. if ($serialnumber_long !~ /\S/) { - print CONFIG + print $CONFIG "\n" . "# The device's serial number is unknown.\n" . "# "; } else { - print CONFIG + print $CONFIG "\n" . "# The serial number of the device that was originally detected on this port:\n"; if ($bus =~ /^[pu]/) { - print CONFIG + print $CONFIG "# Comment out if you want to disable serial-number matching.\n"; } } - print CONFIG + print $CONFIG qq(init.mlcd.append+=-devidmatch "$serialnumber_long"\n); if ($bus =~ /^[pu]/) { - print CONFIG + print $CONFIG "\n" . "# Standard options passed to ptal-mlcd:\n" . "init.mlcd.append+="; if ($bus eq "usb") { # Important: don't put more quotes around /dev/usb/lp[0-9]*, # because ptal-mlcd currently does no globbing: - print CONFIG "-device /dev/usb/lp0 /dev/usb/lp1 /dev/usb/lp2 /dev/usb/lp3 /dev/usb/lp4 /dev/usb/lp5 /dev/usb/lp6 /dev/usb/lp7 /dev/usb/lp8 /dev/usb/lp9 /dev/usb/lp10 /dev/usb/lp11 /dev/usb/lp12 /dev/usb/lp13 /dev/usb/lp14 /dev/usb/lp15"; + print $CONFIG "-device /dev/usb/lp0 /dev/usb/lp1 /dev/usb/lp2 /dev/usb/lp3 /dev/usb/lp4 /dev/usb/lp5 /dev/usb/lp6 /dev/usb/lp7 /dev/usb/lp8 /dev/usb/lp9 /dev/usb/lp10 /dev/usb/lp11 /dev/usb/lp12 /dev/usb/lp13 /dev/usb/lp14 /dev/usb/lp15"; } elsif ($bus eq "par") { - print CONFIG "$address_arg -device $device"; + print $CONFIG "$address_arg -device $device"; } - print CONFIG "\n" . + print $CONFIG "\n" . "\n" . "# ptal-mlcd's remote console can be useful for debugging, but may be a\n" . "# security/DoS risk otherwise. In any case, it's accessible with the\n" . @@ -2479,7 +2575,7 @@ init.version=2 "# following line to disable ptal-printd for this device:\n" . "# init.printd.start=0\n"; } else { - print CONFIG + print $CONFIG "\n" . "# By default ptal-printd isn't started for hpjd: devices.\n" . "# If for some reason you want to start it for this device, then\n" . @@ -2487,13 +2583,13 @@ init.version=2 "init.printd.start=1\n"; } - print CONFIG + print $CONFIG "\n" . "# If you need to pass any additional command-line options to ptal-printd,\n" . "# then add them to the following line and uncomment the line:\n" . "# init.printd.append+=\n"; if ($cardreader) { - print CONFIG + print $CONFIG "\n" . "# Uncomment the following line to enable ptal-photod for this device:\n" . "init.photod.start=1\n" . @@ -2503,7 +2599,7 @@ init.version=2 qq(# then change the line below to use the "-portoffset <n>" option.\n) . "init.photod.append+=-maxaltports 26\n"; } - close(CONFIG); + close($CONFIG); printer::hpoj::readOneDevice($ptaldevice); # Restart HPOJ @@ -2517,27 +2613,26 @@ sub devicefound { my ($usbid, $model, $serial) = @_; # Compare the output of "lsusb -vv" with the elements of the device # ID string - if ($serial && ($usbid->{'SERIALNUMBER'} eq $serial)) { + if ($serial && $usbid->{SERIALNUMBER} eq $serial) { # Match of serial number has absolute priority return 1; - } elsif ($model && ($usbid->{'MODEL'} eq $model)) { + } elsif ($model && $usbid->{MODEL} eq $model) { # Try to match the model name otherwise return 1; } return 0; } -sub usbdevice() { +sub usbdevice { my ($usbid) = @_; # Run "lsusb -vv¨ and search the given device to get its USB bus and # device numbers - local *F; - open F, ($::testing ? "" : "chroot $::prefix/ ") . - '/bin/sh -c "export LC_ALL=C; lsusb -vv 2> /dev/null" |' + open(my $F, ($::testing ? "" : "chroot $::prefix/ ") . + '/bin/sh -c "export LC_ALL=C; lsusb -vv 2> /dev/null" |') or return undef; my ($bus, $device, $model, $serial) = ("", "", "", ""); my $found = 0; - while (my $line = <F>) { + while (my $line = <$F>) { chomp $line; if ($line =~ m/^\s*Bus\s+(\d+)\s+Device\s+(\d+)\s*:/i) { # head line of a new device @@ -2555,7 +2650,7 @@ sub usbdevice() { $serial = $1; } } - close F; + close $F; # Check last entry $found = devicefound($usbid, $model, $serial); @@ -2567,6 +2662,7 @@ sub config_sane() { # Add HPOJ backend to /etc/sane.d/dll.conf if needed (no individual # config file /etc/sane.d/hpoj.conf necessary, the HPOJ driver finds the # scanner automatically) + return if (! -f "$::prefix/etc/sane.d/dll.conf"); return if member("hpoj", chomp_(cat_("$::prefix/etc/sane.d/dll.conf"))); eval { append_to_file("$::prefix/etc/sane.d/dll.conf", "hpoj\n") } or die "can't write SANE config in /etc/sane.d/dll.conf: $!"; @@ -2594,7 +2690,7 @@ EOF my $mtoolsfmconf; if (-f "$::prefix/etc/mtoolsfm.conf") { $mtoolsfmconf = cat_("$::prefix/etc/mtoolsfm.conf") or die "can't read MToolsFM config in $::prefix/etc/mtoolsfm.conf: $!"; - my $alloweddrives = lc($1) if $mtoolsfmconf =~ m/^\s*DRIVES\s*=\s*\"([A-Za-z ]*)\"/m; + my $alloweddrives = lc($1) if $mtoolsfmconf =~ m/^\s*DRIVES\s*=\s*"([A-Za-z ]*)"/m; foreach my $letter ("p", "q", "r", "s") { $alloweddrives .= $letter if $alloweddrives !~ /$letter/; } @@ -2623,44 +2719,6 @@ EOF output("$::prefix/etc/mtoolsfm.conf", $mtoolsfmconf); } -# ------------------------------------------------------------------ -# -# Configuration of printers in applications -# -# ------------------------------------------------------------------ - -sub configureapplications { - my ($printer) = @_; - setcupslink($printer); - printer::office::configureoffice('Star Office', $printer); - printer::office::configureoffice('OpenOffice.Org', $printer); - printer::gimp::configure($printer); -} - -sub addcupsremotetoapplications { - my ($printer, $queue) = @_; - setcupslink($printer); - return printer::office::add_cups_remote_to_office('Star Office', $printer, $queue) && - printer::office::add_cups_remote_to_office('OpenOffice.Org', $printer, $queue) && - printer::gimp::addcupsremoteto($printer, $queue); -} - -sub removeprinterfromapplications { - my ($printer, $queue) = @_; - setcupslink($printer); - return printer::office::remove_printer_from_office('Star Office', $printer, $queue) && - printer::office::remove_printer_from_office('OpenOffice.Org', $printer, $queue) && - printer::gimp::removeprinterfrom($printer, $queue); -} - -sub removelocalprintersfromapplications { - my ($printer) = @_; - setcupslink($printer); - printer::office::remove_local_printers_from_office('Star Office', $printer); - printer::office::remove_local_printers_from_office('OpenOffice.Org', $printer); - printer::gimp::removelocalprintersfrom($printer); -} - sub setcupslink { my ($printer) = @_; return 1 if !$::isInstall || $printer->{SPOOLER} ne "cups" || -d "/etc/cups/ppd"; |
