#include <sys/types.h>
#include <sys/sysent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "funcdef.h"
#include "../defs.h"
#include "../funcs.h"

char _near shared_buf[4096];

int _fastcall
tcpopen_init(buf)
short _far *buf;
{
    dfputs("TCPOpen transport layer\r\n");
    buf[0] = net_init(0);
    buf[2] = (u_short)shared_buf;
    buf[3] = (u_short)((u_long)(char far *)shared_buf >> 16);
    buf[4] = sizeof shared_buf;
    return 10;
}

int _fastcall
tcpopen_drain(buf)
short _far *buf;
{
    int ret;

    ret = recv(buf[1] | FD_SOCKET, shared_buf, sizeof shared_buf, 0);
    if (ret < 0)
	return ret;
    buf[0] = ret;
    return 2;
}

int _fastcall
tcpopen_read(buf)
short _far *buf;
{
    int ret;

    ret = recv(buf[1] | FD_SOCKET, shared_buf, buf[2], 0);
    if (ret < 0)
	return ret;
    buf[0] = ret;
    return 2;
}

int _fastcall
tcpopen_write(buf)
short _far *buf;
{
    int ret;

    ret = send(buf[1] | FD_SOCKET, shared_buf, buf[2], 0);
    if (ret < 0)
	return ret;
    buf[0] = ret;
    return 2;
}

int _fastcall
tcpopen_recv(buf)
short _far *buf;
{
    int ret;
    struct sockaddr_in in;
    int len;
    struct net_addr _far *addr = (struct net_addr _far *)&buf[1];


    len = sizeof in;
    ret = recvfrom(buf[1] | FD_SOCKET, shared_buf, buf[2], 0, (fptr)&in, &len);
    if (ret < 0)
	return ret;
    buf[0] = ret;
    addr->host = in.sin_addr.s_addr;
    addr->socket = ntohs(in.sin_port);
    return sizeof (struct net_addr) + sizeof (short);
}

int _fastcall
tcpopen_sendto(buf)
short _far *buf;
{
    struct sockaddr_in in;
    struct net_addr _far *addr = (struct net_addr _far *)&buf[4];
    int ret;

    in.sin_family = AF_INET;
    in.sin_addr.s_addr = addr->host;
    in.sin_port = htons(addr->socket);
    memset(in.sin_zero, 0, sizeof in.sin_zero);
    ret = sendto(buf[1] | FD_SOCKET, shared_buf, buf[2], 0, (fptr)&in, sizeof in);
    if (ret < 0)
	return ret;
    buf[0] = ret;
    return 2;
}
