Populate and remember extensions from static config file. More...
#include "asterisk.h"
#include <ctype.h>
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
Go to the source code of this file.
Defines | |
#define | PUT_CTX_HDR |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static void | append_interface (char *iface, int maxlen, char *add) |
static char * | complete_dialplan_add_extension (struct ast_cli_args *) |
static char * | complete_dialplan_add_ignorepat (struct ast_cli_args *) |
static char * | complete_dialplan_add_include (struct ast_cli_args *) |
static char * | complete_dialplan_remove_extension (struct ast_cli_args *) |
static char * | complete_dialplan_remove_ignorepat (struct ast_cli_args *) |
static char * | complete_dialplan_remove_include (struct ast_cli_args *) |
static char * | handle_cli_dialplan_add_extension (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
ADD EXTENSION command stuff. | |
static char * | handle_cli_dialplan_add_ignorepat (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_add_include (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_remove_extension (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_remove_ignorepat (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_remove_include (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_dialplan_save (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
'save dialplan' CLI command implementation functions ... | |
static int | load_module (void) |
static int | lookup_c_ip (struct ast_context *c, const char *name) |
return true if 'name' is in the ignorepats for context c | |
static int | lookup_ci (struct ast_context *c, const char *name) |
return true if 'name' is included by context c | |
static int | partial_match (const char *s, const char *word, int len) |
match the first 'len' chars of word. len==0 always succeeds | |
static int | pbx_load_config (const char *config_file) |
static int | pbx_load_module (void) |
static void | pbx_load_users (void) |
static char * | pbx_strsep (char **destructible, const char *delim) |
static int | reload (void) |
static const char * | skip_words (const char *p, int n) |
moves to the n-th word in the string, or empty string if none | |
static int | split_ec (const char *src, char **ext, char **const ctx, char **const cid) |
split extension@context in two parts, return -1 on error. The return string is malloc'ed and pointed by *ext | |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Text Extension Configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .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 | reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
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 |
Populate and remember extensions from static config file.
Definition in file pbx_config.c.
#define PUT_CTX_HDR |
Referenced by handle_cli_dialplan_save().
static void __reg_module | ( | void | ) | [static] |
Definition at line 1826 of file pbx_config.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1826 of file pbx_config.c.
static void append_interface | ( | char * | iface, | |
int | maxlen, | |||
char * | add | |||
) | [static] |
Definition at line 1655 of file pbx_config.c.
References len().
Referenced by pbx_load_users().
01656 { 01657 int len = strlen(iface); 01658 if (strlen(add) + len < maxlen - 2) { 01659 if (strlen(iface)) { 01660 iface[len] = '&'; 01661 strcpy(iface + len + 1, add); 01662 } else 01663 strcpy(iface, add); 01664 } 01665 }
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 1026 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().
01027 { 01028 int which = 0; 01029 01030 if (a->pos == 4) { /* complete 'into' word ... */ 01031 return (a->n == 0) ? strdup("into") : NULL; 01032 } else if (a->pos == 5) { /* complete context */ 01033 struct ast_context *c = NULL; 01034 int len = strlen(a->word); 01035 char *res = NULL; 01036 01037 /* try to lock contexts list ... */ 01038 if (ast_rdlock_contexts()) { 01039 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01040 return NULL; 01041 } 01042 01043 /* walk through all contexts */ 01044 while ( !res && (c = ast_walk_contexts(c)) ) 01045 if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n) 01046 res = strdup(ast_get_context_name(c)); 01047 ast_unlock_contexts(); 01048 return res; 01049 } else if (a->pos == 6) { 01050 return a->n == 0 ? strdup("replace") : NULL; 01051 } 01052 return NULL; 01053 }
static char * complete_dialplan_add_ignorepat | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 1112 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, and ast_cli_args::word.
Referenced by handle_cli_dialplan_add_ignorepat().
01113 { 01114 if (a->pos == 4) 01115 return a->n == 0 ? strdup("into") : NULL; 01116 else if (a->pos == 5) { 01117 struct ast_context *c; 01118 int which = 0; 01119 char *dupline, *ignorepat = NULL; 01120 const char *s; 01121 char *ret = NULL; 01122 int len = strlen(a->word); 01123 01124 /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */ 01125 s = skip_words(a->line, 3); 01126 if (s == NULL) 01127 return NULL; 01128 dupline = strdup(s); 01129 if (!dupline) { 01130 ast_log(LOG_ERROR, "Malloc failure\n"); 01131 return NULL; 01132 } 01133 ignorepat = strsep(&dupline, " "); 01134 01135 if (ast_rdlock_contexts()) { 01136 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 01137 return NULL; 01138 } 01139 01140 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01141 int found = 0; 01142 01143 if (!partial_match(ast_get_context_name(c), a->word, len)) 01144 continue; /* not mine */ 01145 if (ignorepat) /* there must be one, right ? */ 01146 found = lookup_c_ip(c, ignorepat); 01147 if (!found && ++which > a->n) 01148 ret = strdup(ast_get_context_name(c)); 01149 } 01150 01151 free(ignorepat); 01152 ast_unlock_contexts(); 01153 return ret; 01154 } 01155 01156 return NULL; 01157 }
static char * complete_dialplan_add_include | ( | struct ast_cli_args * | a | ) | [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, 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 * | a | ) | [static] |
Definition at line 398 of file pbx_config.c.
References ast_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, exten, free, len(), ast_cli_args::line, LOG_ERROR, 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().
00399 { 00400 char *ret = NULL; 00401 int which = 0; 00402 00403 if (a->pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */ 00404 struct ast_context *c = NULL; 00405 char *context = NULL, *exten = NULL, *cid = NULL; 00406 int le = 0; /* length of extension */ 00407 int lc = 0; /* length of context */ 00408 int lcid = 0; /* length of cid */ 00409 00410 lc = split_ec(a->word, &exten, &context, &cid); 00411 if (lc) { /* error */ 00412 return NULL; 00413 } 00414 le = strlen(exten); 00415 lc = strlen(context); 00416 lcid = cid ? strlen(cid) : -1; 00417 00418 if (ast_rdlock_contexts()) { 00419 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00420 goto error2; 00421 } 00422 00423 /* find our context ... */ 00424 while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */ 00425 struct ast_exten *e = NULL; 00426 /* XXX locking ? */ 00427 if (!partial_match(ast_get_context_name(c), context, lc)) 00428 continue; /* context not matched */ 00429 while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */ 00430 if ( !strchr(a->word, '/') || 00431 (!strchr(a->word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) || 00432 (strchr(a->word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) { 00433 if ( ((strchr(a->word, '/') || strchr(a->word, '@')) && !strcmp(ast_get_extension_name(e), exten)) || 00434 (!strchr(a->word, '/') && !strchr(a->word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */ 00435 if (++which > a->n) { 00436 /* If there is an extension then return exten@context. */ 00437 if (ast_get_extension_matchcid(e) && (!strchr(a->word, '@') || strchr(a->word, '/'))) { 00438 if (ast_asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)) < 0) { 00439 ret = NULL; 00440 } 00441 break; 00442 } else if (!ast_get_extension_matchcid(e) && !strchr(a->word, '/')) { 00443 if (ast_asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) { 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 * | a | ) | [static] |
Definition at line 1208 of file pbx_config.c.
References ast_get_context_name(), ast_get_ignorepat_name(), ast_log(), ast_rdlock_context(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_ignorepats(), ast_walk_contexts(), free, len(), ast_cli_args::line, LOG_WARNING, lookup_c_ip(), ast_cli_args::n, partial_match(), ast_cli_args::pos, strdup, and ast_cli_args::word.
Referenced by handle_cli_dialplan_remove_ignorepat().
01209 { 01210 struct ast_context *c; 01211 int which = 0; 01212 char *ret = NULL; 01213 01214 if (a->pos == 3) { 01215 int len = strlen(a->word); 01216 if (ast_rdlock_contexts()) { 01217 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01218 return NULL; 01219 } 01220 01221 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01222 struct ast_ignorepat *ip; 01223 01224 if (ast_rdlock_context(c)) /* error, skip it */ 01225 continue; 01226 01227 for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) { 01228 if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) { 01229 /* n-th match */ 01230 struct ast_context *cw = NULL; 01231 int found = 0; 01232 while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) { 01233 /* XXX do i stop on c, or skip it ? */ 01234 found = lookup_c_ip(cw, ast_get_ignorepat_name(ip)); 01235 } 01236 if (!found) 01237 ret = strdup(ast_get_ignorepat_name(ip)); 01238 } 01239 } 01240 ast_unlock_context(c); 01241 } 01242 ast_unlock_contexts(); 01243 return ret; 01244 } else if (a->pos == 4) { 01245 return a->n == 0 ? strdup("from") : NULL; 01246 } else if (a->pos == 5) { /* XXX check this */ 01247 char *dupline, *duplinet, *ignorepat; 01248 int len = strlen(a->word); 01249 01250 dupline = strdup(a->line); 01251 if (!dupline) { 01252 ast_log(LOG_WARNING, "Out of free memory\n"); 01253 return NULL; 01254 } 01255 01256 duplinet = dupline; 01257 strsep(&duplinet, " "); 01258 strsep(&duplinet, " "); 01259 ignorepat = strsep(&duplinet, " "); 01260 01261 if (!ignorepat) { 01262 free(dupline); 01263 return NULL; 01264 } 01265 01266 if (ast_rdlock_contexts()) { 01267 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01268 free(dupline); 01269 return NULL; 01270 } 01271 01272 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 01273 if (ast_rdlock_context(c)) /* fail, skip it */ 01274 continue; 01275 if (!partial_match(ast_get_context_name(c), a->word, len)) 01276 continue; 01277 if (lookup_c_ip(c, ignorepat) && ++which > a->n) 01278 ret = strdup(ast_get_context_name(c)); 01279 ast_unlock_context(c); 01280 } 01281 ast_unlock_contexts(); 01282 free(dupline); 01283 return NULL; 01284 } 01285 01286 return NULL; 01287 }
static char * complete_dialplan_remove_include | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 188 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, and ast_cli_args::word.
Referenced by handle_cli_dialplan_remove_include().
00189 { 00190 int which = 0; 00191 char *res = NULL; 00192 int len = strlen(a->word); /* how many bytes to match */ 00193 struct ast_context *c = NULL; 00194 00195 if (a->pos == 3) { /* "dialplan remove include _X_" */ 00196 if (ast_wrlock_contexts()) { 00197 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00198 return NULL; 00199 } 00200 /* walk contexts and their includes, return the n-th match */ 00201 while (!res && (c = ast_walk_contexts(c))) { 00202 struct ast_include *i = NULL; 00203 00204 if (ast_rdlock_context(c)) /* error ? skip this one */ 00205 continue; 00206 00207 while ( !res && (i = ast_walk_context_includes(c, i)) ) { 00208 const char *i_name = ast_get_include_name(i); 00209 struct ast_context *nc = NULL; 00210 int already_served = 0; 00211 00212 if (!partial_match(i_name, a->word, len)) 00213 continue; /* not matched */ 00214 00215 /* check if this include is already served or not */ 00216 00217 /* go through all contexts again till we reach actual 00218 * context or already_served = 1 00219 */ 00220 while ( (nc = ast_walk_contexts(nc)) && nc != c && !already_served) 00221 already_served = lookup_ci(nc, i_name); 00222 00223 if (!already_served && ++which > a->n) 00224 res = strdup(i_name); 00225 } 00226 ast_unlock_context(c); 00227 } 00228 00229 ast_unlock_contexts(); 00230 return res; 00231 } else if (a->pos == 4) { /* "dialplan remove include CTX _X_" */ 00232 /* 00233 * complete as 'from', but only if previous context is really 00234 * included somewhere 00235 */ 00236 char *context, *dupline; 00237 const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */ 00238 00239 if (a->n > 0) 00240 return NULL; 00241 context = dupline = strdup(s); 00242 if (!dupline) { 00243 ast_log(LOG_ERROR, "Out of free memory\n"); 00244 return NULL; 00245 } 00246 strsep(&dupline, " "); 00247 00248 if (ast_rdlock_contexts()) { 00249 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 00250 free(context); 00251 return NULL; 00252 } 00253 00254 /* go through all contexts and check if is included ... */ 00255 while (!res && (c = ast_walk_contexts(c))) 00256 if (lookup_ci(c, context)) /* context is really included, complete "from" command */ 00257 res = strdup("from"); 00258 ast_unlock_contexts(); 00259 if (!res) 00260 ast_log(LOG_WARNING, "%s not included anywhere\n", context); 00261 free(context); 00262 return res; 00263 } else if (a->pos == 5) { /* "dialplan remove include CTX from _X_" */ 00264 /* 00265 * Context from which we removing include ... 00266 */ 00267 char *context, *dupline, *from; 00268 const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */ 00269 context = dupline = strdup(s); 00270 if (!dupline) { 00271 ast_log(LOG_ERROR, "Out of free memory\n"); 00272 return NULL; 00273 } 00274 00275 strsep(&dupline, " "); /* skip context */ 00276 00277 /* fourth word must be 'from' */ 00278 from = strsep(&dupline, " "); 00279 if (!from || strcmp(from, "from")) { 00280 free(context); 00281 return NULL; 00282 } 00283 00284 if (ast_rdlock_contexts()) { 00285 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00286 free(context); 00287 return NULL; 00288 } 00289 00290 /* walk through all contexts ... */ 00291 c = NULL; 00292 while ( !res && (c = ast_walk_contexts(c))) { 00293 const char *c_name = ast_get_context_name(c); 00294 if (!partial_match(c_name, a->word, len)) /* not a good target */ 00295 continue; 00296 /* walk through all includes and check if it is our context */ 00297 if (lookup_ci(c, context) && ++which > a->n) 00298 res = strdup(c_name); 00299 } 00300 ast_unlock_contexts(); 00301 free(context); 00302 return res; 00303 } 00304 00305 return NULL; 00306 }
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 907 of file pbx_config.c.
References app, ast_cli_args::argc, ast_cli_args::argv, ast_add_extension(), ast_cli(), ast_free_ptr(), ast_strdup, ast_strdupa, ast_exten::cidmatch, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_extension(), errno, exten, ast_cli_args::fd, PRIORITY_HINT, and ast_cli_entry::usage.
00908 { 00909 char *whole_exten; 00910 char *exten, *prior; 00911 int iprior = -2; 00912 char *cidmatch, *app, *app_data; 00913 char *start, *end; 00914 00915 switch (cmd) { 00916 case CLI_INIT: 00917 e->command = "dialplan add extension"; 00918 e->usage = 00919 "Usage: dialplan add extension <exten>,<priority>,<app> into <context> [replace]\n" 00920 "\n" 00921 " app can be either:\n" 00922 " app-name\n" 00923 " app-name(app-data)\n" 00924 " app-name,<app-data>\n" 00925 "\n" 00926 " This command will add the new extension into <context>. If\n" 00927 " an extension with the same priority already exists and the\n" 00928 " 'replace' option is given we will replace the extension.\n" 00929 "\n" 00930 "Example: dialplan add extension 6123,1,Dial,IAX/216.207.245.56/6123 into local\n" 00931 " Now, you can dial 6123 and talk to Markster :)\n"; 00932 return NULL; 00933 case CLI_GENERATE: 00934 return complete_dialplan_add_extension(a); 00935 } 00936 00937 /* check for arguments at first */ 00938 if (a->argc != 6 && a->argc != 7) 00939 return CLI_SHOWUSAGE; 00940 if (strcmp(a->argv[4], "into")) 00941 return CLI_SHOWUSAGE; 00942 if (a->argc == 7) 00943 if (strcmp(a->argv[6], "replace")) 00944 return CLI_SHOWUSAGE; 00945 00946 whole_exten = ast_strdupa(a->argv[3]); 00947 exten = strsep(&whole_exten,","); 00948 if (strchr(exten, '/')) { 00949 cidmatch = exten; 00950 strsep(&cidmatch,"/"); 00951 } else { 00952 cidmatch = NULL; 00953 } 00954 prior = strsep(&whole_exten,","); 00955 if (prior) { 00956 if (!strcmp(prior, "hint")) { 00957 iprior = PRIORITY_HINT; 00958 } else { 00959 if (sscanf(prior, "%30d", &iprior) != 1) { 00960 ast_cli(a->fd, "'%s' is not a valid priority\n", prior); 00961 prior = NULL; 00962 } 00963 } 00964 } 00965 app = whole_exten; 00966 if (app) { 00967 if ((start = strchr(app, '(')) && (end = strrchr(app, ')'))) { 00968 *start = *end = '\0'; 00969 app_data = start + 1; 00970 } else { 00971 app_data = strchr(app, ','); 00972 if (app_data) { 00973 *app_data++ = '\0'; 00974 } 00975 } 00976 } else { 00977 app_data = NULL; 00978 } 00979 00980 if (!exten || !prior || !app) { 00981 return CLI_SHOWUSAGE; 00982 } 00983 00984 if (!app_data) 00985 app_data=""; 00986 if (ast_add_extension(a->argv[5], a->argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app, 00987 ast_strdup(app_data), ast_free_ptr, registrar)) { 00988 switch (errno) { 00989 case ENOMEM: 00990 ast_cli(a->fd, "Out of free memory\n"); 00991 break; 00992 00993 case EBUSY: 00994 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 00995 break; 00996 00997 case ENOENT: 00998 ast_cli(a->fd, "No existence of '%s' context\n", a->argv[5]); 00999 break; 01000 01001 case EEXIST: 01002 ast_cli(a->fd, "Extension %s@%s with priority %s already exists\n", 01003 exten, a->argv[5], prior); 01004 break; 01005 01006 default: 01007 ast_cli(a->fd, "Failed to add '%s,%s,%s(%s)' extension into '%s' context\n", 01008 exten, prior, app, app_data, a->argv[5]); 01009 break; 01010 } 01011 return CLI_FAILURE; 01012 } 01013 01014 if (a->argc == 7) { 01015 ast_cli(a->fd, "Extension %s@%s (%s) replace by '%s,%s,%s(%s)'\n", 01016 exten, a->argv[5], prior, exten, prior, app, app_data); 01017 } else { 01018 ast_cli(a->fd, "Extension '%s,%s,%s(%s)' added into '%s' context\n", 01019 exten, prior, app, app_data, a->argv[5]); 01020 } 01021 01022 return CLI_SUCCESS; 01023 }
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 1058 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.
01059 { 01060 switch (cmd) { 01061 case CLI_INIT: 01062 e->command = "dialplan add ignorepat"; 01063 e->usage = 01064 "Usage: dialplan add ignorepat <pattern> into <context>\n" 01065 " This command adds a new ignore pattern into context <context>\n" 01066 "\n" 01067 "Example: dialplan add ignorepat _3XX into local\n"; 01068 return NULL; 01069 case CLI_GENERATE: 01070 return complete_dialplan_add_ignorepat(a); 01071 } 01072 01073 if (a->argc != 6) 01074 return CLI_SHOWUSAGE; 01075 01076 if (strcmp(a->argv[4], "into")) 01077 return CLI_SHOWUSAGE; 01078 01079 if (ast_context_add_ignorepat(a->argv[5], a->argv[3], registrar)) { 01080 switch (errno) { 01081 case ENOMEM: 01082 ast_cli(a->fd, "Out of free memory\n"); 01083 break; 01084 01085 case ENOENT: 01086 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01087 break; 01088 01089 case EEXIST: 01090 ast_cli(a->fd, "Ignore pattern '%s' already included in '%s' context\n", 01091 a->argv[3], a->argv[5]); 01092 break; 01093 01094 case EBUSY: 01095 ast_cli(a->fd, "Failed to lock context(s) list, please, try again later\n"); 01096 break; 01097 01098 default: 01099 ast_cli(a->fd, "Failed to add ingore pattern '%s' into '%s' context\n", 01100 a->argv[3], a->argv[5]); 01101 break; 01102 } 01103 return CLI_FAILURE; 01104 } 01105 01106 ast_cli(a->fd, "Ignore pattern '%s' added into '%s' context\n", 01107 a->argv[3], a->argv[5]); 01108 01109 return CLI_SUCCESS; 01110 }
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 1291 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.
01292 { 01293 switch (cmd) { 01294 case CLI_INIT: 01295 e->command = "dialplan reload"; 01296 e->usage = 01297 "Usage: dialplan reload\n" 01298 " Reload extensions.conf without reloading any other\n" 01299 " modules. This command does not delete global variables\n" 01300 " unless clearglobalvars is set to yes in extensions.conf\n"; 01301 return NULL; 01302 case CLI_GENERATE: 01303 return NULL; 01304 } 01305 01306 if (a->argc != 2) 01307 return CLI_SHOWUSAGE; 01308 01309 if (clearglobalvars_config) 01310 pbx_builtin_clear_globals(); 01311 01312 pbx_load_module(); 01313 ast_cli(a->fd, "Dialplan reloaded.\n"); 01314 return CLI_SUCCESS; 01315 }
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 311 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.
00312 { 00313 int removing_priority = 0; 00314 char *exten, *context, *cid; 00315 char *ret = CLI_FAILURE; 00316 00317 switch (cmd) { 00318 case CLI_INIT: 00319 e->command = "dialplan remove extension"; 00320 e->usage = 00321 "Usage: dialplan remove extension exten[/cid]@context [priority]\n" 00322 " Remove an extension from a given context. If a priority\n" 00323 " is given, only that specific priority from the given extension\n" 00324 " will be removed.\n"; 00325 return NULL; 00326 case CLI_GENERATE: 00327 return complete_dialplan_remove_extension(a); 00328 } 00329 00330 if (a->argc != 5 && a->argc != 4) 00331 return CLI_SHOWUSAGE; 00332 00333 /* 00334 * Priority input checking ... 00335 */ 00336 if (a->argc == 5) { 00337 const char *c = a->argv[4]; 00338 00339 /* check for digits in whole parameter for right priority ... 00340 * why? because atoi (strtol) returns 0 if any characters in 00341 * string and whole extension will be removed, it's not good 00342 */ 00343 if (!strcmp("hint", c)) 00344 removing_priority = PRIORITY_HINT; 00345 else { 00346 while (*c && isdigit(*c)) 00347 c++; 00348 if (*c) { /* non-digit in string */ 00349 ast_cli(a->fd, "Invalid priority '%s'\n", a->argv[4]); 00350 return CLI_FAILURE; 00351 } 00352 removing_priority = atoi(a->argv[4]); 00353 } 00354 00355 if (removing_priority == 0) { 00356 ast_cli(a->fd, "If you want to remove whole extension, please " \ 00357 "omit priority argument\n"); 00358 return CLI_FAILURE; 00359 } 00360 } 00361 00362 /* XXX original overwrote argv[3] */ 00363 /* 00364 * Format exten@context checking ... 00365 */ 00366 if (split_ec(a->argv[3], &exten, &context, &cid)) 00367 return CLI_FAILURE; /* XXX malloc failure */ 00368 if ((!strlen(exten)) || (!(strlen(context)))) { 00369 ast_cli(a->fd, "Missing extension or context name in third argument '%s'\n", 00370 a->argv[3]); 00371 free(exten); 00372 return CLI_FAILURE; 00373 } 00374 00375 if (!ast_context_remove_extension_callerid(context, exten, removing_priority, 00376 /* Do NOT substitute S_OR; it is NOT the same thing */ 00377 cid ? cid : (removing_priority ? "" : NULL), cid ? 1 : 0, registrar)) { 00378 if (!removing_priority) 00379 ast_cli(a->fd, "Whole extension %s@%s removed\n", 00380 exten, context); 00381 else 00382 ast_cli(a->fd, "Extension %s@%s with priority %d removed\n", 00383 exten, context, removing_priority); 00384 00385 ret = CLI_SUCCESS; 00386 } else { 00387 if (cid) { 00388 ast_cli(a->fd, "Failed to remove extension %s/%s@%s\n", exten, cid, context); 00389 } else { 00390 ast_cli(a->fd, "Failed to remove extension %s@%s\n", exten, context); 00391 } 00392 ret = CLI_FAILURE; 00393 } 00394 free(exten); 00395 return ret; 00396 }
static char* handle_cli_dialplan_remove_ignorepat | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1159 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.
01160 { 01161 switch (cmd) { 01162 case CLI_INIT: 01163 e->command = "dialplan remove ignorepat"; 01164 e->usage = 01165 "Usage: dialplan remove ignorepat <pattern> from <context>\n" 01166 " This command removes an ignore pattern from context <context>\n" 01167 "\n" 01168 "Example: dialplan remove ignorepat _3XX from local\n"; 01169 return NULL; 01170 case CLI_GENERATE: 01171 return complete_dialplan_remove_ignorepat(a); 01172 } 01173 01174 if (a->argc != 6) 01175 return CLI_SHOWUSAGE; 01176 01177 if (strcmp(a->argv[4], "from")) 01178 return CLI_SHOWUSAGE; 01179 01180 if (ast_context_remove_ignorepat(a->argv[5], a->argv[3], registrar)) { 01181 switch (errno) { 01182 case EBUSY: 01183 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 01184 break; 01185 01186 case ENOENT: 01187 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01188 break; 01189 01190 case EINVAL: 01191 ast_cli(a->fd, "There is no existence of '%s' ignore pattern in '%s' context\n", 01192 a->argv[3], a->argv[5]); 01193 break; 01194 01195 default: 01196 ast_cli(a->fd, "Failed to remove ignore pattern '%s' from '%s' context\n", 01197 a->argv[3], a->argv[5]); 01198 break; 01199 } 01200 return CLI_FAILURE; 01201 } 01202 01203 ast_cli(a->fd, "Ignore pattern '%s' removed from '%s' context\n", 01204 a->argv[3], a->argv[5]); 01205 return CLI_SUCCESS; 01206 }
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 79 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.
00080 { 00081 switch (cmd) { 00082 case CLI_INIT: 00083 e->command = "dialplan remove include"; 00084 e->usage = 00085 "Usage: dialplan remove include <context> from <context>\n" 00086 " Remove an included context from another context.\n"; 00087 return NULL; 00088 case CLI_GENERATE: 00089 return complete_dialplan_remove_include(a); 00090 } 00091 00092 if (a->argc != 6 || strcmp(a->argv[4], "from")) 00093 return CLI_SHOWUSAGE; 00094 00095 if (!ast_context_remove_include(a->argv[5], a->argv[3], registrar)) { 00096 ast_cli(a->fd, "We are not including '%s' into '%s' now\n", 00097 a->argv[3], a->argv[5]); 00098 return CLI_SUCCESS; 00099 } 00100 00101 ast_cli(a->fd, "Failed to remove '%s' include from '%s' context\n", 00102 a->argv[3], a->argv[5]); 00103 return CLI_FAILURE; 00104 }
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, el, ext, ast_cli_args::fd, ast_exten::label, ast_variable::name, ast_variable::next, overrideswitch, PRIORITY_HINT, PUT_CTX_HDR, save_dialplan_lock, ast_cli_entry::usage, and ast_variable::value.
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 if (!cfg) { 00735 ast_cli(a->fd, "Failed to load extensions.conf\n"); 00736 ast_mutex_unlock(&save_dialplan_lock); 00737 return CLI_FAILURE; 00738 } 00739 00740 /* try to lock contexts list */ 00741 if (ast_rdlock_contexts()) { 00742 ast_cli(a->fd, "Failed to lock contexts list\n"); 00743 ast_mutex_unlock(&save_dialplan_lock); 00744 ast_config_destroy(cfg); 00745 return CLI_FAILURE; 00746 } 00747 00748 /* create new file ... */ 00749 if (!(output = fopen(filename, "wt"))) { 00750 ast_cli(a->fd, "Failed to create file '%s'\n", 00751 filename); 00752 ast_unlock_contexts(); 00753 ast_mutex_unlock(&save_dialplan_lock); 00754 ast_config_destroy(cfg); 00755 return CLI_FAILURE; 00756 } 00757 00758 /* fireout general info */ 00759 if (overrideswitch_config) { 00760 snprintf(overrideswitch, sizeof(overrideswitch), "overrideswitch=%s\n", overrideswitch_config); 00761 } 00762 fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\n%sextenpatternmatchnew=%s\n\n", 00763 static_config ? "yes" : "no", 00764 write_protect_config ? "yes" : "no", 00765 autofallthrough_config ? "yes" : "no", 00766 clearglobalvars_config ? "yes" : "no", 00767 overrideswitch_config ? overrideswitch : "", 00768 extenpatternmatchnew_config ? "yes" : "no"); 00769 00770 if ((v = ast_variable_browse(cfg, "globals"))) { 00771 fprintf(output, "[globals]\n"); 00772 while(v) { 00773 fprintf(output, "%s => %s\n", v->name, v->value); 00774 v = v->next; 00775 } 00776 fprintf(output, "\n"); 00777 } 00778 00779 ast_config_destroy(cfg); 00780 00781 #define PUT_CTX_HDR do { \ 00782 if (!context_header_written) { \ 00783 fprintf(output, "[%s]\n", ast_get_context_name(c)); \ 00784 context_header_written = 1; \ 00785 } \ 00786 } while (0) 00787 00788 /* walk all contexts */ 00789 for (c = NULL; (c = ast_walk_contexts(c)); ) { 00790 int context_header_written = 0; 00791 struct ast_exten *ext, *last_written_e = NULL; 00792 struct ast_include *i; 00793 struct ast_ignorepat *ip; 00794 struct ast_sw *sw; 00795 00796 /* try to lock context and fireout all info */ 00797 if (ast_rdlock_context(c)) { /* lock failure */ 00798 incomplete = 1; 00799 continue; 00800 } 00801 /* registered by this module? */ 00802 /* XXX do we need this ? */ 00803 if (!strcmp(ast_get_context_registrar(c), registrar)) { 00804 fprintf(output, "[%s]\n", ast_get_context_name(c)); 00805 context_header_written = 1; 00806 } 00807 00808 /* walk extensions ... */ 00809 for (ext = NULL; (ext = ast_walk_context_extensions(c, ext)); ) { 00810 struct ast_exten *p = NULL; 00811 00812 /* fireout priorities */ 00813 while ( (p = ast_walk_extension_priorities(ext, p)) ) { 00814 if (strcmp(ast_get_extension_registrar(p), registrar) != 0) /* not this source */ 00815 continue; 00816 00817 /* make empty line between different extensions */ 00818 if (last_written_e != NULL && 00819 strcmp(ast_get_extension_name(last_written_e), 00820 ast_get_extension_name(p))) 00821 fprintf(output, "\n"); 00822 last_written_e = p; 00823 00824 PUT_CTX_HDR; 00825 00826 if (ast_get_extension_priority(p) == PRIORITY_HINT) { /* easy */ 00827 fprintf(output, "exten => %s,hint,%s\n", 00828 ast_get_extension_name(p), 00829 ast_get_extension_app(p)); 00830 } else { 00831 const char *sep, *cid; 00832 const char *el = ast_get_extension_label(p); 00833 char label[128] = ""; 00834 00835 if (ast_get_extension_matchcid(p)) { 00836 sep = "/"; 00837 cid = ast_get_extension_cidmatch(p); 00838 } else 00839 sep = cid = ""; 00840 00841 if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2))) 00842 incomplete = 1; /* error encountered or label > 125 chars */ 00843 00844 fprintf(output, "exten => %s%s%s,%d%s,%s(%s)\n", 00845 ast_get_extension_name(p), (ast_strlen_zero(sep) ? "" : sep), (ast_strlen_zero(cid) ? "" : cid), 00846 ast_get_extension_priority(p), label, 00847 ast_get_extension_app(p), (ast_strlen_zero(ast_get_extension_app_data(p)) ? "" : (const char *)ast_get_extension_app_data(p))); 00848 } 00849 } 00850 } 00851 00852 /* written any extensions? ok, write space between exten & inc */ 00853 if (last_written_e) 00854 fprintf(output, "\n"); 00855 00856 /* walk through includes */ 00857 for (i = NULL; (i = ast_walk_context_includes(c, i)) ; ) { 00858 if (strcmp(ast_get_include_registrar(i), registrar) != 0) 00859 continue; /* not mine */ 00860 PUT_CTX_HDR; 00861 fprintf(output, "include => %s\n", ast_get_include_name(i)); 00862 } 00863 if (ast_walk_context_includes(c, NULL)) 00864 fprintf(output, "\n"); 00865 00866 /* walk through switches */ 00867 for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) { 00868 if (strcmp(ast_get_switch_registrar(sw), registrar) != 0) 00869 continue; /* not mine */ 00870 PUT_CTX_HDR; 00871 fprintf(output, "switch => %s/%s\n", 00872 ast_get_switch_name(sw), ast_get_switch_data(sw)); 00873 } 00874 00875 if (ast_walk_context_switches(c, NULL)) 00876 fprintf(output, "\n"); 00877 00878 /* fireout ignorepats ... */ 00879 for (ip = NULL; (ip = ast_walk_context_ignorepats(c, ip)); ) { 00880 if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0) 00881 continue; /* not mine */ 00882 PUT_CTX_HDR; 00883 fprintf(output, "ignorepat => %s\n", 00884 ast_get_ignorepat_name(ip)); 00885 } 00886 00887 ast_unlock_context(c); 00888 } 00889 00890 ast_unlock_contexts(); 00891 ast_mutex_unlock(&save_dialplan_lock); 00892 fclose(output); 00893 00894 if (incomplete) { 00895 ast_cli(a->fd, "Saved dialplan is incomplete\n"); 00896 return CLI_FAILURE; 00897 } 00898 00899 ast_cli(a->fd, "Dialplan successfully saved into '%s'\n", 00900 filename); 00901 return CLI_SUCCESS; 00902 }
static int load_module | ( | void | ) | [static] |
Definition at line 1803 of file pbx_config.c.
References ARRAY_LEN, ast_cli_register(), ast_cli_register_multiple(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and pbx_load_module().
01804 { 01805 if (static_config && !write_protect_config) 01806 ast_cli_register(&cli_dialplan_save); 01807 ast_cli_register_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config)); 01808 01809 if (pbx_load_module()) 01810 return AST_MODULE_LOAD_DECLINE; 01811 01812 return AST_MODULE_LOAD_SUCCESS; 01813 }
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 121 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().
00122 { 00123 struct ast_ignorepat *ip = NULL; 00124 00125 if (ast_rdlock_context(c)) /* error, skip */ 00126 return 0; 00127 while ( (ip = ast_walk_context_ignorepats(c, ip)) ) 00128 if (!strcmp(name, ast_get_ignorepat_name(ip))) 00129 break; 00130 ast_unlock_context(c); 00131 return ip ? -1 /* success */ : 0; 00132 }
static int lookup_ci | ( | struct ast_context * | c, | |
const char * | name | |||
) | [static] |
return true if 'name' is included by context c
Definition at line 107 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().
00108 { 00109 struct ast_include *i = NULL; 00110 00111 if (ast_rdlock_context(c)) /* error, skip */ 00112 return 0; 00113 while ( (i = ast_walk_context_includes(c, i)) ) 00114 if (!strcmp(name, ast_get_include_name(i))) 00115 break; 00116 ast_unlock_context(c); 00117 return i ? -1 /* success */ : 0; 00118 }
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 150 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 1384 of file pbx_config.c.
References ast_add_extension2(), ast_category_browse(), ast_config_destroy(), ast_config_load, ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_find_or_create(), ast_copy_string(), ast_findlabel_extension2(), ast_free, ast_free_ptr(), ast_log(), ast_opt_dont_warn, ast_shrink_phone_number(), ast_skip_blanks(), ast_strdup, ast_strip(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), CONFIG_STATUS_FILEINVALID, errno, ext, ast_variable::file, ast_variable::lineno, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), pbx_strsep(), pbx_substitute_variables_helper(), PRIORITY_HINT, S_OR, and ast_variable::value.
Referenced by pbx_load_module().
01385 { 01386 struct ast_config *cfg; 01387 char *end; 01388 char *label; 01389 #ifdef LOW_MEMORY 01390 char realvalue[256]; 01391 #else 01392 char realvalue[8192]; 01393 #endif 01394 int lastpri = -2; 01395 struct ast_context *con; 01396 struct ast_variable *v; 01397 const char *cxt; 01398 const char *aft; 01399 const char *newpm, *ovsw; 01400 struct ast_flags config_flags = { 0 }; 01401 char lastextension[256]; 01402 cfg = ast_config_load(config_file, config_flags); 01403 if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) 01404 return 0; 01405 01406 /* Use existing config to populate the PBX table */ 01407 static_config = ast_true(ast_variable_retrieve(cfg, "general", "static")); 01408 write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect")); 01409 if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough"))) 01410 autofallthrough_config = ast_true(aft); 01411 if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew"))) 01412 extenpatternmatchnew_config = ast_true(newpm); 01413 clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars")); 01414 if ((ovsw = ast_variable_retrieve(cfg, "general", "overrideswitch"))) { 01415 if (overrideswitch_config) { 01416 ast_free(overrideswitch_config); 01417 } 01418 if (!ast_strlen_zero(ovsw)) { 01419 overrideswitch_config = ast_strdup(ovsw); 01420 } else { 01421 overrideswitch_config = NULL; 01422 } 01423 } 01424 01425 ast_copy_string(userscontext, ast_variable_retrieve(cfg, "general", "userscontext") ?: "default", sizeof(userscontext)); 01426 01427 for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) { 01428 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01429 pbx_builtin_setvar_helper(NULL, v->name, realvalue); 01430 } 01431 for (cxt = ast_category_browse(cfg, NULL); 01432 cxt; 01433 cxt = ast_category_browse(cfg, cxt)) { 01434 /* All categories but "general" or "globals" are considered contexts */ 01435 if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) { 01436 continue; 01437 } 01438 if (!(con = ast_context_find_or_create(&local_contexts, local_table, cxt, registrar))) { 01439 continue; 01440 } 01441 01442 /* Reset continuation items at the beginning of each context */ 01443 lastextension[0] = '\0'; 01444 lastpri = -2; 01445 01446 for (v = ast_variable_browse(cfg, cxt); v; v = v->next) { 01447 char *tc = NULL; 01448 char realext[256] = ""; 01449 char *stringp, *ext; 01450 const char *vfile; 01451 01452 /* get filename for error reporting from top level or an #include */ 01453 vfile = !*v->file ? config_file : v->file; 01454 01455 if (!strncasecmp(v->name, "same", 4)) { 01456 if (ast_strlen_zero(lastextension)) { 01457 ast_log(LOG_ERROR, 01458 "No previous pattern in the first entry of context '%s' to match '%s' at line %d of %s!\n", 01459 cxt, v->name, v->lineno, vfile); 01460 continue; 01461 } 01462 if ((stringp = tc = ast_strdup(v->value))) { 01463 ast_copy_string(realext, lastextension, sizeof(realext)); 01464 goto process_extension; 01465 } 01466 } else if (!strcasecmp(v->name, "exten")) { 01467 int ipri; 01468 char *plus; 01469 char *pri, *appl, *data, *cidmatch; 01470 01471 if (!(stringp = tc = ast_strdup(v->value))) { 01472 continue; 01473 } 01474 01475 ext = S_OR(pbx_strsep(&stringp, ","), ""); 01476 pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1); 01477 ast_copy_string(lastextension, realext, sizeof(lastextension)); 01478 process_extension: 01479 ipri = -2; 01480 if ((cidmatch = strchr(realext, '/'))) { 01481 *cidmatch++ = '\0'; 01482 ast_shrink_phone_number(cidmatch); 01483 } 01484 pri = ast_strip(S_OR(strsep(&stringp, ","), "")); 01485 if ((label = strchr(pri, '('))) { 01486 *label++ = '\0'; 01487 if ((end = strchr(label, ')'))) { 01488 *end = '\0'; 01489 } else { 01490 ast_log(LOG_WARNING, 01491 "Label missing trailing ')' at line %d of %s\n", 01492 v->lineno, vfile); 01493 ast_free(tc); 01494 continue; 01495 } 01496 } 01497 if ((plus = strchr(pri, '+'))) { 01498 *plus++ = '\0'; 01499 } 01500 if (!strcmp(pri,"hint")) { 01501 ipri = PRIORITY_HINT; 01502 } else if (!strcmp(pri, "next") || !strcmp(pri, "n")) { 01503 if (lastpri > -2) { 01504 ipri = lastpri + 1; 01505 } else { 01506 ast_log(LOG_WARNING, 01507 "Can't use 'next' priority on the first entry at line %d of %s!\n", 01508 v->lineno, vfile); 01509 ast_free(tc); 01510 continue; 01511 } 01512 } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) { 01513 if (lastpri > -2) { 01514 ipri = lastpri; 01515 } else { 01516 ast_log(LOG_WARNING, 01517 "Can't use 'same' priority on the first entry at line %d of %s!\n", 01518 v->lineno, vfile); 01519 ast_free(tc); 01520 continue; 01521 } 01522 } else if (sscanf(pri, "%30d", &ipri) != 1 && 01523 (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) { 01524 ast_log(LOG_WARNING, 01525 "Invalid priority/label '%s' at line %d of %s\n", 01526 pri, v->lineno, vfile); 01527 ipri = 0; 01528 ast_free(tc); 01529 continue; 01530 } else if (ipri < 1) { 01531 ast_log(LOG_WARNING, "Invalid priority '%s' at line %d of %s\n", 01532 pri, v->lineno, vfile); 01533 ast_free(tc); 01534 continue; 01535 } 01536 appl = S_OR(stringp, ""); 01537 /* Find the first occurrence of '(' */ 01538 if (!strchr(appl, '(')) { 01539 /* No arguments */ 01540 data = ""; 01541 } else { 01542 char *orig_appl = ast_strdup(appl); 01543 01544 if (!orig_appl) { 01545 ast_free(tc); 01546 continue; 01547 } 01548 01549 appl = strsep(&stringp, "("); 01550 01551 /* check if there are variables or expressions without an application, like: exten => 100,hint,DAHDI/g0/${GLOBAL(var)} */ 01552 if (strstr(appl, "${") || strstr(appl, "$[")){ 01553 /* set appl to original one */ 01554 strcpy(appl, orig_appl); 01555 /* set no data */ 01556 data = ""; 01557 /* no variable before application found -> go ahead */ 01558 } else { 01559 data = S_OR(stringp, ""); 01560 if ((end = strrchr(data, ')'))) { 01561 *end = '\0'; 01562 } else { 01563 ast_log(LOG_WARNING, 01564 "No closing parenthesis found? '%s(%s' at line %d of %s\n", 01565 appl, data, v->lineno, vfile); 01566 } 01567 } 01568 ast_free(orig_appl); 01569 } 01570 01571 appl = ast_skip_blanks(appl); 01572 if (ipri) { 01573 if (plus) { 01574 ipri += atoi(plus); 01575 } 01576 lastpri = ipri; 01577 if (!ast_opt_dont_warn && (!strcmp(realext, "_.") || !strcmp(realext, "_!"))) { 01578 ast_log(LOG_WARNING, 01579 "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", 01580 realext, realext[1], v->lineno, vfile); 01581 } 01582 if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, ast_strdup(data), ast_free_ptr, registrar)) { 01583 ast_log(LOG_WARNING, 01584 "Unable to register extension at line %d of %s\n", 01585 v->lineno, vfile); 01586 } 01587 } 01588 ast_free(tc); 01589 } else if (!strcasecmp(v->name, "include")) { 01590 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01591 if (ast_context_add_include2(con, realvalue, registrar)) { 01592 switch (errno) { 01593 case ENOMEM: 01594 ast_log(LOG_WARNING, "Out of memory for context addition\n"); 01595 break; 01596 01597 case EBUSY: 01598 ast_log(LOG_WARNING, "Failed to lock context(s) list, please try again later\n"); 01599 break; 01600 01601 case EEXIST: 01602 ast_log(LOG_WARNING, 01603 "Context '%s' already included in '%s' context on include at line %d of %s\n", 01604 v->value, cxt, v->lineno, vfile); 01605 break; 01606 01607 case ENOENT: 01608 case EINVAL: 01609 ast_log(LOG_WARNING, 01610 "There is no existence of context '%s' included at line %d of %s\n", 01611 errno == ENOENT ? v->value : cxt, v->lineno, vfile); 01612 break; 01613 01614 default: 01615 ast_log(LOG_WARNING, 01616 "Failed to include '%s' in '%s' context at line %d of %s\n", 01617 v->value, cxt, v->lineno, vfile); 01618 break; 01619 } 01620 } 01621 } else if (!strcasecmp(v->name, "ignorepat")) { 01622 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01623 if (ast_context_add_ignorepat2(con, realvalue, registrar)) { 01624 ast_log(LOG_WARNING, 01625 "Unable to include ignorepat '%s' in context '%s' at line %d of %s\n", 01626 v->value, cxt, v->lineno, vfile); 01627 } 01628 } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) { 01629 char *stringp = realvalue; 01630 char *appl, *data; 01631 01632 if (!strcasecmp(v->name, "switch")) { 01633 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01634 } else { 01635 ast_copy_string(realvalue, v->value, sizeof(realvalue)); 01636 } 01637 appl = strsep(&stringp, "/"); 01638 data = S_OR(stringp, ""); 01639 if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar)) { 01640 ast_log(LOG_WARNING, 01641 "Unable to include switch '%s' in context '%s' at line %d of %s\n", 01642 v->value, cxt, v->lineno, vfile); 01643 } 01644 } else { 01645 ast_log(LOG_WARNING, 01646 "==!!== Unknown directive: %s at line %d of %s -- IGNORING!!!\n", 01647 v->name, v->lineno, vfile); 01648 } 01649 } 01650 } 01651 ast_config_destroy(cfg); 01652 return 1; 01653 }
static int pbx_load_module | ( | void | ) | [static] |
Definition at line 1771 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_mutex_lock, ast_mutex_unlock, ast_walk_contexts(), pbx_load_config(), pbx_load_users(), pbx_set_autofallthrough(), pbx_set_extenpatternmatchnew(), pbx_set_overrideswitch(), and reload_lock.
Referenced by handle_cli_dialplan_reload(), load_module(), and reload().
01772 { 01773 struct ast_context *con; 01774 01775 ast_mutex_lock(&reload_lock); 01776 01777 if (!local_table) 01778 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); 01779 01780 if (!pbx_load_config(config)) { 01781 ast_mutex_unlock(&reload_lock); 01782 return AST_MODULE_LOAD_DECLINE; 01783 } 01784 01785 pbx_load_users(); 01786 01787 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar); 01788 local_table = NULL; /* the local table has been moved into the global one. */ 01789 local_contexts = NULL; 01790 01791 ast_mutex_unlock(&reload_lock); 01792 01793 for (con = NULL; (con = ast_walk_contexts(con));) 01794 ast_context_verify_includes(con); 01795 01796 pbx_set_overrideswitch(overrideswitch_config); 01797 pbx_set_autofallthrough(autofallthrough_config); 01798 pbx_set_extenpatternmatchnew(extenpatternmatchnew_config); 01799 01800 return AST_MODULE_LOAD_SUCCESS; 01801 }
static void pbx_load_users | ( | void | ) | [static] |
Definition at line 1667 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_strdup, ast_strlen_zero(), ast_true(), ast_variable_retrieve(), ext, and LOG_ERROR.
Referenced by pbx_load_module().
01668 { 01669 struct ast_config *cfg; 01670 char *cat, *chan; 01671 const char *dahdichan; 01672 const char *hasexten, *altexts; 01673 char tmp[256]; 01674 char iface[256]; 01675 char dahdicopy[256]; 01676 char *ext, altcopy[256]; 01677 char *c; 01678 int hasvoicemail; 01679 int start, finish, x; 01680 struct ast_context *con = NULL; 01681 struct ast_flags config_flags = { 0 }; 01682 01683 cfg = ast_config_load("users.conf", config_flags); 01684 if (!cfg) 01685 return; 01686 01687 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 01688 if (!strcasecmp(cat, "general")) 01689 continue; 01690 iface[0] = '\0'; 01691 if (ast_true(ast_config_option(cfg, cat, "hassip"))) { 01692 snprintf(tmp, sizeof(tmp), "SIP/%s", cat); 01693 append_interface(iface, sizeof(iface), tmp); 01694 } 01695 if (ast_true(ast_config_option(cfg, cat, "hasiax"))) { 01696 snprintf(tmp, sizeof(tmp), "IAX2/%s", cat); 01697 append_interface(iface, sizeof(iface), tmp); 01698 } 01699 if (ast_true(ast_config_option(cfg, cat, "hash323"))) { 01700 snprintf(tmp, sizeof(tmp), "H323/%s", cat); 01701 append_interface(iface, sizeof(iface), tmp); 01702 } 01703 hasexten = ast_config_option(cfg, cat, "hasexten"); 01704 if (hasexten && !ast_true(hasexten)) 01705 continue; 01706 hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail")); 01707 dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan"); 01708 if (!dahdichan) 01709 dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan"); 01710 if (!ast_strlen_zero(dahdichan)) { 01711 ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy)); 01712 c = dahdicopy; 01713 chan = strsep(&c, ","); 01714 while (chan) { 01715 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) { 01716 /* Range */ 01717 } else if (sscanf(chan, "%30d", &start)) { 01718 /* Just one */ 01719 finish = start; 01720 } else { 01721 start = 0; finish = 0; 01722 } 01723 if (finish < start) { 01724 x = finish; 01725 finish = start; 01726 start = x; 01727 } 01728 for (x = start; x <= finish; x++) { 01729 snprintf(tmp, sizeof(tmp), "DAHDI/%d", x); 01730 append_interface(iface, sizeof(iface), tmp); 01731 } 01732 chan = strsep(&c, ","); 01733 } 01734 } 01735 if (!ast_strlen_zero(iface)) { 01736 /* Only create a context here when it is really needed. Otherwise default empty context 01737 created by pbx_config may conflict with the one explicitly created by pbx_ael */ 01738 if (!con) 01739 con = ast_context_find_or_create(&local_contexts, local_table, userscontext, registrar); 01740 01741 if (!con) { 01742 ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext); 01743 return; 01744 } 01745 01746 /* Add hint */ 01747 ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar); 01748 /* If voicemail, use "stdexten" else use plain old dial */ 01749 if (hasvoicemail) { 01750 snprintf(tmp, sizeof(tmp), "stdexten,%s,${HINT}", cat); 01751 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", ast_strdup(tmp), ast_free_ptr, registrar); 01752 } else { 01753 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", ast_strdup("${HINT}"), ast_free_ptr, registrar); 01754 } 01755 altexts = ast_variable_retrieve(cfg, cat, "alternateexts"); 01756 if (!ast_strlen_zero(altexts)) { 01757 snprintf(tmp, sizeof(tmp), "%s,1", cat); 01758 ast_copy_string(altcopy, altexts, sizeof(altcopy)); 01759 c = altcopy; 01760 ext = strsep(&c, ","); 01761 while (ext) { 01762 ast_add_extension2(con, 0, ext, 1, NULL, NULL, "Goto", ast_strdup(tmp), ast_free_ptr, registrar); 01763 ext = strsep(&c, ","); 01764 } 01765 } 01766 } 01767 } 01768 ast_config_destroy(cfg); 01769 }
static char* pbx_strsep | ( | char ** | destructible, | |
const char * | delim | |||
) | [static] |
Definition at line 1354 of file pbx_config.c.
Referenced by pbx_load_config().
01355 { 01356 int square = 0; 01357 char *res; 01358 01359 if (!destructible || !*destructible) { 01360 return NULL; 01361 } 01362 res = *destructible; 01363 for (; **destructible; (*destructible)++) { 01364 if (**destructible == '[' && !strchr(delim, '[')) { 01365 square++; 01366 } else if (**destructible == ']' && !strchr(delim, ']')) { 01367 if (square) { 01368 square--; 01369 } 01370 } else if (**destructible == '\\' && !strchr(delim, '\\')) { 01371 (*destructible)++; 01372 } else if (strchr(delim, **destructible) && !square) { 01373 **destructible = '\0'; 01374 (*destructible)++; 01375 break; 01376 } 01377 } 01378 if (**destructible == '\0') { 01379 *destructible = NULL; 01380 } 01381 return res; 01382 }
static int reload | ( | void | ) | [static] |
Definition at line 1815 of file pbx_config.c.
References pbx_builtin_clear_globals(), and pbx_load_module().
01816 { 01817 if (clearglobalvars_config) 01818 pbx_builtin_clear_globals(); 01819 return pbx_load_module(); 01820 }
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 135 of file pbx_config.c.
Referenced by complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), and complete_dialplan_remove_include().
00136 { 00137 int in_blank = 0; 00138 for (;n && *p; p++) { 00139 if (isblank(*p) /* XXX order is important */ && !in_blank) { 00140 n--; /* one word is gone */ 00141 in_blank = 1; 00142 } else if (/* !is_blank(*p), we know already, && */ in_blank) { 00143 in_blank = 0; 00144 } 00145 } 00146 return p; 00147 }
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 158 of file pbx_config.c.
References ast_strdup, and free.
Referenced by complete_dialplan_remove_extension(), and handle_cli_dialplan_remove_extension().
00159 { 00160 char *i, *c, *e = ast_strdup(src); /* now src is not used anymore */ 00161 00162 if (e == NULL) 00163 return -1; /* malloc error */ 00164 /* now, parse values from 'exten@context' */ 00165 *ext = e; 00166 c = strchr(e, '@'); 00167 if (c == NULL) /* no context part */ 00168 *ctx = ""; /* it is not overwritten, anyways */ 00169 else { /* found context, check for duplicity ... */ 00170 *c++ = '\0'; 00171 *ctx = c; 00172 if (strchr(c, '@')) { /* two @, not allowed */ 00173 free(e); 00174 return -1; 00175 } 00176 } 00177 if (cid && (i = strchr(e, '/'))) { 00178 *i++ = '\0'; 00179 *cid = i; 00180 } else if (cid) { 00181 /* Signal none detected */ 00182 *cid = NULL; 00183 } 00184 return 0; 00185 }
static int unload_module | ( | void | ) | [static] |
Standard module functions ...
Definition at line 1337 of file pbx_config.c.
References ARRAY_LEN, ast_cli_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), and ast_free.
01338 { 01339 if (static_config && !write_protect_config) 01340 ast_cli_unregister(&cli_dialplan_save); 01341 if (overrideswitch_config) { 01342 ast_free(overrideswitch_config); 01343 } 01344 ast_cli_unregister_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config)); 01345 ast_context_destroy(NULL, registrar); 01346 return 0; 01347 }
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1826 of file pbx_config.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1826 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] |
AST_CLI_DEFINE(handle_cli_dialplan_save, "Save dialplan")
Definition at line 1331 of file pbx_config.c.
struct ast_cli_entry cli_pbx_config[] [static] |
CLI entries for commands provided by this module
Definition at line 1320 of file pbx_config.c.
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 60 of file pbx_config.c.
Referenced by ast_context_find_or_create(), and pbx_load_module().
struct ast_hashtab* local_table = NULL [static] |
Definition at line 61 of file pbx_config.c.
Referenced by pbx_load_module().
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 reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 58 of file pbx_config.c.
Referenced by pbx_load_module().
ast_mutex_t save_dialplan_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 56 of file pbx_config.c.
Referenced by handle_cli_dialplan_save().
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.