/*! * \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; }
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; }