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