/* vi: set sw=4 ts=4: */
/*
 * Utility routines.
 *
 * Connect to host at port using address resolusion from getaddrinfo
 *
 */

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include "libbb.h"

int xconnect(const char *host, const char *port)
{
#ifdef CONFIG_FEATURE_IPV6
	struct addrinfo hints;
	struct addrinfo *res;
	struct addrinfo *addr_info;
	int error;
	int s;

	memset(&hints, 0, sizeof(hints));
	/* set-up hints structure */
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	error = getaddrinfo(host, port, &hints, &res);
	if (error||!res)
		bb_perror_msg_and_die(gai_strerror(error));
	addr_info=res;
	while (res) {
		s=socket(res->ai_family, res->ai_socktype, res->ai_protocol);
		if (s<0)
		{
			error=s;
			res=res->ai_next;
			continue;
		}
		/* try to connect() to res->ai_addr */
		error = connect(s, res->ai_addr, res->ai_addrlen);
		if (error >= 0)
			break;
		close(s);
		res=res->ai_next;
	}
	freeaddrinfo(addr_info);
	if (error < 0)
	{
		bb_perror_msg_and_die("Unable to connect to remote host (%s)", host);
	}
	return s;
#else
	struct sockaddr_in s_addr;
	int s = socket(AF_INET, SOCK_STREAM, 0);
	struct servent *tserv;
	int port_nr=htons(atoi(port));
	struct hostent * he;

	if (port_nr==0 && (tserv = getservbyname(port, "tcp")) != NULL)
		port_nr = tserv->s_port;

	memset(&s_addr, 0, sizeof(struct sockaddr_in));
	s_addr.sin_family = AF_INET;
	s_addr.sin_port = port_nr;

	he = xgethostbyname(host);
	memcpy(&s_addr.sin_addr, he->h_addr, sizeof s_addr.sin_addr);

	if (connect(s, (struct sockaddr *)&s_addr, sizeof s_addr) < 0)
	{
		bb_perror_msg_and_die("Unable to connect to remote host (%s)", host);
	}
	return s;
#endif
}
