
typedef struct {
  char *buffer;
  int   Nalloc;
  int   Nmaxread;
  int   Nextra;
  int   Nlast;
  int   Nbuffer;
} Fifo;

typedef struct {
  int argc; char **argv; /* a list of words that define this object */
  struct timeval start, accum, timer;
  int   status;
  char *logfile;
  char *lastproc;
} Object;

typedef struct {
  Object **object;
  int    Nobject;
  int    NOBJECT;
} Queue;

typedef struct {
  char   *hostname;
  int     rsock, wsock;
  int     status; /* idle, busy, etc... */
  struct  timeval start, accum, timer;
  Fifo    fifo;
  int     code;
  Object *object;
} Machine;


currently, the transport is /usr/bin/rsh, defined in InitMachines.c 

the shell on the remote machines is /bin/tcsh, defined by rconnect.c

---

pcontrol.client:

 - remote process initiated by pcontrol

 - accepts jobs, returns status, stdout and stderr

 - valid commands:

   - job (argv)
     returns PID or -1 (0?) on failure

   - status
     returns current job status:
     BUSY
     EXIT n 
     CRASH n
     
   - stderr
     returns the current stderr buffer:
     NBYTES n
     (DATA)

   - stdout
     returns the current stdout buffer:
     NBYTES n
     (DATA)

   
---

the client needs to accept commands from the server (via
stdin/stdout), but it also needs to monitor its process.  I can use
the opihi structure to implement the command-line interpretation with
readline.  I can use the readline function rl_event_hook to set the
background functions to check and rl_set_keyboard_input_timeout to set
the polling period.

this same method can be used with the scheduler:  the command 'run'
can set the CheckTask function to this hook (& unset it).


---

rl_event_hook -> CheckChild

  - needs to handle the case when no child process yet exists
  - needs to examine the child status,
  - needs to read from child stderr and store
  - needs to read from child stdout and store

  * no warnings (will not do anything clever if buffers get too large)

---

 pcontrol commands:

 job [options] argv0 argv1 argv2 ...
  -host name : run job on specified host, or any other if not available
  +host name : run job on specified host, error if not available (error when attempted, not when submitted)
  -timeout N : seconds before controller gives up on job (once started)

  * priority information?
  * returns JobID
  * adds job to pending queue

 host (hostname) [-delete]
 (may have multiple entries to the same machine, these are not distinguished)

 stdout ID [-file name]
 stderr ID [-file name]
 delete ID

 status -job ID
 status -machine hostname
 status -queues

 
---

write message
read until MESSAGE END


Job States:

PENDING
BUSY
EXIT
CRASH
NEW
DEL

Job State Transitions:

NEW     -> PENDING : AddJob
PENDING -> BUSY    : StartJob
PENDING -> DEL     : DelJob
BUSY    -> EXIT    : CheckJob
BUSY    -> CRASH   : CheckJob | KillJob
BUSY    -> PENDING : CheckJob | CheckHost
EXIT    -> DEL     : DelJob
CRASH   -> DEL     : DelJob

Host States:

IDLE
BUSY
DOWN
OFF
NEW
DEL

Host State Transitions:

NEW      -> OFF      : AddHost
OFF      -> DEL      : DelHost
OFF      -> DOWN     : OnHost
DOWN     -> OFF      : OffHost
IDLE     -> OFF      : OffHost
DOWN     -> IDLE     : StartHost
IDLE     -> BUSY     : StartJob
BUSY     -> IDLE     : CheckJob | KillJob
BUSY     -> BUSY-OFF : OffHost
BUSY     -> DOWN     : CheckJob | CheckHost
BUSY-OFF -> OFF      : CheckJob

AddJob    - U
DelJob    - U
StartJob  - P
CheckJob  - P
KillJob   - U

AddHost   - U
DelHost   - U
OnHost    - U
OffHost   - U
StartHost - P
CheckHost - P
