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

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

#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;

    fcntl(fd, F_SETOWN, getpid());

    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;
 bzero(&timeout,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, 0);  
	      }
	      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;
       else if( errno == EIDRM ) _exit(0);
       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 );
     kill(getppid(), SIGIO);    /* simulate async I/O */
#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	      bytes;

  setup_sig_sets(&sig_block);
  setup_fd_sets();

  while(1)
  {
    int		val;

    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) )
	    {
	      if( ioctl( async_ctl.ws_sock->fd, FIONREAD, (char*)&bytes) != -1 )
	      {
	        if( bytes )	/* got data */
	        {
#if __WS_ASYNC_DEBUG
		  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); 
	        }
	      }
	      else async_ctl.ip.lParam = WSAMAKESELECTREPLY( WS_FD_READ, wsaErrno() );

	      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) );
     kill(getppid(), SIGIO);    /* simulate async I/O */
     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.ws_aop->init)
	 : gethostbyaddr(async_ctl.ws_aop->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();
  _exit(0);
}

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.ws_aop->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();
  _exit(0);
}

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.ws_aop->init, async_ctl.buffer)
	 : getservbyport(async_ctl.lEvent, async_ctl.ws_aop->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();
  _exit(0);
}

