Skip to content
Snippets Groups Projects
config.c 107 KiB
Newer Older
  • Learn to ignore specific revisions
  • {
    	struct cache_file_mtime *cfmtime;
    
    	switch (cmd) {
    	case CLI_INIT:
    		e->command = "config list";
    		e->usage =
    			"Usage: config list\n"
    			"   Show all modules that have loaded a configuration file\n";
    		return NULL;
    	case CLI_GENERATE:
    		return NULL;
    	}
    
    	AST_LIST_LOCK(&cfmtime_head);
    	AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
    
    		ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename);
    
    static struct ast_cli_entry cli_config[] = {
    
    	AST_CLI_DEFINE(handle_cli_core_show_config_mappings, "Display config mappings (file names to config engines)"),
    
    	AST_CLI_DEFINE(handle_cli_config_reload, "Force a reload on modules using a particular configuration file"),
    	AST_CLI_DEFINE(handle_cli_config_list, "Show all files that have loaded a configuration file"),
    
    static void config_shutdown(void)
    {
    	struct cache_file_mtime *cfmtime;
    
    	AST_LIST_LOCK(&cfmtime_head);
    	while ((cfmtime = AST_LIST_REMOVE_HEAD(&cfmtime_head, list))) {
    
    	}
    	AST_LIST_UNLOCK(&cfmtime_head);
    
    	ast_cli_unregister_multiple(cli_config, ARRAY_LEN(cli_config));
    
    	ao2_cleanup(cfg_hooks);
    	cfg_hooks = NULL;
    
    int register_config_cli(void)
    
    	ast_cli_register_multiple(cli_config, ARRAY_LEN(cli_config));
    
    	ast_register_cleanup(config_shutdown);
    
    
    struct cfg_hook {
    	const char *name;
    	const char *filename;
    	const char *module;
    	config_hook_cb hook_cb;
    };
    
    static void hook_destroy(void *obj)
    {
    	struct cfg_hook *hook = obj;
    	ast_free((void *) hook->name);
    	ast_free((void *) hook->filename);
    	ast_free((void *) hook->module);
    }
    
    static int hook_cmp(void *obj, void *arg, int flags)
    {
    	struct cfg_hook *hook1 = obj;
    	struct cfg_hook *hook2 = arg;
    
    	return !(strcasecmp(hook1->name, hook2->name)) ? CMP_MATCH | CMP_STOP : 0;
    }
    
    static int hook_hash(const void *obj, const int flags)
    {
    	const struct cfg_hook *hook = obj;
    
    	return ast_str_hash(hook->name);
    }
    
    void ast_config_hook_unregister(const char *name)
    {
    	struct cfg_hook tmp;
    
    	tmp.name = ast_strdupa(name);
    
    	ao2_find(cfg_hooks, &tmp, OBJ_POINTER | OBJ_UNLINK | OBJ_NODATA);
    }
    
    
    static void config_hook_exec(const char *filename, const char *module, const struct ast_config *cfg)
    
    {
    	struct ao2_iterator it;
    	struct cfg_hook *hook;
    	if (!(cfg_hooks)) {
    		return;
    	}
    	it = ao2_iterator_init(cfg_hooks, 0);
    	while ((hook = ao2_iterator_next(&it))) {
    		if (!strcasecmp(hook->filename, filename) &&
    				!strcasecmp(hook->module, module)) {
    			struct ast_config *copy = ast_config_copy(cfg);
    			hook->hook_cb(copy);
    		}
    		ao2_ref(hook, -1);
    	}
    	ao2_iterator_destroy(&it);
    }
    
    int ast_config_hook_register(const char *name,
    		const char *filename,
    		const char *module,
    		enum config_hook_flags flags,
    		config_hook_cb hook_cb)
    {
    	struct cfg_hook *hook;
    	if (!cfg_hooks && !(cfg_hooks = ao2_container_alloc(17, hook_hash, hook_cmp))) {
    		return -1;
    	}
    
    	if (!(hook = ao2_alloc(sizeof(*hook), hook_destroy))) {
    		return -1;
    	}
    
    	hook->hook_cb = hook_cb;
    	hook->filename = ast_strdup(filename);
    	hook->name = ast_strdup(name);
    	hook->module = ast_strdup(module);
    
    	ao2_link(cfg_hooks, hook);