xref: /onnv-gate/usr/src/cmd/print/selector/print-service (revision 10120:d36eaa844e85)
16237Sjacobs#!/usr/perl5/bin/perl
26237Sjacobs#
36237Sjacobs# CDDL HEADER START
46237Sjacobs#
56237Sjacobs# The contents of this file are subject to the terms of the
66237Sjacobs# Common Development and Distribution License (the "License").
76237Sjacobs# You may not use this file except in compliance with the License.
86237Sjacobs#
96237Sjacobs# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
106237Sjacobs# or http://www.opensolaris.org/os/licensing.
116237Sjacobs# See the License for the specific language governing permissions
126237Sjacobs# and limitations under the License.
136237Sjacobs#
146237Sjacobs# When distributing Covered Code, include this CDDL HEADER in each
156237Sjacobs# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
166237Sjacobs# If applicable, add the following below this CDDL HEADER, with the
176237Sjacobs# fields enclosed by brackets "[]" replaced with your own identifying
186237Sjacobs# information: Portions Copyright [yyyy] [name of copyright owner]
196237Sjacobs#
206237Sjacobs# CDDL HEADER END
216237Sjacobs#
22*10120SGhee.Teo@Sun.COM# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
236237Sjacobs# Use is subject to license terms.
246237Sjacobs#
256237Sjacobs#
266237Sjacobs
276237Sjacobs#
286237Sjacobs# This program manages the "active" print service selection.
296237Sjacobs#   If called as 'print-service', it takes one of four options.
306237Sjacobs#   Options:
316237Sjacobs#     [-s[et] service [-m]]	Select the "active" print service, optionally
326237Sjacobs#				migrating basic print queue configuration.
336237Sjacobs#     [-q[uery]]		Display the "active" print service.
346237Sjacobs#     [-e[xport] file]		Export basic print queue configuration to
356237Sjacobs#				a file.
366237Sjacobs#     [-i[mport] file]		Import basic print queue configuration from
376237Sjacobs#				a file.
386237Sjacobs#
396237Sjacobs#   If called by any other name, it will look for a corresponding command
406237Sjacobs#   under /usr/lib/{active-service}/bin/{command} and execute that program
416237Sjacobs#   with the original arguments.
426237Sjacobs#
436237Sjacobs
446237Sjacobsuse Getopt::Long;
456237Sjacobsuse File::Basename;
466237Sjacobsuse File::Copy;
476237Sjacobsuse File::Temp qw/ :POSIX /;
486237Sjacobs
496237Sjacobsmy $cmd = basename($0);
506237Sjacobs
516237Sjacobsmy $LPSTAT = '/usr/bin/lpstat';
526237Sjacobsmy $LPADMIN = '/usr/sbin/lpadmin';
536237Sjacobsmy $ENABLE = '/usr/bin/enable';
546237Sjacobsmy $ACCEPT = '/usr/sbin/accept';
556237Sjacobsmy $SVCADM = '/usr/sbin/svcadm';
566237Sjacobsmy $SVCPROP = '/usr/bin/svcprop';
576237Sjacobsmy $SVCCFG = '/usr/sbin/svccfg';
586237Sjacobsmy $SVC_LP_SCHEDULER = 'print/server';
596237Sjacobsmy $SVC_LP_LPD = 'print/rfc1179';
606237Sjacobsmy $SVC_LP_IPP = 'print/ipp-listener';
616817Sjacobsmy $SVC_LP_PPD = 'print/ppd-cache-update';
626237Sjacobsmy $SVC_CUPS_SCHEDULER = 'cups/scheduler';
636237Sjacobsmy $SVC_CUPS_LPD = 'cups/in-lpd';
646237Sjacobs
656237Sjacobssub fatal {
667253Sjacobs	($ENV{"DESKTOP_LAUNCHED"}) &&
677253Sjacobs		exec("/bin/zenity", "--error", "--text=@_");
686237Sjacobs	print STDERR @_;
696237Sjacobs	exit(1);
706237Sjacobs}
716237Sjacobs
726237Sjacobssub usage {
736237Sjacobs	print STDERR <<EOF ;
746237SjacobsUsage:
756237Sjacobs  $cmd [-s[et] service [-m]]	Select the \"active\" print service,
766237Sjacobs					optionally migrating basic print queue
776237Sjacobs					configuration.
786237Sjacobs  $cmd [-q[uery]]		Display the "active" print service.
796237Sjacobs  $cmd [-e[xport] file]	Export basic print queue configuration
806237Sjacobs					to a file.
816237Sjacobs  $cmd [-i[mport] file]	Import basic print queue configuration
826237Sjacobs					from a file.
836237SjacobsEOF
846237Sjacobs	exit(1);
856237Sjacobs}
866237Sjacobs
876237Sjacobssub svcprop {
886237Sjacobs	local ($fmri, $property) = @_;
896237Sjacobs	my $FH;
906237Sjacobs
916237Sjacobs	open($FH, "$SVCPROP -C -p $property $fmri 2>/dev/null |");
926237Sjacobs	$result = <$FH>;
936237Sjacobs	close($FH);
946237Sjacobs
956237Sjacobs	return ($result);
966237Sjacobs}
976237Sjacobs
986237Sjacobssub svccfg {
996237Sjacobs	local ($fmri, $operation) = @_;
1006237Sjacobs	my $FH;
1016237Sjacobs
1026237Sjacobs	open($FH, "$SVCCFG -s $fmri \"$operation\" 2>/dev/null |");
1036237Sjacobs	$result = <$FH>;
1046237Sjacobs	close($FH);
1056237Sjacobs
1066237Sjacobs	return ($result);
1076237Sjacobs}
1086237Sjacobs
1096237Sjacobssub svcadm {
1106237Sjacobs	local ($operation, @fmris) = @_;
1116237Sjacobs
1126237Sjacobs	system("$SVCADM $operation -s @fmris");
1136237Sjacobs}
1146237Sjacobs
1156237Sjacobs
1166237Sjacobssub print_service {
1176237Sjacobs	my $service;
1186237Sjacobs
1196237Sjacobs	$service = svcprop("$SVC_CUPS_SCHEDULER:default", "general/active");
1206237Sjacobs	($service =~ /true/) && ($service = 'cups') || ($service = 'lp');
1216237Sjacobs
1226237Sjacobs	return ($service);
1236237Sjacobs}
1246237Sjacobs
1256237Sjacobssub print_command {
1266237Sjacobs	local($command, @av) = @_;
1276237Sjacobs	my $service = print_service();
1286237Sjacobs
1296237Sjacobs	if (!defined($service)) {
1306237Sjacobs		fatal("failed to detect active print service: $!\n");
1316237Sjacobs	}
1326237Sjacobs
1336237Sjacobs	if (! -d "/usr/lib/$service/bin") {
1346237Sjacobs		fatal("print service: $service is not installed\n");
1356237Sjacobs	}
1366237Sjacobs
1376237Sjacobs	my $executable = "/usr/lib/$service/bin/$command";
1386237Sjacobs	# CUPS has it's own names for enable and disable
1396237Sjacobs	($command =~ /(en|dis)able/) && ($service eq 'cups') &&
1406237Sjacobs		(! -x $executable) &&
1416237Sjacobs		($executable = "/usr/lib/$service/bin/$service$command");
1426237Sjacobs
1436237Sjacobs	if (! -x $executable) {
1446237Sjacobs		fatal("$command is not available from $service print service\n");
1456237Sjacobs	}
1466237Sjacobs
1476237Sjacobs	exec($executable, @ARGV);
1486237Sjacobs}
1496237Sjacobs
1506237Sjacobssub export_print_queues {
1516237Sjacobs	local ($path) = @_;
1526237Sjacobs	my $service = print_service();
1536237Sjacobs
1546237Sjacobs	if ($service eq 'lp') {
1556237Sjacobs		my $FH, $DFH;
1566237Sjacobs
1576237Sjacobs		open($FH, ">$path");
1586237Sjacobs		open($DFH, "$LPSTAT -v|");
1596237Sjacobs		while (<$DFH>) {
1606237Sjacobs			if (/device for (.+): (.+)/) {
1616237Sjacobs				my $EFH;
1626237Sjacobs
1636237Sjacobs				print $FH "<Printer $1>\nDeviceURI $2\n";
1646237Sjacobs				open($EFH, "$LPSTAT -p $1 -l |");
1656237Sjacobs				while (<$EFH>) {
1666237Sjacobs					(/Description: (.+)/) &&
1676237Sjacobs						print $FH "Info $1\n";
1686237Sjacobs				}
1696237Sjacobs				close($EFH);
1706237Sjacobs				print $FH "</Printer>\n";
1716237Sjacobs			}
1726237Sjacobs		}
1736237Sjacobs		close($DFH);
1746237Sjacobs		close($FH);
1756237Sjacobs	} else {
1766237Sjacobs		copy('/etc/cups/printers.conf', $path);
1776237Sjacobs	}
1786237Sjacobs}
1796237Sjacobs
1806237Sjacobssub psystem {
1816237Sjacobs	print "  @_\n";
1826237Sjacobs	system(@_);
1836237Sjacobs}
1846237Sjacobs
1856237Sjacobssub import_print_queues {
1866237Sjacobs	local ($path) = @_;
1876237Sjacobs	my $service = print_service();
1886237Sjacobs	my $FH, %printer, @options;
1896237Sjacobs
1906237Sjacobs	# store queue info in the 'active' print service
1916237Sjacobs	open($FH, "<$path");
1926237Sjacobs	while (<$FH>) {
1936237Sjacobs		if (/<Printer (.+)>/) {
1946237Sjacobs			$printer{'Printer'} = $1;
1956237Sjacobs			@options = ();
1966237Sjacobs			push(@options, "-p", $1);
1976237Sjacobs		} elsif (/([^\s]+)\s(.+)/) {
1986237Sjacobs			$printer{$1} = $2;
1996237Sjacobs			my $value = $2;
2006237Sjacobs			($1 eq 'DeviceURI') &&
2016237Sjacobs				push(@options, "-v", $value);
2026237Sjacobs			($1 eq 'Info') &&
2036237Sjacobs				push(@options, "-D", $value);
2046237Sjacobs		} elsif (/<\/Printer>/) {
2056237Sjacobs			($service eq 'lp') &&
2066237Sjacobs				push(@options, "-m", "uri");
2076237Sjacobs			print "importing $printer{'Printer'}...\n";
2086237Sjacobs			# create a queue
2096237Sjacobs			psystem($LPADMIN, @options);
2106237Sjacobs			psystem($ENABLE, $printer{'Printer'});
2116237Sjacobs			($printer{'Accepting'} eq 'Yes') &&
2126237Sjacobs				psystem($ACCEPT, $printer{'Printer'});
2136237Sjacobs			$printer = ();
2146237Sjacobs		}
2156237Sjacobs	}
2166237Sjacobs	close($FH);
2176237Sjacobs}
2186237Sjacobs
2196237Sjacobssub select_service {
2206237Sjacobs	my ($service, $migrate) = @_;
2216237Sjacobs	my $FH, $queues;
2226237Sjacobs
2236237Sjacobs	if (! -d "/usr/lib/$service/bin") {
2246237Sjacobs		fatal("print service: $service is not installed\n");
2256237Sjacobs	}
2266237Sjacobs
2276237Sjacobs	if ($migrate == 1) {
2286237Sjacobs		# export old print queue configuration (if migrating)
2296237Sjacobs		$queues = tmpnam();
2306237Sjacobs		export_print_queues($queues);
2316237Sjacobs	}
2326237Sjacobs
2336237Sjacobs	# enable/disable the services
2346237Sjacobs	if ($service eq 'cups') {
2356817Sjacobs		(-f '/etc/printers.conf') && (! -f '/etc/lp/printers.conf') &&
2366817Sjacobs			rename('/etc/printers.conf', '/etc/lp/printers.conf');
2376237Sjacobs		print("disabling LP services...\n");
2386817Sjacobs		svcadm("disable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD,
2396817Sjacobs				  $SVC_LP_PPD);
2406237Sjacobs		print("enabling CUPS services...\n");
2416237Sjacobs		svcadm("enable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD);
2426237Sjacobs		svccfg("cups/scheduler:default",
2436237Sjacobs			"setprop general/active = boolean: true");
244*10120SGhee.Teo@Sun.COM		system("pkill -USR1 -f '/desktop-print-management-applet'");
2456237Sjacobs	} else {
2466237Sjacobs		print("disabling CUPS services...\n");
2476237Sjacobs		svcadm("disable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD);
2486237Sjacobs		print("enabling LP services...\n");
2496817Sjacobs		svcadm("enable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD,
2506817Sjacobs				  $SVC_LP_PPD);
2516817Sjacobs		(-f '/etc/lp/printers.conf') &&
2526817Sjacobs			rename('/etc/lp/printers.conf', '/etc/printers.conf');
2536237Sjacobs		svccfg("cups/scheduler:default", "delprop general/active");
254*10120SGhee.Teo@Sun.COM		system("pkill -USR1 -f '/desktop-print-management-applet'");
2556237Sjacobs	}
2566237Sjacobs
2576237Sjacobs	# import the new print queue configuration (if migrating)
2586237Sjacobs	defined($queues) && import_print_queues($queues);
2596237Sjacobs}
2606237Sjacobs
2616237Sjacobssub query_service {
2626237Sjacobs	my $service = print_service();
2636237Sjacobs
2646237Sjacobs	if (!defined($service)) {
2656237Sjacobs		fatal("failed to detect active print service: $!\n");
2666237Sjacobs	}
2676237Sjacobs	print "active print service: $service\n";
2686237Sjacobs}
2696237Sjacobs
2706237Sjacobsif ($cmd eq 'print-service') {
2716237Sjacobs	my ($import_path, $export_path, $svc_name, $query, $migrate) = ();
2726237Sjacobs
2736237Sjacobs	my $res = GetOptions('q|query' => \$query, 's|set=s' => \$service,
2746237Sjacobs		'm|migrate' => \$migrate, 'e|export=s' => \$export_path,
2756237Sjacobs		'i|import=s' => \$import_path);
2766237Sjacobs
2776237Sjacobs	($res) || usage();
2786237Sjacobs
2796237Sjacobs	if (defined($import_path) && !defined($export_path) &&
2806237Sjacobs	    !defined($query) && !defined($service) && !defined($migrate)) {
2816237Sjacobs		import_print_queues($import_path);
2826237Sjacobs	} elsif (!defined($import_path) && defined($export_path) &&
2836237Sjacobs		 !defined($query) && !defined($service) && !defined($migrate)) {
2846237Sjacobs		export_print_queues($export_path);
2856237Sjacobs	} elsif (!defined($import_path) && !defined($export_path) &&
2866237Sjacobs		 defined($query) && !defined($service) && !defined($migrate)) {
2876237Sjacobs		query_service();
2886237Sjacobs	} elsif (!defined($import_path) && !defined($export_path) &&
2896237Sjacobs		 !defined($query) && defined($service)) {
2906237Sjacobs		select_service($service, $migrate);
2916237Sjacobs	} else {
2926237Sjacobs		usage();
2936237Sjacobs	}
2946237Sjacobs} else {
2956237Sjacobs	print_command($cmd, @ARGV);
2966237Sjacobs}
2976237Sjacobs
2986237Sjacobsexit(0);
299