/*
 * asynchronous winsock services
 * 
 * (C) 1996 Alex Korobka.
 *
 * FIXME: telftp16 (ftp part) stalls on AsyncSelect with FD_ACCEPT.
 */
#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>
#include <sys/param.h>
#endif
#ifdef __svr4__
#include <sys/file.h>
#include <sys/filio.h>
#endif

extern int h_errno;

#include "windows.h"
#include "winsock.h"
#include "debug.h"

#ifndef FASYNC
#define FASYNC FIOASYNC
#endif

#define __WS_ASYNC_DEBUG	0

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

extern ws_async_ctl	async_ctl;
extern int		async_qid;

fd_set		 fd_read, fd_write, fd_excp;

/* ----------------------------------- 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;
}

void WINSOCK_cancel_async_op(HTASK16 hTask)
{
  ws_async_op*   p = __async_op_list;
  while( p ) 
     if(hTask == GetWindowTask16(p->hWnd)) 
        p->flags = 0;
}

void WINSOCK_link_async_op(ws_async_op* p_aop)
{
  if( __async_op_list ) __async_op_list->prev = p_aop;
  else FD_ZERO(&__async_io_fdset);

  p_aop->next = __async_op_list; 
  p_aop->prev = NULL;
  __async_op_list = p_aop;

  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)
{
  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: AsyncGetXbyY expilicitly raise it.
 */

void WINSOCK_sigio(int signal)
{
 struct timeval         timeout;
 fd_set                 check_set;
 ws_async_op*		p_aop;

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

/* ----------------------------------- child process IPC */

static void _sigusr1_handler_child(int sig)
{
   /* read message queue to decide which
    * async_ctl parameters to update 
    *
    * Note: we don't want to have SA_RESTART on this signal
    * handler, otherwise select() won't notice changed fd sets.
    */

   signal( SIGUSR1, _sigusr1_handler_child );
   while( msgrcv(async_qid, (struct msgbuf*)&async_ctl.ip,
          MTYPE_PARENT_SIZE, MTYPE_PARENT, IPC_NOWAIT) != -1 )
   {
       /* only ip.lParam is updated */
#if __WS_ASYNC_DEBUG
       printf("handler - event %08x\n", async_ctl.ip.lParam );
#endif

       switch( async_ctl.ip.lParam )
       {
	  /* These are events we are notified of.
	   */

          case   WS_FD_CONNECTED: async_ctl.lEvent &= ~WS_FD_CONNECT;
				  FD_SET(async_ctl.ws_sock->fd, &fd_read);
				  FD_SET(async_ctl.ws_sock->fd, &fd_write);
			  	  break;

          case   WS_FD_ACCEPT:  async_ctl.ws_sock->flags |= WS_FD_ACCEPT;
				FD_SET(async_ctl.ws_sock->fd, &fd_read);
                                FD_SET(async_ctl.ws_sock->fd, &fd_write);
                                break;
          case   WS_FD_OOB:     async_ctl.lEvent |= WS_FD_OOB;
				FD_SET(async_ctl.ws_sock->fd, &fd_excp);
                                break;
          case   WS_FD_READ:    async_ctl.lEvent |= WS_FD_READ;
				FD_SET(async_ctl.ws_sock->fd, &fd_read);
                                break;
          case   WS_FD_WRITE:   async_ctl.lEvent |= WS_FD_WRITE;
				FD_SET(async_ctl.ws_sock->fd, &fd_write);
                                break;
          default:
       }
   }
}

static int notify_parent( unsigned flag )
{
  if( flag & WSMSG_ASYNC_SELECT )
  {
     async_ctl.ip.mtype = MTYPE_CLIENT;
     while( msgsnd(async_qid, (struct msgbuf*)&(async_ctl.ip),
                               MTYPE_CLIENT_SIZE, 0) == -1 )
     {
       if( errno == EINTR ) continue;
#ifdef EIDRM
       else if( errno == EIDRM ) _exit(0);
#endif
       else 
       { 
	 perror("AsyncSelect(child)"); 
	 return 0; 
       }
     }
     kill(getppid(), SIGUSR1); 

#if __WS_ASYNC_DEBUG
  printf("handler - notify [%08x]\n", async_ctl.ip.lParam);
#endif
  }
  else /* use half-duplex pipe to handle variable length packets */
  {
     write(async_ctl.ws_aop->fd[1], &async_ctl.lLength, sizeof(unsigned) );
     write(async_ctl.ws_aop->fd[1], async_ctl.buffer, async_ctl.lLength );
#ifndef __EMX__
     kill(getppid(), SIGIO);    /* simulate async I/O */
#endif
#if __WS_ASYNC_DEBUG
  printf("handler - notify aop [%d, buf %d]\n", async_ctl.lLength, async_ctl.ws_aop->buflen);
#endif
     pause();
  }
  return 1;
}

/* ----------------------------------- async select */

static void setup_fd_sets()
{
   FD_ZERO(&fd_read); FD_ZERO(&fd_write); FD_ZERO(&fd_excp);

   if( async_ctl.lEvent & WS_FD_OOB) 
       FD_SET(async_ctl.ws_sock->fd, &fd_excp);
   if( async_ctl.lEvent & (WS_FD_ACCEPT | WS_FD_READ |
			   WS_FD_CONNECT | WS_FD_CLOSE) ) 
       FD_SET(async_ctl.ws_sock->fd, &fd_read);
   if( async_ctl.lEvent & (WS_FD_WRITE | WS_FD_CONNECT) ) 
       FD_SET(async_ctl.ws_sock->fd, &fd_write);
}

static void setup_sig_sets(sigset_t* sig_block)
{
   sigemptyset(sig_block);
   sigaddset(sig_block, SIGUSR1);
   sigprocmask( SIG_BLOCK, sig_block, NULL);
   signal( SIGUSR1, _sigusr1_handler_child );
}

void WINSOCK_do_async_select()
{
  sigset_t    sig_block;
  int	      sock_type, bytes;

  getsockopt(async_ctl.ws_sock->fd, SOL_SOCKET, SO_TYPE, &sock_type, &bytes);
  setup_sig_sets(&sig_block);
  setup_fd_sets();

  while(1)
  {
    int		val;

    if( sock_type != SOCK_STREAM )
        async_ctl.lEvent &= ~(WS_FD_ACCEPT | WS_FD_CONNECT);
    sigprocmask( SIG_UNBLOCK, &sig_block, NULL); 

#if __WS_ASYNC_DEBUG
    printf("select(2)[%i,%i,%i]... ", 
	     FD_ISSET(async_ctl.ws_sock->fd, &fd_read),
	     FD_ISSET(async_ctl.ws_sock->fd, &fd_write),
	     FD_ISSET(async_ctl.ws_sock->fd, &fd_excp));
#endif
    if( (val = select(async_ctl.ws_sock->fd + 1, 
		     &fd_read, &fd_write, &fd_excp, NULL)) == -1 )
      if( errno == EINTR ) continue;
#if __WS_ASYNC_DEBUG
    printf("got %i events\n", val);
#endif

#if __WS_ASYNC_DEBUG
    if( FD_ISSET(async_ctl.ws_sock->fd, &fd_read) )
	printf("handler - read is READY! [%08x]\n", async_ctl.lEvent & (WS_FD_READ | WS_FD_CLOSE));
#endif

    sigprocmask( SIG_BLOCK, &sig_block, NULL);
    async_ctl.ip.lParam = 0;
    if( async_ctl.ws_sock->flags & WS_FD_ACCEPT )
    {
	/* listening socket */
	
	FD_CLR(async_ctl.ws_sock->fd, &fd_read);
	FD_CLR(async_ctl.ws_sock->fd, &fd_write);

	async_ctl.ip.lParam = WSAMAKESELECTREPLY( WS_FD_ACCEPT, 0 );
        notify_parent( WSMSG_ASYNC_SELECT );
	continue;
    }
    else /* I/O socket */
    {
	if( async_ctl.lEvent & WS_FD_CONNECT )
	{
	  if( FD_ISSET(async_ctl.ws_sock->fd, &fd_write) ) 
	  {
	      /* success - reinit fd sets to start I/O */

	      if( async_ctl.lEvent & (WS_FD_READ | WS_FD_CLOSE))
		   FD_SET(async_ctl.ws_sock->fd, &fd_read);
	      else FD_CLR(async_ctl.ws_sock->fd, &fd_read);
	      if( async_ctl.lEvent & WS_FD_WRITE )
		   FD_SET(async_ctl.ws_sock->fd, &fd_write);
	      else FD_CLR(async_ctl.ws_sock->fd, &fd_write);

	      async_ctl.ip.lParam = WSAMAKESELECTREPLY( WS_FD_CONNECT, 0 );
	      async_ctl.lEvent &= ~WS_FD_CONNECT; /* one-shot */
	  }
	  else if( FD_ISSET(async_ctl.ws_sock->fd, &fd_read) )
	  {
              /* failure - do read() to get correct errno */

              if( read(async_ctl.ws_sock->fd, &bytes, 4) == -1 )
                  async_ctl.ip.lParam = WSAMAKESELECTREPLY( WS_FD_CONNECT, wsaErrno() );
              else continue;
	  } else continue; /* OOB?? */

          notify_parent( WSMSG_ASYNC_SELECT );
	}
	else /* connected socket */
	{

	  if( async_ctl.lEvent & WS_FD_OOB )
	    if( FD_ISSET(async_ctl.ws_sock->fd, &fd_excp) )
	    {
	      async_ctl.ip.lParam = WSAMAKESELECTREPLY( WS_FD_OOB, 0 );
	      async_ctl.lEvent &= ~WS_FD_OOB;
	      FD_CLR(async_ctl.ws_sock->fd, &fd_excp);
	      notify_parent( WSMSG_ASYNC_SELECT );
	    }
	    else FD_SET(async_ctl.ws_sock->fd, &fd_excp);

          if( async_ctl.lEvent & WS_FD_WRITE )
            if( FD_ISSET( async_ctl.ws_sock->fd, &fd_write ) )
            {
              async_ctl.ip.lParam = WSAMAKESELECTREPLY( WS_FD_WRITE, 0 );
              async_ctl.lEvent &= ~WS_FD_WRITE;
              FD_CLR(async_ctl.ws_sock->fd, &fd_write);
              notify_parent( WSMSG_ASYNC_SELECT );
            }
            else FD_SET(async_ctl.ws_sock->fd, &fd_write);

	  if( async_ctl.lEvent & (WS_FD_READ | WS_FD_CLOSE) )
	    if( FD_ISSET(async_ctl.ws_sock->fd, &fd_read) )
	    {
	      int 	ok = 0;

	      if( sock_type == SOCK_RAW ) ok = 1;
	      else if( ioctl( async_ctl.ws_sock->fd, FIONREAD, (char*)&bytes) == -1 )
	      {
		  async_ctl.ip.lParam = WSAMAKESELECTREPLY( WS_FD_READ, wsaErrno() );
		  FD_CLR( async_ctl.ws_sock->fd, &fd_read );
		  bytes = 0;
	      }

	      if( bytes || ok )	/* got data */
	      {
#if __WS_ASYNC_DEBUG
		  if( ok ) printf("\traw/datagram read pending\n");
		  else printf("\t%i bytes pending\n", bytes );
#endif
		  if( async_ctl.lEvent & WS_FD_READ )
		  {
		     async_ctl.ip.lParam = WSAMAKESELECTREPLY( WS_FD_READ, 0 );
		     async_ctl.lEvent &= ~WS_FD_READ;
		     if( !(async_ctl.lEvent & WS_FD_CLOSE) ) 
			   FD_CLR( async_ctl.ws_sock->fd, &fd_read );
		  }
		  else if( !(async_ctl.lEvent & (WS_FD_WRITE | WS_FD_OOB)) ) 
		       {
			  sigprocmask( SIG_UNBLOCK, &sig_block, NULL);
			  pause();
			  sigprocmask( SIG_BLOCK, &sig_block, NULL);
		       }
		       else continue;
	      }
	      else		/* 0 bytes to read */
	      {
		  val = read( async_ctl.ws_sock->fd, (char*)&bytes, 4);
	          if( errno == EWOULDBLOCK || errno == EINTR ) 
		  { 
#if __WS_ASYNC_DEBUG
		    printf("\twould block..\n");
#endif
		    continue;
		  }
		  switch( val )
		  {
		    case  0: errno = ENETDOWN;	/* ENETDOWN */
		    case -1: 			/* ECONNRESET */
			     async_ctl.ip.lParam = WSAMAKESELECTREPLY( WS_FD_CLOSE, wsaErrno() );
			     break;
		    default: continue;
		  }
		  async_ctl.lEvent &= ~(WS_FD_CLOSE | WS_FD_READ); /* one-shot */
		  FD_ZERO(&fd_read); FD_ZERO(&fd_write); 
	      }

	      notify_parent( WSMSG_ASYNC_SELECT );
	  }
	  else FD_SET(async_ctl.ws_sock->fd, &fd_read);

	} /* connected socket */
    } /* I/O socket */
  } /* while */
}


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

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

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

  printf("h_name = %08x\t[%s]\n", (unsigned)wshe->h_name, base + (unsigned)wshe->h_name);
  printf("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++ )
  {
	printf("%i - %08x ", i + 1, ptr[i]);
	printf(" [%s]\n", ((char*)base) + ptr[i]);
  }
  printf("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.init)
	 : gethostbyaddr(async_ctl.init,
		 	 async_ctl.lLength, async_ctl.lEvent);
  if( p_he ) size = WS_dup_he(pwsi, p_he, WS_DUP_SEGPTR | WS_DUP_OFFSET );
  if( size )
  {
     async_ctl.buffer = pwsi->buffer;
     async_ctl.lLength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
     notify_parent( 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.init)
	 : getprotobynumber(async_ctl.lEvent);
  if( p_pe ) size = WS_dup_pe(pwsi, p_pe, WS_DUP_SEGPTR | WS_DUP_OFFSET );
  if( size )
  {
     async_ctl.buffer = pwsi->buffer;
     async_ctl.lLength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
     notify_parent( 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.init, async_ctl.buffer)
	 : getservbyport(async_ctl.lEvent, async_ctl.init);
  if( p_se ) size = WS_dup_se(pwsi, p_se, WS_DUP_SEGPTR | WS_DUP_OFFSET );
  if( size )
  {
     async_ctl.buffer = pwsi->buffer;
     async_ctl.lLength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
     notify_parent( flag );
  }
  else _async_fail();
}

