Index: /trunk/Ohana/src/opihi/cmd.basic/quit.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.basic/quit.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/cmd.basic/quit.c	(revision 3212)
@@ -7,4 +7,5 @@
   fprintf (stderr, "Goodbye!\n");
   cleanup ();
+  fprintf (stderr, "Cleanup done!\n");
 
   state = 0;
Index: /trunk/Ohana/src/opihi/include/pcontrol.h
===================================================================
--- /trunk/Ohana/src/opihi/include/pcontrol.h	(revision 3211)
+++ /trunk/Ohana/src/opihi/include/pcontrol.h	(revision 3212)
@@ -110,4 +110,5 @@
 static char *CONNECT;  /* connection method (ssh, rsh, etc) */
 static char *PCLIENT;  /* shell on remote host (eg, pclient) */
+# define PCLIENT_PROMPT "pclient:"
 
 # define FREE(X) if (X != NULL) { free (X); }
@@ -130,4 +131,5 @@
 void AddHost (char *hostname);
 void DownHost (Host *host);
+void OffHost (Host *host);
 void DelHost (Host *host);
 int CheckSystem ();
@@ -149,5 +151,5 @@
 int GetJobOutput (Job *job, char *channel);
 int ResetJob (Job *job);
-int PclientCommand (Host *host, char *command, IOBuffer *buffer);
+int PclientCommand (Host *host, char *command, char *response, IOBuffer *buffer);
 int rconnect (char *command, char *hostname, char *shell, int *stdio);
 int CheckHost (Host *host);
Index: /trunk/Ohana/src/opihi/pclient/ChildOps.c
===================================================================
--- /trunk/Ohana/src/opihi/pclient/ChildOps.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pclient/ChildOps.c	(revision 3212)
@@ -35,15 +35,9 @@
   if (dtime < 0.0001) Nbad ++;
   if (dtime > 0.01) Nbad = 0;
-  if (Nbad > 10) {
-    fprintf (stderr, "parent shutdown\n");
-    exit (2);
-  }  
+  if (Nbad > 10) exit (2);
 
   /* this is a bit lame : we must exit if calling process exits */
   ppid = getppid();
-  if (ppid == 1) {
-    fprintf (stderr, "parent shutdown\n");
-    exit (2);
-  }  
+  if (ppid == 1) exit (2);
 
   CheckChildStatus ();
Index: /trunk/Ohana/src/opihi/pcontrol/CheckBusyJob.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/CheckBusyJob.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/CheckBusyJob.c	(revision 3212)
@@ -16,5 +16,5 @@
   InitIOBuffer (&buffer, 0x100);
 
-  status = PclientCommand (host, "status", &buffer);
+  status = PclientCommand (host, "status", PCLIENT_PROMPT, &buffer);
 
   /* check on success of pclient command */
@@ -34,5 +34,5 @@
 
     case PCLIENT_GOOD:
-      fprintf (stderr, "message received\n");  
+      fprintf (stderr, "message received (CheckBusyJob)\n");  
       break;
 
Index: /trunk/Ohana/src/opihi/pcontrol/CheckDoneHost.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/CheckDoneHost.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/CheckDoneHost.c	(revision 3212)
@@ -9,5 +9,5 @@
   InitIOBuffer (&buffer, 0x100);
   
-  status = PclientCommand (host, "reset", &buffer);
+  status = PclientCommand (host, "reset", PCLIENT_PROMPT, &buffer);
 
   /* check on success of pclient command */
@@ -27,5 +27,5 @@
 
     case PCLIENT_GOOD:
-      fprintf (stderr, "message received\n");  
+      fprintf (stderr, "message received (CheckDoneHost)\n");  
       break;
 
Index: /trunk/Ohana/src/opihi/pcontrol/CheckHost.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/CheckHost.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/CheckHost.c	(revision 3212)
@@ -9,5 +9,5 @@
   InitIOBuffer (&buffer, 0x100);
 
-  status = PclientCommand (host, "echo OK", &buffer);
+  status = PclientCommand (host, "echo OK", PCLIENT_PROMPT, &buffer);
   switch (status) {
     case 0:
Index: /trunk/Ohana/src/opihi/pcontrol/CheckSystem.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/CheckSystem.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/CheckSystem.c	(revision 3212)
@@ -11,4 +11,6 @@
   /** add in different timescales for heartbeat? **/
   CheckLiveHosts();
+
+  /* status (0, NULL); */
 }
 
@@ -54,5 +56,5 @@
   for (i = 0; i < Nobject; i++) {
     host = GetStack (stack, STACK_TOP);
-    StartHost (host);
+    CheckDoneHost (host);
   }
 }
Index: /trunk/Ohana/src/opihi/pcontrol/GetJobOutput.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/GetJobOutput.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/GetJobOutput.c	(revision 3212)
@@ -20,5 +20,5 @@
   /** must have a valid host : if not, move to pending? **/
   host = job[0].host;
-  status = PclientCommand (host, channel, buffer);
+  status = PclientCommand (host, channel, PCLIENT_PROMPT, buffer);
 
   /* check on success of pclient command */
@@ -37,5 +37,5 @@
 
     case PCLIENT_GOOD:
-      fprintf (stderr, "message received\n");  
+      fprintf (stderr, "message received (GetJobOutput : %s)\n", channel);  
       return (TRUE);
 
Index: /trunk/Ohana/src/opihi/pcontrol/HostOps.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/HostOps.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/HostOps.c	(revision 3212)
@@ -37,5 +37,5 @@
 int PutHost (Host *host, int StackID, int where) {
 
-  int status;
+  int stat;
   Stack *stack;
 
@@ -44,6 +44,7 @@
 
   host[0].stack = StackID;
-  status = PutStack (stack, where, host);
-  return (status);
+  stat = PutStack (stack, where, host);
+  /* status (0, NULL); */
+  return (stat);
 }
   
@@ -70,5 +71,5 @@
 
   for (i = 0; i < stack[0].Nobject; i++) {
-    host = (Host *) stack[0].object;
+    host = (Host *) stack[0].object[i];
     if (host[0].HostID == HostID) {
       return (i);
@@ -88,5 +89,5 @@
 
   for (i = 0; i < stack[0].Nobject; i++) {
-    host = (Host *) stack[0].object;
+    host = (Host *) stack[0].object[i];
     if (!strcasecmp (host[0].hostname, name)) {
       return (i);
@@ -113,13 +114,4 @@
 }
 
-void DownHost (Host *host) {
-
-  CLOSE (host[0].stdin);
-  CLOSE (host[0].stdout);
-  CLOSE (host[0].stderr);
-  host[0].job = NULL;
-  PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
-}
-
 void DelHost (Host *host) {
   FREE (host[0].hostname);
Index: /trunk/Ohana/src/opihi/pcontrol/JobOps.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/JobOps.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/JobOps.c	(revision 3212)
@@ -37,5 +37,5 @@
 int PutJob (Job *job, int StackID, int where) {
 
-  int status;
+  int stat;
   Stack *stack;
 
@@ -46,6 +46,7 @@
   job[0].state = StackID;
   job[0].stack = StackID;
-  status = PutStack (stack, where, job);
-  return (status);
+  stat = PutStack (stack, where, job);
+  /* status (0, NULL); */
+  return (stat);
 }
   
@@ -72,5 +73,5 @@
 
   for (i = 0; i < stack[0].Nobject; i++) {
-    job = (Job *) stack[0].object;
+    job = (Job *) stack[0].object[i];
     if (job[0].JobID == JobID) {
       return (i);
@@ -163,5 +164,29 @@
 
 void LinkJobAndHost (Job *job, Host *host) {
+  int N;
+
   job[0].host = host;
   host[0].job = job;
+
+# if (0)
+  /*** need to pop host off of correct stack XXX ***/
+  N = FindHost (host[0].HostID, host[0].stack);
+  if (N < 0) {
+    fprintf (stderr, "programming error: host is not found in current stack\n");
+    exit (2);
+  }
+  host = GetHost (host[0].stack, N);
+# endif
+
+  /*** need to pop job off of correct stack XXX ***/
+  N = FindJob (job[0].JobID, job[0].stack);
+  if (N < 0) {
+    fprintf (stderr, "programming error: job is not found in current stack\n");
+    exit (2);
+  }
+  job = GetJob (job[0].stack, N);
+
+  /*** this is fairly crazy : the only reason this works is cause I 
+       get the same host ptr here and in CheckIdleHost 
+  ***/
 }
Index: /trunk/Ohana/src/opihi/pcontrol/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/Makefile	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/Makefile	(revision 3212)
@@ -45,4 +45,5 @@
 $(SDIR)/ResetJob.$(ARCH).o \
 $(SDIR)/StartHost.$(ARCH).o \
+$(SDIR)/StopHosts.$(ARCH).o \
 $(SDIR)/StartJob.$(ARCH).o
 
Index: /trunk/Ohana/src/opihi/pcontrol/ResetJob.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/ResetJob.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/ResetJob.c	(revision 3212)
@@ -15,5 +15,5 @@
   job[0].Reset = TRUE;
 
-  status = PclientCommand (host, "reset", &buffer);
+  status = PclientCommand (host, "reset", PCLIENT_PROMPT, &buffer);
 
   /* check on success of pclient command */
@@ -32,5 +32,5 @@
 
     case PCLIENT_GOOD:
-      fprintf (stderr, "message received\n");  
+      fprintf (stderr, "message received (ResetJob)\n");  
       FreeIOBuffer (&buffer);
       return (TRUE);
Index: /trunk/Ohana/src/opihi/pcontrol/StartJob.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/StartJob.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/StartJob.c	(revision 3212)
@@ -30,5 +30,5 @@
   }
 
-  status = PclientCommand (host, line, &buffer);
+  status = PclientCommand (host, line, PCLIENT_PROMPT, &buffer);
   free (line);
 
@@ -44,5 +44,5 @@
 
     case PCLIENT_GOOD:
-      fprintf (stderr, "message received\n");  
+      fprintf (stderr, "message received (StartJob)\n");  
       break;
 
Index: /trunk/Ohana/src/opihi/pcontrol/StopHosts.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/StopHosts.c	(revision 3212)
+++ /trunk/Ohana/src/opihi/pcontrol/StopHosts.c	(revision 3212)
@@ -0,0 +1,117 @@
+# include "pcontrol.h"
+
+int DownHosts () {
+
+  int i, Nobject;
+  Stack *stack;
+  Host  *host;
+
+  stack = GetHostStack (PCONTROL_HOST_IDLE);
+  Nobject = stack[0].Nobject;
+
+  for (i = 0; i < Nobject; i++) {
+    host = GetStack (stack, STACK_TOP);
+    StopHost (host);
+    DownHost (host);
+  }
+
+  stack = GetHostStack (PCONTROL_HOST_BUSY);
+  Nobject = stack[0].Nobject;
+
+  for (i = 0; i < Nobject; i++) {
+    host = GetStack (stack, STACK_TOP);
+    StopHost (host);
+    DownHost (host);
+  }
+}
+
+int StopHost (Host *host) {
+
+  int       result;
+  int       waitstatus;
+  int       status;
+  char     *p;
+  IOBuffer  buffer;
+
+  InitIOBuffer (&buffer, 0x100);
+  status = PclientCommand (host, "exit", "Goodbye", &buffer);
+
+  /* check on success of pclient command */
+  switch (status) {
+    case PCLIENT_DOWN:
+      break;
+
+    case PCLIENT_HUNG:
+      fprintf (stderr, "host %s is not responding\n", host[0].hostname);
+      break;
+
+    case PCLIENT_GOOD:
+      break;
+
+    default:
+      fprintf (stderr, "unknown status for pclient command: programming error\n");  
+      exit (1);
+  }
+  usleep (10000);
+
+  /* check current child status */
+  result = waitpid (host[0].pid, &waitstatus, WNOHANG);
+  switch (result) {
+    case -1:  /* error with waitpid */
+      switch (errno) {
+	case ECHILD:
+	  fprintf (stderr, "unknown PID, not a child proc\n");
+	  fprintf (stderr, "did process already exit?  programming error?\n");
+	  break;
+	case EINVAL:
+	  fprintf (stderr, "error EINVAL (waitpid): programming error\n");
+	  exit (1);
+	case EINTR:
+	  fprintf (stderr, "error EINTR (waitpid): programming error\n");
+	  exit (1);
+	default:
+	  fprintf (stderr, "unknown error for waitpid (%d): programming error\n", errno);
+	  exit (1);
+      }
+      break;
+      
+    case 0:
+      fprintf (stderr, "child did not exit??");
+      /** put back in IDLE state? **/
+      break;
+
+    default:
+      if (result != host[0].pid) {
+	fprintf (stderr, "waitpid error: mis-matched PID (%d vs %d).  programming error\n", result, host[0].pid);
+	exit (1);
+      }
+      
+      if (WIFEXITED(waitstatus)) {
+	fprintf (stderr, "child exited with status %d\n", WEXITSTATUS(waitstatus));
+      }
+      if (WIFSIGNALED(waitstatus)) {
+	fprintf (stderr, "child crashed with status %d\n", WTERMSIG(waitstatus));
+      }
+      if (WIFSTOPPED(waitstatus)) {
+	fprintf (stderr, "waitpid returns 'stopped': programming error\n");
+	exit (1);
+      }
+  }
+  return (TRUE);
+}
+
+void DownHost (Host *host) {
+  CLOSE (host[0].stdin);
+  CLOSE (host[0].stdout);
+  CLOSE (host[0].stderr);
+  host[0].job = NULL;
+  PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
+}
+
+void OffHost (Host *host) {
+  CLOSE (host[0].stdin);
+  CLOSE (host[0].stdout);
+  CLOSE (host[0].stderr);
+  host[0].job = NULL;
+  PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
+}
Index: /trunk/Ohana/src/opihi/pcontrol/host.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/host.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/host.c	(revision 3212)
@@ -3,5 +3,5 @@
 int host (int argc, char **argv) {
 
-  int N, Delete, Off, On;
+  int N, Delete, Off, On, Start, Stop, Check;
   Host *host;
 
@@ -26,5 +26,5 @@
   /* this section needs some help: find the specified host in the stacks */
   On = FALSE;
-  if ((N = get_argument (argc, argv, "-off"))) {
+  if ((N = get_argument (argc, argv, "-on"))) {
     if (Delete || Off) {
       fprintf (stderr, "only one of -delete, -off, -on\n");
@@ -35,5 +35,26 @@
   }
  
-  if (argc < 2) {
+  /* this section needs some help: find the specified host in the stacks */
+  Start = FALSE;
+  if ((N = get_argument (argc, argv, "-start"))) {
+    remove_argument (N, &argc, argv);
+    Start = TRUE;
+  }
+ 
+  /* this section needs some help: find the specified host in the stacks */
+  Check = FALSE;
+  if ((N = get_argument (argc, argv, "-check"))) {
+    remove_argument (N, &argc, argv);
+    Check = TRUE;
+  }
+ 
+  /* this section needs some help: find the specified host in the stacks */
+  Stop = FALSE;
+  if ((N = get_argument (argc, argv, "-stop"))) {
+    remove_argument (N, &argc, argv);
+    Stop = TRUE;
+  }
+ 
+  if (argc != 2) {
     fprintf (stderr, "USAGE: host (hostname) [-delete]\n");
     return (FALSE);
@@ -62,12 +83,49 @@
   }
 
+  if (Check) {
+    N = FindNamedHost (argv[1], PCONTROL_HOST_IDLE);
+    if (N >= 0) {
+      host = GetHost (PCONTROL_HOST_IDLE, N);
+      CheckHost (host);
+      return (TRUE);
+    }
+    N = FindNamedHost (argv[1], PCONTROL_HOST_BUSY);
+    if (N >= 0) {
+      host = GetHost (PCONTROL_HOST_BUSY, N);
+      CheckHost (host);
+      return (TRUE);
+    }
+    fprintf (stderr, "host %s is not BUSY or IDLE\n", argv[1]);
+    return (FALSE);
+  }
+
+  if (Start) {
+    N = FindNamedHost (argv[1], PCONTROL_HOST_DOWN);
+    if (N < 0) {
+      fprintf (stderr, "host %s is not DOWN\n", argv[1]);
+      return (FALSE);
+    }
+    host = GetHost (PCONTROL_HOST_DOWN, N);
+    StartHost (host);
+    return (TRUE);
+  }
+  if (Stop) {
+    N = FindNamedHost (argv[1], PCONTROL_HOST_IDLE);
+    if (N < 0) {
+      fprintf (stderr, "host %s is not IDLE\n", argv[1]);
+      return (FALSE);
+    }
+    host = GetHost (PCONTROL_HOST_IDLE, N);
+    StopHost (host);
+    DownHost (host);
+    return (TRUE);
+  }
+
   if (Off) {
     N = FindNamedHost (argv[1], PCONTROL_HOST_IDLE);
     if (N >= 0) {
       host = GetHost (PCONTROL_HOST_IDLE, N);
-      CLOSE (host[0].stdin);
-      CLOSE (host[0].stdout);
-      CLOSE (host[0].stderr);
-      PutHost (host, PCONTROL_HOST_OFF, STACK_BOTTOM);
+      StopHost (host);
+      OffHost (host);
       return (TRUE);
     }
@@ -75,5 +133,5 @@
     if (N >= 0) {
       host = GetHost (PCONTROL_HOST_DOWN, N);
-      PutHost (host, PCONTROL_HOST_OFF, STACK_BOTTOM);
+      OffHost (host);
       return (TRUE);
     }
Index: /trunk/Ohana/src/opihi/pcontrol/job.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/job.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/job.c	(revision 3212)
@@ -48,7 +48,4 @@
   JobID = AddJob (Host, Mode, Timeout, targc, targv);
   FREE (Host);
-
-  fprintf (stdout, "STATUS %d\n", JobID);
   return (TRUE);
-
 }
Index: /trunk/Ohana/src/opihi/pcontrol/pclient.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/pclient.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/pclient.c	(revision 3212)
@@ -1,8 +1,6 @@
 # include "pcontrol.h"
+# define PCLIENT_TIMEOUT 20
 
-# define PCLIENT_TIMEOUT 20
-# define PCLIENT_PROMPT "pclient:"
-
-int PclientCommand (Host *host, char *command, IOBuffer *buffer) {
+int PclientCommand (Host *host, char *command, char *response, IOBuffer *buffer) {
 
   int i;
@@ -10,6 +8,9 @@
   char *line;
 
+  ReadtoIOBuffer (buffer, host[0].stdout);
+  FlushIOBuffer (buffer);
+
   /* send command to client (adding on \n) */
-  fprintf (stderr, "send: %s (%d)\n", command, buffer[0].Nbuffer);
+  /* fprintf (stderr, "send: %s (%d)\n", command, buffer[0].Nbuffer); */
   ALLOCATE (line, char, MAX (1, strlen(command)));
   sprintf (line, "%s\n", command);
@@ -25,9 +26,10 @@
   for (i = 0; (i < PCLIENT_TIMEOUT) && (status == -1) && (line == NULL); i++) {
     status = ReadtoIOBuffer (buffer, host[0].stdout);
-    line = memstr (buffer[0].buffer, PCLIENT_PROMPT, buffer[0].Nbuffer);
+    line = memstr (buffer[0].buffer, response, buffer[0].Nbuffer);
+    if (status == -1) usleep (10000);
   }
   if (status ==  0) return (PCLIENT_DOWN);
   if (status == -1) return (PCLIENT_HUNG);
-  fprintf (stderr, "buffer.buffer: %s\n", buffer[0].buffer);
+  /* fprintf (stderr, "buffer.buffer: %s\n", buffer[0].buffer); */
   return (PCLIENT_GOOD);
 }
Index: /trunk/Ohana/src/opihi/pcontrol/pcontrol.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/pcontrol.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/pcontrol.c	(revision 3212)
@@ -45,4 +45,5 @@
   rl_attempted_completion_function = command_completer;
   rl_event_hook = CheckSystem;
+  /* rl_set_keyboard_input_timeout (2000000);  */
 
   set_str_variable ("HISTORY", opihi_history);
@@ -57,4 +58,5 @@
 /* add program-dependent exit functions here */
 void cleanup () {
+  DownHosts ();
   return;
 }
Index: /trunk/Ohana/src/opihi/pcontrol/status.c
===================================================================
--- /trunk/Ohana/src/opihi/pcontrol/status.c	(revision 3211)
+++ /trunk/Ohana/src/opihi/pcontrol/status.c	(revision 3212)
@@ -1,3 +1,5 @@
 # include "pcontrol.h"
+char jobname[6][32] = {"PENDING", "BUSY", "EXIT", "CRASH", "HUNG", "DONE"};
+char hostname[5][32] = {"IDLE", "BUSY", "DOWN", "DONE", "OFF"};
 
 int status (int argc, char **argv) {
@@ -28,5 +30,5 @@
   stack = GetJobStack (Nstack);
   Nobject = stack[0].Nobject;
-  fprintf (stderr, "job stack %d:  %d objects\n", Nstack, Nobject);
+  fprintf (stderr, "job stack %s:  %d objects\n", jobname[Nstack], Nobject);
 
   for (i = 0; i < Nobject; i++) {
@@ -49,5 +51,5 @@
   stack = GetHostStack (Nstack);
   Nobject = stack[0].Nobject;
-  fprintf (stderr, "host stack %d:  %d objects\n", Nstack, Nobject);
+  fprintf (stderr, "host stack %s:  %d objects\n", hostname[Nstack], Nobject);
 
   for (i = 0; i < Nobject; i++) {
