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# 226237Sjacobs# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 236237Sjacobs# Use is subject to license terms. 246237Sjacobs# 256237Sjacobs# ident "%Z%%M% %I% %E% SMI" 266237Sjacobs# 276237Sjacobs 286237Sjacobs# 296237Sjacobs# This program manages the "active" print service selection. 306237Sjacobs# If called as 'print-service', it takes one of four options. 316237Sjacobs# Options: 326237Sjacobs# [-s[et] service [-m]] Select the "active" print service, optionally 336237Sjacobs# migrating basic print queue configuration. 346237Sjacobs# [-q[uery]] Display the "active" print service. 356237Sjacobs# [-e[xport] file] Export basic print queue configuration to 366237Sjacobs# a file. 376237Sjacobs# [-i[mport] file] Import basic print queue configuration from 386237Sjacobs# a file. 396237Sjacobs# 406237Sjacobs# If called by any other name, it will look for a corresponding command 416237Sjacobs# under /usr/lib/{active-service}/bin/{command} and execute that program 426237Sjacobs# with the original arguments. 436237Sjacobs# 446237Sjacobs 456237Sjacobsuse Getopt::Long; 466237Sjacobsuse File::Basename; 476237Sjacobsuse File::Copy; 486237Sjacobsuse File::Temp qw/ :POSIX /; 496237Sjacobs 506237Sjacobsmy $cmd = basename($0); 516237Sjacobs 526237Sjacobsmy $LPSTAT = '/usr/bin/lpstat'; 536237Sjacobsmy $LPADMIN = '/usr/sbin/lpadmin'; 546237Sjacobsmy $ENABLE = '/usr/bin/enable'; 556237Sjacobsmy $ACCEPT = '/usr/sbin/accept'; 566237Sjacobsmy $SVCADM = '/usr/sbin/svcadm'; 576237Sjacobsmy $SVCPROP = '/usr/bin/svcprop'; 586237Sjacobsmy $SVCCFG = '/usr/sbin/svccfg'; 596237Sjacobsmy $SVC_LP_SCHEDULER = 'print/server'; 606237Sjacobsmy $SVC_LP_LPD = 'print/rfc1179'; 616237Sjacobsmy $SVC_LP_IPP = 'print/ipp-listener'; 626817Sjacobsmy $SVC_LP_PPD = 'print/ppd-cache-update'; 636237Sjacobsmy $SVC_CUPS_SCHEDULER = 'cups/scheduler'; 646237Sjacobsmy $SVC_CUPS_LPD = 'cups/in-lpd'; 656237Sjacobs 666237Sjacobssub fatal { 67*7253Sjacobs ($ENV{"DESKTOP_LAUNCHED"}) && 68*7253Sjacobs exec("/bin/zenity", "--error", "--text=@_"); 696237Sjacobs print STDERR @_; 706237Sjacobs exit(1); 716237Sjacobs} 726237Sjacobs 736237Sjacobssub usage { 746237Sjacobs print STDERR <<EOF ; 756237SjacobsUsage: 766237Sjacobs $cmd [-s[et] service [-m]] Select the \"active\" print service, 776237Sjacobs optionally migrating basic print queue 786237Sjacobs configuration. 796237Sjacobs $cmd [-q[uery]] Display the "active" print service. 806237Sjacobs $cmd [-e[xport] file] Export basic print queue configuration 816237Sjacobs to a file. 826237Sjacobs $cmd [-i[mport] file] Import basic print queue configuration 836237Sjacobs from a file. 846237SjacobsEOF 856237Sjacobs exit(1); 866237Sjacobs} 876237Sjacobs 886237Sjacobssub svcprop { 896237Sjacobs local ($fmri, $property) = @_; 906237Sjacobs my $FH; 916237Sjacobs 926237Sjacobs open($FH, "$SVCPROP -C -p $property $fmri 2>/dev/null |"); 936237Sjacobs $result = <$FH>; 946237Sjacobs close($FH); 956237Sjacobs 966237Sjacobs return ($result); 976237Sjacobs} 986237Sjacobs 996237Sjacobssub svccfg { 1006237Sjacobs local ($fmri, $operation) = @_; 1016237Sjacobs my $FH; 1026237Sjacobs 1036237Sjacobs open($FH, "$SVCCFG -s $fmri \"$operation\" 2>/dev/null |"); 1046237Sjacobs $result = <$FH>; 1056237Sjacobs close($FH); 1066237Sjacobs 1076237Sjacobs return ($result); 1086237Sjacobs} 1096237Sjacobs 1106237Sjacobssub svcadm { 1116237Sjacobs local ($operation, @fmris) = @_; 1126237Sjacobs 1136237Sjacobs system("$SVCADM $operation -s @fmris"); 1146237Sjacobs} 1156237Sjacobs 1166237Sjacobs 1176237Sjacobssub print_service { 1186237Sjacobs my $service; 1196237Sjacobs 1206237Sjacobs $service = svcprop("$SVC_CUPS_SCHEDULER:default", "general/active"); 1216237Sjacobs ($service =~ /true/) && ($service = 'cups') || ($service = 'lp'); 1226237Sjacobs 1236237Sjacobs return ($service); 1246237Sjacobs} 1256237Sjacobs 1266237Sjacobssub print_command { 1276237Sjacobs local($command, @av) = @_; 1286237Sjacobs my $service = print_service(); 1296237Sjacobs 1306237Sjacobs if (!defined($service)) { 1316237Sjacobs fatal("failed to detect active print service: $!\n"); 1326237Sjacobs } 1336237Sjacobs 1346237Sjacobs if (! -d "/usr/lib/$service/bin") { 1356237Sjacobs fatal("print service: $service is not installed\n"); 1366237Sjacobs } 1376237Sjacobs 1386237Sjacobs my $executable = "/usr/lib/$service/bin/$command"; 1396237Sjacobs # CUPS has it's own names for enable and disable 1406237Sjacobs ($command =~ /(en|dis)able/) && ($service eq 'cups') && 1416237Sjacobs (! -x $executable) && 1426237Sjacobs ($executable = "/usr/lib/$service/bin/$service$command"); 1436237Sjacobs 1446237Sjacobs if (! -x $executable) { 1456237Sjacobs fatal("$command is not available from $service print service\n"); 1466237Sjacobs } 1476237Sjacobs 1486237Sjacobs exec($executable, @ARGV); 1496237Sjacobs} 1506237Sjacobs 1516237Sjacobssub export_print_queues { 1526237Sjacobs local ($path) = @_; 1536237Sjacobs my $service = print_service(); 1546237Sjacobs 1556237Sjacobs if ($service eq 'lp') { 1566237Sjacobs my $FH, $DFH; 1576237Sjacobs 1586237Sjacobs open($FH, ">$path"); 1596237Sjacobs open($DFH, "$LPSTAT -v|"); 1606237Sjacobs while (<$DFH>) { 1616237Sjacobs if (/device for (.+): (.+)/) { 1626237Sjacobs my $EFH; 1636237Sjacobs 1646237Sjacobs print $FH "<Printer $1>\nDeviceURI $2\n"; 1656237Sjacobs open($EFH, "$LPSTAT -p $1 -l |"); 1666237Sjacobs while (<$EFH>) { 1676237Sjacobs (/Description: (.+)/) && 1686237Sjacobs print $FH "Info $1\n"; 1696237Sjacobs } 1706237Sjacobs close($EFH); 1716237Sjacobs print $FH "</Printer>\n"; 1726237Sjacobs } 1736237Sjacobs } 1746237Sjacobs close($DFH); 1756237Sjacobs close($FH); 1766237Sjacobs } else { 1776237Sjacobs copy('/etc/cups/printers.conf', $path); 1786237Sjacobs } 1796237Sjacobs} 1806237Sjacobs 1816237Sjacobssub psystem { 1826237Sjacobs print " @_\n"; 1836237Sjacobs system(@_); 1846237Sjacobs} 1856237Sjacobs 1866237Sjacobssub import_print_queues { 1876237Sjacobs local ($path) = @_; 1886237Sjacobs my $service = print_service(); 1896237Sjacobs my $FH, %printer, @options; 1906237Sjacobs 1916237Sjacobs # store queue info in the 'active' print service 1926237Sjacobs open($FH, "<$path"); 1936237Sjacobs while (<$FH>) { 1946237Sjacobs if (/<Printer (.+)>/) { 1956237Sjacobs $printer{'Printer'} = $1; 1966237Sjacobs @options = (); 1976237Sjacobs push(@options, "-p", $1); 1986237Sjacobs } elsif (/([^\s]+)\s(.+)/) { 1996237Sjacobs $printer{$1} = $2; 2006237Sjacobs my $value = $2; 2016237Sjacobs ($1 eq 'DeviceURI') && 2026237Sjacobs push(@options, "-v", $value); 2036237Sjacobs ($1 eq 'Info') && 2046237Sjacobs push(@options, "-D", $value); 2056237Sjacobs } elsif (/<\/Printer>/) { 2066237Sjacobs ($service eq 'lp') && 2076237Sjacobs push(@options, "-m", "uri"); 2086237Sjacobs print "importing $printer{'Printer'}...\n"; 2096237Sjacobs # create a queue 2106237Sjacobs psystem($LPADMIN, @options); 2116237Sjacobs psystem($ENABLE, $printer{'Printer'}); 2126237Sjacobs ($printer{'Accepting'} eq 'Yes') && 2136237Sjacobs psystem($ACCEPT, $printer{'Printer'}); 2146237Sjacobs $printer = (); 2156237Sjacobs } 2166237Sjacobs } 2176237Sjacobs close($FH); 2186237Sjacobs} 2196237Sjacobs 2206237Sjacobssub select_service { 2216237Sjacobs my ($service, $migrate) = @_; 2226237Sjacobs my $FH, $queues; 2236237Sjacobs 2246237Sjacobs if (! -d "/usr/lib/$service/bin") { 2256237Sjacobs fatal("print service: $service is not installed\n"); 2266237Sjacobs } 2276237Sjacobs 2286237Sjacobs if ($migrate == 1) { 2296237Sjacobs # export old print queue configuration (if migrating) 2306237Sjacobs $queues = tmpnam(); 2316237Sjacobs export_print_queues($queues); 2326237Sjacobs } 2336237Sjacobs 2346237Sjacobs # enable/disable the services 2356237Sjacobs if ($service eq 'cups') { 2366817Sjacobs (-f '/etc/printers.conf') && (! -f '/etc/lp/printers.conf') && 2376817Sjacobs rename('/etc/printers.conf', '/etc/lp/printers.conf'); 2386237Sjacobs print("disabling LP services...\n"); 2396817Sjacobs svcadm("disable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD, 2406817Sjacobs $SVC_LP_PPD); 2416237Sjacobs print("enabling CUPS services...\n"); 2426237Sjacobs svcadm("enable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD); 2436237Sjacobs svccfg("cups/scheduler:default", 2446237Sjacobs "setprop general/active = boolean: true"); 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"); 2546237Sjacobs } 2556237Sjacobs 2566237Sjacobs # import the new print queue configuration (if migrating) 2576237Sjacobs defined($queues) && import_print_queues($queues); 2586237Sjacobs} 2596237Sjacobs 2606237Sjacobssub query_service { 2616237Sjacobs my $service = print_service(); 2626237Sjacobs 2636237Sjacobs if (!defined($service)) { 2646237Sjacobs fatal("failed to detect active print service: $!\n"); 2656237Sjacobs } 2666237Sjacobs print "active print service: $service\n"; 2676237Sjacobs} 2686237Sjacobs 2696237Sjacobsif ($cmd eq 'print-service') { 2706237Sjacobs my ($import_path, $export_path, $svc_name, $query, $migrate) = (); 2716237Sjacobs 2726237Sjacobs my $res = GetOptions('q|query' => \$query, 's|set=s' => \$service, 2736237Sjacobs 'm|migrate' => \$migrate, 'e|export=s' => \$export_path, 2746237Sjacobs 'i|import=s' => \$import_path); 2756237Sjacobs 2766237Sjacobs ($res) || usage(); 2776237Sjacobs 2786237Sjacobs if (defined($import_path) && !defined($export_path) && 2796237Sjacobs !defined($query) && !defined($service) && !defined($migrate)) { 2806237Sjacobs import_print_queues($import_path); 2816237Sjacobs } elsif (!defined($import_path) && defined($export_path) && 2826237Sjacobs !defined($query) && !defined($service) && !defined($migrate)) { 2836237Sjacobs export_print_queues($export_path); 2846237Sjacobs } elsif (!defined($import_path) && !defined($export_path) && 2856237Sjacobs defined($query) && !defined($service) && !defined($migrate)) { 2866237Sjacobs query_service(); 2876237Sjacobs } elsif (!defined($import_path) && !defined($export_path) && 2886237Sjacobs !defined($query) && defined($service)) { 2896237Sjacobs select_service($service, $migrate); 2906237Sjacobs } else { 2916237Sjacobs usage(); 2926237Sjacobs } 2936237Sjacobs} else { 2946237Sjacobs print_command($cmd, @ARGV); 2956237Sjacobs} 2966237Sjacobs 2976237Sjacobsexit(0); 298