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