view config.c @ 2:a36ce212c6fc

config: configuration parser Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Thu, 27 Jul 2017 01:31:30 +0300
parents
children
line wrap: on
line source

/*
 * Copyright (c) 2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <jeffpc/sexpr.h>
#include <jeffpc/io.h>

#include "config.h"

/*
 * The actual config
 */
struct config config;

static struct str exampledotcom = STR_STATIC_INITIALIZER("example.com");

static void config_load_u64(struct val *lv, const char *vname,
			    uint64_t *ret, uint64_t def)
{
	uint64_t tmp;
	bool found;

	tmp = sexpr_alist_lookup_int(lv, vname, &found);

	if (found)
		*ret = tmp;
	else
		*ret = def;
}

static void config_load_url(struct val *lv, const char *vname,
			    struct str **ret)
{
	struct str *s;

	s = sexpr_alist_lookup_str(lv, vname);

	if (s)
		*ret = s;
	else
		*ret = str_getref(&exampledotcom);
}

static void config_load_str(struct val *lv, const char *vname,
			    struct str **ret, const char *def)
{
	struct str *s;

	s = sexpr_alist_lookup_str(lv, vname);

	if (s)
		*ret = s;
	else if (def)
		*ret = STR_DUP(def);
	else
		*ret = NULL;
}

static void config_load_scgi_port(struct val *lv)
{
	uint64_t tmp;

	config_load_u64(lv, CONFIG_SCGI_PORT, &tmp, DEFAULT_SCGI_PORT);

	if (tmp < 65536)
		config.scgi_port = tmp;
	else
		config.scgi_port = DEFAULT_SCGI_PORT;
}

static void config_load_scgi_threads(struct val *lv)
{
	config_load_u64(lv, CONFIG_SCGI_THREADS, &config.scgi_threads,
			DEFAULT_SCGI_THREADS);

	/* we need at least one thread */
	if (!config.scgi_threads)
		config.scgi_threads = DEFAULT_SCGI_THREADS;
}

int config_load(const char *fname)
{
	struct val *lv;
	char *raw;

	srand(time(NULL));

	if (fname) {
		raw = read_file(fname);
		if (IS_ERR(raw))
			return PTR_ERR(raw);

		lv = sexpr_parse_cstr(raw);

		free(raw);

		if (IS_ERR(lv))
			return PTR_ERR(lv);
	} else {
		lv = NULL;
	}

	config_load_scgi_port(lv);
	config_load_scgi_threads(lv);
	config_load_str(lv, CONFIG_DATA_DIR, &config.data_dir, DEFAULT_DATA_DIR);
	config_load_str(lv, CONFIG_WEB_DIR, &config.web_dir, DEFAULT_WEB_DIR);
	config_load_url(lv, CONFIG_BASE_URL, &config.base_url);

	val_putref(lv);

	cmn_err(CE_DEBUG, "config.scgi_port = %u", config.scgi_port);
	cmn_err(CE_DEBUG, "config.scgi_threads = %"PRIu64, config.scgi_threads);
	cmn_err(CE_DEBUG, "config.data_dir = %s", str_cstr(config.data_dir));
	cmn_err(CE_DEBUG, "config.web_dir = %s", str_cstr(config.web_dir));
	cmn_err(CE_DEBUG, "config.base_url = %s", str_cstr(config.base_url));

	return 0;
}