smeserver-print-monitor/root/var/www/html/LPRng/cgi-bin/lpinfo

1195 lines
45 KiB
Plaintext
Raw Permalink Normal View History

#!/usr/bin/perl
#^^^^^^^^^^^^^^^^^^^^ Update pathname appropriately to where you have Perl installed
# And update the path below of the configuration file as appropriate.
$lpinfo_ph = "/usr/local/lprng/info/lpinfo.ph";
#-------------- Should be fairly boilerplate from here on out --------------
# lpinfo - a Web/command line "printtool" for LPRng
# Copyright 1997, 1998, 1999, 2000 by Alek Komarnitsky,
# Use and distribution of this software is covered by the GNU GPL license.
# Please see the LICENSE file and http://www.gnu.org/
# Script to provide misc. info on LPRng from the Web and command line.
# Perhaps more bloated than we need ...
$version="2.63";
$updatetime = 5 ; # Number of seconds between autoupdates
$testpageupdatetime = 3; # Number of seconds betwen auto-update on printing test page
$timeout = 35; # Number of seconds for lpq's and other system stuff to timeout
$| = 1; # This seems to be needed so system calls don't write "too fast" to STDOUT
require 5.002;
use Socket;
# These are how I color code what is returned from the lpq status
# It is used in both the "middle" and "bottom" displays, so I put it here.
@orange = ("spooling disabled" , "who knows - NT Q" , "who knows - A-T Q" , "who knows - forward" , "appears busy" , "appears waiting" );
@red = ("WARNING" , "not in printcap","printing disabled","cannot open conn", "Connection refused" , "No Access" ,"unknown printer" , "paper jam" , "P-S does not know" , "No AppleTalk printer status", "queue not enabled" , "bad queue name" , "Stopped - NT Q" , "queue is turned off" , "ink low" , "cannot chdir" , "remove media" , "lpq timed out" , "out of ink" , "(Paused)" );
@green = ("0 jobs", "no printable jobs" , "Ready" , "No Status" );
@blue = ("job" );
# Grab stuff from lpinfo.ph ...
if ( -r "$lpinfo_ph" ) {
require "$lpinfo_ph";
} else {
print "could not open $lpinfo_ph - serious error ... \n";
exit(2);
}
if ( ! ( ($lpq_all_dir) and ( -r "$lpq_all_dir/current" ) and ( ! -z "$lpq_all_dir/current") ) ) {
$lpq_all_dir = 0 ;
}
# See if we are running in a command line or as a CGI
$html = 1 if (length($ENV{GATEWAY_INTERFACE}));
$lookup_info = 1 if ( -d $info_dir );
$locations_file = 0 if ( ! -r $locations_file );
# Here we determine if hacks are allowed ... ;-)
if (( -r "/etc/resolv.conf" ) && (`cat /etc/resolv.conf` =~ "SITE.com" )) {
$site_hacks = 1;
}
if ( $html ) {
print "Content-type: text/html\n\n\n" ;
print $meta_tags if (defined($meta_tags));
&ReadParse;
# Turn on admin mode as appropriate ...
$adminmode = 1;
$_ = &get_env_variable("^SCRIPT_NAME");
if ( $_ eq $thisURLadmin ) {
$thisURL = $thisURLadmin;
$_ = &get_env_variable("^REMOTE_USER");
$adminmode = $_;
$adminmode = "nobody" if ($adminmode eq "");
}
$counter2 = &Increment_Accumulator($count_file2) if (($count_file2) && (-w $count_file2));
$lpqlevel = -1;
$lpqlevel = $in{'lpqlevel'} if (defined($in{'lpqlevel'}));
# Generate some JavaScript to fire up new mode of operation ...
if (( defined($in{'poweruseron'}) ) || ( defined($in{'normaluseron'})) || ( defined($in{'adminmodeon'})) ) {
print "<script language=JavaScript>";
if ( defined($in{'poweruseron'}) ) {
print "windowclear=window.open('$thisURL?poweruser=true','main');";
} elsif ( defined($in{'normaluseron'}) ) {
print "windowclear=window.open('$thisURL?normaluseruser=true','main');";
} elsif ( defined($in{'adminmodeon'}) ) {
print "windowclear=window.open('$thisURLadmin?adminmode=true','main');";
} else {
print "OOOPS ... got into JavaScript power/normal/admin area, but nothing started up ...";
}
print "windowclear.close();";
print "</script>";
exit();
}
# Show the middle frame at startup ...
if ( defined($in{'show_middle_frame'}) ) {
if ( $webservers_subnets_file) {
print "<a href=\"$thisURL?show_web_servers=true\" target=\"bottom\">Other Web Servers </a>";
### print "<a href=\"$thisURL?show_web_servers=true&alek_special=true\" target=\"bottom\">debug</a>";
}
$counter0 = &Get_Accumulator($count_file0) if (($count_file0) && (-r $count_file0));
$counter1 = &Increment_Accumulator($count_file1) if (($count_file1) && ( -w $count_file1));
$tempvar = "$counter1-$counter2" if (($counter1) && ($counter2));
$tempvar = "$counter0-$counter1-$counter2" if (( $counter0) && ($counter1) && ($counter2));
$_ = `uname -n`;
$tempvar = "($version: $tempvar - $_)";
print "<p>Questions/suggestions on this web page can be directed to <a href=mailto:$email_address> $email_address</a> $tempvar";
exit();
}
# show initial page
if ( (!defined($in{'location'})) && ( !defined($in{'showqueue'})) && ( !defined($in{'printer'} )) && ( !defined($in{'auto'})) && ( !defined($in{'show_web_servers'})) && ( !defined($in{'getinfo'})) ) {
$counter0 = &Increment_Accumulator($count_file0) if (($count_file0) && (-w $count_file0) && ($adminmode));
print "<form method=\"post\" action=\"$thisURL\" target=\"middle\">";
print "&nbsp; &nbsp;";
print "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;";
print "<strong><input type=\"submit\" value=\"Show\"></strong>";
print "&nbsp;";
if ( $locations_file ) {
if ( -r $locations_subnets_file) {
$_ = &get_env_variable("^REMOTE_ADDR");
if ( $_ ne "" ) {
@iplist = split(/\./,$_);
$browser_subnet = "$iplist[0]\.$iplist[1]\.$iplist[2]";
@_ = `cat $locations_subnets_file`;
foreach $_ (@_) {
chomp();
next if ( /^#/ );
next if ( /^\s*$/ );
($subnet,$bldg) = split();
$SUBNET_BLDG{$subnet} = $bldg;
}
$SUBNET_BLDG{$browser_subnet} = "NOT-FOUND" if ( ! defined ($SUBNET_BLDG{$browser_subnet}) );
}
}
@_ = `cat $locations_file`;
@locations = ();
foreach $_ (@_) {
chomp();
next if ( /^#/ );
next if ( /^\s*$/ );
($location) = split();
if ( $location eq $SUBNET_BLDG{$browser_subnet} ) {
$browser_building = $SUBNET_BLDG{$browser_subnet};
} else {
push (@locations,$location);
}
}
print "printers in ";
print "<select name=\"location\">";
print "<option>$browser_building" if ($browser_building);
foreach $_ ( @locations ) {
print "<option>$_";
}
print "</select>";
print " location";
if (( $adminmode) || ( defined($in{'poweruser'}))) {
print "&nbsp; &nbsp;";
print "or enter optional override substring: <input type=\"input\" name=\"keyword\" size=\"9\" value=\"$in{'keyword'}\">";
}
} else {
print "Enter optional string to reduce number of printers displayed: <input type=\"input\" size=\"9\" name=\"keyword\" value=\"$in{'keyword'}\">";
}
if ( ($adminmode) || (defined($in{'poweruser'}))) {
print "<table cols=5 border=0 width=95%><tr>";
print "<td></td>";
print "<td><input type=\"radio\" name=\"showqueue\" value=\"0\" checked> List only (fast!)</td>";
print "<td><input type=\"radio\" name=\"showqueue\" value=\"1\"> queue status</td>";
print "<td><input type=\"radio\" name=\"showqueue\" value=\"2\"> active/broke</td>";
print "</tr></table>";
}
print "</form>";
&clear_window("bottom");
# Generate admin table of contents in middle frame
} elsif ( defined($in{'adminsetup'})) {
print "<frameset cols=\"30%,*\">";
if ( $adminmode ) {
print "<frame src=\"$lpinfo_web_dir/admin/admintoc.html\" name=\"admintoc\">";
print "<frame src=\"$lpinfo_web_dir/admin/middle.html\" name=\"adminout\">";
} else {
print "<frame src=\"$lpinfo_web_dir/admintoc.html\" name=\"admintoc\">";
print "<frame src=\"$lpinfo_web_dir/middle.html\" name=\"adminout\">";
}
print "</frameset>";
&clear_window("bottom");
# Various lpc commands ...
} elsif ( (defined($in{'lpc_restart'})) || (defined($in{'lpc_release'})) || (defined($in{'lpc_enable'})) || (defined($in{'lpc_disable'})) || (defined($in{'lpc_pause'})) || (defined($in{'lpc_resume'})) ) {
if ($adminmode ) {
$_ = &get_env_variable("^REMOTE_ADDR");
if ( $_ ne "" ) {
@iplist = split(/\./,$_);
$ip = pack('C4',@iplist);
$browserhost = gethostbyaddr($ip,AF_INET);
}
$browserhost = &get_env_variable("^REMOTE_ADDR") if ( $browserhost eq "" );
if (defined($in{'lpc_restart'})) {
$lpc_options = "kill";
} elsif (defined($in{'lpc_release'})) {
$lpc_options = "release";
} elsif (defined($in{'lpc_enable'})) {
$lpc_options = "enable";
} elsif (defined($in{'lpc_disable'})) {
$lpc_options = "disable";
} elsif (defined($in{'lpc_pause'})) {
$lpc_options = "PA";
} elsif (defined($in{'lpc_resume'})) {
$lpc_options = "RE";
} else {
print "Could not figure out option to pass to lpc ...";
exit(2);
}
$printserver = "unix";
$queue_is_nt = &check_if_nt_queue($in{'printer'});
if ( $queue_is_nt) {
$printserver = &get_printserver($in{'printer'});
}
$_ = `$lpc_suid $adminmode $browserhost $in{'printer'} $printserver $lpc_options`;
print "$_ ";
} else {
print "You have not enabled adminmode ...";
}
# Misc. Admin fucntions/documentation ...
} elsif ( defined($in{'showactivebroke'})) {
if ( $lpq_all_dir ) {
$days = -M "$lpq_all_dir/current";
$minutes = int (60 * 24 * $days);
print "<pre><b>";
print "\"active/broke\" printers from an \"lpq-all\" run $minutes minutes ago <br>";
print "Transient Network and/or Print Server outages may result in reds<br>";
print "Queue Status Printer Name Description<br>";
print "<hr></b>";
open (LPQALL,"<$lpq_all_dir/current") || ( print "Can't open $lpq_all_dir/current: $!" || die() ) ;
while (<LPQALL>) {
chomp ();
($color,$results,$printer) = split(" +");
printf "%s%-22s%s%s%-24s" ,"<font color=$color>" , $results , "</font>" ,"<a href=\"$thisURL?printer=$printer\" target=\"bottom\">", "$printer</a>";
if ( $lookup_info ) {
$description = &get_shortinfo($printer);
}
print "<br>";
}
close (LPQALL);
} else {
print "<pre><b>Does not appear to be active/broke queue data available<br>";
}
# Show mis-configured queues ...
} elsif ( defined($in{'misconfigured'})) {
print "<pre><b><center>";
print "List of queues that are mis-configured";
print "</center><hr></b>";
open (MISCONFIGURED,"<$misconfigured") || ( print "Can't open $misconfigured: $!" || die() ) ;
while (<MISCONFIGURED>) {
print $_;
}
close (MISCONFIGURED);
# Check LPRng print servers
} elsif ( defined($in{'checkprintservers'})) {
print "<center><pre><b>Checking status of LPRng print servers</center><hr>";
printf "Print Server Status<br>";
open (SERVERS,"<$lprng_print_servers") || print "Can't open $lprng_print_servers: $!" ;
while (<SERVERS>) {
chomp($printer = $_ );
$results = `$lpc -Plp\@$printer lpd`;
chomp ($results);
if (( "$results" =~ "Server PID" ) || ( "$results" =~ "lpd server pid") ) {
printf "%s%-16s%s" ,"<font color=green>" , "$printer" , "OK - $results";
} else {
printf "%s%-16s%s" ,"<font color=red>" , "$printer", "$results";
}
print "<br>";
}
close (SERVERS);
# Print a test page ...
} elsif ( defined($in{'testpage'})) {
print "Printing test page to $in{'printer'} <br>\n";
$banner = "echo" if ( ! -x $banner );
$testpage = "/tmp/lp-testpage-$$";
open(TESTPAGE,">$testpage") || print "Can't open $testpage: $!" ;
$_ = `$banner -w40 "lpinfo"`;
print TESTPAGE "$_ \n\n";
$_ = `$banner -w40"test\ page"`;
print TESTPAGE "$_ \n\n\n\n\n";
$_ = `date`;
print TESTPAGE "printed to queue $in{'printer'} on $_ \n\n\014";
close(TESTPAGE);
system ("$lpr -h -P$in{'printer'} $testpage");
system ("rm $testpage");
print "<meta http-equiv=\"Refresh\" content=\"0 ; URL=$thisURL?printer=$in{'printer'}&auto=$testpageupdatetime\"></html>";
# Display help file
} elsif ( defined($in{'show_help_'})) {
open (HELP,"<$helpfile") || ( print "Can't open $helpfile: $!" || die() );
while (<HELP>) {
print $_;
}
close (HELP);
&clear_window("bottom");
# Update middle window (with or without (selective) queue status)
} elsif ( (defined($in{'location'})) || (defined($in{'showqueue'}))) {
@printers = &parse_printcap();
if ( $#printers == -1 ) {
print "ZERO printers returned ... something is amiss ... maybe 'cause @printers \n";
exit(2);
}
if ( (! defined($in{'keyword'})) || (( $in{'keyword'} eq "" ))) {
if ( $in{'location'} eq "ALL" ) {
@print_printers = &grep_printers("");
$num_printers = $#print_printers + 1;
print "<center>ALL Printers ($num_printers total)</center>";
} else {
open(LOCATION,"<$locations_file") || die "Can't open $locations_file: $!";
while (<LOCATION>) {
chomp();
@locations = split();
if ($in{'location'} eq $locations[0]) {
$keyword = "";
foreach $_ (@locations[1 .. $#locations]) {
if ($keyword eq "" ) {
$keyword = "$_";
} else {
$keyword = "$keyword $_";
}
}
}
}
close (LOCATION);
@print_printers = &grep_printers($keyword);
$num_printers = $#print_printers + 1;
print "<center>$num_printers printers located in \"$in{'location'}\"</center>";
}
} else {
@print_printers = &grep_printers($in{'keyword'});
$num_printers = $#print_printers + 1;
print "<center>$num_printers printers have the string \"$in{'keyword'}\" in the printer name</center>";
}
&show_printers;
&clear_window("bottom");
# Display other web servers that are available in bottom window
} elsif ( defined($in{'show_web_servers_'}) ) {
if (( $webservers_subnets_file) && ( -r $webservers_subnets_file)) {
$_ = &get_env_variable("^REMOTE_ADDR");
if ( $_ ne "" ) {
@iplist = split(/\./,$_);
$browser_subnet = "$iplist[0]\.$iplist[1]\.$iplist[2]";
open(SUBNETS,"<$webservers_subnets_file") || die "Can't open $webservers_subnets_file: $!";
while (<SUBNETS>) {
chomp();
@list = split();
push (@web_servers,$list[0]);
push (@web_server_locations,$list[1]);
foreach $entry (@list[2 .. $#list]) {
if ( $entry eq $browser_subnet ) {
$web_server = $list[0];
$web_server_location = $list[1];
last;
}
}
}
close (SUBNETS);
}
chomp($_ = `uname -n`);
print "You are browsing from $browser_subnet.$iplist[3] and connecting to the Web Server on $_<br><br>\n";
if (( $web_server ) || ( defined($in{'alek_special'}))) {
print "<strong>The nearest Print Web Server to you appears to be <a href=\"http://$web_server\" target=_parent>$web_server_location (http://$web_server)</a></strong><br><br>\n";
}
if (defined($in{'alek_special'})) {
print "<blink>WARNING:</blink> you are in some debug code here ...<br>";
}
print "Or you can click on one of the links below for other Print Web Servers:<br>\n";
print "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;";
print "<a href=\"$default_web_server\" target=_parent>$default_web_server_location ($default_web_server)</a> &nbsp; (DEFAULT)<br>\n";
foreach $web_server (@web_servers) {
$web_server_location = $web_server_locations[0];
shift @web_server_locations;
print "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;";
print "<a href=\"http://$web_server\" target=_parent>$web_server_location (http://$web_server)</a><br>\n";
}
} else {
print "Could not find webservers_subnets_file at $webservers_subnets_file ... DOOPPP";
}
# show info (bottom window) of selected printer
} elsif ( defined($in{'getinfo'}) ) {
&get_longinfo($in{'getinfo'});
# Show queue status in bottom window
} else {
if ( ( defined($in{'changelpqless'})) || ( defined ($in{'changelpqmore'}) ) ) {
# Should be a more clever way to do this than this extra re-direct ...
$lpqlevel = $in{'lpqlevel'} if ( defined($in{'lpqlevel'}));
$lpqlevel-- if ( defined($in{'changelpqless'}));
$lpqlevel++ if ( defined($in{'changelpqmore'}));
$lpqlevel = -1 if ( $lpqlevel < -1 ) ;
print "<meta http-equiv=\"Refresh\" content=\"0 ; URL=$thisURL?printer=$in{'printer'}&auto=0&lpqlevel=$lpqlevel\"></html>";
exit();
}
if ( ( !defined($in{'auto'})) || ($in{'auto'} eq 0)) {
# Show long queue status (bottom window) of selected printer and setup for STOP/START
$lpqlevel = $in{'lpqlevel'} if ( defined($in{'lpqlevel'}));
print "<center><strong><b>$in{'printer'} Print Queue";
# Allow direct access to printers with a web interface
if (( $adminmode ) && ($printers_with_web) && ( -r $printers_with_web) ) {
open(WEB_PRINTERS,"<$printers_with_web") || die "Can't open $printers_with_web: $!";
while (<WEB_PRINTERS>) {
chomp();
if ( $in{'printer'} =~ /$_/ ) {
print " <a href=\"http://$in{'printer'}\" target=\"new\">(Direct Web Interface)</a>";
}
}
close (WEB_PRINTERS);
}
print "</center></strong></b>";
print "<form method=\"post\" action=\"$thisURL?printer=$in{'printer'}&auto=$updatetime&lpqlevel=$lpqlevel\" target=bottom>";
print "<input type=\"hidden\" name=\"printer\" value=\"$in{'printer'}\">";
print "<input type=\"hidden\" name=\"auto\" value=\"$updatetime\">";
print "<input type=\"hidden\" name = \"lpqlevel\" value = \"$lpqlevel\">";
if ($no_over_ride_updatetime) {
print "<input type=\"submit\" value=\"Check Queue every $updatetime seconds\" name=\"autostop\">";
} else {
print "<input type=\"submit\" value=\"Check Queue\" name=\"autostop\">every <input type=\"input\" name=\"changeupdatetime\" size=\"2\" value=\"$updatetime\"> seconds";
}
$queue_is_lprng = &check_if_lprng_queue($in{'printer'});
if ( $queue_is_lprng ) {
print " &nbsp; &nbsp; &nbsp;";
print "<input type=\"submit\" value=\"More\" name=\"changelpqmore\">";
print "<input type=\"submit\" value=\"Less\" name=\"changelpqless\">" if ( $lpqlevel > -1 );
print " Queue Info";
}
print " &nbsp; &nbsp; &nbsp;";
print "<input type=\"submit\" name=\"testpage\" value=\"Print Test Page\">";
if ( $adminmode ) {
print " &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ";
if ( $queue_is_lprng ) {
print "<input type=\"submit\" name=\"lpc_restart\" value=\"RestartQ\">";
print " &nbsp; &nbsp; &nbsp;";
print "<input type=\"submit\" name=\"lpc_release\" value=\"ReleaseQ\">";
print " &nbsp; &nbsp; &nbsp;";
print "<input type=\"submit\" name=\"lpc_enable\" value=\"EnableQ\">";
print " &nbsp; &nbsp; &nbsp;";
print "<input type=\"submit\" name=\"lpc_disable\" value=\"DisableQ\">";
} else {
$queue_is_nt = &check_if_nt_queue($in{'printer'});
if ( $queue_is_nt ) {
print " &nbsp; &nbsp; &nbsp;";
print "<input type=\"submit\" name=\"lpc_pause\" value=\"PauseQ\">";
print " &nbsp; &nbsp; &nbsp;";
print "<input type=\"submit\" name=\"lpc_resume\" value=\"ResumeQ\">";
} else {
print "Not a LPRng print queue - no admin commands available";
}
}
}
print "</form>";
} else {
if ( (defined($in{'changeupdatetime'})) && ( $in{'changeupdatetime'} >= 1 )) {
# Should be a more clever way to do this than this extra re-direct ...
print "<meta http-equiv=\"Refresh\" content=\"0 ; URL=$thisURL?printer=$in{'printer'}&auto=$in{'changeupdatetime'}&lpqlevel=$in{'lpqlevel'}\"></html>";
exit();
} else {
print "<center><strong><b>$in{'printer'} Print Queue</center></strong></b>";
print <<"EndofTEXT";
<meta http-equiv="Refresh" content="$in{'auto'}">
<form method="post" action="$thisURL?printer=$in{'printer'}&auto=0&$lpqlevel=$in{'lpqlevel'}" target=bottom>
<input type="submit" value = "STOP" name="autostop"> Auto update of $in{'printer'} queue status every $in{'auto'} seconds
<input type="hidden" name = "printer" value = "$in{'printer'}">
<input type="hidden" name = "auto" value = "0">
<input type="hidden" name = "lpqlevel" value = "$lpqlevel">
</form>
EndofTEXT
}
}
# Show queue status of selected printer
&check_queue($in{'printer'});
}
print "</html>";
exit();
#Command line output ...
} else {
# Big hack to enable continued use of SunOS printtool at ...
# You can ignore this ... since you are using lpinfo because you *are* using LPRng! ;-)
if ( $site_hacks ) {
if ( ! ( ( -e "/etc/init.d/lprng") or ( -e "/sbin/init.d/lprng" ) or ( -e "/etc/rc.lprng" ) ) ) {
$_ = `uname`;
if ( ( "$_" =~ "SunOS" ) and ( -x "/usr/local/share/bin/printtool.SunOS4.x" ) ){
$SIG{'HUP'} = 'IGNORE';
exec "/usr/local/share/bin/printtool.SunOS4.x &";
} else {
print "command line lpinfo not available here - use the Web interface at: \n";
print " $url_address \n";
}
exit(2);
}
}
# How 'bout this for a nice little hack to get access to things via the command line!
if ( $ARGV[0] eq "special" ) {
$special = $ARGV[1];
$keyword = ".";
if (defined($ARGV[2])) {
shift @ARGV ; shift @ARGV;
$keyword = "@ARGV";
}
if (( $special eq 1 ) or ( $special eq 2 )) {
@printers = &parse_printcap();
if ( $#printers == -1 ) {
print "ZERO printers returned ... something is amiss ... maybe 'cause";
print @printers;
exit(2);
}
@print_printers = &grep_printers($keyword);
&show_printers;
} else {
print "you passed in >>> @ARGV <<< and what was special about that ...\n";
}
exit();
}
print "Command line version $version of lpinfo\n";
print "The Web version is at $url_address\n";
print "Pls send comments/questions/suggestions/etc. to $email_address\n\n";
TOP:
print "\nPls select one of the following options\n";
print "1 Show all printers\n";
print "2 Search (by keyword) for particular printers\n";
print "3 Check queue status of a particular printer\n";
print "9 Exit\n";
print "Enter choice ===> ";
chomp($_ = <STDIN>);
$selection = &sanitize($_);
if ( $selection eq 1 ) {
@printers = &parse_printcap();
if ( $#printers == -1 ) {
print "ZERO printers returned ... something is amiss ... maybe 'cause @printers \n";
exit(2);
}
@print_printers = @printers;
&show_printers;
} elsif ( $selection eq 2 ) {
print "Enter keyword to search for (multiple entries seperated by whitespace) ===> ";
chomp($_ = <STDIN>);
$keyword = &sanitize($_);
@printers = &parse_printcap();
if ( $#printers == -1 ) {
print "ZERO printers returned ... something is amiss ... maybe 'cause @printers \n";
exit(2);
}
@print_printers = &grep_printers($keyword);
&show_printers;
} elsif ( $selection eq 3 ) {
print "Enter name of queue to check status on ===> ";
chomp($_ = <STDIN>);
$queue = &sanitize($_);
&check_queue($queue);
} elsif ( $selection eq 9 ) {
print "Exiting lpinfo\n";
exit();
} else {
print "Got an illegal value of $_ ... pls pick one of the selections\n\n";
}
goto TOP;
print "Should never reach here ... \n";
}
exit();
# HTML parsing ...
sub ReadParse {
if (@_) { local (*in) = @_; }
local ($i, $loc, $key, $val);
# Read in text
if ($ENV{'REQUEST_METHOD'} eq "GET") {
$in = $ENV{'QUERY_STRING'};
} elsif ($ENV{'REQUEST_METHOD'} eq "POST") {
for ($i = 0; $i < $ENV{'CONTENT_LENGTH'}; $i++) {
$in .= getc; }
}
@in = split(/&/,$in);
foreach $i (0 .. $#in) {
# Convert plus's to spaces
$_ = $in[$i];
$in[$i] = &sanitize($_);
$in[$i] =~ s/\+/ /g;
# Convert %XX from hex numbers to alphanumeric
$in[$i] =~ s/%(..)/pack("c",hex($1))/ge;
# Split into key and value.
$loc = index($in[$i],"=");
$key = substr($in[$i],0,$loc);
$val = substr($in[$i],$loc+1);
$in{$key} .= '\0' if (defined($in{$key})); # \0 is the multiple separator
$in{$key} .= $val;
}
}
# Grope through printcap file (or NIS) to generate list of printers
sub parse_printcap {
@printers = ();
if ( $printcap ne "NIS" ) {
if ( !open (PRINTCAP,"<$printcap" )) {
$printers[1] = "could not open $printcap";
} else {
while (<PRINTCAP>) {
if ( ! ( ( $_ =~ '^\s.*$' ) or ( $_ =~ '^#.*$' ) or ( $_ =~ '^$' ))) {
s/\s*\:\\$//;
chomp();
push (@printers,$_);
}
}
close PRINTCAP;
}
} else {
# because the YP map may contain some identical entries for one
# printer (each keyed by another name) we must check for duplicates.
my(%printers, $printer);
open (PRINTCAP,"ypcat printcap|"); # return code is meaningless
# we check $? later
while (<PRINTCAP>) {
next unless /^[a-z]/i; # skip prototype entries
next if /:ss=/; # skip queue servers
s/:.*//;
chomp();
next if /all/;
($printer = $_) =~ s/\|.*//;
next if $printers{$printer};
$printers{$printer}++;
push(@printers,$_);
}
close(PRINTCAP);
$printers[1] = "could not open $printcap" if $?;
}
return (@printers);
}
# Show table of printers and possible associated queue status
sub show_printers{
$num_printers = $#print_printers + 1;
if ( $html ) {
if (defined($in{'showqueue'})) {
$showqueue = $in{'showqueue'};
$showbadones = 1 if ($showqueue eq 2 ) ;
}
print "<TABLE FRAME=\"border\" RULES=\"rows\" CELLPADDING=0 CELLSPACING=0 BORDER=0><TR>";
}
if ( $special ) {
$showqueue = 1;
$showbadones = 1 if ( $special eq 2 ) ;
}
if ( ! $special) {
if ( $showqueue ) {
print "<TD><B>Queue Status &nbsp; &nbsp; &nbsp;</B>" if ( $html );
print "Queue Status " if ( ! $html) ;
}
print "<td><b>Printer Name &nbsp; &nbsp; &nbsp;</b>" if ($html);
print "Printer " if ( ! $html);
if ( $lookup_info ) {
print "<TD><B>Description &nbsp; &nbsp; &nbsp;</B>" if ($html);
print "Description " if ( ! $html );
}
print "<TD><B>Aliases &nbsp; &nbsp; &nbsp;</B>" if ($html);
print "Aliases " if ( ! $html ) ;
print "\n";
print "</TR>" if ( $html );
}
print "No printers matched\n" if ( $num_printers eq 0 );
foreach $printer (@print_printers) {
@printer_names = split(/\|/,$printer);
if ( $html or $special) {
print "<TR>" if ( $html );
if ( $showqueue ) {
($color,$results)=&check_queue_short($printer_names[0]);
if ( $results =~ "job" ) {
$results =~ s/^.* (\d* jobs?).*$/$1/s;
$results =~ /^(.*)\s.*$/;
$results = " $results" if ($1 < 10 );
}
if ((( $showbadones ) and ($color ne "green")) or ( ! $showbadones) ){
if ( $special) {
$color = "purple" if ( "$color" =~ "purple" );
printf "%-9s%-22s%-24s" , "$color" , "$results" , "$printer_names[0]";
} else {
print "<TD><font color=$color>$results</font></TD><TD><a href=\"$thisURL?printer=$printer_names[0]\" target=\"bottom\">$printer_names[0]</a> </TD>";
}
}
} else {
print "<TD><a href=\"$thisURL?printer=$printer_names[0]\" target=\"bottom\">$printer_names[0]</a> </TD>";
}
if (( $showbadones ) and (($color ne "green" ) ) or ( ! $showbadones)){
if ( $lookup_info ) {
$description = &get_shortinfo($printer_names[0]);
}
if ( ! $special ) {
shift @printer_names;
print "<TD>" if ($html);
foreach (@printer_names) {
print "$_";
print ", " if ( $_ ne $printer_names[$#printer_names] );
}
print "</TD>" if ($html);
}
print "ERROR CODE AMISS on $printer - TELL ALEK</blink>" if ( ($showqueue) && ("$color" =~ "purple"));
}
print "</TR>" if ( $html );
} else {
printf "%-20s" ,$printer_names[0];
if ( $lookup_info ) {
$description = &get_shortinfo($printer_names[0]);
}
shift @printer_names;
foreach (@printer_names) {
print "$_ ";
}
}
if ((( $showbadones ) and ($color ne "green")) or ( ! $showbadones) ){
print "\n";
}
}
print "</TABLE>" if ( $html ) ;
}
# grep out this printers we are interested.
# Note that multiple words and regular expressions are allowed.
sub grep_printers{
my($keywords) = @_;
@print_printers = ();
if ($keywords eq "" ) {
@print_printers = @printers;
} else {
foreach $printer_full (@printers) {
NEXT_PRINTER: foreach $printer (split(/\|/,$printer_full)) {
foreach $key (split(/\s+/,$keywords)) {
if ( $printer =~ /$key/i ) {
push(@print_printers,$printer_full);
last NEXT_PRINTER;
}
}
}
}
}
return(@print_printers);
}
# Show (optional) short information available from "info" database in middle window
sub get_shortinfo{
if ( ! $special) {
if ( $lookup_info ) {
if ( -r "$info_dir/short/@_" ) {
open (INFO,"<$info_dir/short/@_") || ( print "Can't open $info_dir/short/@_: $!" || die() ) ;
chomp($_ = <INFO>);
close (INFO);
if ( $html ) {
print "<TD><a href=\"$thisURL?getinfo=@_\" target=\"bottom\">$_</a> </TD>";
} else {
printf "%-30s ", "$_";
}
} else {
if ( $html ) {
print "<TD>No data available </TD>";
} else {
printf "%-30s ", "No data available";
}
}
} else {
if ( $html ) {
printf "%-30s ", "<TD>No printer info dir</TD>";
} else {
printf "%-30s ", "No printer info dir";
}
}
}
}
# Show extended info in bottom window
sub get_longinfo{
if ( -r "$info_dir/long/@_" ) {
print "<center><u>Information on printer @_ </center></u>";
print "<pre>";
open (INFO,"<$info_dir/long/@_") || ( print "Can't open $info_dir/long/@_: $!" || die() ) ;
while (<INFO>) {
print $_;
}
close (INFO);
print "</pre>";
} else {
print "No long information available for printer @_";
}
}
# This is misc. counter stuff ... better ways to do this, but this is pretty portable ...
sub Increment_Accumulator {
local ($Accumulator) =@_;local ($accum);
open (LOG,$Accumulator) || return "-111";
while (<LOG>) { chomp($accum=$_); ++$accum;}
close LOG;
# Reset the accumulator file
open (LOG,">$Accumulator") || return "-222";
print LOG "$accum\n";
close LOG;
$accum;
}
sub Get_Accumulator {
local ($Accumulator) =@_;local ($accum);
open (LOG,$Accumulator) || die " Problem opening the accumulator file $Accumulator\n";
while (<LOG>) { $accum=$_; chomp($accum); }
close LOG;
$accum;
}
# Added per CERT advistory - send Alek EMail if you want changes here ...
sub sanitize {
# This is opened up a bit 'cause we want to allow Perl regular expressions ...
local ($OK_CHARS);
$OK_CHARS='-a-zA-Z0-9_.@=/?+[]* \s';
s/[^$OK_CHARS]/_/go;
return $_;
}
sub clear_window {
$frame = $_[0];
print "<script language=JavaScript>";
print "window.open('about:blank','$frame');";
print "</script>";
}
# Returns long queue status for bottom window
sub check_queue{
$printer = $_[0];
$number_ls = "";
for ($i = 1; $i <= $lpqlevel ; $i++ ) {
$number_ls = "l$number_ls";
}
$number_ls = "\-$number_ls" if ($number_ls ne "") ;
print "<pre>" if ( $html ) ;
if ( defined($in{'check_via_nt'})) {
$printserver = &get_printserver($printer);
$command = "$lpq_nt $printer $printserver" ;
} else {
$command = "$lpq -P$printer $number_ls" ;
}
# Here's some mildly trick code to insure we never loose the lpq ... gives it $timeout seconds max
$SIG{ALRM} = \&timed_out;
eval {
alarm ($timeout);
@results = `$command` ;
alarm(0);
};
if ($@ =~ /timed out/ ) {
@results = "lpq timed out";
}
if ( $html ) {
$_ = &get_env_variable("^REMOTE_ADDR");
if (defined($in{'check_via_nt'})) {
$browserhost = $_;
} else {
if ( $_ ne "" ) {
@iplist = split(/\./,$_);
$ip = pack('C4',@iplist);
$browserhost = gethostbyaddr($ip,AF_INET);
}
}
@results_mod = ();
@results_status = ();
$foundsomething = "no" ;
foreach $line (@results) {
next if ( $line =~ /^$/);
if (($foundrank ) || ( ( defined($in{'check_via_nt'})) && ($foundsomething eq "yes") )) {
($rank,$owner,$class,$job,$misc) = split(/\s+/,$line);
$_ = $owner;
s/^.*@(.*)\+.*$/$1/s;
tr/A-Z/a-z/;
if (( "$rank" =~ /stalled\(/ ) || ( "$rank" =~ /error/) ) {
$line = "<font color=red>$line</font>";
}
if (( $lprmURL ) && (("$class" eq "A" ) || ($queue_is_nt)) && (($_ eq $browserhost ) || ( $adminmode)) ){
if (($queue_is_nt) && ( ! (defined($in{'check_via_nt'})))) {
$job = substr($line,42,6); $job =~ s/^\s+//; $job =~ s/(\S)\s+/$1_/g;
}
if (( $lprmURLadmin) && ($adminmode )) {
push (@results_mod,"<a href=\"$lprmURLadmin?printer=$printer&jobnumber=$job$queue_is_nt\" target=\"bottom\">REMOVE</a> $line");
} else {
push(@results_mod,"<a href=\"$lprmURL?printer=$printer&jobnumber=$job$queue_is_nt\" target=\"bottom\">REMOVE</a> $line");
}
} else {
push(@results_mod," $line");
}
$foundsomething = "yes";
} else {
push (@results_mod," $line");
foreach $_ (@red) {
if ( $line =~ $_ ) {
push(@results_status," <font color=\"red\">$line</font>");
$print_results = 1;
}
}
foreach $_ (@orange) {
if ( $line =~ $_ ) {
push(@results_status," <font color=\"orange\">$line</font>");
$print_results = 1;
}
}
if (( $line =~ "printable job") && ( ! ($line =~ "no printable job"))) {
push(@results_status," $line");
$print_results = 1;
}
}
if ( $line =~ "Rank Owner/ID") {
$foundrank = 1;
@results_mod = (" $line") if ($lpqlevel eq -1);
}
if ( $line =~ "Windows NT LPD Server") {
if (! defined($in{'check_via_nt'})) {
$printserver = &get_printserver($printer);
}
$queue_is_nt = "&queue_is_nt=yes&printserver=$printserver";
}
if ( ($queue_is_nt) && ($foundsomething eq "hyphens")) {
$foundsomething = "yes";
}
if ( ($queue_is_nt) && ($line =~ "------------------")) {
$foundrank = 1;
$foundsomething = "hyphens";
}
if ( $line =~ "Queue: no printable jobs in queue") {
$foundsomething = "no" ;
}
}
if ( ( ($foundsomething eq "no")) && ( $lpqlevel eq -1) ) {
@results_mod = (" Queue is empty");
}
print @results_status if (( ($print_results) || ($foundrank)) && ($lpqlevel eq -1));
print @results_mod;
print "</pre>" if ( $html ) ;
if (($foundsomething eq "yes") && ( $lprmURLadmin) && ($adminmode ) && ($foundrank) && ( $html)) {
print "<a href=\"$lprmURLadmin?printer=$printer&jobnumber=all$queue_is_nt\" target=\"bottom\">REMOVE 'em ALL!</a>";
}
if (( $lpq_nt ) && (! defined($in{'check_via_nt'})) && ( ! $adminmode ) && ($foundsomething eq "yes") && ($queue_is_nt) ) {
print "This is an NT Print Server Queue: <a href=\"$thisURL?printer=$printer&check_via_nt=yes\">Click here to see which jobs you may delete</a> - takes a few seconds to determine";
}
} else {
print "@results\n";
}
}
sub timed_out{
die "timed out";
}
sub get_env_variable{
$env_variable = $_[0];
@env = `env`;
@array=();
push(@array,grep(/$env_variable/,@env));
chomp($_ = $array[0]);
$_ = &sanitize($_);
s/^.*=//s;
return $_;
}
sub check_if_lprng_queue{
$printer = $_[0];
$printer = "zip-nada" if ($printer eq "");
# Here's some mildly trick code to insure we never loose the lpq ... gives it $timeout seconds max
$SIG{ALRM} = \&timed_out;
eval {
alarm ($timeout);
chomp($_ = `$lpc -V -P$printer status`);
alarm(0);
};
if (( /Status\/Debug/ ) && ( ! /not in printcap/ ) ) {
return 1;
} elsif (( /Status\/\(Debug/ ) && ( ! /not in printcap/ ) ) {
return 1;
} else {
return 0;
}
}
sub check_if_nt_queue{
$printer = $_[0];
$printer = "zip-nada" if ($printer eq "");
# Here's some mildly trick code to insure we never loose the lpq ... gives it $timeout seconds max
$SIG{ALRM} = \&timed_out;
eval {
alarm ($timeout);
chomp($_ = `$lpq -P$printer`);
alarm(0);
};
if (( /Windows NT LPD Server/ ) && ( ! /not in printcap/ ) ) {
return 1;
} else {
return 0;
}
}
sub get_printserver {
$printer = $_[0];
$printserver = "not_found";
if ( $printcap ne "NIS" ) {
if ( !open (PRINTCAP,"<$printcap" )) {
$printserver = "could_not_open_$printcap";
} else {
while (<PRINTCAP>) {
$found = 1 if (/^$printer/);
if ($found) {
if (/:lp=\S+@(\S+?):/) {
$printserver = $1;
last;
}
}
}
}
close PRINTCAP;
} else {
# because the YP map may contain some identical entries for one
# printer (each keyed by another name) we must check for duplicates.
# We don't distribute via NIS, so this is not tested ...
my(%printers, $printer);
open (PRINTCAP,"ypcat printcap|"); # return code is meaningless
# we check $? later
while (<PRINTCAP>) {
next unless /^[a-z]/i; # skip prototype entries
next if /:ss=/; # skip queue servers
s/:.*//;
chomp();
next if /all/;
($printerentry = $_) =~ s/\|.*//;
$found = 1 if ($printerentry =~ /^$printer/);
if ($found) {
if (/:lp=\S+@(\S+?):/) {
$printserver = $1;
last;
}
}
}
close(PRINTCAP);
$printserver= "could_not_open_$printcap" if $?;
}
return ("$printserver");
}
# Return short queue status for middle window (and color coding as appropriate)
sub check_queue_short{
# Here's some mildly trick code to insure we never loose the lpq ... gives it $timeout seconds max
$SIG{ALRM} = \&timed_out;
eval {
alarm ($timeout);
chomp($_ = `$lpq -s -P@_`);
alarm(0);
};
if ($@ =~ /timed out/ ) {
$_ = "bogus lpq timed out";
}
# Handle bounce queues
if ( /bounce to/ ) {
@array = split();
$jobs = 0 ;
foreach $_ (@array) {
$jobs = $jobs + $job if ( /^job/ );
$job = $_
}
$_ = "bogus $jobs jobs";
}
# Here come the hacks to deal with remove non-LPRng printers ...
if ( /No entries/ ) {
$_ = "bugus 0 jobs";
}
if ( /no entries/ ) {
$_ = "bugus 0 jobs";
}
if ( /Rank Owner/ ) {
$count = s/\n/\n/g;
$count = $count - 1;
$_ = "bogus $count jobs";
}
if ( /No job currently printing/ ) {
$_ = "bogus 0 jobs";
}
if ( /No such file or directory/ ) {
$_ = "bogus cannot chdir";
}
if ( /unknown printer/ ) {
$_ = "bogus unknown printer";
}
if ( /forwarding to/ ) {
$_ = "bogus who knows - forward";
}
if (/status: busy; source: LPR/ ) {
$_ = "bogus appears busy";
}
if ( /status: waiting; source: LPR/ ) {
$_ = "bogus appears waiting";
}
if (/Active: .* printing via TCP\/IP/ ) {
$_ = "bogus appears busy";
}
if ( /Couldn\'t get AppleTalk printer status/ ) {
$_ = "No AppleTalk printer status";
}
if ( /Host name for your address.*unknown/ ) {
$_ = "bogus P-S does not know";
}
if ( /status: busy; source: EtherTalk/ ) {
$_ = "bogus who knows - A-T Q";
}
if ( /status: waiting; source: EtherTalk/ ) {
$_ = "bogus who knows - A-T Q";
}
# For wierd stuff
if ( /Ready$/ ) {
$_ = "bogus Ready";
}
if ( /^$/ ) {
$_ = "bogus No Status";
}
# Some misc. conditions we want to shorten
if ( /Your host does not have line printer access/ ) {
$_ = "bogus No Access";
}
# For NT Print Servers
if ( /Server Queue .* is Processing/ ) {
$_ = "bogus who knows - NT Q";
}
if ( /Server Queue .* is Stopped/ ) {
$_ = "bogus Stopped - NT Q";
}
if (/Windows NT LPD Server/) {
$jobcount = 0;
@lpqout = split(/\n/,$_);
foreach $line (@lpqout) {
if ( ($line =~ /Windows NT LPD Server/) || ($line =~ /^Owner/) || ($line =~ /--------------------/) || ($line =~ /^\s*$/)) {
next;
} elsif ($line =~ /Printer $printer/) {
$queuestatus = $line;
$queuestatus =~ s/^\s*Printer $printer\s*(\S*)\s*/$1/;
} else {
$jobcount++;
}
}
if ( $queuestatus =~ /^\s*$/ ) {
$_ = "bogus 0 jobs" if ($jobcount == 0);
$_ = "bogus 1 job" if ($jobcount == 1);
$_ = "bogus $jobcount jobs" if ($jobcount > 0);
} else {
$_ = "bogus $queuestatus";
}
}
($printer,$results) = split(/\s/,$_,2);
foreach $_ (@orange) { if ( $results =~ $_ ) { return("orange","$_")} };
foreach $_ (@red) { if ( $results =~ $_ ) { return("red","$_")} };
foreach $_ (@green) { if ( $results =~ $_ ) { return("green","$_")} };
foreach $_ (@blue) { if ( $results =~ $_ ) { return("blue","$results")} };
return("purple><blink","$results");
}