summaryrefslogtreecommitdiff
path: root/usr/src/cmd/print/selector/print-service
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/print/selector/print-service')
-rwxr-xr-xusr/src/cmd/print/selector/print-service288
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);