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'; 62*36615d24Sjacobsmy $SVC_LP_PPD = 'print/ppd-cache-update'; 639622934aSjacobsmy $SVC_CUPS_SCHEDULER = 'cups/scheduler'; 649622934aSjacobsmy $SVC_CUPS_LPD = 'cups/in-lpd'; 659622934aSjacobs 669622934aSjacobssub fatal { 679622934aSjacobs print STDERR @_; 689622934aSjacobs exit(1); 699622934aSjacobs} 709622934aSjacobs 719622934aSjacobssub usage { 729622934aSjacobs print STDERR <<EOF ; 739622934aSjacobsUsage: 749622934aSjacobs $cmd [-s[et] service [-m]] Select the \"active\" print service, 759622934aSjacobs optionally migrating basic print queue 769622934aSjacobs configuration. 779622934aSjacobs $cmd [-q[uery]] Display the "active" print service. 789622934aSjacobs $cmd [-e[xport] file] Export basic print queue configuration 799622934aSjacobs to a file. 809622934aSjacobs $cmd [-i[mport] file] Import basic print queue configuration 819622934aSjacobs from a file. 829622934aSjacobsEOF 839622934aSjacobs exit(1); 849622934aSjacobs} 859622934aSjacobs 869622934aSjacobssub svcprop { 879622934aSjacobs local ($fmri, $property) = @_; 889622934aSjacobs my $FH; 899622934aSjacobs 909622934aSjacobs open($FH, "$SVCPROP -C -p $property $fmri 2>/dev/null |"); 919622934aSjacobs $result = <$FH>; 929622934aSjacobs close($FH); 939622934aSjacobs 949622934aSjacobs return ($result); 959622934aSjacobs} 969622934aSjacobs 979622934aSjacobssub svccfg { 989622934aSjacobs local ($fmri, $operation) = @_; 999622934aSjacobs my $FH; 1009622934aSjacobs 1019622934aSjacobs open($FH, "$SVCCFG -s $fmri \"$operation\" 2>/dev/null |"); 1029622934aSjacobs $result = <$FH>; 1039622934aSjacobs close($FH); 1049622934aSjacobs 1059622934aSjacobs return ($result); 1069622934aSjacobs} 1079622934aSjacobs 1089622934aSjacobssub svcadm { 1099622934aSjacobs local ($operation, @fmris) = @_; 1109622934aSjacobs 1119622934aSjacobs system("$SVCADM $operation -s @fmris"); 1129622934aSjacobs} 1139622934aSjacobs 1149622934aSjacobs 1159622934aSjacobssub print_service { 1169622934aSjacobs my $service; 1179622934aSjacobs 1189622934aSjacobs $service = svcprop("$SVC_CUPS_SCHEDULER:default", "general/active"); 1199622934aSjacobs ($service =~ /true/) && ($service = 'cups') || ($service = 'lp'); 1209622934aSjacobs 1219622934aSjacobs return ($service); 1229622934aSjacobs} 1239622934aSjacobs 1249622934aSjacobssub print_command { 1259622934aSjacobs local($command, @av) = @_; 1269622934aSjacobs my $service = print_service(); 1279622934aSjacobs 1289622934aSjacobs if (!defined($service)) { 1299622934aSjacobs fatal("failed to detect active print service: $!\n"); 1309622934aSjacobs } 1319622934aSjacobs 1329622934aSjacobs if (! -d "/usr/lib/$service/bin") { 1339622934aSjacobs fatal("print service: $service is not installed\n"); 1349622934aSjacobs } 1359622934aSjacobs 1369622934aSjacobs my $executable = "/usr/lib/$service/bin/$command"; 1379622934aSjacobs # CUPS has it's own names for enable and disable 1389622934aSjacobs ($command =~ /(en|dis)able/) && ($service eq 'cups') && 1399622934aSjacobs (! -x $executable) && 1409622934aSjacobs ($executable = "/usr/lib/$service/bin/$service$command"); 1419622934aSjacobs 1429622934aSjacobs if (! -x $executable) { 1439622934aSjacobs fatal("$command is not available from $service print service\n"); 1449622934aSjacobs } 1459622934aSjacobs 1469622934aSjacobs exec($executable, @ARGV); 1479622934aSjacobs} 1489622934aSjacobs 1499622934aSjacobssub export_print_queues { 1509622934aSjacobs local ($path) = @_; 1519622934aSjacobs my $service = print_service(); 1529622934aSjacobs 1539622934aSjacobs if ($service eq 'lp') { 1549622934aSjacobs my $FH, $DFH; 1559622934aSjacobs 1569622934aSjacobs open($FH, ">$path"); 1579622934aSjacobs open($DFH, "$LPSTAT -v|"); 1589622934aSjacobs while (<$DFH>) { 1599622934aSjacobs if (/device for (.+): (.+)/) { 1609622934aSjacobs my $EFH; 1619622934aSjacobs 1629622934aSjacobs print $FH "<Printer $1>\nDeviceURI $2\n"; 1639622934aSjacobs open($EFH, "$LPSTAT -p $1 -l |"); 1649622934aSjacobs while (<$EFH>) { 1659622934aSjacobs (/Description: (.+)/) && 1669622934aSjacobs print $FH "Info $1\n"; 1679622934aSjacobs } 1689622934aSjacobs close($EFH); 1699622934aSjacobs print $FH "</Printer>\n"; 1709622934aSjacobs } 1719622934aSjacobs } 1729622934aSjacobs close($DFH); 1739622934aSjacobs close($FH); 1749622934aSjacobs } else { 1759622934aSjacobs copy('/etc/cups/printers.conf', $path); 1769622934aSjacobs } 1779622934aSjacobs} 1789622934aSjacobs 1799622934aSjacobssub psystem { 1809622934aSjacobs print " @_\n"; 1819622934aSjacobs system(@_); 1829622934aSjacobs} 1839622934aSjacobs 1849622934aSjacobssub import_print_queues { 1859622934aSjacobs local ($path) = @_; 1869622934aSjacobs my $service = print_service(); 1879622934aSjacobs my $FH, %printer, @options; 1889622934aSjacobs 1899622934aSjacobs # store queue info in the 'active' print service 1909622934aSjacobs open($FH, "<$path"); 1919622934aSjacobs while (<$FH>) { 1929622934aSjacobs if (/<Printer (.+)>/) { 1939622934aSjacobs $printer{'Printer'} = $1; 1949622934aSjacobs @options = (); 1959622934aSjacobs push(@options, "-p", $1); 1969622934aSjacobs } elsif (/([^\s]+)\s(.+)/) { 1979622934aSjacobs $printer{$1} = $2; 1989622934aSjacobs my $value = $2; 1999622934aSjacobs ($1 eq 'DeviceURI') && 2009622934aSjacobs push(@options, "-v", $value); 2019622934aSjacobs ($1 eq 'Info') && 2029622934aSjacobs push(@options, "-D", $value); 2039622934aSjacobs } elsif (/<\/Printer>/) { 2049622934aSjacobs ($service eq 'lp') && 2059622934aSjacobs push(@options, "-m", "uri"); 2069622934aSjacobs print "importing $printer{'Printer'}...\n"; 2079622934aSjacobs # create a queue 2089622934aSjacobs psystem($LPADMIN, @options); 2099622934aSjacobs psystem($ENABLE, $printer{'Printer'}); 2109622934aSjacobs ($printer{'Accepting'} eq 'Yes') && 2119622934aSjacobs psystem($ACCEPT, $printer{'Printer'}); 2129622934aSjacobs $printer = (); 2139622934aSjacobs } 2149622934aSjacobs } 2159622934aSjacobs close($FH); 2169622934aSjacobs} 2179622934aSjacobs 2189622934aSjacobssub select_service { 2199622934aSjacobs my ($service, $migrate) = @_; 2209622934aSjacobs my $FH, $queues; 2219622934aSjacobs 2229622934aSjacobs if (! -d "/usr/lib/$service/bin") { 2239622934aSjacobs fatal("print service: $service is not installed\n"); 2249622934aSjacobs } 2259622934aSjacobs 2269622934aSjacobs if ($migrate == 1) { 2279622934aSjacobs # export old print queue configuration (if migrating) 2289622934aSjacobs $queues = tmpnam(); 2299622934aSjacobs export_print_queues($queues); 2309622934aSjacobs } 2319622934aSjacobs 2329622934aSjacobs # enable/disable the services 2339622934aSjacobs if ($service eq 'cups') { 234*36615d24Sjacobs (-f '/etc/printers.conf') && (! -f '/etc/lp/printers.conf') && 235*36615d24Sjacobs rename('/etc/printers.conf', '/etc/lp/printers.conf'); 2369622934aSjacobs print("disabling LP services...\n"); 237*36615d24Sjacobs svcadm("disable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD, 238*36615d24Sjacobs $SVC_LP_PPD); 2399622934aSjacobs print("enabling CUPS services...\n"); 2409622934aSjacobs svcadm("enable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD); 2419622934aSjacobs svccfg("cups/scheduler:default", 2429622934aSjacobs "setprop general/active = boolean: true"); 2439622934aSjacobs } else { 2449622934aSjacobs print("disabling CUPS services...\n"); 2459622934aSjacobs svcadm("disable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD); 2469622934aSjacobs print("enabling LP services...\n"); 247*36615d24Sjacobs svcadm("enable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD, 248*36615d24Sjacobs $SVC_LP_PPD); 249*36615d24Sjacobs (-f '/etc/lp/printers.conf') && 250*36615d24Sjacobs rename('/etc/lp/printers.conf', '/etc/printers.conf'); 2519622934aSjacobs svccfg("cups/scheduler:default", "delprop general/active"); 2529622934aSjacobs } 2539622934aSjacobs 2549622934aSjacobs # import the new print queue configuration (if migrating) 2559622934aSjacobs defined($queues) && import_print_queues($queues); 2569622934aSjacobs} 2579622934aSjacobs 2589622934aSjacobssub query_service { 2599622934aSjacobs my $service = print_service(); 2609622934aSjacobs 2619622934aSjacobs if (!defined($service)) { 2629622934aSjacobs fatal("failed to detect active print service: $!\n"); 2639622934aSjacobs } 2649622934aSjacobs print "active print service: $service\n"; 2659622934aSjacobs} 2669622934aSjacobs 2679622934aSjacobsif ($cmd eq 'print-service') { 2689622934aSjacobs my ($import_path, $export_path, $svc_name, $query, $migrate) = (); 2699622934aSjacobs 2709622934aSjacobs my $res = GetOptions('q|query' => \$query, 's|set=s' => \$service, 2719622934aSjacobs 'm|migrate' => \$migrate, 'e|export=s' => \$export_path, 2729622934aSjacobs 'i|import=s' => \$import_path); 2739622934aSjacobs 2749622934aSjacobs ($res) || usage(); 2759622934aSjacobs 2769622934aSjacobs if (defined($import_path) && !defined($export_path) && 2779622934aSjacobs !defined($query) && !defined($service) && !defined($migrate)) { 2789622934aSjacobs import_print_queues($import_path); 2799622934aSjacobs } elsif (!defined($import_path) && defined($export_path) && 2809622934aSjacobs !defined($query) && !defined($service) && !defined($migrate)) { 2819622934aSjacobs export_print_queues($export_path); 2829622934aSjacobs } elsif (!defined($import_path) && !defined($export_path) && 2839622934aSjacobs defined($query) && !defined($service) && !defined($migrate)) { 2849622934aSjacobs query_service(); 2859622934aSjacobs } elsif (!defined($import_path) && !defined($export_path) && 2869622934aSjacobs !defined($query) && defined($service)) { 2879622934aSjacobs select_service($service, $migrate); 2889622934aSjacobs } else { 2899622934aSjacobs usage(); 2909622934aSjacobs } 2919622934aSjacobs} else { 2929622934aSjacobs print_command($cmd, @ARGV); 2939622934aSjacobs} 2949622934aSjacobs 2959622934aSjacobsexit(0); 296