<commit_before>/*
 * Copyright (C) 2010-2016 <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "plibsys-private.h"
#include "pmem.h"
#include "psocketaddress.h"
#include "pstring.h"

#include <stdlib.h>
#include <string.h>

#ifndef P_OS_WIN
#  include <arpa/inet.h>
#endif

#ifdef PLIBSYS_HAS_GETADDRINFO
#  include <netdb.h>
#endif

/* According to Open Group specifications */
#ifndef INET_ADDRSTRLEN
#  ifdef P_OS_WIN
     /* On Windows it includes port number  */
#    define INET_ADDRSTRLEN 22
#  else
#    define INET_ADDRSTRLEN 16
#  endif
#endif

#ifdef AF_INET6
#  ifndef INET6_ADDRSTRLEN
#    ifdef P_OS_WIN
       /* On Windows it includes port number */
#      define INET6_ADDRSTRLEN 65
#    else
#      define INET6_ADDRSTRLEN 46
#    endif
#  endif
#endif

struct _PSocketAddress {
	PSocketFamily	family;
	union _addr {
		struct in_addr sin_addr;
#ifdef AF_INET6
		struct in6_addr sin6_addr;
#endif
	} 		addr;
	puint16 	port;
	puint32		flowinfo;
	puint32		scope_id;
};

P_LIB_API PSocketAddress *
p_socket_address_new_from_native (pconstpointer	native,
				  psize		len)
{
	PSocketAddress	*ret;
	puint16		family;

	if (P_UNLIKELY (native == NULL || len == 0))
		return NULL;

	if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSocketAddress))) == NULL))
		return NULL;

	family = ((struct sockaddr *) native)->sa_family;

	if (family == AF_INET) {
		if (len < sizeof (struct sockaddr_in)) {
			P_WARNING ("PSocketAddress: not enough space to convert from native");
			p_free (ret);
			return NULL;
		}

		memcpy (&ret->addr.sin_addr, &((struct sockaddr_in *) native)->sin_addr, sizeof (struct in_addr));
		ret->family = P_SOCKET_FAMILY_INET;
		ret->port   = p_ntohs (((struct sockaddr_in *) native)->sin_port);
		return ret;
	}
#ifdef AF_INET6
	else if (family == AF_INET6) {
		if (len < sizeof (struct sockaddr_in6)) {
			P_WARNING ("PSocketAddress: not enough space to convert from native");
			p_free (ret);
			return NULL;
		}

		memcpy (&ret->addr.sin6_addr, &((struct sockaddr_in6 *) native)->sin6_addr, sizeof (struct in6_addr));
		ret->family   = P_SOCKET_FAMILY_INET6;
		ret->port     = p_ntohs (((struct sockaddr_in *) native)->sin_port);
		ret->flowinfo = ((struct sockaddr_in6 *) native)->sin6_flowinfo;
		ret->scope_id = ((struct sockaddr_in6 *) native)->sin6_scope_id;
		return ret;
	}
#endif
	else {
		p_free (ret);
		return NULL;
	}
}

P_LIB_API PSocketAddress *
p_socket_address_new (const pchar	*address,
		      puint16		port)
{
	PSocketAddress		*ret;
#if defined (P_OS_WIN) || defined (PLIBSYS_HAS_GETADDRINFO)
	struct addrinfo		hints;
	struct addrinfo		*res;
#endif

#ifdef P_OS_WIN
	struct sockaddr_storage	sa;
	struct sockaddr_in 	*sin = (struct sockaddr_in *) &sa;
#  ifdef AF_INET6
	struct sockaddr_in6 	*sin6 = (struct sockaddr_in6 *) &sa;
#  endif /* AF_INET6 */
	pint 			len;
#endif /* P_OS_WIN */

	if (P_UNLIKELY (address == NULL))
		return NULL;

#if (defined (P_OS_WIN) || defined (PLIBSYS_HAS_GETADDRINFO)) && defined (AF_INET6)
	if (strchr (address, ':') != NULL) {
		memset (&hints, 0, sizeof (hints));

		hints.ai_family   = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_protocol = 0;
		hints.ai_flags    = AI_NUMERICHOST;

		if (getaddrinfo (address, NULL, &hints, &res) != 0)
			return NULL;

		if (res->ai_family  == AF_INET6 &&
		    res->ai_addrlen == sizeof (struct sockaddr_in6)) {
			((struct sockaddr_in6 *) res->ai_addr)->sin6_port = p_htons (port);
			ret = p_socket_address_new_from_native (res->ai_addr, res->ai_addrlen);
		} else
			ret = NULL;

		freeaddrinfo (res);

		return ret;
	}
#endif

	if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSocketAddress))) == NULL)) {
		P_ERROR ("PSocketAddress: failed to allocate memory");
		return NULL;
	}

	ret->port = port;<commit_msg>Add conditional compiler hints<commit_after>/*
 * Copyright (C) 2010-2016 <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "plibsys-private.h"
#include "pmem.h"
#include "psocketaddress.h"
#include "pstring.h"

#include <stdlib.h>
#include <string.h>

#ifndef P_OS_WIN
#  include <arpa/inet.h>
#endif

#ifdef PLIBSYS_HAS_GETADDRINFO
#  include <netdb.h>
#endif

/* According to Open Group specifications */
#ifndef INET_ADDRSTRLEN
#  ifdef P_OS_WIN
     /* On Windows it includes port number  */
#    define INET_ADDRSTRLEN 22
#  else
#    define INET_ADDRSTRLEN 16
#  endif
#endif

#ifdef AF_INET6
#  ifndef INET6_ADDRSTRLEN
#    ifdef P_OS_WIN
       /* On Windows it includes port number */
#      define INET6_ADDRSTRLEN 65
#    else
#      define INET6_ADDRSTRLEN 46
#    endif
#  endif
#endif

struct _PSocketAddress {
	PSocketFamily	family;
	union _addr {
		struct in_addr sin_addr;
#ifdef AF_INET6
		struct in6_addr sin6_addr;
#endif
	} 		addr;
	puint16 	port;
	puint32		flowinfo;
	puint32		scope_id;
};

P_LIB_API PSocketAddress *
p_socket_address_new_from_native (pconstpointer	native,
				  psize		len)
{
	PSocketAddress	*ret;
	puint16		family;

	if (P_UNLIKELY (native == NULL || len == 0))
		return NULL;

	if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSocketAddress))) == NULL))
		return NULL;

	family = ((struct sockaddr *) native)->sa_family;

	if (family == AF_INET) {
		if (len < sizeof (struct sockaddr_in)) {
			P_WARNING ("PSocketAddress: not enough space to convert from native");
			p_free (ret);
			return NULL;
		}

		memcpy (&ret->addr.sin_addr, &((struct sockaddr_in *) native)->sin_addr, sizeof (struct in_addr));
		ret->family = P_SOCKET_FAMILY_INET;
		ret->port   = p_ntohs (((struct sockaddr_in *) native)->sin_port);
		return ret;
	}
#ifdef AF_INET6
	else if (family == AF_INET6) {
		if (len < sizeof (struct sockaddr_in6)) {
			P_WARNING ("PSocketAddress: not enough space to convert from native");
			p_free (ret);
			return NULL;
		}

		memcpy (&ret->addr.sin6_addr, &((struct sockaddr_in6 *) native)->sin6_addr, sizeof (struct in6_addr));
		ret->family   = P_SOCKET_FAMILY_INET6;
		ret->port     = p_ntohs (((struct sockaddr_in *) native)->sin_port);
		ret->flowinfo = ((struct sockaddr_in6 *) native)->sin6_flowinfo;
		ret->scope_id = ((struct sockaddr_in6 *) native)->sin6_scope_id;
		return ret;
	}
#endif
	else {
		p_free (ret);
		return NULL;
	}
}

P_LIB_API PSocketAddress *
p_socket_address_new (const pchar	*address,
		      puint16		port)
{
	PSocketAddress		*ret;
#if defined (P_OS_WIN) || defined (PLIBSYS_HAS_GETADDRINFO)
	struct addrinfo		hints;
	struct addrinfo		*res;
#endif

#ifdef P_OS_WIN
	struct sockaddr_storage	sa;
	struct sockaddr_in 	*sin = (struct sockaddr_in *) &sa;
#  ifdef AF_INET6
	struct sockaddr_in6 	*sin6 = (struct sockaddr_in6 *) &sa;
#  endif /* AF_INET6 */
	pint 			len;
#endif /* P_OS_WIN */

	if (P_UNLIKELY (address == NULL))
		return NULL;

#if (defined (P_OS_WIN) || defined (PLIBSYS_HAS_GETADDRINFO)) && defined (AF_INET6)
	if (strchr (address, ':') != NULL) {
		memset (&hints, 0, sizeof (hints));

		hints.ai_family   = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_protocol = 0;
		hints.ai_flags    = AI_NUMERICHOST;

		if (P_UNLIKELY (getaddrinfo (address, NULL, &hints, &res) != 0))
			return NULL;

		if (P_LIKELY (res->ai_family  == AF_INET6 &&
			      res->ai_addrlen == sizeof (struct sockaddr_in6))) {
			((struct sockaddr_in6 *) res->ai_addr)->sin6_port = p_htons (port);
			ret = p_socket_address_new_from_native (res->ai_addr, res->ai_addrlen);
		} else
			ret = NULL;

		freeaddrinfo (res);

		return ret;
	}
#endif

	if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSocketAddress))) == NULL)) {
		P_ERROR ("PSocketAddress: failed to allocate memory");
		return NULL;
	}

	ret->port = port;
{'fraction_non_alphanumeric': 0.11609378556794901, 'fraction_numerical': 0.014113362167083997, 'mean_word_length': 3.9337450870297586, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3058885', 'n_tokens_mistral': 3438, 'n_tokens_neox': 3209, 'n_words': 898}