--- pbx/pbx_config.c.orig 2012-02-02 11:49:19.920686402 +0400 +++ pbx/pbx_config.c 2012-02-02 16:11:30.823684037 +0400 @@ -521,6 +521,8 @@ */ static char *handle_cli_dialplan_add_include(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { + const char *into_context; + switch (cmd) { case CLI_INIT: e->command = "dialplan add include"; @@ -539,6 +541,18 @@ if (strcmp(a->argv[4], "into")) return CLI_SHOWUSAGE; + into_context = a->argv[5]; + + if (!ast_context_find(into_context)) { + ast_cli(a->fd, "Context '%s' did not exist prior to add include - the context will be created.\n", into_context); + } + + if (!ast_context_find_or_create(NULL, NULL, into_context, registrar)) { + ast_cli(a->fd, "ast_context_find_or_create() failed\n"); + ast_cli(a->fd, "Failed to include '%s' in '%s' context\n",a->argv[3], a->argv[5]); + return CLI_FAILURE; + } + if (ast_context_add_include(a->argv[5], a->argv[3], registrar)) { switch (errno) { case ENOMEM: @@ -593,43 +607,18 @@ ast_unlock_contexts(); return ret; } else if (a->pos == 4) { /* dialplan add include CTX _X_ */ - /* complete as 'into' if context exists or we are unable to check */ - char *context, *dupline; - const char *s = skip_words(a->line, 3); /* should not fail */ - - if (a->n != 0) /* only once */ - return NULL; - - /* parse context from line ... */ - context = dupline = strdup(s); - if (!context) { - ast_log(LOG_ERROR, "Out of free memory\n"); - return strdup("into"); - } - strsep(&dupline, " "); - - /* check for context existence ... */ - if (ast_rdlock_contexts()) { - ast_log(LOG_ERROR, "Failed to lock context list\n"); - /* our fault, we can't check, so complete 'into' ... */ - ret = strdup("into"); - } else { - struct ast_context *ctx; - for (ctx = NULL; !ret && (ctx = ast_walk_contexts(ctx)); ) - if (!strcmp(context, ast_get_context_name(ctx))) - ret = strdup("into"); /* found */ - ast_unlock_contexts(); - } - free(context); - return ret; + /* always complete as 'into' */ + return (a->n == 0) ? strdup("into") : NULL; } else if (a->pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */ char *context, *dupline, *into; const char *s = skip_words(a->line, 3); /* should not fail */ context = dupline = strdup(s); + if (!dupline) { ast_log(LOG_ERROR, "Out of free memory\n"); return NULL; } + strsep(&dupline, " "); /* skip context */ into = strsep(&dupline, " "); /* error if missing context or fifth word is not 'into' */ @@ -644,21 +633,13 @@ goto error3; } - for (c = NULL; (c = ast_walk_contexts(c)); ) + for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { if (!strcmp(context, ast_get_context_name(c))) - break; - if (c) { /* first context exists, go on... */ - /* go through all contexts ... */ - for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { - if (!strcmp(context, ast_get_context_name(c))) - continue; /* skip ourselves */ - if (partial_match(ast_get_context_name(c), a->word, len) && - !lookup_ci(c, context) /* not included yet */ && - ++which > a->n) - ret = strdup(ast_get_context_name(c)); - } - } else { - ast_log(LOG_ERROR, "context %s not found\n", context); + continue; /* skip ourselves */ + if (partial_match(ast_get_context_name(c), a->word, len) && + !lookup_ci(c, context) /* not included yet */ && + ++which > a->n) + ret = strdup(ast_get_context_name(c)); } ast_unlock_contexts(); error3: