xref: /titanic_51/usr/src/cmd/print/selector/print-service (revision 6124874e2cec65f2e7a974b3833b05dbf2a7d905)
19622934aSjacobs#!/usr/perl5/bin/perl
29622934aSjacobs#
39622934aSjacobs# CDDL HEADER START
49622934aSjacobs#
59622934aSjacobs# The contents of this file are subject to the terms of the
69622934aSjacobs# Common Development and Distribution License (the "License").
79622934aSjacobs# You may not use this file except in compliance with the License.
89622934aSjacobs#
99622934aSjacobs# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
109622934aSjacobs# or http://www.opensolaris.org/os/licensing.
119622934aSjacobs# See the License for the specific language governing permissions
129622934aSjacobs# and limitations under the License.
139622934aSjacobs#
149622934aSjacobs# When distributing Covered Code, include this CDDL HEADER in each
159622934aSjacobs# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
169622934aSjacobs# If applicable, add the following below this CDDL HEADER, with the
179622934aSjacobs# fields enclosed by brackets "[]" replaced with your own identifying
189622934aSjacobs# information: Portions Copyright [yyyy] [name of copyright owner]
199622934aSjacobs#
209622934aSjacobs# CDDL HEADER END
219622934aSjacobs#
22*6124874eSGhee Teo# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
239622934aSjacobs# Use is subject to license terms.
249622934aSjacobs#
259622934aSjacobs#
269622934aSjacobs
279622934aSjacobs#
289622934aSjacobs# This program manages the "active" print service selection.
299622934aSjacobs#   If called as 'print-service', it takes one of four options.
309622934aSjacobs#   Options:
319622934aSjacobs#     [-s[et] service [-m]]	Select the "active" print service, optionally
329622934aSjacobs#				migrating basic print queue configuration.
339622934aSjacobs#     [-q[uery]]		Display the "active" print service.
349622934aSjacobs#     [-e[xport] file]		Export basic print queue configuration to
359622934aSjacobs#				a file.
369622934aSjacobs#     [-i[mport] file]		Import basic print queue configuration from
379622934aSjacobs#				a file.
389622934aSjacobs#
399622934aSjacobs#   If called by any other name, it will look for a corresponding command
409622934aSjacobs#   under /usr/lib/{active-service}/bin/{command} and execute that program
419622934aSjacobs#   with the original arguments.
429622934aSjacobs#
439622934aSjacobs
449622934aSjacobsuse Getopt::Long;
459622934aSjacobsuse File::Basename;
469622934aSjacobsuse File::Copy;
479622934aSjacobsuse File::Temp qw/ :POSIX /;
489622934aSjacobs
499622934aSjacobsmy $cmd = basename($0);
509622934aSjacobs
519622934aSjacobsmy $LPSTAT = '/usr/bin/lpstat';
529622934aSjacobsmy $LPADMIN = '/usr/sbin/lpadmin';
539622934aSjacobsmy $ENABLE = '/usr/bin/enable';
549622934aSjacobsmy $ACCEPT = '/usr/sbin/accept';
559622934aSjacobsmy $SVCADM = '/usr/sbin/svcadm';
569622934aSjacobsmy $SVCPROP = '/usr/bin/svcprop';
579622934aSjacobsmy $SVCCFG = '/usr/sbin/svccfg';
589622934aSjacobsmy $SVC_LP_SCHEDULER = 'print/server';
599622934aSjacobsmy $SVC_LP_LPD = 'print/rfc1179';
609622934aSjacobsmy $SVC_LP_IPP = 'print/ipp-listener';
6136615d24Sjacobsmy $SVC_LP_PPD = 'print/ppd-cache-update';
629622934aSjacobsmy $SVC_CUPS_SCHEDULER = 'cups/scheduler';
639622934aSjacobsmy $SVC_CUPS_LPD = 'cups/in-lpd';
649622934aSjacobs
659622934aSjacobssub fatal {
66c1ecd8b9Sjacobs	($ENV{"DESKTOP_LAUNCHED"}) &&
67c1ecd8b9Sjacobs		exec("/bin/zenity", "--error", "--text=@_");
689622934aSjacobs	print STDERR @_;
699622934aSjacobs	exit(1);
709622934aSjacobs}
719622934aSjacobs
729622934aSjacobssub usage {
739622934aSjacobs	print STDERR <<EOF ;
749622934aSjacobsUsage:
759622934aSjacobs  $cmd [-s[et] service [-m]]	Select the \"active\" print service,
769622934aSjacobs					optionally migrating basic print queue
779622934aSjacobs					configuration.
789622934aSjacobs  $cmd [-q[uery]]		Display the "active" print service.
799622934aSjacobs  $cmd [-e[xport] file]	Export basic print queue configuration
809622934aSjacobs					to a file.
819622934aSjacobs  $cmd [-i[mport] file]	Import basic print queue configuration
829622934aSjacobs					from a file.
839622934aSjacobsEOF
849622934aSjacobs	exit(1);
859622934aSjacobs}
869622934aSjacobs
879622934aSjacobssub svcprop {
889622934aSjacobs	local ($fmri, $property) = @_;
899622934aSjacobs	my $FH;
909622934aSjacobs
919622934aSjacobs	open($FH, "$SVCPROP -C -p $property $fmri 2>/dev/null |");
929622934aSjacobs	$result = <$FH>;
939622934aSjacobs	close($FH);
949622934aSjacobs
959622934aSjacobs	return ($result);
969622934aSjacobs}
979622934aSjacobs
989622934aSjacobssub svccfg {
999622934aSjacobs	local ($fmri, $operation) = @_;
1009622934aSjacobs	my $FH;
1019622934aSjacobs
1029622934aSjacobs	open($FH, "$SVCCFG -s $fmri \"$operation\" 2>/dev/null |");
1039622934aSjacobs	$result = <$FH>;
1049622934aSjacobs	close($FH);
1059622934aSjacobs
1069622934aSjacobs	return ($result);
1079622934aSjacobs}
1089622934aSjacobs
1099622934aSjacobssub svcadm {
1109622934aSjacobs	local ($operation, @fmris) = @_;
1119622934aSjacobs
1129622934aSjacobs	system("$SVCADM $operation -s @fmris");
1139622934aSjacobs}
1149622934aSjacobs
1159622934aSjacobs
1169622934aSjacobssub print_service {
1179622934aSjacobs	my $service;
1189622934aSjacobs
1199622934aSjacobs	$service = svcprop("$SVC_CUPS_SCHEDULER:default", "general/active");
1209622934aSjacobs	($service =~ /true/) && ($service = 'cups') || ($service = 'lp');
1219622934aSjacobs
1229622934aSjacobs	return ($service);
1239622934aSjacobs}
1249622934aSjacobs
1259622934aSjacobssub print_command {
1269622934aSjacobs	local($command, @av) = @_;
1279622934aSjacobs	my $service = print_service();
1289622934aSjacobs
1299622934aSjacobs	if (!defined($service)) {
1309622934aSjacobs		fatal("failed to detect active print service: $!\n");
1319622934aSjacobs	}
1329622934aSjacobs
1339622934aSjacobs	if (! -d "/usr/lib/$service/bin") {
1349622934aSjacobs		fatal("print service: $service is not installed\n");
1359622934aSjacobs	}
1369622934aSjacobs
1379622934aSjacobs	my $executable = "/usr/lib/$service/bin/$command";
1389622934aSjacobs	# CUPS has it's own names for enable and disable
1399622934aSjacobs	($command =~ /(en|dis)able/) && ($service eq 'cups') &&
1409622934aSjacobs		(! -x $executable) &&
1419622934aSjacobs		($executable = "/usr/lib/$service/bin/$service$command");
1429622934aSjacobs
1439622934aSjacobs	if (! -x $executable) {
1449622934aSjacobs		fatal("$command is not available from $service print service\n");
1459622934aSjacobs	}
1469622934aSjacobs
1479622934aSjacobs	exec($executable, @ARGV);
1489622934aSjacobs}
1499622934aSjacobs
1509622934aSjacobssub export_print_queues {
1519622934aSjacobs	local ($path) = @_;
1529622934aSjacobs	my $service = print_service();
1539622934aSjacobs
1549622934aSjacobs	if ($service eq 'lp') {
1559622934aSjacobs		my $FH, $DFH;
1569622934aSjacobs
1579622934aSjacobs		open($FH, ">$path");
1589622934aSjacobs		open($DFH, "$LPSTAT -v|");
1599622934aSjacobs		while (<$DFH>) {
1609622934aSjacobs			if (/device for (.+): (.+)/) {
1619622934aSjacobs				my $EFH;
1629622934aSjacobs
1639622934aSjacobs				print $FH "<Printer $1>\nDeviceURI $2\n";
1649622934aSjacobs				open($EFH, "$LPSTAT -p $1 -l |");
1659622934aSjacobs				while (<$EFH>) {
1669622934aSjacobs					(/Description: (.+)/) &&
1679622934aSjacobs						print $FH "Info $1\n";
1689622934aSjacobs				}
1699622934aSjacobs				close($EFH);
1709622934aSjacobs				print $FH "</Printer>\n";
1719622934aSjacobs			}
1729622934aSjacobs		}
1739622934aSjacobs		close($DFH);
1749622934aSjacobs		close($FH);
1759622934aSjacobs	} else {
1769622934aSjacobs		copy('/etc/cups/printers.conf', $path);
1779622934aSjacobs	}
1789622934aSjacobs}
1799622934aSjacobs
1809622934aSjacobssub psystem {
1819622934aSjacobs	print "  @_\n";
1829622934aSjacobs	system(@_);
1839622934aSjacobs}
1849622934aSjacobs
1859622934aSjacobssub import_print_queues {
1869622934aSjacobs	local ($path) = @_;
1879622934aSjacobs	my $service = print_service();
1889622934aSjacobs	my $FH, %printer, @options;
1899622934aSjacobs
1909622934aSjacobs	# store queue info in the 'active' print service
1919622934aSjacobs	open($FH, "<$path");
1929622934aSjacobs	while (<$FH>) {
1939622934aSjacobs		if (/<Printer (.+)>/) {
1949622934aSjacobs			$printer{'Printer'} = $1;
1959622934aSjacobs			@options = ();
1969622934aSjacobs			push(@options, "-p", $1);
1979622934aSjacobs		} elsif (/([^\s]+)\s(.+)/) {
1989622934aSjacobs			$printer{$1} = $2;
1999622934aSjacobs			my $value = $2;
2009622934aSjacobs			($1 eq 'DeviceURI') &&
2019622934aSjacobs				push(@options, "-v", $value);
2029622934aSjacobs			($1 eq 'Info') &&
2039622934aSjacobs				push(@options, "-D", $value);
2049622934aSjacobs		} elsif (/<\/Printer>/) {
2059622934aSjacobs			($service eq 'lp') &&
2069622934aSjacobs				push(@options, "-m", "uri");
2079622934aSjacobs			print "importing $printer{'Printer'}...\n";
2089622934aSjacobs			# create a queue
2099622934aSjacobs			psystem($LPADMIN, @options);
2109622934aSjacobs			psystem($ENABLE, $printer{'Printer'});
2119622934aSjacobs			($printer{'Accepting'} eq 'Yes') &&
2129622934aSjacobs				psystem($ACCEPT, $printer{'Printer'});
2139622934aSjacobs			$printer = ();
2149622934aSjacobs		}
2159622934aSjacobs	}
2169622934aSjacobs	close($FH);
2179622934aSjacobs}
2189622934aSjacobs
2199622934aSjacobssub select_service {
2209622934aSjacobs	my ($service, $migrate) = @_;
2219622934aSjacobs	my $FH, $queues;
2229622934aSjacobs
2239622934aSjacobs	if (! -d "/usr/lib/$service/bin") {
2249622934aSjacobs		fatal("print service: $service is not installed\n");
2259622934aSjacobs	}
2269622934aSjacobs
2279622934aSjacobs	if ($migrate == 1) {
2289622934aSjacobs		# export old print queue configuration (if migrating)
2299622934aSjacobs		$queues = tmpnam();
2309622934aSjacobs		export_print_queues($queues);
2319622934aSjacobs	}
2329622934aSjacobs
2339622934aSjacobs	# enable/disable the services
2349622934aSjacobs	if ($service eq 'cups') {
23536615d24Sjacobs		(-f '/etc/printers.conf') && (! -f '/etc/lp/printers.conf') &&
23636615d24Sjacobs			rename('/etc/printers.conf', '/etc/lp/printers.conf');
2379622934aSjacobs		print("disabling LP services...\n");
23836615d24Sjacobs		svcadm("disable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD,
23936615d24Sjacobs				  $SVC_LP_PPD);
2409622934aSjacobs		print("enabling CUPS services...\n");
2419622934aSjacobs		svcadm("enable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD);
2429622934aSjacobs		svccfg("cups/scheduler:default",
2439622934aSjacobs			"setprop general/active = boolean: true");
244*6124874eSGhee Teo		system("pkill -USR1 -f '/desktop-print-management-applet'");
2459622934aSjacobs	} else {
2469622934aSjacobs		print("disabling CUPS services...\n");
2479622934aSjacobs		svcadm("disable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD);
2489622934aSjacobs		print("enabling LP services...\n");
24936615d24Sjacobs		svcadm("enable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD,
25036615d24Sjacobs				  $SVC_LP_PPD);
25136615d24Sjacobs		(-f '/etc/lp/printers.conf') &&
25236615d24Sjacobs			rename('/etc/lp/printers.conf', '/etc/printers.conf');
2539622934aSjacobs		svccfg("cups/scheduler:default", "delprop general/active");
254*6124874eSGhee Teo		system("pkill -USR1 -f '/desktop-print-management-applet'");
2559622934aSjacobs	}
2569622934aSjacobs
2579622934aSjacobs	# import the new print queue configuration (if migrating)
2589622934aSjacobs	defined($queues) && import_print_queues($queues);
2599622934aSjacobs}
2609622934aSjacobs
2619622934aSjacobssub query_service {
2629622934aSjacobs	my $service = print_service();
2639622934aSjacobs
2649622934aSjacobs	if (!defined($service)) {
2659622934aSjacobs		fatal("failed to detect active print service: $!\n");
2669622934aSjacobs	}
2679622934aSjacobs	print "active print service: $service\n";
2689622934aSjacobs}
2699622934aSjacobs
2709622934aSjacobsif ($cmd eq 'print-service') {
2719622934aSjacobs	my ($import_path, $export_path, $svc_name, $query, $migrate) = ();
2729622934aSjacobs
2739622934aSjacobs	my $res = GetOptions('q|query' => \$query, 's|set=s' => \$service,
2749622934aSjacobs		'm|migrate' => \$migrate, 'e|export=s' => \$export_path,
2759622934aSjacobs		'i|import=s' => \$import_path);
2769622934aSjacobs
2779622934aSjacobs	($res) || usage();
2789622934aSjacobs
2799622934aSjacobs	if (defined($import_path) && !defined($export_path) &&
2809622934aSjacobs	    !defined($query) && !defined($service) && !defined($migrate)) {
2819622934aSjacobs		import_print_queues($import_path);
2829622934aSjacobs	} elsif (!defined($import_path) && defined($export_path) &&
2839622934aSjacobs		 !defined($query) && !defined($service) && !defined($migrate)) {
2849622934aSjacobs		export_print_queues($export_path);
2859622934aSjacobs	} elsif (!defined($import_path) && !defined($export_path) &&
2869622934aSjacobs		 defined($query) && !defined($service) && !defined($migrate)) {
2879622934aSjacobs		query_service();
2889622934aSjacobs	} elsif (!defined($import_path) && !defined($export_path) &&
2899622934aSjacobs		 !defined($query) && defined($service)) {
2909622934aSjacobs		select_service($service, $migrate);
2919622934aSjacobs	} else {
2929622934aSjacobs		usage();
2939622934aSjacobs	}
2949622934aSjacobs} else {
2959622934aSjacobs	print_command($cmd, @ARGV);
2969622934aSjacobs}
2979622934aSjacobs
2989622934aSjacobsexit(0);
299