#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 char * | config = "extensions.conf" |
| static int | extenpatternmatchnew_config = 0 |
| static struct ast_context * | local_contexts = NULL |
| static struct ast_hashtab * | local_table = NULL |
| static char * | overrideswitch_config = NULL |
| static char * | registrar = "pbx_config" |
| static ast_mutex_t | save_dialplan_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
| 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 1746 of file pbx_config.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1746 of file pbx_config.c.
| static void append_interface | ( | char * | iface, | |
| int | maxlen, | |||
| char * | add | |||
| ) | [static] |
Definition at line 1579 of file pbx_config.c.
References len().
Referenced by pbx_load_users().
01580 { 01581 int len = strlen(iface); 01582 if (strlen(add) + len < maxlen - 2) { 01583 if (strlen(iface)) { 01584 iface[len] = '&'; 01585 strcpy(iface + len + 1, add); 01586 } else 01587 strcpy(iface, add); 01588 } 01589 }
| static char * complete_dialplan_add_extension | ( | struct ast_cli_args * | a | ) | [static] |
dialplan add extension 6123,1,Dial,IAX/212.71.138.13/6123 into local
Definition at line 1014 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), len(), LOG_WARNING, ast_cli_args::n, partial_match(), ast_cli_args::pos, strdup, and ast_cli_args::word.
Referenced by handle_cli_dialplan_add_extension().
01015 { 01016 int which = 0; 01017 01018 if (a->pos == 4) { /* complete 'into' word ... */ 01019 return (a->n == 0) ? strdup("into") : NULL; 01020 } else if (a->pos == 5) { /* complete context */ 01021 struct ast_context *c = NULL; 01022 int len = strlen(a->word); 01023 char *res = NULL; 01024 01025 /* try to lock contexts list ... */ 01026 if (ast_rdlock_contexts()) { 01027 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01028 return NULL; 01029 } 01030 01031 /* walk through all contexts */ 01032 while ( !res && (c = ast_walk_contexts(c)) ) 01033 if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n) 01034 res = strdup(ast_get_context_name(c)); 01035 ast_unlock_contexts(); 01036 return res; 01037 } else if (a->pos == 6) { 01038 return a->n == 0 ? strdup("replace") : NULL; 01039 } 01040 return NULL; 01041 }
| static char * complete_dialplan_add_ignorepat | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 1100 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), free, len(), ast_cli_args::line, LOG_ERROR, lookup_c_ip(), ast_cli_args::n, partial_match(), ast_cli_args::pos, s, skip_words(), strdup, strsep(), and ast_cli_args::word.
Referenced by handle_cli_dialplan_add_ignorepat().
01101 { 01102 if (a->pos == 4) 01103 return a->n == 0 ? strdup("into") : NULL; 01104 else if (a->pos == 5) { 01105 struct ast_context *c; 01106 int which = 0; 01107 char *dupline, *ignorepat = NULL; 01108 const char *s; 01109 char *ret = NULL; 01110 int len = strlen(a->word); 01111 01112 /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */ 01113 s = skip_words(a->line, 3); 01114 if (s == NULL) 01115 return NULL; 01116 dupline = strdup(s); 01117 if (!dupline) { 01118 ast_log(LOG_ERROR, "Malloc failure\n"); 01119 return NULL; 01120 } 01121 ignorepat = strsep(&dupline, " "); 01122 01123 if (ast_rdlock_contexts()) { 01124 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 01125 return NULL; 01126 } 01127 01128 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01129 int found = 0; 01130 01131 if (!partial_match(ast_get_context_name(c), a->word, len)) 01132 continue; /* not mine */ 01133 if (ignorepat) /* there must be one, right ? */ 01134 found = lookup_c_ip(c, ignorepat); 01135 if (!found && ++which > a->n) 01136 ret = strdup(ast_get_context_name(c)); 01137 } 01138 01139 free(ignorepat); 01140 ast_unlock_contexts(); 01141 return ret; 01142 } 01143 01144 return NULL; 01145 }
| static char * complete_dialplan_add_include | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 575 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), context, free, len(), ast_cli_args::line, LOG_ERROR, lookup_ci(), ast_cli_args::n, partial_match(), ast_cli_args::pos, s, skip_words(), strdup, strsep(), and ast_cli_args::word.
Referenced by handle_cli_dialplan_add_include().
00576 { 00577 struct ast_context *c; 00578 int which = 0; 00579 char *ret = NULL; 00580 int len = strlen(a->word); 00581 00582 if (a->pos == 3) { /* 'dialplan add include _X_' (context) ... */ 00583 if (ast_rdlock_contexts()) { 00584 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00585 return NULL; 00586 } 00587 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) 00588 if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n) 00589 ret = strdup(ast_get_context_name(c)); 00590 ast_unlock_contexts(); 00591 return ret; 00592 } else if (a->pos == 4) { /* dialplan add include CTX _X_ */ 00593 /* complete as 'into' if context exists or we are unable to check */ 00594 char *context, *dupline; 00595 const char *s = skip_words(a->line, 3); /* should not fail */ 00596 00597 if (a->n != 0) /* only once */ 00598 return NULL; 00599 00600 /* parse context from line ... */ 00601 context = dupline = strdup(s); 00602 if (!context) { 00603 ast_log(LOG_ERROR, "Out of free memory\n"); 00604 return strdup("into"); 00605 } 00606 strsep(&dupline, " "); 00607 00608 /* check for context existence ... */ 00609 if (ast_rdlock_contexts()) { 00610 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00611 /* our fault, we can't check, so complete 'into' ... */ 00612 ret = strdup("into"); 00613 } else { 00614 struct ast_context *ctx; 00615 for (ctx = NULL; !ret && (ctx = ast_walk_contexts(ctx)); ) 00616 if (!strcmp(context, ast_get_context_name(ctx))) 00617 ret = strdup("into"); /* found */ 00618 ast_unlock_contexts(); 00619 } 00620 free(context); 00621 return ret; 00622 } else if (a->pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */ 00623 char *context, *dupline, *into; 00624 const char *s = skip_words(a->line, 3); /* should not fail */ 00625 context = dupline = strdup(s); 00626 if (!dupline) { 00627 ast_log(LOG_ERROR, "Out of free memory\n"); 00628 return NULL; 00629 } 00630 strsep(&dupline, " "); /* skip context */ 00631 into = strsep(&dupline, " "); 00632 /* error if missing context or fifth word is not 'into' */ 00633 if (!strlen(context) || strcmp(into, "into")) { 00634 ast_log(LOG_ERROR, "bad context %s or missing into %s\n", 00635 context, into); 00636 goto error3; 00637 } 00638 00639 if (ast_rdlock_contexts()) { 00640 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00641 goto error3; 00642 } 00643 00644 for (c = NULL; (c = ast_walk_contexts(c)); ) 00645 if (!strcmp(context, ast_get_context_name(c))) 00646 break; 00647 if (c) { /* first context exists, go on... */ 00648 /* go through all contexts ... */ 00649 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 00650 if (!strcmp(context, ast_get_context_name(c))) 00651 continue; /* skip ourselves */ 00652 if (partial_match(ast_get_context_name(c), a->word, len) && 00653 !lookup_ci(c, context) /* not included yet */ && 00654 ++which > a->n) 00655 ret = strdup(ast_get_context_name(c)); 00656 } 00657 } else { 00658 ast_log(LOG_ERROR, "context %s not found\n", context); 00659 } 00660 ast_unlock_contexts(); 00661 error3: 00662 free(context); 00663 return ret; 00664 } 00665 00666 return NULL; 00667 }
| static char * complete_dialplan_remove_extension | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 392 of file pbx_config.c.
References asprintf, ast_get_context_name(), ast_get_extension_cidmatch(), ast_get_extension_matchcid(), ast_get_extension_name(), ast_get_extension_priority(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), context, errno, exten, free, len(), ast_cli_args::line, LOG_ERROR, LOG_WARNING, ast_cli_args::n, partial_match(), ast_cli_args::pos, ast_exten::priority, s, skip_words(), split_ec(), strdup, and ast_cli_args::word.
Referenced by handle_cli_dialplan_remove_extension().
00393 { 00394 char *ret = NULL; 00395 int which = 0; 00396 00397 if (a->pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */ 00398 struct ast_context *c = NULL; 00399 char *context = NULL, *exten = NULL, *cid = NULL; 00400 int le = 0; /* length of extension */ 00401 int lc = 0; /* length of context */ 00402 int lcid = 0; /* length of cid */ 00403 00404 lc = split_ec(a->word, &exten, &context, &cid); 00405 if (lc) { /* error */ 00406 return NULL; 00407 } 00408 le = strlen(exten); 00409 lc = strlen(context); 00410 lcid = cid ? strlen(cid) : -1; 00411 00412 if (ast_rdlock_contexts()) { 00413 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00414 goto error2; 00415 } 00416 00417 /* find our context ... */ 00418 while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */ 00419 struct ast_exten *e = NULL; 00420 /* XXX locking ? */ 00421 if (!partial_match(ast_get_context_name(c), context, lc)) 00422 continue; /* context not matched */ 00423 while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */ 00424 if ( !strchr(a->word, '/') || 00425 (!strchr(a->word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) || 00426 (strchr(a->word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) { 00427 if ( ((strchr(a->word, '/') || strchr(a->word, '@')) && !strcmp(ast_get_extension_name(e), exten)) || 00428 (!strchr(a->word, '/') && !strchr(a->word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */ 00429 if (++which > a->n) { 00430 /* If there is an extension then return exten@context. */ 00431 if (ast_get_extension_matchcid(e) && (!strchr(a->word, '@') || strchr(a->word, '/'))) { 00432 if (asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)) < 0) { 00433 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00434 ret = NULL; 00435 } 00436 break; 00437 } else if (!ast_get_extension_matchcid(e) && !strchr(a->word, '/')) { 00438 if (asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) { 00439 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00440 ret = NULL; 00441 } 00442 break; 00443 } 00444 } 00445 } 00446 } 00447 } 00448 if (e) /* got a match */ 00449 break; 00450 } 00451 00452 ast_unlock_contexts(); 00453 error2: 00454 free(exten); 00455 } else if (a->pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */ 00456 char *exten = NULL, *context, *cid, *p; 00457 struct ast_context *c; 00458 int le, lc, lcid, len; 00459 const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'extension' */ 00460 int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */ 00461 00462 if (i) /* error */ 00463 goto error3; 00464 if ( (p = strchr(exten, ' ')) ) /* remove space after extension */ 00465 *p = '\0'; 00466 if ( (p = strchr(context, ' ')) ) /* remove space after context */ 00467 *p = '\0'; 00468 le = strlen(exten); 00469 lc = strlen(context); 00470 lcid = strlen(cid); 00471 len = strlen(a->word); 00472 if (le == 0 || lc == 0) 00473 goto error3; 00474 00475 if (ast_rdlock_contexts()) { 00476 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00477 goto error3; 00478 } 00479 00480 /* walk contexts */ 00481 c = NULL; 00482 while ( (c = ast_walk_contexts(c)) ) { 00483 /* XXX locking on c ? */ 00484 struct ast_exten *e; 00485 if (strcmp(ast_get_context_name(c), context) != 0) 00486 continue; 00487 /* got it, we must match here */ 00488 e = NULL; 00489 while ( (e = ast_walk_context_extensions(c, e)) ) { 00490 struct ast_exten *priority; 00491 char buffer[10]; 00492 00493 if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) { 00494 continue; 00495 } 00496 if (strcmp(ast_get_extension_name(e), exten) != 0) 00497 continue; 00498 /* XXX lock e ? */ 00499 priority = NULL; 00500 while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) { 00501 snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority)); 00502 if (partial_match(buffer, a->word, len) && ++which > a->n) /* n-th match */ 00503 ret = strdup(buffer); 00504 } 00505 break; 00506 } 00507 break; 00508 } 00509 ast_unlock_contexts(); 00510 error3: 00511 free(exten); 00512 } 00513 return ret; 00514 }
| static char * complete_dialplan_remove_ignorepat | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 1196 of file pbx_config.c.
References ast_get_context_name(), ast_get_ignorepat_name(), ast_log(), ast_rdlock_context(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_ignorepats(), ast_walk_contexts(), free, len(), ast_cli_args::line, LOG_WARNING, lookup_c_ip(), ast_cli_args::n, partial_match(), ast_cli_args::pos, strdup, strsep(), and ast_cli_args::word.
Referenced by handle_cli_dialplan_remove_ignorepat().
01197 { 01198 struct ast_context *c; 01199 int which = 0; 01200 char *ret = NULL; 01201 01202 if (a->pos == 3) { 01203 int len = strlen(a->word); 01204 if (ast_rdlock_contexts()) { 01205 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01206 return NULL; 01207 } 01208 01209 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01210 struct ast_ignorepat *ip; 01211 01212 if (ast_rdlock_context(c)) /* error, skip it */ 01213 continue; 01214 01215 for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) { 01216 if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) { 01217 /* n-th match */ 01218 struct ast_context *cw = NULL; 01219 int found = 0; 01220 while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) { 01221 /* XXX do i stop on c, or skip it ? */ 01222 found = lookup_c_ip(cw, ast_get_ignorepat_name(ip)); 01223 } 01224 if (!found) 01225 ret = strdup(ast_get_ignorepat_name(ip)); 01226 } 01227 } 01228 ast_unlock_context(c); 01229 } 01230 ast_unlock_contexts(); 01231 return ret; 01232 } else if (a->pos == 4) { 01233 return a->n == 0 ? strdup("from") : NULL; 01234 } else if (a->pos == 5) { /* XXX check this */ 01235 char *dupline, *duplinet, *ignorepat; 01236 int len = strlen(a->word); 01237 01238 dupline = strdup(a->line); 01239 if (!dupline) { 01240 ast_log(LOG_WARNING, "Out of free memory\n"); 01241 return NULL; 01242 } 01243 01244 duplinet = dupline; 01245 strsep(&duplinet, " "); 01246 strsep(&duplinet, " "); 01247 ignorepat = strsep(&duplinet, " "); 01248 01249 if (!ignorepat) { 01250 free(dupline); 01251 return NULL; 01252 } 01253 01254 if (ast_rdlock_contexts()) { 01255 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01256 free(dupline); 01257 return NULL; 01258 } 01259 01260 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 01261 if (ast_rdlock_context(c)) /* fail, skip it */ 01262 continue; 01263 if (!partial_match(ast_get_context_name(c), a->word, len)) 01264 continue; 01265 if (lookup_c_ip(c, ignorepat) && ++which > a->n) 01266 ret = strdup(ast_get_context_name(c)); 01267 ast_unlock_context(c); 01268 } 01269 ast_unlock_contexts(); 01270 free(dupline); 01271 return NULL; 01272 } 01273 01274 return NULL; 01275 }
| static char * complete_dialplan_remove_include | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 182 of file pbx_config.c.
References ast_get_context_name(), ast_get_include_name(), ast_log(), ast_rdlock_context(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_includes(), ast_walk_contexts(), ast_wrlock_contexts(), context, free, len(), ast_cli_args::line, LOG_ERROR, LOG_WARNING, lookup_ci(), ast_cli_args::n, partial_match(), ast_cli_args::pos, s, skip_words(), strdup, strsep(), and ast_cli_args::word.
Referenced by handle_cli_dialplan_remove_include().
00183 { 00184 int which = 0; 00185 char *res = NULL; 00186 int len = strlen(a->word); /* how many bytes to match */ 00187 struct ast_context *c = NULL; 00188 00189 if (a->pos == 3) { /* "dialplan remove include _X_" */ 00190 if (ast_wrlock_contexts()) { 00191 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00192 return NULL; 00193 } 00194 /* walk contexts and their includes, return the n-th match */ 00195 while (!res && (c = ast_walk_contexts(c))) { 00196 struct ast_include *i = NULL; 00197 00198 if (ast_rdlock_context(c)) /* error ? skip this one */ 00199 continue; 00200 00201 while ( !res && (i = ast_walk_context_includes(c, i)) ) { 00202 const char *i_name = ast_get_include_name(i); 00203 struct ast_context *nc = NULL; 00204 int already_served = 0; 00205 00206 if (!partial_match(i_name, a->word, len)) 00207 continue; /* not matched */ 00208 00209 /* check if this include is already served or not */ 00210 00211 /* go through all contexts again till we reach actual 00212 * context or already_served = 1 00213 */ 00214 while ( (nc = ast_walk_contexts(nc)) && nc != c && !already_served) 00215 already_served = lookup_ci(nc, i_name); 00216 00217 if (!already_served && ++which > a->n) 00218 res = strdup(i_name); 00219 } 00220 ast_unlock_context(c); 00221 } 00222 00223 ast_unlock_contexts(); 00224 return res; 00225 } else if (a->pos == 4) { /* "dialplan remove include CTX _X_" */ 00226 /* 00227 * complete as 'from', but only if previous context is really 00228 * included somewhere 00229 */ 00230 char *context, *dupline; 00231 const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */ 00232 00233 if (a->n > 0) 00234 return NULL; 00235 context = dupline = strdup(s); 00236 if (!dupline) { 00237 ast_log(LOG_ERROR, "Out of free memory\n"); 00238 return NULL; 00239 } 00240 strsep(&dupline, " "); 00241 00242 if (ast_rdlock_contexts()) { 00243 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 00244 free(context); 00245 return NULL; 00246 } 00247 00248 /* go through all contexts and check if is included ... */ 00249 while (!res && (c = ast_walk_contexts(c))) 00250 if (lookup_ci(c, context)) /* context is really included, complete "from" command */ 00251 res = strdup("from"); 00252 ast_unlock_contexts(); 00253 if (!res) 00254 ast_log(LOG_WARNING, "%s not included anywhere\n", context); 00255 free(context); 00256 return res; 00257 } else if (a->pos == 5) { /* "dialplan remove include CTX from _X_" */ 00258 /* 00259 * Context from which we removing include ... 00260 */ 00261 char *context, *dupline, *from; 00262 const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */ 00263 context = dupline = strdup(s); 00264 if (!dupline) { 00265 ast_log(LOG_ERROR, "Out of free memory\n"); 00266 return NULL; 00267 } 00268 00269 strsep(&dupline, " "); /* skip context */ 00270 00271 /* fourth word must be 'from' */ 00272 from = strsep(&dupline, " "); 00273 if (!from || strcmp(from, "from")) { 00274 free(context); 00275 return NULL; 00276 } 00277 00278 if (ast_rdlock_contexts()) { 00279 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00280 free(context); 00281 return NULL; 00282 } 00283 00284 /* walk through all contexts ... */ 00285 c = NULL; 00286 while ( !res && (c = ast_walk_contexts(c))) { 00287 const char *c_name = ast_get_context_name(c); 00288 if (!partial_match(c_name, a->word, len)) /* not a good target */ 00289 continue; 00290 /* walk through all includes and check if it is our context */ 00291 if (lookup_ci(c, context) && ++which > a->n) 00292 res = strdup(c_name); 00293 } 00294 ast_unlock_contexts(); 00295 free(context); 00296 return res; 00297 } 00298 00299 return NULL; 00300 }
| static char* handle_cli_dialplan_add_extension | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
ADD EXTENSION command stuff.
Definition at line 902 of file pbx_config.c.
References app, ast_cli_args::argc, ast_cli_args::argv, ast_add_extension(), ast_cli(), ast_free_ptr, ast_strdupa, ast_exten::cidmatch, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_extension(), errno, exten, ast_cli_args::fd, PRIORITY_HINT, strdup, strsep(), and ast_cli_entry::usage.
00903 { 00904 char *whole_exten; 00905 char *exten, *prior; 00906 int iprior = -2; 00907 char *cidmatch, *app, *app_data; 00908 char *start, *end; 00909 00910 switch (cmd) { 00911 case CLI_INIT: 00912 e->command = "dialplan add extension"; 00913 e->usage = 00914 "Usage: dialplan add extension <exten>,<priority>,<app>,<app-data>\n" 00915 " into <context> [replace]\n\n" 00916 " This command will add new extension into <context>. If there is an\n" 00917 " existence of extension with the same priority and last 'replace'\n" 00918 " arguments is given here we simply replace this extension.\n" 00919 "\n" 00920 "Example: dialplan add extension 6123,1,Dial,IAX/216.207.245.56/6123 into local\n" 00921 " Now, you can dial 6123 and talk to Markster :)\n"; 00922 return NULL; 00923 case CLI_GENERATE: 00924 return complete_dialplan_add_extension(a); 00925 } 00926 00927 /* check for arguments at first */ 00928 if (a->argc != 6 && a->argc != 7) 00929 return CLI_SHOWUSAGE; 00930 if (strcmp(a->argv[4], "into")) 00931 return CLI_SHOWUSAGE; 00932 if (a->argc == 7) 00933 if (strcmp(a->argv[6], "replace")) 00934 return CLI_SHOWUSAGE; 00935 00936 whole_exten = ast_strdupa(a->argv[3]); 00937 exten = strsep(&whole_exten,","); 00938 if (strchr(exten, '/')) { 00939 cidmatch = exten; 00940 strsep(&cidmatch,"/"); 00941 } else { 00942 cidmatch = NULL; 00943 } 00944 prior = strsep(&whole_exten,","); 00945 if (prior) { 00946 if (!strcmp(prior, "hint")) { 00947 iprior = PRIORITY_HINT; 00948 } else { 00949 if (sscanf(prior, "%30d", &iprior) != 1) { 00950 ast_cli(a->fd, "'%s' is not a valid priority\n", prior); 00951 prior = NULL; 00952 } 00953 } 00954 } 00955 app = whole_exten; 00956 if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) { 00957 *start = *end = '\0'; 00958 app_data = start + 1; 00959 } else { 00960 if (app) { 00961 app_data = strchr(app, ','); 00962 if (app_data) { 00963 *app_data = '\0'; 00964 app_data++; 00965 } 00966 } else 00967 app_data = NULL; 00968 } 00969 00970 if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT)) 00971 return CLI_SHOWUSAGE; 00972 00973 if (!app_data) 00974 app_data=""; 00975 if (ast_add_extension(a->argv[5], a->argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app, 00976 (void *)strdup(app_data), ast_free_ptr, registrar)) { 00977 switch (errno) { 00978 case ENOMEM: 00979 ast_cli(a->fd, "Out of free memory\n"); 00980 break; 00981 00982 case EBUSY: 00983 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 00984 break; 00985 00986 case ENOENT: 00987 ast_cli(a->fd, "No existence of '%s' context\n", a->argv[5]); 00988 break; 00989 00990 case EEXIST: 00991 ast_cli(a->fd, "Extension %s@%s with priority %s already exists\n", 00992 exten, a->argv[5], prior); 00993 break; 00994 00995 default: 00996 ast_cli(a->fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n", 00997 exten, prior, app, app_data, a->argv[5]); 00998 break; 00999 } 01000 return CLI_FAILURE; 01001 } 01002 01003 if (a->argc == 7) 01004 ast_cli(a->fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n", 01005 exten, a->argv[5], prior, exten, prior, app, app_data); 01006 else 01007 ast_cli(a->fd, "Extension '%s,%s,%s,%s' added into '%s' context\n", 01008 exten, prior, app, app_data, a->argv[5]); 01009 01010 return CLI_SUCCESS; 01011 }
| static char* handle_cli_dialplan_add_ignorepat | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
IGNOREPAT CLI stuff
Definition at line 1046 of file pbx_config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_add_ignorepat(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_ignorepat(), errno, ast_cli_args::fd, and ast_cli_entry::usage.
01047 { 01048 switch (cmd) { 01049 case CLI_INIT: 01050 e->command = "dialplan add ignorepat"; 01051 e->usage = 01052 "Usage: dialplan add ignorepat <pattern> into <context>\n" 01053 " This command adds a new ignore pattern into context <context>\n" 01054 "\n" 01055 "Example: dialplan add ignorepat _3XX into local\n"; 01056 return NULL; 01057 case CLI_GENERATE: 01058 return complete_dialplan_add_ignorepat(a); 01059 } 01060 01061 if (a->argc != 6) 01062 return CLI_SHOWUSAGE; 01063 01064 if (strcmp(a->argv[4], "into")) 01065 return CLI_SHOWUSAGE; 01066 01067 if (ast_context_add_ignorepat(a->argv[5], a->argv[3], registrar)) { 01068 switch (errno) { 01069 case ENOMEM: 01070 ast_cli(a->fd, "Out of free memory\n"); 01071 break; 01072 01073 case ENOENT: 01074 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01075 break; 01076 01077 case EEXIST: 01078 ast_cli(a->fd, "Ignore pattern '%s' already included in '%s' context\n", 01079 a->argv[3], a->argv[5]); 01080 break; 01081 01082 case EBUSY: 01083 ast_cli(a->fd, "Failed to lock context(s) list, please, try again later\n"); 01084 break; 01085 01086 default: 01087 ast_cli(a->fd, "Failed to add ingore pattern '%s' into '%s' context\n", 01088 a->argv[3], a->argv[5]); 01089 break; 01090 } 01091 return CLI_FAILURE; 01092 } 01093 01094 ast_cli(a->fd, "Ignore pattern '%s' added into '%s' context\n", 01095 a->argv[3], a->argv[5]); 01096 01097 return CLI_SUCCESS; 01098 }
| static char* handle_cli_dialplan_add_include | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Include context ...
Definition at line 519 of file pbx_config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_add_include(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_include(), errno, ast_cli_args::fd, and ast_cli_entry::usage.
00520 { 00521 switch (cmd) { 00522 case CLI_INIT: 00523 e->command = "dialplan add include"; 00524 e->usage = 00525 "Usage: dialplan add include <context> into <context>\n" 00526 " Include a context in another context.\n"; 00527 return NULL; 00528 case CLI_GENERATE: 00529 return complete_dialplan_add_include(a); 00530 } 00531 00532 if (a->argc != 6) /* dialplan add include CTX in CTX */ 00533 return CLI_SHOWUSAGE; 00534 00535 /* fifth arg must be 'into' ... */ 00536 if (strcmp(a->argv[4], "into")) 00537 return CLI_SHOWUSAGE; 00538 00539 if (ast_context_add_include(a->argv[5], a->argv[3], registrar)) { 00540 switch (errno) { 00541 case ENOMEM: 00542 ast_cli(a->fd, "Out of memory for context addition\n"); 00543 break; 00544 00545 case EBUSY: 00546 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 00547 break; 00548 00549 case EEXIST: 00550 ast_cli(a->fd, "Context '%s' already included in '%s' context\n", 00551 a->argv[3], a->argv[5]); 00552 break; 00553 00554 case ENOENT: 00555 case EINVAL: 00556 ast_cli(a->fd, "There is no existence of context '%s'\n", 00557 errno == ENOENT ? a->argv[5] : a->argv[3]); 00558 break; 00559 00560 default: 00561 ast_cli(a->fd, "Failed to include '%s' in '%s' context\n", 00562 a->argv[3], a->argv[5]); 00563 break; 00564 } 00565 return CLI_FAILURE; 00566 } 00567 00568 /* show some info ... */ 00569 ast_cli(a->fd, "Context '%s' included in '%s' context\n", 00570 a->argv[3], a->argv[5]); 00571 00572 return CLI_SUCCESS; 00573 }
| static char* handle_cli_dialplan_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1279 of file pbx_config.c.
References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, pbx_builtin_clear_globals(), pbx_load_module(), and ast_cli_entry::usage.
01280 { 01281 switch (cmd) { 01282 case CLI_INIT: 01283 e->command = "dialplan reload"; 01284 e->usage = 01285 "Usage: dialplan reload\n" 01286 " Reload extensions.conf without reloading any other\n" 01287 " modules. This command does not delete global variables\n" 01288 " unless clearglobalvars is set to yes in extensions.conf\n"; 01289 return NULL; 01290 case CLI_GENERATE: 01291 return NULL; 01292 } 01293 01294 if (a->argc != 2) 01295 return CLI_SHOWUSAGE; 01296 01297 if (clearglobalvars_config) 01298 pbx_builtin_clear_globals(); 01299 01300 pbx_load_module(); 01301 ast_cli(a->fd, "Dialplan reloaded.\n"); 01302 return CLI_SUCCESS; 01303 }
| static char* handle_cli_dialplan_remove_extension | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
REMOVE EXTENSION command stuff
Definition at line 305 of file pbx_config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_remove_extension_callerid(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_remove_extension(), context, exten, ast_cli_args::fd, free, PRIORITY_HINT, split_ec(), and ast_cli_entry::usage.
00306 { 00307 int removing_priority = 0; 00308 char *exten, *context, *cid; 00309 char *ret = CLI_FAILURE; 00310 00311 switch (cmd) { 00312 case CLI_INIT: 00313 e->command = "dialplan remove extension"; 00314 e->usage = 00315 "Usage: dialplan remove extension exten[/cid]@context [priority]\n" 00316 " Remove an extension from a given context. If a priority\n" 00317 " is given, only that specific priority from the given extension\n" 00318 " will be removed.\n"; 00319 return NULL; 00320 case CLI_GENERATE: 00321 return complete_dialplan_remove_extension(a); 00322 } 00323 00324 if (a->argc != 5 && a->argc != 4) 00325 return CLI_SHOWUSAGE; 00326 00327 /* 00328 * Priority input checking ... 00329 */ 00330 if (a->argc == 5) { 00331 const char *c = a->argv[4]; 00332 00333 /* check for digits in whole parameter for right priority ... 00334 * why? because atoi (strtol) returns 0 if any characters in 00335 * string and whole extension will be removed, it's not good 00336 */ 00337 if (!strcmp("hint", c)) 00338 removing_priority = PRIORITY_HINT; 00339 else { 00340 while (*c && isdigit(*c)) 00341 c++; 00342 if (*c) { /* non-digit in string */ 00343 ast_cli(a->fd, "Invalid priority '%s'\n", a->argv[4]); 00344 return CLI_FAILURE; 00345 } 00346 removing_priority = atoi(a->argv[4]); 00347 } 00348 00349 if (removing_priority == 0) { 00350 ast_cli(a->fd, "If you want to remove whole extension, please " \ 00351 "omit priority argument\n"); 00352 return CLI_FAILURE; 00353 } 00354 } 00355 00356 /* XXX original overwrote argv[3] */ 00357 /* 00358 * Format exten@context checking ... 00359 */ 00360 if (split_ec(a->argv[3], &exten, &context, &cid)) 00361 return CLI_FAILURE; /* XXX malloc failure */ 00362 if ((!strlen(exten)) || (!(strlen(context)))) { 00363 ast_cli(a->fd, "Missing extension or context name in third argument '%s'\n", 00364 a->argv[3]); 00365 free(exten); 00366 return CLI_FAILURE; 00367 } 00368 00369 if (!ast_context_remove_extension_callerid(context, exten, removing_priority, 00370 /* Do NOT substitute S_OR; it is NOT the same thing */ 00371 cid ? cid : (removing_priority ? "" : NULL), cid ? 1 : 0, registrar)) { 00372 if (!removing_priority) 00373 ast_cli(a->fd, "Whole extension %s@%s removed\n", 00374 exten, context); 00375 else 00376 ast_cli(a->fd, "Extension %s@%s with priority %d removed\n", 00377 exten, context, removing_priority); 00378 00379 ret = CLI_SUCCESS; 00380 } else { 00381 if (cid) { 00382 ast_cli(a->fd, "Failed to remove extension %s/%s@%s\n", exten, cid, context); 00383 } else { 00384 ast_cli(a->fd, "Failed to remove extension %s@%s\n", exten, context); 00385 } 00386 ret = CLI_FAILURE; 00387 } 00388 free(exten); 00389 return ret; 00390 }
| static char* handle_cli_dialplan_remove_ignorepat | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1147 of file pbx_config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_remove_ignorepat(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_remove_ignorepat(), errno, ast_cli_args::fd, and ast_cli_entry::usage.
01148 { 01149 switch (cmd) { 01150 case CLI_INIT: 01151 e->command = "dialplan remove ignorepat"; 01152 e->usage = 01153 "Usage: dialplan remove ignorepat <pattern> from <context>\n" 01154 " This command removes an ignore pattern from context <context>\n" 01155 "\n" 01156 "Example: dialplan remove ignorepat _3XX from local\n"; 01157 return NULL; 01158 case CLI_GENERATE: 01159 return complete_dialplan_remove_ignorepat(a); 01160 } 01161 01162 if (a->argc != 6) 01163 return CLI_SHOWUSAGE; 01164 01165 if (strcmp(a->argv[4], "from")) 01166 return CLI_SHOWUSAGE; 01167 01168 if (ast_context_remove_ignorepat(a->argv[5], a->argv[3], registrar)) { 01169 switch (errno) { 01170 case EBUSY: 01171 ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n"); 01172 break; 01173 01174 case ENOENT: 01175 ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]); 01176 break; 01177 01178 case EINVAL: 01179 ast_cli(a->fd, "There is no existence of '%s' ignore pattern in '%s' context\n", 01180 a->argv[3], a->argv[5]); 01181 break; 01182 01183 default: 01184 ast_cli(a->fd, "Failed to remove ignore pattern '%s' from '%s' context\n", 01185 a->argv[3], a->argv[5]); 01186 break; 01187 } 01188 return CLI_FAILURE; 01189 } 01190 01191 ast_cli(a->fd, "Ignore pattern '%s' removed from '%s' context\n", 01192 a->argv[3], a->argv[5]); 01193 return CLI_SUCCESS; 01194 }
| static char* handle_cli_dialplan_remove_include | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
REMOVE INCLUDE command stuff
Definition at line 73 of file pbx_config.c.
References ast_cli_args::argv, ast_cli(), ast_context_remove_include(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_remove_include(), ast_cli_args::fd, and ast_cli_entry::usage.
00074 { 00075 switch (cmd) { 00076 case CLI_INIT: 00077 e->command = "dialplan remove include"; 00078 e->usage = 00079 "Usage: dialplan remove include <context> from <context>\n" 00080 " Remove an included context from another context.\n"; 00081 return NULL; 00082 case CLI_GENERATE: 00083 return complete_dialplan_remove_include(a); 00084 } 00085 00086 if (strcmp(a->argv[4], "from")) 00087 return CLI_SHOWUSAGE; 00088 00089 if (!ast_context_remove_include(a->argv[5], a->argv[3], registrar)) { 00090 ast_cli(a->fd, "We are not including '%s' into '%s' now\n", 00091 a->argv[3], a->argv[5]); 00092 return CLI_SUCCESS; 00093 } 00094 00095 ast_cli(a->fd, "Failed to remove '%s' include from '%s' context\n", 00096 a->argv[3], a->argv[5]); 00097 return CLI_FAILURE; 00098 }
| static char* handle_cli_dialplan_save | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
'save dialplan' CLI command implementation functions ...
Definition at line 672 of file pbx_config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_config_AST_CONFIG_DIR, ast_config_destroy(), ast_config_load, ast_get_context_name(), ast_get_context_registrar(), ast_get_extension_app(), ast_get_extension_app_data(), ast_get_extension_cidmatch(), ast_get_extension_label(), ast_get_extension_matchcid(), ast_get_extension_name(), ast_get_extension_priority(), ast_get_extension_registrar(), ast_get_ignorepat_name(), ast_get_ignorepat_registrar(), ast_get_include_name(), ast_get_include_registrar(), ast_get_switch_data(), ast_get_switch_name(), ast_get_switch_registrar(), ast_mutex_lock(), ast_mutex_unlock(), ast_rdlock_context(), ast_rdlock_contexts(), ast_strlen_zero(), ast_unlock_context(), ast_unlock_contexts(), ast_variable_browse(), ast_walk_context_extensions(), ast_walk_context_ignorepats(), ast_walk_context_includes(), ast_walk_context_switches(), ast_walk_contexts(), ast_walk_extension_priorities(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, el, ext, ast_cli_args::fd, ast_exten::label, ast_variable::name, ast_variable::next, overrideswitch, PRIORITY_HINT, PUT_CTX_HDR, save_dialplan_lock, ast_cli_entry::usage, and ast_variable::value.
00673 { 00674 char filename[256], overrideswitch[256] = ""; 00675 struct ast_context *c; 00676 struct ast_config *cfg; 00677 struct ast_variable *v; 00678 int incomplete = 0; /* incomplete config write? */ 00679 FILE *output; 00680 struct ast_flags config_flags = { 0 }; 00681 const char *base, *slash, *file; 00682 00683 switch (cmd) { 00684 case CLI_INIT: 00685 e->command = "dialplan save"; 00686 e->usage = 00687 "Usage: dialplan save [/path/to/extension/file]\n" 00688 " Save dialplan created by pbx_config module.\n" 00689 "\n" 00690 "Example: dialplan save (/etc/asterisk/extensions.conf)\n" 00691 " dialplan save /home/markster (/home/markster/extensions.conf)\n"; 00692 return NULL; 00693 case CLI_GENERATE: 00694 return NULL; 00695 } 00696 00697 if (! (static_config && !write_protect_config)) { 00698 ast_cli(a->fd, 00699 "I can't save dialplan now, see '%s' example file.\n", 00700 config); 00701 return CLI_FAILURE; 00702 } 00703 00704 if (a->argc != 2 && a->argc != 3) 00705 return CLI_SHOWUSAGE; 00706 00707 if (ast_mutex_lock(&save_dialplan_lock)) { 00708 ast_cli(a->fd, 00709 "Failed to lock dialplan saving (another proccess saving?)\n"); 00710 return CLI_FAILURE; 00711 } 00712 /* XXX the code here is quite loose, a pathname with .conf in it 00713 * is assumed to be a complete pathname 00714 */ 00715 if (a->argc == 3) { /* have config path. Look for *.conf */ 00716 base = a->argv[2]; 00717 if (!strstr(a->argv[2], ".conf")) { /*no, this is assumed to be a pathname */ 00718 /* if filename ends with '/', do not add one */ 00719 slash = (*(a->argv[2] + strlen(a->argv[2]) -1) == '/') ? "/" : ""; 00720 file = config; /* default: 'extensions.conf' */ 00721 } else { /* yes, complete file name */ 00722 slash = ""; 00723 file = ""; 00724 } 00725 } else { 00726 /* no config file, default one */ 00727 base = ast_config_AST_CONFIG_DIR; 00728 slash = "/"; 00729 file = config; 00730 } 00731 snprintf(filename, sizeof(filename), "%s%s%s", base, slash, config); 00732 00733 cfg = ast_config_load("extensions.conf", config_flags); 00734 00735 /* try to lock contexts list */ 00736 if (ast_rdlock_contexts()) { 00737 ast_cli(a->fd, "Failed to lock contexts list\n"); 00738 ast_mutex_unlock(&save_dialplan_lock); 00739 ast_config_destroy(cfg); 00740 return CLI_FAILURE; 00741 } 00742 00743 /* create new file ... */ 00744 if (!(output = fopen(filename, "wt"))) { 00745 ast_cli(a->fd, "Failed to create file '%s'\n", 00746 filename); 00747 ast_unlock_contexts(); 00748 ast_mutex_unlock(&save_dialplan_lock); 00749 ast_config_destroy(cfg); 00750 return CLI_FAILURE; 00751 } 00752 00753 /* fireout general info */ 00754 if (overrideswitch_config) { 00755 snprintf(overrideswitch, sizeof(overrideswitch), "overrideswitch=%s\n", overrideswitch_config); 00756 } 00757 fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\n%sextenpatternmatchnew=%s\n\n", 00758 static_config ? "yes" : "no", 00759 write_protect_config ? "yes" : "no", 00760 autofallthrough_config ? "yes" : "no", 00761 clearglobalvars_config ? "yes" : "no", 00762 overrideswitch_config ? overrideswitch : "", 00763 extenpatternmatchnew_config ? "yes" : "no"); 00764 00765 if ((v = ast_variable_browse(cfg, "globals"))) { 00766 fprintf(output, "[globals]\n"); 00767 while(v) { 00768 fprintf(output, "%s => %s\n", v->name, v->value); 00769 v = v->next; 00770 } 00771 fprintf(output, "\n"); 00772 } 00773 00774 ast_config_destroy(cfg); 00775 00776 #define PUT_CTX_HDR do { \ 00777 if (!context_header_written) { \ 00778 fprintf(output, "[%s]\n", ast_get_context_name(c)); \ 00779 context_header_written = 1; \ 00780 } \ 00781 } while (0) 00782 00783 /* walk all contexts */ 00784 for (c = NULL; (c = ast_walk_contexts(c)); ) { 00785 int context_header_written = 0; 00786 struct ast_exten *ext, *last_written_e = NULL; 00787 struct ast_include *i; 00788 struct ast_ignorepat *ip; 00789 struct ast_sw *sw; 00790 00791 /* try to lock context and fireout all info */ 00792 if (ast_rdlock_context(c)) { /* lock failure */ 00793 incomplete = 1; 00794 continue; 00795 } 00796 /* registered by this module? */ 00797 /* XXX do we need this ? */ 00798 if (!strcmp(ast_get_context_registrar(c), registrar)) { 00799 fprintf(output, "[%s]\n", ast_get_context_name(c)); 00800 context_header_written = 1; 00801 } 00802 00803 /* walk extensions ... */ 00804 for (ext = NULL; (ext = ast_walk_context_extensions(c, ext)); ) { 00805 struct ast_exten *p = NULL; 00806 00807 /* fireout priorities */ 00808 while ( (p = ast_walk_extension_priorities(ext, p)) ) { 00809 if (strcmp(ast_get_extension_registrar(p), registrar) != 0) /* not this source */ 00810 continue; 00811 00812 /* make empty line between different extensions */ 00813 if (last_written_e != NULL && 00814 strcmp(ast_get_extension_name(last_written_e), 00815 ast_get_extension_name(p))) 00816 fprintf(output, "\n"); 00817 last_written_e = p; 00818 00819 PUT_CTX_HDR; 00820 00821 if (ast_get_extension_priority(p) == PRIORITY_HINT) { /* easy */ 00822 fprintf(output, "exten => %s,hint,%s\n", 00823 ast_get_extension_name(p), 00824 ast_get_extension_app(p)); 00825 } else { 00826 const char *sep, *cid; 00827 const char *el = ast_get_extension_label(p); 00828 char label[128] = ""; 00829 00830 if (ast_get_extension_matchcid(p)) { 00831 sep = "/"; 00832 cid = ast_get_extension_cidmatch(p); 00833 } else 00834 sep = cid = ""; 00835 00836 if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2))) 00837 incomplete = 1; /* error encountered or label > 125 chars */ 00838 00839 fprintf(output, "exten => %s%s%s,%d%s,%s(%s)\n", 00840 ast_get_extension_name(p), (ast_strlen_zero(sep) ? "" : sep), (ast_strlen_zero(cid) ? "" : cid), 00841 ast_get_extension_priority(p), label, 00842 ast_get_extension_app(p), (ast_strlen_zero(ast_get_extension_app_data(p)) ? "" : (const char *)ast_get_extension_app_data(p))); 00843 } 00844 } 00845 } 00846 00847 /* written any extensions? ok, write space between exten & inc */ 00848 if (last_written_e) 00849 fprintf(output, "\n"); 00850 00851 /* walk through includes */ 00852 for (i = NULL; (i = ast_walk_context_includes(c, i)) ; ) { 00853 if (strcmp(ast_get_include_registrar(i), registrar) != 0) 00854 continue; /* not mine */ 00855 PUT_CTX_HDR; 00856 fprintf(output, "include => %s\n", ast_get_include_name(i)); 00857 } 00858 if (ast_walk_context_includes(c, NULL)) 00859 fprintf(output, "\n"); 00860 00861 /* walk through switches */ 00862 for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) { 00863 if (strcmp(ast_get_switch_registrar(sw), registrar) != 0) 00864 continue; /* not mine */ 00865 PUT_CTX_HDR; 00866 fprintf(output, "switch => %s/%s\n", 00867 ast_get_switch_name(sw), ast_get_switch_data(sw)); 00868 } 00869 00870 if (ast_walk_context_switches(c, NULL)) 00871 fprintf(output, "\n"); 00872 00873 /* fireout ignorepats ... */ 00874 for (ip = NULL; (ip = ast_walk_context_ignorepats(c, ip)); ) { 00875 if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0) 00876 continue; /* not mine */ 00877 PUT_CTX_HDR; 00878 fprintf(output, "ignorepat => %s\n", 00879 ast_get_ignorepat_name(ip)); 00880 } 00881 00882 ast_unlock_context(c); 00883 } 00884 00885 ast_unlock_contexts(); 00886 ast_mutex_unlock(&save_dialplan_lock); 00887 fclose(output); 00888 00889 if (incomplete) { 00890 ast_cli(a->fd, "Saved dialplan is incomplete\n"); 00891 return CLI_FAILURE; 00892 } 00893 00894 ast_cli(a->fd, "Dialplan successfully saved into '%s'\n", 00895 filename); 00896 return CLI_SUCCESS; 00897 }
| static int load_module | ( | void | ) | [static] |
Definition at line 1723 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().
01724 { 01725 if (pbx_load_module()) 01726 return AST_MODULE_LOAD_DECLINE; 01727 01728 if (static_config && !write_protect_config) 01729 ast_cli_register(&cli_dialplan_save); 01730 ast_cli_register_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config)); 01731 01732 return AST_MODULE_LOAD_SUCCESS; 01733 }
| static int lookup_c_ip | ( | struct ast_context * | c, | |
| const char * | name | |||
| ) | [static] |
return true if 'name' is in the ignorepats for context c
Definition at line 115 of file pbx_config.c.
References ast_get_ignorepat_name(), ast_rdlock_context(), ast_unlock_context(), and ast_walk_context_ignorepats().
Referenced by complete_dialplan_add_ignorepat(), and complete_dialplan_remove_ignorepat().
00116 { 00117 struct ast_ignorepat *ip = NULL; 00118 00119 if (ast_rdlock_context(c)) /* error, skip */ 00120 return 0; 00121 while ( (ip = ast_walk_context_ignorepats(c, ip)) ) 00122 if (!strcmp(name, ast_get_ignorepat_name(ip))) 00123 break; 00124 ast_unlock_context(c); 00125 return ip ? -1 /* success */ : 0; 00126 }
| static int lookup_ci | ( | struct ast_context * | c, | |
| const char * | name | |||
| ) | [static] |
return true if 'name' is included by context c
Definition at line 101 of file pbx_config.c.
References ast_get_include_name(), ast_rdlock_context(), ast_unlock_context(), and ast_walk_context_includes().
Referenced by complete_dialplan_add_include(), and complete_dialplan_remove_include().
00102 { 00103 struct ast_include *i = NULL; 00104 00105 if (ast_rdlock_context(c)) /* error, skip */ 00106 return 0; 00107 while ( (i = ast_walk_context_includes(c, i)) ) 00108 if (!strcmp(name, ast_get_include_name(i))) 00109 break; 00110 ast_unlock_context(c); 00111 return i ? -1 /* success */ : 0; 00112 }
| static int partial_match | ( | const char * | s, | |
| const char * | word, | |||
| int | len | |||
| ) | [static] |
match the first 'len' chars of word. len==0 always succeeds
Definition at line 144 of file pbx_config.c.
Referenced by complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), and complete_dialplan_remove_include().
| static int pbx_load_config | ( | const char * | config_file | ) | [static] |
Definition at line 1366 of file pbx_config.c.
References ast_add_extension2(), ast_category_browse(), ast_config_destroy(), ast_config_load, ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_find_or_create(), ast_copy_string(), ast_findlabel_extension2(), ast_free, ast_free_ptr, ast_log(), ast_opt_dont_warn, ast_shrink_phone_number(), ast_skip_blanks(), ast_strdup, ast_strlen_zero(), ast_trim_blanks(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), CONFIG_STATUS_FILEINVALID, errno, ext, free, ast_variable::lineno, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), pbx_strsep(), pbx_substitute_variables_helper(), PRIORITY_HINT, S_OR, strdup, strsep(), and ast_variable::value.
Referenced by pbx_load_module().
01367 { 01368 struct ast_config *cfg; 01369 char *end; 01370 char *label; 01371 #ifdef LOW_MEMORY 01372 char realvalue[256]; 01373 #else 01374 char realvalue[8192]; 01375 #endif 01376 int lastpri = -2; 01377 struct ast_context *con; 01378 struct ast_variable *v; 01379 const char *cxt; 01380 const char *aft; 01381 const char *newpm, *ovsw; 01382 struct ast_flags config_flags = { 0 }; 01383 char lastextension[256]; 01384 cfg = ast_config_load(config_file, config_flags); 01385 if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) 01386 return 0; 01387 01388 /* Use existing config to populate the PBX table */ 01389 static_config = ast_true(ast_variable_retrieve(cfg, "general", "static")); 01390 write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect")); 01391 if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough"))) 01392 autofallthrough_config = ast_true(aft); 01393 if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew"))) 01394 extenpatternmatchnew_config = ast_true(newpm); 01395 clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars")); 01396 if ((ovsw = ast_variable_retrieve(cfg, "general", "overrideswitch"))) { 01397 if (overrideswitch_config) { 01398 ast_free(overrideswitch_config); 01399 } 01400 if (!ast_strlen_zero(ovsw)) { 01401 overrideswitch_config = ast_strdup(ovsw); 01402 } else { 01403 overrideswitch_config = NULL; 01404 } 01405 } 01406 01407 ast_copy_string(userscontext, ast_variable_retrieve(cfg, "general", "userscontext") ?: "default", sizeof(userscontext)); 01408 01409 for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) { 01410 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01411 pbx_builtin_setvar_helper(NULL, v->name, realvalue); 01412 } 01413 for (cxt = ast_category_browse(cfg, NULL); 01414 cxt; 01415 cxt = ast_category_browse(cfg, cxt)) { 01416 /* All categories but "general" or "globals" are considered contexts */ 01417 if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) { 01418 continue; 01419 } 01420 if (!(con = ast_context_find_or_create(&local_contexts, local_table, cxt, registrar))) { 01421 continue; 01422 } 01423 01424 /* Reset continuation items at the beginning of each context */ 01425 lastextension[0] = '\0'; 01426 lastpri = -2; 01427 01428 for (v = ast_variable_browse(cfg, cxt); v; v = v->next) { 01429 char *tc = NULL; 01430 char realext[256] = ""; 01431 char *stringp, *ext; 01432 01433 if (!strncasecmp(v->name, "same", 4)) { 01434 if (ast_strlen_zero(lastextension)) { 01435 ast_log(LOG_ERROR, "No previous pattern in the first entry of context '%s' to match '%s'!\n", cxt, v->name); 01436 continue; 01437 } 01438 if ((stringp = tc = ast_strdup(v->value))) { 01439 ast_copy_string(realext, lastextension, sizeof(realext)); 01440 goto process_extension; 01441 } 01442 } else if (!strcasecmp(v->name, "exten")) { 01443 int ipri; 01444 char *plus, *firstp; 01445 char *pri, *appl, *data, *cidmatch; 01446 01447 if (!(stringp = tc = ast_strdup(v->value))) { 01448 continue; 01449 } 01450 01451 ext = S_OR(pbx_strsep(&stringp, ","), ""); 01452 pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1); 01453 ast_copy_string(lastextension, realext, sizeof(lastextension)); 01454 process_extension: 01455 ipri = -2; 01456 if ((cidmatch = strchr(realext, '/'))) { 01457 *cidmatch++ = '\0'; 01458 ast_shrink_phone_number(cidmatch); 01459 } 01460 pri = S_OR(strsep(&stringp, ","), ""); 01461 pri = ast_skip_blanks(pri); 01462 pri = ast_trim_blanks(pri); 01463 if ((label = strchr(pri, '('))) { 01464 *label++ = '\0'; 01465 if ((end = strchr(label, ')'))) { 01466 *end = '\0'; 01467 } else { 01468 ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno); 01469 } 01470 } 01471 if ((plus = strchr(pri, '+'))) { 01472 *plus++ = '\0'; 01473 } 01474 if (!strcmp(pri,"hint")) { 01475 ipri = PRIORITY_HINT; 01476 } else if (!strcmp(pri, "next") || !strcmp(pri, "n")) { 01477 if (lastpri > -2) { 01478 ipri = lastpri + 1; 01479 } else { 01480 ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry!\n"); 01481 } 01482 } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) { 01483 if (lastpri > -2) { 01484 ipri = lastpri; 01485 } else { 01486 ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry!\n"); 01487 } 01488 } else if (sscanf(pri, "%30d", &ipri) != 1 && 01489 (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) { 01490 ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno); 01491 ipri = 0; 01492 } 01493 appl = S_OR(stringp, ""); 01494 /* Find the first occurrence of '(' */ 01495 if (!(firstp = strchr(appl, '('))) { 01496 /* No arguments */ 01497 data = ""; 01498 } else { 01499 appl = strsep(&stringp, "("); 01500 data = S_OR(stringp, ""); 01501 if ((end = strrchr(data, ')'))) { 01502 *end = '\0'; 01503 } else { 01504 ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s'\n", appl, data); 01505 } 01506 } 01507 01508 appl = ast_skip_blanks(appl); 01509 if (ipri) { 01510 if (plus) { 01511 ipri += atoi(plus); 01512 } 01513 lastpri = ipri; 01514 if (!ast_opt_dont_warn && !strcmp(realext, "_.")) { 01515 ast_log(LOG_WARNING, "The use of '_.' for an extension is strongly discouraged and can have unexpected behavior. Please use '_X.' instead at line %d\n", v->lineno); 01516 } 01517 if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free_ptr, registrar)) { 01518 ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno); 01519 } 01520 } 01521 free(tc); 01522 } else if (!strcasecmp(v->name, "include")) { 01523 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01524 if (ast_context_add_include2(con, realvalue, registrar)) { 01525 switch (errno) { 01526 case ENOMEM: 01527 ast_log(LOG_WARNING, "Out of memory for context addition\n"); 01528 break; 01529 01530 case EBUSY: 01531 ast_log(LOG_WARNING, "Failed to lock context(s) list, please try again later\n"); 01532 break; 01533 01534 case EEXIST: 01535 ast_log(LOG_WARNING, "Context '%s' already included in '%s' context\n", 01536 v->value, cxt); 01537 break; 01538 01539 case ENOENT: 01540 case EINVAL: 01541 ast_log(LOG_WARNING, "There is no existence of context '%s'\n", 01542 errno == ENOENT ? v->value : cxt); 01543 break; 01544 01545 default: 01546 ast_log(LOG_WARNING, "Failed to include '%s' in '%s' context\n", 01547 v->value, cxt); 01548 break; 01549 } 01550 } 01551 } else if (!strcasecmp(v->name, "ignorepat")) { 01552 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01553 if (ast_context_add_ignorepat2(con, realvalue, registrar)) { 01554 ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt); 01555 } 01556 } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) { 01557 char *stringp = realvalue; 01558 char *appl, *data; 01559 01560 if (!strcasecmp(v->name, "switch")) { 01561 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01562 } else { 01563 ast_copy_string(realvalue, v->value, sizeof(realvalue)); 01564 } 01565 appl = strsep(&stringp, "/"); 01566 data = S_OR(stringp, ""); 01567 if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar)) { 01568 ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt); 01569 } 01570 } else { 01571 ast_log(LOG_WARNING, "==!!== Unknown directive: %s at line %d -- IGNORING!!!\n", v->name, v->lineno); 01572 } 01573 } 01574 } 01575 ast_config_destroy(cfg); 01576 return 1; 01577 }
| static int pbx_load_module | ( | void | ) | [static] |
Definition at line 1697 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().
01698 { 01699 struct ast_context *con; 01700 01701 if (!local_table) 01702 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); 01703 01704 if (!pbx_load_config(config)) 01705 return AST_MODULE_LOAD_DECLINE; 01706 01707 pbx_load_users(); 01708 01709 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar); 01710 local_table = NULL; /* the local table has been moved into the global one. */ 01711 local_contexts = NULL; 01712 01713 for (con = NULL; (con = ast_walk_contexts(con));) 01714 ast_context_verify_includes(con); 01715 01716 pbx_set_overrideswitch(overrideswitch_config); 01717 pbx_set_autofallthrough(autofallthrough_config); 01718 pbx_set_extenpatternmatchnew(extenpatternmatchnew_config); 01719 01720 return AST_MODULE_LOAD_SUCCESS; 01721 }
| static void pbx_load_users | ( | void | ) | [static] |
Definition at line 1591 of file pbx_config.c.
References append_interface(), ast_add_extension2(), ast_category_browse(), ast_config_destroy(), ast_config_load, ast_config_option(), ast_context_find_or_create(), ast_copy_string(), ast_free_ptr, ast_log(), ast_strlen_zero(), ast_true(), ast_variable_retrieve(), chan, ext, len(), LOG_ERROR, strdup, and strsep().
Referenced by pbx_load_module().
01592 { 01593 struct ast_config *cfg; 01594 char *cat, *chan; 01595 const char *dahdichan; 01596 const char *hasexten, *altexts; 01597 char tmp[256]; 01598 char iface[256]; 01599 char dahdicopy[256]; 01600 char *ext, altcopy[256]; 01601 char *c; 01602 int len; 01603 int hasvoicemail; 01604 int start, finish, x; 01605 struct ast_context *con = NULL; 01606 struct ast_flags config_flags = { 0 }; 01607 01608 cfg = ast_config_load("users.conf", config_flags); 01609 if (!cfg) 01610 return; 01611 01612 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 01613 if (!strcasecmp(cat, "general")) 01614 continue; 01615 iface[0] = '\0'; 01616 len = sizeof(iface); 01617 if (ast_true(ast_config_option(cfg, cat, "hassip"))) { 01618 snprintf(tmp, sizeof(tmp), "SIP/%s", cat); 01619 append_interface(iface, sizeof(iface), tmp); 01620 } 01621 if (ast_true(ast_config_option(cfg, cat, "hasiax"))) { 01622 snprintf(tmp, sizeof(tmp), "IAX2/%s", cat); 01623 append_interface(iface, sizeof(iface), tmp); 01624 } 01625 if (ast_true(ast_config_option(cfg, cat, "hash323"))) { 01626 snprintf(tmp, sizeof(tmp), "H323/%s", cat); 01627 append_interface(iface, sizeof(iface), tmp); 01628 } 01629 hasexten = ast_config_option(cfg, cat, "hasexten"); 01630 if (hasexten && !ast_true(hasexten)) 01631 continue; 01632 hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail")); 01633 dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan"); 01634 if (!dahdichan) 01635 dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan"); 01636 if (!ast_strlen_zero(dahdichan)) { 01637 ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy)); 01638 c = dahdicopy; 01639 chan = strsep(&c, ","); 01640 while (chan) { 01641 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) { 01642 /* Range */ 01643 } else if (sscanf(chan, "%30d", &start)) { 01644 /* Just one */ 01645 finish = start; 01646 } else { 01647 start = 0; finish = 0; 01648 } 01649 if (finish < start) { 01650 x = finish; 01651 finish = start; 01652 start = x; 01653 } 01654 for (x = start; x <= finish; x++) { 01655 snprintf(tmp, sizeof(tmp), "DAHDI/%d", x); 01656 append_interface(iface, sizeof(iface), tmp); 01657 } 01658 chan = strsep(&c, ","); 01659 } 01660 } 01661 if (!ast_strlen_zero(iface)) { 01662 /* Only create a context here when it is really needed. Otherwise default empty context 01663 created by pbx_config may conflict with the one explicitly created by pbx_ael */ 01664 if (!con) 01665 con = ast_context_find_or_create(&local_contexts, local_table, userscontext, registrar); 01666 01667 if (!con) { 01668 ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext); 01669 return; 01670 } 01671 01672 /* Add hint */ 01673 ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar); 01674 /* If voicemail, use "stdexten" else use plain old dial */ 01675 if (hasvoicemail) { 01676 snprintf(tmp, sizeof(tmp), "stdexten,%s,${HINT}", cat); 01677 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", strdup(tmp), ast_free_ptr, registrar); 01678 } else { 01679 ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", strdup("${HINT}"), ast_free_ptr, registrar); 01680 } 01681 altexts = ast_variable_retrieve(cfg, cat, "alternateexts"); 01682 if (!ast_strlen_zero(altexts)) { 01683 snprintf(tmp, sizeof(tmp), "%s,1", cat); 01684 ast_copy_string(altcopy, altexts, sizeof(altcopy)); 01685 c = altcopy; 01686 ext = strsep(&c, ","); 01687 while (ext) { 01688 ast_add_extension2(con, 0, ext, 1, NULL, NULL, "Goto", strdup(tmp), ast_free_ptr, registrar); 01689 ext = strsep(&c, ","); 01690 } 01691 } 01692 } 01693 } 01694 ast_config_destroy(cfg); 01695 }
| static char* pbx_strsep | ( | char ** | destructible, | |
| const char * | delim | |||
| ) | [static] |
Definition at line 1341 of file pbx_config.c.
Referenced by pbx_load_config().
01342 { 01343 int square = 0; 01344 char *res = *destructible; 01345 for (; destructible && *destructible && **destructible; (*destructible)++) { 01346 if (**destructible == '[' && !strchr(delim, '[')) { 01347 square++; 01348 } else if (**destructible == ']' && !strchr(delim, ']')) { 01349 if (square) { 01350 square--; 01351 } 01352 } else if (**destructible == '\\' && !strchr(delim, '\\')) { 01353 (*destructible)++; 01354 } else if (strchr(delim, **destructible) && !square) { 01355 **destructible = '\0'; 01356 (*destructible)++; 01357 break; 01358 } 01359 } 01360 if (destructible && *destructible && **destructible == '\0') { 01361 *destructible = NULL; 01362 } 01363 return res; 01364 }
| static int reload | ( | void | ) | [static] |
Definition at line 1735 of file pbx_config.c.
References pbx_builtin_clear_globals(), and pbx_load_module().
01736 { 01737 if (clearglobalvars_config) 01738 pbx_builtin_clear_globals(); 01739 return pbx_load_module(); 01740 }
| static const char* skip_words | ( | const char * | p, | |
| int | n | |||
| ) | [static] |
moves to the n-th word in the string, or empty string if none
Definition at line 129 of file pbx_config.c.
Referenced by complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), and complete_dialplan_remove_include().
00130 { 00131 int in_blank = 0; 00132 for (;n && *p; p++) { 00133 if (isblank(*p) /* XXX order is important */ && !in_blank) { 00134 n--; /* one word is gone */ 00135 in_blank = 1; 00136 } else if (/* !is_blank(*p), we know already, && */ in_blank) { 00137 in_blank = 0; 00138 } 00139 } 00140 return p; 00141 }
| static int split_ec | ( | const char * | src, | |
| char ** | ext, | |||
| char **const | ctx, | |||
| char **const | cid | |||
| ) | [static] |
split extension@context in two parts, return -1 on error. The return string is malloc'ed and pointed by *ext
Definition at line 152 of file pbx_config.c.
References ast_strdup, and free.
Referenced by complete_dialplan_remove_extension(), and handle_cli_dialplan_remove_extension().
00153 { 00154 char *i, *c, *e = ast_strdup(src); /* now src is not used anymore */ 00155 00156 if (e == NULL) 00157 return -1; /* malloc error */ 00158 /* now, parse values from 'exten@context' */ 00159 *ext = e; 00160 c = strchr(e, '@'); 00161 if (c == NULL) /* no context part */ 00162 *ctx = ""; /* it is not overwritten, anyways */ 00163 else { /* found context, check for duplicity ... */ 00164 *c++ = '\0'; 00165 *ctx = c; 00166 if (strchr(c, '@')) { /* two @, not allowed */ 00167 free(e); 00168 return -1; 00169 } 00170 } 00171 if (cid && (i = strchr(e, '/'))) { 00172 *i++ = '\0'; 00173 *cid = i; 00174 } else if (cid) { 00175 /* Signal none detected */ 00176 *cid = NULL; 00177 } 00178 return 0; 00179 }
| static int unload_module | ( | void | ) | [static] |
Standard module functions ...
Definition at line 1324 of file pbx_config.c.
References ARRAY_LEN, ast_cli_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), and ast_free.
01325 { 01326 if (static_config && !write_protect_config) 01327 ast_cli_unregister(&cli_dialplan_save); 01328 if (overrideswitch_config) { 01329 ast_free(overrideswitch_config); 01330 } 01331 ast_cli_unregister_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config)); 01332 ast_context_destroy(NULL, registrar); 01333 return 0; 01334 }
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 1746 of file pbx_config.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1746 of file pbx_config.c.
int autofallthrough_config = 1 [static] |
Definition at line 47 of file pbx_config.c.
int clearglobalvars_config = 0 [static] |
Definition at line 48 of file pbx_config.c.
struct ast_cli_entry cli_dialplan_save [static] |
Initial value:
AST_CLI_DEFINE(handle_cli_dialplan_save, "Save dialplan")
Definition at line 1318 of file pbx_config.c.
struct ast_cli_entry cli_pbx_config[] [static] |
CLI entries for commands provided by this module
Definition at line 1308 of file pbx_config.c.
char* config = "extensions.conf" [static] |
Definition at line 41 of file pbx_config.c.
int extenpatternmatchnew_config = 0 [static] |
Definition at line 49 of file pbx_config.c.
struct ast_context* local_contexts = NULL [static] |
Definition at line 54 of file pbx_config.c.
Referenced by ast_context_find_or_create(), and pbx_load_module().
struct ast_hashtab* local_table = NULL [static] |
char* overrideswitch_config = NULL [static] |
Definition at line 50 of file pbx_config.c.
char* registrar = "pbx_config" [static] |
Definition at line 42 of file pbx_config.c.
ast_mutex_t save_dialplan_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
int static_config = 0 [static] |
Definition at line 45 of file pbx_config.c.
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 43 of file pbx_config.c.
int write_protect_config = 1 [static] |
Definition at line 46 of file pbx_config.c.
1.5.6