Skip to content
Snippets Groups Projects
config.c 107 KiB
Newer Older
Mark Spencer's avatar
Mark Spencer committed
/*
 * Asterisk -- An open source telephony toolkit.
Mark Spencer's avatar
Mark Spencer committed
 *
 * Copyright (C) 1999 - 2010, Digium, Inc.
Mark Spencer's avatar
Mark Spencer committed
 *
Mark Spencer's avatar
Mark Spencer committed
 *
 * See http://www.asterisk.org for more information about
 * the Asterisk project. Please do not directly contact
 * any of the maintainers of this project for assistance;
 * the project provides a web site, mailing lists and IRC
 * channels for your use.
 *
Mark Spencer's avatar
Mark Spencer committed
 * This program is free software, distributed under the terms of
 * the GNU General Public License Version 2. See the LICENSE file
 * at the top of the source tree.
 */

/*! \file
 *
 * \brief Configuration File Parser
 * \author Mark Spencer <markster@digium.com>
 *
 * Includes the Asterisk Realtime API - ARA
 * See http://wiki.asterisk.org
/*** MODULEINFO
	<support_level>core</support_level>
 ***/

#include "asterisk.h"

ASTERISK_FILE_VERSION(__FILE__, "$Revision$")

#include "asterisk/paths.h"	/* use ast_config_AST_CONFIG_DIR */
Luigi Rizzo's avatar
Luigi Rizzo committed
#include "asterisk/network.h"	/* we do some sockaddr manipulation here */
#include <time.h>
Luigi Rizzo's avatar
Luigi Rizzo committed

#include <math.h>	/* HUGE_VAL */
#define AST_INCLUDE_GLOB 1
Luigi Rizzo's avatar
Luigi Rizzo committed

#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/channel.h"
#include "asterisk/app.h"
#include "asterisk/strings.h"	/* for the ast_str_*() API */
Mark Michelson's avatar
Mark Michelson committed
#include "asterisk/netsock2.h"
#define MAX_NESTED_COMMENTS 128
#define COMMENT_START ";--"
#define COMMENT_END "--;"
#define COMMENT_META ';'
#define COMMENT_TAG '-'
/*!
 * Define the minimum filename space to reserve for each
 * ast_variable in case the filename is renamed later by
 * ast_include_rename().
 */
#define MIN_VARIABLE_FNAME_SPACE	40

static char *extconfig_conf = "extconfig.conf";
static struct ao2_container *cfg_hooks;
static void config_hook_exec(const char *filename, const char *module, const struct ast_config *cfg);
static inline struct ast_variable *variable_list_switch(struct ast_variable *l1, struct ast_variable *l2);
static int does_category_match(struct ast_category *cat, const char *category_name,
	const char *match, char sep);
/*! \brief Structure to keep comments for rewriting configuration files */
struct ast_comment {
	struct ast_comment *next;
	/*! Comment body allocated after struct. */
/*! \brief Hold the mtime for config files, so if we don't need to reread our config, don't. */
struct cache_file_include {
	AST_LIST_ENTRY(cache_file_include) list;
	/*! Filename or wildcard pattern as specified by the including file. */
	char include[0];
};

struct cache_file_mtime {
	AST_LIST_ENTRY(cache_file_mtime) list;
	AST_LIST_HEAD_NOLOCK(includes, cache_file_include) includes;
	/*! stat() file size */
	unsigned long stat_size;
	/*! stat() file modtime nanoseconds */
	unsigned long stat_mtime_nsec;
	/*! stat() file modtime seconds since epoc */
	time_t stat_mtime;

	/*! String stuffed in filename[] after the filename string. */
	const char *who_asked;
	/*! Filename and who_asked stuffed after it. */
/*! Cached file mtime list. */
static AST_LIST_HEAD_STATIC(cfmtime_head, cache_file_mtime);

static int init_appendbuf(void *data)
{
	struct ast_str **str = data;
	*str = ast_str_create(16);
	return *str ? 0 : -1;
}

AST_THREADSTORAGE_CUSTOM(appendbuf, init_appendbuf, ast_free_ptr);
/* comment buffers are better implemented using the ast_str_*() API */
#define CB_SIZE 250	/* initial size of comment buffers */
static void  CB_ADD(struct ast_str **cb, const char *str)
static void  CB_ADD_LEN(struct ast_str **cb, const char *str, int len)
	char *s = ast_alloca(len + 1);

	memcpy(s, str, len);
	s[len] = '\0';
	ast_str_append(cb, 0, "%s", s);
static void CB_RESET(struct ast_str *cb, struct ast_str *llb)
{
	if (cb) {
		ast_str_reset(cb);
	}
	if (llb) {
		ast_str_reset(llb);
	}
static struct ast_comment *ALLOC_COMMENT(struct ast_str *buffer)
	if (!buffer || !ast_str_strlen(buffer)) {
		return NULL;
	}
	if ((x = ast_calloc(1, sizeof(*x) + ast_str_strlen(buffer) + 1))) {
		strcpy(x->cmt, ast_str_buffer(buffer)); /* SAFE */
	}
/* I need to keep track of each config file, and all its inclusions,
   so that we can track blank lines in each */

Luigi Rizzo's avatar
Luigi Rizzo committed
struct inclfile {
	char *fname;
	int lineno;
};

static int hash_string(const void *obj, const int flags)
{
	char *str = ((struct inclfile *) obj)->fname;
		unsigned int tmp = total;
		total <<= 1; /* multiply by 2 */
		total += tmp; /* multiply by 3 */
		total <<= 2; /* multiply by 12 */
		total += tmp; /* multiply by 13 */
		total += ((unsigned int) (*str));
static int hashtab_compare_strings(void *a, void *b, int flags)
	return !strcmp(ae->fname, be->fname) ? CMP_MATCH | CMP_STOP : 0;
static struct ast_config_map {
	struct ast_config_map *next;
	int priority;
	/*! Stored in stuff[] at struct end. */
Loading
Loading full blame...