/* -*-C-*-
 * gnudoit.c	-- pbreton Thu Jan 25 1996
 *
 * Client code to allow locally and remotely evaluate lisp forms
 * using GNU Emacs.
 *
 * This file is not part of GNU Emacs. 
 * 
 * Copying is permitted under those conditions described by the GNU
 * General Public License.
 *
 * Copyright (C) 1996 Peter Breton
 *
 * Author: Peter Breton (pbreton@cs.umb.edu)
 * Based heavily on Andy Norman's gnuserv (ange@hplb.hpl.hp.com), 
 * which in turn was based on 'etc/emacsclient.c' from the GNU 
 * Emacs 18.52 distribution.
 *
 * Modifications: Nico Francois (nico.francois@scala.nl) 
 *                Mon Jun 3 1996
 * See comment in gnuserv.c.
 *
 * $Log: gnudoit.c,v $
 * Revision 1.2  1996/01/29 05:47:44  peter
 * Fixed typo
 *
 * Revision 1.1  1996/01/29 05:14:56  peter
 * Initial revision
 *
 */

static char rcsid [] = "$Header$";

#include "gnuserv.h" 
#include "getopt.h" 

/* Name of this program */
static char * progname;

void
main(argc,argv)
     int argc;
     char *argv[];
{
  int    qflg   = 0;			 /* quick edit */
  int    dbgflg = 0;			 /* debug flag */
  int    errflg = 0;			 /* option error */
  int    c;				 /* char from getopt */
  HANDLE h;				 /* mailslot handle */
  char   clientidstr[20];
  char * hostarg = GNUSERV_DEFAULT_HOST; /* hostname */
  char * basecommand;
  HANDLE resultslot;
  DWORD  clientid = GetCurrentProcessId();
  BOOL   noresult = FALSE;

  progname = argv[0];

  /* Parse arguments */
  while ((c = getopt(argc, argv, "h:qd?" )) != EOF)
    switch (c) {
    case 'q':
      qflg++;
      break;

    case 'd':
      dbgflg++;
      break;

    case 'h':
      hostarg = optarg;
	  // FIX! We don't support results from a server on another host just yet.
	  noresult = TRUE;
      break;

    case '?':
      errflg++;
    }; 

  /* Print a usage message and quit */   
  if (errflg)
  {
    fprintf(stderr,
	    "usage: %s [-q] [-d] [-h hostname] [sexpr] ...\n",
	    progname);
    exit (1);
  }; /* if */

  // First create mailslot to receive result
  resultslot = CreateGnuServSlot (TRUE, clientid);
  if (INVALID_HANDLE_VALUE == resultslot)
	  exit (1);

  /* Try to connect to the mailslot. Dies on failure */
  h = ConnectToMailslot (hostarg, FALSE, 0);  

  /* Send a lisp command... */
  basecommand = (qflg) ?
    "(server-eval-quickly '(progn " : "(server-eval '(progn "; 

  sprintf (clientidstr, "C:%d ", clientid);
  if (!SendString (h, clientidstr)) exit (1);

  SendString (h, basecommand); 

  if (dbgflg)
    printf(basecommand);

  /* ...followed by lisp expressions to the server process */
  /* Sexp on command line */
  if (optind < argc)
  {
    for (; optind < argc; optind++)
      {
	SendString (h, argv[optind]);
	SendString (h, " ");
	
	if (dbgflg)
	  printf("%s ", argv[optind]);
      } /* for */
  } /* if */  
  /* no sexp on the command line, so read it from stdin */
  else
  {
    char   buf[GSERV_BUFSZ];
    DWORD  NumBytesRead;
    HANDLE consoleStdin = GetStdHandle(STD_INPUT_HANDLE);

    if (INVALID_HANDLE_VALUE == consoleStdin)
    {
      fprintf(stderr, "Can't get console stdin\n");
      exit (1);
    }

    while(ReadFile(consoleStdin, buf,
		   GSERV_BUFSZ,  &NumBytesRead, 0))
    {  
      /* Should always be true */
      if (NumBytesRead > 0)
      {
	/* Quit if we see an EOT */
	if (EOT_CHR == buf[0])
	  break;

	/* Overwrite the CR on the end with a NULL */
	buf[NumBytesRead -1] = '\0';
	SendString (h, buf);
      }
    }
  }

  /* Finish off the sexp and send an EOT */
  SendString (h, "))");
  SendString (h, EOT_STR);

  if (dbgflg)
    printf("))");

  /* Disconnect */
  DisconnectFromMailslot (h);

  // Now wait for result, then exit.  The result will be printed,
  // unless the -q flag was used.
  if (!noresult) WaitForServerResult (resultslot, !qflg);
  DisconnectFromMailslot (resultslot);

  exit(0);

} /* main */
