/*
 *  Copyright (C) 2011-2012 Christian Beier <dontmind@freeshell.org>
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
 *
 *  This 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 2 of the License, or
 *  (at your option) any later version.
 *
 *  This software 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 software; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 *  USA.
 */

/*
 * listen.c - listen for incoming connections
 */

#ifdef __STRICT_ANSI__
#define _BSD_SOURCE
#endif
#include <unistd.h>
#include <sys/types.h>
#ifdef WIN32
#define close closesocket
#include <winsock2.h>
#ifdef _MINGW32
#undef max
#endif // #ifdef _MINGW32
#else // #ifdef WIN32
#include <sys/wait.h>
#include <sys/utsname.h>
#endif
#include <sys/time.h>
#include <rfb/rfbclient.h>

/*
 * listenForIncomingConnections() - listen for incoming connections from
 * servers, and fork a new process to deal with each connection.
 */

void
listenForIncomingConnections(rfbClient* client)
{
#ifdef WIN32
  /* FIXME */
  rfbClientErr("listenForIncomingConnections on MinGW32 NOT IMPLEMENTED\n");
  return;
#else
  int listenSocket, listen6Socket = -1;
  fd_set fds;

  client->listenSpecified = TRUE;

  listenSocket = ListenAtTcpPortAndAddress(client->listenPort, client->listenAddress);

  if ((listenSocket < 0))
    return;

  rfbClientLog("%s -listen: Listening on port %d\n",
	  client->programName,client->listenPort);
  rfbClientLog("%s -listen: Command line errors are not reported until "
	  "a connection comes in.\n", client->programName);

#ifdef LIBVNCSERVER_IPv6 /* only try that if we're IPv6-capable, otherwise we may try to bind to the same port which would make all that listening fail */ 
  /* only do IPv6 listen of listen6Port is set */
  if (client->listen6Port > 0)
    {
      listen6Socket = ListenAtTcpPortAndAddress(client->listen6Port, client->listen6Address);

      if (listen6Socket < 0)
	return;

      rfbClientLog("%s -listen: Listening on IPV6 port %d\n",
		   client->programName,client->listenPort);
      rfbClientLog("%s -listen: Command line errors are not reported until "
		   "a connection comes in.\n", client->programName);
    }
#endif

  while (TRUE) {
    int r;
    /* reap any zombies */
    int status, pid;
    while ((pid= wait3(&status, WNOHANG, (struct rusage *)0))>0);

    /* TODO: callback for discard any events (like X11 events) */

    FD_ZERO(&fds); 

    if(listenSocket >= 0)
      FD_SET(listenSocket, &fds);  
    if(listen6Socket >= 0)
      FD_SET(listen6Socket, &fds);

    r = select(max(listenSocket, listen6Socket)+1, &fds, NULL, NULL, NULL);

    if (r > 0) {
      if (FD_ISSET(listenSocket, &fds))
	client->sock = AcceptTcpConnection(client->listenSock); 
      else if (FD_ISSET(listen6Socket, &fds))
	client->sock = AcceptTcpConnection(client->listen6Sock);

      if (client->sock < 0)
	return;
      if (!SetNonBlocking(client->sock))
	return;

      /* Now fork off a new process to deal with it... */

      switch (fork()) {

      case -1: 
	rfbClientErr("fork\n"); 
	return;

      case 0:
	/* child - return to caller */
	close(listenSocket);
	close(listen6Socket);
	return;

      default:
	/* parent - go round and listen again */
	close(client->sock); 
	break;
      }
    }
  }
#endif
}



/*
 * listenForIncomingConnectionsNoFork() - listen for incoming connections
 * from servers, but DON'T fork, instead just wait timeout microseconds.
 * If timeout is negative, block indefinitly.
 * Returns 1 on success (there was an incoming connection on the listen socket
 * and we accepted it successfully), -1 on error, 0 on timeout.
 */

int
listenForIncomingConnectionsNoFork(rfbClient* client, int timeout)
{
  fd_set fds;
  struct timeval to;
  int r;

  to.tv_sec= timeout / 1000000;
  to.tv_usec= timeout % 1000000;

  client->listenSpecified = TRUE;

  if (client->listenSock < 0)
    {
      client->listenSock = ListenAtTcpPortAndAddress(client->listenPort, client->listenAddress);

      if (client->listenSock < 0)
	return -1;

      rfbClientLog("%s -listennofork: Listening on port %d\n",
		   client->programName,client->listenPort);
      rfbClientLog("%s -listennofork: Command line errors are not reported until "
		   "a connection comes in.\n", client->programName);
    }

#ifdef LIBVNCSERVER_IPv6 /* only try that if we're IPv6-capable, otherwise we may try to bind to the same port which would make all that listening fail */ 
  /* only do IPv6 listen of listen6Port is set */
  if (client->listen6Port > 0 && client->listen6Sock < 0)
    {
      client->listen6Sock = ListenAtTcpPortAndAddress(client->listen6Port, client->listen6Address);

      if (client->listen6Sock < 0)
	return -1;

      rfbClientLog("%s -listennofork: Listening on IPV6 port %d\n",
		   client->programName,client->listenPort);
      rfbClientLog("%s -listennofork: Command line errors are not reported until "
		   "a connection comes in.\n", client->programName);
    }
#endif

  FD_ZERO(&fds);

  if(client->listenSock >= 0)
    FD_SET(client->listenSock, &fds);
  if(client->listen6Sock >= 0)
    FD_SET(client->listen6Sock, &fds);

  if (timeout < 0)
    r = select(max(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, NULL);
  else
    r = select(max(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, &to);

  if (r > 0)
    {
      if (FD_ISSET(client->listenSock, &fds))
	client->sock = AcceptTcpConnection(client->listenSock); 
      else if (FD_ISSET(client->listen6Sock, &fds))
	client->sock = AcceptTcpConnection(client->listen6Sock);

      if (client->sock < 0)
	return -1;
      if (!SetNonBlocking(client->sock))
	return -1;

      if(client->listenSock >= 0) {
	close(client->listenSock);
	client->listenSock = -1;
      }
      if(client->listen6Sock >= 0) {
	close(client->listen6Sock);
	client->listen6Sock = -1;
      }
      return r;
    }

  /* r is now either 0 (timeout) or -1 (error) */
  return r;
}


