#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 = AST_BUILDOPT_SUM, .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_MUTEX_INITIALIZER , 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 1824 of file pbx_config.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1824 of file pbx_config.c.
| static void append_interface | ( | char * | iface, | |
| int | maxlen, | |||
| char * | add | |||
| ) | [static] |
Definition at line 1659 of file pbx_config.c.
References len().
Referenced by pbx_load_users().
01660 { 01661 int len = strlen(iface); 01662 if (strlen(add) + len < maxlen - 2) { 01663 if (strlen(iface)) { 01664 iface[len] = '&'; 01665 strcpy(iface + len + 1, add); 01666 } else 01667 strcpy(iface, add); 01668 } 01669 }
| 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 1035 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().
01036 { 01037 int which = 0; 01038 01039 if (a->pos == 4) { /* complete 'into' word ... */ 01040 return (a->n == 0) ? strdup("into") : NULL; 01041 } else if (a->pos == 5) { /* complete context */ 01042 struct ast_context *c = NULL; 01043 int len = strlen(a->word); 01044 char *res = NULL; 01045 01046 /* try to lock contexts list ... */ 01047 if (ast_rdlock_contexts()) { 01048 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01049 return NULL; 01050 } 01051 01052 /* walk through all contexts */ 01053 while ( !res && (c = ast_walk_contexts(c)) ) 01054 if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n) 01055 res = strdup(ast_get_context_name(c)); 01056 ast_unlock_contexts(); 01057 return res; 01058 } else if (a->pos == 6) { 01059 return a->n == 0 ? strdup("replace") : NULL; 01060 } 01061 return NULL; 01062 }
| static char * complete_dialplan_add_ignorepat | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 1121 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().
01122 { 01123 if (a->pos == 4) 01124 return a->n == 0 ? strdup("into") : NULL; 01125 else if (a->pos == 5) { 01126 struct ast_context *c; 01127 int which = 0; 01128 char *dupline, *ignorepat = NULL; 01129 const char *s; 01130 char *ret = NULL; 01131 int len = strlen(a->word); 01132 01133 /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */ 01134 s = skip_words(a->line, 3); 01135 if (s == NULL) 01136 return NULL; 01137 dupline = strdup(s); 01138 if (!dupline) { 01139 ast_log(LOG_ERROR, "Malloc failure\n"); 01140 return NULL; 01141 } 01142 ignorepat = strsep(&dupline, " "); 01143 01144 if (ast_rdlock_contexts()) { 01145 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 01146 return NULL; 01147 } 01148 01149 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01150 int found = 0; 01151 01152 if (!partial_match(ast_get_context_name(c), a->word, len)) 01153 continue; /* not mine */ 01154 if (ignorepat) /* there must be one, right ? */ 01155 found = lookup_c_ip(c, ignorepat); 01156 if (!found && ++which > a->n) 01157 ret = strdup(ast_get_context_name(c)); 01158 } 01159 01160 free(ignorepat); 01161 ast_unlock_contexts(); 01162 return ret; 01163 } 01164 01165 return NULL; 01166 }
| 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, 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 * | a | ) | [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 * | a | ) | [static] |
Definition at line 1217 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().
01218 { 01219 struct ast_context *c; 01220 int which = 0; 01221 char *ret = NULL; 01222 01223 if (a->pos == 3) { 01224 int len = strlen(a->word); 01225 if (ast_rdlock_contexts()) { 01226 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01227 return NULL; 01228 } 01229 01230 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01231 struct ast_ignorepat *ip; 01232 01233 if (ast_rdlock_context(c)) /* error, skip it */ 01234 continue; 01235 01236 for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) { 01237 if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) { 01238 /* n-th match */ 01239 struct ast_context *cw = NULL; 01240 int found = 0; 01241 while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) { 01242 /* XXX do i stop on c, or skip it ? */ 01243 found = lookup_c_ip(cw, ast_get_ignorepat_name(ip)); 01244 } 01245 if (!found) 01246 ret = strdup(ast_get_ignorepat_name(ip)); 01247 } 01248 } 01249 ast_unlock_context(c); 01250 } 01251 ast_unlock_contexts(); 01252 return ret; 01253 } else if (a->pos == 4) { 01254 return a->n == 0 ? strdup("from") : NULL; 01255 } else if (a->pos == 5) { /* XXX check this */ 01256 char *dupline, *duplinet, *ignorepat; 01257 int len = strlen(a->word); 01258 01259 dupline = strdup(a->line); 01260 if (!dupline) { 01261 ast_log(LOG_WARNING, "Out of free memory\n"); 01262 return NULL; 01263 } 01264 01265 duplinet = dupline; 01266 strsep(&duplinet, " "); 01267 strsep(&duplinet, " "); 01268 ignorepat = strsep(&duplinet, " "); 01269 01270 if (!ignorepat) { 01271 free(dupline); 01272 return NULL; 01273 } 01274 01275 if (ast_rdlock_contexts()) { 01276 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01277 free(dupline); 01278 return NULL; 01279 } 01280 01281 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 01282 if (ast_rdlock_context(c)) /* fail, skip it */ 01283 continue; 01284 if (!partial_match(ast_get_context_name(c), a->word, len)) 01285 continue; 01286 if (lookup_c_ip(c, ignorepat) && ++which > a->n) 01287 ret = strdup(ast_get_context_name(c)); 01288 ast_unlock_context(c); 01289 } 01290 ast_unlock_contexts(); 01291 free(dupline); 01292 return NULL; 01293 } 01294 01295 return NULL; 01296 }
| static char * complete_dialplan_remove_include | ( | struct ast_cli_args * | a | ) | [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_context_find(), ast_context_find_or_create(), 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, 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 const char *into_context; 00910 00911 switch (cmd) { 00912 case CLI_INIT: 00913 e->command = "dialplan add extension"; 00914 e->usage = 00915 "Usage: dialplan add extension <exten>,<priority>,<app> into <context> [replace]\n" 00916 "\n" 00917 " app can be either:\n" 00918 " app-name\n" 00919 " app-name(app-data)\n" 00920 " app-name,<app-data>\n" 00921 "\n" 00922 " This command will add the new extension into <context>. If\n" 00923 " an extension with the same priority already exists and the\n" 00924 " 'replace' option is given we will replace the extension.\n" 00925 "\n" 00926 "Example: dialplan add extension 6123,1,Dial,IAX/216.207.245.56/6123 into local\n" 00927 " Now, you can dial 6123 and talk to Markster :)\n"; 00928 return NULL; 00929 case CLI_GENERATE: 00930 return complete_dialplan_add_extension(a); 00931 } 00932 00933 /* check for arguments at first */ 00934 if (a->argc != 6 && a->argc != 7) 00935 return CLI_SHOWUSAGE; 00936 if (strcmp(a->argv[4], "into")) 00937 return CLI_SHOWUSAGE; 00938 if (a->argc == 7) 00939 if (strcmp(a->argv[6], "replace")) 00940 return CLI_SHOWUSAGE; 00941 00942 whole_exten = ast_strdupa(a->argv[3]); 00943 exten = strsep(&whole_exten,","); 00944 if (strchr(exten, '/')) { 00945 cidmatch = exten; 00946 strsep(&cidmatch,"/"); 00947 } else { 00948 cidmatch = NULL; 00949 } 00950 prior = strsep(&whole_exten,","); 00951 if (prior) { 00952 if (!strcmp(prior, "hint")) { 00953 iprior = PRIORITY_HINT; 00954 } else { 00955 if (sscanf(prior, "%30d", &iprior) != 1) { 00956 ast_cli(a->fd, "'%s' is not a valid priority\n", prior); 00957 prior = NULL; 00958 } 00959 } 00960 } 00961 app = whole_exten; 00962 if (app) { 00963 if ((start = strchr(app, '(')) && (end = strrchr(app, ')'))) { 00964 *start = *end = '\0'; 00965 app_data = start + 1; 00966 } else { 00967 app_data = strchr(app, ','); 00968 if (app_data) { 00969 *app_data++ = '\0'; 00970 } 00971 } 00972 } else { 00973 app_data = NULL; 00974 } 00975 00976 if (!exten || !prior || !app) { 00977 return CLI_SHOWUSAGE; 00978 } 00979 00980 if (!app_data) { 00981 app_data = ""; 00982 } 00983 into_context = a->argv[5]; 00984 00985 if (!ast_context_find(into_context)) { 00986 ast_cli(a->fd, "Context '%s' did not exist prior to add extension - the context will be created.\n", into_context); 00987 } 00988 00989 if (!ast_context_find_or_create(NULL, NULL, into_context, registrar)) { 00990 ast_cli(a->fd, "Failed to add '%s,%s,%s(%s)' extension into '%s' context\n", 00991 exten, prior, app, app_data, into_context); 00992 return CLI_FAILURE; 00993 } 00994 00995 if (ast_add_extension(into_context, a->argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app, 00996 ast_strdup(app_data), ast_free_ptr, registrar)) { 00997 switch (errno) { 00998 case ENOMEM: 00999 ast_cli(a->fd, "Out of free memory\n"); 01000 break; 01001 01002 case EBUSY: 01003 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 01004 break; 01005 01006 case ENOENT: 01007 ast_cli(a->fd, "No existence of '%s' context\n", into_context); 01008 break; 01009 01010 case EEXIST: 01011 ast_cli(a->fd, "Extension %s@%s with priority %s already exists\n", 01012 exten, into_context, prior); 01013 break; 01014 01015 default: 01016 ast_cli(a->fd, "Failed to add '%s,%s,%s(%s)' extension into '%s' context\n", 01017 exten, prior, app, app_data, into_context); 01018 break; 01019 } 01020 return CLI_FAILURE; 01021 } 01022 01023 if (a->argc == 7) { 01024 ast_cli(a->fd, "Extension %s@%s (%s) replace by '%s,%s,%s(%s)'\n", 01025 exten, into_context, prior, exten, prior, app, app_data); 01026 } else { 01027 ast_cli(a->fd, "Extension '%s,%s,%s(%s)' added into '%s' context\n", 01028 exten, prior, app, app_data, into_context); 01029 } 01030 01031 return CLI_SUCCESS; 01032 }
| 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 1067 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.
01068 { 01069 switch (cmd) { 01070 case CLI_INIT: 01071 e->command = "dialplan add ignorepat"; 01072 e->usage = 01073 "Usage: dialplan add ignorepat <pattern> into <context>\n" 01074 " This command adds a new ignore pattern into context <context>\n" 01075 "\n" 01076 "Example: dialplan add ignorepat _3XX into local\n"; 01077 return NULL; 01078 case CLI_GENERATE: 01079 return complete_dialplan_add_ignorepat(a); 01080 } 01081 01082 if (a->argc != 6) 01083 return CLI_SHOWUSAGE; 01084 01085 if (strcmp(a->argv[4], "into")) 01086 return CLI_SHOWUSAGE; 01087 01088 if (ast_context_add_ignorepat(a->argv[5], a->argv[3], registrar)) { 01089 switch (errno) { 01090 case ENOMEM: 01091 ast_cli(a->fd, "Out of free memory\n"); 01092 break; 01093 01094 case ENOENT: 01095 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01096 break; 01097 01098 case EEXIST: 01099 ast_cli(a->fd, "Ignore pattern '%s' already included in '%s' context\n", 01100 a->argv[3], a->argv[5]); 01101 break; 01102 01103 case EBUSY: 01104 ast_cli(a->fd, "Failed to lock context(s) list, please, try again later\n"); 01105 break; 01106 01107 default: 01108 ast_cli(a->fd, "Failed to add ingore pattern '%s' into '%s' context\n", 01109 a->argv[3], a->argv[5]); 01110 break; 01111 } 01112 return CLI_FAILURE; 01113 } 01114 01115 ast_cli(a->fd, "Ignore pattern '%s' added into '%s' context\n", 01116 a->argv[3], a->argv[5]); 01117 01118 return CLI_SUCCESS; 01119 }
| 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 1300 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.
01301 { 01302 switch (cmd) { 01303 case CLI_INIT: 01304 e->command = "dialplan reload"; 01305 e->usage = 01306 "Usage: dialplan reload\n" 01307 " Reload extensions.conf without reloading any other\n" 01308 " modules. This command does not delete global variables\n" 01309 " unless clearglobalvars is set to yes in extensions.conf\n"; 01310 return NULL; 01311 case CLI_GENERATE: 01312 return NULL; 01313 } 01314 01315 if (a->argc != 2) 01316 return CLI_SHOWUSAGE; 01317 01318 if (clearglobalvars_config) 01319 pbx_builtin_clear_globals(); 01320 01321 pbx_load_module(); 01322 ast_cli(a->fd, "Dialplan reloaded.\n"); 01323 return CLI_SUCCESS; 01324 }
| 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 1168 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.
01169 { 01170 switch (cmd) { 01171 case CLI_INIT: 01172 e->command = "dialplan remove ignorepat"; 01173 e->usage = 01174 "Usage: dialplan remove ignorepat <pattern> from <context>\n" 01175 " This command removes an ignore pattern from context <context>\n" 01176 "\n" 01177 "Example: dialplan remove ignorepat _3XX from local\n"; 01178 return NULL; 01179 case CLI_GENERATE: 01180 return complete_dialplan_remove_ignorepat(a); 01181 } 01182 01183 if (a->argc != 6) 01184 return CLI_SHOWUSAGE; 01185 01186 if (strcmp(a->argv[4], "from")) 01187 return CLI_SHOWUSAGE; 01188 01189 if (ast_context_remove_ignorepat(a->argv[5], a->argv[3], registrar)) { 01190 switch (errno) { 01191 case EBUSY: 01192 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 01193 break; 01194 01195 case ENOENT: 01196 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01197 break; 01198 01199 case EINVAL: 01200 ast_cli(a->fd, "There is no existence of '%s' ignore pattern in '%s' context\n", 01201 a->argv[3], a->argv[5]); 01202 break; 01203 01204 default: 01205 ast_cli(a->fd, "Failed to remove ignore pattern '%s' from '%s' context\n", 01206 a->argv[3], a->argv[5]); 01207 break; 01208 } 01209 return CLI_FAILURE; 01210 } 01211 01212 ast_cli(a->fd, "Ignore pattern '%s' removed from '%s' context\n", 01213 a->argv[3], a->argv[5]); 01214 return CLI_SUCCESS; 01215 }
| 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, 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 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 1801 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().
01802 { 01803 if (static_config && !write_protect_config) 01804 ast_cli_register(&cli_dialplan_save); 01805 ast_cli_register_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config)); 01806 01807 if (pbx_load_module()) 01808 return AST_MODULE_LOAD_DECLINE; 01809 01810 return AST_MODULE_LOAD_SUCCESS; 01811 }
| 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 1388 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, free, ast_variable::lineno, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), pbx_strsep(), pbx_substitute_variables_helper(), PRIORITY_HINT, S_OR, strsep(), and ast_variable::value.
Referenced by pbx_load_module().
01389 { 01390 struct ast_config *cfg; 01391 char *end; 01392 char *label; 01393 #ifdef LOW_MEMORY 01394 char realvalue[256]; 01395 #else 01396 char realvalue[8192]; 01397 #endif 01398 int lastpri = -2; 01399 struct ast_context *con; 01400 struct ast_variable *v; 01401 const char *cxt; 01402 const char *aft; 01403 const char *newpm, *ovsw; 01404 struct ast_flags config_flags = { 0 }; 01405 char lastextension[256]; 01406 cfg = ast_config_load(config_file, config_flags); 01407 if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) 01408 return 0; 01409 01410 /* Use existing config to populate the PBX table */ 01411 static_config = ast_true(ast_variable_retrieve(cfg, "general", "static")); 01412 write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect")); 01413 if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough"))) 01414 autofallthrough_config = ast_true(aft); 01415 if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew"))) 01416 extenpatternmatchnew_config = ast_true(newpm); 01417 clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars")); 01418 if ((ovsw = ast_variable_retrieve(cfg, "general", "overrideswitch"))) { 01419 if (overrideswitch_config) { 01420 ast_free(overrideswitch_config); 01421 } 01422 if (!ast_strlen_zero(ovsw)) { 01423 overrideswitch_config = ast_strdup(ovsw); 01424 } else { 01425 overrideswitch_config = NULL; 01426 } 01427 } 01428 01429 ast_copy_string(userscontext, ast_variable_retrieve(cfg, "general", "userscontext") ?: "default", sizeof(userscontext)); 01430 01431 for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) { 01432 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01433 pbx_builtin_setvar_helper(NULL, v->name, realvalue); 01434 } 01435 for (cxt = ast_category_browse(cfg, NULL); 01436 cxt; 01437 cxt = ast_category_browse(cfg, cxt)) { 01438 /* All categories but "general" or "globals" are considered contexts */ 01439 if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) { 01440 continue; 01441 } 01442 if (!(con = ast_context_find_or_create(&local_contexts, local_table, cxt, registrar))) { 01443 continue; 01444 } 01445 01446 /* Reset continuation items at the beginning of each context */ 01447 lastextension[0] = '\0'; 01448 lastpri = -2; 01449 01450 for (v = ast_variable_browse(cfg, cxt); v; v = v->next) { 01451 char *tc = NULL; 01452 char realext[256] = ""; 01453 char *stringp, *ext; 01454 const char *vfile; 01455 01456 /* get filename for error reporting from top level or an #include */ 01457 vfile = !*v->file ? config_file : v->file; 01458 01459 if (!strncasecmp(v->name, "same", 4)) { 01460 if (ast_strlen_zero(lastextension)) { 01461 ast_log(LOG_ERROR, 01462 "No previous pattern in the first entry of context '%s' to match '%s' at line %d of %s!\n", 01463 cxt, v->name, v->lineno, vfile); 01464 continue; 01465 } 01466 if ((stringp = tc = ast_strdup(v->value))) { 01467 ast_copy_string(realext, lastextension, sizeof(realext)); 01468 goto process_extension; 01469 } 01470 } else if (!strcasecmp(v->name, "exten")) { 01471 int ipri; 01472 char *plus, *firstp; 01473 char *pri, *appl, *data, *cidmatch; 01474 01475 if (!(stringp = tc = ast_strdup(v->value))) { 01476 continue; 01477 } 01478 01479 ext = S_OR(pbx_strsep(&stringp, ","), ""); 01480 pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1); 01481 ast_copy_string(lastextension, realext, sizeof(lastextension)); 01482 process_extension: 01483 ipri = -2; 01484 if ((cidmatch = strchr(realext, '/'))) { 01485 *cidmatch++ = '\0'; 01486 ast_shrink_phone_number(cidmatch); 01487 } 01488 pri = ast_strip(S_OR(strsep(&stringp, ","), "")); 01489 if ((label = strchr(pri, '('))) { 01490 *label++ = '\0'; 01491 if ((end = strchr(label, ')'))) { 01492 *end = '\0'; 01493 } else { 01494 ast_log(LOG_WARNING, 01495 "Label missing trailing ')' at line %d of %s\n", 01496 v->lineno, vfile); 01497 ast_free(tc); 01498 continue; 01499 } 01500 } 01501 if ((plus = strchr(pri, '+'))) { 01502 *plus++ = '\0'; 01503 } 01504 if (!strcmp(pri,"hint")) { 01505 ipri = PRIORITY_HINT; 01506 } else if (!strcmp(pri, "next") || !strcmp(pri, "n")) { 01507 if (lastpri > -2) { 01508 ipri = lastpri + 1; 01509 } else { 01510 ast_log(LOG_WARNING, 01511 "Can't use 'next' priority on the first entry at line %d of %s!\n", 01512 v->lineno, vfile); 01513 ast_free(tc); 01514 continue; 01515 } 01516 } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) { 01517 if (lastpri > -2) { 01518 ipri = lastpri; 01519 } else { 01520 ast_log(LOG_WARNING, 01521 "Can't use 'same' priority on the first entry at line %d of %s!\n", 01522 v->lineno, vfile); 01523 ast_free(tc); 01524 continue; 01525 } 01526 } else if (sscanf(pri, "%30d", &ipri) != 1 && 01527 (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) { 01528 ast_log(LOG_WARNING, 01529 "Invalid priority/label '%s' at line %d of %s\n", 01530 pri, v->lineno, vfile); 01531 ipri = 0; 01532 ast_free(tc); 01533 continue; 01534 } else if (ipri < 1) { 01535 ast_log(LOG_WARNING, "Invalid priority '%s' at line %d of %s\n", 01536 pri, v->lineno, vfile); 01537 ast_free(tc); 01538 continue; 01539 } 01540 appl = S_OR(stringp, ""); 01541 /* Find the first occurrence of '(' */ 01542 if (!(firstp = strchr(appl, '('))) { 01543 /* No arguments */ 01544 data = ""; 01545 } else { 01546 char *orig_appl = ast_strdup(appl); 01547 01548 if (!orig_appl) { 01549 ast_free(tc); 01550 continue; 01551 } 01552 01553 appl = strsep(&stringp, "("); 01554 01555 /* check if there are variables or expressions without an application, like: exten => 100,hint,DAHDI/g0/${GLOBAL(var)} */ 01556 if (strstr(appl, "${") || strstr(appl, "$[")){ 01557 /* set appl to original one */ 01558 strcpy(appl, orig_appl); 01559 /* set no data */ 01560 data = ""; 01561 /* no variable before application found -> go ahead */ 01562 } else { 01563 data = S_OR(stringp, ""); 01564 if ((end = strrchr(data, ')'))) { 01565 *end = '\0'; 01566 } else { 01567 ast_log(LOG_WARNING, 01568 "No closing parenthesis found? '%s(%s' at line %d of %s\n", 01569 appl, data, v->lineno, vfile); 01570 } 01571 } 01572 ast_free(orig_appl); 01573 } 01574 01575 appl = ast_skip_blanks(appl); 01576 if (ipri) { 01577 if (plus) { 01578 ipri += atoi(plus); 01579 } 01580 lastpri = ipri; 01581 if (!ast_opt_dont_warn && (!strcmp(realext, "_.") || !strcmp(realext, "_!"))) { 01582 ast_log(LOG_WARNING, 01583 "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", 01584 realext, realext[1], v->lineno, vfile); 01585 } 01586 if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, ast_strdup(data), ast_free_ptr, registrar)) { 01587 ast_log(LOG_WARNING, 01588 "Unable to register extension at line %d of %s\n", 01589 v->lineno, vfile); 01590 } 01591 } 01592 free(tc); 01593 } else if (!strcasecmp(v->name, "include")) { 01594 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01595 if (ast_context_add_include2(con, realvalue, registrar)) { 01596 switch (errno) { 01597 case ENOMEM: 01598 ast_log(LOG_WARNING, "Out of memory for context addition\n"); 01599 break; 01600 01601 case EBUSY: 01602 ast_log(LOG_WARNING, "Failed to lock context(s) list, please try again later\n"); 01603 break; 01604 01605 case EEXIST: 01606 ast_log(LOG_WARNING, 01607 "Context '%s' already included in '%s' context on include at line %d of %s\n", 01608 v->value, cxt, v->lineno, vfile); 01609 break; 01610 01611 case ENOENT: 01612 case EINVAL: 01613 ast_log(LOG_WARNING, 01614 "There is no existence of context '%s' included at line %d of %s\n", 01615 errno == ENOENT ? v->value : cxt, v->lineno, vfile); 01616 break; 01617 01618 default: 01619 ast_log(LOG_WARNING, 01620 "Failed to include '%s' in '%s' context at line %d of %s\n", 01621 v->value, cxt, v->lineno, vfile); 01622 break; 01623 } 01624 } 01625 } else if (!strcasecmp(v->name, "ignorepat")) { 01626 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01627 if (ast_context_add_ignorepat2(con, realvalue, registrar)) { 01628 ast_log(LOG_WARNING, 01629 "Unable to include ignorepat '%s' in context '%s' at line %d of %s\n", 01630 v->value, cxt, v->lineno, vfile); 01631 } 01632 } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) { 01633 char *stringp = realvalue; 01634 char *appl, *data; 01635 01636 if (!strcasecmp(v->name, "switch")) { 01637 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01638 } else { 01639 ast_copy_string(realvalue, v->value, sizeof(realvalue)); 01640 } 01641 appl = strsep(&stringp, "/"); 01642 data = S_OR(stringp, ""); 01643 if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar)) { 01644 ast_log(LOG_WARNING, 01645 "Unable to include switch '%s' in context '%s' at line %d of %s\n", 01646 v->value, cxt, v->lineno, vfile); 01647 } 01648 } else { 01649 ast_log(LOG_WARNING, 01650 "==!!== Unknown directive: %s at line %d of %s -- IGNORING!!!\n", 01651 v->name, v->lineno, vfile); 01652 } 01653 } 01654 } 01655 ast_config_destroy(cfg); 01656 return 1; 01657 }
| static int pbx_load_module | ( | void | ) | [static] |
Definition at line 1775 of file pbx_config.c.
References ast_context_verify_includes(), ast_hashtab_compare_contexts(), ast_hashtab_create(), ast_hashtab_hash_contexts(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), ast_merge_contexts_and_delete(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_walk_contexts(), pbx_load_config(), pbx_load_users(), pbx_set_autofallthrough(), pbx_set_extenpatternmatchnew(), and pbx_set_overrideswitch().
01776 { 01777 struct ast_context *con; 01778 01779 if (!local_table) 01780 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); 01781 01782 if (!pbx_load_config(config)) 01783 return AST_MODULE_LOAD_DECLINE; 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 for (con = NULL; (con = ast_walk_contexts(con));) 01792 ast_context_verify_includes(con); 01793 01794 pbx_set_overrideswitch(overrideswitch_config); 01795 pbx_set_autofallthrough(autofallthrough_config); 01796 pbx_set_extenpatternmatchnew(extenpatternmatchnew_config); 01797 01798 return AST_MODULE_LOAD_SUCCESS; 01799 }
| static void pbx_load_users | ( | void | ) | [static] |
Definition at line 1671 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, LOG_ERROR, and strsep().
Referenced by pbx_load_module().
01672 { 01673 struct ast_config *cfg; 01674 char *cat, *chan; 01675 const char *dahdichan; 01676 const char *hasexten, *altexts; 01677 char tmp[256]; 01678 char iface[256]; 01679 char dahdicopy[256]; 01680 char *ext, altcopy[256]; 01681 char *c; 01682 int hasvoicemail; 01683 int start, finish, x; 01684 struct ast_context *con = NULL; 01685 struct ast_flags config_flags = { 0 }; 01686 01687 cfg = ast_config_load("users.conf", config_flags); 01688 if (!cfg) 01689 return; 01690 01691 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 01692 if (!strcasecmp(cat, "general")) 01693 continue; 01694 iface[0] = '\0'; 01695 if (ast_true(ast_config_option(cfg, cat, "hassip"))) { 01696 snprintf(tmp, sizeof(tmp), "SIP/%s", cat); 01697 append_interface(iface, sizeof(iface), tmp); 01698 } 01699 if (ast_true(ast_config_option(cfg, cat, "hasiax"))) { 01700 snprintf(tmp, sizeof(tmp), "IAX2/%s", cat); 01701 append_interface(iface, sizeof(iface), tmp); 01702 } 01703 if (ast_true(ast_config_option(cfg, cat, "hash323"))) { 01704 snprintf(tmp, sizeof(tmp), "H323/%s", cat); 01705 append_interface(iface, sizeof(iface), tmp); 01706 } 01707 hasexten = ast_config_option(cfg, cat, "hasexten"); 01708 if (hasexten && !ast_true(hasexten)) 01709 continue; 01710 hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail")); 01711 dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan"); 01712 if (!dahdichan) 01713 dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan"); 01714 if (!ast_strlen_zero(dahdichan)) { 01715 ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy)); 01716 c = dahdicopy; 01717 chan = strsep(&c, ","); 01718 while (chan) { 01719 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) { 01720 /* Range */ 01721 } else if (sscanf(chan, "%30d", &start)) { 01722 /* Just one */ 01723 finish = start; 01724 } else { 01725 start = 0; finish = 0; 01726 } 01727 if (finish < start) { 01728 x = finish; 01729 finish = start; 01730 start = x; 01731 } 01732 for (x = start; x <= finish; x++) { 01733 snprintf(tmp, sizeof(tmp), "DAHDI/%d", x); 01734 append_interface(iface, sizeof(iface), tmp); 01735 } 01736 chan = strsep(&c, ","); 01737 } 01738 } 01739 if (!ast_strlen_zero(iface)) { 01740 /* Only create a context here when it is really needed. Otherwise default empty context 01741 created by pbx_config may conflict with the one explicitly created by pbx_ael */ 01742 if (!con) 01743 con = ast_context_find_or_create(&local_contexts, local_table, userscontext, registrar); 01744 01745 if (!con) { 01746 ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext); 01747 return; 01748 } 01749 01750 /* Add hint */ 01751 ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar); 01752 /* If voicemail, use "stdexten" else use plain old dial */ 01753 if (hasvoicemail) { 01754 snprintf(tmp, sizeof(tmp), "%s,stdexten(${HINT})", cat); 01755 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Gosub", ast_strdup(tmp), ast_free_ptr, registrar); 01756 } else { 01757 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", ast_strdup("${HINT}"), ast_free_ptr, registrar); 01758 } 01759 altexts = ast_variable_retrieve(cfg, cat, "alternateexts"); 01760 if (!ast_strlen_zero(altexts)) { 01761 snprintf(tmp, sizeof(tmp), "%s,1", cat); 01762 ast_copy_string(altcopy, altexts, sizeof(altcopy)); 01763 c = altcopy; 01764 ext = strsep(&c, ","); 01765 while (ext) { 01766 ast_add_extension2(con, 0, ext, 1, NULL, NULL, "Goto", ast_strdup(tmp), ast_free_ptr, registrar); 01767 ext = strsep(&c, ","); 01768 } 01769 } 01770 } 01771 } 01772 ast_config_destroy(cfg); 01773 }
| static char* pbx_strsep | ( | char ** | destructible, | |
| const char * | delim | |||
| ) | [static] |
Definition at line 1363 of file pbx_config.c.
Referenced by pbx_load_config().
01364 { 01365 int square = 0; 01366 char *res = *destructible; 01367 for (; destructible && *destructible && **destructible; (*destructible)++) { 01368 if (**destructible == '[' && !strchr(delim, '[')) { 01369 square++; 01370 } else if (**destructible == ']' && !strchr(delim, ']')) { 01371 if (square) { 01372 square--; 01373 } 01374 } else if (**destructible == '\\' && !strchr(delim, '\\')) { 01375 (*destructible)++; 01376 } else if (strchr(delim, **destructible) && !square) { 01377 **destructible = '\0'; 01378 (*destructible)++; 01379 break; 01380 } 01381 } 01382 if (destructible && *destructible && **destructible == '\0') { 01383 *destructible = NULL; 01384 } 01385 return res; 01386 }
| static int reload | ( | void | ) | [static] |
Definition at line 1813 of file pbx_config.c.
References pbx_builtin_clear_globals(), and pbx_load_module().
01814 { 01815 if (clearglobalvars_config) 01816 pbx_builtin_clear_globals(); 01817 return pbx_load_module(); 01818 }
| 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 1346 of file pbx_config.c.
References ARRAY_LEN, ast_cli_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), and ast_free.
01347 { 01348 if (static_config && !write_protect_config) 01349 ast_cli_unregister(&cli_dialplan_save); 01350 if (overrideswitch_config) { 01351 ast_free(overrideswitch_config); 01352 } 01353 ast_cli_unregister_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config)); 01354 ast_context_destroy(NULL, registrar); 01355 return 0; 01356 }
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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1824 of file pbx_config.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1824 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:
AST_CLI_DEFINE(handle_cli_dialplan_save, "Save dialplan")
Definition at line 1340 of file pbx_config.c.
struct ast_cli_entry cli_pbx_config[] [static] |
CLI entries for commands provided by this module
Definition at line 1329 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 58 of file pbx_config.c.
Referenced by ast_context_find_or_create(), and pbx_load_module().
struct ast_hashtab* local_table = NULL [static] |
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_MUTEX_INITIALIZER , 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.
1.5.6