view xsocket.c @ 261:a03df7dc98f8

Add xsocket wrappers
author Daniele Nicolodi <daniele.nicolodi@obspm.fr>
date Tue, 16 Jun 2015 15:09:23 +0200
parents
children ebbe0f198322
line wrap: on
line source

#ifdef _CVI_
#include <winsock2.h>
#include <ansi_c.h>
#define strdup(s) StrDup(s)
#else
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ctype.h>
#include <math.h>
#include <stdarg.h>
#endif

#include "xsocket.h"


struct xsocket * xsocket(const char *hostname, const int port)
{
	struct xsocket *s = malloc(sizeof(struct xsocket));
	if (! s)
		return NULL;
	
	s->hostname = strdup(hostname);
	s->port = port;
	s->fd = -1;

	return s;
}


int xconnect(struct xsocket *s)
{
	int r, sock;
	struct sockaddr_in addr;
	struct hostent* host;	

#ifdef _CVI_
	WSADATA wsdata;
	WSAStartup(MAKEWORD(2,2), &wsdata);	
#endif

	if (s->fd >= 0)
		return 0;

	host = gethostbyname(s->hostname);
	if (host == NULL)
		return -errno;
	
	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0)
		return -errno;
	
	addr.sin_family = host->h_addrtype;
	memcpy(&addr.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
	addr.sin_port = htons(s->port);

	r = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
	if (r < 0)
		return -errno;
	
	s->fd = sock;
	return 0;
}


int xsend(struct xsocket *s, const char *data, size_t len)
{
	int r, retry = 2;

	while (--retry) {
		
		r = xconnect(s);
		if (r < 0)
			return r;
	
		r = send(s->fd, data, len, 0);
		if (r < 0) {
			close(s->fd);
			s->fd = -1;
			continue;
		}

		break;
	}

	return (r < 0) ? -errno : 0;
}


int xrecv(struct xsocket *s, char *buffer, size_t len)
{
	return recv(s->fd, buffer, len, 0);
}


int msend(struct xsocket *s, const char *data, size_t len)
{
	char *buffer = malloc(len + 2);
	memcpy(buffer, data, len);
	
	buffer[len++] = '\r';
	buffer[len++] = '\n';

	return xsend(s, buffer, len);
}


int mrecv(struct xsocket *s, char *buffer, size_t len)
{
	int n;

	n = xrecv(s, buffer, len);
	if (n < 0)
		return n;

	if ((buffer[--n] != '\n') || (buffer[--n] != '\r'))
		return -EINVAL;

	buffer[n] = '\0';

	return n;
}


int command(struct xsocket *s, char *frmt, ...)
{
	int r, n;
	char buffer[1024];
	va_list v;

	va_start(v, frmt);
	n = vsnprintf(buffer, sizeof(buffer) - 2, frmt, v);
	va_end(v);

	buffer[n++] = '\r';
	buffer[n++] = '\n';

	r = xsend(s, buffer, n);
	if (r < 0)
		return r;

	r = mrecv(s, buffer, sizeof(buffer));
	if (r < 0)
		return r;

	if (strcmp(buffer, "OK") != 0)
		return -EINVAL;

	return 0;
}