#!/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';

if (($#ARGV != 1) || ($ARGV[0] =~ /^-/) || ($ARGV[0] =~ /.*[\/].*/)) {
  print "Improper command option.\n\n";
  print "Usage:\n\n\tmvdir directory destdir\n\n";
  print "Wild cards and multiple directories are not allowed for security reasons.\n";
  print "Full paths for the source directory are not allowed since the path would be\nretained in the new area.\n";
  print "Currently renaming the directory during the move is not allowed.\n";
  exit(1);
}

# Get the directory.
if ($ARGV[0] =~ /(.+)/) {
  $src = $1;
}
shift(@ARGV);
if ($ARGV[0] =~ /(.+)/) {
  $dest = $1;
}
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);
}

# 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 ((-d $dest) && (-e $src) && $status == 1) {
    system("/bin/tar cf - $src | (cd $dest; /bin/tar xf -)");
    system("/bin/diff -r $src $dest > /dev/null");
    if (($? >> 8)) {
      system("/bin/rm -rf $src");
    } else {
      print "Directory moved failed: $!\n";
      system("/bin/rm -rf $dest/$src");
    }
  } else {
    print "Non-existant or no permission to directory $dest" if ((!$status) || (!-d $dest));
    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";
}
