#!/usr/bin/perl ################################################################################ # # # ext|scripts (C) 2000-2004 Pavel Novikov (pavel@ext.by) # # # ################################################################################ ################################################################################ # # This one makes "top(1)" and then maps pids to jails. # # Usage: ./jtop.pl [] [lj|long_jails] [ll|long_lines] [b|batch] [] [i|install] # # TODO: # # - sort by jail # - interactive mode # #:-) use strict; #:) eval { require Term::ReadKey; }; #no buffer $|=1; #constants my $TOP_BIN="/usr/bin/top"; my $TOP_OPTIONS; my $DIR_PROC="/proc"; my $FILE_STATUS="status"; #get sizes my ($MAX_WIDTH,$MAX_HEIGHT)=(80,25); eval { ($MAX_WIDTH,$MAX_HEIGHT)=Term::ReadKey::GetTerminalSize(); }; #other defaults my $MAX_LINE_SIZE=$MAX_WIDTH; my $MAX_LINE_COUNT=$MAX_HEIGHT; my $O_CUT_LINES=1; my $O_CUT_JAILS=1; my $O_BATCH=0; my $O_DELAY=2; my $JAIL_DEAD=""; #clear sign - tricky shit my $CLEAR=`/usr/bin/clear`; my $CTL=$CLEAR; $CTL=~s;H.*$;H;gsmio; #this will kill us local($SIG{INT})=sub{$O_BATCH=1;}; #strip shit sub strip { #come on my $line=shift; #leading spacing ones $line=~s{^\s\s*(.*)$}{$1}gs; #trailing spacing ones $line=~s{^(.*)\s\s*$}{$1}gs; #add eol return($line); } #read options while(my $option=shift) { if(($option eq 'lj')||($option eq 'long_jails')) { $O_CUT_JAILS=0; } elsif(($option eq 'll')||($option eq 'long_lines')) { $O_CUT_LINES=0; } elsif(($option eq 'b')||($option eq 'batch')) { $O_BATCH=1; } elsif($option =~ '^(\d\d*)$') { $O_DELAY=$1; } elsif(($option eq "i")||($option eq "install")) { system("cd /usr/ports/devel/p5-Term-ReadKey && make install"); exit(0); } else { $TOP_OPTIONS=$TOP_OPTIONS." ".$option; } } if(!$TOP_OPTIONS){$TOP_OPTIONS=" -Stbnq";} #use only as much as we need $TOP_OPTIONS=$TOP_OPTIONS." -d1 ".($MAX_LINE_COUNT-5); #cycling for(;;) { #data my @lines; my %pids; my $pid_line=-1; my $pid_position=-1; my $max_jail=length('JAIL'); #flush data #open a pipe if(open(P,$TOP_BIN.$TOP_OPTIONS." |")) { #fetch data my $c=0; while(

) { #fix & save chomp($_); my $line=$_; push(@lines,$line); #split data my @line=split(/\s\s*/,&strip($line)); #header if($pid_position==-1) { my $i=0; foreach my $field (@line) { if($field eq 'PID') { $pid_position=$i; $pid_line=$c; last; } ++$i; } } #line else { if($pid_position>=0) { my $pid=@line[$pid_position]; if(open(F,"<".$DIR_PROC."/".$pid."/".$FILE_STATUS)) { while() { chomp($_); my @data=split(/\s\s*/,$_); my $jail=$data[$#data]; if($jail) { if($O_CUT_JAILS) { $jail=~s/^([^\.]*)\..*$/$1/gsmi; } $pids{$pid}=$jail; if(length($jail) > $max_jail){$max_jail=length($jail);} } } close(F); } else { $pids{$pid}=$JAIL_DEAD; if(length($JAIL_DEAD) > $max_jail){$max_jail=length($JAIL_DEAD);} } } } #next ++$c; } #close the pipe close(P); #make a format my $f; if($O_CUT_LINES) { $f="%".$max_jail."s %-.".($MAX_LINE_SIZE-$max_jail-1)."s"; } else { $f="%".$max_jail."s %s"; } #clear print "$CTL"; #output my $i=0; foreach my $line (@lines) { if(&strip($line)) { if(($i>=$pid_line)&&(&strip($line))) { my @data=split(/\s\s*/,&strip($line)); if($i==$pid_line){print (" " x $MAX_WIDTH)."\n";} my $o=sprintf($f,($i==$pid_line)?'JAIL':$pids{$data[$pid_position]},$line); if(length($o)<$MAX_WIDTH) { $o=$o.(" " x ($MAX_WIDTH-length($o))); } print $o."\n"; } else { my $o=sprintf($f,$line); if(length($o)<$MAX_WIDTH) { $o=$o.(" " x ($MAX_WIDTH-length($o))); } print $o."\n"; } } ++$i; if($i>$MAX_LINE_COUNT){last;} } } #check if batch if($O_BATCH){last;} #delay sleep($O_DELAY); }