Populate and remember extensions from static config file. More...
#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 char * | pbx_strsep (char **destructible, const char *delim) |
| 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 = "0901e4e500243c855563a2d78b0c03e4" , .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 |
Populate and remember extensions from static config file.
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 1763 of file pbx_config.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1763 of file pbx_config.c.
| static void append_interface | ( | char * | iface, | |
| int | maxlen, | |||
| char * | add | |||
| ) | [static] |
Definition at line 1596 of file pbx_config.c.
References len().
Referenced by pbx_load_users().
01597 { 01598 int len = strlen(iface); 01599 if (strlen(add) + len < maxlen - 2) { 01600 if (strlen(iface)) { 01601 iface[len] = '&'; 01602 strcpy(iface + len + 1, add); 01603 } else 01604 strcpy(iface, add); 01605 } 01606 }
| 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 * | a | ) | [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, 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 * | a | ) | [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, 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 * | a | ) | [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 * | a | ) | [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, 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 * | a | ) | [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, 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(), ast_exten::cidmatch, 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, 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, el, ext, ast_cli_args::fd, ast_exten::label, 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 1740 of file pbx_config.c.
References ARRAY_LEN, ast_cli_register(), ast_cli_register_multiple(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and pbx_load_module().
01741 { 01742 if (pbx_load_module()) 01743 return AST_MODULE_LOAD_DECLINE; 01744 01745 if (static_config && !write_protect_config) 01746 ast_cli_register(&cli_dialplan_save); 01747 ast_cli_register_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config)); 01748 01749 return AST_MODULE_LOAD_SUCCESS; 01750 }
| 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 1367 of file pbx_config.c.
References ast_add_extension2(), ast_category_browse(), ast_config_destroy(), 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_STATUS_FILEINVALID, errno, ext, free, ast_variable::lineno, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), pbx_strsep(), pbx_substitute_variables_helper(), PRIORITY_HINT, S_OR, strdup, and ast_variable::value.
Referenced by pbx_load_module().
01368 { 01369 struct ast_config *cfg; 01370 char *end; 01371 char *label; 01372 #ifdef LOW_MEMORY 01373 char realvalue[256]; 01374 #else 01375 char realvalue[8192]; 01376 #endif 01377 int lastpri = -2; 01378 struct ast_context *con; 01379 struct ast_variable *v; 01380 const char *cxt; 01381 const char *aft; 01382 const char *newpm, *ovsw; 01383 struct ast_flags config_flags = { 0 }; 01384 char lastextension[256]; 01385 cfg = ast_config_load(config_file, config_flags); 01386 if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) 01387 return 0; 01388 01389 /* Use existing config to populate the PBX table */ 01390 static_config = ast_true(ast_variable_retrieve(cfg, "general", "static")); 01391 write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect")); 01392 if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough"))) 01393 autofallthrough_config = ast_true(aft); 01394 if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew"))) 01395 extenpatternmatchnew_config = ast_true(newpm); 01396 clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars")); 01397 if ((ovsw = ast_variable_retrieve(cfg, "general", "overrideswitch"))) { 01398 if (overrideswitch_config) { 01399 ast_free(overrideswitch_config); 01400 } 01401 if (!ast_strlen_zero(ovsw)) { 01402 overrideswitch_config = ast_strdup(ovsw); 01403 } else { 01404 overrideswitch_config = NULL; 01405 } 01406 } 01407 01408 ast_copy_string(userscontext, ast_variable_retrieve(cfg, "general", "userscontext") ?: "default", sizeof(userscontext)); 01409 01410 for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) { 01411 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01412 pbx_builtin_setvar_helper(NULL, v->name, realvalue); 01413 } 01414 for (cxt = ast_category_browse(cfg, NULL); 01415 cxt; 01416 cxt = ast_category_browse(cfg, cxt)) { 01417 /* All categories but "general" or "globals" are considered contexts */ 01418 if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) { 01419 continue; 01420 } 01421 if (!(con = ast_context_find_or_create(&local_contexts, local_table, cxt, registrar))) { 01422 continue; 01423 } 01424 01425 /* Reset continuation items at the beginning of each context */ 01426 lastextension[0] = '\0'; 01427 lastpri = -2; 01428 01429 for (v = ast_variable_browse(cfg, cxt); v; v = v->next) { 01430 char *tc = NULL; 01431 char realext[256] = ""; 01432 char *stringp, *ext; 01433 01434 if (!strncasecmp(v->name, "same", 4)) { 01435 if (ast_strlen_zero(lastextension)) { 01436 ast_log(LOG_ERROR, "No previous pattern in the first entry of context '%s' to match '%s'!\n", cxt, v->name); 01437 continue; 01438 } 01439 if ((stringp = tc = ast_strdup(v->value))) { 01440 ast_copy_string(realext, lastextension, sizeof(realext)); 01441 goto process_extension; 01442 } 01443 } else if (!strcasecmp(v->name, "exten")) { 01444 int ipri; 01445 char *plus, *firstp; 01446 char *pri, *appl, *data, *cidmatch; 01447 01448 if (!(stringp = tc = ast_strdup(v->value))) { 01449 continue; 01450 } 01451 01452 ext = S_OR(pbx_strsep(&stringp, ","), ""); 01453 pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1); 01454 ast_copy_string(lastextension, realext, sizeof(lastextension)); 01455 process_extension: 01456 ipri = -2; 01457 if ((cidmatch = strchr(realext, '/'))) { 01458 *cidmatch++ = '\0'; 01459 ast_shrink_phone_number(cidmatch); 01460 } 01461 pri = S_OR(strsep(&stringp, ","), ""); 01462 pri = ast_skip_blanks(pri); 01463 pri = ast_trim_blanks(pri); 01464 if ((label = strchr(pri, '('))) { 01465 *label++ = '\0'; 01466 if ((end = strchr(label, ')'))) { 01467 *end = '\0'; 01468 } else { 01469 ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno); 01470 } 01471 } 01472 if ((plus = strchr(pri, '+'))) { 01473 *plus++ = '\0'; 01474 } 01475 if (!strcmp(pri,"hint")) { 01476 ipri = PRIORITY_HINT; 01477 } else if (!strcmp(pri, "next") || !strcmp(pri, "n")) { 01478 if (lastpri > -2) { 01479 ipri = lastpri + 1; 01480 } else { 01481 ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry!\n"); 01482 } 01483 } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) { 01484 if (lastpri > -2) { 01485 ipri = lastpri; 01486 } else { 01487 ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry!\n"); 01488 } 01489 } else if (sscanf(pri, "%30d", &ipri) != 1 && 01490 (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) { 01491 ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno); 01492 ipri = 0; 01493 } 01494 appl = S_OR(stringp, ""); 01495 /* Find the first occurrence of '(' */ 01496 if (!(firstp = strchr(appl, '('))) { 01497 /* No arguments */ 01498 data = ""; 01499 } else { 01500 char *orig_appl = ast_strdup(appl); 01501 01502 if (!orig_appl) 01503 return -1; 01504 01505 appl = strsep(&stringp, "("); 01506 01507 /* check if there are variables or expressions without an application, like: exten => 100,hint,DAHDI/g0/${GLOBAL(var)} */ 01508 if (strstr(appl, "${") || strstr(appl, "$[")){ 01509 /* set appl to original one */ 01510 strcpy(appl, orig_appl); 01511 /* set no data */ 01512 data = ""; 01513 /* no variable before application found -> go ahead */ 01514 } else { 01515 data = S_OR(stringp, ""); 01516 if ((end = strrchr(data, ')'))) { 01517 *end = '\0'; 01518 } else { 01519 ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s'\n", appl, data); 01520 } 01521 } 01522 ast_free(orig_appl); 01523 } 01524 01525 appl = ast_skip_blanks(appl); 01526 if (ipri) { 01527 if (plus) { 01528 ipri += atoi(plus); 01529 } 01530 lastpri = ipri; 01531 if (!ast_opt_dont_warn && !strcmp(realext, "_.")) { 01532 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); 01533 } 01534 if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free_ptr, registrar)) { 01535 ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno); 01536 } 01537 } 01538 free(tc); 01539 } else if (!strcasecmp(v->name, "include")) { 01540 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01541 if (ast_context_add_include2(con, realvalue, registrar)) { 01542 switch (errno) { 01543 case ENOMEM: 01544 ast_log(LOG_WARNING, "Out of memory for context addition\n"); 01545 break; 01546 01547 case EBUSY: 01548 ast_log(LOG_WARNING, "Failed to lock context(s) list, please try again later\n"); 01549 break; 01550 01551 case EEXIST: 01552 ast_log(LOG_WARNING, "Context '%s' already included in '%s' context\n", 01553 v->value, cxt); 01554 break; 01555 01556 case ENOENT: 01557 case EINVAL: 01558 ast_log(LOG_WARNING, "There is no existence of context '%s'\n", 01559 errno == ENOENT ? v->value : cxt); 01560 break; 01561 01562 default: 01563 ast_log(LOG_WARNING, "Failed to include '%s' in '%s' context\n", 01564 v->value, cxt); 01565 break; 01566 } 01567 } 01568 } else if (!strcasecmp(v->name, "ignorepat")) { 01569 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01570 if (ast_context_add_ignorepat2(con, realvalue, registrar)) { 01571 ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt); 01572 } 01573 } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) { 01574 char *stringp = realvalue; 01575 char *appl, *data; 01576 01577 if (!strcasecmp(v->name, "switch")) { 01578 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01579 } else { 01580 ast_copy_string(realvalue, v->value, sizeof(realvalue)); 01581 } 01582 appl = strsep(&stringp, "/"); 01583 data = S_OR(stringp, ""); 01584 if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar)) { 01585 ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt); 01586 } 01587 } else { 01588 ast_log(LOG_WARNING, "==!!== Unknown directive: %s at line %d -- IGNORING!!!\n", v->name, v->lineno); 01589 } 01590 } 01591 } 01592 ast_config_destroy(cfg); 01593 return 1; 01594 }
| static int pbx_load_module | ( | void | ) | [static] |
Definition at line 1714 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(), pbx_load_config(), pbx_load_users(), pbx_set_autofallthrough(), pbx_set_extenpatternmatchnew(), and pbx_set_overrideswitch().
Referenced by handle_cli_dialplan_reload(), load_module(), and reload().
01715 { 01716 struct ast_context *con; 01717 01718 if (!local_table) 01719 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); 01720 01721 if (!pbx_load_config(config)) 01722 return AST_MODULE_LOAD_DECLINE; 01723 01724 pbx_load_users(); 01725 01726 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar); 01727 local_table = NULL; /* the local table has been moved into the global one. */ 01728 local_contexts = NULL; 01729 01730 for (con = NULL; (con = ast_walk_contexts(con));) 01731 ast_context_verify_includes(con); 01732 01733 pbx_set_overrideswitch(overrideswitch_config); 01734 pbx_set_autofallthrough(autofallthrough_config); 01735 pbx_set_extenpatternmatchnew(extenpatternmatchnew_config); 01736 01737 return AST_MODULE_LOAD_SUCCESS; 01738 }
| static void pbx_load_users | ( | void | ) | [static] |
Definition at line 1608 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, ext, len(), LOG_ERROR, and strdup.
Referenced by pbx_load_module().
01609 { 01610 struct ast_config *cfg; 01611 char *cat, *chan; 01612 const char *dahdichan; 01613 const char *hasexten, *altexts; 01614 char tmp[256]; 01615 char iface[256]; 01616 char dahdicopy[256]; 01617 char *ext, altcopy[256]; 01618 char *c; 01619 int len; 01620 int hasvoicemail; 01621 int start, finish, x; 01622 struct ast_context *con = NULL; 01623 struct ast_flags config_flags = { 0 }; 01624 01625 cfg = ast_config_load("users.conf", config_flags); 01626 if (!cfg) 01627 return; 01628 01629 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 01630 if (!strcasecmp(cat, "general")) 01631 continue; 01632 iface[0] = '\0'; 01633 len = sizeof(iface); 01634 if (ast_true(ast_config_option(cfg, cat, "hassip"))) { 01635 snprintf(tmp, sizeof(tmp), "SIP/%s", cat); 01636 append_interface(iface, sizeof(iface), tmp); 01637 } 01638 if (ast_true(ast_config_option(cfg, cat, "hasiax"))) { 01639 snprintf(tmp, sizeof(tmp), "IAX2/%s", cat); 01640 append_interface(iface, sizeof(iface), tmp); 01641 } 01642 if (ast_true(ast_config_option(cfg, cat, "hash323"))) { 01643 snprintf(tmp, sizeof(tmp), "H323/%s", cat); 01644 append_interface(iface, sizeof(iface), tmp); 01645 } 01646 hasexten = ast_config_option(cfg, cat, "hasexten"); 01647 if (hasexten && !ast_true(hasexten)) 01648 continue; 01649 hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail")); 01650 dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan"); 01651 if (!dahdichan) 01652 dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan"); 01653 if (!ast_strlen_zero(dahdichan)) { 01654 ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy)); 01655 c = dahdicopy; 01656 chan = strsep(&c, ","); 01657 while (chan) { 01658 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) { 01659 /* Range */ 01660 } else if (sscanf(chan, "%30d", &start)) { 01661 /* Just one */ 01662 finish = start; 01663 } else { 01664 start = 0; finish = 0; 01665 } 01666 if (finish < start) { 01667 x = finish; 01668 finish = start; 01669 start = x; 01670 } 01671 for (x = start; x <= finish; x++) { 01672 snprintf(tmp, sizeof(tmp), "DAHDI/%d", x); 01673 append_interface(iface, sizeof(iface), tmp); 01674 } 01675 chan = strsep(&c, ","); 01676 } 01677 } 01678 if (!ast_strlen_zero(iface)) { 01679 /* Only create a context here when it is really needed. Otherwise default empty context 01680 created by pbx_config may conflict with the one explicitly created by pbx_ael */ 01681 if (!con) 01682 con = ast_context_find_or_create(&local_contexts, local_table, userscontext, registrar); 01683 01684 if (!con) { 01685 ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext); 01686 return; 01687 } 01688 01689 /* Add hint */ 01690 ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar); 01691 /* If voicemail, use "stdexten" else use plain old dial */ 01692 if (hasvoicemail) { 01693 snprintf(tmp, sizeof(tmp), "stdexten,%s,${HINT}", cat); 01694 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", strdup(tmp), ast_free_ptr, registrar); 01695 } else { 01696 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", strdup("${HINT}"), ast_free_ptr, registrar); 01697 } 01698 altexts = ast_variable_retrieve(cfg, cat, "alternateexts"); 01699 if (!ast_strlen_zero(altexts)) { 01700 snprintf(tmp, sizeof(tmp), "%s,1", cat); 01701 ast_copy_string(altcopy, altexts, sizeof(altcopy)); 01702 c = altcopy; 01703 ext = strsep(&c, ","); 01704 while (ext) { 01705 ast_add_extension2(con, 0, ext, 1, NULL, NULL, "Goto", strdup(tmp), ast_free_ptr, registrar); 01706 ext = strsep(&c, ","); 01707 } 01708 } 01709 } 01710 } 01711 ast_config_destroy(cfg); 01712 }
| static char* pbx_strsep | ( | char ** | destructible, | |
| const char * | delim | |||
| ) | [static] |
Definition at line 1342 of file pbx_config.c.
Referenced by pbx_load_config().
01343 { 01344 int square = 0; 01345 char *res = *destructible; 01346 for (; destructible && *destructible && **destructible; (*destructible)++) { 01347 if (**destructible == '[' && !strchr(delim, '[')) { 01348 square++; 01349 } else if (**destructible == ']' && !strchr(delim, ']')) { 01350 if (square) { 01351 square--; 01352 } 01353 } else if (**destructible == '\\' && !strchr(delim, '\\')) { 01354 (*destructible)++; 01355 } else if (strchr(delim, **destructible) && !square) { 01356 **destructible = '\0'; 01357 (*destructible)++; 01358 break; 01359 } 01360 } 01361 if (destructible && *destructible && **destructible == '\0') { 01362 *destructible = NULL; 01363 } 01364 return res; 01365 }
| static int reload | ( | void | ) | [static] |
Definition at line 1752 of file pbx_config.c.
References pbx_builtin_clear_globals(), and pbx_load_module().
01753 { 01754 if (clearglobalvars_config) 01755 pbx_builtin_clear_globals(); 01756 return pbx_load_module(); 01757 }
| 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 ARRAY_LEN, ast_cli_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), and ast_free.
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, ARRAY_LEN(cli_pbx_config)); 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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1763 of file pbx_config.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1763 of file pbx_config.c.
int autofallthrough_config = 1 [static] |
Definition at line 47 of file pbx_config.c.
int clearglobalvars_config = 0 [static] |
Definition at line 48 of file pbx_config.c.
struct ast_cli_entry cli_dialplan_save [static] |
AST_CLI_DEFINE(handle_cli_dialplan_save, "Save dialplan")
Definition at line 1319 of file pbx_config.c.
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.
char config[] = "extensions.conf" [static] |
Definition at line 41 of file pbx_config.c.
int extenpatternmatchnew_config = 0 [static] |
Definition at line 49 of file pbx_config.c.
struct ast_context* local_contexts = NULL [static] |
Definition at line 54 of file pbx_config.c.
Referenced by ast_context_find_or_create(), and pbx_load_module().
struct ast_hashtab* local_table = NULL [static] |
Definition at line 55 of file pbx_config.c.
Referenced by pbx_load_module().
char* overrideswitch_config = NULL [static] |
Definition at line 50 of file pbx_config.c.
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] |
Definition at line 52 of file pbx_config.c.
Referenced by handle_cli_dialplan_save().
int static_config = 0 [static] |
Definition at line 45 of file pbx_config.c.
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 43 of file pbx_config.c.
int write_protect_config = 1 [static] |
Definition at line 46 of file pbx_config.c.
1.6.2