<commit_before>/*-------------------------------------------------------------------------
 *
 * ip.c
 *	  IPv6-aware network access.
 *
 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.6 2003/04/03 21:50:23 tgl Exp $
 *
 * This file and the IPV6 implementation were initially provided by
 * <NAME> <<EMAIL>>, Linux Based Systems Design
 * http://www.lbsd.net.
 *
 *-------------------------------------------------------------------------
 */

/* This is intended to be used in both frontend and backend, so use c.h */
#include "c.h"

#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include <arpa/inet.h>
#include <sys/file.h>

#include "libpq/ip.h"


static int   rangeSockAddrAF_INET(const SockAddr *addr,
								  const SockAddr *netaddr,
								  const SockAddr *netmask);

#ifdef HAVE_IPV6
static int   rangeSockAddrAF_INET6(const SockAddr *addr,
								   const SockAddr *netaddr,
								   const SockAddr *netmask);
static void  convSockAddr6to4(const SockAddr *src, SockAddr *dst);
#endif

#ifdef HAVE_UNIX_SOCKETS
static int getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
							struct addrinfo **result);
#endif


/*
 *	getaddrinfo2 - get address info for Unix, IPv4 and IPv6 sockets
 */
int
getaddrinfo2(const char *hostname, const char *servname,
			 const struct addrinfo *hintp, struct addrinfo **result)
{
#ifdef HAVE_UNIX_SOCKETS
	if (hintp != NULL && hintp->ai_family == AF_UNIX)
		return getaddrinfo_unix(servname, hintp, result);
#endif

	/* NULL has special meaning to getaddrinfo */
	return getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
					   servname, hintp, result);
}


/*
 *	freeaddrinfo2 - free IPv6 addrinfo structures
 */
void
freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
{
#ifdef HAVE_UNIX_SOCKETS
	if (hint_ai_family == AF_UNIX)
	{
		struct addrinfo *p;

		while (ai != NULL)
		{
			p = ai;
			ai = ai->ai_next;
			free(p->ai_addr);
			free(p);
		}
	}
	else
#endif   /* HAVE_UNIX_SOCKETS */
		freeaddrinfo(ai);
}


#if defined(HAVE_UNIX_SOCKETS)
/* -------
 *	getaddrinfo_unix - get unix socket info using IPv6-compatible API
 *
 *	Bug:  only one addrinfo is set even though hintsp is NULL or
 *		  ai_socktype is 0
 *		  AI_CANONNAME is not supported.
 * -------
 */
static int
getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
				 struct addrinfo **result)
{
	struct addrinfo hints;
	struct addrinfo *aip;
	struct sockaddr_un *unp;

	MemSet(&hints, 0, sizeof(hints));

	if (hintsp == NULL)
	{
		hints.ai_family = AF_UNIX;
		hints.ai_socktype = SOCK_STREAM;
	}
	else
		memcpy(&hints, hintsp, sizeof(hints));

	if (hints.ai_socktype == 0)
		hints.ai_socktype = SOCK_STREAM;

	if (hints.ai_family != AF_UNIX)
	{
		/* shouldn't have been called */
		return EAI_ADDRFAMILY;
	}

	aip = calloc(1, sizeof(struct addrinfo));
	if (aip == NULL)
		return EAI_MEMORY;

	aip->ai_family = AF_UNIX;
	aip->ai_socktype = hints.ai_socktype;
	aip->ai_protocol = hints.ai_protocol;
	aip->ai_next = NULL;
	aip->ai_canonname = NULL;
	*result = aip;

	unp = calloc(1, sizeof(struct sockaddr_un));
	if (aip == NULL)
		return EAI_MEMORY;

	unp->sun_family = AF_UNIX;
	aip->ai_addr = (struct sockaddr *) unp;
	aip->ai_addrlen = sizeof(struct sockaddr_un);

	if (strlen(path) >= sizeof(unp->sun_path))
		return EAI_SERVICE;
	strcpy(unp->sun_path, path);

#if SALEN
	unp->sun_len = sizeof(struct sockaddr_un);
#endif   /* SALEN */

	if (hints.ai_flags & AI_PASSIVE)
		unlink(unp->sun_path);

	return 0;
}
#endif   /* HAVE_UNIX_SOCKETS */

/* ----------
 * SockAddr_ntop - set IP address string from SockAddr
 *
 * parameters...  sa	: SockAddr union
 *				  dst	: buffer for address string
 *				  cnt	: sizeof dst
 *				  v4conv: non-zero: if address is IPv4 mapped IPv6 address then
 *						  convert to IPv4 address.
 * returns... pointer to dst
 * if sa.sa_family is not AF_INET or AF_INET6 dst is set as empy string.
 * ----------
 */
char *
SockAddr_ntop(const SockAddr *sa, char *dst, size_t cnt, int v4conv)
{
	switch (sa->sa.sa_family)
	{
		case AF_INET:
#ifdef HAVE_IPV6<commit_msg>getaddrinfo has no business doing unlink().<commit_after>/*-------------------------------------------------------------------------
 *
 * ip.c
 *	  IPv6-aware network access.
 *
 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.7 2003/04/22 03:52:56 tgl Exp $
 *
 * This file and the IPV6 implementation were initially provided by
 * <NAME> <<EMAIL>>, Linux Based Systems Design
 * http://www.lbsd.net.
 *
 *-------------------------------------------------------------------------
 */

/* This is intended to be used in both frontend and backend, so use c.h */
#include "c.h"

#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include <arpa/inet.h>
#include <sys/file.h>

#include "libpq/ip.h"


static int   rangeSockAddrAF_INET(const SockAddr *addr,
								  const SockAddr *netaddr,
								  const SockAddr *netmask);

#ifdef HAVE_IPV6
static int   rangeSockAddrAF_INET6(const SockAddr *addr,
								   const SockAddr *netaddr,
								   const SockAddr *netmask);
static void  convSockAddr6to4(const SockAddr *src, SockAddr *dst);
#endif

#ifdef HAVE_UNIX_SOCKETS
static int getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
							struct addrinfo **result);
#endif


/*
 *	getaddrinfo2 - get address info for Unix, IPv4 and IPv6 sockets
 */
int
getaddrinfo2(const char *hostname, const char *servname,
			 const struct addrinfo *hintp, struct addrinfo **result)
{
#ifdef HAVE_UNIX_SOCKETS
	if (hintp != NULL && hintp->ai_family == AF_UNIX)
		return getaddrinfo_unix(servname, hintp, result);
#endif

	/* NULL has special meaning to getaddrinfo */
	return getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
					   servname, hintp, result);
}


/*
 *	freeaddrinfo2 - free IPv6 addrinfo structures
 */
void
freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
{
#ifdef HAVE_UNIX_SOCKETS
	if (hint_ai_family == AF_UNIX)
	{
		struct addrinfo *p;

		while (ai != NULL)
		{
			p = ai;
			ai = ai->ai_next;
			free(p->ai_addr);
			free(p);
		}
	}
	else
#endif   /* HAVE_UNIX_SOCKETS */
		freeaddrinfo(ai);
}


#if defined(HAVE_UNIX_SOCKETS)
/* -------
 *	getaddrinfo_unix - get unix socket info using IPv6-compatible API
 *
 *	Bug:  only one addrinfo is set even though hintsp is NULL or
 *		  ai_socktype is 0
 *		  AI_CANONNAME is not supported.
 * -------
 */
static int
getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
				 struct addrinfo **result)
{
	struct addrinfo hints;
	struct addrinfo *aip;
	struct sockaddr_un *unp;

	MemSet(&hints, 0, sizeof(hints));

	if (hintsp == NULL)
	{
		hints.ai_family = AF_UNIX;
		hints.ai_socktype = SOCK_STREAM;
	}
	else
		memcpy(&hints, hintsp, sizeof(hints));

	if (hints.ai_socktype == 0)
		hints.ai_socktype = SOCK_STREAM;

	if (hints.ai_family != AF_UNIX)
	{
		/* shouldn't have been called */
		return EAI_ADDRFAMILY;
	}

	aip = calloc(1, sizeof(struct addrinfo));
	if (aip == NULL)
		return EAI_MEMORY;

	aip->ai_family = AF_UNIX;
	aip->ai_socktype = hints.ai_socktype;
	aip->ai_protocol = hints.ai_protocol;
	aip->ai_next = NULL;
	aip->ai_canonname = NULL;
	*result = aip;

	unp = calloc(1, sizeof(struct sockaddr_un));
	if (aip == NULL)
		return EAI_MEMORY;

	unp->sun_family = AF_UNIX;
	aip->ai_addr = (struct sockaddr *) unp;
	aip->ai_addrlen = sizeof(struct sockaddr_un);

	if (strlen(path) >= sizeof(unp->sun_path))
		return EAI_SERVICE;
	strcpy(unp->sun_path, path);

#if SALEN
	unp->sun_len = sizeof(struct sockaddr_un);
#endif   /* SALEN */

	return 0;
}
#endif   /* HAVE_UNIX_SOCKETS */

/* ----------
 * SockAddr_ntop - set IP address string from SockAddr
 *
 * parameters...  sa	: SockAddr union
 *				  dst	: buffer for address string
 *				  cnt	: sizeof dst
 *				  v4conv: non-zero: if address is IPv4 mapped IPv6 address then
 *						  convert to IPv4 address.
 * returns... pointer to dst
 * if sa.sa_family is not AF_INET or AF_INET6 dst is set as empy string.
 * ----------
 */
char *
SockAddr_ntop(const SockAddr *sa, char *dst, size_t cnt, int v4conv)
{
	switch (sa->sa.sa_family)
	{
		case AF_INET:
#ifdef HAVE_IPV6
{'fraction_non_alphanumeric': 0.1560364464692483, 'fraction_numerical': 0.012984054669703872, 'mean_word_length': 3.042817679558011, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 62, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2722072', 'n_tokens_mistral': 3524, 'n_tokens_neox': 3197, 'n_words': 848}