#ifndef AMITCP_TO_IW225
#define AMITCP_TO_IW225 1

#include <proto/socket.h>
#include <netinet/inetconfig.h>
#include <netinet/in.h>
#include <sys/syslog.h>

#define Syslog	      syslog
#define CloseSocket   s_close
#define IoctlSocket   s_ioctl
#define Errno	      s_errno

#define ObtainSocket(a1,a2,a3,a4)   s_inherit ((void *) a1)

#define UNIQUE_ID (-1)

static __inline long
Dup2Socket (long fd1, long fd2)
{
    if (fd2 == -1)
	return s_dup (fd1);

    return s_dup2 (fd1, fd2);
}

/*
** for ReleaseCopyOfSocket and ReleaseSocket(), the caller
** should be checking explicitly for -1, not for < 0. Otherwise,
** these can fail, if the memory on the user's machine is such
** that the negative bit (bit 31) is set...
*/

static __inline LONG
ReleaseCopyOfSocket (LONG fd, LONG id)
{
    if (id == UNIQUE_ID)
    {
	int
	    newfd = s_dup (fd);
	void
	    *val;

	if (newfd >= 0)
	{
	    val = s_release (newfd);
	    if (!val)
		return -1;

	    return (LONG) val;
	}

	return -1;
    }

    return -1;
}

static __inline LONG
ReleaseSocket (LONG fd, LONG id)
{
    if (id == UNIQUE_ID)
    {
	void
	    *val = s_release (fd);

	if (!val)
	    return -1;

	return (LONG) val;
    }

    return -1;
}

static __inline LONG
SetDTableSize (UWORD size)
{
    if (size > FD_SETSIZE)
	size = FD_SETSIZE;
    ConfigureInet (INET_MaxSocks, size, TAG_DONE);

    return size;
}

static __inline void
SetErrnoPtr (void *ptr, UBYTE size)
{
    if (size != 4)
    {
	/* ?? */
	return;
    }

    ConfigureInet (INET_Errno, ptr, TAG_DONE);
    return;
}

static __inline int
countbits (unsigned long x)
{
    x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
    x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
    x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
    x = (x & 0x0000FFFF) + ((x >>16) & 0x0000FFFF);

    return (int) (x & 255);
}

static __inline int
findbit (unsigned long x)
{
    int
	i;

    for (i = 31; i >= 0; i--)
    {
	if (x & (1 << i))
	    return i;
    }

    return -1;
}

static __inline void
SetSocketSignals (ULONG sigintrmask, ULONG sigiomask, ULONG sigurgmask)
{
    int
	sigio  = findbit (sigiomask),
	sigurg = findbit (sigurgmask);

    if (countbits (sigintrmask) != 0)
	syslog (LOG_WARNING, "Sigintrmask ignored 0x%lx", sigintrmask)

    if (countbits (sigiomask) > 1)
	syslog (LOG_WARNING, "Only most significant bit used in sigiomask 0x%lx", sigiomask);

    if (countbits (sigurgmask) > 1)
	syslog (LOG_WARNING, "Only most significant bit used in sigurgmask 0x%lx", sigurgmask);

    ConfigureInet (INET_SignalIO, sigio, INET_SignalUrgent, sigurg, TAG_DONE);

    return;
}

static __inline char *
Inet_NtoA (unsigned long addr)
{
    struct in_addr
	inaddr;

    inaddr.s_addr = addr;
    return inet_ntoa (inaddr);
}

static __inline unsigned long
Inet_MakeAddr (long net, long lna)
{
    struct in_addr
	inaddr = inet_makeaddr ((int) net, (int) lna);

    return inaddr.s_addr;
}

static __inline long
Inet_LnaOf (unsigned long addr)
{
    struct in_addr
	inaddr;

    inaddr.s_addr = addr;
    return inet_lnaof (inaddr);
}

static __inline long
Inet_NetOf (unsigned long in)
{
    struct in_addr
	inaddr;

    inaddr.s_addr = in;
    return inet_netof (inaddr);
}
#endif /* AMITCP_TO_IW225 */


