/*
 * asynchronous DNS services
 * 
 * (C) 1996,1997 Alex Korobka.
 *
 * TODO: Fork dns lookup helper during the startup (with a pipe
 *       for communication) and make it fork for a database request
 *       instead of forking the main process (i.e. something like
 *       Netscape 4.0).
 */

#include "config.h"

#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <errno.h>
#ifdef __EMX__
# include <sys/so_ioctl.h>
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
#endif
#ifdef __svr4__
# include <sys/file.h>
#endif

#include "winsock.h"
#include "windows.h"
#include "heap.h"
#include "ldt.h"
#include "message.h"
#include "selectors.h"
#include "miscemu.h"
#include "sig_context.h"
#include "debug.h"

#ifndef FASYNC
#define FASYNC FIOASYNC
#endif

/* async DNS op control struct */
typedef struct          
{
  ws_async_op*  ws_aop;
  char*         buffer;
  int           type;
  union
  {
    char*       init;
    char*       name;
    char*       addr;
  } rq;
  unsigned      ilength;
} ws_async_ctl;

extern HANDLE16	__ws_gethandle( void* ptr );
extern void*	__ws_memalloc( int size );
extern void	__ws_memfree( void* ptr );

/* NOTE: ws_async_op list is traversed inside the SIGIO handler! */

static int		__async_io_max_fd = 0;
static fd_set		__async_io_fdset;
static ws_async_op*	__async_op_list = NULL;

static void fixup_wshe(struct ws_hostent* p_wshe, void* base);
static void fixup_wspe(struct ws_protoent* p_wspe, void* base);
static void fixup_wsse(struct ws_servent* p_wsse, void* base);

/* ----------------------------------- async/non-blocking I/O */

int WINSOCK_async_io(int fd, int async)
{
    int fd_flags;

#ifndef __EMX__
    fcntl(fd, F_SETOWN, getpid());
#endif

    fd_flags = fcntl(fd, F_GETFL, 0);
    if (fcntl(fd, F_SETFL, (async)? fd_flags | FASYNC
                                  : fd_flags & ~FASYNC ) != -1) return 0;
    return -1;
}

int WINSOCK_unblock_io(int fd, int noblock)
{
    int fd_flags;

    fd_flags = fcntl(fd, F_GETFL, 0);
    if (fcntl(fd, F_SETFL, (noblock)? fd_flags |  O_NONBLOCK
                                    : fd_flags & ~O_NONBLOCK ) != -1) return 0;
    return -1;
}

int WINSOCK_check_async_op(ws_async_op* p_aop)
{
  ws_async_op*   p = __async_op_list;
  while( p ) if( p == p_aop ) return 1;
	     else p = p->next;
  return 0;
}

int WINSOCK_cancel_async_op(ws_async_op* p_aop)
{
    /* SIGIO unsafe! */

    if( WINSOCK_check_async_op(p_aop) )
    {
	if( !(p_aop->flags & WSMSG_DEAD_AOP) )
	{
            kill(p_aop->pid, SIGKILL);
            waitpid(p_aop->pid, NULL, 0); /* just in case */
            close(p_aop->fd[0]);
	}
        WINSOCK_unlink_async_op(p_aop);
	EVENT_DeleteIO( p_aop->fd[0], EVENT_IO_READ );
        p_aop->flags = 0;
	p_aop->hWnd = p_aop->uMsg = 0;
        return 1;
    }
    return 0;
}

void WINSOCK_cancel_task_aops(HTASK16 hTask, void (*__opfree)(void*))
{
    /* SIGIO safe, hTask == 0 cancels all outstanding async ops */

    int num = 0, num_dead = 0;
    ws_async_op*   p, *next;

    TRACE(winsock," cancelling async DNS requests... \n");

    SIGNAL_MaskAsyncEvents( TRUE );
    next = __async_op_list;
    while( (p = next) ) 
    {
	HTASK16 hWndTask = GetWindowTask16(p->hWnd);

	next = p->next;
	if(!hTask || !hWndTask || (hTask == hWndTask))
	{
	    num++;
	    if( p->flags & WSMSG_DEAD_AOP )
		num_dead++;

	    WINSOCK_cancel_async_op(p);
	    if( __opfree ) __opfree(p);
	}
    }
    SIGNAL_MaskAsyncEvents( FALSE );
    TRACE(winsock," -> %i total (%i active)\n", num, num - num_dead );
}

void WINSOCK_link_async_op(ws_async_op* p_aop)
{
  /* SIGIO safe */

  p_aop->prev = NULL;
  SIGNAL_MaskAsyncEvents( TRUE );
  if( __async_op_list )
  {
      ws_async_op*	p = __async_op_list;
      __async_op_list->prev = p_aop;

      /* traverse the list and retire dead ops created
       * by the signal handler (see below). */

      while( p )
      {
	  if( p->flags & WSMSG_DEAD_AOP )
	  {
	      ws_async_op* dead = p;

	      TRACE(winsock,"\treaping dead aop [%08x]\n", (unsigned)p );

	      p = p->next;
	      WINSOCK_unlink_async_op( dead );
	      __ws_memfree( dead );
	      continue;
	  }
	  p = p->next;
      }
  }
  else FD_ZERO(&__async_io_fdset);
  p_aop->next = __async_op_list;
  __async_op_list = p_aop;
  SIGNAL_MaskAsyncEvents( FALSE );

  FD_SET(p_aop->fd[0], &__async_io_fdset);
  if( p_aop->fd[0] > __async_io_max_fd ) 
		     __async_io_max_fd = p_aop->fd[0];
}

void WINSOCK_unlink_async_op(ws_async_op* p_aop)
{
  /* SIGIO unsafe! */

  if( p_aop == __async_op_list ) __async_op_list = p_aop->next;
  else
      p_aop->prev->next = p_aop->next;
  if( p_aop->next ) p_aop->next->prev = p_aop->prev;

  FD_CLR(p_aop->fd[0], &__async_io_fdset); 
  if( p_aop->fd[0] == __async_io_max_fd )
		      __async_io_max_fd--;
}

/* ----------------------------------- SIGIO handler -
 *
 * link_async_op/unlink_async_op allow to install generic
 * async IO handlers (provided that aop_control function is defined).
 *
 * Note: pipe-based handlers must raise explicit SIGIO with kill(2).
 */

HANDLER_DEF(WINSOCK_sigio)
{
 struct timeval         timeout;
 fd_set                 check_set;
 ws_async_op*		p_aop;

 HANDLER_INIT();

 check_set = __async_io_fdset;
 memset(&timeout, 0, sizeof(timeout));

 while( select(__async_io_max_fd + 1,
              &check_set, NULL, NULL, &timeout) > 0)
 {
   for( p_aop = __async_op_list;
	p_aop ; p_aop = p_aop->next )
      if( FD_ISSET(p_aop->fd[0], &check_set) )
          if( p_aop->aop_control(p_aop, AOP_IO) == AOP_CONTROL_REMOVE )
	  {
	     /* NOTE: memory management is signal-unsafe, therefore
	      * we can only set a flag to remove this p_aop later on.
	      */

	      p_aop->flags = WSMSG_DEAD_AOP;
	      close(p_aop->fd[0]);
	      FD_CLR(p_aop->fd[0],&__async_io_fdset);
	      if( p_aop->fd[0] == __async_io_max_fd )
				 __async_io_max_fd = p_aop->fd[0];
	      if( p_aop->pid ) 
	      { 
		  kill(p_aop->pid, SIGKILL); 
		  waitpid(p_aop->pid, NULL, WNOHANG);
		  p_aop->pid = 0;
	      }
	  }
   check_set = __async_io_fdset;
  }
}

/* ----------------------------------- getXbyY requests */

/* child process control struct */
static	 ws_async_ctl	async_ctl; 

static int aop_control(ws_async_op* p_aop, int flag )
{
    unsigned    lLength;

  /* success:   LOWORD(lLength) has the length of the struct
   *            to read.
   * failure:   LOWORD(lLength) is zero, HIWORD(lLength) contains
   *            the error code.
   */

    read(p_aop->fd[0], &lLength, sizeof(unsigned));
    if( LOWORD(lLength) )
    {
	if( (int)LOWORD(lLength) <= p_aop->buflen )
	{
            char* buffer = (p_aop->flags & WSMSG_WIN32_AOP)
		  ? p_aop->b.lin_base : (char*)PTR_SEG_TO_LIN(p_aop->b.seg_base);

            read(p_aop->fd[0], buffer, LOWORD(lLength));
            switch( p_aop->flags & WSMSG_ASYNC_RQMASK )
            {
		case WSMSG_ASYNC_HOSTBYNAME:
		case WSMSG_ASYNC_HOSTBYADDR:
		     fixup_wshe((struct ws_hostent*)buffer, p_aop->b.ptr_base); break;
		case WSMSG_ASYNC_PROTOBYNAME:
		case WSMSG_ASYNC_PROTOBYNUM:
		     fixup_wspe((struct ws_protoent*)buffer, p_aop->b.ptr_base); break;
		case WSMSG_ASYNC_SERVBYNAME:
		case WSMSG_ASYNC_SERVBYPORT:
		     fixup_wsse((struct ws_servent*)buffer, p_aop->b.ptr_base); break;
		default:
                     if( p_aop->flags ) WARN(winsock,"Received unknown async request!\n");
                     return AOP_CONTROL_REMOVE;
            }
	}
        else lLength =  ((UINT32)LOWORD(lLength)) | ((unsigned)WSAENOBUFS << 16);
    } /* failure */

     /* was a __WS_ASYNC_DEBUG statement */
     TRACE(winsock, "DNS aop completed: hWnd [%04x], uMsg [%04x], "
 	  "aop [%04x], event [%08lx]\n",
 	  p_aop->hWnd, p_aop->uMsg, __ws_gethandle(p_aop), (LPARAM)lLength);

    /* FIXME: update num_async_rq */
    EVENT_DeleteIO( p_aop->fd[0], EVENT_IO_READ );
    PostMessage32A( p_aop->hWnd, p_aop->uMsg, __ws_gethandle(p_aop), (LPARAM)lLength );
    
    return AOP_CONTROL_REMOVE;  /* one-shot request */
}


HANDLE16 __WSAsyncDBQuery(LPWSINFO pwsi, HWND32 hWnd, UINT32 uMsg, INT32 type, 
    LPCSTR init, INT32 len, LPCSTR proto, void* sbuf, INT32 buflen, UINT32 flag)
{
    /* queue 'flag' request and fork off its handler */

    async_ctl.ws_aop = (ws_async_op*)__ws_memalloc(sizeof(ws_async_op));

    if( async_ctl.ws_aop )
    {
	HANDLE16        handle = __ws_gethandle(async_ctl.ws_aop);

	if( pipe(async_ctl.ws_aop->fd) == 0 )
	{
	    async_ctl.rq.init = (char*)init;
	    async_ctl.ilength = len;
	    async_ctl.buffer = (char*)proto;
	    async_ctl.type = type;

	    async_ctl.ws_aop->hWnd = hWnd;
	    async_ctl.ws_aop->uMsg = uMsg;
	    async_ctl.ws_aop->b.ptr_base = sbuf; 
	    async_ctl.ws_aop->buflen = buflen;
	    async_ctl.ws_aop->flags = flag;
	    async_ctl.ws_aop->aop_control = &aop_control;

	    WINSOCK_link_async_op( async_ctl.ws_aop );

	    EVENT_AddIO( async_ctl.ws_aop->fd[0], EVENT_IO_READ );
	    pwsi->num_async_rq++;

	    async_ctl.ws_aop->pid = fork();
	    if( async_ctl.ws_aop->pid )
	    {
		TRACE(winsock, "\tasync_op = %04x (child %i)\n", 
				handle, async_ctl.ws_aop->pid);

		close(async_ctl.ws_aop->fd[1]);  /* write endpoint */
		if( async_ctl.ws_aop->pid > 0 )
		    return __ws_gethandle(async_ctl.ws_aop);

		/* fork() failed */

	        pwsi->num_async_rq--;
		EVENT_DeleteIO( async_ctl.ws_aop->fd[0], EVENT_IO_READ );
		close(async_ctl.ws_aop->fd[0]);
		pwsi->err = WSAEWOULDBLOCK;
	    }
	    else
	    {
	    	extern BOOL32 THREAD_InitDone;

	        THREAD_InitDone = FALSE;
		/* child process */

		close(async_ctl.ws_aop->fd[0]);  /* read endpoint */
		switch( flag & WSMSG_ASYNC_RQMASK )
		{
		    case WSMSG_ASYNC_HOSTBYADDR:
		    case WSMSG_ASYNC_HOSTBYNAME:
			WS_do_async_gethost(pwsi, flag);
			break;
		    case WSMSG_ASYNC_PROTOBYNUM:
		    case WSMSG_ASYNC_PROTOBYNAME:
			WS_do_async_getproto(pwsi, flag);
			break;
		    case WSMSG_ASYNC_SERVBYPORT:
		    case WSMSG_ASYNC_SERVBYNAME:
			WS_do_async_getserv(pwsi, flag);
			break;
		}
		_exit(0); 	/* skip  atexit()'ed cleanup */
	    }
	}
	else pwsi->err = wsaErrno(); /* failed to create pipe */

	__ws_memfree((void*)async_ctl.ws_aop);
    } else pwsi->err = WSAEWOULDBLOCK;
    return 0;
}

static int _async_notify()
{
    /* use half-duplex pipe to send variable length packets 
     * to the parent process */
     
    write(async_ctl.ws_aop->fd[1], &async_ctl.ilength, sizeof(unsigned));
    write(async_ctl.ws_aop->fd[1], async_ctl.buffer, async_ctl.ilength );

#ifndef __EMX__
    kill(getppid(), SIGIO);    /* simulate async I/O */
#endif

    /* was a __WS_ASYNC_DEBUG statement */
    TRACE(winsock, "handler - notify aop [%d, buf %d]\n", 
	  async_ctl.ilength, async_ctl.ws_aop->buflen);
    return 1;
}

static void _async_fail()
{
     /* write a DWORD with error code (low word is zero) */

     async_ctl.ilength =
        (h_errno < 0) ? (unsigned)WSAMAKEASYNCREPLY( 0, wsaErrno() )
                      : (unsigned)WSAMAKEASYNCREPLY( 0, wsaHerrno() );
     write(async_ctl.ws_aop->fd[1], &async_ctl.ilength, sizeof(unsigned) );
#ifndef __EMX__
     kill(getppid(), SIGIO);    /* simulate async I/O */
#endif

    /* was a __WS_ASYNC_DEBUG statement */
    TRACE(winsock, "handler - failed aop [%d, buf %d]\n", 
	  async_ctl.ilength, async_ctl.ws_aop->buflen);
}

void dump_ws_hostent_offset(struct ws_hostent* wshe)
{
  int		i;
  char*		base = (char*)wshe;
  unsigned*	ptr;

  DUMP("h_name = %08x\t[%s]\n", 
       (unsigned)wshe->h_name, base + (unsigned)wshe->h_name);
  DUMP("h_aliases = %08x\t[%08x]\n", 
       (unsigned)wshe->h_aliases, (unsigned)(base+(unsigned)wshe->h_aliases));
  ptr = (unsigned*)(base + (unsigned)wshe->h_aliases);
  for(i = 0; ptr[i]; i++ )
  {
	DUMP("%i - %08x [%s]\n", i + 1, ptr[i], ((char*)base) + ptr[i]);
  }
  DUMP("h_length = %i\n", wshe->h_length);
}

void WS_do_async_gethost(LPWSINFO pwsi, unsigned flag )
{  
  int			size = 0;
  struct hostent* 	p_he;

  close(async_ctl.ws_aop->fd[0]);

  p_he = (flag & WSMSG_ASYNC_HOSTBYNAME)
	 ? gethostbyname(async_ctl.rq.name)
	 : gethostbyaddr(async_ctl.rq.name,
		 	 async_ctl.ilength, async_ctl.type);

  TRACE(winsock,"DNS: got hostent for [%s]\n", async_ctl.rq.name );

  if( p_he ) /* convert to the Winsock format with internal pointers as offsets */
      size = WS_dup_he(pwsi, p_he, WS_DUP_OFFSET | 
		     ((flag & WSMSG_WIN32_AOP) ? WS_DUP_LINEAR : WS_DUP_SEGPTR) );
  if( size )
  {
      async_ctl.buffer = pwsi->buffer;
      async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
     _async_notify( flag );
  }
  else _async_fail();
}

void WS_do_async_getproto(LPWSINFO pwsi, unsigned flag )
{
  int			size = 0;
  struct protoent*	p_pe;

  close(async_ctl.ws_aop->fd[0]);
  p_pe = (flag & WSMSG_ASYNC_PROTOBYNAME)
	 ? getprotobyname(async_ctl.rq.name)
	 : getprotobynumber(async_ctl.type);

  TRACE(winsock,"DNS: got protoent for [%s]\n", async_ctl.rq.name );

  if( p_pe ) /* convert to the Winsock format with internal pointers as offsets */
      size = WS_dup_pe(pwsi, p_pe, WS_DUP_OFFSET |
		     ((flag & WSMSG_WIN32_AOP) ? WS_DUP_LINEAR : WS_DUP_SEGPTR) );
  if( size )
  {
      async_ctl.buffer = pwsi->buffer;
      async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
     _async_notify( flag );
  } 
  else _async_fail();
}

void WS_do_async_getserv(LPWSINFO pwsi, unsigned flag )
{
  int			size = 0;
  struct servent* 	p_se;

  close(async_ctl.ws_aop->fd[0]);
  p_se = (flag & WSMSG_ASYNC_SERVBYNAME)
	 ? getservbyname(async_ctl.rq.name, async_ctl.buffer)
	 : getservbyport(async_ctl.type, async_ctl.buffer);

  if( p_se ) /* convert to the Winsock format with internal pointers as offsets */
      size = WS_dup_se(pwsi, p_se, WS_DUP_OFFSET |
		      ((flag & WSMSG_WIN32_AOP) ? WS_DUP_LINEAR : WS_DUP_SEGPTR) );
  if( size )
  {
      async_ctl.buffer = pwsi->buffer;
      async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
     _async_notify( flag );
  }
  else _async_fail();
}

/* ----------------------------------- helper functions -
 *
 * Raw results from the pipe contain internal pointers stored as
 * offsets relative to the beginning of the buffer and we need
 * to apply a fixup before passing them to applications.
 *
 * NOTE: It is possible to exploit the fact that fork() doesn't 
 * change the buffer address by storing fixed up pointers right 
 * in the handler. However, this will get in the way if we ever 
 * get around to implementing DNS helper daemon a-la Netscape 4.x.
 */

void fixup_wshe(struct ws_hostent* p_wshe, void* base)
{
   /* add 'base' to ws_hostent pointers to convert them from offsets */

   int i;
   unsigned*    p_aliases,*p_addr;

   p_aliases = (unsigned*)((char*)p_wshe + (unsigned)p_wshe->h_aliases);
   p_addr = (unsigned*)((char*)p_wshe + (unsigned)p_wshe->h_addr_list);
   ((unsigned)(p_wshe->h_name)) += (unsigned)base;
   ((unsigned)(p_wshe->h_aliases)) += (unsigned)base;
   ((unsigned)(p_wshe->h_addr_list)) += (unsigned)base;
   for(i=0;p_aliases[i];i++) p_aliases[i] += (unsigned)base;
   for(i=0;p_addr[i];i++) p_addr[i] += (unsigned)base;
}

void fixup_wspe(struct ws_protoent* p_wspe, void* base)
{
   int i;
   unsigned*       p_aliases = (unsigned*)((char*)p_wspe + (unsigned)p_wspe->p_aliases);
   ((unsigned)(p_wspe->p_name)) += (unsigned)base;
   ((unsigned)(p_wspe->p_aliases)) += (unsigned)base;
   for(i=0;p_aliases[i];i++) p_aliases[i] += (unsigned)base;
}

void fixup_wsse(struct ws_servent* p_wsse, void* base)
{
   int i;
   unsigned*       p_aliases = (unsigned*)((char*)p_wsse + (unsigned)p_wsse->s_aliases);
   ((unsigned)(p_wsse->s_name)) += (unsigned)base;
   ((p_wsse->s_proto)) += (unsigned)base;
   ((p_wsse->s_aliases)) += (unsigned)base;
   for(i=0;p_aliases[i];i++) p_aliases[i] += (unsigned)base;
}

