Esempio n. 1
0
/*!
 * \brief Register dialplan hints for our pbx_lua contexs.
 *
 * In the event of an error, an error string will be pushed onto the lua stack.
 *
 * \retval 0 success
 * \retval 1 failure
 */
static int lua_register_hints(lua_State *L)
{
	int hints;
	struct ast_context *con = NULL;

	/* create the hash table for our contexts */
	/* XXX do we ever need to destroy this? pbx_config does not */
	if (!local_table)
		local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);

	/* load the 'hints' table */
	lua_getglobal(L, "hints");
	hints = lua_gettop(L);
	if (lua_isnil(L, -1)) {
		/* hints table not found, move along */
		lua_pop(L, 1);
		return 0;
	}

	/* iterate through the hints table and register each context and
	 * the hints that go along with it
	 */
	for (lua_pushnil(L); lua_next(L, hints); lua_pop(L, 1)) {
		int context = lua_gettop(L);
		int context_name = context - 1;
		const char *context_str = lua_tostring(L, context_name);

		/* find or create this context */
		con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
		if (!con) {
			/* remove hints table and context key and value */
			lua_pop(L, 3);
			lua_pushstring(L, "Failed to find or create context\n");
			return 1;
		}

		/* register each hint */
		for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
			const char *hint_value = lua_tostring(L, -1);
			const char *hint_name;

			/* the hint value is not a string, ignore it */
			if (!hint_value) {
				continue;
			}

			/* copy the name then convert it to a string */
			lua_pushvalue(L, -2);
			if (!(hint_name = lua_tostring(L, -1))) {
				/* ignore non-string value */
				lua_pop(L, 1);
				continue;
			}

			if (ast_add_extension2(con, 0, hint_name, PRIORITY_HINT, NULL, NULL, hint_value, NULL, NULL, registrar)) {
				/* remove hints table, hint name, hint value,
				 * key copy, context name, and contex table */
				lua_pop(L, 6);
				lua_pushstring(L, "Error creating hint\n");
				return 1;
			}

			/* pop the name copy */
			lua_pop(L, 1);
		}
	}

	/* remove the hints table */
	lua_pop(L, 1);

	return 0;
}
Esempio n. 2
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;
}