#!/usr/bin/perl # Copyright (C) 2003 Enrico Scholz # based on vps by Krischan Jodies # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Wrapper for ps. Adds security context number and name # to the PID column. # # (c) 2002 krischan.jodies@sernet.de # version 1.0 # 1.1 Added error messages if ($ARGV[0] eq "--help") { exec("ps @ARGV"); exit; } $lockdir = "/var/run/vservers"; $pid_length = 5; get_server_names(); $context=get_context("self"); if ($context == -1) { print "Can not find my security context. Is this a ctx kernel?\n"; exit; } if ($context != 1) { exec("@SBINDIR@/chcontext --silent --ctx 1 $0 @ARGV"); print "Can not execute chcontext\n"; exit; # not reached } if (! open PS, "ps @ARGV|") { print "Can not execute ps\n"; exit; } while () { chomp; push @ps,$_; } $header = shift @ps; $header =~ /(.*) PID(.+)/; $left = $1; $right = $2; $left_length = length($left); print "${left} PID CONTEXT ${right}\n"; foreach $line (@ps) { $pid = substr $line,$left_length,$pid_length; print substr $line,0,$left_length; print "$pid"; $context = get_context($pid); $context_name = getcontextname($context); printf " %-3s %-10s",$context,$context_name; print substr $line,$left_length + $pid_length; print "\n"; } exit; sub get_context { my $pid = $_[0]; $pid =~ s/ //g; open STATUS, "/proc/$pid/status"; while () { chomp; if (/s_context: (\d+)/) { close STATUS; return $1; } } close STATUS; return -1; } sub getcontextname { if (exists $name{$_[0]}) { return $name{$_[0]}; } if ($_[0] == 1) { return "ALL_PROCS"; } elsif ($_[0] == 0) { return "MAIN"; } return "UNKNOWN"; } sub get_server_names { opendir LOCKDIR, "$lockdir"; while ($file=readdir(LOCKDIR)) { if (-f "$lockdir/$file") { open FILE, "$lockdir/$file"; $file =~ s/(.+)\.ctx/$1/; while () { if (/S_CONTEXT=(\d+)/) { $name{$1} = $file; } } } } }