out_udp.c
author viric@llimona
Tue, 30 May 2006 12:57:31 +0200
changeset 58 c03287b2c3c1
parent 39 60858d13b22c
permissions -rw-r--r--
Now the tcp_server handles well the situation where there isn't a log file.

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

#include "syslog.h"

/* Prototypes */
static int init_socket(const char * restrict node,
		const char * restrict service);

/* Local globals */
static int out_socket;
static bool socket_enabled = false;


/* Returns -2 when the socket wasn't initialized by config, 0 when all was ok,
 * -1 on more important error */
int init_out_udp()
{
	char node[MAX_STRING];
	char service[MAX_STRING];

	/* Get the configuration */
	get_config(TO_UDP_HOST, node, MAX_STRING);
	get_config(TO_UDP_PORT, service, MAX_STRING);

	if (strncmp(node, "disabled", MAX_STRING) == 0)
		return -2;

	if (strncmp(service, "disabled", MAX_STRING) == 0)
		return -2;

	return init_socket(node, service);
}

/* Returns 0 when all was ok, -1 on error */
static int init_socket(const char * restrict node,
		const char * restrict service)
{
	int res;
	struct addrinfo *addr_res, *ptr;
	struct addrinfo hints;

	/* Prepare the hints for datagram */
	memset(&hints, 0, sizeof(hints));
	hints.ai_flags = AI_ADDRCONFIG;
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_addr = NULL;
	hints.ai_canonname = NULL;
	hints.ai_next = NULL;

	/* Ask the system for the service */
	res = getaddrinfo(node, service, &hints, &addr_res);
	if (res != 0)
	{
		fprintf(stderr, "Error trying to resolve the out_udp"
				" name: %s\n", gai_strerror(res));
		if (res == EAI_SYSTEM)
		{
			fprintf(stderr, " More system info: %s\n",
					strerror(errno));
		}
		return -1;
	}

	ptr = addr_res;
	do
	{
		res = -1; /* For further error catching */
		out_socket = socket(ptr->ai_family, ptr->ai_socktype,
				ptr->ai_protocol);
		if (out_socket == -1)
			continue;
		res = connect(out_socket, ptr->ai_addr, ptr->ai_addrlen);
		if (res == 0)
		{
			break;
		}
		else /* Unsuccesful connect */
		{
			close(out_socket);
			continue;
		}

	} while((ptr = ptr->ai_next) != NULL);

	freeaddrinfo(addr_res);

	/* If everything is fine */
	if (res == 0)
	{
		socket_enabled = true;
	}

	return res;
}


/* Return -2 when the socket is not enabled. Otherwise, the output of send().*/
int write_out_udp(const char * restrict buf, const int len)
{
	int res;

	if (!socket_enabled)
		return -2;

	res = send(out_socket, buf, len, 0);

	if (res == -1)
	{
		fprintf(stderr, "Error sending to the UDP socket: %s\n", 
			strerror(errno));
	}

	return res;
}

/* Return -2 when the socket is not enabled. Otherwise, the output of close().*/
int close_out_udp()
{
	int res;
	if (!socket_enabled)
		return -2;

	res = close(out_socket);

	if (res == -1)
	{
		fprintf(stderr, "Error closing the output UDP socket: %s\n", 
			strerror(errno));
	}

	return res;
}