/*   

  Copyright 2004-2012, Martian Software, Inc.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  
*/

/**
 */

#ifdef WIN32
	#include <direct.h>
	#include <winsock2.h>
#else
	#include <arpa/inet.h>
	#include <netdb.h>
	#include <netinet/in.h>
	#include <sys/socket.h>
	#include <sys/time.h>
	#include <sys/types.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#define NAILGUN_VERSION "0.9.0"

#define BUFSIZE (2048)

#ifdef WIN32
	HANDLE NG_STDIN_FILENO;
	HANDLE NG_STDOUT_FILENO;
	HANDLE NG_STDERR_FILENO;
	#define FILE_SEPARATOR '\\'
	#define MSG_WAITALL 0
#else
	#define NG_STDIN_FILENO STDIN_FILENO
	#define NG_STDOUT_FILENO STDOUT_FILENO
	#define NG_STDERR_FILENO STDERR_FILENO
	#define FILE_SEPARATOR '/'
	typedef int HANDLE;
	typedef unsigned int SOCKET;
	/* buffer used for reading an writing chunk data */
	char buf[BUFSIZE];
#endif

#ifndef MIN
#define MIN(a,b) ((a<b)?(a):(b))
#endif

#ifdef WIN32
	#define NAILGUN_FILESEPARATOR "NAILGUN_FILESEPARATOR=\\"
	#define NAILGUN_PATHSEPARATOR "NAILGUN_PATHSEPARATOR=;"
#else
	#define NAILGUN_FILESEPARATOR "NAILGUN_FILESEPARATOR=/"
	#define NAILGUN_PATHSEPARATOR "NAILGUN_PATHSEPARATOR=:"
#endif

#define NAILGUN_CLIENT_NAME_EXE "ng.exe"

#define NAILGUN_PORT_DEFAULT "2113"
#define NAILGUN_CLIENT_NAME "ng"
#define CHUNK_HEADER_LEN (5)

#define NAILGUN_SOCKET_FAILED (231)
#define NAILGUN_CONNECT_FAILED (230)
#define NAILGUN_UNEXPECTED_CHUNKTYPE (229)
#define NAILGUN_EXCEPTION_ON_SERVER (228)
#define NAILGUN_CONNECTION_BROKEN (227)
#define NAILGUN_BAD_ARGUMENTS (226)

#define CHUNKTYPE_STDIN '0'
#define CHUNKTYPE_STDOUT '1'
#define CHUNKTYPE_STDERR '2'
#define CHUNKTYPE_STDIN_EOF '.'
#define CHUNKTYPE_ARG 'A'
#define CHUNKTYPE_LONGARG 'L'
#define CHUNKTYPE_ENV 'E'
#define CHUNKTYPE_DIR 'D'
#define CHUNKTYPE_CMD 'C'
#define CHUNKTYPE_EXIT 'X'
#define CHUNKTYPE_SENDINPUT 'S'
#define CHUNKTYPE_HEARTBEAT 'H'

#define HEARTBEAT_TIMEOUT_MILLIS 500

/*
   the following is required to compile for hp-ux
   originally posted at http://jira.codehaus.org/browse/JRUBY-2346
*/
#ifndef MSG_WAITALL
#define MSG_WAITALL 0x40 /* wait for full request or error */
#endif

/* the socket connected to the nailgun server */
int nailgunsocket = 0;

/* buffer used for receiving and writing nail output chunks */
char buf[BUFSIZE];

/* track whether server is ready to receive */
#ifdef WIN32
    HANDLE readyToSend = 0;
    HANDLE sending = 0;
#else
    int readyToSend = 0;
#endif

/**
 * Clean up the application.
 */
void cleanUpAndExit (int exitCode) {


  #ifdef WIN32
    CancelIo(STDIN_FILENO);
    WSACleanup();
    if (nailgunsocket) {
      closesocket(nailgunsocket);
    }
  #else
    close(nailgunsocket);
  #endif

  exit(exitCode);
}

#ifdef WIN32
/**
 * Handles an error.
 * Shows the message for the latest error then exits.
 */
void handleError () {
  LPVOID lpMsgBuf;
  int error = GetLastError();

  FormatMessage( 
    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
    FORMAT_MESSAGE_FROM_SYSTEM | 
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    error,
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
    (LPTSTR) &lpMsgBuf,
    0,
    NULL);

  /* Display the string. */
  MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONERROR );

  /* Free the buffer. */
  LocalFree( lpMsgBuf );
 
  cleanUpAndExit(error);
}
#endif

/**
 * Writes everything in the specified buffer to the specified
 * socket handle.
 *
 * @param s the socket descriptor
 * @param buf the buffer containing the data to send
 * @param len the number of bytes to send.  Also used to
 *            return the number of bytes sent.
 * @return total bytes written or 0 if failure
 */
int sendAll(SOCKET s, char *buf, int len) {
  int total = 0;      
  int bytesleft = len; 
  int n = 0;
    
  while(total < len) {
    n = send(s, buf+total, bytesleft, 0);
    
    if (n == -1) { 
      break;
    }
    
    total += n;
    bytesleft -= n;
  }

  return n==-1 ? 0:total; 
}

/**
 * Sends a chunk noting the specified payload size and chunk type.
 * Waits for sending mutex on Win32.
 * 
 * @param size the payload size
 * @param chunkType the chunk type identifier
 */
void sendChunk(unsigned int size, char chunkType, char* buf) {
  /* buffer used for reading and writing chunk headers */
  char header[CHUNK_HEADER_LEN];

  header[0] = (size >> 24) & 0xff;
  header[1] = (size >> 16) & 0xff;
  header[2] = (size >> 8) & 0xff;
  header[3] = size & 0xff;
  header[4] = chunkType;

#ifdef WIN32
  if (WaitForSingleObject(sending, INFINITE) != WAIT_OBJECT_0) {
    handleError();
  }
#endif

  sendAll(nailgunsocket, header, CHUNK_HEADER_LEN);
  if (size > 0) {
	  sendAll(nailgunsocket, buf, size);
  }

#ifdef WIN32
  ReleaseMutex(sending);
#endif
}

/**
 * Sends the contents of the specified file as a long argument (--nailgun-filearg)
 * This is sent as one or more chunks of type CHUNK_LONGARG.  The end of the argument
 * is indicated by an empty chunk.
 *
 * @param filename the name of the file to send.
 * @return nonzero on failure
 */
int sendFileArg(char *filename) {
  int i, f;
  
  if ((f = open(filename, O_RDONLY)) < 0) {
    perror("--nailgun-filearg");
    return 1;  
  }

  i = read(f, buf, BUFSIZE);
  while (i > 0) {
    sendChunk(i, CHUNKTYPE_LONGARG, buf);
    i = read(f, buf, BUFSIZE);
  }
  if (i < 0) {
    perror("--nailgun-filearg");
    return 1;
  }
  sendChunk(0, CHUNKTYPE_LONGARG, buf);
  
  close(f);
  return 0;
}

/**
 * Sends a null-terminated string with the specified chunk type.
 *
 * @param chunkType the chunk type identifier
 * @param text the null-terminated string to send
 */
void sendText(char chunkType, char *text) {
  int len = text ? strlen(text) : 0;
  sendChunk(len, chunkType, text);
}

/**
 * Exits the client if the nailgun server ungracefully shut down the connection.
 */
void handleSocketClose() {
  cleanUpAndExit(NAILGUN_CONNECTION_BROKEN);
}

/**
 * Receives len bytes from the nailgun socket and copies them to the specified file descriptor.
 * Used to route data to stdout or stderr on the client.
 *
 * @param destFD the destination file descriptor (stdout or stderr)
 * @param len the number of bytes to copy
 */
void recvToFD(HANDLE destFD, char *buf, unsigned long len) {
  unsigned long bytesRead = 0;
  int bytesCopied;
  
  while (bytesRead < len) {
    unsigned long bytesRemaining = len - bytesRead;
    int bytesToRead = (BUFSIZE < bytesRemaining) ? BUFSIZE : bytesRemaining;
    int thisPass = 0;
    
    thisPass = recv(nailgunsocket, buf, bytesToRead, MSG_WAITALL);
	if (thisPass == 0) {
	  handleSocketClose();
	}
    bytesRead += thisPass;

    bytesCopied = 0;

    while(bytesCopied < thisPass) {
      #ifdef WIN32
        DWORD thisWrite =  0;

        WriteFile(destFD, buf + bytesCopied, thisPass - bytesCopied,
          &thisWrite, NULL);

        if (thisWrite < 0) {
          break;
        }

        bytesCopied += thisWrite;
      #else
        bytesCopied += write(destFD, buf + bytesCopied, thisPass - bytesCopied);
      #endif
    }  
  }
}

unsigned long recvToBuffer(unsigned long len) {
  unsigned long bytesRead = 0;
  while(bytesRead < len) {
    int thisPass = recv(nailgunsocket, buf + bytesRead, len - bytesRead, MSG_WAITALL);
	if (thisPass == 0) {
      handleSocketClose();
	}
	bytesRead += thisPass;
  }
  return bytesRead;
}

/**
 * Processes an exit chunk from the server.  This is just a string
 * containing the exit code in decimal format.  It should fit well
 * within our buffer, so assume that it does.
 *
 * @param len the current length of the buffer containing the exit code.
 */
void processExit(char *buf, unsigned long len) {
  int exitcode;
  int bytesToRead = (BUFSIZE - 1 < len) ? BUFSIZE - 1 : len;
  int bytesRead = recvToBuffer(bytesToRead);
  
  if (bytesRead < 0) {
    handleSocketClose();
  }
  
  buf[bytesRead] = 0;
  
  exitcode = atoi(buf);
  
  cleanUpAndExit(exitcode);
}


/**
 * Sends len bytes from buf to the nailgun server in a stdin chunk.
 *
 * @param buf the bytes to send
 * @param len the number of bytes to send
 */
void sendStdin(char *buf, unsigned int len) {
#ifndef WIN32
  readyToSend = 0;
#endif
  sendChunk(len, CHUNKTYPE_STDIN, buf);
}

/**
 * Sends a stdin-eof chunk to the nailgun server
 */
void processEof() {
  sendChunk(0, CHUNKTYPE_STDIN_EOF, buf);
}

/**
 * Sends a heartbeat chunk to let the server know the client is still alive.
 */
void sendHeartbeat() {
  sendChunk(0, CHUNKTYPE_HEARTBEAT, buf);
}

#ifdef WIN32

HANDLE createEvent(BOOL manualReset) {
  return CreateEvent(NULL, /* default security */
		     manualReset,
		     FALSE, /* initial state unsignalled */
		     NULL /* unnamed event */);
}

DWORD WINAPI sendHeartbeats(LPVOID lpParameter) {
		
	/* this could be made more efficient by only sending heartbeats when stdin chunks aren't being sent */
	for (;;) {
		Sleep(HEARTBEAT_TIMEOUT_MILLIS);
		sendHeartbeat();
	}
}

/**
 * Thread main for reading from stdin and sending
 */
DWORD WINAPI processStdin (LPVOID lpParameter) {
  /* buffer used for reading and sending stdin chunks */
  char wbuf[BUFSIZE];

  /* number of bytes read */
  DWORD numberOfBytes;

  for (;;) {

    /* wait for ready to send */
    if(WaitForSingleObject(readyToSend, INFINITE) != WAIT_OBJECT_0) {
      handleError();
    }

	/* read data from stdin */
	if (! ReadFile(NG_STDIN_FILENO, wbuf, BUFSIZE, &numberOfBytes, NULL)) {
		if (numberOfBytes != 0) {
			handleError();
		}
	}

    /* send data to server */
    if (numberOfBytes > 0) {
      sendStdin(wbuf, numberOfBytes);
    } else {
      processEof();
      break;
    }

  }
  return 0;
}
#else
/**
 * Reads from stdin and transmits it to the nailgun server in a stdin chunk.
 * Sends a stdin-eof chunk if necessary.
 *
 * @return zero if eof has been reached.
 */
int processStdin() {
	int bytesread = read(STDIN_FILENO, buf, BUFSIZE);
	if (bytesread > 0) {
		sendStdin(buf, bytesread);
	} else if (bytesread == 0) {
		processEof();
	}
	return(bytesread);
}
#endif

#ifdef WIN32
/**
 * Initialise Windows sockets
 */
void initSockets () {
  WSADATA win_socket_data;     /* required to initialise winsock */
  
  WSAStartup(2, &win_socket_data);

  /* create flow control event and mutex */
  readyToSend = createEvent(FALSE);
  sending = CreateMutex(NULL, FALSE, NULL);
}
#endif

#ifdef WIN32
/**
 * Initialise the asynchronous io.
 */
void initIo () {
  /* create non-blocking console io */
  AllocConsole();
  
  NG_STDIN_FILENO = GetStdHandle(STD_INPUT_HANDLE);
  NG_STDOUT_FILENO = GetStdHandle(STD_OUTPUT_HANDLE);
  NG_STDERR_FILENO = GetStdHandle(STD_ERROR_HANDLE);
}
#endif

#ifdef WIN32
/**
 * Initialise the asynchronous io.
 */
void winStartInput () {
  SECURITY_ATTRIBUTES securityAttributes;
  DWORD threadId = 0;

  securityAttributes.bInheritHandle = TRUE;
  securityAttributes.lpSecurityDescriptor = NULL;
  securityAttributes.nLength = 0;
  
  if (!CreateThread(&securityAttributes, 0, &processStdin, NULL, 0, &threadId)) {
    handleError();
  }

  if (!CreateThread(&securityAttributes, 0, &sendHeartbeats, NULL, 0, &threadId)) {
    handleError();
  }
}
#endif

/**
 * Processes data from the nailgun server.
 */
void processnailgunstream() {

  /*for (;;) {*/
    unsigned long len;
    char chunkType;

    recvToBuffer(CHUNK_HEADER_LEN);

    len = ((buf[0] << 24) & 0xff000000)
      | ((buf[1] << 16) & 0x00ff0000)
      | ((buf[2] << 8) & 0x0000ff00)
      | ((buf[3]) & 0x000000ff);
  
    chunkType = buf[4];
  
    switch(chunkType) {
      case CHUNKTYPE_STDOUT: recvToFD(NG_STDOUT_FILENO, buf, len);
            break;
      case CHUNKTYPE_STDERR: recvToFD(NG_STDERR_FILENO, buf, len);
            break;
      case CHUNKTYPE_EXIT:   processExit(buf, len);
            break;
      case CHUNKTYPE_SENDINPUT:
#ifdef WIN32
            SetEvent(readyToSend);
#else
            readyToSend = 1;
#endif
            break;
      default:  fprintf(stderr, "Unexpected chunk type %d ('%c')\n", chunkType, chunkType);
          cleanUpAndExit(NAILGUN_UNEXPECTED_CHUNKTYPE);
    }
  /*}*/
}

/**
 * Trims any path info from the beginning of argv[0] to determine
 * the name used to launch the client.
 *
 * @param s argv[0]
 */
char *shortClientName(char *s) {
  char *result = strrchr(s, FILE_SEPARATOR);
  return ((result == NULL) ? s : result + 1);
}

/**
 * Returns true if the specified string is the name of the nailgun
 * client.  The comparison is made case-insensitively for windows.
 *
 * @param s the program name to check
 */
int isNailgunClientName(char *s) {
  #ifdef WIN32
  return (!strcasecmp(s, NAILGUN_CLIENT_NAME) ||
           !strcasecmp(s, NAILGUN_CLIENT_NAME_EXE));
  #else
  return(!(strcmp(s, NAILGUN_CLIENT_NAME)));
  #endif
}

/**
 * Displays usage info and bails
 */
void usage(int exitcode) {
  fprintf(stderr, "NailGun v%s\n\n", NAILGUN_VERSION);
  fprintf(stderr, "Usage: ng class [--nailgun-options] [args]\n");
  fprintf(stderr, "          (to execute a class)\n");
  fprintf(stderr, "   or: ng alias [--nailgun-options] [args]\n");
  fprintf(stderr, "          (to execute an aliased class)\n");
  fprintf(stderr, "   or: alias [--nailgun-options] [args]\n");
  fprintf(stderr, "          (to execute an aliased class, where \"alias\"\n");
  fprintf(stderr, "           is both the alias for the class and a symbolic\n");
  fprintf(stderr, "           link to the ng client)\n\n");
  
  fprintf(stderr, "where options include:\n");
  fprintf(stderr, "   --nailgun-D<name>=<value>   set/override a client environment variable\n");
  fprintf(stderr, "   --nailgun-version           print product version and exit\n");
  fprintf(stderr, "   --nailgun-showversion       print product version and continue\n");
  fprintf(stderr, "   --nailgun-server            to specify the address of the nailgun server\n");
  fprintf(stderr, "                               (default is NAILGUN_SERVER environment variable\n");
  fprintf(stderr, "                               if set, otherwise localhost)\n");
  fprintf(stderr, "   --nailgun-port              to specify the port of the nailgun server\n");
  fprintf(stderr, "                               (default is NAILGUN_PORT environment variable\n");
  fprintf(stderr, "                               if set, otherwise 2113)\n");  
  fprintf(stderr, "   --nailgun-filearg FILE      places the entire contents of FILE into the\n");
  fprintf(stderr, "                               next argument, which is interpreted as a string\n");
  fprintf(stderr, "                               using the server's default character set.  May be\n");
  fprintf(stderr, "                               specified more than once.\n");
  fprintf(stderr, "   --nailgun-help              print this message and exit\n");

  cleanUpAndExit(exitcode);
}

int main(int argc, char *argv[], char *env[]) {
  int i;
  struct sockaddr_in server_addr;
  char *nailgun_server;        /* server as specified by user */
  char *nailgun_port;          /* port as specified by user */
  char *cwd;
  u_short port;                /* port */
  struct hostent *hostinfo;
  char *cmd;
  int firstArgIndex;           /* the first argument _to pass to the server_ */

  #ifndef WIN32
    fd_set readfds;
    int eof = 0;
    struct timeval readtimeout;
  #endif

  #ifdef WIN32
  initSockets();
  #endif
  
  /* start with environment variable.  default to localhost if not defined. */
  nailgun_server = getenv("NAILGUN_SERVER");
  if (nailgun_server == NULL) {
    nailgun_server = "127.0.0.1";
  }
  
  /* start with environment variable.  default to normal nailgun port if not defined */
  nailgun_port = getenv("NAILGUN_PORT");
  if (nailgun_port == NULL) {
    nailgun_port = NAILGUN_PORT_DEFAULT;
  }
  
  /* look at the command used to launch this program.  if it was "ng", then the actual
     command to issue to the server must be specified as another argument.  if it
     wasn't ng, assume that the desired command name was symlinked to ng in the user's
     filesystem, and use the symlink name (without path info) as the command for the server. */
  cmd = shortClientName(argv[0]);

  if (isNailgunClientName(cmd)) {
    cmd = NULL;
  }

  /* if executing just the ng client with no arguments or -h|--help, then
     display usage and exit.  Don't handle -h|--help if a command other than
     ng or ng.exe was used, since the appropriate nail should then handle
     --help. */
  if (cmd == NULL && 
        (argc == 1 || 
	  (argc == 2 && strcmp("--help", argv[1]) == 0) ||
	  (argc == 2 && strcmp("-h", argv[1]) == 0))) usage(0);
     
  firstArgIndex = 1;

  /* quite possibly the lamest commandline parsing ever. 
     look for the two args we care about (--nailgun-server and
     --nailgun-port) and NULL them and their parameters after
     reading them if found.  later, when we send args to the
     server, skip the null args. */
  for (i = 1; i < argc; ++i) {
    if (!strcmp("--nailgun-server", argv[i])) {
      if (i == argc - 1) usage(NAILGUN_BAD_ARGUMENTS);
      nailgun_server = argv[i + 1];
      argv[i] = argv[i + 1] = NULL;
      ++i;
    } else if(!strcmp("--nailgun-port", argv[i])) {
      if (i == argc - 1) usage(NAILGUN_BAD_ARGUMENTS);
      nailgun_port = argv[i + 1];
      argv[i] = argv[i + 1]= NULL;
      ++i;
    } else if (!strcmp("--nailgun-filearg", argv[i])) {
      /* just verify usage here.  do the rest when sending args. */
      if (i == argc - 1) usage (NAILGUN_BAD_ARGUMENTS);
    } else if (!strcmp("--nailgun-version", argv[i])) {
      printf("NailGun client version %s\n", NAILGUN_VERSION);
      cleanUpAndExit(0);
    } else if (!strcmp("--nailgun-showversion", argv[i])) {
      printf("NailGun client version %s\n", NAILGUN_VERSION);
      argv[i] = NULL;
    } else if (!strcmp("--nailgun-help", argv[i])) {
      usage(0);
    } else if (cmd == NULL) {
      cmd = argv[i];
      firstArgIndex = i + 1;
    }
  }

  /* if there's no command, we should only display usage info
     if the version number was not displayed. */
  if (cmd == NULL) {
    usage(NAILGUN_BAD_ARGUMENTS);
  }
  
  /* jump through a series of connection hoops */  
  hostinfo = gethostbyname(nailgun_server);

  if (hostinfo == NULL) {
    fprintf(stderr, "Unknown host: %s\n", nailgun_server);
    cleanUpAndExit(NAILGUN_CONNECT_FAILED);
  }
 
  port = atoi(nailgun_port);

  if ((nailgunsocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    cleanUpAndExit(NAILGUN_SOCKET_FAILED);
  }

  server_addr.sin_family = AF_INET;    
  server_addr.sin_port = htons(port);
  server_addr.sin_addr = *(struct in_addr *) hostinfo->h_addr;
  
  memset(&(server_addr.sin_zero), '\0', 8);

  if (connect(nailgunsocket, (struct sockaddr *)&server_addr,
    sizeof(struct sockaddr)) == -1) {
    perror("connect");
    cleanUpAndExit(NAILGUN_CONNECT_FAILED);
  } 
    
  /* ok, now we're connected.  first send all of the command line
     arguments for the server, if any.  remember that we may have
     marked some arguments NULL if we read them to specify the
     nailgun server and/or port */
  for(i = firstArgIndex; i < argc; ++i) {
    if (argv[i] != NULL) {
      if (!strcmp("--nailgun-filearg", argv[i])) {
        sendFileArg(argv[++i]);
      } else sendText(CHUNKTYPE_ARG, argv[i]);
    }
  }

  /* now send environment */  
  sendText(CHUNKTYPE_ENV, NAILGUN_FILESEPARATOR);
  sendText(CHUNKTYPE_ENV, NAILGUN_PATHSEPARATOR);
  for(i = 0; env[i]; ++i) {
    sendText(CHUNKTYPE_ENV, env[i]);
  }
  
  /* now send the working directory */
  cwd = getcwd(NULL, 0);
  sendText(CHUNKTYPE_DIR, cwd);
  free(cwd);
  
  /* and finally send the command.  this marks the point at which
     streams are linked between client and server. */
  sendText(CHUNKTYPE_CMD, cmd);

  
  /* initialise the std-* handles and the thread to send stdin to the server */ 
  #ifdef WIN32
  initIo();
  winStartInput();
  #endif

  /* stream forwarding loop */	
  while(1) {
    #ifndef WIN32
      FD_ZERO(&readfds);

      /* don't select on stdin if we've already reached its end */
      if (readyToSend && !eof) {
	FD_SET(NG_STDIN_FILENO, &readfds);
      }

      FD_SET(nailgunsocket, &readfds);

      memset(&readtimeout, '\0', sizeof(readtimeout));
      readtimeout.tv_usec = HEARTBEAT_TIMEOUT_MILLIS * 1000;
      if(select (nailgunsocket + 1, &readfds, NULL, NULL, &readtimeout) == -1) {
	  perror("select");
      }
	  
      if (FD_ISSET(nailgunsocket, &readfds)) {
    #endif
	processnailgunstream();
    #ifndef WIN32
      } else if (FD_ISSET(NG_STDIN_FILENO, &readfds)) {
	if (!processStdin()) {
	  FD_CLR(NG_STDIN_FILENO, &readfds);
	  eof = 1;
	}
      } else {
	sendHeartbeat();
      }
    #endif
  }  

  /* normal termination is triggered by the server, and so occurs in processExit(), above */
}
