#include "defs.h"
#include "rpc.h"
#include "funcs.h"
#include <string.h>

int
net_read(fd, buf, size)
int fd;
void *buf;
int size;
{
    short ctrl[3];

    if (size > net_shared_size) {
	size = net_shared_size;
    }
    ctrl[0] = FUNC_READ;
    ctrl[1] = fd;
    ctrl[2] = size;
    rpc_call(net_handle, sizeof ctrl, sizeof ctrl, ctrl);
    if (ctrl[0] < 0) {
	neterrno = ctrl[2];
	if (neterrno == NETERR_ERRNO)
	    map_errno(ctrl[1]);
	return -1;
    }
    _fmemcpy(buf, net_shared, ctrl[0]);
    return ctrl[0];
}

int
net_write(fd, buf, size)
int fd;
const void *buf;
int size;
{
    short ctrl[3];

    if (size > net_shared_size) {
	size = net_shared_size;
    }
    ctrl[0] = FUNC_WRITE;
    ctrl[1] = fd;
    ctrl[2] = size;
    _fmemcpy(net_shared, buf, size);
    rpc_call(net_handle, sizeof ctrl, sizeof ctrl, ctrl);
    if (ctrl[0] < 0) {
	neterrno = ctrl[2];
	if (neterrno == NETERR_ERRNO)
	    map_errno(ctrl[1]);
	return -1;
    }
    return ctrl[0];
}

int
net_sendto(fd, buf, size, addr, flags)
int fd;
const void *buf;
int size;
const struct net_addr *addr;
int flags;
{
    short ctrl[4 + sizeof (struct net_addr) / sizeof (short)];

    if (size > net_shared_size) {
	size = net_shared_size;
	if (!size)
		return 0;
    }
    ctrl[0] = FUNC_SENDTO;
    ctrl[1] = fd;
    ctrl[2] = size;
    ctrl[3] = flags;
    *(struct net_addr *)&ctrl[4] = *addr;
    _fmemcpy(net_shared, buf, size);
    rpc_call(net_handle, sizeof ctrl, sizeof ctrl, ctrl);
    if (ctrl[0] < 0) {
	neterrno = ctrl[2];
	if (neterrno == NETERR_ERRNO)
	    map_errno(ctrl[1]);
	return -1;
    }
    return ctrl[0];
}

int
net_recv(fd, buf, size, addr)
int fd;
void *buf;
int size;
struct net_addr *addr;
{
    short ctrl[1 + sizeof (struct net_addr) / sizeof (short)];

    if (size > net_shared_size) {
	size = net_shared_size;
    }
    ctrl[0] = FUNC_RECV;
    ctrl[1] = fd;
    ctrl[2] = size;
    rpc_call(net_handle, sizeof ctrl, sizeof ctrl, ctrl);
    if (ctrl[0] < 0) {
	neterrno = ctrl[2];
	if (neterrno == NETERR_ERRNO)
	    map_errno(ctrl[1]);
	return -1;
    }
    if (addr)
	*addr = *(struct net_addr *)&ctrl[1];
    _fmemcpy(buf, net_shared, ctrl[0]);
    return ctrl[0];
}
