<commit_before>/*
 * Copyright (c) 2013, NLNet Labs, Verisign, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * * Neither the names of the copyright holders nor the
 *   names of its contributors may be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include <getdns/getdns.h>
#include <getdns/getdns_extra.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <assert.h>
#if defined(STUBBY_ON_WINDOWS) || defined(GETDNS_ON_WINDOWS)
#include <shlobj.h>
#else
#include <pwd.h>
#include <unistd.h>
#endif
#include <signal.h>
#include <limits.h>

#ifdef HAVE_GETDNS_YAML2DICT
getdns_return_t getdns_yaml2dict(const char *str, getdns_dict **dict);
#else
# include "yaml/convert_yaml_to_json.h"
# define getdns_yaml2dict stubby_yaml2dict
getdns_return_t
getdns_yaml2dict(const char *str, getdns_dict **dict)
{
	char *jsonstr;
	
	if (!str || !dict)
		return GETDNS_RETURN_INVALID_PARAMETER;

	jsonstr = yaml_string_to_json_string(str);
	if (jsonstr) {
		getdns_return_t res = getdns_str2dict(jsonstr, dict);
		free(jsonstr);
		return res;
	} else {
		return GETDNS_RETURN_GENERIC_ERROR;
	}       
}
#endif

static char *make_config_file_path(const char *dir, const char *fname)
{
	int reslen = strlen(dir) + strlen(fname) + 1;
	char *res = malloc(reslen);

	if (res == NULL)
		return NULL;

	snprintf(res, reslen, "%s%s", dir, fname);
	return res;
}

#if defined(STUBBY_ON_WINDOWS) || defined(GETDNS_ON_WINDOWS)
#define DEBUG_ON(...) do { \
	                struct timeval tv_dEbUgSyM; \
	                struct tm tm_dEbUgSyM; \
	                char buf_dEbUgSyM[10]; \
	                time_t tsec_dEbUgSyM; \
	                \
	                gettimeofday(&tv_dEbUgSyM, NULL); \
	                tsec_dEbUgSyM = (time_t) tv_dEbUgSyM.tv_sec; \
	                gmtime_s(&tm_dEbUgSyM, (const time_t *) &tsec_dEbUgSyM); \
	                strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
	                fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
	                fprintf(stderr, __VA_ARGS__); \
	        } while (0)

static char *folder_config_file(int csidl)
{
	TCHAR szPath[MAX_PATH];

	if (!SUCCEEDED(SHGetFolderPath(NULL,
	    csidl | CSIDL_FLAG_CREATE, NULL, 0, szPath)))
		return NULL;

	return make_config_file_path(szPath, "\\Stubby\\stubby.yml");
}

// %APPDATA%/Stubby/stubby.yml.
char *home_config_file()
{
	return folder_config_file(CSIDL_APPDATA);
}

char *system_config_file()
{
	return folder_config_file(CSIDL_PROGRAM_FILES);
}
#else
#define STUBBYPIDFILE RUNSTATEDIR"/stubby.pid"

#define DEBUG_ON(...) do { \
	                struct timeval tv_dEbUgSyM; \
	                struct tm tm_dEbUgSyM; \
	                char buf_dEbUgSyM[10]; \
	                \
	                gettimeofday(&tv_dEbUgSyM, NULL); \
	                gmtime_r(&tv_dEbUgSyM.tv_sec, &tm_dEbUgSyM); \
	                strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
	                fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
	                fprintf(stderr, __VA_ARGS__); \
	        } while (0)

char *home_config_file()
{
	struct passwd *p = getpwuid(getuid());
	char *home = p ? p->pw_dir : getend("HOME");
	if (!home)
		return NULL;
	return make_config_file_path(home, "/.stubby.yml");
}

char *system_config_file()
{
	return make_config_file_path(STUBBYCONFDIR, "/stubby.yml");
}
#endif
#define DEBUG_OFF(...) do {} while (0)

#if defined(SERVER_DEBUG) && SERVER_DEBUG
#include <time.h>
#define DEBUG_SERVER(...) DEBUG_ON(__VA_ARGS__)
#else
#define DEBUG_SERVER(...) DEBUG_OFF(__VA_ARGS__)
#endif

static const char *default_config =
"{ resolution_type: GETDNS_RESOLUTION_STUB"
", dns_transport_list: [ GETDNS_TRANSPORT_TLS"
"                      , GETDNS_TRANSPORT_UDP"
"                      , GETDNS_TRANSPORT_TCP ]"
", idle_timeout: 10000"
", listen_addresses: [ 127.0.0.1@53, 0::1@53 ]"
", tls_query_padding_blocksize: 256"
", edns_client_subnet_private : 1"
", round_robin_upstreams: 1"
"}";
<commit_msg>Fix typo<commit_after>/*
 * Copyright (c) 2013, NLNet Labs, Verisign, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * * Neither the names of the copyright holders nor the
 *   names of its contributors may be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include <getdns/getdns.h>
#include <getdns/getdns_extra.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <assert.h>
#if defined(STUBBY_ON_WINDOWS) || defined(GETDNS_ON_WINDOWS)
#include <shlobj.h>
#else
#include <pwd.h>
#include <unistd.h>
#endif
#include <signal.h>
#include <limits.h>

#ifdef HAVE_GETDNS_YAML2DICT
getdns_return_t getdns_yaml2dict(const char *str, getdns_dict **dict);
#else
# include "yaml/convert_yaml_to_json.h"
# define getdns_yaml2dict stubby_yaml2dict
getdns_return_t
getdns_yaml2dict(const char *str, getdns_dict **dict)
{
	char *jsonstr;
	
	if (!str || !dict)
		return GETDNS_RETURN_INVALID_PARAMETER;

	jsonstr = yaml_string_to_json_string(str);
	if (jsonstr) {
		getdns_return_t res = getdns_str2dict(jsonstr, dict);
		free(jsonstr);
		return res;
	} else {
		return GETDNS_RETURN_GENERIC_ERROR;
	}       
}
#endif

static char *make_config_file_path(const char *dir, const char *fname)
{
	int reslen = strlen(dir) + strlen(fname) + 1;
	char *res = malloc(reslen);

	if (res == NULL)
		return NULL;

	snprintf(res, reslen, "%s%s", dir, fname);
	return res;
}

#if defined(STUBBY_ON_WINDOWS) || defined(GETDNS_ON_WINDOWS)
#define DEBUG_ON(...) do { \
	                struct timeval tv_dEbUgSyM; \
	                struct tm tm_dEbUgSyM; \
	                char buf_dEbUgSyM[10]; \
	                time_t tsec_dEbUgSyM; \
	                \
	                gettimeofday(&tv_dEbUgSyM, NULL); \
	                tsec_dEbUgSyM = (time_t) tv_dEbUgSyM.tv_sec; \
	                gmtime_s(&tm_dEbUgSyM, (const time_t *) &tsec_dEbUgSyM); \
	                strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
	                fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
	                fprintf(stderr, __VA_ARGS__); \
	        } while (0)

static char *folder_config_file(int csidl)
{
	TCHAR szPath[MAX_PATH];

	if (!SUCCEEDED(SHGetFolderPath(NULL,
	    csidl | CSIDL_FLAG_CREATE, NULL, 0, szPath)))
		return NULL;

	return make_config_file_path(szPath, "\\Stubby\\stubby.yml");
}

// %APPDATA%/Stubby/stubby.yml.
char *home_config_file()
{
	return folder_config_file(CSIDL_APPDATA);
}

char *system_config_file()
{
	return folder_config_file(CSIDL_PROGRAM_FILES);
}
#else
#define STUBBYPIDFILE RUNSTATEDIR"/stubby.pid"

#define DEBUG_ON(...) do { \
	                struct timeval tv_dEbUgSyM; \
	                struct tm tm_dEbUgSyM; \
	                char buf_dEbUgSyM[10]; \
	                \
	                gettimeofday(&tv_dEbUgSyM, NULL); \
	                gmtime_r(&tv_dEbUgSyM.tv_sec, &tm_dEbUgSyM); \
	                strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
	                fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
	                fprintf(stderr, __VA_ARGS__); \
	        } while (0)

char *home_config_file()
{
	struct passwd *p = getpwuid(getuid());
	char *home = p ? p->pw_dir : getenv("HOME");
	if (!home)
		return NULL;
	return make_config_file_path(home, "/.stubby.yml");
}

char *system_config_file()
{
	return make_config_file_path(STUBBYCONFDIR, "/stubby.yml");
}
#endif
#define DEBUG_OFF(...) do {} while (0)

#if defined(SERVER_DEBUG) && SERVER_DEBUG
#include <time.h>
#define DEBUG_SERVER(...) DEBUG_ON(__VA_ARGS__)
#else
#define DEBUG_SERVER(...) DEBUG_OFF(__VA_ARGS__)
#endif

static const char *default_config =
"{ resolution_type: GETDNS_RESOLUTION_STUB"
", dns_transport_list: [ GETDNS_TRANSPORT_TLS"
"                      , GETDNS_TRANSPORT_UDP"
"                      , GETDNS_TRANSPORT_TCP ]"
", idle_timeout: 10000"
", listen_addresses: [ 127.0.0.1@53, 0::1@53 ]"
", tls_query_padding_blocksize: 256"
", edns_client_subnet_private : 1"
", round_robin_upstreams: 1"
"}";

{'fraction_non_alphanumeric': 0.11045586445754937, 'fraction_numerical': 0.008799026490686137, 'mean_word_length': 3.4853064651553316, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, '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': '708005', 'n_tokens_mistral': 4061, 'n_tokens_neox': 3800, 'n_words': 957}