package printer::main;
# $Id$
use strict;
use common;
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 services;
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(%printer_type %printer_type_inv);
#-location of the printer database in an installed system
my $PRINTER_DB_FILE = "/usr/share/foomatic/db/compiled/overview.xml";
#-Did we already read the subroutines of /usr/sbin/ptal-init?
my $ptalinitread = 0;
our %printer_type = (
N("Local printer") => "LOCAL",
N("Remote printer") => "REMOTE",
N("Printer on remote CUPS server") => "CUPS",
N("Printer on remote lpd server") => "LPD",
N("Network printer (TCP/Socket)") => "SOCKET",
N("Printer on SMB/Windows 95/98/NT server") => "SMB",
N("Printer on NetWare server") => "NCP",
N("Enter a printer device URI") => "URI",
N("Pipe job into a command") => "POSTPIPE"
);
our %printer_type_inv = reverse %printer_type;
our %thedb;
#------------------------------------------------------------------------------
sub spooler {
# LPD is taken from the menu for the moment because the classic LPD is
# highly unsecure. Depending on how the GNU lpr development is going on
# LPD support can be reactivated by uncommenting the following line.
#return @spooler_inv{qw(cups lpd lprng pdq)};
# LPRng is not officially supported any more since Mandrake 9.0, so
# show it only in the spooler menu when it was manually installed.
return map { $spoolers{$_}{long_name} } qw(cups pdq), if_(files_exist(qw(/usr/lib/filters/lpf /usr/sbin/lpd)), 'lprng');
}
sub printer_type($) {
my ($printer) = @_;
for ($printer->{SPOOLER}) {
/cups/ && return @printer_type_inv{qw(LOCAL LPD SOCKET SMB), if_($::expert, qw(URI))};
/lpd/ && return @printer_type_inv{qw(LOCAL LPD SOCKET SMB NCP), if_($::expert, qw(POSTPIPE URI))};
/lprng/ && return @printer_type_inv{qw(LOCAL LPD SOCKET SMB NCP), if_($::expert, qw(POSTPIPE URI))};
/pdq/ && return @printer_type_inv{qw(LOCAL LPD SOCKET), if_($::expert, qw(URI))};
}
}
sub SIGHUP_daemon {
my ($service) = @_;
if ($service eq "cupsd") { $service = "cups" };
# PDQ has no daemon, exit.
if ($service eq "pdq") { return 1 };
# CUPS needs auto-correction for its configuration
run_program::rooted($::prefix, "/usr/sbin/correctcupsconfig") if $service eq "cups";
# Name of the daemon
my %daemons = (
"lpr" => "lpd",
"lpd" => "lpd",
"lprng" => "lpd",
"cups" => "cupsd",
"devfs" => "devfsd",
);
my $daemon = $daemons{$service};
$daemon = $service unless defined $daemon;
# if ($service eq "cups") {
# # The current CUPS (1.1.13) dies on SIGHUP, do the normal restart.
# printer::services::restart($service);
# # CUPS needs some time to come up.
# printer::services::wait_for_cups();
# } else {
# Send the SIGHUP
run_program::rooted($::prefix, "/usr/bin/killall", "-HUP", $daemon);
if ($service eq "cups") {
# CUPS needs some time to come up.
printer::services::wait_for_cups();
}
return 1;
}
sub assure_device_is_available_for_cups {
# Checks whether CUPS already "knows" a certain port, it does not
# know it usually when the appropriate kernel module is loaded
# after CUPS was started or when the printer is turned on after
# CUPS was started. CUPS 1.1.12 and newer refuses to set up queues
# on devices which it does not know, it points these queues to
# file:/dev/null instead. Restart CUPS if necessary to assure that
# CUPS knows the device.
my ($device) = @_;
my ($result, $i);
for ($i = 0; $i < 3; $i++) {
local *F;
open 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>) {
if ($line =~ /$device/) { # Found a line containing the device
# name, so CUPS knows it.
close F;
return 1;
}
}
close F;
$result = SIGHUP_daemon("cups");
}
return $result;
}
sub spooler_in_security_level {
# Was the current spooler already added to the current security level?
my ($spooler, $level) = @_;
my $sp;
$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>) {
if ($line =~ /^\s*$sp\s*$/) {
close F;
return 1;
}
}
close F;
}
return 0;
}
sub add_spooler_to_security_level {
my ($spooler, $level) = @_;
my $sp;
$sp = $spooler eq "lpr" || $spooler eq "lprng" ? "lpd" : $spooler;
my $file = "$::prefix/etc/security/msec/server.$level";
if (-f $file) {
eval { append_to_file($file, "$sp\n") } or return 0;
}
return 1;
}
sub pdq_panic_button {
my $setting = $_[0];
if (-f "$::prefix/usr/sbin/pdqpanicbutton") {
run_program::rooted($::prefix, "/usr/sbin/pdqpanicbutton", "--$setting")
or die "Could not $setting PDQ panic buttons!";
}
}
sub copy_printer_params($$) {
my ($from, $to) = @_;
map { $to->{$_} = $from->{$_} } grep { $_ ne 'configured' } keys %$from;
#- avoid cycles-----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
sub getinfo($) {
my ($prefix) = @_;
my $printer = {};
$::prefix = $prefix;
# Initialize $printer data structure
resetinfo($printer);
return $printer;
}
#------------------------------------------------------------------------------
sub resetinfo($) {
my ($printer) = @_;
$printer->{QUEUE} = "";
$printer->{OLD_QUEUE} = "";
$printer->{OLD_CHOICE} = "";
$printer->{ARGS} = "";
$printer->{DBENTRY} = "";
$printer->{DEFAULT} = "";
$printer->{currentqueue} = {};
# -check which printing system was used previously and load the information
# -about its queues
read_configured_queues($printer);
}
sub read_configured_queues($) {
my ($printer) = @_;
my @QUEUES;
# Get the default spooler choice from the config file
$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)) {
#- Is the spooler's daemon running?
my $service = $spooler;
if ($service eq "lprng") {
$service = "lpd";
}
if ($service ne "pdq") {
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;
if ($service eq "pdq") {
#- Have we found queues? PDQ has no damon, so we consider
#- it in use when there are defined printer queues
if ($#QUEUES != -1) {
$printer->{SPOOLER} = $spooler;
last;
}
} else {
#- For other spoolers we have already found a running
#- daemon when we have arrived here
last;
}
}
} else {
#- Poll the queues of the current default spooler
local *F;
open F, ($::testing ? $::prefix : "chroot $::prefix/ ") .
"foomatic-configure -P -q -s $printer->{SPOOLER} |" or
die "Could not run foomatic-configure";
eval join('', <F>);
close F;
}
$printer->{configured} = {};
my $i;
my $N = $#QUEUES + 1;
|