#!/usr/local/bin/perl5 -T

$OSH = "/usr/local/bin/osh";

# Just in case we need to clear the IFS for the system call below.
$ENV{'IFS'} = '' if $ENV{'IFS'};
$ENV{'PATH'} = '/bin:/sbin';

# Any flags?
while ($_ = $ARGV[0], /^-[fi]+$/) {
  $flags = "-f" if (/f/);
  if (/i/) {
    print "Interactive mode not allowed.\n";
    exit(1);
  }
  shift;
}

if (($#ARGV != 1) || ($ARGV[0] =~ /^-/)) {
  print "Improper command option.\n\n";
  print "Usage:\n\n\tmv [-f] file dest\n\n";
  print "Wild cards and multiple files are not allowed for security reasons.\n";
  exit(1);
}

# Get the directory.
$src = shift(@ARGV);
$dest = shift(@ARGV);

# Check for someone trying to escape things out. It's facist, but better
# safe than sorry.
if (($src =~ /["\\'`]/) || ($dest =~ /["\\'`]/)) {
  print "Special characters (ie. \", \\, ', `) are not allowed.\n";
  exit(1);
}

# Is source a full path? If not, we need to make sure it is before the
# system call below. (su will cd to/home/user if it can't access the cwd.)
if ($src =~ /^[^\/]/) {
  $cwd = `pwd`;
  chop($cwd);
  $src = $cwd . "/" . $src;
}

# Is destination a full path? If not, we need to make sure it is before the
# system call below. (su will cd to/home/user if it can't access the cwd.)
if ($dest =~ /^[^\/]/) {
  $cwd = `pwd`;
  chop($cwd);
  $dest = $cwd . "/" . $dest;
}

# Get the user, which is the owner of the parent process since the
# current process was setuid(0) before spawning off.
#
# Btw, this is how `ps` gets the info for printing as well.
# By name.
#$USER=(getpwuid((stat("/proc/". getppid))[4]))[0];
# By UID.
$USER=(getpwuid((stat("/proc/". getppid))[4]))[2];

if ($pid = fork) {
  wait;
  $status = ($? >> 8);
  if ((-e $src) && $status == 1) {
    if (defined($flags)) {
      exit(system("/bin/mv", "$flags", "$src", "$dest") >> 8);
    }
    else {
      exit(system("/bin/mv", "$src", "$dest") >> 8);
    }
  } else {
    print "Non-existant or no permission to file/directory $dest" if (!$status);
    print ".\n" if ((!$status) && (!(-e $src)));
    print "Non-existant source $src" if (!(-e $src));
    print ".\n";
    exit(1);
  }
} elsif (defined $pid) {

  # Ignore the interrupts until we get into the program.
  $SIG{'INT'} = 'IGNORE';
  $SIG{'QUIT'} = 'IGNORE';

  # Set the previously gotten UID.
  $> = $< = $USER;

  # Call osh test -w to see if they have priveledge to write where they
  # are trying to.
  $stat1 = (system("$OSH", "test", "-w \"$src\"") >> 8);
  $stat2 = (system("$OSH", "test", "-w \"$dest\"") >> 8);
  exit ($stat1 && $stat2);
} else {
  die "Can't fork: $!\n";
}
