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'; 62*6817Sjacobsmy $SVC_LP_PPD = 'print/ppd-cache-update'; 636237Sjacobsmy $SVC_CUPS_SCHEDULER = 'cups/scheduler'; 646237Sjacobsmy $SVC_CUPS_LPD = 'cups/in-lpd'; 656237Sjacobs 666237Sjacobssub fatal { 676237Sjacobs print STDERR @_; 686237Sjacobs exit(1); 696237Sjacobs} 706237Sjacobs 716237Sjacobssub usage { 726237Sjacobs print STDERR <<EOF ; 736237SjacobsUsage: 746237Sjacobs $cmd [-s[et] service [-m]] Select the \"active\" print service, 756237Sjacobs optionally migrating basic print queue 766237Sjacobs configuration. 776237Sjacobs $cmd [-q[uery]] Display the "active" print service. 786237Sjacobs $cmd [-e[xport] file] Export basic print queue configuration 796237Sjacobs to a file. 806237Sjacobs $cmd [-i[mport] file] Import basic print queue configuration 816237Sjacobs from a file. 826237SjacobsEOF 836237Sjacobs exit(1); 846237Sjacobs} 856237Sjacobs 866237Sjacobssub svcprop { 876237Sjacobs local ($fmri, $property) = @_; 886237Sjacobs my $FH; 896237Sjacobs 906237Sjacobs open($FH, "$SVCPROP -C -p $property $fmri 2>/dev/null |"); 916237Sjacobs $result = <$FH>; 926237Sjacobs close($FH); 936237Sjacobs 946237Sjacobs return ($result); 956237Sjacobs} 966237Sjacobs 976237Sjacobssub svccfg { 986237Sjacobs local ($fmri, $operation) = @_; 996237Sjacobs my $FH; 1006237Sjacobs 1016237Sjacobs open($FH, "$SVCCFG -s $fmri \"$operation\" 2>/dev/null |"); 1026237Sjacobs $result = <$FH>; 1036237Sjacobs close($FH); 1046237Sjacobs 1056237Sjacobs return ($result); 1066237Sjacobs} 1076237Sjacobs 1086237Sjacobssub svcadm { 1096237Sjacobs local ($operation, @fmris) = @_; 1106237Sjacobs 1116237Sjacobs system("$SVCADM $operation -s @fmris"); 1126237Sjacobs} 1136237Sjacobs 1146237Sjacobs 1156237Sjacobssub print_service { 1166237Sjacobs my $service; 1176237Sjacobs 1186237Sjacobs $service = svcprop("$SVC_CUPS_SCHEDULER:default", "general/active"); 1196237Sjacobs ($service =~ /true/) && ($service = 'cups') || ($service = 'lp'); 1206237Sjacobs 1216237Sjacobs return ($service); 1226237Sjacobs} 1236237Sjacobs 1246237Sjacobssub print_command { 1256237Sjacobs local($command, @av) = @_; 1266237Sjacobs my $service = print_service(); 1276237Sjacobs 1286237Sjacobs if (!defined($service)) { 1296237Sjacobs fatal("failed to detect active print service: $!\n"); 1306237Sjacobs } 1316237Sjacobs 1326237Sjacobs if (! -d "/usr/lib/$service/bin") { 1336237Sjacobs fatal("print service: $service is not installed\n"); 1346237Sjacobs } 1356237Sjacobs 1366237Sjacobs my $executable = "/usr/lib/$service/bin/$command"; 1376237Sjacobs # CUPS has it's own names for enable and disable 1386237Sjacobs ($command =~ /(en|dis)able/) && ($service eq 'cups') && 1396237Sjacobs (! -x $executable) && 1406237Sjacobs ($executable = "/usr/lib/$service/bin/$service$command"); 1416237Sjacobs 1426237Sjacobs if (! -x $executable) { 1436237Sjacobs fatal("$command is not available from $service print service\n"); 1446237Sjacobs } 1456237Sjacobs 1466237Sjacobs exec($executable, @ARGV); 1476237Sjacobs} 1486237Sjacobs 1496237Sjacobssub export_print_queues { 1506237Sjacobs local ($path) = @_; 1516237Sjacobs my $service = print_service(); 1526237Sjacobs 1536237Sjacobs if ($service eq 'lp') { 1546237Sjacobs my $FH, $DFH; 1556237Sjacobs 1566237Sjacobs open($FH, ">$path"); 1576237Sjacobs open($DFH, "$LPSTAT -v|"); 1586237Sjacobs while (<$DFH>) { 1596237Sjacobs if (/device for (.+): (.+)/) { 1606237Sjacobs my $EFH; 1616237Sjacobs 1626237Sjacobs print $FH "<Printer $1>\nDeviceURI $2\n"; 1636237Sjacobs open($EFH, "$LPSTAT -p $1 -l |"); 1646237Sjacobs while (<$EFH>) { 1656237Sjacobs (/Description: (.+)/) && 1666237Sjacobs print $FH "Info $1\n"; 1676237Sjacobs } 1686237Sjacobs close($EFH); 1696237Sjacobs print $FH "</Printer>\n"; 1706237Sjacobs } 1716237Sjacobs } 1726237Sjacobs close($DFH); 1736237Sjacobs close($FH); 1746237Sjacobs } else { 1756237Sjacobs copy('/etc/cups/printers.conf', $path); 1766237Sjacobs } 1776237Sjacobs} 1786237Sjacobs 1796237Sjacobssub psystem { 1806237Sjacobs print " @_\n"; 1816237Sjacobs system(@_); 1826237Sjacobs} 1836237Sjacobs 1846237Sjacobssub import_print_queues { 1856237Sjacobs local ($path) = @_; 1866237Sjacobs my $service = print_service(); 1876237Sjacobs my $FH, %printer, @options; 1886237Sjacobs 1896237Sjacobs # store queue info in the 'active' print service 1906237Sjacobs open($FH, "<$path"); 1916237Sjacobs while (<$FH>) { 1926237Sjacobs if (/<Printer (.+)>/) { 1936237Sjacobs $printer{'Printer'} = $1; 1946237Sjacobs @options = (); 1956237Sjacobs push(@options, "-p", $1); 1966237Sjacobs } elsif (/([^\s]+)\s(.+)/) { 1976237Sjacobs $printer{$1} = $2; 1986237Sjacobs my $value = $2; 1996237Sjacobs ($1 eq 'DeviceURI') && 2006237Sjacobs push(@options, "-v", $value); 2016237Sjacobs ($1 eq 'Info') && 2026237Sjacobs push(@options, "-D", $value); 2036237Sjacobs } elsif (/<\/Printer>/) { 2046237Sjacobs ($service eq 'lp') && 2056237Sjacobs push(@options, "-m", "uri"); 2066237Sjacobs print "importing $printer{'Printer'}...\n"; 2076237Sjacobs # create a queue 2086237Sjacobs psystem($LPADMIN, @options); 2096237Sjacobs psystem($ENABLE, $printer{'Printer'}); 2106237Sjacobs ($printer{'Accepting'} eq 'Yes') && 2116237Sjacobs psystem($ACCEPT, $printer{'Printer'}); 2126237Sjacobs $printer = (); 2136237Sjacobs } 2146237Sjacobs } 2156237Sjacobs close($FH); 2166237Sjacobs} 2176237Sjacobs 2186237Sjacobssub select_service { 2196237Sjacobs my ($service, $migrate) = @_; 2206237Sjacobs my $FH, $queues; 2216237Sjacobs 2226237Sjacobs if (! -d "/usr/lib/$service/bin") { 2236237Sjacobs fatal("print service: $service is not installed\n"); 2246237Sjacobs } 2256237Sjacobs 2266237Sjacobs if ($migrate == 1) { 2276237Sjacobs # export old print queue configuration (if migrating) 2286237Sjacobs $queues = tmpnam(); 2296237Sjacobs export_print_queues($queues); 2306237Sjacobs } 2316237Sjacobs 2326237Sjacobs # enable/disable the services 2336237Sjacobs if ($service eq 'cups') { 234*6817Sjacobs (-f '/etc/printers.conf') && (! -f '/etc/lp/printers.conf') && 235*6817Sjacobs rename('/etc/printers.conf', '/etc/lp/printers.conf'); 2366237Sjacobs print("disabling LP services...\n"); 237*6817Sjacobs svcadm("disable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD, 238*6817Sjacobs $SVC_LP_PPD); 2396237Sjacobs print("enabling CUPS services...\n"); 2406237Sjacobs svcadm("enable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD); 2416237Sjacobs svccfg("cups/scheduler:default", 2426237Sjacobs "setprop general/active = boolean: true"); 2436237Sjacobs } else { 2446237Sjacobs print("disabling CUPS services...\n"); 2456237Sjacobs svcadm("disable", $SVC_CUPS_SCHEDULER, $SVC_CUPS_LPD); 2466237Sjacobs print("enabling LP services...\n"); 247*6817Sjacobs svcadm("enable", $SVC_LP_SCHEDULER, $SVC_LP_IPP, $SVC_LP_LPD, 248*6817Sjacobs $SVC_LP_PPD); 249*6817Sjacobs (-f '/etc/lp/printers.conf') && 250*6817Sjacobs rename('/etc/lp/printers.conf', '/etc/printers.conf'); 2516237Sjacobs svccfg("cups/scheduler:default", "delprop general/active"); 2526237Sjacobs } 2536237Sjacobs 2546237Sjacobs # import the new print queue configuration (if migrating) 2556237Sjacobs defined($queues) && import_print_queues($queues); 2566237Sjacobs} 2576237Sjacobs 2586237Sjacobssub query_service { 2596237Sjacobs my $service = print_service(); 2606237Sjacobs 2616237Sjacobs if (!defined($service)) { 2626237Sjacobs fatal("failed to detect active print service: $!\n"); 2636237Sjacobs } 2646237Sjacobs print "active print service: $service\n"; 2656237Sjacobs} 2666237Sjacobs 2676237Sjacobsif ($cmd eq 'print-service') { 2686237Sjacobs my ($import_path, $export_path, $svc_name, $query, $migrate) = (); 2696237Sjacobs 2706237Sjacobs my $res = GetOptions('q|query' => \$query, 's|set=s' => \$service, 2716237Sjacobs 'm|migrate' => \$migrate, 'e|export=s' => \$export_path, 2726237Sjacobs 'i|import=s' => \$import_path); 2736237Sjacobs 2746237Sjacobs ($res) || usage(); 2756237Sjacobs 2766237Sjacobs if (defined($import_path) && !defined($export_path) && 2776237Sjacobs !defined($query) && !defined($service) && !defined($migrate)) { 2786237Sjacobs import_print_queues($import_path); 2796237Sjacobs } elsif (!defined($import_path) && defined($export_path) && 2806237Sjacobs !defined($query) && !defined($service) && !defined($migrate)) { 2816237Sjacobs export_print_queues($export_path); 2826237Sjacobs } elsif (!defined($import_path) && !defined($export_path) && 2836237Sjacobs defined($query) && !defined($service) && !defined($migrate)) { 2846237Sjacobs query_service(); 2856237Sjacobs } elsif (!defined($import_path) && !defined($export_path) && 2866237Sjacobs !defined($query) && defined($service)) { 2876237Sjacobs select_service($service, $migrate); 2886237Sjacobs } else { 2896237Sjacobs usage(); 2906237Sjacobs } 2916237Sjacobs} else { 2926237Sjacobs print_command($cmd, @ARGV); 2936237Sjacobs} 2946237Sjacobs 2956237Sjacobsexit(0); 296