#!/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 ""; exit(); } # Show the middle frame at startup ... if ( defined($in{'show_middle_frame'}) ) { if ( $webservers_subnets_file) { print "Other Web Servers "; ### print "debug"; } $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 "

Questions/suggestions on this web page can be directed to $email_address $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 "

"; print "   "; print "           "; print ""; print " "; 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 ""; print " location"; if (( $adminmode) || ( defined($in{'poweruser'}))) { print "   "; print "or enter optional override substring: "; } } else { print "Enter optional string to reduce number of printers displayed: "; } if ( ($adminmode) || (defined($in{'poweruser'}))) { print ""; print ""; print ""; print ""; print ""; print "
List only (fast!) queue status active/broke
"; } print "
"; &clear_window("bottom"); # Generate admin table of contents in middle frame } elsif ( defined($in{'adminsetup'})) { print ""; if ( $adminmode ) { print ""; print ""; } else { print ""; print ""; } print ""; &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 "
";
         print "\"active/broke\" printers from an \"lpq-all\" run $minutes minutes ago 
"; print "Transient Network and/or Print Server outages may result in reds
"; print "Queue Status Printer Name Description
"; print "
"; open (LPQALL,"<$lpq_all_dir/current") || ( print "Can't open $lpq_all_dir/current: $!" || die() ) ; while () { chomp (); ($color,$results,$printer) = split(" +"); printf "%s%-22s%s%s%-24s" ,"" , $results , "" ,"", "$printer"; if ( $lookup_info ) { $description = &get_shortinfo($printer); } print "
"; } close (LPQALL); } else { print "
Does not appear to be active/broke queue data available
"; } # Show mis-configured queues ... } elsif ( defined($in{'misconfigured'})) { print "
"; print "List of queues that are mis-configured"; print "

"; open (MISCONFIGURED,"<$misconfigured") || ( print "Can't open $misconfigured: $!" || die() ) ; while () { print $_; } close (MISCONFIGURED); # Check LPRng print servers } elsif ( defined($in{'checkprintservers'})) { print "
Checking status of LPRng print servers

"; printf "Print Server Status
"; open (SERVERS,"<$lprng_print_servers") || print "Can't open $lprng_print_servers: $!" ; while () { chomp($printer = $_ ); $results = `$lpc -Plp\@$printer lpd`; chomp ($results); if (( "$results" =~ "Server PID" ) || ( "$results" =~ "lpd server pid") ) { printf "%s%-16s%s" ,"" , "$printer" , "OK - $results"; } else { printf "%s%-16s%s" ,"" , "$printer", "$results"; } print "
"; } close (SERVERS); # Print a test page ... } elsif ( defined($in{'testpage'})) { print "Printing test page to $in{'printer'}
\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 ""; # Display help file } elsif ( defined($in{'show_help_'})) { open (HELP,"<$helpfile") || ( print "Can't open $helpfile: $!" || die() ); while () { 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 "
ALL Printers ($num_printers total)
"; } else { open(LOCATION,"<$locations_file") || die "Can't open $locations_file: $!"; while () { 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 "
$num_printers printers located in \"$in{'location'}\"
"; } } else { @print_printers = &grep_printers($in{'keyword'}); $num_printers = $#print_printers + 1; print "
$num_printers printers have the string \"$in{'keyword'}\" in the printer name
"; } &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 () { 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 $_

\n"; if (( $web_server ) || ( defined($in{'alek_special'}))) { print "The nearest Print Web Server to you appears to be $web_server_location (http://$web_server)

\n"; } if (defined($in{'alek_special'})) { print "WARNING: you are in some debug code here ...
"; } print "Or you can click on one of the links below for other Print Web Servers:
\n"; print "         "; print "$default_web_server_location ($default_web_server)   (DEFAULT)
\n"; foreach $web_server (@web_servers) { $web_server_location = $web_server_locations[0]; shift @web_server_locations; print "         "; print "$web_server_location (http://$web_server)
\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 ""; 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 "
$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 () { chomp(); if ( $in{'printer'} =~ /$_/ ) { print " (Direct Web Interface)"; } } close (WEB_PRINTERS); } print "
"; print "
"; print ""; print ""; print ""; if ($no_over_ride_updatetime) { print ""; } else { print "every seconds"; } $queue_is_lprng = &check_if_lprng_queue($in{'printer'}); if ( $queue_is_lprng ) { print "      "; print ""; print "" if ( $lpqlevel > -1 ); print " Queue Info"; } print "      "; print ""; if ( $adminmode ) { print "           "; if ( $queue_is_lprng ) { print ""; print "      "; print ""; print "      "; print ""; print "      "; print ""; } else { $queue_is_nt = &check_if_nt_queue($in{'printer'}); if ( $queue_is_nt ) { print "      "; print ""; print "      "; print ""; } else { print "Not a LPRng print queue - no admin commands available"; } } } print "
"; } else { if ( (defined($in{'changeupdatetime'})) && ( $in{'changeupdatetime'} >= 1 )) { # Should be a more clever way to do this than this extra re-direct ... print ""; exit(); } else { print "
$in{'printer'} Print Queue
"; print <<"EndofTEXT";
Auto update of $in{'printer'} queue status every $in{'auto'} seconds
EndofTEXT } } # Show queue status of selected printer &check_queue($in{'printer'}); } print ""; 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($_ = ); $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($_ = ); $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($_ = ); $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 () { 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 () { 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 ""; } if ( $special ) { $showqueue = 1; $showbadones = 1 if ( $special eq 2 ) ; } if ( ! $special) { if ( $showqueue ) { print "" 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 "" 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 ""; } } } else { print ""; } if (( $showbadones ) and (($color ne "green" ) ) or ( ! $showbadones)){ if ( $lookup_info ) { $description = &get_shortinfo($printer_names[0]); } if ( ! $special ) { shift @printer_names; print "" if ($html); } print "ERROR CODE AMISS on $printer - TELL ALEK" if ( ($showqueue) && ("$color" =~ "purple")); } print "" 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 "
Queue Status      " if ( $html ); print "Queue Status " if ( ! $html) ; } print "Printer Name      " if ($html); print "Printer " if ( ! $html); if ( $lookup_info ) { print "Description      " if ($html); print "Description " if ( ! $html ); } print "Aliases      " if ($html); print "Aliases " if ( ! $html ) ; print "\n"; print "
$results$printer_names[0] $printer_names[0] " if ($html); foreach (@printer_names) { print "$_"; print ", " if ( $_ ne $printer_names[$#printer_names] ); } print "
" 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($_ = ); close (INFO); if ( $html ) { print "$_ "; } else { printf "%-30s ", "$_"; } } else { if ( $html ) { print "No data available "; } else { printf "%-30s ", "No data available"; } } } else { if ( $html ) { printf "%-30s ", "No printer info dir"; } else { printf "%-30s ", "No printer info dir"; } } } } # Show extended info in bottom window sub get_longinfo{ if ( -r "$info_dir/long/@_" ) { print "
Information on printer @_
"; print "
";
      open (INFO,"<$info_dir/long/@_") ||  ( print "Can't open $info_dir/long/@_: $!" || die() ) ; 
      while () {
         print $_;
      }
      close (INFO);
      print "
"; } 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 () { 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 () { $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 ""; } # 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 "
" 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 = "$line";
            }
            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,"REMOVE  $line"); 
               } else {
                  push(@results_mod,"REMOVE  $line");
               }
            } else { 
               push(@results_mod,"        $line");
            } 
            $foundsomething = "yes";
         } else { 
            push (@results_mod,"        $line"); 
            foreach $_ (@red) { 
               if ( $line =~ $_ ) {
                  push(@results_status,"       $line"); 
                  $print_results = 1;
               }
            }
            foreach $_ (@orange) { 
               if ( $line =~ $_ ) {
                  push(@results_status,"       $line"); 
                  $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 "
" if ( $html ) ; if (($foundsomething eq "yes") && ( $lprmURLadmin) && ($adminmode ) && ($foundrank) && ( $html)) { print "REMOVE 'em ALL!"; } if (( $lpq_nt ) && (! defined($in{'check_via_nt'})) && ( ! $adminmode ) && ($foundsomething eq "yes") && ($queue_is_nt) ) { print "This is an NT Print Server Queue: Click here to see which jobs you may delete - 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 () { $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 () { 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>