/*
 * Micro-X -- an X server for DOS
 * Copyright (C) 1994 StarNet Communications Corp.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 * StarNet Communications Corp.
 * 550 Lakeside Dr. #3
 * Sunnyvale CA 94086 US
 * http://www.starnet.com
 * x-dos@starnet.com
 */

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

int _fastcall _near
tcpopen_init(arg, len, buf)
int arg, _near *len;
void _far *buf;
{
    dfputs("TCPOpen transport layer\r\n");
    *len = 0;
    return net_init(0);
}

int _fastcall _near
tcpopen_drain(arg, len, buf)
int arg, _near *len;
void _far *buf;
{
    char junk[512];

    *len = 0;
    return recv(arg | FD_SOCKET, junk, sizeof junk, 0);
}

int _fastcall _near
tcpopen_read(arg, len, buf)
int arg, _near *len;
void _far *buf;
{
    int ret;

    ret = recv(arg | FD_SOCKET, buf, *len, 0);
    if (ret < 0)
	return ret;
    *len = ret;
    return ret;
}

int _fastcall _near
tcpopen_write(arg, len, buf)
int arg, _near *len;
void _far *buf;
{
    return send(arg | FD_SOCKET, buf, *len, 0);
}

int _fastcall _near
tcpopen_recv(arg, len, buf)
int arg, _near *len;
void _far *buf;
{
    int ret;
    struct sockaddr_in in;

    ret = sizeof in;
    ret = recvfrom(arg | FD_SOCKET, (char _far *)buf + sizeof (struct net_addr),
	    *len, 0, (fptr)&in, &ret);
    if (ret < 0)
	return ret;
    *len = ret + sizeof (struct net_addr);
    ((struct net_addr _far *)buf)->socket = ntohs(in.sin_port);
    ((struct net_addr _far *)buf)->host = in.sin_addr.s_addr;
    return ret;
}

int _fastcall _near
tcpopen_sendto(arg, len, buf)
int arg, _near *len;
void _far *buf;
{
    struct sockaddr_in in;
    struct sendto_head head = *(struct sendto_head _far *)buf;

    in.sin_family = AF_INET;
    in.sin_addr.s_addr = head.addr.host;
    in.sin_port = htons(head.addr.socket);
    memset(in.sin_zero, 0, sizeof in.sin_zero);
    buf = (char _far *)buf + sizeof (struct sendto_head);
    *len -= sizeof (struct sendto_head);
    return sendto(arg | FD_SOCKET, buf, *len, 0, (fptr)&in, sizeof in);
}
