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# 229622934aSjacobs# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 239622934aSjacobs# Use is subject to license terms. 249622934aSjacobs# 259622934aSjacobs# ident "%Z%%M% %I% %E% SMI" 269622934aSjacobs# 279622934aSjacobs 289622934aSjacobs# 299622934aSjacobs# This program manages the "active" print service selection. 309622934aSjacobs# If called as 'print-service', it takes one of four options. 319622934aSjacobs# Options: 329622934aSjacobs# [-s[et] service [-m]] Select the "active" print service, optionally 339622934aSjacobs# migrating basic print queue configuration. 349622934aSjacobs# [-q[uery]] Display the "active" print service. 359622934aSjacobs# [-e[xport] file] Export basic print queue configuration to 369622934aSjacobs# a file. 379622934aSjacobs# [-i[mport] file] Import basic print queue configuration from 389622934aSjacobs# a file. 399622934aSjacobs# 409622934aSjacobs# If called by any other name, it will look for a corresponding command 419622934aSjacobs# under /usr/lib/{active-service}/bin/{command} and execute that program 429622934aSjacobs# with the original arguments. 439622934aSjacobs# 449622934aSjacobs 459622934aSjacobsuse Getopt::Long; 469622934aSjacobsuse File::Basename; 479622934aSjacobsuse File::Copy; 489622934aSjacobsuse File::Temp qw/ :POSIX /; 499622934aSjacobs 509622934aSjacobsmy $cmd = basename($0); 519622934aSjacobs 529622934aSjacobsmy $LPSTAT = '/usr/bin/lpstat'; 539622934aSjacobsmy $LPADMIN = '/usr/sbin/lpadmin'; 549622934aSjacobsmy $ENABLE = '/usr/bin/enable'; 559622934aSjacobsmy $ACCEPT = '/usr/sbin/accept'; 569622934aSjacobsmy $SVCADM = '/usr/sbin/svcadm'; 579622934aSjacobsmy $SVCPROP = '/usr/bin/svcprop'; 589622934aSjacobsmy $SVCCFG = '/usr/sbin/svccfg'; 599622934aSjacobsmy $SVC_LP_SCHEDULER = 'print/server'; 609622934aSjacobsmy $SVC_LP_LPD = 'print/rfc1179'; 619622934aSjacobsmy $SVC_LP_IPP = 'print/ipp-listener'; 6236615d24Sjacobsmy $SVC_LP_PPD = 'print/ppd-cache-update'; 639622934aSjacobsmy $SVC_CUPS_SCHEDULER = 'cups/scheduler'; 649622934aSjacobsmy $SVC_CUPS_LPD = 'cups/in-lpd'; 659622934aSjacobs 669622934aSjacobssub fatal { 67*c1ecd8b9Sjacobs ($ENV{"DESKTOP_LAUNCHED"}) && 68*c1ecd8b9Sjacobs exec("/bin/zenity", "--error", "--text=@_"); 699622934aSjacobs print STDERR @_; 709622934aSjacobs exit(1); 719622934aSjacobs} 729622934aSjacobs 739622934aSjacobssub usage { 749622934aSjacobs print STDERR <<EOF ; 759622934aSjacobsUsage: 769622934aSjacobs $cmd [-s[et] service [-m]] Select the \"active\" print service, 779622934aSjacobs optionally migrating basic print queue 789622934aSjacobs configuration. 799622934aSjacobs $cmd [-q[uery]] Display the "active" print service. 809622934aSjacobs $cmd [-e[xport] file] Export basic print queue configuration 819622934aSjacobs to a file. 829622934aSjacobs $cmd [-i[mport] file] Import basic print queue configuration 839622934aSjacobs from a file. 849622934aSjacobsEOF 859622934aSjacobs exit(1); 869622934aSjacobs} 879622934aSjacobs 889622934aSjacobssub svcprop { 899622934aSjacobs local ($fmri, $property) = @_; 909622934aSjacobs my $FH; 919622934aSjacobs 929622934aSjacobs open($FH, "$SVCPROP -C -p $property $fmri 2>/dev/null |"); 939622934aSjacobs $result = <$FH>; 949622934aSjacobs close($FH); 959622934aSjacobs 969622934aSjacobs return ($result); 979622934aSjacobs} 989622934aSjacobs 999622934aSjacobssub svccfg { 1009622934aSjacobs local ($fmri, $operation) = @_; 1019622934aSjacobs my $FH; 1029622934aSjacobs 1039622934aSjacobs open($FH, "$SVCCFG -s $fmri \"$operation\" 2>/dev/null |"); 1049622934aSjacobs $result = <$FH>; 1059622934aSjacobs close($FH); 1069622934aSjacobs 1079622934aSjacobs return ($result); 1089622934aSjacobs} 1099622934aSjacobs 1109622934aSjacobssub svcadm { 1119622934aSjacobs local ($operation, @fmris) = @_; 1129622934aSjacobs 1139622934aSjacobs system("$SVCADM $operation -s @fmris"); 1149622934aSjacobs} 1159622934aSjacobs 1169622934aSjacobs 1179622934aSjacobssub print_service { 1189622934aSjacobs my $service; 1199622934aSjacobs 1209622934aSjacobs $service = svcprop("$SVC_CUPS_SCHEDULER:default", "general/active"); 1219622934aSjacobs ($service =~ /true/) && ($service = 'cups') || ($service = 'lp'); 1229622934aSjacobs 1239622934aSjacobs return ($service); 1249622934aSjacobs} 1259622934aSjacobs 1269622934aSjacobssub print_command { 1279622934aSjacobs local($command, @av) = @_; 1289622934aSjacobs my $service = print_service(); 1299622934aSjacobs 1309622934aSjacobs if (!defined($service)) { 1319622934aSjacobs fatal("failed to detect active print service: $!\n"); 1329622934aSjacobs } 1339622934aSjacobs 1349622934aSjacobs if (! -d "/usr/lib/$service/bin") { 1359622934aSjacobs fatal("print service: $service is not installed\n"); 1369622934aSjacobs } 1379622934aSjacobs 1389622934aSjacobs my $executable = "/usr/lib/$service/bin/$command"; 1399622934aSjacobs # CUPS has it's own names for enable and disable 1409622934aSjacobs ($command =~ /(en|dis)able/) && ($service eq 'cups') && 1419622934aSjacobs (! -x $executable) && 1429622934aSjacobs ($executable = "/usr/lib/$service/bin/$service$command"); 1439622934aSjacobs 1449622934aSjacobs if (! -x $executable) { 1459622934aSjacobs fatal("$command is not available from $service print service\n"); 1469622934aSjacobs } 1479622934aSjacobs 1489622934aSjacobs exec($executable, @ARGV); 1499622934aSjacobs} 1509622934aSjacobs 1519622934aSjacobssub export_print_queues { 1529622934aSjacobs local ($path) = @_; 1539622934aSjacobs my $service = print_service(); 1549622934aSjacobs 1559622934aSjacobs if ($service eq 'lp') { 1569622934aSjacobs my $FH, $DFH; 1579622934aSjacobs 1589622934aSjacobs open($FH, ">$path"); 1599622934aSjacobs open($DFH, "$LPSTAT -v|"); 1609622934aSjacobs while (<$DFH>) { 1619622934aSjacobs if (/device for (.+): (.+)/) { 1629622934aSjacobs my $EFH; 1639622934aSjacobs 1649622934aSjacobs print $FH "<Printer $1>\nDeviceURI $2\n"; 1659622934aSjacobs open($EFH, "$LPSTAT -p $1 -l |"); 1669622934aSjacobs while (<$EFH>) { 1679622934aSjacobs (/Description: (.+)/) && 1689622934aSjacobs print $FH "Info $1\n"; 1699622934aSjacobs } 1709622934aSjacobs close($EFH); 1719622934aSjacobs print $FH "</Printer>\n"; 1729622934aSjacobs } 1739622934aSjacobs } 1749622934aSjacobs close($DFH); 1759622934aSjacobs close($FH); 1769622934aSjacobs } else { 1779622934aSjacobs copy('/etc/cups/printers.conf', $path); 1789622934aSjacobs } 1799622934aSjacobs} 1809622934aSjacobs 1819622934aSjacobssub psystem { 1829622934aSjacobs print " @_\n"; 1839622934aSjacobs system(@_); 1849622934aSjacobs} 1859622934aSjacobs 1869622934aSjacobssub import_print_queues { 1879622934aSjacobs local ($path) = @_; 1889622934aSjacobs my $service = print_service(); 1899622934aSjacobs my $FH, %printer, @options; 1909622934aSjacobs 1919622934aSjacobs # store queue info in the 'active' print service 1929622934aSjacobs open($FH, "<$path"); 1939622934aSjacobs while (<$FH>) { 1949622934aSjacobs if (/<Printer (.+)>/) { 1959622934aSjacobs $printer{'Printer'} = $1; 1969622934aSjacobs @options = (); 1979622934aSjacobs push(@options, "-p", $1); 1989622934aSjacobs } elsif (/([^\s]+)\s(.+)/) { 1999622934aSjacobs $printer{$1} = $2; 2009622934aSjacobs my $value = $2; 2019622934aSjacobs ($1 eq 'DeviceURI') && 2029622934aSjacobs push(@options, "-v", $value); 2039622934aSjacobs ($1 eq 'Info') && 2049622934aSjacobs push(@options, "-D", $value); 2059622934aSjacobs } elsif (/<\/Printer>/) { 2069622934aSjacobs ($service eq 'lp') && 2079622934aSjacobs push(@options, "-m", "uri"); 2089622934aSjacobs print "importing $printer{'Printer'}...\n"; 2099622934aSjacobs # create a queue 2109622934aSjacobs psystem($LPADMIN, @options); 2119622934aSjacobs psystem($ENABLE, $printer{'Printer'}); 2129622934aSjacobs ($printer{'Accepting'} eq 'Yes') && 2139622934aSjacobs psystem($ACCEPT, $printer{'Printer'}); 2149622934aSjacobs $printer = (); 2159622934aSjacobs } 2169622934aSjacobs } 2179622934aSjacobs close($FH); 2189622934aSjacobs} 2199622934aSjacobs 2209622934aSjacobssub select_service { 2219622934aSjacobs my ($service, $migrate) = @_; 2229622934aSjacobs my $FH, $queues; 2239622934aSjacobs 2249622934aSjacobs if (! -d "/usr/lib/$service/bin") { 2259622934aSjacobs fatal("print service: $service is not installed\n"); 2269622934aSjacobs } 2279622934aSjacobs 2289622934aSjacobs if ($migrate == 1) { 2299622934aSjacobs # export old print queue configuration (if migrating) 2309622934aSjacobs $queues = tmpnam(); 2319622934aSjacobs export_print_queues($queues); 2329622934aSjacobs } 2339622934aSjacobs 2349622934aSjacobs # enable/disable the services 2359622934aSjacobs if ($service eq 'cups') { 23636615d24Sjacobs (-f '/etc/printers.conf') && (! -f '/etc/lp/printers.conf') && 23736615d24Sjacobs rename('/etc/printers.conf', '/etc/lp/printers.conf'); 2389622934aSjacobs print("disabling LP services...\n"); 23936615d24Sjacobs svcadm("disable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD, 24036615d24Sjacobs $SVC_LP_PPD); 2419622934aSjacobs print("enabling CUPS services...\n"); 2429622934aSjacobs svcadm("enable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD); 2439622934aSjacobs svccfg("cups/scheduler:default", 2449622934aSjacobs "setprop general/active = boolean: true"); 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"); 2549622934aSjacobs } 2559622934aSjacobs 2569622934aSjacobs # import the new print queue configuration (if migrating) 2579622934aSjacobs defined($queues) && import_print_queues($queues); 2589622934aSjacobs} 2599622934aSjacobs 2609622934aSjacobssub query_service { 2619622934aSjacobs my $service = print_service(); 2629622934aSjacobs 2639622934aSjacobs if (!defined($service)) { 2649622934aSjacobs fatal("failed to detect active print service: $!\n"); 2659622934aSjacobs } 2669622934aSjacobs print "active print service: $service\n"; 2679622934aSjacobs} 2689622934aSjacobs 2699622934aSjacobsif ($cmd eq 'print-service') { 2709622934aSjacobs my ($import_path, $export_path, $svc_name, $query, $migrate) = (); 2719622934aSjacobs 2729622934aSjacobs my $res = GetOptions('q|query' => \$query, 's|set=s' => \$service, 2739622934aSjacobs 'm|migrate' => \$migrate, 'e|export=s' => \$export_path, 2749622934aSjacobs 'i|import=s' => \$import_path); 2759622934aSjacobs 2769622934aSjacobs ($res) || usage(); 2779622934aSjacobs 2789622934aSjacobs if (defined($import_path) && !defined($export_path) && 2799622934aSjacobs !defined($query) && !defined($service) && !defined($migrate)) { 2809622934aSjacobs import_print_queues($import_path); 2819622934aSjacobs } elsif (!defined($import_path) && defined($export_path) && 2829622934aSjacobs !defined($query) && !defined($service) && !defined($migrate)) { 2839622934aSjacobs export_print_queues($export_path); 2849622934aSjacobs } elsif (!defined($import_path) && !defined($export_path) && 2859622934aSjacobs defined($query) && !defined($service) && !defined($migrate)) { 2869622934aSjacobs query_service(); 2879622934aSjacobs } elsif (!defined($import_path) && !defined($export_path) && 2889622934aSjacobs !defined($query) && defined($service)) { 2899622934aSjacobs select_service($service, $migrate); 2909622934aSjacobs } else { 2919622934aSjacobs usage(); 2929622934aSjacobs } 2939622934aSjacobs} else { 2949622934aSjacobs print_command($cmd, @ARGV); 2959622934aSjacobs} 2969622934aSjacobs 2979622934aSjacobsexit(0); 298