/******************************************************************************
 *
 * RCS ID
 * $Id: sock_utils,v 1.2 2002/11/17 16:43:22 david Exp $
 *
 * HISTORY
 * $Log: sock_utils,v $
 * Revision 1.2  2002/11/17 16:43:22  david
 * Updates to compiler with new 32-bit compiler
 *
 * Revision 1.1  2000/04/22 14:50:57  david
 * Updates for nmbd module debugging.
 * Updates for integrating nmbd with main smbserver application
 *
 *
 *
 *****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>

#include "kernel.h"

#include "socklib.h"
#include "unixlib.h"
#include "inetlib.h"
/*#include "sockets:include.h.errno"*/
#include "sys/errno.h"
/*#include "sockets:include.h.netdb"*/
#include "netdb.h"
#include "sys/ioctl.h"


#include "mytypes.h"

#include "local.h"

#include "byteorder.h"

#include "smb.h"

#include "smbserver.h"

#include "smbswi.h"

extern BOOL dbghdr( int level, char *file, char *func, int line );

int mySockOpts(int s)
{
  int on = 1;

  if (socketioctl(s, FIONBIO, &on)<0)
  {
    return -1;
  }

  if (socketioctl(s, FIOASYNC, &on) < 0)
  {
    return -1;
  }

  return 0;
}

ssize_t write_non_block(int *fd,char *buffer,size_t len)
{
   struct timeval     timeout2;
   int                maxd;
/* TM */
/* unecassary input_set removed */
   fd_set             output_set;
   BOOL               result=True;
   size_t nwritten=0;
   int ret;

   DEBUG(2,("NMBD write_non_block %d\n", *fd));

   maxd=(*fd)+1;

   timeout2.tv_sec = 0;
   timeout2.tv_usec = 0;

   while (nwritten < len)
   {
/* TM */
/* unecassry input_set removed */
     /* zero output set */
     FD_ZERO (&output_set);

     /* set "listening" socket */
     FD_SET ((*fd), &output_set);

     if (select (maxd,
                 NULL,
                 &output_set,
                 NULL,
                 &timeout2) < 0)
      {
/* TM */
/* unecassry EINTR removed.
   return size -1 not false */
         /*perror ("select");*/
         return -1;
      }
      else
      {
         if (FD_ISSET ((*fd), &output_set))
         {
            ret = write(*fd,buffer+nwritten,len - nwritten);
            if (ret <= 0)
            {
/* TM */
/* unecassry EWOULDBLOCK removed. */
                  DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
                  /*closesockets();*/
                  /*exit(1);*/
                  *fd=0;
                  return -1;
            }
            else
            {
              nwritten += ret;
            }
         }
         if (nwritten < len)
         {
            /*event_process();*/
            /*WimpPoll();*/
         }
      }
   }

   return nwritten;
}

BOOL killSocket(int port,uint32 socket_addr)
{
  int i, fdTableSize;
  BOOL res=False;
  struct sockaddr_in sock;
  int namelen=sizeof(struct sockaddr_in);

  fdTableSize=getstablesize();
  if (fdTableSize>0)
  {
    for (i=0;i<fdTableSize;i++)
    {
      if (getsockname(i,(struct sockaddr *)&sock,&namelen)==0)
      {
         DEBUG(5,("socket %d, address %s, port %d\n",
                 i,inet_ntoa(sock.sin_addr),ntohs(sock.sin_port)));
         if (port==ntohs(sock.sin_port) &&
             socket_addr==ntohl(sock.sin_addr.s_addr))
         {
           DEBUG(0,("omniclient is using socket %d for port %d\n",
                    i,port));
           close(i);
           res=True;
           break;
         }
      }

    }
  }

  return res;
}

