<commit_before>/*
 * This file is part of buxton.
 *
 * Copyright (C) 2013 Intel Corporation
 *
 * buxton is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 */

/**
 * \file lbuxton.c Buxton library implementation
 */
#ifdef HAVE_CONFIG_H
	#include "config.h"
#endif

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <dirent.h>
#include <string.h>
#include <stdint.h>

#include "buxton.h"
#include "buxtonclient.h"
#include "buxtonkey.h"
#include "buxtonresponse.h"
#include "buxtonstring.h"
#include "configurator.h"
#include "hashmap.h"
#include "log.h"
#include "protocol.h"
#include "util.h"

static Hashmap *key_hash = NULL;

int buxton_set_conf_file(char *path)
{
	int r;
	struct stat st;

	r = stat(path, &st);
	if (r == -1) {
		return errno;
	} else {
		if (st.st_mode & S_IFDIR) {
			return EINVAL;
		}
	}

	buxton_add_cmd_line(CONFIG_CONF_FILE, path);

	return 0;
}

int buxton_open(BuxtonClient *client)
{
	_BuxtonClient **c = (_BuxtonClient **)client;
	_BuxtonClient *cl = NULL;
	int bx_socket, r;
	struct sockaddr_un remote;
	size_t sock_name_len;

	if ((bx_socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
		return -1;
	}

	remote.sun_family = AF_UNIX;
	sock_name_len = strlen(buxton_socket()) + 1;
	if (sock_name_len >= sizeof(remote.sun_path)) {
		buxton_log("Provided socket name: %s is too long, maximum allowed length is %d bytes\n",
			   buxton_socket(), sizeof(remote.sun_path));
		return -1;
	}

	strncpy(remote.sun_path, buxton_socket(), sock_name_len);
	r = connect(bx_socket, (struct sockaddr *)&remote, sizeof(remote));
	if ( r == -1) {
		close(bx_socket);
		return -1;
	}

	if (fcntl(bx_socket, F_SETFL, O_NONBLOCK)) {
		close(bx_socket);
		return -1;
	}

	if (!setup_callbacks()) {
		close(bx_socket);
		return -1;
	}

	cl = malloc0(sizeof(_BuxtonClient));
	if (!cl) {
		close(bx_socket);
		return -1;
	}

	cl->fd = bx_socket;
	*c = cl;

	return bx_socket;
}

void buxton_close(BuxtonClient client)
{
	_BuxtonClient *c;
	BuxtonKey key = NULL;
	Iterator i;

	/* Free all remaining allocated keys */
	HASHMAP_FOREACH_KEY(key, key, key_hash, i) {
		hashmap_remove_value(key_hash, key, key);
		buxton_key_free(key);
	}

	hashmap_free(key_hash);

	if (!client) {<commit_msg>libbuxton: Fix bug in hashmap freeing that can cause a segfault<commit_after>/*
 * This file is part of buxton.
 *
 * Copyright (C) 2013 Intel Corporation
 *
 * buxton is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 */

/**
 * \file lbuxton.c Buxton library implementation
 */
#ifdef HAVE_CONFIG_H
	#include "config.h"
#endif

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <dirent.h>
#include <string.h>
#include <stdint.h>

#include "buxton.h"
#include "buxtonclient.h"
#include "buxtonkey.h"
#include "buxtonresponse.h"
#include "buxtonstring.h"
#include "configurator.h"
#include "hashmap.h"
#include "log.h"
#include "protocol.h"
#include "util.h"

static Hashmap *key_hash = NULL;

int buxton_set_conf_file(char *path)
{
	int r;
	struct stat st;

	r = stat(path, &st);
	if (r == -1) {
		return errno;
	} else {
		if (st.st_mode & S_IFDIR) {
			return EINVAL;
		}
	}

	buxton_add_cmd_line(CONFIG_CONF_FILE, path);

	return 0;
}

int buxton_open(BuxtonClient *client)
{
	_BuxtonClient **c = (_BuxtonClient **)client;
	_BuxtonClient *cl = NULL;
	int bx_socket, r;
	struct sockaddr_un remote;
	size_t sock_name_len;

	if ((bx_socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
		return -1;
	}

	remote.sun_family = AF_UNIX;
	sock_name_len = strlen(buxton_socket()) + 1;
	if (sock_name_len >= sizeof(remote.sun_path)) {
		buxton_log("Provided socket name: %s is too long, maximum allowed length is %d bytes\n",
			   buxton_socket(), sizeof(remote.sun_path));
		return -1;
	}

	strncpy(remote.sun_path, buxton_socket(), sock_name_len);
	r = connect(bx_socket, (struct sockaddr *)&remote, sizeof(remote));
	if ( r == -1) {
		close(bx_socket);
		return -1;
	}

	if (fcntl(bx_socket, F_SETFL, O_NONBLOCK)) {
		close(bx_socket);
		return -1;
	}

	if (!setup_callbacks()) {
		close(bx_socket);
		return -1;
	}

	cl = malloc0(sizeof(_BuxtonClient));
	if (!cl) {
		close(bx_socket);
		return -1;
	}

	cl->fd = bx_socket;
	*c = cl;

	return bx_socket;
}

void buxton_close(BuxtonClient client)
{
	_BuxtonClient *c;
	BuxtonKey key = NULL;
	Iterator i;

	/* Free all remaining allocated keys */
	HASHMAP_FOREACH_KEY(key, key, key_hash, i) {
		hashmap_remove_value(key_hash, key, key);
		buxton_key_free(key);
	}

	hashmap_free(key_hash);

	key_hash = NULL;

	if (!client) {
{'fraction_non_alphanumeric': 0.1404353689077249, 'fraction_numerical': 0.007320362165286072, 'mean_word_length': 4.265720081135902, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 33, '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': '1516174', 'n_tokens_mistral': 2194, 'n_tokens_neox': 2032, 'n_words': 524}