#!/usr/bin/perl

# Program: execMPWcmd
# Author: Patrick Luby
# Usage: exec perl execMPWcmd -h for this program's usage

$scriptfile = "execMPWcmd.$$";
$status = 1; 

# Define an END() subprocedure to do all of our cleanup when this script
# exits.
sub END {
  unlink("$scriptfile");
  unlink("$scriptfile.open");
  unlink("$scriptfile.out");
  unlink("$scriptfile.err");
  unlink("$scriptfile.status");
}

# Trap signals and so that we get the normal END subroutine execution.
use sigtrap qw(die normal-signals);

# Check if there are any arguments to execute. If not, print a usage statement.
if ($#ARGV < 0 || $ARGV[0] eq "-h") {
  select(STDERR);
  print "\n";
  print "This command takes all of its arguments and executes it as a MPW\n";
  print "Shell command. It does this by putting the arguments into an MPW\n";
  print "script and then having the ToolServer program execute the script.\n";
  print "Ths command has the following usage:\n";
  print "     perl $0 MPW_command [MPW_argument_1] ... [MPW_argument_n]\n";
  print "\n";
  print "Notes:\n";
  print "\n";
  print "This command assumes that you have installed both the MPW Shell\n";
  print "the ToolServer programs on this machine.\n";
  print "\n";
  print "Also, this command assumes that you have made Mac OS X aware of\n";
  print "both of these programs by executing both commands immediately\n";
  print "after they are initially installed. You can make Mac OS X aware\n";
  print "of these two programs by doing the following steps:\n";
  print "  - Open the Mac OS X Finder and change its working directory to\n";
  print "    the MPW subdirectory of the MPW package that you installed.\n";
  print "  - In the Mac OS X Finder, double click on the ToolServer file.\n";
  print "    This should launch the ToolServer program inside of Mac OS 9\n.";
  print "    If Mac OS 9 is not running, it will also launch Mac OS 9.\n";
  print "  - Log out of the Mac OS X desktop and restart it by logging back\n";
  print "    in from the Mac OS X login window.\n";
  print "The above steps only need to be once for each Mac OS X user that\n";
  print "uses this script.\n";
  print "\n";
  print "Lastly, remember that Mac OS 9 can only read HFS or HFS+ file\n";
  print "systems and that a ':' is the directory separator. So, make sure\n";
  print "that any MPW commands you try to execute conform to the following\n";
  print "rules:\n";
  print "  - Make sure all path references are in Mac OS 9 format.\n";
  print "    Mac OS 9 cannot make sense out of Unix path formats.\n";
  print "  - Make sure you use the MPW Shell escape and other special\n";
  print "    characters. They are usually different that the Unix shell\n";
  print "    characters.\n";
  print "    Mac OS 9 cannot make sense out of Unix path formats.\n";
  print "  - Make sure that all path references are on an HFS or HFS+\n";
  print "    formatted disk. Otherwise, Mac OS 9 will not be able to see\n";
  print "    them.\n";
  print "\n";
  exit($status);
}

# Expand out arguments into a coherent command line. We do a for loop
# instead of using @ARGV because some arguments may have spaces in them.
for ($i = 0; $i <= $#ARGV; $i++) {
  $currentarg = "$ARGV[$i]";
  $currentarg =~ s/"/\xB6"/g;
  $currentarg =~ s/'/\xB6'/g;
  if ($currentarg  =~ /\s/) {
    $currentarg = "\"$currentarg\"";
  }
  if ($i == 0) {
    $command = "$currentarg";
  }
  else {
    $command = "$command $currentarg";
  }
}

# Put the command to exec into an MPW script file
open(SCRIPT, ">$scriptfile");
# Echo a blank line so that we know ToolServer is actually processing this
# script
print(SCRIPT "echo >> $scriptfile.err\r");
print(SCRIPT "set -e Exit 0\r");
print(SCRIPT "$command\r");
print(SCRIPT "echo {status} >> $scriptfile.status");
close(SCRIPT);

# Set type and creator of file so that it will be opened by ToolServer
if ($status = 
  system("/System/Developer/Tools/SetFile -t 'TEXT' -c 'MPSX' $scriptfile")) {
    exit($status);
}

# Execute the command
if ($status = system("/usr/bin/open $scriptfile >$scriptfile.open 2>&1")) {
  exit($status);
}

# Check if there was any output from the /usr/bin/open command. This is a
# hack that is needed because /usr/bin/open always has an exit value of 0.
if ( -s "$scriptfile.open" ) {
    print STDERR "The following errors were encountered when trying to run\n";
    print STDERR "the MPW command:\n";
    print STDERR "\n";
    print STDERR `cat $scriptfile.open`;
    print STDERR "\n";
    print STDERR "If Mac OS 9 is in the processing of starting up, wait for\n";
    print STDERR "both Mac OS 9 and ToolServer to finish loading before\n";
    print STDERR "running this program again. If that is not the case, try\n";
    print STDERR "the following steps before running this program again:\n";
    print STDERR "1. Close any running instances of the ToolServer program\n";
    print STDERR "   and the restart it by double-clicking on the ToolServer\n";
    print STDERR "   executable in the Mac OS X Finder\n";
    print STDERR "2. Close any running instances of Mac OS 9 and restart it\n";
    print STDERR "   by double-clicking on the Classic executable in the\n";
    print STDERR "   Mac OS X Finder\n";
    print STDERR "3. Log out of the Mac OS X and restart it by logging back\n";
    print STDERR "   in from the Mac OS X login window\n";
    print STDERR "\n";
    # Set status so that we know the open command was unsuccessful
    $status = 1;
    exit($status);
}

# Poll for exit status file. When it shows up, we know the script is done
$elapsedtime = 0;
$timeout = 120;
$interval = 2;
while (! -f "$scriptfile.status") {
  sleep $interval;
  $elapsedtime += $interval;
  if ($elapsedtime > $timeout && ! -f "$scriptfile.err" ) {
    print STDERR "Request timed out. It does not appear that this script is\n";
    print STDERR "being run by the ToolServer program. Run this program\n";
    print STDERR "the -h option to get instructions for setting ToolServer\n";
    print STDERR "to work with this program.\n";
    $status = 1;
    exit($status);
  }
} 
 
if (-f "$scriptfile.out") { 
  system("unset DYLD_LIBRARY_PATH ; /usr/bin/native2ascii " . "$scriptfile.out 2>/dev/null");
} 

if (-f "$scriptfile.err") {
  system("(unset DYLD_LIBRARY_PATH ; /usr/bin/native2ascii " . "$scriptfile.err" . " 2>/dev/null) >&2");
} 

open(SCRIPTSTATUS, "<$scriptfile.status");
$status = '';
while (read(SCRIPTSTATUS, $line, 1) gt 0) {
  if ("$line" eq "\r") {
    break;
  }
  $status += $line;
}
close(SCRIPTSTATUS);
$status = abs($status);

exit($status);

