#include "asterisk.h"
#include <ctype.h>
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
Go to the source code of this file.
Defines | |
#define | PUT_CTX_HDR |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static void | append_interface (char *iface, int maxlen, char *add) |
static char * | complete_dialplan_add_extension (struct ast_cli_args *) |
static char * | complete_dialplan_add_ignorepat (struct ast_cli_args *) |
static char * | complete_dialplan_add_include (struct ast_cli_args *) |
static char * | complete_dialplan_remove_extension (struct ast_cli_args *) |
static char * | complete_dialplan_remove_ignorepat (struct ast_cli_args *) |
static char * | complete_dialplan_remove_include (struct ast_cli_args *) |
static char * | handle_cli_dialplan_add_extension (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
ADD EXTENSION command stuff. | |
static char * | handle_cli_dialplan_add_ignorepat (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_add_include (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_remove_extension (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_remove_ignorepat (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_remove_include (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_save (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
'save dialplan' CLI command implementation functions ... | |
static int | load_module (void) |
static int | lookup_c_ip (struct ast_context *c, const char *name) |
return true if 'name' is in the ignorepats for context c | |
static int | lookup_ci (struct ast_context *c, const char *name) |
return true if 'name' is included by context c | |
static int | partial_match (const char *s, const char *word, int len) |
match the first 'len' chars of word. len==0 always succeeds | |
static int | pbx_load_config (const char *config_file) |
static int | pbx_load_module (void) |
static void | pbx_load_users (void) |
static int | reload (void) |
static const char * | skip_words (const char *p, int n) |
moves to the n-th word in the string, or empty string if none | |
static int | split_ec (const char *src, char **ext, char **const ctx, char **const cid) |
split extension@context in two parts, return -1 on error. The return string is malloc'ed and pointed by *ext | |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Text Extension Configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static int | autofallthrough_config = 1 |
static int | clearglobalvars_config = 0 |
static struct ast_cli_entry | cli_dialplan_save |
static struct ast_cli_entry | cli_pbx_config [] |
static char * | config = "extensions.conf" |
static int | extenpatternmatchnew_config = 0 |
static struct ast_context * | local_contexts = NULL |
static struct ast_hashtab * | local_table = NULL |
static char * | overrideswitch_config = NULL |
static char * | registrar = "pbx_config" |
static ast_mutex_t | save_dialplan_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static int | static_config = 0 |
static char | userscontext [AST_MAX_EXTENSION] = "default" |
static int | write_protect_config = 1 |
Definition in file pbx_config.c.
#define PUT_CTX_HDR |
Referenced by handle_cli_dialplan_save().
static void __reg_module | ( | void | ) | [static] |
Definition at line 1689 of file pbx_config.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1689 of file pbx_config.c.
static void append_interface | ( | char * | iface, | |
int | maxlen, | |||
char * | add | |||
) | [static] |
Definition at line 1522 of file pbx_config.c.
References len().
Referenced by pbx_load_users().
01523 { 01524 int len = strlen(iface); 01525 if (strlen(add) + len < maxlen - 2) { 01526 if (strlen(iface)) { 01527 iface[len] = '&'; 01528 strcpy(iface + len + 1, add); 01529 } else 01530 strcpy(iface, add); 01531 } 01532 }
static char * complete_dialplan_add_extension | ( | struct ast_cli_args * | a | ) | [static] |
dialplan add extension 6123,1,Dial,IAX/212.71.138.13/6123 into local
Definition at line 1015 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), len(), LOG_WARNING, ast_cli_args::n, partial_match(), ast_cli_args::pos, strdup, and ast_cli_args::word.
Referenced by handle_cli_dialplan_add_extension().
01016 { 01017 int which = 0; 01018 01019 if (a->pos == 4) { /* complete 'into' word ... */ 01020 return (a->n == 0) ? strdup("into") : NULL; 01021 } else if (a->pos == 5) { /* complete context */ 01022 struct ast_context *c = NULL; 01023 int len = strlen(a->word); 01024 char *res = NULL; 01025 01026 /* try to lock contexts list ... */ 01027 if (ast_rdlock_contexts()) { 01028 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01029 return NULL; 01030 } 01031 01032 /* walk through all contexts */ 01033 while ( !res && (c = ast_walk_contexts(c)) ) 01034 if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n) 01035 res = strdup(ast_get_context_name(c)); 01036 ast_unlock_contexts(); 01037 return res; 01038 } else if (a->pos == 6) { 01039 return a->n == 0 ? strdup("replace") : NULL; 01040 } 01041 return NULL; 01042 }
static char * complete_dialplan_add_ignorepat | ( | struct ast_cli_args * | ) | [static] |
Definition at line 1101 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), free, len(), ast_cli_args::line, LOG_ERROR, lookup_c_ip(), ast_cli_args::n, partial_match(), ast_cli_args::pos, s, skip_words(), strdup, strsep(), and ast_cli_args::word.
Referenced by handle_cli_dialplan_add_ignorepat().
01102 { 01103 if (a->pos == 4) 01104 return a->n == 0 ? strdup("into") : NULL; 01105 else if (a->pos == 5) { 01106 struct ast_context *c; 01107 int which = 0; 01108 char *dupline, *ignorepat = NULL; 01109 const char *s; 01110 char *ret = NULL; 01111 int len = strlen(a->word); 01112 01113 /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */ 01114 s = skip_words(a->line, 3); 01115 if (s == NULL) 01116 return NULL; 01117 dupline = strdup(s); 01118 if (!dupline) { 01119 ast_log(LOG_ERROR, "Malloc failure\n"); 01120 return NULL; 01121 } 01122 ignorepat = strsep(&dupline, " "); 01123 01124 if (ast_rdlock_contexts()) { 01125 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 01126 return NULL; 01127 } 01128 01129 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01130 int found = 0; 01131 01132 if (!partial_match(ast_get_context_name(c), a->word, len)) 01133 continue; /* not mine */ 01134 if (ignorepat) /* there must be one, right ? */ 01135 found = lookup_c_ip(c, ignorepat); 01136 if (!found && ++which > a->n) 01137 ret = strdup(ast_get_context_name(c)); 01138 } 01139 01140 free(ignorepat); 01141 ast_unlock_contexts(); 01142 return ret; 01143 } 01144 01145 return NULL; 01146 }
static char * complete_dialplan_add_include | ( | struct ast_cli_args * | ) | [static] |
Definition at line 575 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), context, free, len(), ast_cli_args::line, LOG_ERROR, lookup_ci(), ast_cli_args::n, partial_match(), ast_cli_args::pos, s, skip_words(), strdup, strsep(), and ast_cli_args::word.
Referenced by handle_cli_dialplan_add_include().
00576 { 00577 struct ast_context *c; 00578 int which = 0; 00579 char *ret = NULL; 00580 int len = strlen(a->word); 00581 00582 if (a->pos == 3) { /* 'dialplan add include _X_' (context) ... */ 00583 if (ast_rdlock_contexts()) { 00584 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00585 return NULL; 00586 } 00587 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) 00588 if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n) 00589 ret = strdup(ast_get_context_name(c)); 00590 ast_unlock_contexts(); 00591 return ret; 00592 } else if (a->pos == 4) { /* dialplan add include CTX _X_ */ 00593 /* complete as 'into' if context exists or we are unable to check */ 00594 char *context, *dupline; 00595 const char *s = skip_words(a->line, 3); /* should not fail */ 00596 00597 if (a->n != 0) /* only once */ 00598 return NULL; 00599 00600 /* parse context from line ... */ 00601 context = dupline = strdup(s); 00602 if (!context) { 00603 ast_log(LOG_ERROR, "Out of free memory\n"); 00604 return strdup("into"); 00605 } 00606 strsep(&dupline, " "); 00607 00608 /* check for context existence ... */ 00609 if (ast_rdlock_contexts()) { 00610 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00611 /* our fault, we can't check, so complete 'into' ... */ 00612 ret = strdup("into"); 00613 } else { 00614 struct ast_context *ctx; 00615 for (ctx = NULL; !ret && (ctx = ast_walk_contexts(ctx)); ) 00616 if (!strcmp(context, ast_get_context_name(ctx))) 00617 ret = strdup("into"); /* found */ 00618 ast_unlock_contexts(); 00619 } 00620 free(context); 00621 return ret; 00622 } else if (a->pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */ 00623 char *context, *dupline, *into; 00624 const char *s = skip_words(a->line, 3); /* should not fail */ 00625 context = dupline = strdup(s); 00626 if (!dupline) { 00627 ast_log(LOG_ERROR, "Out of free memory\n"); 00628 return NULL; 00629 } 00630 strsep(&dupline, " "); /* skip context */ 00631 into = strsep(&dupline, " "); 00632 /* error if missing context or fifth word is not 'into' */ 00633 if (!strlen(context) || strcmp(into, "into")) { 00634 ast_log(LOG_ERROR, "bad context %s or missing into %s\n", 00635 context, into); 00636 goto error3; 00637 } 00638 00639 if (ast_rdlock_contexts()) { 00640 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00641 goto error3; 00642 } 00643 00644 for (c = NULL; (c = ast_walk_contexts(c)); ) 00645 if (!strcmp(context, ast_get_context_name(c))) 00646 break; 00647 if (c) { /* first context exists, go on... */ 00648 /* go through all contexts ... */ 00649 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 00650 if (!strcmp(context, ast_get_context_name(c))) 00651 continue; /* skip ourselves */ 00652 if (partial_match(ast_get_context_name(c), a->word, len) && 00653 !lookup_ci(c, context) /* not included yet */ && 00654 ++which > a->n) 00655 ret = strdup(ast_get_context_name(c)); 00656 } 00657 } else { 00658 ast_log(LOG_ERROR, "context %s not found\n", context); 00659 } 00660 ast_unlock_contexts(); 00661 error3: 00662 free(context); 00663 return ret; 00664 } 00665 00666 return NULL; 00667 }
static char * complete_dialplan_remove_extension | ( | struct ast_cli_args * | ) | [static] |
Definition at line 392 of file pbx_config.c.
References asprintf, ast_get_context_name(), ast_get_extension_cidmatch(), ast_get_extension_matchcid(), ast_get_extension_name(), ast_get_extension_priority(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), context, errno, exten, free, len(), ast_cli_args::line, LOG_ERROR, LOG_WARNING, ast_cli_args::n, partial_match(), ast_cli_args::pos, ast_exten::priority, s, skip_words(), split_ec(), strdup, and ast_cli_args::word.
Referenced by handle_cli_dialplan_remove_extension().
00393 { 00394 char *ret = NULL; 00395 int which = 0; 00396 00397 if (a->pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */ 00398 struct ast_context *c = NULL; 00399 char *context = NULL, *exten = NULL, *cid = NULL; 00400 int le = 0; /* length of extension */ 00401 int lc = 0; /* length of context */ 00402 int lcid = 0; /* length of cid */ 00403 00404 lc = split_ec(a->word, &exten, &context, &cid); 00405 if (lc) { /* error */ 00406 return NULL; 00407 } 00408 le = strlen(exten); 00409 lc = strlen(context); 00410 lcid = cid ? strlen(cid) : -1; 00411 00412 if (ast_rdlock_contexts()) { 00413 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00414 goto error2; 00415 } 00416 00417 /* find our context ... */ 00418 while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */ 00419 struct ast_exten *e = NULL; 00420 /* XXX locking ? */ 00421 if (!partial_match(ast_get_context_name(c), context, lc)) 00422 continue; /* context not matched */ 00423 while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */ 00424 if ( !strchr(a->word, '/') || 00425 (!strchr(a->word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) || 00426 (strchr(a->word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) { 00427 if ( ((strchr(a->word, '/') || strchr(a->word, '@')) && !strcmp(ast_get_extension_name(e), exten)) || 00428 (!strchr(a->word, '/') && !strchr(a->word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */ 00429 if (++which > a->n) { 00430 /* If there is an extension then return exten@context. */ 00431 if (ast_get_extension_matchcid(e) && (!strchr(a->word, '@') || strchr(a->word, '/'))) { 00432 if (asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)) < 0) { 00433 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00434 ret = NULL; 00435 } 00436 break; 00437 } else if (!ast_get_extension_matchcid(e) && !strchr(a->word, '/')) { 00438 if (asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) { 00439 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00440 ret = NULL; 00441 } 00442 break; 00443 } 00444 } 00445 } 00446 } 00447 } 00448 if (e) /* got a match */ 00449 break; 00450 } 00451 00452 ast_unlock_contexts(); 00453 error2: 00454 free(exten); 00455 } else if (a->pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */ 00456 char *exten = NULL, *context, *cid, *p; 00457 struct ast_context *c; 00458 int le, lc, lcid, len; 00459 const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'extension' */ 00460 int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */ 00461 00462 if (i) /* error */ 00463 goto error3; 00464 if ( (p = strchr(exten, ' ')) ) /* remove space after extension */ 00465 *p = '\0'; 00466 if ( (p = strchr(context, ' ')) ) /* remove space after context */ 00467 *p = '\0'; 00468 le = strlen(exten); 00469 lc = strlen(context); 00470 lcid = strlen(cid); 00471 len = strlen(a->word); 00472 if (le == 0 || lc == 0) 00473 goto error3; 00474 00475 if (ast_rdlock_contexts()) { 00476 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00477 goto error3; 00478 } 00479 00480 /* walk contexts */ 00481 c = NULL; 00482 while ( (c = ast_walk_contexts(c)) ) { 00483 /* XXX locking on c ? */ 00484 struct ast_exten *e; 00485 if (strcmp(ast_get_context_name(c), context) != 0) 00486 continue; 00487 /* got it, we must match here */ 00488 e = NULL; 00489 while ( (e = ast_walk_context_extensions(c, e)) ) { 00490 struct ast_exten *priority; 00491 char buffer[10]; 00492 00493 if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) { 00494 continue; 00495 } 00496 if (strcmp(ast_get_extension_name(e), exten) != 0) 00497 continue; 00498 /* XXX lock e ? */ 00499 priority = NULL; 00500 while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) { 00501 snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority)); 00502 if (partial_match(buffer, a->word, len) && ++which > a->n) /* n-th match */ 00503 ret = strdup(buffer); 00504 } 00505 break; 00506 } 00507 break; 00508 } 00509 ast_unlock_contexts(); 00510 error3: 00511 free(exten); 00512 } 00513 return ret; 00514 }
static char * complete_dialplan_remove_ignorepat | ( | struct ast_cli_args * | ) | [static] |
Definition at line 1197 of file pbx_config.c.
References ast_get_context_name(), ast_get_ignorepat_name(), ast_log(), ast_rdlock_context(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_ignorepats(), ast_walk_contexts(), free, len(), ast_cli_args::line, LOG_WARNING, lookup_c_ip(), ast_cli_args::n, partial_match(), ast_cli_args::pos, strdup, strsep(), and ast_cli_args::word.
Referenced by handle_cli_dialplan_remove_ignorepat().
01198 { 01199 struct ast_context *c; 01200 int which = 0; 01201 char *ret = NULL; 01202 01203 if (a->pos == 3) { 01204 int len = strlen(a->word); 01205 if (ast_rdlock_contexts()) { 01206 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01207 return NULL; 01208 } 01209 01210 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01211 struct ast_ignorepat *ip; 01212 01213 if (ast_rdlock_context(c)) /* error, skip it */ 01214 continue; 01215 01216 for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) { 01217 if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) { 01218 /* n-th match */ 01219 struct ast_context *cw = NULL; 01220 int found = 0; 01221 while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) { 01222 /* XXX do i stop on c, or skip it ? */ 01223 found = lookup_c_ip(cw, ast_get_ignorepat_name(ip)); 01224 } 01225 if (!found) 01226 ret = strdup(ast_get_ignorepat_name(ip)); 01227 } 01228 } 01229 ast_unlock_context(c); 01230 } 01231 ast_unlock_contexts(); 01232 return ret; 01233 } else if (a->pos == 4) { 01234 return a->n == 0 ? strdup("from") : NULL; 01235 } else if (a->pos == 5) { /* XXX check this */ 01236 char *dupline, *duplinet, *ignorepat; 01237 int len = strlen(a->word); 01238 01239 dupline = strdup(a->line); 01240 if (!dupline) { 01241 ast_log(LOG_WARNING, "Out of free memory\n"); 01242 return NULL; 01243 } 01244 01245 duplinet = dupline; 01246 strsep(&duplinet, " "); 01247 strsep(&duplinet, " "); 01248 ignorepat = strsep(&duplinet, " "); 01249 01250 if (!ignorepat) { 01251 free(dupline); 01252 return NULL; 01253 } 01254 01255 if (ast_rdlock_contexts()) { 01256 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01257 free(dupline); 01258 return NULL; 01259 } 01260 01261 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 01262 if (ast_rdlock_context(c)) /* fail, skip it */ 01263 continue; 01264 if (!partial_match(ast_get_context_name(c), a->word, len)) 01265 continue; 01266 if (lookup_c_ip(c, ignorepat) && ++which > a->n) 01267 ret = strdup(ast_get_context_name(c)); 01268 ast_unlock_context(c); 01269 } 01270 ast_unlock_contexts(); 01271 free(dupline); 01272 return NULL; 01273 } 01274 01275 return NULL; 01276 }
static char * complete_dialplan_remove_include | ( | struct ast_cli_args * | ) | [static] |
Definition at line 182 of file pbx_config.c.
References ast_get_context_name(), ast_get_include_name(), ast_log(), ast_rdlock_context(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_includes(), ast_walk_contexts(), ast_wrlock_contexts(), context, free, len(), ast_cli_args::line, LOG_ERROR, LOG_WARNING, lookup_ci(), ast_cli_args::n, partial_match(), ast_cli_args::pos, s, skip_words(), strdup, strsep(), and ast_cli_args::word.
Referenced by handle_cli_dialplan_remove_include().
00183 { 00184 int which = 0; 00185 char *res = NULL; 00186 int len = strlen(a->word); /* how many bytes to match */ 00187 struct ast_context *c = NULL; 00188 00189 if (a->pos == 3) { /* "dialplan remove include _X_" */ 00190 if (ast_wrlock_contexts()) { 00191 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00192 return NULL; 00193 } 00194 /* walk contexts and their includes, return the n-th match */ 00195 while (!res && (c = ast_walk_contexts(c))) { 00196 struct ast_include *i = NULL; 00197 00198 if (ast_rdlock_context(c)) /* error ? skip this one */ 00199 continue; 00200 00201 while ( !res && (i = ast_walk_context_includes(c, i)) ) { 00202 const char *i_name = ast_get_include_name(i); 00203 struct ast_context *nc = NULL; 00204 int already_served = 0; 00205 00206 if (!partial_match(i_name, a->word, len)) 00207 continue; /* not matched */ 00208 00209 /* check if this include is already served or not */ 00210 00211 /* go through all contexts again till we reach actual 00212 * context or already_served = 1 00213 */ 00214 while ( (nc = ast_walk_contexts(nc)) && nc != c && !already_served) 00215 already_served = lookup_ci(nc, i_name); 00216 00217 if (!already_served && ++which > a->n) 00218 res = strdup(i_name); 00219 } 00220 ast_unlock_context(c); 00221 } 00222 00223 ast_unlock_contexts(); 00224 return res; 00225 } else if (a->pos == 4) { /* "dialplan remove include CTX _X_" */ 00226 /* 00227 * complete as 'from', but only if previous context is really 00228 * included somewhere 00229 */ 00230 char *context, *dupline; 00231 const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */ 00232 00233 if (a->n > 0) 00234 return NULL; 00235 context = dupline = strdup(s); 00236 if (!dupline) { 00237 ast_log(LOG_ERROR, "Out of free memory\n"); 00238 return NULL; 00239 } 00240 strsep(&dupline, " "); 00241 00242 if (ast_rdlock_contexts()) { 00243 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 00244 free(context); 00245 return NULL; 00246 } 00247 00248 /* go through all contexts and check if is included ... */ 00249 while (!res && (c = ast_walk_contexts(c))) 00250 if (lookup_ci(c, context)) /* context is really included, complete "from" command */ 00251 res = strdup("from"); 00252 ast_unlock_contexts(); 00253 if (!res) 00254 ast_log(LOG_WARNING, "%s not included anywhere\n", context); 00255 free(context); 00256 return res; 00257 } else if (a->pos == 5) { /* "dialplan remove include CTX from _X_" */ 00258 /* 00259 * Context from which we removing include ... 00260 */ 00261 char *context, *dupline, *from; 00262 const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */ 00263 context = dupline = strdup(s); 00264 if (!dupline) { 00265 ast_log(LOG_ERROR, "Out of free memory\n"); 00266 return NULL; 00267 } 00268 00269 strsep(&dupline, " "); /* skip context */ 00270 00271 /* fourth word must be 'from' */ 00272 from = strsep(&dupline, " "); 00273 if (!from || strcmp(from, "from")) { 00274 free(context); 00275 return NULL; 00276 } 00277 00278 if (ast_rdlock_contexts()) { 00279 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00280 free(context); 00281 return NULL; 00282 } 00283 00284 /* walk through all contexts ... */ 00285 c = NULL; 00286 while ( !res && (c = ast_walk_contexts(c))) { 00287 const char *c_name = ast_get_context_name(c); 00288 if (!partial_match(c_name, a->word, len)) /* not a good target */ 00289 continue; 00290 /* walk through all includes and check if it is our context */ 00291 if (lookup_ci(c, context) && ++which > a->n) 00292 res = strdup(c_name); 00293 } 00294 ast_unlock_contexts(); 00295 free(context); 00296 return res; 00297 } 00298 00299 return NULL; 00300 }
static char* handle_cli_dialplan_add_extension | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
ADD EXTENSION command stuff.
Definition at line 902 of file pbx_config.c.
References app, ast_cli_args::argc, ast_cli_args::argv, ast_add_extension(), ast_cli(), ast_free_ptr, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_extension(), errno, exten, ast_cli_args::fd, PRIORITY_HINT, strdup, strsep(), and ast_cli_entry::usage.
00903 { 00904 char *whole_exten; 00905 char *exten, *prior; 00906 int iprior = -2; 00907 char *cidmatch, *app, *app_data; 00908 char *start, *end; 00909 00910 switch (cmd) { 00911 case CLI_INIT: 00912 e->command = "dialplan add extension"; 00913 e->usage = 00914 "Usage: dialplan add extension <exten>,<priority>,<app>,<app-data>\n" 00915 " into <context> [replace]\n\n" 00916 " This command will add new extension into <context>. If there is an\n" 00917 " existence of extension with the same priority and last 'replace'\n" 00918 " arguments is given here we simply replace this extension.\n" 00919 "\n" 00920 "Example: dialplan add extension 6123,1,Dial,IAX/216.207.245.56/6123 into local\n" 00921 " Now, you can dial 6123 and talk to Markster :)\n"; 00922 return NULL; 00923 case CLI_GENERATE: 00924 return complete_dialplan_add_extension(a); 00925 } 00926 00927 /* check for arguments at first */ 00928 if (a->argc != 6 && a->argc != 7) 00929 return CLI_SHOWUSAGE; 00930 if (strcmp(a->argv[4], "into")) 00931 return CLI_SHOWUSAGE; 00932 if (a->argc == 7) 00933 if (strcmp(a->argv[6], "replace")) 00934 return CLI_SHOWUSAGE; 00935 00936 /* XXX overwrite argv[3] */ 00937 whole_exten = a->argv[3]; 00938 exten = strsep(&whole_exten,","); 00939 if (strchr(exten, '/')) { 00940 cidmatch = exten; 00941 strsep(&cidmatch,"/"); 00942 } else { 00943 cidmatch = NULL; 00944 } 00945 prior = strsep(&whole_exten,","); 00946 if (prior) { 00947 if (!strcmp(prior, "hint")) { 00948 iprior = PRIORITY_HINT; 00949 } else { 00950 if (sscanf(prior, "%30d", &iprior) != 1) { 00951 ast_cli(a->fd, "'%s' is not a valid priority\n", prior); 00952 prior = NULL; 00953 } 00954 } 00955 } 00956 app = whole_exten; 00957 if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) { 00958 *start = *end = '\0'; 00959 app_data = start + 1; 00960 } else { 00961 if (app) { 00962 app_data = strchr(app, ','); 00963 if (app_data) { 00964 *app_data = '\0'; 00965 app_data++; 00966 } 00967 } else 00968 app_data = NULL; 00969 } 00970 00971 if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT)) 00972 return CLI_SHOWUSAGE; 00973 00974 if (!app_data) 00975 app_data=""; 00976 if (ast_add_extension(a->argv[5], a->argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app, 00977 (void *)strdup(app_data), ast_free_ptr, registrar)) { 00978 switch (errno) { 00979 case ENOMEM: 00980 ast_cli(a->fd, "Out of free memory\n"); 00981 break; 00982 00983 case EBUSY: 00984 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 00985 break; 00986 00987 case ENOENT: 00988 ast_cli(a->fd, "No existence of '%s' context\n", a->argv[5]); 00989 break; 00990 00991 case EEXIST: 00992 ast_cli(a->fd, "Extension %s@%s with priority %s already exists\n", 00993 exten, a->argv[5], prior); 00994 break; 00995 00996 default: 00997 ast_cli(a->fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n", 00998 exten, prior, app, app_data, a->argv[5]); 00999 break; 01000 } 01001 return CLI_FAILURE; 01002 } 01003 01004 if (a->argc == 7) 01005 ast_cli(a->fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n", 01006 exten, a->argv[5], prior, exten, prior, app, app_data); 01007 else 01008 ast_cli(a->fd, "Extension '%s,%s,%s,%s' added into '%s' context\n", 01009 exten, prior, app, app_data, a->argv[5]); 01010 01011 return CLI_SUCCESS; 01012 }
static char* handle_cli_dialplan_add_ignorepat | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
IGNOREPAT CLI stuff
Definition at line 1047 of file pbx_config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_add_ignorepat(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_ignorepat(), errno, ast_cli_args::fd, and ast_cli_entry::usage.
01048 { 01049 switch (cmd) { 01050 case CLI_INIT: 01051 e->command = "dialplan add ignorepat"; 01052 e->usage = 01053 "Usage: dialplan add ignorepat <pattern> into <context>\n" 01054 " This command adds a new ignore pattern into context <context>\n" 01055 "\n" 01056 "Example: dialplan add ignorepat _3XX into local\n"; 01057 return NULL; 01058 case CLI_GENERATE: 01059 return complete_dialplan_add_ignorepat(a); 01060 } 01061 01062 if (a->argc != 6) 01063 return CLI_SHOWUSAGE; 01064 01065 if (strcmp(a->argv[4], "into")) 01066 return CLI_SHOWUSAGE; 01067 01068 if (ast_context_add_ignorepat(a->argv[5], a->argv[3], registrar)) { 01069 switch (errno) { 01070 case ENOMEM: 01071 ast_cli(a->fd, "Out of free memory\n"); 01072 break; 01073 01074 case ENOENT: 01075 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01076 break; 01077 01078 case EEXIST: 01079 ast_cli(a->fd, "Ignore pattern '%s' already included in '%s' context\n", 01080 a->argv[3], a->argv[5]); 01081 break; 01082 01083 case EBUSY: 01084 ast_cli(a->fd, "Failed to lock context(s) list, please, try again later\n"); 01085 break; 01086 01087 default: 01088 ast_cli(a->fd, "Failed to add ingore pattern '%s' into '%s' context\n", 01089 a->argv[3], a->argv[5]); 01090 break; 01091 } 01092 return CLI_FAILURE; 01093 } 01094 01095 ast_cli(a->fd, "Ignore pattern '%s' added into '%s' context\n", 01096 a->argv[3], a->argv[5]); 01097 01098 return CLI_SUCCESS; 01099 }
static char* handle_cli_dialplan_add_include | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Include context ...
Definition at line 519 of file pbx_config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_add_include(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_include(), errno, ast_cli_args::fd, and ast_cli_entry::usage.
00520 { 00521 switch (cmd) { 00522 case CLI_INIT: 00523 e->command = "dialplan add include"; 00524 e->usage = 00525 "Usage: dialplan add include <context> into <context>\n" 00526 " Include a context in another context.\n"; 00527 return NULL; 00528 case CLI_GENERATE: 00529 return complete_dialplan_add_include(a); 00530 } 00531 00532 if (a->argc != 6) /* dialplan add include CTX in CTX */ 00533 return CLI_SHOWUSAGE; 00534 00535 /* fifth arg must be 'into' ... */ 00536 if (strcmp(a->argv[4], "into")) 00537 return CLI_SHOWUSAGE; 00538 00539 if (ast_context_add_include(a->argv[5], a->argv[3], registrar)) { 00540 switch (errno) { 00541 case ENOMEM: 00542 ast_cli(a->fd, "Out of memory for context addition\n"); 00543 break; 00544 00545 case EBUSY: 00546 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 00547 break; 00548 00549 case EEXIST: 00550 ast_cli(a->fd, "Context '%s' already included in '%s' context\n", 00551 a->argv[3], a->argv[5]); 00552 break; 00553 00554 case ENOENT: 00555 case EINVAL: 00556 ast_cli(a->fd, "There is no existence of context '%s'\n", 00557 errno == ENOENT ? a->argv[5] : a->argv[3]); 00558 break; 00559 00560 default: 00561 ast_cli(a->fd, "Failed to include '%s' in '%s' context\n", 00562 a->argv[3], a->argv[5]); 00563 break; 00564 } 00565 return CLI_FAILURE; 00566 } 00567 00568 /* show some info ... */ 00569 ast_cli(a->fd, "Context '%s' included in '%s' context\n", 00570 a->argv[3], a->argv[5]); 00571 00572 return CLI_SUCCESS; 00573 }
static char* handle_cli_dialplan_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1280 of file pbx_config.c.
References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, pbx_builtin_clear_globals(), pbx_load_module(), and ast_cli_entry::usage.
01281 { 01282 switch (cmd) { 01283 case CLI_INIT: 01284 e->command = "dialplan reload"; 01285 e->usage = 01286 "Usage: dialplan reload\n" 01287 " Reload extensions.conf without reloading any other\n" 01288 " modules. This command does not delete global variables\n" 01289 " unless clearglobalvars is set to yes in extensions.conf\n"; 01290 return NULL; 01291 case CLI_GENERATE: 01292 return NULL; 01293 } 01294 01295 if (a->argc != 2) 01296 return CLI_SHOWUSAGE; 01297 01298 if (clearglobalvars_config) 01299 pbx_builtin_clear_globals(); 01300 01301 pbx_load_module(); 01302 ast_cli(a->fd, "Dialplan reloaded.\n"); 01303 return CLI_SUCCESS; 01304 }
static char* handle_cli_dialplan_remove_extension | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
REMOVE EXTENSION command stuff
Definition at line 305 of file pbx_config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_remove_extension_callerid(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_remove_extension(), context, exten, ast_cli_args::fd, free, PRIORITY_HINT, split_ec(), and ast_cli_entry::usage.
00306 { 00307 int removing_priority = 0; 00308 char *exten, *context, *cid; 00309 char *ret = CLI_FAILURE; 00310 00311 switch (cmd) { 00312 case CLI_INIT: 00313 e->command = "dialplan remove extension"; 00314 e->usage = 00315 "Usage: dialplan remove extension exten[/cid]@context [priority]\n" 00316 " Remove an extension from a given context. If a priority\n" 00317 " is given, only that specific priority from the given extension\n" 00318 " will be removed.\n"; 00319 return NULL; 00320 case CLI_GENERATE: 00321 return complete_dialplan_remove_extension(a); 00322 } 00323 00324 if (a->argc != 5 && a->argc != 4) 00325 return CLI_SHOWUSAGE; 00326 00327 /* 00328 * Priority input checking ... 00329 */ 00330 if (a->argc == 5) { 00331 char *c = a->argv[4]; 00332 00333 /* check for digits in whole parameter for right priority ... 00334 * why? because atoi (strtol) returns 0 if any characters in 00335 * string and whole extension will be removed, it's not good 00336 */ 00337 if (!strcmp("hint", c)) 00338 removing_priority = PRIORITY_HINT; 00339 else { 00340 while (*c && isdigit(*c)) 00341 c++; 00342 if (*c) { /* non-digit in string */ 00343 ast_cli(a->fd, "Invalid priority '%s'\n", a->argv[4]); 00344 return CLI_FAILURE; 00345 } 00346 removing_priority = atoi(a->argv[4]); 00347 } 00348 00349 if (removing_priority == 0) { 00350 ast_cli(a->fd, "If you want to remove whole extension, please " \ 00351 "omit priority argument\n"); 00352 return CLI_FAILURE; 00353 } 00354 } 00355 00356 /* XXX original overwrote argv[3] */ 00357 /* 00358 * Format exten@context checking ... 00359 */ 00360 if (split_ec(a->argv[3], &exten, &context, &cid)) 00361 return CLI_FAILURE; /* XXX malloc failure */ 00362 if ((!strlen(exten)) || (!(strlen(context)))) { 00363 ast_cli(a->fd, "Missing extension or context name in third argument '%s'\n", 00364 a->argv[3]); 00365 free(exten); 00366 return CLI_FAILURE; 00367 } 00368 00369 if (!ast_context_remove_extension_callerid(context, exten, removing_priority, 00370 /* Do NOT substitute S_OR; it is NOT the same thing */ 00371 cid ? cid : (removing_priority ? "" : NULL), cid ? 1 : 0, registrar)) { 00372 if (!removing_priority) 00373 ast_cli(a->fd, "Whole extension %s@%s removed\n", 00374 exten, context); 00375 else 00376 ast_cli(a->fd, "Extension %s@%s with priority %d removed\n", 00377 exten, context, removing_priority); 00378 00379 ret = CLI_SUCCESS; 00380 } else { 00381 if (cid) { 00382 ast_cli(a->fd, "Failed to remove extension %s/%s@%s\n", exten, cid, context); 00383 } else { 00384 ast_cli(a->fd, "Failed to remove extension %s@%s\n", exten, context); 00385 } 00386 ret = CLI_FAILURE; 00387 } 00388 free(exten); 00389 return ret; 00390 }
static char* handle_cli_dialplan_remove_ignorepat | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1148 of file pbx_config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_remove_ignorepat(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_remove_ignorepat(), errno, ast_cli_args::fd, and ast_cli_entry::usage.
01149 { 01150 switch (cmd) { 01151 case CLI_INIT: 01152 e->command = "dialplan remove ignorepat"; 01153 e->usage = 01154 "Usage: dialplan remove ignorepat <pattern> from <context>\n" 01155 " This command removes an ignore pattern from context <context>\n" 01156 "\n" 01157 "Example: dialplan remove ignorepat _3XX from local\n"; 01158 return NULL; 01159 case CLI_GENERATE: 01160 return complete_dialplan_remove_ignorepat(a); 01161 } 01162 01163 if (a->argc != 6) 01164 return CLI_SHOWUSAGE; 01165 01166 if (strcmp(a->argv[4], "from")) 01167 return CLI_SHOWUSAGE; 01168 01169 if (ast_context_remove_ignorepat(a->argv[5], a->argv[3], registrar)) { 01170 switch (errno) { 01171 case EBUSY: 01172 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 01173 break; 01174 01175 case ENOENT: 01176 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01177 break; 01178 01179 case EINVAL: 01180 ast_cli(a->fd, "There is no existence of '%s' ignore pattern in '%s' context\n", 01181 a->argv[3], a->argv[5]); 01182 break; 01183 01184 default: 01185 ast_cli(a->fd, "Failed to remove ignore pattern '%s' from '%s' context\n", 01186 a->argv[3], a->argv[5]); 01187 break; 01188 } 01189 return CLI_FAILURE; 01190 } 01191 01192 ast_cli(a->fd, "Ignore pattern '%s' removed from '%s' context\n", 01193 a->argv[3], a->argv[5]); 01194 return CLI_SUCCESS; 01195 }
static char* handle_cli_dialplan_remove_include | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
REMOVE INCLUDE command stuff
Definition at line 73 of file pbx_config.c.
References ast_cli_args::argv, ast_cli(), ast_context_remove_include(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_remove_include(), ast_cli_args::fd, and ast_cli_entry::usage.
00074 { 00075 switch (cmd) { 00076 case CLI_INIT: 00077 e->command = "dialplan remove include"; 00078 e->usage = 00079 "Usage: dialplan remove include <context> from <context>\n" 00080 " Remove an included context from another context.\n"; 00081 return NULL; 00082 case CLI_GENERATE: 00083 return complete_dialplan_remove_include(a); 00084 } 00085 00086 if (strcmp(a->argv[4], "from")) 00087 return CLI_SHOWUSAGE; 00088 00089 if (!ast_context_remove_include(a->argv[5], a->argv[3], registrar)) { 00090 ast_cli(a->fd, "We are not including '%s' into '%s' now\n", 00091 a->argv[3], a->argv[5]); 00092 return CLI_SUCCESS; 00093 } 00094 00095 ast_cli(a->fd, "Failed to remove '%s' include from '%s' context\n", 00096 a->argv[3], a->argv[5]); 00097 return CLI_FAILURE; 00098 }
static char* handle_cli_dialplan_save | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
'save dialplan' CLI command implementation functions ...
Definition at line 672 of file pbx_config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_config_AST_CONFIG_DIR, ast_config_destroy(), ast_config_load, ast_get_context_name(), ast_get_context_registrar(), ast_get_extension_app(), ast_get_extension_app_data(), ast_get_extension_cidmatch(), ast_get_extension_label(), ast_get_extension_matchcid(), ast_get_extension_name(), ast_get_extension_priority(), ast_get_extension_registrar(), ast_get_ignorepat_name(), ast_get_ignorepat_registrar(), ast_get_include_name(), ast_get_include_registrar(), ast_get_switch_data(), ast_get_switch_name(), ast_get_switch_registrar(), ast_mutex_lock(), ast_mutex_unlock(), ast_rdlock_context(), ast_rdlock_contexts(), ast_strlen_zero(), ast_unlock_context(), ast_unlock_contexts(), ast_variable_browse(), ast_walk_context_extensions(), ast_walk_context_ignorepats(), ast_walk_context_includes(), ast_walk_context_switches(), ast_walk_contexts(), ast_walk_extension_priorities(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, config_flags, el, ext, ast_cli_args::fd, ast_variable::name, ast_variable::next, overrideswitch, PRIORITY_HINT, PUT_CTX_HDR, save_dialplan_lock, ast_cli_entry::usage, and ast_variable::value.
00673 { 00674 char filename[256], overrideswitch[256] = ""; 00675 struct ast_context *c; 00676 struct ast_config *cfg; 00677 struct ast_variable *v; 00678 int incomplete = 0; /* incomplete config write? */ 00679 FILE *output; 00680 struct ast_flags config_flags = { 0 }; 00681 const char *base, *slash, *file; 00682 00683 switch (cmd) { 00684 case CLI_INIT: 00685 e->command = "dialplan save"; 00686 e->usage = 00687 "Usage: dialplan save [/path/to/extension/file]\n" 00688 " Save dialplan created by pbx_config module.\n" 00689 "\n" 00690 "Example: dialplan save (/etc/asterisk/extensions.conf)\n" 00691 " dialplan save /home/markster (/home/markster/extensions.conf)\n"; 00692 return NULL; 00693 case CLI_GENERATE: 00694 return NULL; 00695 } 00696 00697 if (! (static_config && !write_protect_config)) { 00698 ast_cli(a->fd, 00699 "I can't save dialplan now, see '%s' example file.\n", 00700 config); 00701 return CLI_FAILURE; 00702 } 00703 00704 if (a->argc != 2 && a->argc != 3) 00705 return CLI_SHOWUSAGE; 00706 00707 if (ast_mutex_lock(&save_dialplan_lock)) { 00708 ast_cli(a->fd, 00709 "Failed to lock dialplan saving (another proccess saving?)\n"); 00710 return CLI_FAILURE; 00711 } 00712 /* XXX the code here is quite loose, a pathname with .conf in it 00713 * is assumed to be a complete pathname 00714 */ 00715 if (a->argc == 3) { /* have config path. Look for *.conf */ 00716 base = a->argv[2]; 00717 if (!strstr(a->argv[2], ".conf")) { /*no, this is assumed to be a pathname */ 00718 /* if filename ends with '/', do not add one */ 00719 slash = (*(a->argv[2] + strlen(a->argv[2]) -1) == '/') ? "/" : ""; 00720 file = config; /* default: 'extensions.conf' */ 00721 } else { /* yes, complete file name */ 00722 slash = ""; 00723 file = ""; 00724 } 00725 } else { 00726 /* no config file, default one */ 00727 base = ast_config_AST_CONFIG_DIR; 00728 slash = "/"; 00729 file = config; 00730 } 00731 snprintf(filename, sizeof(filename), "%s%s%s", base, slash, config); 00732 00733 cfg = ast_config_load("extensions.conf", config_flags); 00734 00735 /* try to lock contexts list */ 00736 if (ast_rdlock_contexts()) { 00737 ast_cli(a->fd, "Failed to lock contexts list\n"); 00738 ast_mutex_unlock(&save_dialplan_lock); 00739 ast_config_destroy(cfg); 00740 return CLI_FAILURE; 00741 } 00742 00743 /* create new file ... */ 00744 if (!(output = fopen(filename, "wt"))) { 00745 ast_cli(a->fd, "Failed to create file '%s'\n", 00746 filename); 00747 ast_unlock_contexts(); 00748 ast_mutex_unlock(&save_dialplan_lock); 00749 ast_config_destroy(cfg); 00750 return CLI_FAILURE; 00751 } 00752 00753 /* fireout general info */ 00754 if (overrideswitch_config) { 00755 snprintf(overrideswitch, sizeof(overrideswitch), "overrideswitch=%s\n", overrideswitch_config); 00756 } 00757 fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\n%sextenpatternmatchnew=%s\n\n", 00758 static_config ? "yes" : "no", 00759 write_protect_config ? "yes" : "no", 00760 autofallthrough_config ? "yes" : "no", 00761 clearglobalvars_config ? "yes" : "no", 00762 overrideswitch_config ? overrideswitch : "", 00763 extenpatternmatchnew_config ? "yes" : "no"); 00764 00765 if ((v = ast_variable_browse(cfg, "globals"))) { 00766 fprintf(output, "[globals]\n"); 00767 while(v) { 00768 fprintf(output, "%s => %s\n", v->name, v->value); 00769 v = v->next; 00770 } 00771 fprintf(output, "\n"); 00772 } 00773 00774 ast_config_destroy(cfg); 00775 00776 #define PUT_CTX_HDR do { \ 00777 if (!context_header_written) { \ 00778 fprintf(output, "[%s]\n", ast_get_context_name(c)); \ 00779 context_header_written = 1; \ 00780 } \ 00781 } while (0) 00782 00783 /* walk all contexts */ 00784 for (c = NULL; (c = ast_walk_contexts(c)); ) { 00785 int context_header_written = 0; 00786 struct ast_exten *ext, *last_written_e = NULL; 00787 struct ast_include *i; 00788 struct ast_ignorepat *ip; 00789 struct ast_sw *sw; 00790 00791 /* try to lock context and fireout all info */ 00792 if (ast_rdlock_context(c)) { /* lock failure */ 00793 incomplete = 1; 00794 continue; 00795 } 00796 /* registered by this module? */ 00797 /* XXX do we need this ? */ 00798 if (!strcmp(ast_get_context_registrar(c), registrar)) { 00799 fprintf(output, "[%s]\n", ast_get_context_name(c)); 00800 context_header_written = 1; 00801 } 00802 00803 /* walk extensions ... */ 00804 for (ext = NULL; (ext = ast_walk_context_extensions(c, ext)); ) { 00805 struct ast_exten *p = NULL; 00806 00807 /* fireout priorities */ 00808 while ( (p = ast_walk_extension_priorities(ext, p)) ) { 00809 if (strcmp(ast_get_extension_registrar(p), registrar) != 0) /* not this source */ 00810 continue; 00811 00812 /* make empty line between different extensions */ 00813 if (last_written_e != NULL && 00814 strcmp(ast_get_extension_name(last_written_e), 00815 ast_get_extension_name(p))) 00816 fprintf(output, "\n"); 00817 last_written_e = p; 00818 00819 PUT_CTX_HDR; 00820 00821 if (ast_get_extension_priority(p) == PRIORITY_HINT) { /* easy */ 00822 fprintf(output, "exten => %s,hint,%s\n", 00823 ast_get_extension_name(p), 00824 ast_get_extension_app(p)); 00825 } else { 00826 const char *sep, *cid; 00827 const char *el = ast_get_extension_label(p); 00828 char label[128] = ""; 00829 00830 if (ast_get_extension_matchcid(p)) { 00831 sep = "/"; 00832 cid = ast_get_extension_cidmatch(p); 00833 } else 00834 sep = cid = ""; 00835 00836 if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2))) 00837 incomplete = 1; /* error encountered or label > 125 chars */ 00838 00839 fprintf(output, "exten => %s%s%s,%d%s,%s(%s)\n", 00840 ast_get_extension_name(p), (ast_strlen_zero(sep) ? "" : sep), (ast_strlen_zero(cid) ? "" : cid), 00841 ast_get_extension_priority(p), label, 00842 ast_get_extension_app(p), (ast_strlen_zero(ast_get_extension_app_data(p)) ? "" : (const char *)ast_get_extension_app_data(p))); 00843 } 00844 } 00845 } 00846 00847 /* written any extensions? ok, write space between exten & inc */ 00848 if (last_written_e) 00849 fprintf(output, "\n"); 00850 00851 /* walk through includes */ 00852 for (i = NULL; (i = ast_walk_context_includes(c, i)) ; ) { 00853 if (strcmp(ast_get_include_registrar(i), registrar) != 0) 00854 continue; /* not mine */ 00855 PUT_CTX_HDR; 00856 fprintf(output, "include => %s\n", ast_get_include_name(i)); 00857 } 00858 if (ast_walk_context_includes(c, NULL)) 00859 fprintf(output, "\n"); 00860 00861 /* walk through switches */ 00862 for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) { 00863 if (strcmp(ast_get_switch_registrar(sw), registrar) != 0) 00864 continue; /* not mine */ 00865 PUT_CTX_HDR; 00866 fprintf(output, "switch => %s/%s\n", 00867 ast_get_switch_name(sw), ast_get_switch_data(sw)); 00868 } 00869 00870 if (ast_walk_context_switches(c, NULL)) 00871 fprintf(output, "\n"); 00872 00873 /* fireout ignorepats ... */ 00874 for (ip = NULL; (ip = ast_walk_context_ignorepats(c, ip)); ) { 00875 if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0) 00876 continue; /* not mine */ 00877 PUT_CTX_HDR; 00878 fprintf(output, "ignorepat => %s\n", 00879 ast_get_ignorepat_name(ip)); 00880 } 00881 00882 ast_unlock_context(c); 00883 } 00884 00885 ast_unlock_contexts(); 00886 ast_mutex_unlock(&save_dialplan_lock); 00887 fclose(output); 00888 00889 if (incomplete) { 00890 ast_cli(a->fd, "Saved dialplan is incomplete\n"); 00891 return CLI_FAILURE; 00892 } 00893 00894 ast_cli(a->fd, "Dialplan successfully saved into '%s'\n", 00895 filename); 00896 return CLI_SUCCESS; 00897 }
static int load_module | ( | void | ) | [static] |
Definition at line 1666 of file pbx_config.c.
References ast_cli_register(), ast_cli_register_multiple(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, cli_dialplan_save, cli_pbx_config, pbx_load_module(), static_config, and write_protect_config.
01667 { 01668 if (pbx_load_module()) 01669 return AST_MODULE_LOAD_DECLINE; 01670 01671 if (static_config && !write_protect_config) 01672 ast_cli_register(&cli_dialplan_save); 01673 ast_cli_register_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry)); 01674 01675 return AST_MODULE_LOAD_SUCCESS; 01676 }
static int lookup_c_ip | ( | struct ast_context * | c, | |
const char * | name | |||
) | [static] |
return true if 'name' is in the ignorepats for context c
Definition at line 115 of file pbx_config.c.
References ast_get_ignorepat_name(), ast_rdlock_context(), ast_unlock_context(), and ast_walk_context_ignorepats().
Referenced by complete_dialplan_add_ignorepat(), and complete_dialplan_remove_ignorepat().
00116 { 00117 struct ast_ignorepat *ip = NULL; 00118 00119 if (ast_rdlock_context(c)) /* error, skip */ 00120 return 0; 00121 while ( (ip = ast_walk_context_ignorepats(c, ip)) ) 00122 if (!strcmp(name, ast_get_ignorepat_name(ip))) 00123 break; 00124 ast_unlock_context(c); 00125 return ip ? -1 /* success */ : 0; 00126 }
static int lookup_ci | ( | struct ast_context * | c, | |
const char * | name | |||
) | [static] |
return true if 'name' is included by context c
Definition at line 101 of file pbx_config.c.
References ast_get_include_name(), ast_rdlock_context(), ast_unlock_context(), and ast_walk_context_includes().
Referenced by complete_dialplan_add_include(), and complete_dialplan_remove_include().
00102 { 00103 struct ast_include *i = NULL; 00104 00105 if (ast_rdlock_context(c)) /* error, skip */ 00106 return 0; 00107 while ( (i = ast_walk_context_includes(c, i)) ) 00108 if (!strcmp(name, ast_get_include_name(i))) 00109 break; 00110 ast_unlock_context(c); 00111 return i ? -1 /* success */ : 0; 00112 }
static int partial_match | ( | const char * | s, | |
const char * | word, | |||
int | len | |||
) | [static] |
match the first 'len' chars of word. len==0 always succeeds
Definition at line 144 of file pbx_config.c.
Referenced by complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), and complete_dialplan_remove_include().
static int pbx_load_config | ( | const char * | config_file | ) | [static] |
Definition at line 1337 of file pbx_config.c.
References ast_add_extension2(), ast_category_browse(), ast_config_load, ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_find_or_create(), ast_copy_string(), ast_findlabel_extension2(), ast_free, ast_free_ptr, ast_log(), ast_opt_dont_warn, ast_shrink_phone_number(), ast_skip_blanks(), ast_strdup, ast_strlen_zero(), ast_trim_blanks(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), config_flags, ext, free, ast_variable::lineno, local_contexts, local_table, LOG_WARNING, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), PRIORITY_HINT, S_OR, strdup, strsep(), and ast_variable::value.
Referenced by pbx_load_module().
01338 { 01339 struct ast_config *cfg; 01340 char *end; 01341 char *label; 01342 #ifdef LOW_MEMORY 01343 char realvalue[256]; 01344 #else 01345 char realvalue[8192]; 01346 #endif 01347 int lastpri = -2; 01348 struct ast_context *con; 01349 struct ast_variable *v; 01350 const char *cxt; 01351 const char *aft; 01352 const char *newpm, *ovsw; 01353 struct ast_flags config_flags = { 0 }; 01354 cfg = ast_config_load(config_file, config_flags); 01355 if (!cfg) 01356 return 0; 01357 01358 /* Use existing config to populate the PBX table */ 01359 static_config = ast_true(ast_variable_retrieve(cfg, "general", "static")); 01360 write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect")); 01361 if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough"))) 01362 autofallthrough_config = ast_true(aft); 01363 if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew"))) 01364 extenpatternmatchnew_config = ast_true(newpm); 01365 clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars")); 01366 if ((ovsw = ast_variable_retrieve(cfg, "general", "overrideswitch"))) { 01367 if (overrideswitch_config) { 01368 ast_free(overrideswitch_config); 01369 } 01370 if (!ast_strlen_zero(ovsw)) { 01371 overrideswitch_config = ast_strdup(ovsw); 01372 } else { 01373 overrideswitch_config = NULL; 01374 } 01375 } 01376 01377 if ((cxt = ast_variable_retrieve(cfg, "general", "userscontext"))) 01378 ast_copy_string(userscontext, cxt, sizeof(userscontext)); 01379 else 01380 ast_copy_string(userscontext, "default", sizeof(userscontext)); 01381 01382 for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) { 01383 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01384 pbx_builtin_setvar_helper(NULL, v->name, realvalue); 01385 } 01386 for (cxt = NULL; (cxt = ast_category_browse(cfg, cxt)); ) { 01387 /* All categories but "general" or "globals" are considered contexts */ 01388 if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) 01389 continue; 01390 con=ast_context_find_or_create(&local_contexts, local_table, cxt, registrar); 01391 if (con == NULL) 01392 continue; 01393 01394 for (v = ast_variable_browse(cfg, cxt); v; v = v->next) { 01395 if (!strcasecmp(v->name, "exten")) { 01396 char *tc = ast_strdup(v->value); 01397 if (tc) { 01398 int ipri = -2; 01399 char realext[256]=""; 01400 char *plus, *firstp; 01401 char *pri, *appl, *data, *cidmatch; 01402 char *stringp = tc; 01403 char *ext = strsep(&stringp, ","); 01404 if (!ext) 01405 ext=""; 01406 pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1); 01407 cidmatch = strchr(realext, '/'); 01408 if (cidmatch) { 01409 *cidmatch++ = '\0'; 01410 ast_shrink_phone_number(cidmatch); 01411 } 01412 pri = strsep(&stringp, ","); 01413 if (!pri) 01414 pri=""; 01415 pri = ast_skip_blanks(pri); 01416 pri = ast_trim_blanks(pri); 01417 label = strchr(pri, '('); 01418 if (label) { 01419 *label++ = '\0'; 01420 end = strchr(label, ')'); 01421 if (end) 01422 *end = '\0'; 01423 else 01424 ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno); 01425 } 01426 plus = strchr(pri, '+'); 01427 if (plus) 01428 *plus++ = '\0'; 01429 if (!strcmp(pri,"hint")) 01430 ipri=PRIORITY_HINT; 01431 else if (!strcmp(pri, "next") || !strcmp(pri, "n")) { 01432 if (lastpri > -2) 01433 ipri = lastpri + 1; 01434 else 01435 ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry!\n"); 01436 } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) { 01437 if (lastpri > -2) 01438 ipri = lastpri; 01439 else 01440 ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry!\n"); 01441 } else if (sscanf(pri, "%30d", &ipri) != 1 && 01442 (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) { 01443 ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno); 01444 ipri = 0; 01445 } 01446 appl = S_OR(stringp, ""); 01447 /* Find the first occurrence of '(' */ 01448 firstp = strchr(appl, '('); 01449 if (!firstp) { 01450 /* No arguments */ 01451 data = ""; 01452 } else { 01453 char *orig_appl = ast_strdup(appl); 01454 01455 if (!orig_appl) 01456 return -1; 01457 01458 appl = strsep(&stringp, "("); 01459 01460 /* check if there are variables or expressions without an application, like: exten => 100,hint,DAHDI/g0/${GLOBAL(var)} */ 01461 if (strstr(appl, "${") || strstr(appl, "$[")){ 01462 /* set appl to original one */ 01463 strcpy(appl, orig_appl); 01464 /* set no data */ 01465 data = ""; 01466 /* no variable before application found -> go ahead */ 01467 } else { 01468 data = S_OR(stringp, ""); 01469 if ((end = strrchr(data, ')'))) { 01470 *end = '\0'; 01471 } else { 01472 ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s' at line %d\n", appl, data, v->lineno); 01473 } 01474 } 01475 ast_free(orig_appl); 01476 } 01477 01478 if (!data) 01479 data = ""; 01480 appl = ast_skip_blanks(appl); 01481 if (ipri) { 01482 if (plus) 01483 ipri += atoi(plus); 01484 lastpri = ipri; 01485 if (!ast_opt_dont_warn && !strcmp(realext, "_.")) 01486 ast_log(LOG_WARNING, "The use of '_.' for an extension is strongly discouraged and can have unexpected behavior. Please use '_X.' instead at line %d\n", v->lineno); 01487 if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free_ptr, registrar)) { 01488 ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno); 01489 } 01490 } 01491 free(tc); 01492 } 01493 } else if (!strcasecmp(v->name, "include")) { 01494 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01495 if (ast_context_add_include2(con, realvalue, registrar)) 01496 ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s' at line %d\n", v->value, cxt, v->lineno); 01497 } else if (!strcasecmp(v->name, "ignorepat")) { 01498 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01499 if (ast_context_add_ignorepat2(con, realvalue, registrar)) 01500 ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s' at line %d\n", v->value, cxt, v->lineno); 01501 } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) { 01502 char *stringp = realvalue; 01503 char *appl, *data; 01504 01505 if (!strcasecmp(v->name, "switch")) 01506 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01507 else 01508 ast_copy_string(realvalue, v->value, sizeof(realvalue)); 01509 appl = strsep(&stringp, "/"); 01510 data = S_OR(stringp, ""); 01511 if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar)) 01512 ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s' at line %d\n", v->value, cxt, v->lineno); 01513 } else { 01514 ast_log(LOG_WARNING, "==!!== Unknown directive: %s at line %d -- IGNORING!!!\n", v->name, v->lineno); 01515 } 01516 } 01517 } 01518 ast_config_destroy(cfg); 01519 return 1; 01520 }
static int pbx_load_module | ( | void | ) | [static] |
Definition at line 1640 of file pbx_config.c.
References ast_context_verify_includes(), ast_hashtab_compare_contexts(), ast_hashtab_create(), ast_hashtab_hash_contexts(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), ast_merge_contexts_and_delete(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_walk_contexts(), autofallthrough_config, config, extenpatternmatchnew_config, local_contexts, local_table, overrideswitch_config, pbx_load_config(), pbx_load_users(), pbx_set_autofallthrough(), pbx_set_extenpatternmatchnew(), pbx_set_overrideswitch(), and registrar.
01641 { 01642 struct ast_context *con; 01643 01644 if (!local_table) 01645 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); 01646 01647 if (!pbx_load_config(config)) 01648 return AST_MODULE_LOAD_DECLINE; 01649 01650 pbx_load_users(); 01651 01652 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar); 01653 local_table = NULL; /* the local table has been moved into the global one. */ 01654 local_contexts = NULL; 01655 01656 for (con = NULL; (con = ast_walk_contexts(con));) 01657 ast_context_verify_includes(con); 01658 01659 pbx_set_overrideswitch(overrideswitch_config); 01660 pbx_set_autofallthrough(autofallthrough_config); 01661 pbx_set_extenpatternmatchnew(extenpatternmatchnew_config); 01662 01663 return AST_MODULE_LOAD_SUCCESS; 01664 }
static void pbx_load_users | ( | void | ) | [static] |
Definition at line 1534 of file pbx_config.c.
References append_interface(), ast_add_extension2(), ast_category_browse(), ast_config_destroy(), ast_config_load, ast_config_option(), ast_context_find_or_create(), ast_copy_string(), ast_free_ptr, ast_log(), ast_strlen_zero(), ast_true(), ast_variable_retrieve(), chan, config_flags, ext, len(), local_contexts, local_table, LOG_ERROR, registrar, strdup, strsep(), and userscontext.
Referenced by pbx_load_module().
01535 { 01536 struct ast_config *cfg; 01537 char *cat, *chan; 01538 const char *dahdichan; 01539 const char *hasexten, *altexts; 01540 char tmp[256]; 01541 char iface[256]; 01542 char dahdicopy[256]; 01543 char *ext, altcopy[256]; 01544 char *c; 01545 int len; 01546 int hasvoicemail; 01547 int start, finish, x; 01548 struct ast_context *con = NULL; 01549 struct ast_flags config_flags = { 0 }; 01550 01551 cfg = ast_config_load("users.conf", config_flags); 01552 if (!cfg) 01553 return; 01554 01555 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 01556 if (!strcasecmp(cat, "general")) 01557 continue; 01558 iface[0] = '\0'; 01559 len = sizeof(iface); 01560 if (ast_true(ast_config_option(cfg, cat, "hassip"))) { 01561 snprintf(tmp, sizeof(tmp), "SIP/%s", cat); 01562 append_interface(iface, sizeof(iface), tmp); 01563 } 01564 if (ast_true(ast_config_option(cfg, cat, "hasiax"))) { 01565 snprintf(tmp, sizeof(tmp), "IAX2/%s", cat); 01566 append_interface(iface, sizeof(iface), tmp); 01567 } 01568 if (ast_true(ast_config_option(cfg, cat, "hash323"))) { 01569 snprintf(tmp, sizeof(tmp), "H323/%s", cat); 01570 append_interface(iface, sizeof(iface), tmp); 01571 } 01572 hasexten = ast_config_option(cfg, cat, "hasexten"); 01573 if (hasexten && !ast_true(hasexten)) 01574 continue; 01575 hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail")); 01576 dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan"); 01577 if (!dahdichan) 01578 dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan"); 01579 if (!ast_strlen_zero(dahdichan)) { 01580 ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy)); 01581 c = dahdicopy; 01582 chan = strsep(&c, ","); 01583 while (chan) { 01584 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) { 01585 /* Range */ 01586 } else if (sscanf(chan, "%30d", &start)) { 01587 /* Just one */ 01588 finish = start; 01589 } else { 01590 start = 0; finish = 0; 01591 } 01592 if (finish < start) { 01593 x = finish; 01594 finish = start; 01595 start = x; 01596 } 01597 for (x = start; x <= finish; x++) { 01598 snprintf(tmp, sizeof(tmp), "DAHDI/%d", x); 01599 append_interface(iface, sizeof(iface), tmp); 01600 } 01601 chan = strsep(&c, ","); 01602 } 01603 } 01604 if (!ast_strlen_zero(iface)) { 01605 /* Only create a context here when it is really needed. Otherwise default empty context 01606 created by pbx_config may conflict with the one explicitly created by pbx_ael */ 01607 if (!con) 01608 con = ast_context_find_or_create(&local_contexts, local_table, userscontext, registrar); 01609 01610 if (!con) { 01611 ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext); 01612 return; 01613 } 01614 01615 /* Add hint */ 01616 ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar); 01617 /* If voicemail, use "stdexten" else use plain old dial */ 01618 if (hasvoicemail) { 01619 snprintf(tmp, sizeof(tmp), "stdexten,%s,${HINT}", cat); 01620 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", strdup(tmp), ast_free_ptr, registrar); 01621 } else { 01622 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", strdup("${HINT}"), ast_free_ptr, registrar); 01623 } 01624 altexts = ast_variable_retrieve(cfg, cat, "alternateexts"); 01625 if (!ast_strlen_zero(altexts)) { 01626 snprintf(tmp, sizeof(tmp), "%s,1", cat); 01627 ast_copy_string(altcopy, altexts, sizeof(altcopy)); 01628 c = altcopy; 01629 ext = strsep(&c, ","); 01630 while (ext) { 01631 ast_add_extension2(con, 0, ext, 1, NULL, NULL, "Goto", strdup(tmp), ast_free_ptr, registrar); 01632 ext = strsep(&c, ","); 01633 } 01634 } 01635 } 01636 } 01637 ast_config_destroy(cfg); 01638 }
static int reload | ( | void | ) | [static] |
Definition at line 1678 of file pbx_config.c.
References clearglobalvars_config, pbx_builtin_clear_globals(), and pbx_load_module().
01679 { 01680 if (clearglobalvars_config) 01681 pbx_builtin_clear_globals(); 01682 return pbx_load_module(); 01683 }
static const char* skip_words | ( | const char * | p, | |
int | n | |||
) | [static] |
moves to the n-th word in the string, or empty string if none
Definition at line 129 of file pbx_config.c.
Referenced by complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), and complete_dialplan_remove_include().
00130 { 00131 int in_blank = 0; 00132 for (;n && *p; p++) { 00133 if (isblank(*p) /* XXX order is important */ && !in_blank) { 00134 n--; /* one word is gone */ 00135 in_blank = 1; 00136 } else if (/* !is_blank(*p), we know already, && */ in_blank) { 00137 in_blank = 0; 00138 } 00139 } 00140 return p; 00141 }
static int split_ec | ( | const char * | src, | |
char ** | ext, | |||
char **const | ctx, | |||
char **const | cid | |||
) | [static] |
split extension@context in two parts, return -1 on error. The return string is malloc'ed and pointed by *ext
Definition at line 152 of file pbx_config.c.
References ast_strdup, and free.
Referenced by complete_dialplan_remove_extension(), and handle_cli_dialplan_remove_extension().
00153 { 00154 char *i, *c, *e = ast_strdup(src); /* now src is not used anymore */ 00155 00156 if (e == NULL) 00157 return -1; /* malloc error */ 00158 /* now, parse values from 'exten@context' */ 00159 *ext = e; 00160 c = strchr(e, '@'); 00161 if (c == NULL) /* no context part */ 00162 *ctx = ""; /* it is not overwritten, anyways */ 00163 else { /* found context, check for duplicity ... */ 00164 *c++ = '\0'; 00165 *ctx = c; 00166 if (strchr(c, '@')) { /* two @, not allowed */ 00167 free(e); 00168 return -1; 00169 } 00170 } 00171 if (cid && (i = strchr(e, '/'))) { 00172 *i++ = '\0'; 00173 *cid = i; 00174 } else if (cid) { 00175 /* Signal none detected */ 00176 *cid = NULL; 00177 } 00178 return 0; 00179 }
static int unload_module | ( | void | ) | [static] |
Standard module functions ...
Definition at line 1325 of file pbx_config.c.
References ast_cli_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_free, cli_dialplan_save, and cli_pbx_config.
01326 { 01327 if (static_config && !write_protect_config) 01328 ast_cli_unregister(&cli_dialplan_save); 01329 if (overrideswitch_config) { 01330 ast_free(overrideswitch_config); 01331 } 01332 ast_cli_unregister_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry)); 01333 ast_context_destroy(NULL, registrar); 01334 return 0; 01335 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Text Extension Configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1689 of file pbx_config.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1689 of file pbx_config.c.
int autofallthrough_config = 1 [static] |
int clearglobalvars_config = 0 [static] |
struct ast_cli_entry cli_dialplan_save [static] |
Initial value:
{ .handler = handle_cli_dialplan_save , .summary = "Save dialplan" ,__VA_ARGS__ }
Definition at line 1319 of file pbx_config.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_pbx_config[] [static] |
CLI entries for commands provided by this module
Definition at line 1309 of file pbx_config.c.
Referenced by load_module(), and unload_module().
char* config = "extensions.conf" [static] |
Definition at line 41 of file pbx_config.c.
int extenpatternmatchnew_config = 0 [static] |
struct ast_context* local_contexts = NULL [static] |
Definition at line 54 of file pbx_config.c.
Referenced by ast_context_find_or_create(), lua_register_switches(), lua_reload_extensions(), pbx_load_config(), pbx_load_module(), and pbx_load_users().
struct ast_hashtab* local_table = NULL [static] |
Definition at line 55 of file pbx_config.c.
Referenced by lua_register_switches(), lua_reload_extensions(), pbx_load_config(), pbx_load_module(), and pbx_load_users().
char* overrideswitch_config = NULL [static] |
char* registrar = "pbx_config" [static] |
Definition at line 42 of file pbx_config.c.
ast_mutex_t save_dialplan_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
int static_config = 0 [static] |
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 43 of file pbx_config.c.
int write_protect_config = 1 [static] |