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