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