#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 = "88eaa8f5c1bd988bedd71113385e0886" , .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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
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 1803 of file pbx_config.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1803 of file pbx_config.c.
static void append_interface | ( | char * | iface, | |
int | maxlen, | |||
char * | add | |||
) | [static] |
Definition at line 1638 of file pbx_config.c.
References len().
Referenced by pbx_load_users().
01639 { 01640 int len = strlen(iface); 01641 if (strlen(add) + len < maxlen - 2) { 01642 if (strlen(iface)) { 01643 iface[len] = '&'; 01644 strcpy(iface + len + 1, add); 01645 } else 01646 strcpy(iface, add); 01647 } 01648 }
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 1014 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().
01015 { 01016 int which = 0; 01017 01018 if (a->pos == 4) { /* complete 'into' word ... */ 01019 return (a->n == 0) ? strdup("into") : NULL; 01020 } else if (a->pos == 5) { /* complete context */ 01021 struct ast_context *c = NULL; 01022 int len = strlen(a->word); 01023 char *res = NULL; 01024 01025 /* try to lock contexts list ... */ 01026 if (ast_rdlock_contexts()) { 01027 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01028 return NULL; 01029 } 01030 01031 /* walk through all contexts */ 01032 while ( !res && (c = ast_walk_contexts(c)) ) 01033 if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n) 01034 res = strdup(ast_get_context_name(c)); 01035 ast_unlock_contexts(); 01036 return res; 01037 } else if (a->pos == 6) { 01038 return a->n == 0 ? strdup("replace") : NULL; 01039 } 01040 return NULL; 01041 }
static char * complete_dialplan_add_ignorepat | ( | struct ast_cli_args * | ) | [static] |
Definition at line 1100 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().
01101 { 01102 if (a->pos == 4) 01103 return a->n == 0 ? strdup("into") : NULL; 01104 else if (a->pos == 5) { 01105 struct ast_context *c; 01106 int which = 0; 01107 char *dupline, *ignorepat = NULL; 01108 const char *s; 01109 char *ret = NULL; 01110 int len = strlen(a->word); 01111 01112 /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */ 01113 s = skip_words(a->line, 3); 01114 if (s == NULL) 01115 return NULL; 01116 dupline = strdup(s); 01117 if (!dupline) { 01118 ast_log(LOG_ERROR, "Malloc failure\n"); 01119 return NULL; 01120 } 01121 ignorepat = strsep(&dupline, " "); 01122 01123 if (ast_rdlock_contexts()) { 01124 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 01125 return NULL; 01126 } 01127 01128 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01129 int found = 0; 01130 01131 if (!partial_match(ast_get_context_name(c), a->word, len)) 01132 continue; /* not mine */ 01133 if (ignorepat) /* there must be one, right ? */ 01134 found = lookup_c_ip(c, ignorepat); 01135 if (!found && ++which > a->n) 01136 ret = strdup(ast_get_context_name(c)); 01137 } 01138 01139 free(ignorepat); 01140 ast_unlock_contexts(); 01141 return ret; 01142 } 01143 01144 return NULL; 01145 }
static char * complete_dialplan_add_include | ( | struct ast_cli_args * | ) | [static] |
Definition at line 578 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().
00579 { 00580 struct ast_context *c; 00581 int which = 0; 00582 char *ret = NULL; 00583 int len = strlen(a->word); 00584 00585 if (a->pos == 3) { /* 'dialplan add include _X_' (context) ... */ 00586 if (ast_rdlock_contexts()) { 00587 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00588 return NULL; 00589 } 00590 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) 00591 if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n) 00592 ret = strdup(ast_get_context_name(c)); 00593 ast_unlock_contexts(); 00594 return ret; 00595 } else if (a->pos == 4) { /* dialplan add include CTX _X_ */ 00596 /* complete as 'into' if context exists or we are unable to check */ 00597 char *context, *dupline; 00598 const char *s = skip_words(a->line, 3); /* should not fail */ 00599 00600 if (a->n != 0) /* only once */ 00601 return NULL; 00602 00603 /* parse context from line ... */ 00604 context = dupline = strdup(s); 00605 if (!context) { 00606 ast_log(LOG_ERROR, "Out of free memory\n"); 00607 return strdup("into"); 00608 } 00609 strsep(&dupline, " "); 00610 00611 /* check for context existence ... */ 00612 if (ast_rdlock_contexts()) { 00613 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00614 /* our fault, we can't check, so complete 'into' ... */ 00615 ret = strdup("into"); 00616 } else { 00617 struct ast_context *ctx; 00618 for (ctx = NULL; !ret && (ctx = ast_walk_contexts(ctx)); ) 00619 if (!strcmp(context, ast_get_context_name(ctx))) 00620 ret = strdup("into"); /* found */ 00621 ast_unlock_contexts(); 00622 } 00623 free(context); 00624 return ret; 00625 } else if (a->pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */ 00626 char *context, *dupline, *into; 00627 const char *s = skip_words(a->line, 3); /* should not fail */ 00628 context = dupline = strdup(s); 00629 if (!dupline) { 00630 ast_log(LOG_ERROR, "Out of free memory\n"); 00631 return NULL; 00632 } 00633 strsep(&dupline, " "); /* skip context */ 00634 into = strsep(&dupline, " "); 00635 /* error if missing context or fifth word is not 'into' */ 00636 if (!strlen(context) || strcmp(into, "into")) { 00637 ast_log(LOG_ERROR, "bad context %s or missing into %s\n", 00638 context, into); 00639 goto error3; 00640 } 00641 00642 if (ast_rdlock_contexts()) { 00643 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00644 goto error3; 00645 } 00646 00647 for (c = NULL; (c = ast_walk_contexts(c)); ) 00648 if (!strcmp(context, ast_get_context_name(c))) 00649 break; 00650 if (c) { /* first context exists, go on... */ 00651 /* go through all contexts ... */ 00652 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 00653 if (!strcmp(context, ast_get_context_name(c))) 00654 continue; /* skip ourselves */ 00655 if (partial_match(ast_get_context_name(c), a->word, len) && 00656 !lookup_ci(c, context) /* not included yet */ && 00657 ++which > a->n) 00658 ret = strdup(ast_get_context_name(c)); 00659 } 00660 } else { 00661 ast_log(LOG_ERROR, "context %s not found\n", context); 00662 } 00663 ast_unlock_contexts(); 00664 error3: 00665 free(context); 00666 return ret; 00667 } 00668 00669 return NULL; 00670 }
static char * complete_dialplan_remove_extension | ( | struct ast_cli_args * | ) | [static] |
Definition at line 396 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().
00397 { 00398 char *ret = NULL; 00399 int which = 0; 00400 00401 if (a->pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */ 00402 struct ast_context *c = NULL; 00403 char *context = NULL, *exten = NULL, *cid = NULL; 00404 int le = 0; /* length of extension */ 00405 int lc = 0; /* length of context */ 00406 int lcid = 0; /* length of cid */ 00407 00408 lc = split_ec(a->word, &exten, &context, &cid); 00409 if (lc) { /* error */ 00410 return NULL; 00411 } 00412 le = strlen(exten); 00413 lc = strlen(context); 00414 lcid = cid ? strlen(cid) : -1; 00415 00416 if (ast_rdlock_contexts()) { 00417 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00418 goto error2; 00419 } 00420 00421 /* find our context ... */ 00422 while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */ 00423 struct ast_exten *e = NULL; 00424 /* XXX locking ? */ 00425 if (!partial_match(ast_get_context_name(c), context, lc)) 00426 continue; /* context not matched */ 00427 while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */ 00428 if ( !strchr(a->word, '/') || 00429 (!strchr(a->word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) || 00430 (strchr(a->word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) { 00431 if ( ((strchr(a->word, '/') || strchr(a->word, '@')) && !strcmp(ast_get_extension_name(e), exten)) || 00432 (!strchr(a->word, '/') && !strchr(a->word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */ 00433 if (++which > a->n) { 00434 /* If there is an extension then return exten@context. */ 00435 if (ast_get_extension_matchcid(e) && (!strchr(a->word, '@') || strchr(a->word, '/'))) { 00436 if (asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)) < 0) { 00437 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00438 ret = NULL; 00439 } 00440 break; 00441 } else if (!ast_get_extension_matchcid(e) && !strchr(a->word, '/')) { 00442 if (asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) { 00443 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00444 ret = NULL; 00445 } 00446 break; 00447 } 00448 } 00449 } 00450 } 00451 } 00452 if (e) /* got a match */ 00453 break; 00454 } 00455 00456 ast_unlock_contexts(); 00457 error2: 00458 free(exten); 00459 } else if (a->pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */ 00460 char *exten = NULL, *context, *cid, *p; 00461 struct ast_context *c; 00462 int le, lc, len; 00463 const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'extension' */ 00464 int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */ 00465 00466 if (i) /* error */ 00467 goto error3; 00468 if ( (p = strchr(exten, ' ')) ) /* remove space after extension */ 00469 *p = '\0'; 00470 if ( (p = strchr(context, ' ')) ) /* remove space after context */ 00471 *p = '\0'; 00472 le = strlen(exten); 00473 lc = strlen(context); 00474 len = strlen(a->word); 00475 if (le == 0 || lc == 0) 00476 goto error3; 00477 00478 if (ast_rdlock_contexts()) { 00479 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00480 goto error3; 00481 } 00482 00483 /* walk contexts */ 00484 c = NULL; 00485 while ( (c = ast_walk_contexts(c)) ) { 00486 /* XXX locking on c ? */ 00487 struct ast_exten *e; 00488 if (strcmp(ast_get_context_name(c), context) != 0) 00489 continue; 00490 /* got it, we must match here */ 00491 e = NULL; 00492 while ( (e = ast_walk_context_extensions(c, e)) ) { 00493 struct ast_exten *priority; 00494 char buffer[10]; 00495 00496 if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) { 00497 continue; 00498 } 00499 if (strcmp(ast_get_extension_name(e), exten) != 0) 00500 continue; 00501 /* XXX lock e ? */ 00502 priority = NULL; 00503 while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) { 00504 snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority)); 00505 if (partial_match(buffer, a->word, len) && ++which > a->n) /* n-th match */ 00506 ret = strdup(buffer); 00507 } 00508 break; 00509 } 00510 break; 00511 } 00512 ast_unlock_contexts(); 00513 error3: 00514 free(exten); 00515 } 00516 return ret; 00517 }
static char * complete_dialplan_remove_ignorepat | ( | struct ast_cli_args * | ) | [static] |
Definition at line 1196 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().
01197 { 01198 struct ast_context *c; 01199 int which = 0; 01200 char *ret = NULL; 01201 01202 if (a->pos == 3) { 01203 int len = strlen(a->word); 01204 if (ast_rdlock_contexts()) { 01205 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01206 return NULL; 01207 } 01208 01209 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01210 struct ast_ignorepat *ip; 01211 01212 if (ast_rdlock_context(c)) /* error, skip it */ 01213 continue; 01214 01215 for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) { 01216 if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) { 01217 /* n-th match */ 01218 struct ast_context *cw = NULL; 01219 int found = 0; 01220 while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) { 01221 /* XXX do i stop on c, or skip it ? */ 01222 found = lookup_c_ip(cw, ast_get_ignorepat_name(ip)); 01223 } 01224 if (!found) 01225 ret = strdup(ast_get_ignorepat_name(ip)); 01226 } 01227 } 01228 ast_unlock_context(c); 01229 } 01230 ast_unlock_contexts(); 01231 return ret; 01232 } else if (a->pos == 4) { 01233 return a->n == 0 ? strdup("from") : NULL; 01234 } else if (a->pos == 5) { /* XXX check this */ 01235 char *dupline, *duplinet, *ignorepat; 01236 int len = strlen(a->word); 01237 01238 dupline = strdup(a->line); 01239 if (!dupline) { 01240 ast_log(LOG_WARNING, "Out of free memory\n"); 01241 return NULL; 01242 } 01243 01244 duplinet = dupline; 01245 strsep(&duplinet, " "); 01246 strsep(&duplinet, " "); 01247 ignorepat = strsep(&duplinet, " "); 01248 01249 if (!ignorepat) { 01250 free(dupline); 01251 return NULL; 01252 } 01253 01254 if (ast_rdlock_contexts()) { 01255 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01256 free(dupline); 01257 return NULL; 01258 } 01259 01260 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 01261 if (ast_rdlock_context(c)) /* fail, skip it */ 01262 continue; 01263 if (!partial_match(ast_get_context_name(c), a->word, len)) 01264 continue; 01265 if (lookup_c_ip(c, ignorepat) && ++which > a->n) 01266 ret = strdup(ast_get_context_name(c)); 01267 ast_unlock_context(c); 01268 } 01269 ast_unlock_contexts(); 01270 free(dupline); 01271 return NULL; 01272 } 01273 01274 return NULL; 01275 }
static char * complete_dialplan_remove_include | ( | struct ast_cli_args * | ) | [static] |
Definition at line 186 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().
00187 { 00188 int which = 0; 00189 char *res = NULL; 00190 int len = strlen(a->word); /* how many bytes to match */ 00191 struct ast_context *c = NULL; 00192 00193 if (a->pos == 3) { /* "dialplan remove include _X_" */ 00194 if (ast_wrlock_contexts()) { 00195 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00196 return NULL; 00197 } 00198 /* walk contexts and their includes, return the n-th match */ 00199 while (!res && (c = ast_walk_contexts(c))) { 00200 struct ast_include *i = NULL; 00201 00202 if (ast_rdlock_context(c)) /* error ? skip this one */ 00203 continue; 00204 00205 while ( !res && (i = ast_walk_context_includes(c, i)) ) { 00206 const char *i_name = ast_get_include_name(i); 00207 struct ast_context *nc = NULL; 00208 int already_served = 0; 00209 00210 if (!partial_match(i_name, a->word, len)) 00211 continue; /* not matched */ 00212 00213 /* check if this include is already served or not */ 00214 00215 /* go through all contexts again till we reach actual 00216 * context or already_served = 1 00217 */ 00218 while ( (nc = ast_walk_contexts(nc)) && nc != c && !already_served) 00219 already_served = lookup_ci(nc, i_name); 00220 00221 if (!already_served && ++which > a->n) 00222 res = strdup(i_name); 00223 } 00224 ast_unlock_context(c); 00225 } 00226 00227 ast_unlock_contexts(); 00228 return res; 00229 } else if (a->pos == 4) { /* "dialplan remove include CTX _X_" */ 00230 /* 00231 * complete as 'from', but only if previous context is really 00232 * included somewhere 00233 */ 00234 char *context, *dupline; 00235 const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */ 00236 00237 if (a->n > 0) 00238 return NULL; 00239 context = dupline = strdup(s); 00240 if (!dupline) { 00241 ast_log(LOG_ERROR, "Out of free memory\n"); 00242 return NULL; 00243 } 00244 strsep(&dupline, " "); 00245 00246 if (ast_rdlock_contexts()) { 00247 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 00248 free(context); 00249 return NULL; 00250 } 00251 00252 /* go through all contexts and check if is included ... */ 00253 while (!res && (c = ast_walk_contexts(c))) 00254 if (lookup_ci(c, context)) /* context is really included, complete "from" command */ 00255 res = strdup("from"); 00256 ast_unlock_contexts(); 00257 if (!res) 00258 ast_log(LOG_WARNING, "%s not included anywhere\n", context); 00259 free(context); 00260 return res; 00261 } else if (a->pos == 5) { /* "dialplan remove include CTX from _X_" */ 00262 /* 00263 * Context from which we removing include ... 00264 */ 00265 char *context, *dupline, *from; 00266 const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */ 00267 context = dupline = strdup(s); 00268 if (!dupline) { 00269 ast_log(LOG_ERROR, "Out of free memory\n"); 00270 return NULL; 00271 } 00272 00273 strsep(&dupline, " "); /* skip context */ 00274 00275 /* fourth word must be 'from' */ 00276 from = strsep(&dupline, " "); 00277 if (!from || strcmp(from, "from")) { 00278 free(context); 00279 return NULL; 00280 } 00281 00282 if (ast_rdlock_contexts()) { 00283 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00284 free(context); 00285 return NULL; 00286 } 00287 00288 /* walk through all contexts ... */ 00289 c = NULL; 00290 while ( !res && (c = ast_walk_contexts(c))) { 00291 const char *c_name = ast_get_context_name(c); 00292 if (!partial_match(c_name, a->word, len)) /* not a good target */ 00293 continue; 00294 /* walk through all includes and check if it is our context */ 00295 if (lookup_ci(c, context) && ++which > a->n) 00296 res = strdup(c_name); 00297 } 00298 ast_unlock_contexts(); 00299 free(context); 00300 return res; 00301 } 00302 00303 return NULL; 00304 }
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_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.
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 whole_exten = ast_strdupa(a->argv[3]); 00937 exten = strsep(&whole_exten,","); 00938 if (strchr(exten, '/')) { 00939 cidmatch = exten; 00940 strsep(&cidmatch,"/"); 00941 } else { 00942 cidmatch = NULL; 00943 } 00944 prior = strsep(&whole_exten,","); 00945 if (prior) { 00946 if (!strcmp(prior, "hint")) { 00947 iprior = PRIORITY_HINT; 00948 } else { 00949 if (sscanf(prior, "%30d", &iprior) != 1) { 00950 ast_cli(a->fd, "'%s' is not a valid priority\n", prior); 00951 prior = NULL; 00952 } 00953 } 00954 } 00955 app = whole_exten; 00956 if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) { 00957 *start = *end = '\0'; 00958 app_data = start + 1; 00959 } else { 00960 if (app) { 00961 app_data = strchr(app, ','); 00962 if (app_data) { 00963 *app_data = '\0'; 00964 app_data++; 00965 } 00966 } else 00967 app_data = NULL; 00968 } 00969 00970 if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT)) 00971 return CLI_SHOWUSAGE; 00972 00973 if (!app_data) 00974 app_data=""; 00975 if (ast_add_extension(a->argv[5], a->argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app, 00976 (void *)strdup(app_data), ast_free_ptr, registrar)) { 00977 switch (errno) { 00978 case ENOMEM: 00979 ast_cli(a->fd, "Out of free memory\n"); 00980 break; 00981 00982 case EBUSY: 00983 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 00984 break; 00985 00986 case ENOENT: 00987 ast_cli(a->fd, "No existence of '%s' context\n", a->argv[5]); 00988 break; 00989 00990 case EEXIST: 00991 ast_cli(a->fd, "Extension %s@%s with priority %s already exists\n", 00992 exten, a->argv[5], prior); 00993 break; 00994 00995 default: 00996 ast_cli(a->fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n", 00997 exten, prior, app, app_data, a->argv[5]); 00998 break; 00999 } 01000 return CLI_FAILURE; 01001 } 01002 01003 if (a->argc == 7) 01004 ast_cli(a->fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n", 01005 exten, a->argv[5], prior, exten, prior, app, app_data); 01006 else 01007 ast_cli(a->fd, "Extension '%s,%s,%s,%s' added into '%s' context\n", 01008 exten, prior, app, app_data, a->argv[5]); 01009 01010 return CLI_SUCCESS; 01011 }
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 1046 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.
01047 { 01048 switch (cmd) { 01049 case CLI_INIT: 01050 e->command = "dialplan add ignorepat"; 01051 e->usage = 01052 "Usage: dialplan add ignorepat <pattern> into <context>\n" 01053 " This command adds a new ignore pattern into context <context>\n" 01054 "\n" 01055 "Example: dialplan add ignorepat _3XX into local\n"; 01056 return NULL; 01057 case CLI_GENERATE: 01058 return complete_dialplan_add_ignorepat(a); 01059 } 01060 01061 if (a->argc != 6) 01062 return CLI_SHOWUSAGE; 01063 01064 if (strcmp(a->argv[4], "into")) 01065 return CLI_SHOWUSAGE; 01066 01067 if (ast_context_add_ignorepat(a->argv[5], a->argv[3], registrar)) { 01068 switch (errno) { 01069 case ENOMEM: 01070 ast_cli(a->fd, "Out of free memory\n"); 01071 break; 01072 01073 case ENOENT: 01074 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01075 break; 01076 01077 case EEXIST: 01078 ast_cli(a->fd, "Ignore pattern '%s' already included in '%s' context\n", 01079 a->argv[3], a->argv[5]); 01080 break; 01081 01082 case EBUSY: 01083 ast_cli(a->fd, "Failed to lock context(s) list, please, try again later\n"); 01084 break; 01085 01086 default: 01087 ast_cli(a->fd, "Failed to add ingore pattern '%s' into '%s' context\n", 01088 a->argv[3], a->argv[5]); 01089 break; 01090 } 01091 return CLI_FAILURE; 01092 } 01093 01094 ast_cli(a->fd, "Ignore pattern '%s' added into '%s' context\n", 01095 a->argv[3], a->argv[5]); 01096 01097 return CLI_SUCCESS; 01098 }
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 522 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.
00523 { 00524 switch (cmd) { 00525 case CLI_INIT: 00526 e->command = "dialplan add include"; 00527 e->usage = 00528 "Usage: dialplan add include <context> into <context>\n" 00529 " Include a context in another context.\n"; 00530 return NULL; 00531 case CLI_GENERATE: 00532 return complete_dialplan_add_include(a); 00533 } 00534 00535 if (a->argc != 6) /* dialplan add include CTX in CTX */ 00536 return CLI_SHOWUSAGE; 00537 00538 /* fifth arg must be 'into' ... */ 00539 if (strcmp(a->argv[4], "into")) 00540 return CLI_SHOWUSAGE; 00541 00542 if (ast_context_add_include(a->argv[5], a->argv[3], registrar)) { 00543 switch (errno) { 00544 case ENOMEM: 00545 ast_cli(a->fd, "Out of memory for context addition\n"); 00546 break; 00547 00548 case EBUSY: 00549 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 00550 break; 00551 00552 case EEXIST: 00553 ast_cli(a->fd, "Context '%s' already included in '%s' context\n", 00554 a->argv[3], a->argv[5]); 00555 break; 00556 00557 case ENOENT: 00558 case EINVAL: 00559 ast_cli(a->fd, "There is no existence of context '%s'\n", 00560 errno == ENOENT ? a->argv[5] : a->argv[3]); 00561 break; 00562 00563 default: 00564 ast_cli(a->fd, "Failed to include '%s' in '%s' context\n", 00565 a->argv[3], a->argv[5]); 00566 break; 00567 } 00568 return CLI_FAILURE; 00569 } 00570 00571 /* show some info ... */ 00572 ast_cli(a->fd, "Context '%s' included in '%s' context\n", 00573 a->argv[3], a->argv[5]); 00574 00575 return CLI_SUCCESS; 00576 }
static char* handle_cli_dialplan_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1279 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.
01280 { 01281 switch (cmd) { 01282 case CLI_INIT: 01283 e->command = "dialplan reload"; 01284 e->usage = 01285 "Usage: dialplan reload\n" 01286 " Reload extensions.conf without reloading any other\n" 01287 " modules. This command does not delete global variables\n" 01288 " unless clearglobalvars is set to yes in extensions.conf\n"; 01289 return NULL; 01290 case CLI_GENERATE: 01291 return NULL; 01292 } 01293 01294 if (a->argc != 2) 01295 return CLI_SHOWUSAGE; 01296 01297 if (clearglobalvars_config) 01298 pbx_builtin_clear_globals(); 01299 01300 pbx_load_module(); 01301 ast_cli(a->fd, "Dialplan reloaded.\n"); 01302 return CLI_SUCCESS; 01303 }
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 309 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.
00310 { 00311 int removing_priority = 0; 00312 char *exten, *context, *cid; 00313 char *ret = CLI_FAILURE; 00314 00315 switch (cmd) { 00316 case CLI_INIT: 00317 e->command = "dialplan remove extension"; 00318 e->usage = 00319 "Usage: dialplan remove extension exten[/cid]@context [priority]\n" 00320 " Remove an extension from a given context. If a priority\n" 00321 " is given, only that specific priority from the given extension\n" 00322 " will be removed.\n"; 00323 return NULL; 00324 case CLI_GENERATE: 00325 return complete_dialplan_remove_extension(a); 00326 } 00327 00328 if (a->argc != 5 && a->argc != 4) 00329 return CLI_SHOWUSAGE; 00330 00331 /* 00332 * Priority input checking ... 00333 */ 00334 if (a->argc == 5) { 00335 const char *c = a->argv[4]; 00336 00337 /* check for digits in whole parameter for right priority ... 00338 * why? because atoi (strtol) returns 0 if any characters in 00339 * string and whole extension will be removed, it's not good 00340 */ 00341 if (!strcmp("hint", c)) 00342 removing_priority = PRIORITY_HINT; 00343 else { 00344 while (*c && isdigit(*c)) 00345 c++; 00346 if (*c) { /* non-digit in string */ 00347 ast_cli(a->fd, "Invalid priority '%s'\n", a->argv[4]); 00348 return CLI_FAILURE; 00349 } 00350 removing_priority = atoi(a->argv[4]); 00351 } 00352 00353 if (removing_priority == 0) { 00354 ast_cli(a->fd, "If you want to remove whole extension, please " \ 00355 "omit priority argument\n"); 00356 return CLI_FAILURE; 00357 } 00358 } 00359 00360 /* XXX original overwrote argv[3] */ 00361 /* 00362 * Format exten@context checking ... 00363 */ 00364 if (split_ec(a->argv[3], &exten, &context, &cid)) 00365 return CLI_FAILURE; /* XXX malloc failure */ 00366 if ((!strlen(exten)) || (!(strlen(context)))) { 00367 ast_cli(a->fd, "Missing extension or context name in third argument '%s'\n", 00368 a->argv[3]); 00369 free(exten); 00370 return CLI_FAILURE; 00371 } 00372 00373 if (!ast_context_remove_extension_callerid(context, exten, removing_priority, 00374 /* Do NOT substitute S_OR; it is NOT the same thing */ 00375 cid ? cid : (removing_priority ? "" : NULL), cid ? 1 : 0, registrar)) { 00376 if (!removing_priority) 00377 ast_cli(a->fd, "Whole extension %s@%s removed\n", 00378 exten, context); 00379 else 00380 ast_cli(a->fd, "Extension %s@%s with priority %d removed\n", 00381 exten, context, removing_priority); 00382 00383 ret = CLI_SUCCESS; 00384 } else { 00385 if (cid) { 00386 ast_cli(a->fd, "Failed to remove extension %s/%s@%s\n", exten, cid, context); 00387 } else { 00388 ast_cli(a->fd, "Failed to remove extension %s@%s\n", exten, context); 00389 } 00390 ret = CLI_FAILURE; 00391 } 00392 free(exten); 00393 return ret; 00394 }
static char* handle_cli_dialplan_remove_ignorepat | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1147 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.
01148 { 01149 switch (cmd) { 01150 case CLI_INIT: 01151 e->command = "dialplan remove ignorepat"; 01152 e->usage = 01153 "Usage: dialplan remove ignorepat <pattern> from <context>\n" 01154 " This command removes an ignore pattern from context <context>\n" 01155 "\n" 01156 "Example: dialplan remove ignorepat _3XX from local\n"; 01157 return NULL; 01158 case CLI_GENERATE: 01159 return complete_dialplan_remove_ignorepat(a); 01160 } 01161 01162 if (a->argc != 6) 01163 return CLI_SHOWUSAGE; 01164 01165 if (strcmp(a->argv[4], "from")) 01166 return CLI_SHOWUSAGE; 01167 01168 if (ast_context_remove_ignorepat(a->argv[5], a->argv[3], registrar)) { 01169 switch (errno) { 01170 case EBUSY: 01171 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 01172 break; 01173 01174 case ENOENT: 01175 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01176 break; 01177 01178 case EINVAL: 01179 ast_cli(a->fd, "There is no existence of '%s' ignore pattern in '%s' context\n", 01180 a->argv[3], a->argv[5]); 01181 break; 01182 01183 default: 01184 ast_cli(a->fd, "Failed to remove ignore pattern '%s' from '%s' context\n", 01185 a->argv[3], a->argv[5]); 01186 break; 01187 } 01188 return CLI_FAILURE; 01189 } 01190 01191 ast_cli(a->fd, "Ignore pattern '%s' removed from '%s' context\n", 01192 a->argv[3], a->argv[5]); 01193 return CLI_SUCCESS; 01194 }
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 77 of file pbx_config.c.
References ast_cli_args::argc, 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.
00078 { 00079 switch (cmd) { 00080 case CLI_INIT: 00081 e->command = "dialplan remove include"; 00082 e->usage = 00083 "Usage: dialplan remove include <context> from <context>\n" 00084 " Remove an included context from another context.\n"; 00085 return NULL; 00086 case CLI_GENERATE: 00087 return complete_dialplan_remove_include(a); 00088 } 00089 00090 if (a->argc != 6 || strcmp(a->argv[4], "from")) 00091 return CLI_SHOWUSAGE; 00092 00093 if (!ast_context_remove_include(a->argv[5], a->argv[3], registrar)) { 00094 ast_cli(a->fd, "We are not including '%s' into '%s' now\n", 00095 a->argv[3], a->argv[5]); 00096 return CLI_SUCCESS; 00097 } 00098 00099 ast_cli(a->fd, "Failed to remove '%s' include from '%s' context\n", 00100 a->argv[3], a->argv[5]); 00101 return CLI_FAILURE; 00102 }
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 675 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.
00676 { 00677 char filename[256], overrideswitch[256] = ""; 00678 struct ast_context *c; 00679 struct ast_config *cfg; 00680 struct ast_variable *v; 00681 int incomplete = 0; /* incomplete config write? */ 00682 FILE *output; 00683 struct ast_flags config_flags = { 0 }; 00684 const char *base, *slash; 00685 00686 switch (cmd) { 00687 case CLI_INIT: 00688 e->command = "dialplan save"; 00689 e->usage = 00690 "Usage: dialplan save [/path/to/extension/file]\n" 00691 " Save dialplan created by pbx_config module.\n" 00692 "\n" 00693 "Example: dialplan save (/etc/asterisk/extensions.conf)\n" 00694 " dialplan save /home/markster (/home/markster/extensions.conf)\n"; 00695 return NULL; 00696 case CLI_GENERATE: 00697 return NULL; 00698 } 00699 00700 if (! (static_config && !write_protect_config)) { 00701 ast_cli(a->fd, 00702 "I can't save dialplan now, see '%s' example file.\n", 00703 config); 00704 return CLI_FAILURE; 00705 } 00706 00707 if (a->argc != 2 && a->argc != 3) 00708 return CLI_SHOWUSAGE; 00709 00710 if (ast_mutex_lock(&save_dialplan_lock)) { 00711 ast_cli(a->fd, 00712 "Failed to lock dialplan saving (another proccess saving?)\n"); 00713 return CLI_FAILURE; 00714 } 00715 /* XXX the code here is quite loose, a pathname with .conf in it 00716 * is assumed to be a complete pathname 00717 */ 00718 if (a->argc == 3) { /* have config path. Look for *.conf */ 00719 base = a->argv[2]; 00720 if (!strstr(a->argv[2], ".conf")) { /*no, this is assumed to be a pathname */ 00721 /* if filename ends with '/', do not add one */ 00722 slash = (*(a->argv[2] + strlen(a->argv[2]) -1) == '/') ? "/" : ""; 00723 } else { /* yes, complete file name */ 00724 slash = ""; 00725 } 00726 } else { 00727 /* no config file, default one */ 00728 base = ast_config_AST_CONFIG_DIR; 00729 slash = "/"; 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 1780 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().
01781 { 01782 if (static_config && !write_protect_config) 01783 ast_cli_register(&cli_dialplan_save); 01784 ast_cli_register_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config)); 01785 01786 if (pbx_load_module()) 01787 return AST_MODULE_LOAD_DECLINE; 01788 01789 return AST_MODULE_LOAD_SUCCESS; 01790 }
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 119 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().
00120 { 00121 struct ast_ignorepat *ip = NULL; 00122 00123 if (ast_rdlock_context(c)) /* error, skip */ 00124 return 0; 00125 while ( (ip = ast_walk_context_ignorepats(c, ip)) ) 00126 if (!strcmp(name, ast_get_ignorepat_name(ip))) 00127 break; 00128 ast_unlock_context(c); 00129 return ip ? -1 /* success */ : 0; 00130 }
static int lookup_ci | ( | struct ast_context * | c, | |
const char * | name | |||
) | [static] |
return true if 'name' is included by context c
Definition at line 105 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().
00106 { 00107 struct ast_include *i = NULL; 00108 00109 if (ast_rdlock_context(c)) /* error, skip */ 00110 return 0; 00111 while ( (i = ast_walk_context_includes(c, i)) ) 00112 if (!strcmp(name, ast_get_include_name(i))) 00113 break; 00114 ast_unlock_context(c); 00115 return i ? -1 /* success */ : 0; 00116 }
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 148 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_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::file, 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().
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 const char *vfile; 01434 01435 /* get filename for error reporting from top level or an #include */ 01436 vfile = !*v->file ? config_file : v->file; 01437 01438 if (!strncasecmp(v->name, "same", 4)) { 01439 if (ast_strlen_zero(lastextension)) { 01440 ast_log(LOG_ERROR, 01441 "No previous pattern in the first entry of context '%s' to match '%s' at line %d of %s!\n", 01442 cxt, v->name, v->lineno, vfile); 01443 continue; 01444 } 01445 if ((stringp = tc = ast_strdup(v->value))) { 01446 ast_copy_string(realext, lastextension, sizeof(realext)); 01447 goto process_extension; 01448 } 01449 } else if (!strcasecmp(v->name, "exten")) { 01450 int ipri; 01451 char *plus, *firstp; 01452 char *pri, *appl, *data, *cidmatch; 01453 01454 if (!(stringp = tc = ast_strdup(v->value))) { 01455 continue; 01456 } 01457 01458 ext = S_OR(pbx_strsep(&stringp, ","), ""); 01459 pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1); 01460 ast_copy_string(lastextension, realext, sizeof(lastextension)); 01461 process_extension: 01462 ipri = -2; 01463 if ((cidmatch = strchr(realext, '/'))) { 01464 *cidmatch++ = '\0'; 01465 ast_shrink_phone_number(cidmatch); 01466 } 01467 pri = ast_strip(S_OR(strsep(&stringp, ","), "")); 01468 if ((label = strchr(pri, '('))) { 01469 *label++ = '\0'; 01470 if ((end = strchr(label, ')'))) { 01471 *end = '\0'; 01472 } else { 01473 ast_log(LOG_WARNING, 01474 "Label missing trailing ')' at line %d of %s\n", 01475 v->lineno, vfile); 01476 ast_free(tc); 01477 continue; 01478 } 01479 } 01480 if ((plus = strchr(pri, '+'))) { 01481 *plus++ = '\0'; 01482 } 01483 if (!strcmp(pri,"hint")) { 01484 ipri = PRIORITY_HINT; 01485 } else if (!strcmp(pri, "next") || !strcmp(pri, "n")) { 01486 if (lastpri > -2) { 01487 ipri = lastpri + 1; 01488 } else { 01489 ast_log(LOG_WARNING, 01490 "Can't use 'next' priority on the first entry at line %d of %s!\n", 01491 v->lineno, vfile); 01492 ast_free(tc); 01493 continue; 01494 } 01495 } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) { 01496 if (lastpri > -2) { 01497 ipri = lastpri; 01498 } else { 01499 ast_log(LOG_WARNING, 01500 "Can't use 'same' priority on the first entry at line %d of %s!\n", 01501 v->lineno, vfile); 01502 ast_free(tc); 01503 continue; 01504 } 01505 } else if (sscanf(pri, "%30d", &ipri) != 1 && 01506 (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) { 01507 ast_log(LOG_WARNING, 01508 "Invalid priority/label '%s' at line %d of %s\n", 01509 pri, v->lineno, vfile); 01510 ipri = 0; 01511 ast_free(tc); 01512 continue; 01513 } else if (ipri < 1) { 01514 ast_log(LOG_WARNING, "Invalid priority '%s' at line %d of %s\n", 01515 pri, v->lineno, vfile); 01516 ast_free(tc); 01517 continue; 01518 } 01519 appl = S_OR(stringp, ""); 01520 /* Find the first occurrence of '(' */ 01521 if (!(firstp = strchr(appl, '('))) { 01522 /* No arguments */ 01523 data = ""; 01524 } else { 01525 char *orig_appl = ast_strdup(appl); 01526 01527 if (!orig_appl) { 01528 ast_free(tc); 01529 continue; 01530 } 01531 01532 appl = strsep(&stringp, "("); 01533 01534 /* check if there are variables or expressions without an application, like: exten => 100,hint,DAHDI/g0/${GLOBAL(var)} */ 01535 if (strstr(appl, "${") || strstr(appl, "$[")){ 01536 /* set appl to original one */ 01537 strcpy(appl, orig_appl); 01538 /* set no data */ 01539 data = ""; 01540 /* no variable before application found -> go ahead */ 01541 } else { 01542 data = S_OR(stringp, ""); 01543 if ((end = strrchr(data, ')'))) { 01544 *end = '\0'; 01545 } else { 01546 ast_log(LOG_WARNING, 01547 "No closing parenthesis found? '%s(%s' at line %d of %s\n", 01548 appl, data, v->lineno, vfile); 01549 } 01550 } 01551 ast_free(orig_appl); 01552 } 01553 01554 appl = ast_skip_blanks(appl); 01555 if (ipri) { 01556 if (plus) { 01557 ipri += atoi(plus); 01558 } 01559 lastpri = ipri; 01560 if (!ast_opt_dont_warn && (!strcmp(realext, "_.") || !strcmp(realext, "_!"))) { 01561 ast_log(LOG_WARNING, 01562 "The use of '%s' for an extension is strongly discouraged and can have unexpected behavior. Please use '_X%c' instead at line %d of %s\n", 01563 realext, realext[1], v->lineno, vfile); 01564 } 01565 if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free_ptr, registrar)) { 01566 ast_log(LOG_WARNING, 01567 "Unable to register extension at line %d of %s\n", 01568 v->lineno, vfile); 01569 } 01570 } 01571 free(tc); 01572 } else if (!strcasecmp(v->name, "include")) { 01573 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01574 if (ast_context_add_include2(con, realvalue, registrar)) { 01575 switch (errno) { 01576 case ENOMEM: 01577 ast_log(LOG_WARNING, "Out of memory for context addition\n"); 01578 break; 01579 01580 case EBUSY: 01581 ast_log(LOG_WARNING, "Failed to lock context(s) list, please try again later\n"); 01582 break; 01583 01584 case EEXIST: 01585 ast_log(LOG_WARNING, 01586 "Context '%s' already included in '%s' context on include at line %d of %s\n", 01587 v->value, cxt, v->lineno, vfile); 01588 break; 01589 01590 case ENOENT: 01591 case EINVAL: 01592 ast_log(LOG_WARNING, 01593 "There is no existence of context '%s' included at line %d of %s\n", 01594 errno == ENOENT ? v->value : cxt, v->lineno, vfile); 01595 break; 01596 01597 default: 01598 ast_log(LOG_WARNING, 01599 "Failed to include '%s' in '%s' context at line %d of %s\n", 01600 v->value, cxt, v->lineno, vfile); 01601 break; 01602 } 01603 } 01604 } else if (!strcasecmp(v->name, "ignorepat")) { 01605 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01606 if (ast_context_add_ignorepat2(con, realvalue, registrar)) { 01607 ast_log(LOG_WARNING, 01608 "Unable to include ignorepat '%s' in context '%s' at line %d of %s\n", 01609 v->value, cxt, v->lineno, vfile); 01610 } 01611 } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) { 01612 char *stringp = realvalue; 01613 char *appl, *data; 01614 01615 if (!strcasecmp(v->name, "switch")) { 01616 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01617 } else { 01618 ast_copy_string(realvalue, v->value, sizeof(realvalue)); 01619 } 01620 appl = strsep(&stringp, "/"); 01621 data = S_OR(stringp, ""); 01622 if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar)) { 01623 ast_log(LOG_WARNING, 01624 "Unable to include switch '%s' in context '%s' at line %d of %s\n", 01625 v->value, cxt, v->lineno, vfile); 01626 } 01627 } else { 01628 ast_log(LOG_WARNING, 01629 "==!!== Unknown directive: %s at line %d of %s -- IGNORING!!!\n", 01630 v->name, v->lineno, vfile); 01631 } 01632 } 01633 } 01634 ast_config_destroy(cfg); 01635 return 1; 01636 }
static int pbx_load_module | ( | void | ) | [static] |
Definition at line 1754 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().
01755 { 01756 struct ast_context *con; 01757 01758 if (!local_table) 01759 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); 01760 01761 if (!pbx_load_config(config)) 01762 return AST_MODULE_LOAD_DECLINE; 01763 01764 pbx_load_users(); 01765 01766 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar); 01767 local_table = NULL; /* the local table has been moved into the global one. */ 01768 local_contexts = NULL; 01769 01770 for (con = NULL; (con = ast_walk_contexts(con));) 01771 ast_context_verify_includes(con); 01772 01773 pbx_set_overrideswitch(overrideswitch_config); 01774 pbx_set_autofallthrough(autofallthrough_config); 01775 pbx_set_extenpatternmatchnew(extenpatternmatchnew_config); 01776 01777 return AST_MODULE_LOAD_SUCCESS; 01778 }
static void pbx_load_users | ( | void | ) | [static] |
Definition at line 1650 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, local_contexts, local_table, LOG_ERROR, strdup, and strsep().
Referenced by pbx_load_module().
01651 { 01652 struct ast_config *cfg; 01653 char *cat, *chan; 01654 const char *dahdichan; 01655 const char *hasexten, *altexts; 01656 char tmp[256]; 01657 char iface[256]; 01658 char dahdicopy[256]; 01659 char *ext, altcopy[256]; 01660 char *c; 01661 int hasvoicemail; 01662 int start, finish, x; 01663 struct ast_context *con = NULL; 01664 struct ast_flags config_flags = { 0 }; 01665 01666 cfg = ast_config_load("users.conf", config_flags); 01667 if (!cfg) 01668 return; 01669 01670 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 01671 if (!strcasecmp(cat, "general")) 01672 continue; 01673 iface[0] = '\0'; 01674 if (ast_true(ast_config_option(cfg, cat, "hassip"))) { 01675 snprintf(tmp, sizeof(tmp), "SIP/%s", cat); 01676 append_interface(iface, sizeof(iface), tmp); 01677 } 01678 if (ast_true(ast_config_option(cfg, cat, "hasiax"))) { 01679 snprintf(tmp, sizeof(tmp), "IAX2/%s", cat); 01680 append_interface(iface, sizeof(iface), tmp); 01681 } 01682 if (ast_true(ast_config_option(cfg, cat, "hash323"))) { 01683 snprintf(tmp, sizeof(tmp), "H323/%s", cat); 01684 append_interface(iface, sizeof(iface), tmp); 01685 } 01686 hasexten = ast_config_option(cfg, cat, "hasexten"); 01687 if (hasexten && !ast_true(hasexten)) 01688 continue; 01689 hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail")); 01690 dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan"); 01691 if (!dahdichan) 01692 dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan"); 01693 if (!ast_strlen_zero(dahdichan)) { 01694 ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy)); 01695 c = dahdicopy; 01696 chan = strsep(&c, ","); 01697 while (chan) { 01698 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) { 01699 /* Range */ 01700 } else if (sscanf(chan, "%30d", &start)) { 01701 /* Just one */ 01702 finish = start; 01703 } else { 01704 start = 0; finish = 0; 01705 } 01706 if (finish < start) { 01707 x = finish; 01708 finish = start; 01709 start = x; 01710 } 01711 for (x = start; x <= finish; x++) { 01712 snprintf(tmp, sizeof(tmp), "DAHDI/%d", x); 01713 append_interface(iface, sizeof(iface), tmp); 01714 } 01715 chan = strsep(&c, ","); 01716 } 01717 } 01718 if (!ast_strlen_zero(iface)) { 01719 /* Only create a context here when it is really needed. Otherwise default empty context 01720 created by pbx_config may conflict with the one explicitly created by pbx_ael */ 01721 if (!con) 01722 con = ast_context_find_or_create(&local_contexts, local_table, userscontext, registrar); 01723 01724 if (!con) { 01725 ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext); 01726 return; 01727 } 01728 01729 /* Add hint */ 01730 ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar); 01731 /* If voicemail, use "stdexten" else use plain old dial */ 01732 if (hasvoicemail) { 01733 snprintf(tmp, sizeof(tmp), "stdexten,%s,${HINT}", cat); 01734 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", strdup(tmp), ast_free_ptr, registrar); 01735 } else { 01736 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", strdup("${HINT}"), ast_free_ptr, registrar); 01737 } 01738 altexts = ast_variable_retrieve(cfg, cat, "alternateexts"); 01739 if (!ast_strlen_zero(altexts)) { 01740 snprintf(tmp, sizeof(tmp), "%s,1", cat); 01741 ast_copy_string(altcopy, altexts, sizeof(altcopy)); 01742 c = altcopy; 01743 ext = strsep(&c, ","); 01744 while (ext) { 01745 ast_add_extension2(con, 0, ext, 1, NULL, NULL, "Goto", strdup(tmp), ast_free_ptr, registrar); 01746 ext = strsep(&c, ","); 01747 } 01748 } 01749 } 01750 } 01751 ast_config_destroy(cfg); 01752 }
static char* pbx_strsep | ( | char ** | destructible, | |
const char * | delim | |||
) | [static] |
Definition at line 1342 of file pbx_config.c.
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 1792 of file pbx_config.c.
References pbx_builtin_clear_globals(), and pbx_load_module().
01793 { 01794 if (clearglobalvars_config) 01795 pbx_builtin_clear_globals(); 01796 return pbx_load_module(); 01797 }
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 133 of file pbx_config.c.
Referenced by complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), and complete_dialplan_remove_include().
00134 { 00135 int in_blank = 0; 00136 for (;n && *p; p++) { 00137 if (isblank(*p) /* XXX order is important */ && !in_blank) { 00138 n--; /* one word is gone */ 00139 in_blank = 1; 00140 } else if (/* !is_blank(*p), we know already, && */ in_blank) { 00141 in_blank = 0; 00142 } 00143 } 00144 return p; 00145 }
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 156 of file pbx_config.c.
References ast_strdup, and free.
Referenced by complete_dialplan_remove_extension(), and handle_cli_dialplan_remove_extension().
00157 { 00158 char *i, *c, *e = ast_strdup(src); /* now src is not used anymore */ 00159 00160 if (e == NULL) 00161 return -1; /* malloc error */ 00162 /* now, parse values from 'exten@context' */ 00163 *ext = e; 00164 c = strchr(e, '@'); 00165 if (c == NULL) /* no context part */ 00166 *ctx = ""; /* it is not overwritten, anyways */ 00167 else { /* found context, check for duplicity ... */ 00168 *c++ = '\0'; 00169 *ctx = c; 00170 if (strchr(c, '@')) { /* two @, not allowed */ 00171 free(e); 00172 return -1; 00173 } 00174 } 00175 if (cid && (i = strchr(e, '/'))) { 00176 *i++ = '\0'; 00177 *cid = i; 00178 } else if (cid) { 00179 /* Signal none detected */ 00180 *cid = NULL; 00181 } 00182 return 0; 00183 }
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(), ast_free, cli_dialplan_save, and cli_pbx_config.
01326 { 01327 if (static_config && !write_protect_config) 01328 ast_cli_unregister(&cli_dialplan_save); 01329 if (overrideswitch_config) { 01330 ast_free(overrideswitch_config); 01331 } 01332 ast_cli_unregister_multiple(cli_pbx_config, 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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1803 of file pbx_config.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1803 of file pbx_config.c.
int autofallthrough_config = 1 [static] |
Definition at line 51 of file pbx_config.c.
int clearglobalvars_config = 0 [static] |
Definition at line 52 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 1319 of file pbx_config.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_pbx_config[] [static] |
CLI entries for commands provided by this module
Definition at line 1308 of file pbx_config.c.
Referenced by load_module(), and unload_module().
const char config[] = "extensions.conf" [static] |
Definition at line 45 of file pbx_config.c.
int extenpatternmatchnew_config = 0 [static] |
Definition at line 53 of file pbx_config.c.
struct ast_context* local_contexts = NULL [static] |
Definition at line 58 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 59 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 54 of file pbx_config.c.
const char registrar[] = "pbx_config" [static] |
Definition at line 46 of file pbx_config.c.
ast_mutex_t save_dialplan_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
int static_config = 0 [static] |
Definition at line 49 of file pbx_config.c.
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 47 of file pbx_config.c.
int write_protect_config = 1 [static] |
Definition at line 50 of file pbx_config.c.