diff options
Diffstat (limited to 'usr/src/cmd/print/selector/print-service')
-rwxr-xr-x | usr/src/cmd/print/selector/print-service | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/usr/src/cmd/print/selector/print-service b/usr/src/cmd/print/selector/print-service new file mode 100755 index 0000000000..c2857a9a43 --- /dev/null +++ b/usr/src/cmd/print/selector/print-service @@ -0,0 +1,288 @@ +#!/usr/perl5/bin/perl +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +# +# This program manages the "active" print service selection. +# If called as 'print-service', it takes one of four options. +# Options: +# [-s[et] service [-m]] Select the "active" print service, optionally +# migrating basic print queue configuration. +# [-q[uery]] Display the "active" print service. +# [-e[xport] file] Export basic print queue configuration to +# a file. +# [-i[mport] file] Import basic print queue configuration from +# a file. +# +# If called by any other name, it will look for a corresponding command +# under /usr/lib/{active-service}/bin/{command} and execute that program +# with the original arguments. +# + +use Getopt::Long; +use File::Basename; +use File::Copy; +use File::Temp qw/ :POSIX /; + +my $cmd = basename($0); + +my $LPSTAT = '/usr/bin/lpstat'; +my $LPADMIN = '/usr/sbin/lpadmin'; +my $ENABLE = '/usr/bin/enable'; +my $ACCEPT = '/usr/sbin/accept'; +my $SVCADM = '/usr/sbin/svcadm'; +my $SVCPROP = '/usr/bin/svcprop'; +my $SVCCFG = '/usr/sbin/svccfg'; +my $SVC_LP_SCHEDULER = 'print/server'; +my $SVC_LP_LPD = 'print/rfc1179'; +my $SVC_LP_IPP = 'print/ipp-listener'; +my $SVC_CUPS_SCHEDULER = 'cups/scheduler'; +my $SVC_CUPS_LPD = 'cups/in-lpd'; + +sub fatal { + print STDERR @_; + exit(1); +} + +sub usage { + print STDERR <<EOF ; +Usage: + $cmd [-s[et] service [-m]] Select the \"active\" print service, + optionally migrating basic print queue + configuration. + $cmd [-q[uery]] Display the "active" print service. + $cmd [-e[xport] file] Export basic print queue configuration + to a file. + $cmd [-i[mport] file] Import basic print queue configuration + from a file. +EOF + exit(1); +} + +sub svcprop { + local ($fmri, $property) = @_; + my $FH; + + open($FH, "$SVCPROP -C -p $property $fmri 2>/dev/null |"); + $result = <$FH>; + close($FH); + + return ($result); +} + +sub svccfg { + local ($fmri, $operation) = @_; + my $FH; + + open($FH, "$SVCCFG -s $fmri \"$operation\" 2>/dev/null |"); + $result = <$FH>; + close($FH); + + return ($result); +} + +sub svcadm { + local ($operation, @fmris) = @_; + + system("$SVCADM $operation -s @fmris"); +} + + +sub print_service { + my $service; + + $service = svcprop("$SVC_CUPS_SCHEDULER:default", "general/active"); + ($service =~ /true/) && ($service = 'cups') || ($service = 'lp'); + + return ($service); +} + +sub print_command { + local($command, @av) = @_; + my $service = print_service(); + + if (!defined($service)) { + fatal("failed to detect active print service: $!\n"); + } + + if (! -d "/usr/lib/$service/bin") { + fatal("print service: $service is not installed\n"); + } + + my $executable = "/usr/lib/$service/bin/$command"; + # CUPS has it's own names for enable and disable + ($command =~ /(en|dis)able/) && ($service eq 'cups') && + (! -x $executable) && + ($executable = "/usr/lib/$service/bin/$service$command"); + + if (! -x $executable) { + fatal("$command is not available from $service print service\n"); + } + + exec($executable, @ARGV); +} + +sub export_print_queues { + local ($path) = @_; + my $service = print_service(); + + if ($service eq 'lp') { + my $FH, $DFH; + + open($FH, ">$path"); + open($DFH, "$LPSTAT -v|"); + while (<$DFH>) { + if (/device for (.+): (.+)/) { + my $EFH; + + print $FH "<Printer $1>\nDeviceURI $2\n"; + open($EFH, "$LPSTAT -p $1 -l |"); + while (<$EFH>) { + (/Description: (.+)/) && + print $FH "Info $1\n"; + } + close($EFH); + print $FH "</Printer>\n"; + } + } + close($DFH); + close($FH); + } else { + copy('/etc/cups/printers.conf', $path); + } +} + +sub psystem { + print " @_\n"; + system(@_); +} + +sub import_print_queues { + local ($path) = @_; + my $service = print_service(); + my $FH, %printer, @options; + + # store queue info in the 'active' print service + open($FH, "<$path"); + while (<$FH>) { + if (/<Printer (.+)>/) { + $printer{'Printer'} = $1; + @options = (); + push(@options, "-p", $1); + } elsif (/([^\s]+)\s(.+)/) { + $printer{$1} = $2; + my $value = $2; + ($1 eq 'DeviceURI') && + push(@options, "-v", $value); + ($1 eq 'Info') && + push(@options, "-D", $value); + } elsif (/<\/Printer>/) { + ($service eq 'lp') && + push(@options, "-m", "uri"); + print "importing $printer{'Printer'}...\n"; + # create a queue + psystem($LPADMIN, @options); + psystem($ENABLE, $printer{'Printer'}); + ($printer{'Accepting'} eq 'Yes') && + psystem($ACCEPT, $printer{'Printer'}); + $printer = (); + } + } + close($FH); +} + +sub select_service { + my ($service, $migrate) = @_; + my $FH, $queues; + + if (! -d "/usr/lib/$service/bin") { + fatal("print service: $service is not installed\n"); + } + + if ($migrate == 1) { + # export old print queue configuration (if migrating) + $queues = tmpnam(); + export_print_queues($queues); + } + + # enable/disable the services + if ($service eq 'cups') { + print("disabling LP services...\n"); + svcadm("disable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD); + print("enabling CUPS services...\n"); + svcadm("enable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD); + svccfg("cups/scheduler:default", + "setprop general/active = boolean: true"); + } else { + print("disabling CUPS services...\n"); + svcadm("disable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD); + print("enabling LP services...\n"); + svcadm("enable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD); + svccfg("cups/scheduler:default", "delprop general/active"); + } + + # import the new print queue configuration (if migrating) + defined($queues) && import_print_queues($queues); +} + +sub query_service { + my $service = print_service(); + + if (!defined($service)) { + fatal("failed to detect active print service: $!\n"); + } + print "active print service: $service\n"; +} + +if ($cmd eq 'print-service') { + my ($import_path, $export_path, $svc_name, $query, $migrate) = (); + + my $res = GetOptions('q|query' => \$query, 's|set=s' => \$service, + 'm|migrate' => \$migrate, 'e|export=s' => \$export_path, + 'i|import=s' => \$import_path); + + ($res) || usage(); + + if (defined($import_path) && !defined($export_path) && + !defined($query) && !defined($service) && !defined($migrate)) { + import_print_queues($import_path); + } elsif (!defined($import_path) && defined($export_path) && + !defined($query) && !defined($service) && !defined($migrate)) { + export_print_queues($export_path); + } elsif (!defined($import_path) && !defined($export_path) && + defined($query) && !defined($service) && !defined($migrate)) { + query_service(); + } elsif (!defined($import_path) && !defined($export_path) && + !defined($query) && defined($service)) { + select_service($service, $migrate); + } else { + usage(); + } +} else { + print_command($cmd, @ARGV); +} + +exit(0); |