#include "global.h"
#ifdef TCPGATE
#include "ctype.h"

#ifdef UNIX
#include <netdb.h>
#include <netinet/in.h>
#include "mbuf.h"
#else
#include "socket.h"
#endif
#include "bldsaddr.h"

#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: bldsaddr.c,v 1.12 2000/05/09 16:48:24 brian Exp $";
#endif

static union {
	struct sockaddr sa;
	struct sockaddr_in si;
} addr;

extern unsigned long int inet_addr (const char *cp);

/*---------------------------------------------------------------------------*/


struct sockaddr *
build_sockaddr (const char *name, int *addrlen)
{
char *host_name;
char *serv_name;
char buf[1024];
uint32 *iptr;

	memset ((char *) &addr, 0, sizeof (addr));
	*addrlen = 0;

	host_name = strncpy (buf, name, 1024);
	serv_name = strchr (buf, ':');
	if (!serv_name)
		return 0;
	*serv_name++ = 0;
	if (!*host_name || !*serv_name)
		return 0;

	addr.si.sin_family = AF_INET;

	if (!strcmp (host_name, "*"))
		addr.si.sin_addr.s_addr = INADDR_ANY;
	else if (!strcmp (host_name, "loopback"))
		addr.si.sin_addr.s_addr = inet_addr ("127.0.0.1");
	else if ((addr.si.sin_addr.s_addr = inet_addr (host_name)) == (unsigned long) -1L) {
		struct hostent *hp = gethostbyname (host_name);

		endhostent ();
		if (!hp)
			return 0;
		addr.si.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr;
	}
	if (isdigit (*serv_name & 0xff))
		(void) put16 ((unsigned char *) &addr.si.sin_port, (int16) atoi (serv_name));
	else {
		struct servent *sp = getservbyname (serv_name, (char *) 0);

		endservent ();
		if (!sp)
			return 0;
		addr.si.sin_port = (int16) sp->s_port;
	}


	iptr = (uint32 *) & addr.si.sin_addr;
	(void) put32 ((unsigned char *) &addr.si.sin_addr, *iptr);
	(void) put16 ((unsigned char *) &addr.si.sin_port, (int16) addr.si.sin_port);
	*addrlen = sizeof (struct sockaddr_in);

	return &addr.sa;
}

#endif /* TCPGATE */
