/*
 * 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 <assert.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 "miscemu.h"
#include "async.h"
#include "debug.h"

static void WINSOCK_async_handler(int unixfd,void *private);

/* 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 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_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;
      }
  }
  p_aop->next = __async_op_list;
  __async_op_list = p_aop;

  SIGNAL_MaskAsyncEvents( FALSE );

  ASYNC_RegisterFD(p_aop->fd[0],WINSOCK_async_handler,p_aop);
}

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;

  ASYNC_UnregisterFD(p_aop->fd[0],WINSOCK_async_handler);
}

/* ----------------------------------- 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).
 */

static void WINSOCK_async_handler(int unixfd,void *private)
{
  ws_async_op*		p_aop = (ws_async_op*)private;

  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]);
      if( p_aop->pid ) 
      { 
	  kill(p_aop->pid, SIGKILL); 
	  waitpid(p_aop->pid, NULL, WNOHANG);
	  p_aop->pid = 0;
      }
  }
}

/* ----------------------------------- 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 = (char*)pwsi->he;
      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 = (char*)pwsi->pe;
      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 = (char*)pwsi->se;
      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;
}
