#!/usr/bin/perl
################################################################################
# #
# ext|scripts (C) 2000-2004 Pavel Novikov (pavel@ext.by) #
# #
################################################################################
################################################################################
#
# This one makes "ps(1)" and then maps pids to jails.
#
# Usage: ./jps.pl [<ps options>] [lj|long_jails] [ll|long_lines] [i|install]
#
# TODO:
#
# - sort by jail
#
#:-)
use strict;
#:)
eval
{
require Term::ReadKey;
};
#no buffer
$|=1;
#constants
my $PS_BIN="/bin/ps";
my $PS_OPTIONS;
my $DIR_PROC="/proc";
my $FILE_STATUS="status";
#data
my @lines;
my %pids;
my $pid_position=-1;
my $max_jail=length('JAIL');
#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 $O_CUT_LINES=1;
my $O_CUT_JAILS=1;
my $JAIL_DEAD="<died>";
#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 "i")||($option eq "install"))
{
system("cd /usr/ports/devel/p5-Term-ReadKey && make install");
exit(0);
}
else
{
$PS_OPTIONS=$PS_OPTIONS." ".$option;
}
}
if(!$PS_OPTIONS){$PS_OPTIONS=" -axuf";}
#open a pipe
if(open(P,$PS_BIN.$PS_OPTIONS." |"))
{
#fetch data
my $c=0;
while(<P>)
{
#fix & save
chomp($_);
my $line=$_;
push(@lines,$line);
#split data
my @line=split(/\s\s*/,&strip($line));
#header
if($c==0)
{
my $i=0;
foreach my $field (@line)
{
if($field eq 'PID')
{
$pid_position=$i;
last;
}
++$i;
}
}
#line
else
{
if($pid_position>=0)
{
my $pid=@line[$pid_position];
if(open(F,"<".$DIR_PROC."/".$pid."/".$FILE_STATUS))
{
while(<F>)
{
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\n";
}
else
{
$f="%".$max_jail."s %s\n";
}
#output
my $i=0;
foreach my $line (@lines)
{
my @data=split(/\s\s*/,&strip($line));
printf($f,($i==0)?'JAIL':$pids{$data[$pid_position]},$line);
++$i;
}
}
syntax highlighted by Code2HTML, v. 0.9.1