#!/usr/bin/perl # # $Header: //guest/robert_duff/p4scripts/monitor/p4listener.pl#2 $ # $Date: 2003/12/14 $ # $Author: robert_duff $ # # Description: Server side of p4monitor.pl use strict; use Socket; my $server_port=""; my $output_html=""; my $output_xml=""; my $output=""; my $temp_file="/usr/tmp/p4l-xml-".int(rand(1000)).".tmp"; my $temp_file2="/usr/tmp/p4l-html-".int(rand(1000)).".tmp"; my $dot=0; # Variables to import from XML. my %col; my $pid; my $date; my %uptime; my %uname; my %proc_time; my %proc_cpu; my %proc_mem; my %proc_pid; my %proc_user; my %proc_client; my %proc_op; my %proc_ip; my %proc_parent; my %proc_message; my $progname; ($progname = $0) =~ s#^.*/##; my $usage = < Designates the port to listen for xml data. -html The directory and file you want to serve as a web page. -xml The directory and file you want to put the XML in. -dot Print a dot for every time the file(s) are written. USAGE my $parameter = 0; while($parameter <= $#ARGV) # For as many parameters there are, run this loop. { if($ARGV[0] eq "-h" or $ARGV[0] eq "-?" or $ARGV[0] eq "help" or $ARGV[0] eq "--help") # Print the usage information if -h was found, and then exit. { print STDERR $usage; exit 1; } elsif($ARGV[$parameter] eq "-p") { $parameter++; $server_port=$ARGV[$parameter]; } elsif($ARGV[$parameter] eq "-html") # Get the parameter for the html file, and then check to see if we can write to it. { $parameter++; $output_html=$ARGV[$parameter]; open(HTMLFILE, ">$output_html") or die "Cannot write to file $output_html: $!\n"; open(HTMLTEMP, ">$temp_file2") or die "Cannot write to file $temp_file2: $!\n"; close(HTMLFILE); close(HTMLTEMP); } elsif($ARGV[$parameter] eq "-xml") { $parameter++; $output_xml=$ARGV[$parameter]; open(XMLFILE, ">$output_xml") or die "Cannot write to file $output_xml: $!\n"; open(XMLTEMP, ">$temp_file") or die "Cannot write to file $temp_file: $!\n"; close(XMLFILE); close(XMLTEMP); } elsif($ARGV[$parameter] eq "-dot") { $dot=1; } else { die "Parameter: $ARGV[$parameter] is not recognized. Use the -h parameter for usage.\n"; } $parameter++; # On to the next parameter... } if($server_port == 0 or ($output_xml eq "" and $output_html eq "")) # If these parameters are blank, warn and exit. { if($server_port == 0) { print STDERR "Error: port must be between 1025 and 9999\n"; } if($output_xml eq "" and $output_html eq "") { print STDERR "Error: you must specify either an HTML or an XML file\n"; } print STDERR $usage; exit 1; } socket(Server, PF_INET, SOCK_STREAM, getprotobyname('tcp')); setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, 1); my $my_addr = sockaddr_in($server_port, INADDR_ANY); bind(Server, $my_addr) or die "Couldn't bind to port $server_port: $!\n"; listen(Server, SOMAXCONN) or die "Couldn't listen on port $server_port: $!\n"; print "Listening for XML data on port: $server_port\n"; while (accept(Client, Server)) # When we accept a client, do this... { $| = 1; # autoflush if($output_xml) # Let the user know you're writing to the files s/he requested. { $output=$output_xml; } elsif($output_html) { $output=$output_html; } elsif($output_html and $output_xml) { $output=$output_xml." and ".$output_html; } print "Server (local) received connection from client. Sending output to: $output\n"; while(my $input = ) # For as long as we're receiving data from a client... { if ("$input" eq "\n") # This should signify the beginning of the message. { if($dot==1) # Print a dot for every time we find the beginning of the message if -dot was a parameter. { print "."; } if ($output_xml) # If we are writing to XML, do this... { open(XMLTEMP, ">$temp_file") or die "Cannot write to file $temp_file: $!"; print XMLTEMP "\n"; } if ($output_html) # If we are writing to HTML, do this... { open(HTMLTEMP, ">$temp_file2") or die "Cannot write to file $temp_file2: $!"; print HTMLTEMP "\n\n\n\n"; print HTMLTEMP "\n\n"; print HTMLTEMP "P4 Load Snapshot\n\n\n"; print HTMLTEMP "\n\n\n\n"; print HTMLTEMP "
\n\n\n"; print HTMLTEMP "
"; print HTMLTEMP "\nPerforce Load Snapshot

\n"; print HTMLTEMP "
\n\n";
			}
		}
		elsif ("$input" eq "\n") # This should signify the end of the message.  Clean up and close files now.
		{
			if ($output_xml)
			{
				print XMLTEMP "\n";
				close(XMLTEMP);
				`mv -f $temp_file $output_xml`;
			}
			if ($output_html)
			{
				printf HTMLTEMP "Machine Name:  %-40s %s      %s\n",$uname{machine_name}, "Load Average (one minute):", $uptime{load_one};
				printf HTMLTEMP "OS Type:       %-40s %s    %s\n",$uname{os}, "Load Average (five minutes):", $uptime{load_five};
				printf HTMLTEMP "OS Release:    %-40s %s %s\n",$uname{release}, "Load Average (fifteen minutes):", $uptime{load_fifteen}; 
				printf HTMLTEMP "Date and Time: %-40s %s        %s\n\n",$date,"Machine has been up for:", $uptime{up};
				printf HTMLTEMP "%9s %7s %5s %6s %15s\@%-30s %s\n", $col{start}, $col{mem}, $col{cpu}, $col{pid}, $col{user}, $col{client}, $col{op};
				print HTMLTEMP "----------------------------------------------------------------------------------------------------------------------------------------------------\n";
				foreach my $key (keys %{proc_time})
				{
					if($proc_message{$key})
					{
						printf HTMLTEMP "%9s %7s %5s %6s %s\n", $proc_time{$key}, $proc_mem{$key}, $proc_cpu{$key}, $proc_pid{$key}, $proc_message{$key};
						delete $proc_time{$key};
						delete $proc_mem{$key};
						delete $proc_cpu{$key};
						delete $proc_pid{$key};
						delete $proc_message{$key};
					}
					else
					{
						printf HTMLTEMP "%9s %7s %5s %6s %15s\@%-30s %s\n", $proc_time{$key}, $proc_mem{$key}, $proc_cpu{$key}, $proc_pid{$key}, $proc_user{$key}, $proc_client{$key}, $proc_op{$key};
						delete $proc_time{$key};
						delete $proc_mem{$key};
						delete $proc_cpu{$key};
						delete $proc_pid{$key};
						delete $proc_user{$key};
						delete $proc_client{$key};
						delete $proc_op{$key};
					}
				}
				print HTMLTEMP "\n
\n
\n\n\n"; close(HTMLTEMP); `mv -f $temp_file2 $output_html`; } } else # This takes care of everything in between the beginning and the end. { if ($output_xml) # If we want XML, just print what we have, because it's already in XML. { print XMLTEMP $input; } if ($output_html) # If we want HTML, we have to do some fancy work. { chomp($input); $input =~ s#\s*(<\S*>)\s*(.*)\s*()\s*#$1$2$3#; $input =~ s#(<\S*>.*)\s+()#$1$2#; # Strip off the trailing spaces # Please excuse my change in formatting here. These if statements took too many lines for my taste. if ($input =~ //) { $col{start} = $input; $col{start} =~ s#(\S*)#$1#; } if ($input =~ //) { $col{mem} = $input; $col{mem} =~ s#(\S*)#$1#; } if ($input =~ //) { $col{cpu} = $input; $col{cpu} =~ s#(\S*)#$1#; } if ($input =~ //) { $col{pid} = $input; $col{pid} =~ s#(\S*)#$1#; } if ($input =~ //) { $col{user} = $input; $col{user} =~ s#(\S*)#$1#; } if ($input =~ //) { $col{client} = $input; $col{client} =~ s#(\S*)#$1#; } if ($input =~ //) { $col{op} = $input; $col{op} =~ s#(.*)#$1#; } if ($input =~ //) { $uptime{up} = $input; $uptime{up} =~ s#(.*)#$1#; } if ($input =~ //) { $uptime{load_fifteen} = $input; $uptime{load_fifteen} =~ s#(\S*)#$1#; } if ($input =~ //) { $uptime{load_five} = $input; $uptime{load_five} =~ s#(\S*)#$1#; } if ($input =~ //) { $uptime{load_one} = $input; $uptime{load_one} =~ s#(\S*)#$1#; } if ($input =~ //) { $uname{os} = $input; $uname{os} =~ s#(\S*)#$1#; } if ($input =~ //) { $uname{machine_name} = $input; $uname{machine_name} =~ s#(\S*)#$1#; } if ($input =~ //) { $uname{release} = $input; $uname{release} =~ s#(\S*)#$1#; } if ($input =~ //) { $date = $input; $date =~ s#(.*)#$1#; } if ($input =~ /#$1#; } if ($input =~ //) { $proc_time{$pid} = $input; $proc_time{$pid} =~ s#\s*(\S*)\s*#$1#; } if ($input =~ //) { $proc_mem{$pid} = $input; $proc_mem{$pid} =~ s#\s*(\S*)\s*#$1#; } if ($input =~ //) { $proc_cpu{$pid} = $input; $proc_cpu{$pid} =~ s#\s*(\S*)\s*#$1#; } if ($input =~ //) { $proc_pid{$pid} = $input; $proc_pid{$pid} =~ s#\s*(\S*)\s*#$1#; } if ($input =~ //) { $proc_user{$pid} = $input; $proc_user{$pid} =~ s#\s*(\S*)\s*#$1#; } if ($input =~ //) { $proc_client{$pid} = $input; $proc_client{$pid} =~ s#\s*(\S*)\s*#$1#; } if ($input =~ //) { $proc_op{$pid} = $input; $proc_op{$pid} =~ s#\s*(.*)\s*#$1#; } if ($input =~ //) { $proc_ip{$pid} = $input; $proc_ip{$pid} =~ s#\s*(\S*)\s*#$1#; } if ($input =~ //) { $proc_parent{$pid} = $input; $proc_parent{$pid} =~ s#\s*(\S*)\s*#$1#; } if ($input =~ //) { $proc_message{$pid} = $input; $proc_message{$pid} =~ s#\s*(.*)\s*#$1#; } } } } print STDOUT "Client closed connection.\n"; print STDOUT "Listening for XML data on port: $server_port\n"; } close(Server); print "Server is closed.\n";