#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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 const 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 const char | registrar [] = "pbx_config" |
static ast_mutex_t | save_dialplan_lock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, 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 1773 of file pbx_config.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1773 of file pbx_config.c.
static void append_interface | ( | char * | iface, | |
int | maxlen, | |||
char * | add | |||
) | [static] |
Definition at line 1606 of file pbx_config.c.
References len().
Referenced by pbx_load_users().
01607 { 01608 int len = strlen(iface); 01609 if (strlen(add) + len < maxlen - 2) { 01610 if (strlen(iface)) { 01611 iface[len] = '&'; 01612 strcpy(iface + len + 1, add); 01613 } else 01614 strcpy(iface, add); 01615 } 01616 }
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 1013 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().
01014 { 01015 int which = 0; 01016 01017 if (a->pos == 4) { /* complete 'into' word ... */ 01018 return (a->n == 0) ? strdup("into") : NULL; 01019 } else if (a->pos == 5) { /* complete context */ 01020 struct ast_context *c = NULL; 01021 int len = strlen(a->word); 01022 char *res = NULL; 01023 01024 /* try to lock contexts list ... */ 01025 if (ast_rdlock_contexts()) { 01026 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01027 return NULL; 01028 } 01029 01030 /* walk through all contexts */ 01031 while ( !res && (c = ast_walk_contexts(c)) ) 01032 if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n) 01033 res = strdup(ast_get_context_name(c)); 01034 ast_unlock_contexts(); 01035 return res; 01036 } else if (a->pos == 6) { 01037 return a->n == 0 ? strdup("replace") : NULL; 01038 } 01039 return NULL; 01040 }
static char * complete_dialplan_add_ignorepat | ( | struct ast_cli_args * | ) | [static] |
Definition at line 1099 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, skip_words(), strdup, strsep(), and ast_cli_args::word.
Referenced by handle_cli_dialplan_add_ignorepat().
01100 { 01101 if (a->pos == 4) 01102 return a->n == 0 ? strdup("into") : NULL; 01103 else if (a->pos == 5) { 01104 struct ast_context *c; 01105 int which = 0; 01106 char *dupline, *ignorepat = NULL; 01107 const char *s; 01108 char *ret = NULL; 01109 int len = strlen(a->word); 01110 01111 /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */ 01112 s = skip_words(a->line, 3); 01113 if (s == NULL) 01114 return NULL; 01115 dupline = strdup(s); 01116 if (!dupline) { 01117 ast_log(LOG_ERROR, "Malloc failure\n"); 01118 return NULL; 01119 } 01120 ignorepat = strsep(&dupline, " "); 01121 01122 if (ast_rdlock_contexts()) { 01123 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 01124 return NULL; 01125 } 01126 01127 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01128 int found = 0; 01129 01130 if (!partial_match(ast_get_context_name(c), a->word, len)) 01131 continue; /* not mine */ 01132 if (ignorepat) /* there must be one, right ? */ 01133 found = lookup_c_ip(c, ignorepat); 01134 if (!found && ++which > a->n) 01135 ret = strdup(ast_get_context_name(c)); 01136 } 01137 01138 free(ignorepat); 01139 ast_unlock_contexts(); 01140 return ret; 01141 } 01142 01143 return NULL; 01144 }
static char * complete_dialplan_add_include | ( | struct ast_cli_args * | ) | [static] |
Definition at line 574 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, skip_words(), strdup, strsep(), and ast_cli_args::word.
Referenced by handle_cli_dialplan_add_include().
00575 { 00576 struct ast_context *c; 00577 int which = 0; 00578 char *ret = NULL; 00579 int len = strlen(a->word); 00580 00581 if (a->pos == 3) { /* 'dialplan add include _X_' (context) ... */ 00582 if (ast_rdlock_contexts()) { 00583 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00584 return NULL; 00585 } 00586 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) 00587 if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n) 00588 ret = strdup(ast_get_context_name(c)); 00589 ast_unlock_contexts(); 00590 return ret; 00591 } else if (a->pos == 4) { /* dialplan add include CTX _X_ */ 00592 /* complete as 'into' if context exists or we are unable to check */ 00593 char *context, *dupline; 00594 const char *s = skip_words(a->line, 3); /* should not fail */ 00595 00596 if (a->n != 0) /* only once */ 00597 return NULL; 00598 00599 /* parse context from line ... */ 00600 context = dupline = strdup(s); 00601 if (!context) { 00602 ast_log(LOG_ERROR, "Out of free memory\n"); 00603 return strdup("into"); 00604 } 00605 strsep(&dupline, " "); 00606 00607 /* check for context existence ... */ 00608 if (ast_rdlock_contexts()) { 00609 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00610 /* our fault, we can't check, so complete 'into' ... */ 00611 ret = strdup("into"); 00612 } else { 00613 struct ast_context *ctx; 00614 for (ctx = NULL; !ret && (ctx = ast_walk_contexts(ctx)); ) 00615 if (!strcmp(context, ast_get_context_name(ctx))) 00616 ret = strdup("into"); /* found */ 00617 ast_unlock_contexts(); 00618 } 00619 free(context); 00620 return ret; 00621 } else if (a->pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */ 00622 char *context, *dupline, *into; 00623 const char *s = skip_words(a->line, 3); /* should not fail */ 00624 context = dupline = strdup(s); 00625 if (!dupline) { 00626 ast_log(LOG_ERROR, "Out of free memory\n"); 00627 return NULL; 00628 } 00629 strsep(&dupline, " "); /* skip context */ 00630 into = strsep(&dupline, " "); 00631 /* error if missing context or fifth word is not 'into' */ 00632 if (!strlen(context) || strcmp(into, "into")) { 00633 ast_log(LOG_ERROR, "bad context %s or missing into %s\n", 00634 context, into); 00635 goto error3; 00636 } 00637 00638 if (ast_rdlock_contexts()) { 00639 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00640 goto error3; 00641 } 00642 00643 for (c = NULL; (c = ast_walk_contexts(c)); ) 00644 if (!strcmp(context, ast_get_context_name(c))) 00645 break; 00646 if (c) { /* first context exists, go on... */ 00647 /* go through all contexts ... */ 00648 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 00649 if (!strcmp(context, ast_get_context_name(c))) 00650 continue; /* skip ourselves */ 00651 if (partial_match(ast_get_context_name(c), a->word, len) && 00652 !lookup_ci(c, context) /* not included yet */ && 00653 ++which > a->n) 00654 ret = strdup(ast_get_context_name(c)); 00655 } 00656 } else { 00657 ast_log(LOG_ERROR, "context %s not found\n", context); 00658 } 00659 ast_unlock_contexts(); 00660 error3: 00661 free(context); 00662 return ret; 00663 } 00664 00665 return NULL; 00666 }
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, 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, 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 len = strlen(a->word); 00471 if (le == 0 || lc == 0) 00472 goto error3; 00473 00474 if (ast_rdlock_contexts()) { 00475 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00476 goto error3; 00477 } 00478 00479 /* walk contexts */ 00480 c = NULL; 00481 while ( (c = ast_walk_contexts(c)) ) { 00482 /* XXX locking on c ? */ 00483 struct ast_exten *e; 00484 if (strcmp(ast_get_context_name(c), context) != 0) 00485 continue; 00486 /* got it, we must match here */ 00487 e = NULL; 00488 while ( (e = ast_walk_context_extensions(c, e)) ) { 00489 struct ast_exten *priority; 00490 char buffer[10]; 00491 00492 if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) { 00493 continue; 00494 } 00495 if (strcmp(ast_get_extension_name(e), exten) != 0) 00496 continue; 00497 /* XXX lock e ? */ 00498 priority = NULL; 00499 while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) { 00500 snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority)); 00501 if (partial_match(buffer, a->word, len) && ++which > a->n) /* n-th match */ 00502 ret = strdup(buffer); 00503 } 00504 break; 00505 } 00506 break; 00507 } 00508 ast_unlock_contexts(); 00509 error3: 00510 free(exten); 00511 } 00512 return ret; 00513 }
static char * complete_dialplan_remove_ignorepat | ( | struct ast_cli_args * | ) | [static] |
Definition at line 1195 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().
01196 { 01197 struct ast_context *c; 01198 int which = 0; 01199 char *ret = NULL; 01200 01201 if (a->pos == 3) { 01202 int len = strlen(a->word); 01203 if (ast_rdlock_contexts()) { 01204 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01205 return NULL; 01206 } 01207 01208 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01209 struct ast_ignorepat *ip; 01210 01211 if (ast_rdlock_context(c)) /* error, skip it */ 01212 continue; 01213 01214 for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) { 01215 if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) { 01216 /* n-th match */ 01217 struct ast_context *cw = NULL; 01218 int found = 0; 01219 while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) { 01220 /* XXX do i stop on c, or skip it ? */ 01221 found = lookup_c_ip(cw, ast_get_ignorepat_name(ip)); 01222 } 01223 if (!found) 01224 ret = strdup(ast_get_ignorepat_name(ip)); 01225 } 01226 } 01227 ast_unlock_context(c); 01228 } 01229 ast_unlock_contexts(); 01230 return ret; 01231 } else if (a->pos == 4) { 01232 return a->n == 0 ? strdup("from") : NULL; 01233 } else if (a->pos == 5) { /* XXX check this */ 01234 char *dupline, *duplinet, *ignorepat; 01235 int len = strlen(a->word); 01236 01237 dupline = strdup(a->line); 01238 if (!dupline) { 01239 ast_log(LOG_WARNING, "Out of free memory\n"); 01240 return NULL; 01241 } 01242 01243 duplinet = dupline; 01244 strsep(&duplinet, " "); 01245 strsep(&duplinet, " "); 01246 ignorepat = strsep(&duplinet, " "); 01247 01248 if (!ignorepat) { 01249 free(dupline); 01250 return NULL; 01251 } 01252 01253 if (ast_rdlock_contexts()) { 01254 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01255 free(dupline); 01256 return NULL; 01257 } 01258 01259 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 01260 if (ast_rdlock_context(c)) /* fail, skip it */ 01261 continue; 01262 if (!partial_match(ast_get_context_name(c), a->word, len)) 01263 continue; 01264 if (lookup_c_ip(c, ignorepat) && ++which > a->n) 01265 ret = strdup(ast_get_context_name(c)); 01266 ast_unlock_context(c); 01267 } 01268 ast_unlock_contexts(); 01269 free(dupline); 01270 return NULL; 01271 } 01272 01273 return NULL; 01274 }
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, 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 901 of file pbx_config.c.
References app, ast_cli_args::argc, ast_cli_args::argv, ast_add_extension(), ast_cli(), ast_free_ptr, ast_strdupa, 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.
00902 { 00903 char *whole_exten; 00904 char *exten, *prior; 00905 int iprior = -2; 00906 char *cidmatch, *app, *app_data; 00907 char *start, *end; 00908 00909 switch (cmd) { 00910 case CLI_INIT: 00911 e->command = "dialplan add extension"; 00912 e->usage = 00913 "Usage: dialplan add extension <exten>,<priority>,<app>,<app-data>\n" 00914 " into <context> [replace]\n\n" 00915 " This command will add new extension into <context>. If there is an\n" 00916 " existence of extension with the same priority and last 'replace'\n" 00917 " arguments is given here we simply replace this extension.\n" 00918 "\n" 00919 "Example: dialplan add extension 6123,1,Dial,IAX/216.207.245.56/6123 into local\n" 00920 " Now, you can dial 6123 and talk to Markster :)\n"; 00921 return NULL; 00922 case CLI_GENERATE: 00923 return complete_dialplan_add_extension(a); 00924 } 00925 00926 /* check for arguments at first */ 00927 if (a->argc != 6 && a->argc != 7) 00928 return CLI_SHOWUSAGE; 00929 if (strcmp(a->argv[4], "into")) 00930 return CLI_SHOWUSAGE; 00931 if (a->argc == 7) 00932 if (strcmp(a->argv[6], "replace")) 00933 return CLI_SHOWUSAGE; 00934 00935 whole_exten = ast_strdupa(a->argv[3]); 00936 exten = strsep(&whole_exten,","); 00937 if (strchr(exten, '/')) { 00938 cidmatch = exten; 00939 strsep(&cidmatch,"/"); 00940 } else { 00941 cidmatch = NULL; 00942 } 00943 prior = strsep(&whole_exten,","); 00944 if (prior) { 00945 if (!strcmp(prior, "hint")) { 00946 iprior = PRIORITY_HINT; 00947 } else { 00948 if (sscanf(prior, "%30d", &iprior) != 1) { 00949 ast_cli(a->fd, "'%s' is not a valid priority\n", prior); 00950 prior = NULL; 00951 } 00952 } 00953 } 00954 app = whole_exten; 00955 if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) { 00956 *start = *end = '\0'; 00957 app_data = start + 1; 00958 } else { 00959 if (app) { 00960 app_data = strchr(app, ','); 00961 if (app_data) { 00962 *app_data = '\0'; 00963 app_data++; 00964 } 00965 } else 00966 app_data = NULL; 00967 } 00968 00969 if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT)) 00970 return CLI_SHOWUSAGE; 00971 00972 if (!app_data) 00973 app_data=""; 00974 if (ast_add_extension(a->argv[5], a->argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app, 00975 (void *)strdup(app_data), ast_free_ptr, registrar)) { 00976 switch (errno) { 00977 case ENOMEM: 00978 ast_cli(a->fd, "Out of free memory\n"); 00979 break; 00980 00981 case EBUSY: 00982 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 00983 break; 00984 00985 case ENOENT: 00986 ast_cli(a->fd, "No existence of '%s' context\n", a->argv[5]); 00987 break; 00988 00989 case EEXIST: 00990 ast_cli(a->fd, "Extension %s@%s with priority %s already exists\n", 00991 exten, a->argv[5], prior); 00992 break; 00993 00994 default: 00995 ast_cli(a->fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n", 00996 exten, prior, app, app_data, a->argv[5]); 00997 break; 00998 } 00999 return CLI_FAILURE; 01000 } 01001 01002 if (a->argc == 7) 01003 ast_cli(a->fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n", 01004 exten, a->argv[5], prior, exten, prior, app, app_data); 01005 else 01006 ast_cli(a->fd, "Extension '%s,%s,%s,%s' added into '%s' context\n", 01007 exten, prior, app, app_data, a->argv[5]); 01008 01009 return CLI_SUCCESS; 01010 }
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 1045 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.
01046 { 01047 switch (cmd) { 01048 case CLI_INIT: 01049 e->command = "dialplan add ignorepat"; 01050 e->usage = 01051 "Usage: dialplan add ignorepat <pattern> into <context>\n" 01052 " This command adds a new ignore pattern into context <context>\n" 01053 "\n" 01054 "Example: dialplan add ignorepat _3XX into local\n"; 01055 return NULL; 01056 case CLI_GENERATE: 01057 return complete_dialplan_add_ignorepat(a); 01058 } 01059 01060 if (a->argc != 6) 01061 return CLI_SHOWUSAGE; 01062 01063 if (strcmp(a->argv[4], "into")) 01064 return CLI_SHOWUSAGE; 01065 01066 if (ast_context_add_ignorepat(a->argv[5], a->argv[3], registrar)) { 01067 switch (errno) { 01068 case ENOMEM: 01069 ast_cli(a->fd, "Out of free memory\n"); 01070 break; 01071 01072 case ENOENT: 01073 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01074 break; 01075 01076 case EEXIST: 01077 ast_cli(a->fd, "Ignore pattern '%s' already included in '%s' context\n", 01078 a->argv[3], a->argv[5]); 01079 break; 01080 01081 case EBUSY: 01082 ast_cli(a->fd, "Failed to lock context(s) list, please, try again later\n"); 01083 break; 01084 01085 default: 01086 ast_cli(a->fd, "Failed to add ingore pattern '%s' into '%s' context\n", 01087 a->argv[3], a->argv[5]); 01088 break; 01089 } 01090 return CLI_FAILURE; 01091 } 01092 01093 ast_cli(a->fd, "Ignore pattern '%s' added into '%s' context\n", 01094 a->argv[3], a->argv[5]); 01095 01096 return CLI_SUCCESS; 01097 }
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 518 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.
00519 { 00520 switch (cmd) { 00521 case CLI_INIT: 00522 e->command = "dialplan add include"; 00523 e->usage = 00524 "Usage: dialplan add include <context> into <context>\n" 00525 " Include a context in another context.\n"; 00526 return NULL; 00527 case CLI_GENERATE: 00528 return complete_dialplan_add_include(a); 00529 } 00530 00531 if (a->argc != 6) /* dialplan add include CTX in CTX */ 00532 return CLI_SHOWUSAGE; 00533 00534 /* fifth arg must be 'into' ... */ 00535 if (strcmp(a->argv[4], "into")) 00536 return CLI_SHOWUSAGE; 00537 00538 if (ast_context_add_include(a->argv[5], a->argv[3], registrar)) { 00539 switch (errno) { 00540 case ENOMEM: 00541 ast_cli(a->fd, "Out of memory for context addition\n"); 00542 break; 00543 00544 case EBUSY: 00545 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 00546 break; 00547 00548 case EEXIST: 00549 ast_cli(a->fd, "Context '%s' already included in '%s' context\n", 00550 a->argv[3], a->argv[5]); 00551 break; 00552 00553 case ENOENT: 00554 case EINVAL: 00555 ast_cli(a->fd, "There is no existence of context '%s'\n", 00556 errno == ENOENT ? a->argv[5] : a->argv[3]); 00557 break; 00558 00559 default: 00560 ast_cli(a->fd, "Failed to include '%s' in '%s' context\n", 00561 a->argv[3], a->argv[5]); 00562 break; 00563 } 00564 return CLI_FAILURE; 00565 } 00566 00567 /* show some info ... */ 00568 ast_cli(a->fd, "Context '%s' included in '%s' context\n", 00569 a->argv[3], a->argv[5]); 00570 00571 return CLI_SUCCESS; 00572 }
static char* handle_cli_dialplan_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1278 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.
01279 { 01280 switch (cmd) { 01281 case CLI_INIT: 01282 e->command = "dialplan reload"; 01283 e->usage = 01284 "Usage: dialplan reload\n" 01285 " Reload extensions.conf without reloading any other\n" 01286 " modules. This command does not delete global variables\n" 01287 " unless clearglobalvars is set to yes in extensions.conf\n"; 01288 return NULL; 01289 case CLI_GENERATE: 01290 return NULL; 01291 } 01292 01293 if (a->argc != 2) 01294 return CLI_SHOWUSAGE; 01295 01296 if (clearglobalvars_config) 01297 pbx_builtin_clear_globals(); 01298 01299 pbx_load_module(); 01300 ast_cli(a->fd, "Dialplan reloaded.\n"); 01301 return CLI_SUCCESS; 01302 }
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 const 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 1146 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.
01147 { 01148 switch (cmd) { 01149 case CLI_INIT: 01150 e->command = "dialplan remove ignorepat"; 01151 e->usage = 01152 "Usage: dialplan remove ignorepat <pattern> from <context>\n" 01153 " This command removes an ignore pattern from context <context>\n" 01154 "\n" 01155 "Example: dialplan remove ignorepat _3XX from local\n"; 01156 return NULL; 01157 case CLI_GENERATE: 01158 return complete_dialplan_remove_ignorepat(a); 01159 } 01160 01161 if (a->argc != 6) 01162 return CLI_SHOWUSAGE; 01163 01164 if (strcmp(a->argv[4], "from")) 01165 return CLI_SHOWUSAGE; 01166 01167 if (ast_context_remove_ignorepat(a->argv[5], a->argv[3], registrar)) { 01168 switch (errno) { 01169 case EBUSY: 01170 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 01171 break; 01172 01173 case ENOENT: 01174 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01175 break; 01176 01177 case EINVAL: 01178 ast_cli(a->fd, "There is no existence of '%s' ignore pattern in '%s' context\n", 01179 a->argv[3], a->argv[5]); 01180 break; 01181 01182 default: 01183 ast_cli(a->fd, "Failed to remove ignore pattern '%s' from '%s' context\n", 01184 a->argv[3], a->argv[5]); 01185 break; 01186 } 01187 return CLI_FAILURE; 01188 } 01189 01190 ast_cli(a->fd, "Ignore pattern '%s' removed from '%s' context\n", 01191 a->argv[3], a->argv[5]); 01192 return CLI_SUCCESS; 01193 }
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 671 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.
00672 { 00673 char filename[256], overrideswitch[256] = ""; 00674 struct ast_context *c; 00675 struct ast_config *cfg; 00676 struct ast_variable *v; 00677 int incomplete = 0; /* incomplete config write? */ 00678 FILE *output; 00679 struct ast_flags config_flags = { 0 }; 00680 const char *base, *slash, *file; 00681 00682 switch (cmd) { 00683 case CLI_INIT: 00684 e->command = "dialplan save"; 00685 e->usage = 00686 "Usage: dialplan save [/path/to/extension/file]\n" 00687 " Save dialplan created by pbx_config module.\n" 00688 "\n" 00689 "Example: dialplan save (/etc/asterisk/extensions.conf)\n" 00690 " dialplan save /home/markster (/home/markster/extensions.conf)\n"; 00691 return NULL; 00692 case CLI_GENERATE: 00693 return NULL; 00694 } 00695 00696 if (! (static_config && !write_protect_config)) { 00697 ast_cli(a->fd, 00698 "I can't save dialplan now, see '%s' example file.\n", 00699 config); 00700 return CLI_FAILURE; 00701 } 00702 00703 if (a->argc != 2 && a->argc != 3) 00704 return CLI_SHOWUSAGE; 00705 00706 if (ast_mutex_lock(&save_dialplan_lock)) { 00707 ast_cli(a->fd, 00708 "Failed to lock dialplan saving (another proccess saving?)\n"); 00709 return CLI_FAILURE; 00710 } 00711 /* XXX the code here is quite loose, a pathname with .conf in it 00712 * is assumed to be a complete pathname 00713 */ 00714 if (a->argc == 3) { /* have config path. Look for *.conf */ 00715 base = a->argv[2]; 00716 if (!strstr(a->argv[2], ".conf")) { /*no, this is assumed to be a pathname */ 00717 /* if filename ends with '/', do not add one */ 00718 slash = (*(a->argv[2] + strlen(a->argv[2]) -1) == '/') ? "/" : ""; 00719 file = config; /* default: 'extensions.conf' */ 00720 } else { /* yes, complete file name */ 00721 slash = ""; 00722 file = ""; 00723 } 00724 } else { 00725 /* no config file, default one */ 00726 base = ast_config_AST_CONFIG_DIR; 00727 slash = "/"; 00728 file = config; 00729 } 00730 snprintf(filename, sizeof(filename), "%s%s%s", base, slash, config); 00731 00732 cfg = ast_config_load("extensions.conf", config_flags); 00733 00734 /* try to lock contexts list */ 00735 if (ast_rdlock_contexts()) { 00736 ast_cli(a->fd, "Failed to lock contexts list\n"); 00737 ast_mutex_unlock(&save_dialplan_lock); 00738 ast_config_destroy(cfg); 00739 return CLI_FAILURE; 00740 } 00741 00742 /* create new file ... */ 00743 if (!(output = fopen(filename, "wt"))) { 00744 ast_cli(a->fd, "Failed to create file '%s'\n", 00745 filename); 00746 ast_unlock_contexts(); 00747 ast_mutex_unlock(&save_dialplan_lock); 00748 ast_config_destroy(cfg); 00749 return CLI_FAILURE; 00750 } 00751 00752 /* fireout general info */ 00753 if (overrideswitch_config) { 00754 snprintf(overrideswitch, sizeof(overrideswitch), "overrideswitch=%s\n", overrideswitch_config); 00755 } 00756 fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\n%sextenpatternmatchnew=%s\n\n", 00757 static_config ? "yes" : "no", 00758 write_protect_config ? "yes" : "no", 00759 autofallthrough_config ? "yes" : "no", 00760 clearglobalvars_config ? "yes" : "no", 00761 overrideswitch_config ? overrideswitch : "", 00762 extenpatternmatchnew_config ? "yes" : "no"); 00763 00764 if ((v = ast_variable_browse(cfg, "globals"))) { 00765 fprintf(output, "[globals]\n"); 00766 while(v) { 00767 fprintf(output, "%s => %s\n", v->name, v->value); 00768 v = v->next; 00769 } 00770 fprintf(output, "\n"); 00771 } 00772 00773 ast_config_destroy(cfg); 00774 00775 #define PUT_CTX_HDR do { \ 00776 if (!context_header_written) { \ 00777 fprintf(output, "[%s]\n", ast_get_context_name(c)); \ 00778 context_header_written = 1; \ 00779 } \ 00780 } while (0) 00781 00782 /* walk all contexts */ 00783 for (c = NULL; (c = ast_walk_contexts(c)); ) { 00784 int context_header_written = 0; 00785 struct ast_exten *ext, *last_written_e = NULL; 00786 struct ast_include *i; 00787 struct ast_ignorepat *ip; 00788 struct ast_sw *sw; 00789 00790 /* try to lock context and fireout all info */ 00791 if (ast_rdlock_context(c)) { /* lock failure */ 00792 incomplete = 1; 00793 continue; 00794 } 00795 /* registered by this module? */ 00796 /* XXX do we need this ? */ 00797 if (!strcmp(ast_get_context_registrar(c), registrar)) { 00798 fprintf(output, "[%s]\n", ast_get_context_name(c)); 00799 context_header_written = 1; 00800 } 00801 00802 /* walk extensions ... */ 00803 for (ext = NULL; (ext = ast_walk_context_extensions(c, ext)); ) { 00804 struct ast_exten *p = NULL; 00805 00806 /* fireout priorities */ 00807 while ( (p = ast_walk_extension_priorities(ext, p)) ) { 00808 if (strcmp(ast_get_extension_registrar(p), registrar) != 0) /* not this source */ 00809 continue; 00810 00811 /* make empty line between different extensions */ 00812 if (last_written_e != NULL && 00813 strcmp(ast_get_extension_name(last_written_e), 00814 ast_get_extension_name(p))) 00815 fprintf(output, "\n"); 00816 last_written_e = p; 00817 00818 PUT_CTX_HDR; 00819 00820 if (ast_get_extension_priority(p) == PRIORITY_HINT) { /* easy */ 00821 fprintf(output, "exten => %s,hint,%s\n", 00822 ast_get_extension_name(p), 00823 ast_get_extension_app(p)); 00824 } else { 00825 const char *sep, *cid; 00826 const char *el = ast_get_extension_label(p); 00827 char label[128] = ""; 00828 00829 if (ast_get_extension_matchcid(p)) { 00830 sep = "/"; 00831 cid = ast_get_extension_cidmatch(p); 00832 } else 00833 sep = cid = ""; 00834 00835 if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2))) 00836 incomplete = 1; /* error encountered or label > 125 chars */ 00837 00838 fprintf(output, "exten => %s%s%s,%d%s,%s(%s)\n", 00839 ast_get_extension_name(p), (ast_strlen_zero(sep) ? "" : sep), (ast_strlen_zero(cid) ? "" : cid), 00840 ast_get_extension_priority(p), label, 00841 ast_get_extension_app(p), (ast_strlen_zero(ast_get_extension_app_data(p)) ? "" : (const char *)ast_get_extension_app_data(p))); 00842 } 00843 } 00844 } 00845 00846 /* written any extensions? ok, write space between exten & inc */ 00847 if (last_written_e) 00848 fprintf(output, "\n"); 00849 00850 /* walk through includes */ 00851 for (i = NULL; (i = ast_walk_context_includes(c, i)) ; ) { 00852 if (strcmp(ast_get_include_registrar(i), registrar) != 0) 00853 continue; /* not mine */ 00854 PUT_CTX_HDR; 00855 fprintf(output, "include => %s\n", ast_get_include_name(i)); 00856 } 00857 if (ast_walk_context_includes(c, NULL)) 00858 fprintf(output, "\n"); 00859 00860 /* walk through switches */ 00861 for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) { 00862 if (strcmp(ast_get_switch_registrar(sw), registrar) != 0) 00863 continue; /* not mine */ 00864 PUT_CTX_HDR; 00865 fprintf(output, "switch => %s/%s\n", 00866 ast_get_switch_name(sw), ast_get_switch_data(sw)); 00867 } 00868 00869 if (ast_walk_context_switches(c, NULL)) 00870 fprintf(output, "\n"); 00871 00872 /* fireout ignorepats ... */ 00873 for (ip = NULL; (ip = ast_walk_context_ignorepats(c, ip)); ) { 00874 if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0) 00875 continue; /* not mine */ 00876 PUT_CTX_HDR; 00877 fprintf(output, "ignorepat => %s\n", 00878 ast_get_ignorepat_name(ip)); 00879 } 00880 00881 ast_unlock_context(c); 00882 } 00883 00884 ast_unlock_contexts(); 00885 ast_mutex_unlock(&save_dialplan_lock); 00886 fclose(output); 00887 00888 if (incomplete) { 00889 ast_cli(a->fd, "Saved dialplan is incomplete\n"); 00890 return CLI_FAILURE; 00891 } 00892 00893 ast_cli(a->fd, "Dialplan successfully saved into '%s'\n", 00894 filename); 00895 return CLI_SUCCESS; 00896 }
static int load_module | ( | void | ) | [static] |
Definition at line 1750 of file pbx_config.c.
References ARRAY_LEN, ast_cli_register(), ast_cli_register_multiple(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, cli_dialplan_save, cli_pbx_config, and pbx_load_module().
01751 { 01752 if (static_config && !write_protect_config) 01753 ast_cli_register(&cli_dialplan_save); 01754 ast_cli_register_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config)); 01755 01756 if (pbx_load_module()) 01757 return AST_MODULE_LOAD_DECLINE; 01758 01759 return AST_MODULE_LOAD_SUCCESS; 01760 }
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 1365 of file pbx_config.c.
References ast_category_browse(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), config_flags, CONFIG_STATUS_FILEINVALID, ext, ast_variable::lineno, local_contexts, local_table, LOG_ERROR, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), and ast_variable::value.
Referenced by pbx_load_module().
01366 { 01367 struct ast_config *cfg; 01368 char *end; 01369 char *label; 01370 #ifdef LOW_MEMORY 01371 char realvalue[256]; 01372 #else 01373 char realvalue[8192]; 01374 #endif 01375 int lastpri = -2; 01376 struct ast_context *con; 01377 struct ast_variable *v; 01378 const char *cxt; 01379 const char *aft; 01380 const char *newpm, *ovsw; 01381 struct ast_flags config_flags = { 0 }; 01382 char lastextension[256]; 01383 cfg = ast_config_load(config_file, config_flags); 01384 if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) 01385 return 0; 01386 01387 /* Use existing config to populate the PBX table */ 01388 static_config = ast_true(ast_variable_retrieve(cfg, "general", "static")); 01389 write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect")); 01390 if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough"))) 01391 autofallthrough_config = ast_true(aft); 01392 if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew"))) 01393 extenpatternmatchnew_config = ast_true(newpm); 01394 clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars")); 01395 if ((ovsw = ast_variable_retrieve(cfg, "general", "overrideswitch"))) { 01396 if (overrideswitch_config) { 01397 ast_free(overrideswitch_config); 01398 } 01399 if (!ast_strlen_zero(ovsw)) { 01400 overrideswitch_config = ast_strdup(ovsw); 01401 } else { 01402 overrideswitch_config = NULL; 01403 } 01404 } 01405 01406 ast_copy_string(userscontext, ast_variable_retrieve(cfg, "general", "userscontext") ?: "default", sizeof(userscontext)); 01407 01408 for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) { 01409 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01410 pbx_builtin_setvar_helper(NULL, v->name, realvalue); 01411 } 01412 for (cxt = ast_category_browse(cfg, NULL); 01413 cxt; 01414 cxt = ast_category_browse(cfg, cxt)) { 01415 /* All categories but "general" or "globals" are considered contexts */ 01416 if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) { 01417 continue; 01418 } 01419 if (!(con = ast_context_find_or_create(&local_contexts, local_table, cxt, registrar))) { 01420 continue; 01421 } 01422 01423 /* Reset continuation items at the beginning of each context */ 01424 lastextension[0] = '\0'; 01425 lastpri = -2; 01426 01427 for (v = ast_variable_browse(cfg, cxt); v; v = v->next) { 01428 char *tc = NULL; 01429 char realext[256] = ""; 01430 char *stringp, *ext; 01431 01432 if (!strncasecmp(v->name, "same", 4)) { 01433 if (ast_strlen_zero(lastextension)) { 01434 ast_log(LOG_ERROR, "No previous pattern in the first entry of context '%s' to match '%s' at line %d!\n", cxt, v->name, v->lineno); 01435 continue; 01436 } 01437 if ((stringp = tc = ast_strdup(v->value))) { 01438 ast_copy_string(realext, lastextension, sizeof(realext)); 01439 goto process_extension; 01440 } 01441 } else if (!strcasecmp(v->name, "exten")) { 01442 int ipri; 01443 char *plus, *firstp; 01444 char *pri, *appl, *data, *cidmatch; 01445 01446 if (!(stringp = tc = ast_strdup(v->value))) { 01447 continue; 01448 } 01449 01450 ext = S_OR(pbx_strsep(&stringp, ","), ""); 01451 pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1); 01452 ast_copy_string(lastextension, realext, sizeof(lastextension)); 01453 process_extension: 01454 ipri = -2; 01455 if ((cidmatch = strchr(realext, '/'))) { 01456 *cidmatch++ = '\0'; 01457 ast_shrink_phone_number(cidmatch); 01458 } 01459 pri = ast_strip(S_OR(strsep(&stringp, ","), "")); 01460 if ((label = strchr(pri, '('))) { 01461 *label++ = '\0'; 01462 if ((end = strchr(label, ')'))) { 01463 *end = '\0'; 01464 } else { 01465 ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno); 01466 ast_free(tc); 01467 continue; 01468 } 01469 } 01470 if ((plus = strchr(pri, '+'))) { 01471 *plus++ = '\0'; 01472 } 01473 if (!strcmp(pri,"hint")) { 01474 ipri = PRIORITY_HINT; 01475 } else if (!strcmp(pri, "next") || !strcmp(pri, "n")) { 01476 if (lastpri > -2) { 01477 ipri = lastpri + 1; 01478 } else { 01479 ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry at line %d!\n", v->lineno); 01480 ast_free(tc); 01481 continue; 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 at line %d!\n", v->lineno); 01488 ast_free(tc); 01489 continue; 01490 } 01491 } else if (sscanf(pri, "%30d", &ipri) != 1 && 01492 (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) { 01493 ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno); 01494 ipri = 0; 01495 ast_free(tc); 01496 continue; 01497 } else if (ipri < 1) { 01498 ast_log(LOG_WARNING, "Invalid priority '%s' at line %d\n", pri, v->lineno); 01499 ast_free(tc); 01500 continue; 01501 } 01502 appl = S_OR(stringp, ""); 01503 /* Find the first occurrence of '(' */ 01504 if (!(firstp = strchr(appl, '('))) { 01505 /* No arguments */ 01506 data = ""; 01507 } else { 01508 char *orig_appl = ast_strdup(appl); 01509 01510 if (!orig_appl) { 01511 ast_free(tc); 01512 continue; 01513 } 01514 01515 appl = strsep(&stringp, "("); 01516 01517 /* check if there are variables or expressions without an application, like: exten => 100,hint,DAHDI/g0/${GLOBAL(var)} */ 01518 if (strstr(appl, "${") || strstr(appl, "$[")){ 01519 /* set appl to original one */ 01520 strcpy(appl, orig_appl); 01521 /* set no data */ 01522 data = ""; 01523 /* no variable before application found -> go ahead */ 01524 } else { 01525 data = S_OR(stringp, ""); 01526 if ((end = strrchr(data, ')'))) { 01527 *end = '\0'; 01528 } else { 01529 ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s' at line %d\n", appl, data, v->lineno); 01530 } 01531 } 01532 ast_free(orig_appl); 01533 } 01534 01535 appl = ast_skip_blanks(appl); 01536 if (ipri) { 01537 if (plus) { 01538 ipri += atoi(plus); 01539 } 01540 lastpri = ipri; 01541 if (!ast_opt_dont_warn && (!strcmp(realext, "_.") || !strcmp(realext, "_!"))) { 01542 ast_log(LOG_WARNING, "The use of '%s' for an extension is strongly discouraged and can have unexpected behavior. Please use '_X%c' instead at line %d\n", realext, realext[1], v->lineno); 01543 } 01544 if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free_ptr, registrar)) { 01545 ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno); 01546 } 01547 } 01548 free(tc); 01549 } else if (!strcasecmp(v->name, "include")) { 01550 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01551 if (ast_context_add_include2(con, realvalue, registrar)) { 01552 switch (errno) { 01553 case ENOMEM: 01554 ast_log(LOG_WARNING, "Out of memory for context addition\n"); 01555 break; 01556 01557 case EBUSY: 01558 ast_log(LOG_WARNING, "Failed to lock context(s) list, please try again later\n"); 01559 break; 01560 01561 case EEXIST: 01562 ast_log(LOG_WARNING, "Context '%s' already included in '%s' context on include at line %d\n", 01563 v->value, cxt, v->lineno); 01564 break; 01565 01566 case ENOENT: 01567 case EINVAL: 01568 ast_log(LOG_WARNING, "There is no existence of context '%s' included at line %d\n", 01569 errno == ENOENT ? v->value : cxt, v->lineno); 01570 break; 01571 01572 default: 01573 ast_log(LOG_WARNING, "Failed to include '%s' in '%s' context at line %d\n", 01574 v->value, cxt, v->lineno); 01575 break; 01576 } 01577 } 01578 } else if (!strcasecmp(v->name, "ignorepat")) { 01579 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01580 if (ast_context_add_ignorepat2(con, realvalue, registrar)) { 01581 ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s' at line %d\n", v->value, cxt, v->lineno); 01582 } 01583 } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) { 01584 char *stringp = realvalue; 01585 char *appl, *data; 01586 01587 if (!strcasecmp(v->name, "switch")) { 01588 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01589 } else { 01590 ast_copy_string(realvalue, v->value, sizeof(realvalue)); 01591 } 01592 appl = strsep(&stringp, "/"); 01593 data = S_OR(stringp, ""); 01594 if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar)) { 01595 ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s' at line %d\n", v->value, cxt, v->lineno); 01596 } 01597 } else { 01598 ast_log(LOG_WARNING, "==!!== Unknown directive: %s at line %d -- IGNORING!!!\n", v->name, v->lineno); 01599 } 01600 } 01601 } 01602 ast_config_destroy(cfg); 01603 return 1; 01604 }
static int pbx_load_module | ( | void | ) | [static] |
Definition at line 1724 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(), local_contexts, local_table, pbx_load_config(), pbx_load_users(), pbx_set_autofallthrough(), pbx_set_extenpatternmatchnew(), and pbx_set_overrideswitch().
01725 { 01726 struct ast_context *con; 01727 01728 if (!local_table) 01729 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); 01730 01731 if (!pbx_load_config(config)) 01732 return AST_MODULE_LOAD_DECLINE; 01733 01734 pbx_load_users(); 01735 01736 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar); 01737 local_table = NULL; /* the local table has been moved into the global one. */ 01738 local_contexts = NULL; 01739 01740 for (con = NULL; (con = ast_walk_contexts(con));) 01741 ast_context_verify_includes(con); 01742 01743 pbx_set_overrideswitch(overrideswitch_config); 01744 pbx_set_autofallthrough(autofallthrough_config); 01745 pbx_set_extenpatternmatchnew(extenpatternmatchnew_config); 01746 01747 return AST_MODULE_LOAD_SUCCESS; 01748 }
static void pbx_load_users | ( | void | ) | [static] |
Definition at line 1618 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(), config_flags, ext, len(), local_contexts, local_table, LOG_ERROR, strdup, and strsep().
Referenced by pbx_load_module().
01619 { 01620 struct ast_config *cfg; 01621 char *cat, *chan; 01622 const char *dahdichan; 01623 const char *hasexten, *altexts; 01624 char tmp[256]; 01625 char iface[256]; 01626 char dahdicopy[256]; 01627 char *ext, altcopy[256]; 01628 char *c; 01629 int len; 01630 int hasvoicemail; 01631 int start, finish, x; 01632 struct ast_context *con = NULL; 01633 struct ast_flags config_flags = { 0 }; 01634 01635 cfg = ast_config_load("users.conf", config_flags); 01636 if (!cfg) 01637 return; 01638 01639 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 01640 if (!strcasecmp(cat, "general")) 01641 continue; 01642 iface[0] = '\0'; 01643 len = sizeof(iface); 01644 if (ast_true(ast_config_option(cfg, cat, "hassip"))) { 01645 snprintf(tmp, sizeof(tmp), "SIP/%s", cat); 01646 append_interface(iface, sizeof(iface), tmp); 01647 } 01648 if (ast_true(ast_config_option(cfg, cat, "hasiax"))) { 01649 snprintf(tmp, sizeof(tmp), "IAX2/%s", cat); 01650 append_interface(iface, sizeof(iface), tmp); 01651 } 01652 if (ast_true(ast_config_option(cfg, cat, "hash323"))) { 01653 snprintf(tmp, sizeof(tmp), "H323/%s", cat); 01654 append_interface(iface, sizeof(iface), tmp); 01655 } 01656 hasexten = ast_config_option(cfg, cat, "hasexten"); 01657 if (hasexten && !ast_true(hasexten)) 01658 continue; 01659 hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail")); 01660 dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan"); 01661 if (!dahdichan) 01662 dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan"); 01663 if (!ast_strlen_zero(dahdichan)) { 01664 ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy)); 01665 c = dahdicopy; 01666 chan = strsep(&c, ","); 01667 while (chan) { 01668 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) { 01669 /* Range */ 01670 } else if (sscanf(chan, "%30d", &start)) { 01671 /* Just one */ 01672 finish = start; 01673 } else { 01674 start = 0; finish = 0; 01675 } 01676 if (finish < start) { 01677 x = finish; 01678 finish = start; 01679 start = x; 01680 } 01681 for (x = start; x <= finish; x++) { 01682 snprintf(tmp, sizeof(tmp), "DAHDI/%d", x); 01683 append_interface(iface, sizeof(iface), tmp); 01684 } 01685 chan = strsep(&c, ","); 01686 } 01687 } 01688 if (!ast_strlen_zero(iface)) { 01689 /* Only create a context here when it is really needed. Otherwise default empty context 01690 created by pbx_config may conflict with the one explicitly created by pbx_ael */ 01691 if (!con) 01692 con = ast_context_find_or_create(&local_contexts, local_table, userscontext, registrar); 01693 01694 if (!con) { 01695 ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext); 01696 return; 01697 } 01698 01699 /* Add hint */ 01700 ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar); 01701 /* If voicemail, use "stdexten" else use plain old dial */ 01702 if (hasvoicemail) { 01703 snprintf(tmp, sizeof(tmp), "stdexten,%s,${HINT}", cat); 01704 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", strdup(tmp), ast_free_ptr, registrar); 01705 } else { 01706 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", strdup("${HINT}"), ast_free_ptr, registrar); 01707 } 01708 altexts = ast_variable_retrieve(cfg, cat, "alternateexts"); 01709 if (!ast_strlen_zero(altexts)) { 01710 snprintf(tmp, sizeof(tmp), "%s,1", cat); 01711 ast_copy_string(altcopy, altexts, sizeof(altcopy)); 01712 c = altcopy; 01713 ext = strsep(&c, ","); 01714 while (ext) { 01715 ast_add_extension2(con, 0, ext, 1, NULL, NULL, "Goto", strdup(tmp), ast_free_ptr, registrar); 01716 ext = strsep(&c, ","); 01717 } 01718 } 01719 } 01720 } 01721 ast_config_destroy(cfg); 01722 }
static char* pbx_strsep | ( | char ** | destructible, | |
const char * | delim | |||
) | [static] |
Definition at line 1340 of file pbx_config.c.
01341 { 01342 int square = 0; 01343 char *res = *destructible; 01344 for (; destructible && *destructible && **destructible; (*destructible)++) { 01345 if (**destructible == '[' && !strchr(delim, '[')) { 01346 square++; 01347 } else if (**destructible == ']' && !strchr(delim, ']')) { 01348 if (square) { 01349 square--; 01350 } 01351 } else if (**destructible == '\\' && !strchr(delim, '\\')) { 01352 (*destructible)++; 01353 } else if (strchr(delim, **destructible) && !square) { 01354 **destructible = '\0'; 01355 (*destructible)++; 01356 break; 01357 } 01358 } 01359 if (destructible && *destructible && **destructible == '\0') { 01360 *destructible = NULL; 01361 } 01362 return res; 01363 }
static int reload | ( | void | ) | [static] |
Definition at line 1762 of file pbx_config.c.
References pbx_builtin_clear_globals(), and pbx_load_module().
01763 { 01764 if (clearglobalvars_config) 01765 pbx_builtin_clear_globals(); 01766 return pbx_load_module(); 01767 }
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 1323 of file pbx_config.c.
References ARRAY_LEN, ast_cli_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_free, cli_dialplan_save, and cli_pbx_config.
01324 { 01325 if (static_config && !write_protect_config) 01326 ast_cli_unregister(&cli_dialplan_save); 01327 if (overrideswitch_config) { 01328 ast_free(overrideswitch_config); 01329 } 01330 ast_cli_unregister_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config)); 01331 ast_context_destroy(NULL, registrar); 01332 return 0; 01333 }
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1773 of file pbx_config.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1773 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] |
Initial value:
{ .handler = handle_cli_dialplan_save , .summary = "Save dialplan" ,__VA_ARGS__ }
Definition at line 1317 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 1307 of file pbx_config.c.
Referenced by load_module(), and unload_module().
const 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(), 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] |
Definition at line 50 of file pbx_config.c.
const char registrar[] = "pbx_config" [static] |
Definition at line 42 of file pbx_config.c.
ast_mutex_t save_dialplan_lock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static] |
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.