/*
** Socket Functions
*/

#include <stdio.h>

#include <proto/miami.h>
#include <proto/socket.h>
#include <netdb.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/tcp.h>
#include <sys/time.h>
#include <bsdsocket/socketbasetags.h>
#include <sys/ioctl.h>

#include "socket.h"


void sock_Signal(long signum) {

	unsigned long sigmask;

	sigmask = (1L << signum);
	SocketBaseTags(SBTM_SETVAL(SBTC_SIGIOMASK),(char *)sigmask,TAG_DONE);

}


void sock_Ioctl(long s) {

	long temp;

	temp = 1;
	IoctlSocket(s,FIOASYNC,(char *)&temp);

}


long sock_Connect(char *addr, int port) {

	struct sockaddr_in sin;
	struct hostent *host;
	long s;

	host = gethostbyname(addr);
	if (host==0) return(-1);
	memcpy(&sin.sin_addr,host->h_addr,host->h_length);
	sin.sin_port = port;
	sin.sin_family = host->h_addrtype;
	sin.sin_len = sizeof(sin);

	s = socket(host->h_addrtype,SOCK_STREAM,0);
	if (s<0) return(-1);

	if ( connect(s,(struct sockaddr *)&sin,sin.sin_len) == -1 ) {
		CloseSocket(s);
		return(-1);
	}
	return(s);

}


int sock_Check(long s, long mode) {

	struct fd_set fds;
	struct timeval tv;

	FD_ZERO(&fds);
	FD_SET(s,&fds);
	if (mode==SOCK_CHECK) {
		tv.tv_sec=0;
		tv.tv_usec=5;
	} else {
		tv.tv_sec=2;
		tv.tv_usec=2;
	}

	if (mode!=SOCK_SEND)
		select(s+1,&fds,0,0,&tv);
	else
		return(select(s+1,0,&fds,0,&tv));

}


int sock_Send(long s, char *data, int len) {

	if ( send(s,data,len,NULL)!=len)
		return(-1);
	else
		return(0);

}


int sock_Recv(long s, char *buffer, int len) {

	long i=0;

	while ( i<len ) {
		if ( recv(s,buffer+i,1,NULL)>0)
			i++;
		else
			return(-1);
	}
	return(0);

}


void sock_Close(long s) {

	shutdown(s,2);
	CloseSocket(s);

}
