static char copyright[] = "Copyright 1990 by The MITRE Corporation.";
/* John D. Ramsdell - June 1990
 *
 * Copyright 1990 by The MITRE Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 1, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#import "startSlaveProcess.h"
#import <appkit/appkit.h>
#import <appkit/Application.h>
#import <defaults/defaults.h>
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#import <libc.h>
#import <dpsclient/dpsclient.h>

/* Creates a slave process and the pipes used to do the communication. */

static int pid;

static void processInHandler(int fd, void *userData)
{				/* Handles input from the slave process. */
  static char buf[BUFSIZ + 1]; int n; 
  n = read(fd, buf, BUFSIZ);
  if (n < 0) {
    fprintf(stderr, "\nError in processIn reading %d bytes.\n", n);
    perror ("input from pipe");
    [NXApp terminate:((id) userData)];
  } 
  else if (n == 0) [NXApp terminate:((id) userData)];
  else {
    char *textString;
    textString = malloc(n + 1);
    buf[n] = '\0';
    [((EvalDelegate *) userData) showString:strcpy(textString, buf)];
  } 
}

int interruptSlaveProcess(void)
{
  return kill(pid, SIGINT);
}

const char shellScript[] =
  "if $0\n"
  "then\n"
  "  exit 0\n"
  "else\n"
  "  echo Slave exited with $?.\n"
  "  echo For slave command: $0.\n"
  "  echo\n"
  "  echo Starting a shell.\n"
  "  exec /bin/sh -i\n"
  "fi\n"
  "exit 1\n";

static void createProcess(int out[2])
{
  int in[2]; const char *slaveCommand;

  slaveCommand = NXGetDefaultValue("Twin", "SlaveCommand");
  if (slaveCommand == NULL) slaveCommand = "# Could not get default";
  if (-1 == pipe (in)) perror("Pipe error");
  if (-1 == pipe (out)) perror ("Pipe error");

  if (0 == (pid = fork())) {
    close (0);
    close (1);
    if (0 != dup (in[0])) perror("dup error");
    if (1 != dup (out[1])) perror("dup error");
    close (2);
    if (2 != dup (1)) exit(1);
    close (in[0]); close (in[1]); close (out[0]); close (out[1]);

#if defined DEBUG
    write (2, shellScript, strlen(shellScript)); /* show script. */
    write (2, slaveCommand, strlen(slaveCommand));
    write (2, "\n\n", 2);
#endif

    execl("/bin/sh", "-sh", "-c", shellScript, slaveCommand, NULL);
    exit(1);
  }
  close (in[0]); close (out[1]);
  out[1] = in[1];
}

FILE *startSlaveProcess(EvalDelegate *evalDelegate)
{				/* Creates the slave process, */
  int fildes[2];		/* adds processInHandler to handle */
  createProcess(fildes);	/* data from the slave, and returns */
  DPSAddFD(fildes[0], processInHandler,	/* the file pointer used to */
	   (void *)evalDelegate, NX_RUNMODALTHRESHOLD);	/* send */
  return fdopen(fildes[1], "a"); /* data to the slave process. */
}
