#!/usr/bin/perl -w

use strict;
my $DEBUG = 0;

my $i;	
my $j;
my $path;
my $k;
my $oldpid = -1;
my $pid;
my $name;
my @temp;
my @temp2;

my $pscmd;
 $pscmd = "/bin/ps -auxwn |/bin/awk \'{ print \$1\"\\t\"\$2\"\\t\"\$11 }\'| \
	/bin/grep afpd";
# pscmd will print something like this
# UID	  PID	filename

my $lsofcmd = "/usr/sbin/lsof -c afpd -F tn0 |".
  "/bin/awk -F\"\\0\" \'{print \$1\"\\t\"\$2}\'";
# lsofcmd will print something like this
# REG PID /drives/hd005/Public/file

my %fhash;
my $files = \%fhash;
# files is a hash that is keyed by user PID.  The contents of the
# value is a complex structure consisting of the user name, the uid and
# gid of the user and an array of regular files that the user has open.
# Those files that have the string /lib/ in them are filtered out.


# *********************************************
# main
# *********************************************

if ($> != 0) {
	print "You must be root to run this command\n";
	exit 1;
}

if ($#ARGV gt 0) {
	print "Usage:\n";
	print "afpstatus [path]\n";
	exit 1;
}	

if ($ARGV[0]) {
	$path = $ARGV[0];
	if ($DEBUG) {
		print "$path\n";
	}
}

if (! -e '/bin/ps') {
	print "/bin/ps not found\n";
	exit 1;
}
if (! -e '/bin/awk') {
	print "/bin/awk now found\n";
	exit 1;
}
if (! -e '/bin/grep') {
	print "/bin/awk not found\n";
	exit 1;
}

@temp = `$lsofcmd`;

foreach $i (@temp) {
  chomp $i;
  if ($i =~ m/^p(\d+)/) {
    $pid = $1;
    $files->{$pid}{'files'} = [];
    if (-e "/proc/$pid/status") {
      @temp2 = `cat /proc/$pid/status`;
      foreach $j (@temp2) {
	chomp $j;
	if ($j =~ m/\s*uid.*?(\d+)$/io) {
	  $files->{$pid}{'uid'} = $1;
	  $files->{$pid}{'name'} = (getpwuid($files->{$pid}{'uid'}))[0];
	} 
	if ($j =~ m/\s*gid.*?(\d+)$/io) {
	  $files->{$pid}{'gid'} = $1;
	}
      }
    } else {
      $files->{$pid}{'uid'} = "unknown";
      $files->{$pid}{'gid'} = "unknown";
    }
  } elsif ($i =~ m/^tREG\s+n(.*)/){
    $name = $1;
    if ($name !~ m/^\/lib\// && $name !~ m/^\/usr\// && $name !~ m/^\/etc\//) {
      push(@{$files->{$pid}{'files'}}, $name);
    }
  }
}
=head
# call pscmd and keep output in @temp

@temp = `$pscmd`;

foreach $i (@temp) {
	chomp $i;
	if ($DEBUG) {print "i = $i\n";}
	@temp2 = split(/\s+/, $i);
	if ($DEBUG) {
		foreach $j (@temp2) {print "temp2: '$j'\n";}
	}
	$pid = int($temp2[1]/1);
	chomp $pid;
	if (exists $files->{$pid} && $DEBUG) {
		print "PID $pid found in file hash\n";
	}
	$files->{$pid}{'name'} = $temp2[0];
}
=cut

# OK, this is what the user sees:
print "AFPD Status\n\n";
print "User:                      PID    UID     GID  \n";
print "-----------------------------------------------\n";
@temp = keys(%{$files});
foreach $i (@temp) {
  next if ($files->{$i}{'name'} eq "root");
  printf("%-25s : %5d : %5d : %5d\n", $files->{$i}{'name'}, $i,
    $files->{$i}{'uid'}, $files->{$i}{'gid'});
}
print "\n";
print "Pid   Filename:\n";
print "---------------------\n";
foreach $i (@temp) {
  next if ($files->{$i}{'name'} eq "root");
  $k=0;
  foreach $j (@{$files->{$i}{'files'}}) {
    printf("%5d %s\n", $i, $j);
    $k++
  }
  if ($k) {print "\n";}
}
