예제 #1
0
/*!
 * \brief Reload the extensions file and update the internal buffers if it
 * loads correctly.
 *
 * \warning This function should not be called on a lua_State returned from
 * lua_get_state().
 *
 * \param L the lua_State to use (must be freshly allocated with
 * luaL_newstate(), don't use lua_get_state())
 */
static int lua_reload_extensions(lua_State *L)
{
	long size = 0;
	char *data = NULL;

	luaL_openlibs(L);

	if (!(data = lua_read_extensions_file(L, &size))) {
		return 1;
	}

	ast_mutex_lock(&config_file_lock);

	if (config_file_data)
		ast_free(config_file_data);

	config_file_data = data;
	config_file_size = size;
	
	/* merge our new contexts */
	ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
	/* merge_contexts_and_delete will actually, at the correct moment, 
	   set the global dialplan pointers to your local_contexts and local_table.
	   It then will free up the old tables itself. Just be sure not to
	   hang onto the pointers. */
	local_table = NULL;
	local_contexts = NULL;

	ast_mutex_unlock(&config_file_lock);
	return 0;
}
예제 #2
0
static int pbx_load_module(void)
{
	int errs=0, sem_err=0, sem_warn=0, sem_note=0;
	char *rfilename;
	struct ast_context *local_contexts=NULL, *con;
	struct ast_hashtab *local_table=NULL;
	
	struct pval *parse_tree;

	ast_log(LOG_NOTICE, "Starting AEL load process.\n");
	if (config[0] == '/')
		rfilename = (char *)config;
	else {
		rfilename = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2);
		sprintf(rfilename, "%s/%s", ast_config_AST_CONFIG_DIR, config);
	}
	if (access(rfilename,R_OK) != 0) {
		ast_log(LOG_NOTICE, "File %s not found; AEL declining load\n", rfilename);
		return AST_MODULE_LOAD_DECLINE;
	}
	
	parse_tree = ael2_parse(rfilename, &errs);
	ast_log(LOG_NOTICE, "AEL load process: parsed config file name '%s'.\n", rfilename);
	ael2_semantic_check(parse_tree, &sem_err, &sem_warn, &sem_note);
	if (errs == 0 && sem_err == 0) {
		ast_log(LOG_NOTICE, "AEL load process: checked config file name '%s'.\n", rfilename);
		local_table = ast_hashtab_create(11, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
		ast_compile_ael2(&local_contexts, local_table, parse_tree);
		ast_log(LOG_NOTICE, "AEL load process: compiled config file name '%s'.\n", rfilename);
		
		ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
		local_table = NULL; /* it's the dialplan global now */
		local_contexts = NULL;
		ast_log(LOG_NOTICE, "AEL load process: merged config file name '%s'.\n", rfilename);
		for (con = ast_walk_contexts(NULL); con; con = ast_walk_contexts(con))
			ast_context_verify_includes(con);
		ast_log(LOG_NOTICE, "AEL load process: verified config file name '%s'.\n", rfilename);
	} else {
		ast_log(LOG_ERROR, "Sorry, but %d syntax errors and %d semantic errors were detected. It doesn't make sense to compile.\n", errs, sem_err);
		destroy_pval(parse_tree); /* free up the memory */
		return AST_MODULE_LOAD_DECLINE;
	}
	destroy_pval(parse_tree); /* free up the memory */
	
	return AST_MODULE_LOAD_SUCCESS;
}
예제 #3
0
static int pbx_load_module(void)
{
	struct ast_config *cfg;
	struct ast_variable *v;
	char *cxt, *ext, *pri, *appl, *data, *tc, *cidmatch;
	struct ast_context *con;
	char *start, *end;
	char realvalue[256];

	cfg = ast_load(config);
	if (cfg) {
		/* Use existing config to populate the PBX table */
		static_config = ast_true(ast_variable_retrieve(cfg, "general",
			"static"));
		write_protect_config = ast_true(ast_variable_retrieve(cfg, "general",
			"writeprotect"));
		v = ast_variable_browse(cfg, "globals");
		while(v) {
			memset(realvalue, 0, sizeof(realvalue));
			pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
			pbx_builtin_setvar_helper(NULL, v->name, realvalue);
			v = v->next;
		}
		cxt = ast_category_browse(cfg, NULL);
		while(cxt) {
			/* All categories but "general" or "globals" are considered contexts */
			if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) {
				cxt = ast_category_browse(cfg, cxt);
				continue;
			}
			if ((con=ast_context_create(&local_contexts,cxt, registrar))) {
				v = ast_variable_browse(cfg, cxt);
				while(v) {
					if (!strcasecmp(v->name, "exten")) {
						char *stringp=NULL;
						int ipri = -2;
						char realext[256]="";
						tc = strdup(v->value);
						if(tc!=NULL){
							stringp=tc;
							ext = strsep(&stringp, ",");
							if (!ext)
								ext="";
							pri = strsep(&stringp, ",");
							if (!pri)
								pri="";
							if (!strcmp(pri,"hint"))
								ipri=PRIORITY_HINT;
							else {
								if (sscanf(pri, "%i", &ipri) != 1) {
									ast_log(LOG_WARNING, "Invalid priority '%s' at line %d\n", pri, v->lineno);
									ipri = 0;
								}
							}
							appl = stringp;
							if (!appl)
								appl="";
							if (!(start = strchr(appl, '('))) {
								if (stringp)
									appl = strsep(&stringp, ",");
								else
									appl = "";
							}
							if (start && (end = strrchr(appl, ')'))) {
								*start = *end = '\0';
								data = start + 1;
								process_quotes_and_slashes(data, ',', '|');
							} else if (stringp!=NULL && *stringp=='"') {
								stringp++;
								data = strsep(&stringp, "\"");
								stringp++;
							} else {
								if (stringp)
									data = strsep(&stringp, ",");
								else
									data = "";
							}
							cidmatch = strchr(ext, '/');
							if (cidmatch) {
								*cidmatch = '\0';
								cidmatch++;
							}
							stringp=ext;
							strsep(&stringp, "/");

							if (!data)
								data="";
							while(*appl && (*appl < 33)) appl++;
							pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1);
							if (ipri) {
								if (ast_add_extension2(con, 0, realext, ipri, cidmatch, appl, strdup(data), FREE, registrar)) {
									ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
								}
							}
							free(tc);
						} else fprintf(stderr,"Error strdup returned NULL in %s\n",__PRETTY_FUNCTION__);
					} else if(!strcasecmp(v->name, "include")) {
						memset(realvalue, 0, sizeof(realvalue));
						pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
						if (ast_context_add_include2(con, realvalue, registrar))
							ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s'\n", v->value, cxt);
					} else if(!strcasecmp(v->name, "ignorepat")) {
						memset(realvalue, 0, sizeof(realvalue));
						pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
						if (ast_context_add_ignorepat2(con, realvalue, registrar))
							ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
					} else if (!strcasecmp(v->name, "switch")) {
						char *stringp=NULL;
						memset(realvalue, 0, sizeof(realvalue));
						pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
						tc = realvalue;
						stringp=tc;
						appl = strsep(&stringp, "/");
						data = strsep(&stringp, "");
						if (!data)
							data = "";
						if (ast_context_add_switch2(con, appl, data, registrar))
							ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt);
					}
					v = v->next;
				}
			}
			cxt = ast_category_browse(cfg, cxt);
		}
		ast_destroy(cfg);
	}
	ast_merge_contexts_and_delete(&local_contexts,registrar);

	for (con = ast_walk_contexts(NULL); con; con = ast_walk_contexts(con))
		ast_context_verify_includes(con);

	return 0;
}