<commit_before>/* common.c - lib-internal IRC-unrelated common routines
 * libsrsirc - a lightweight serious IRC lib - (C) 2012-15, <NAME>
 * See README for contact-, COPYING for license information. */

#define LOG_MODULE MOD_COMMON

#if HAVE_CONFIG_H
# include <config.h>
#endif


#include "common.h"


#include <ctype.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include <platform/base_net.h>
#include <platform/base_string.h>
#include <platform/base_time.h>

#include <logger/intlog.h>

#include <libsrsirc/defs.h>


static int tryhost(struct addrlist *ai, char *remaddr, size_t remaddr_sz,
    uint16_t *peerport, uint64_t to_us);

void
lsi_com_strNcat(char *dest, const char *src, size_t destsz)
{
	size_t len = strlen(dest);
	if (len + 1 >= destsz)
		return;
	size_t rem = destsz - (len + 1);

	char *ptr = dest + len;
	while (rem-- && *src) {
		*ptr++ = *src++;
	}
	*ptr = '\0';
}

size_t
lsi_com_strCchr(const char *str, char c)
{
	size_t r = 0;
	while (*str)
		if (*str++ == c)
			r++;
	return r;
}


char *
lsi_com_strNcpy(char *dst, const char *src, size_t dst_sz)
{
	dst[dst_sz-1] = '\0';
	while (--dst_sz)
		if (!(*dst++ = *src++))
			break;
	return dst;
}

int
lsi_com_consocket(const char *host, uint16_t port, char *remaddr,
    size_t remaddr_sz, uint16_t *peerport, uint64_t softto, uint64_t hardto)
{
	uint64_t hardtsend = hardto ? lsi_b_tstamp_us() + hardto : 0;

	struct addrlist *alist;
	int count = lsi_b_mkaddrlist(host, port, &alist);
	if (count <= 0)
		return -1;

	if (softto && hardto && softto * count < hardto)
		softto = hardto / count;

	int sck = -1;
	for (struct addrlist *ai = alist; ai; ai = ai->next) {
		uint64_t trem = 0;

		if (lsi_com_check_timeout(hardtsend, &trem)) {
			W("hard timeout");
			return false;
		}

		if (trem > softto)
			trem = softto;

		sck = tryhost(ai, remaddr, remaddr_sz, peerport, trem);

		if (sck != -1)
			break;
	}

	lsi_b_freeaddrlist(alist);

	return sck;
}

static int
tryhost(struct addrlist *ai, char *remaddr, size_t remaddr_sz,
    uint16_t *peerport, uint64_t to_us)
{
	int sck = lsi_b_socket(ai->ipv6);

	if (sck == -1)
		return -1;

	if (!lsi_b_blocking(sck, false))
		W("failed to set socket non-blocking, timeout will not work");

	int r = lsi_b_connect(sck, ai);
	if (r == 1)
		return sck;
	else if (r == -1)
		goto tryhost_fail;

	r = lsi_b_select(sck, false, to_us);

	if (r == 1) {
		if (!lsi_b_blocking(sck, true))
			W("failed to clear socket non-blocking mode");

		if (lsi_b_sock_ok(sck)) {
			if (remaddr && remaddr_sz)
				lsi_b_strNcpy(remaddr, ai->addrstr, remaddr_sz);
			if (peerport)
				*peerport = ai->port;

			return sck;
		} else
			W("could not connect socket");<commit_msg>add a lone debug statement<commit_after>/* common.c - lib-internal IRC-unrelated common routines
 * libsrsirc - a lightweight serious IRC lib - (C) 2012-15, <NAME>
 * See README for contact-, COPYING for license information. */

#define LOG_MODULE MOD_COMMON

#if HAVE_CONFIG_H
# include <config.h>
#endif


#include "common.h"


#include <ctype.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include <platform/base_net.h>
#include <platform/base_string.h>
#include <platform/base_time.h>

#include <logger/intlog.h>

#include <libsrsirc/defs.h>


static int tryhost(struct addrlist *ai, char *remaddr, size_t remaddr_sz,
    uint16_t *peerport, uint64_t to_us);

void
lsi_com_strNcat(char *dest, const char *src, size_t destsz)
{
	size_t len = strlen(dest);
	if (len + 1 >= destsz)
		return;
	size_t rem = destsz - (len + 1);

	char *ptr = dest + len;
	while (rem-- && *src) {
		*ptr++ = *src++;
	}
	*ptr = '\0';
}

size_t
lsi_com_strCchr(const char *str, char c)
{
	size_t r = 0;
	while (*str)
		if (*str++ == c)
			r++;
	return r;
}


char *
lsi_com_strNcpy(char *dst, const char *src, size_t dst_sz)
{
	dst[dst_sz-1] = '\0';
	while (--dst_sz)
		if (!(*dst++ = *src++))
			break;
	return dst;
}

int
lsi_com_consocket(const char *host, uint16_t port, char *remaddr,
    size_t remaddr_sz, uint16_t *peerport, uint64_t softto, uint64_t hardto)
{
	uint64_t hardtsend = hardto ? lsi_b_tstamp_us() + hardto : 0;

	struct addrlist *alist;
	int count = lsi_b_mkaddrlist(host, port, &alist);
	if (count <= 0)
		return -1;

	if (softto && hardto && softto * count < hardto)
		softto = hardto / count;

	int sck = -1;
	for (struct addrlist *ai = alist; ai; ai = ai->next) {
		uint64_t trem = 0;

		if (lsi_com_check_timeout(hardtsend, &trem)) {
			W("hard timeout");
			return false;
		}

		if (trem > softto)
			trem = softto;

		sck = tryhost(ai, remaddr, remaddr_sz, peerport, trem);

		if (sck != -1)
			break;
	}

	lsi_b_freeaddrlist(alist);

	return sck;
}

static int
tryhost(struct addrlist *ai, char *remaddr, size_t remaddr_sz,
    uint16_t *peerport, uint64_t to_us)
{
	D("trying host '%s' ('%s')", ai->reqname, ai->addrstr);
	int sck = lsi_b_socket(ai->ipv6);

	if (sck == -1)
		return -1;

	if (!lsi_b_blocking(sck, false))
		W("failed to set socket non-blocking, timeout will not work");

	int r = lsi_b_connect(sck, ai);
	if (r == 1)
		return sck;
	else if (r == -1)
		goto tryhost_fail;

	r = lsi_b_select(sck, false, to_us);

	if (r == 1) {
		if (!lsi_b_blocking(sck, true))
			W("failed to clear socket non-blocking mode");

		if (lsi_b_sock_ok(sck)) {
			if (remaddr && remaddr_sz)
				lsi_b_strNcpy(remaddr, ai->addrstr, remaddr_sz);
			if (peerport)
				*peerport = ai->port;

			return sck;
		} else
			W("could not connect socket");
{'fraction_non_alphanumeric': 0.14941902687000727, 'fraction_numerical': 0.01597676107480029, 'mean_word_length': 3.724699828473413, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '872919', 'n_tokens_mistral': 2511, 'n_tokens_neox': 2299, 'n_words': 607}