#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "asterisk.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/cli.h"
#include "asterisk/callerid.h"

Go to the source code of this file.
Defines | |
| #define | BROKEN_READLINE 1 |
| #define | FREE free |
Functions | |
| AST_MUTEX_DEFINE_STATIC (save_dialplan_lock) | |
| static char * | complete_context_add_extension (char *line, char *word, int pos, int state) |
| static char * | complete_context_add_ignorepat (char *line, char *word, int pos, int state) |
| static char * | complete_context_add_include (char *line, char *word, int pos, int state) |
| static char * | complete_context_dont_include (char *line, char *word, int pos, int state) |
| static char * | complete_context_remove_extension (char *line, char *word, int pos, int state) |
| static char * | complete_context_remove_ignorepat (char *line, char *word, int pos, int state) |
| char * | description (void) |
| Provides a description of the module. | |
| static int | fix_complete_args (char *line, char **word, int *pos) |
| static int | handle_context_add_extension (int fd, int argc, char *argv[]) |
| ADD EXTENSION command stuff. | |
| static int | handle_context_add_ignorepat (int fd, int argc, char *argv[]) |
| static int | handle_context_add_include (int fd, int argc, char *argv[]) |
| static int | handle_context_dont_include (int fd, int argc, char *argv[]) |
| static int | handle_context_remove_extension (int fd, int argc, char *argv[]) |
| static int | handle_context_remove_ignorepat (int fd, int argc, char *argv[]) |
| static int | handle_reload_extensions (int fd, int argc, char *argv[]) |
| static int | handle_save_dialplan (int fd, int argc, char *argv[]) |
| 'save dialplan' CLI command implementation functions ... | |
| char * | key (void) |
| Returns the ASTERISK_GPL_KEY. | |
| int | load_module (void) |
| Initialize the module. | |
| static int | pbx_load_module (void) |
| int | reload (void) |
| Reload stuff. | |
| int | unload_module (void) |
| Cleanup all module structures, sockets, etc. | |
| int | usecount (void) |
| Provides a usecount. | |
Variables | |
| static int | autofallthrough_config = 0 |
| static int | clearglobalvars_config = 0 |
| static char * | config = "extensions.conf" |
| static struct ast_cli_entry | context_add_extension_cli |
| static char | context_add_extension_help [] |
| static struct ast_cli_entry | context_add_ignorepat_cli |
| static char | context_add_ignorepat_help [] |
| static struct ast_cli_entry | context_add_include_cli |
| static char | context_add_include_help [] |
| static struct ast_cli_entry | context_dont_include_cli |
| static char | context_dont_include_help [] |
| static struct ast_cli_entry | context_remove_extension_cli |
| static char | context_remove_extension_help [] |
| static struct ast_cli_entry | context_remove_ignorepat_cli |
| static char | context_remove_ignorepat_help [] |
| static char * | dtext = "Text Extension Configuration" |
| static struct ast_context * | local_contexts = NULL |
| static char * | registrar = "pbx_config" |
| static struct ast_cli_entry | reload_extensions_cli |
| static char | reload_extensions_help [] |
| static struct ast_cli_entry | save_dialplan_cli |
| static char | save_dialplan_help [] |
| static int | static_config = 0 |
| static int | write_protect_config = 1 |
Definition in file pbx_config.c.
| #define BROKEN_READLINE 1 |
Definition at line 437 of file pbx_config.c.
| #define FREE free |
Definition at line 51 of file pbx_config.c.
| AST_MUTEX_DEFINE_STATIC | ( | save_dialplan_lock | ) |
| static char* complete_context_add_extension | ( | char * | line, | |
| char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
add extension 6123,1,Dial,IAX/212.71.138.13/6123 into local
Definition at line 1255 of file pbx_config.c.
References ast_get_context_name(), ast_lock_contexts(), ast_log(), ast_unlock_contexts(), ast_walk_contexts(), LOG_WARNING, and strdup.
01257 { 01258 int which = 0; 01259 01260 /* complete 'into' word ... */ 01261 if (pos == 3) { 01262 if (state == 0) return strdup("into"); 01263 return NULL; 01264 } 01265 01266 /* complete context */ 01267 if (pos == 4) { 01268 struct ast_context *c; 01269 01270 /* try to lock contexts list ... */ 01271 if (ast_lock_contexts()) { 01272 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01273 return NULL; 01274 } 01275 01276 /* walk through all contexts */ 01277 c = ast_walk_contexts(NULL); 01278 while (c) { 01279 /* matching context? */ 01280 if (!strncmp(ast_get_context_name(c), word, strlen(word))) { 01281 if (++which > state) { 01282 char *res = strdup(ast_get_context_name(c)); 01283 ast_unlock_contexts(); 01284 return res; 01285 } 01286 } 01287 c = ast_walk_contexts(c); 01288 } 01289 01290 ast_unlock_contexts(); 01291 return NULL; 01292 } 01293 01294 if (pos == 5) return state == 0 ? strdup("replace") : NULL; 01295 01296 return NULL; 01297 }
| static char* complete_context_add_ignorepat | ( | char * | line, | |
| char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 1338 of file pbx_config.c.
References ast_get_context_name(), ast_get_ignorepat_name(), ast_lock_context(), ast_lock_contexts(), ast_log(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_ignorepats(), ast_walk_contexts(), context, free, LOG_ERROR, strdup, and strsep().
01340 { 01341 if (pos == 3) return state == 0 ? strdup("into") : NULL; 01342 01343 if (pos == 4) { 01344 struct ast_context *c; 01345 int which = 0; 01346 char *dupline, *duplinet, *ignorepat = NULL; 01347 01348 dupline = strdup(line); 01349 duplinet = dupline; 01350 01351 if (duplinet) { 01352 strsep(&duplinet, " "); /* skip 'add' */ 01353 strsep(&duplinet, " "); /* skip 'ignorepat' */ 01354 ignorepat = strsep(&duplinet, " "); 01355 } 01356 01357 if (ast_lock_contexts()) { 01358 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 01359 return NULL; 01360 } 01361 01362 c = ast_walk_contexts(NULL); 01363 while (c) { 01364 if (!strncmp(ast_get_context_name(c), word, strlen(word))) { 01365 int serve_context = 1; 01366 if (ignorepat) { 01367 if (!ast_lock_context(c)) { 01368 struct ast_ignorepat *ip; 01369 ip = ast_walk_context_ignorepats(c, NULL); 01370 while (ip && serve_context) { 01371 if (!strcmp(ast_get_ignorepat_name(ip), ignorepat)) 01372 serve_context = 0; 01373 ip = ast_walk_context_ignorepats(c, ip); 01374 } 01375 ast_unlock_context(c); 01376 } 01377 } 01378 if (serve_context) { 01379 if (++which > state) { 01380 char *context = strdup(ast_get_context_name(c)); 01381 if (dupline) free(dupline); 01382 ast_unlock_contexts(); 01383 return context; 01384 } 01385 } 01386 } 01387 c = ast_walk_contexts(c); 01388 } 01389 01390 if (dupline) free(dupline); 01391 ast_unlock_contexts(); 01392 return NULL; 01393 } 01394 01395 return NULL; 01396 }
| static char* complete_context_add_include | ( | char * | line, | |
| char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 748 of file pbx_config.c.
References ast_get_context_name(), ast_get_include_name(), ast_lock_context(), ast_lock_contexts(), ast_log(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_includes(), ast_walk_contexts(), context, free, LOG_ERROR, strdup, and strsep().
00750 { 00751 struct ast_context *c; 00752 int which = 0; 00753 00754 /* server context for inclusion ... */ 00755 if (pos == 1) 00756 { 00757 if (ast_lock_contexts()) { 00758 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00759 return NULL; 00760 } 00761 00762 /* server all contexts */ 00763 c = ast_walk_contexts(NULL); 00764 while (c) { 00765 if ((!strlen(word) || 00766 !strncmp(ast_get_context_name(c), word, strlen(word))) && 00767 ++which > state) 00768 { 00769 char *context = strdup(ast_get_context_name(c)); 00770 ast_unlock_contexts(); 00771 return context; 00772 } 00773 c = ast_walk_contexts(c); 00774 } 00775 00776 ast_unlock_contexts(); 00777 } 00778 00779 /* complete 'in' only if context exist ... */ 00780 if (pos == 2) 00781 { 00782 char *context, *dupline, *duplinet; 00783 00784 if (state != 0) return NULL; 00785 00786 /* parse context from line ... */ 00787 if (!(dupline = strdup(line))) { 00788 ast_log(LOG_ERROR, "Out of free memory\n"); 00789 if (state == 0) return strdup("in"); 00790 return NULL; 00791 } 00792 00793 duplinet = dupline; 00794 00795 strsep(&duplinet, " "); 00796 context = strsep(&duplinet, " "); 00797 if (context) { 00798 struct ast_context *c; 00799 int context_existence = 0; 00800 00801 /* check for context existence ... */ 00802 if (ast_lock_contexts()) { 00803 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00804 free(dupline); 00805 /* our fault, we can't check, so complete 'in' ... */ 00806 return strdup("in"); 00807 } 00808 00809 c = ast_walk_contexts(NULL); 00810 while (c && !context_existence) { 00811 if (!strcmp(context, ast_get_context_name(c))) { 00812 context_existence = 1; 00813 continue; 00814 } 00815 c = ast_walk_contexts(c); 00816 } 00817 00818 /* if context exists, return 'into' ... */ 00819 if (context_existence) { 00820 free(dupline); 00821 ast_unlock_contexts(); 00822 return strdup("into"); 00823 } 00824 00825 ast_unlock_contexts(); 00826 } 00827 00828 free(dupline); 00829 return NULL; 00830 } 00831 00832 /* serve context into which we include another context */ 00833 if (pos == 3) 00834 { 00835 char *context, *dupline, *duplinet, *in; 00836 int context_existence = 0; 00837 00838 if (!(dupline = strdup(line))) { 00839 ast_log(LOG_ERROR, "Out of free memory\n"); 00840 return NULL; 00841 } 00842 00843 duplinet = dupline; 00844 00845 strsep(&duplinet, " "); /* skip 'include' */ 00846 context = strsep(&duplinet, " "); 00847 in = strsep(&duplinet, " "); 00848 00849 /* given some context and third word is in? */ 00850 if (!strlen(context) || strcmp(in, "in")) { 00851 free(dupline); 00852 return NULL; 00853 } 00854 00855 if (ast_lock_contexts()) { 00856 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00857 free(dupline); 00858 return NULL; 00859 } 00860 00861 /* check for context existence ... */ 00862 c = ast_walk_contexts(NULL); 00863 while (c && !context_existence) { 00864 if (!strcmp(context, ast_get_context_name(c))) { 00865 context_existence = 1; 00866 continue; 00867 } 00868 c = ast_walk_contexts(c); 00869 } 00870 00871 if (!context_existence) { 00872 free(dupline); 00873 ast_unlock_contexts(); 00874 return NULL; 00875 } 00876 00877 /* go through all contexts ... */ 00878 c = ast_walk_contexts(NULL); 00879 while (c) { 00880 /* must be different contexts ... */ 00881 if (strcmp(context, ast_get_context_name(c))) { 00882 if (!ast_lock_context(c)) { 00883 struct ast_include *i; 00884 int included = 0; 00885 00886 /* check for duplicity inclusion ... */ 00887 i = ast_walk_context_includes(c, NULL); 00888 while (i && !included) { 00889 if (!strcmp(ast_get_include_name(i), context)) 00890 included = 1; 00891 i = ast_walk_context_includes(c, i); 00892 } 00893 ast_unlock_context(c); 00894 00895 /* not included yet, so show possibility ... */ 00896 if (!included && 00897 !strncmp(ast_get_context_name(c), word, strlen(word))){ 00898 00899 if (++which > state) { 00900 char *res = strdup(ast_get_context_name(c)); 00901 free(dupline); 00902 ast_unlock_contexts(); 00903 return res; 00904 } 00905 } 00906 } 00907 } 00908 c = ast_walk_contexts(c); 00909 } 00910 00911 ast_unlock_contexts(); 00912 free(dupline); 00913 return NULL; 00914 } 00915 00916 return NULL; 00917 }
| static char* complete_context_dont_include | ( | char * | line, | |
| char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 146 of file pbx_config.c.
References ast_get_context_name(), ast_get_include_name(), ast_lock_context(), ast_lock_contexts(), ast_log(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_includes(), ast_walk_contexts(), context, free, LOG_ERROR, LOG_WARNING, strdup, and strsep().
00148 { 00149 int which = 0; 00150 00151 /* 00152 * Context completion ... 00153 */ 00154 if (pos == 2) { 00155 struct ast_context *c; 00156 00157 if (ast_lock_contexts()) { 00158 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00159 return NULL; 00160 } 00161 00162 /* walk pbx_get_contexts ... */ 00163 c = ast_walk_contexts(NULL); 00164 while (c) { 00165 struct ast_include *i; 00166 00167 if (ast_lock_context(c)) { 00168 c = ast_walk_contexts(c); 00169 continue; 00170 } 00171 00172 i = ast_walk_context_includes(c, NULL); 00173 while (i) { 00174 if (!strlen(word) || 00175 !strncmp(ast_get_include_name(i), word, strlen(word))) { 00176 struct ast_context *nc; 00177 int already_served = 0; 00178 00179 /* check if this include is already served or not */ 00180 00181 /* go through all contexts again till we reach actuall 00182 * context or already_served = 1 00183 */ 00184 nc = ast_walk_contexts(NULL); 00185 while (nc && nc != c && !already_served) { 00186 if (!ast_lock_context(nc)) { 00187 struct ast_include *ni; 00188 00189 ni = ast_walk_context_includes(nc, NULL); 00190 while (ni && !already_served) { 00191 if (!strcmp(ast_get_include_name(i), 00192 ast_get_include_name(ni))) 00193 already_served = 1; 00194 ni = ast_walk_context_includes(nc, ni); 00195 } 00196 00197 ast_unlock_context(nc); 00198 } 00199 nc = ast_walk_contexts(nc); 00200 } 00201 00202 if (!already_served) { 00203 if (++which > state) { 00204 char *res = 00205 strdup(ast_get_include_name(i)); 00206 ast_unlock_context(c); 00207 ast_unlock_contexts(); 00208 return res; 00209 } 00210 } 00211 } 00212 i = ast_walk_context_includes(c, i); 00213 } 00214 00215 ast_unlock_context(c); 00216 c = ast_walk_contexts(c); 00217 } 00218 00219 ast_unlock_contexts(); 00220 return NULL; 00221 } 00222 00223 /* 00224 * 'in' completion ... (complete only if previous context is really 00225 * included somewhere) 00226 */ 00227 if (pos == 3) { 00228 struct ast_context *c; 00229 char *context, *dupline, *duplinet; 00230 00231 if (state > 0) return NULL; 00232 00233 /* take 'context' from line ... */ 00234 if (!(dupline = strdup(line))) { 00235 ast_log(LOG_ERROR, "Out of free memory\n"); 00236 return NULL; 00237 } 00238 00239 duplinet = dupline; 00240 strsep(&duplinet, " "); /* skip 'dont' */ 00241 strsep(&duplinet, " "); /* skip 'include' */ 00242 context = strsep(&duplinet, " "); 00243 00244 if (!context) { 00245 free(dupline); 00246 return NULL; 00247 } 00248 00249 if (ast_lock_contexts()) { 00250 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 00251 free(dupline); 00252 return NULL; 00253 } 00254 00255 /* go through all contexts and check if is included ... */ 00256 c = ast_walk_contexts(NULL); 00257 while (c) { 00258 struct ast_include *i; 00259 if (ast_lock_context(c)) { 00260 free(dupline); 00261 ast_unlock_contexts(); 00262 return NULL; 00263 } 00264 00265 i = ast_walk_context_includes(c, NULL); 00266 while (i) { 00267 /* is it our context? */ 00268 if (!strcmp(ast_get_include_name(i), context)) { 00269 /* yes, it is, context is really included, so 00270 * complete "in" command 00271 */ 00272 free(dupline); 00273 ast_unlock_context(c); 00274 ast_unlock_contexts(); 00275 return strdup("in"); 00276 } 00277 i = ast_walk_context_includes(c, i); 00278 } 00279 ast_unlock_context(c); 00280 c = ast_walk_contexts(c); 00281 } 00282 free(dupline); 00283 ast_unlock_contexts(); 00284 return NULL; 00285 } 00286 00287 /* 00288 * Context from which we removing include ... 00289 */ 00290 if (pos == 4) { 00291 struct ast_context *c; 00292 char *context, *dupline, *duplinet, *in; 00293 00294 if (!(dupline = strdup(line))) { 00295 ast_log(LOG_ERROR, "Out of free memory\n"); 00296 return NULL; 00297 } 00298 00299 duplinet = dupline; 00300 00301 strsep(&duplinet, " "); /* skip 'dont' */ 00302 strsep(&duplinet, " "); /* skip 'include' */ 00303 00304 if (!(context = strsep(&duplinet, " "))) { 00305 free(dupline); 00306 return NULL; 00307 } 00308 00309 /* third word must be in */ 00310 in = strsep(&duplinet, " "); 00311 if (!in || 00312 strcmp(in, "in")) { 00313 free(dupline); 00314 return NULL; 00315 } 00316 00317 if (ast_lock_contexts()) { 00318 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00319 free(dupline); 00320 return NULL; 00321 } 00322 00323 /* walk through all contexts ... */ 00324 c = ast_walk_contexts(NULL); 00325 while (c) { 00326 struct ast_include *i; 00327 if (ast_lock_context(c)) { 00328 free(dupline); 00329 return NULL; 00330 } 00331 00332 /* walk through all includes and check if it is our context */ 00333 i = ast_walk_context_includes(c, NULL); 00334 while (i) { 00335 /* is in this context included another on which we want to 00336 * remove? 00337 */ 00338 if (!strcmp(context, ast_get_include_name(i))) { 00339 /* yes, it's included, is matching our word too? */ 00340 if (!strncmp(ast_get_context_name(c), 00341 word, strlen(word))) { 00342 /* check state for completion */ 00343 if (++which > state) { 00344 char *res = strdup(ast_get_context_name(c)); 00345 free(dupline); 00346 ast_unlock_context(c); 00347 ast_unlock_contexts(); 00348 return res; 00349 } 00350 } 00351 break; 00352 } 00353 i = ast_walk_context_includes(c, i); 00354 } 00355 ast_unlock_context(c); 00356 c = ast_walk_contexts(c); 00357 } 00358 00359 free(dupline); 00360 ast_unlock_contexts(); 00361 return NULL; 00362 } 00363 00364 return NULL; 00365 }
| static char* complete_context_remove_extension | ( | char * | line, | |
| char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 484 of file pbx_config.c.
References ast_get_context_name(), ast_get_extension_name(), ast_get_extension_priority(), ast_lock_contexts(), ast_log(), ast_unlock_contexts(), ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), context, exten, fix_complete_args(), free, LOG_ERROR, malloc, ast_exten::priority, strdup, and strsep().
00486 { 00487 char *ret = NULL; 00488 int which = 0; 00489 00490 #ifdef BROKEN_READLINE 00491 /* 00492 * Fix arguments, *word is a new allocated structure, REMEMBER to 00493 * free *word when you want to return from this function ... 00494 */ 00495 if (fix_complete_args(line, &word, &pos)) { 00496 ast_log(LOG_ERROR, "Out of free memory\n"); 00497 return NULL; 00498 } 00499 #endif 00500 00501 /* 00502 * exten@context completion ... 00503 */ 00504 if (pos == 2) { 00505 struct ast_context *c; 00506 struct ast_exten *e; 00507 char *context = NULL, *exten = NULL, *delim = NULL; 00508 00509 /* now, parse values from word = exten@context */ 00510 if ((delim = strchr(word, (int)'@'))) { 00511 /* check for duplicity ... */ 00512 if (delim != strrchr(word, (int)'@')) { 00513 #ifdef BROKEN_READLINE 00514 free(word); 00515 #endif 00516 return NULL; 00517 } 00518 00519 *delim = '\0'; 00520 exten = strdup(word); 00521 context = strdup(delim + 1); 00522 *delim = '@'; 00523 } else { 00524 exten = strdup(word); 00525 } 00526 #ifdef BROKEN_READLINE 00527 free(word); 00528 #endif 00529 00530 if (ast_lock_contexts()) { 00531 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00532 free(context); free(exten); 00533 return NULL; 00534 } 00535 00536 /* find our context ... */ 00537 c = ast_walk_contexts(NULL); 00538 while (c) { 00539 /* our context? */ 00540 if ( (!context || !strlen(context)) || /* if no input, all contexts ... */ 00541 (context && !strncmp(ast_get_context_name(c), 00542 context, strlen(context))) ) { /* if input, compare ... */ 00543 /* try to complete extensions ... */ 00544 e = ast_walk_context_extensions(c, NULL); 00545 while (e) { 00546 /* our extension? */ 00547 if ( (!exten || !strlen(exten)) || /* if not input, all extensions ... */ 00548 (exten && !strncmp(ast_get_extension_name(e), exten, 00549 strlen(exten))) ) { /* if input, compare ... */ 00550 if (++which > state) { 00551 /* If there is an extension then return 00552 * exten@context. 00553 */ 00554 if (exten) { 00555 ret = malloc(strlen(ast_get_extension_name(e)) + 00556 strlen(ast_get_context_name(c)) + 2); 00557 if (ret) 00558 sprintf(ret, "%s@%s", ast_get_extension_name(e), 00559 ast_get_context_name(c)); 00560 } 00561 free(exten); free(context); 00562 00563 ast_unlock_contexts(); 00564 00565 return ret; 00566 } 00567 } 00568 e = ast_walk_context_extensions(c, e); 00569 } 00570 } 00571 c = ast_walk_contexts(c); 00572 } 00573 00574 ast_unlock_contexts(); 00575 00576 free(exten); free(context); 00577 00578 return NULL; 00579 } 00580 00581 /* 00582 * Complete priority ... 00583 */ 00584 if (pos == 3) { 00585 char *delim, *exten, *context, *dupline, *duplinet, *ec; 00586 struct ast_context *c; 00587 00588 dupline = strdup(line); 00589 if (!dupline) { 00590 #ifdef BROKEN_READLINE 00591 free(word); 00592 #endif 00593 return NULL; 00594 } 00595 duplinet = dupline; 00596 00597 strsep(&duplinet, " "); /* skip 'remove' */ 00598 strsep(&duplinet, " "); /* skip 'extension */ 00599 00600 if (!(ec = strsep(&duplinet, " "))) { 00601 free(dupline); 00602 #ifdef BROKEN_READLINE 00603 free(word); 00604 #endif 00605 return NULL; 00606 } 00607 00608 /* wrong exten@context format? */ 00609 if (!(delim = strchr(ec, (int)'@')) || 00610 (strchr(ec, (int)'@') != strrchr(ec, (int)'@'))) { 00611 #ifdef BROKEN_READLINE 00612 free(word); 00613 #endif 00614 free(dupline); 00615 return NULL; 00616 } 00617 00618 /* check if there is exten and context too ... */ 00619 *delim = '\0'; 00620 if ((!strlen(ec)) || (!strlen(delim + 1))) { 00621 #ifdef BROKEN_READLINE 00622 free(word); 00623 #endif 00624 free(dupline); 00625 return NULL; 00626 } 00627 00628 exten = strdup(ec); 00629 context = strdup(delim + 1); 00630 free(dupline); 00631 00632 if (ast_lock_contexts()) { 00633 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00634 #ifdef BROKEN_READLINE 00635 free(word); 00636 #endif 00637 free(exten); free(context); 00638 return NULL; 00639 } 00640 00641 /* walk contexts */ 00642 c = ast_walk_contexts(NULL); 00643 while (c) { 00644 if (!strcmp(ast_get_context_name(c), context)) { 00645 struct ast_exten *e; 00646 00647 /* walk extensions */ 00648 free(context); 00649 e = ast_walk_context_extensions(c, NULL); 00650 while (e) { 00651 if (!strcmp(ast_get_extension_name(e), exten)) { 00652 struct ast_exten *priority; 00653 char buffer[10]; 00654 00655 free(exten); 00656 priority = ast_walk_extension_priorities(e, NULL); 00657 /* serve priorities */ 00658 do { 00659 snprintf(buffer, 10, "%u", 00660 ast_get_extension_priority(priority)); 00661 if (!strncmp(word, buffer, strlen(word))) { 00662 if (++which > state) { 00663 #ifdef BROKEN_READLINE 00664 free(word); 00665 #endif 00666 ast_unlock_contexts(); 00667 return strdup(buffer); 00668 } 00669 } 00670 priority = ast_walk_extension_priorities(e, 00671 priority); 00672 } while (priority); 00673 00674 #ifdef BROKEN_READLINE 00675 free(word); 00676 #endif 00677 ast_unlock_contexts(); 00678 return NULL; 00679 } 00680 e = ast_walk_context_extensions(c, e); 00681 } 00682 #ifdef BROKEN_READLINE 00683 free(word); 00684 #endif 00685 free(exten); 00686 ast_unlock_contexts(); 00687 return NULL; 00688 } 00689 c = ast_walk_contexts(c); 00690 } 00691 00692 #ifdef BROKEN_READLINE 00693 free(word); 00694 #endif 00695 free(exten); free(context); 00696 00697 ast_unlock_contexts(); 00698 return NULL; 00699 } 00700 00701 #ifdef BROKEN_READLINE 00702 free(word); 00703 #endif 00704 return NULL; 00705 }
| static char* complete_context_remove_ignorepat | ( | char * | line, | |
| char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 1441 of file pbx_config.c.
References ast_get_context_name(), ast_get_ignorepat_name(), ast_lock_context(), ast_lock_contexts(), ast_log(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_ignorepats(), ast_walk_contexts(), free, LOG_WARNING, strdup, and strsep().
01443 { 01444 struct ast_context *c; 01445 int which = 0; 01446 01447 if (pos == 2) { 01448 if (ast_lock_contexts()) { 01449 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01450 return NULL; 01451 } 01452 01453 c = ast_walk_contexts(NULL); 01454 while (c) { 01455 if (!ast_lock_context(c)) { 01456 struct ast_ignorepat *ip; 01457 01458 ip = ast_walk_context_ignorepats(c, NULL); 01459 while (ip) { 01460 if (!strncmp(ast_get_ignorepat_name(ip), word, strlen(word))) { 01461 if (which + 1 > state) { 01462 struct ast_context *cw; 01463 int already_served = 0; 01464 cw = ast_walk_contexts(NULL); 01465 while (cw && cw != c && !already_served) { 01466 if (!ast_lock_context(cw)) { 01467 struct ast_ignorepat *ipw; 01468 ipw = ast_walk_context_ignorepats(cw, NULL); 01469 while (ipw) { 01470 if (!strcmp(ast_get_ignorepat_name(ipw), 01471 ast_get_ignorepat_name(ip))) already_served = 1; 01472 ipw = ast_walk_context_ignorepats(cw, ipw); 01473 } 01474 ast_unlock_context(cw); 01475 } 01476 cw = ast_walk_contexts(cw); 01477 } 01478 if (!already_served) { 01479 char *ret = strdup(ast_get_ignorepat_name(ip)); 01480 ast_unlock_context(c); 01481 ast_unlock_contexts(); 01482 return ret; 01483 } 01484 } else 01485 which++; 01486 } 01487 ip = ast_walk_context_ignorepats(c, ip); 01488 } 01489 01490 ast_unlock_context(c); 01491 } 01492 c = ast_walk_contexts(c); 01493 } 01494 01495 ast_unlock_contexts(); 01496 return NULL; 01497 } 01498 01499 if (pos == 3) return state == 0 ? strdup("from") : NULL; 01500 01501 if (pos == 4) { 01502 char *dupline, *duplinet, *ignorepat; 01503 01504 dupline = strdup(line); 01505 if (!dupline) { 01506 ast_log(LOG_WARNING, "Out of free memory\n"); 01507 return NULL; 01508 } 01509 01510 duplinet = dupline; 01511 strsep(&duplinet, " "); 01512 strsep(&duplinet, " "); 01513 ignorepat = strsep(&duplinet, " "); 01514 01515 if (!ignorepat) { 01516 free(dupline); 01517 return NULL; 01518 } 01519 01520 if (ast_lock_contexts()) { 01521 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01522 free(dupline); 01523 return NULL; 01524 } 01525 01526 c = ast_walk_contexts(NULL); 01527 while (c) { 01528 if (!ast_lock_context(c)) { 01529 struct ast_ignorepat *ip; 01530 ip = ast_walk_context_ignorepats(c, NULL); 01531 while (ip) { 01532 if (!strcmp(ast_get_ignorepat_name(ip), ignorepat)) { 01533 if (!strncmp(ast_get_context_name(c), word, strlen(word))) { 01534 if (++which > state) { 01535 char *ret = strdup(ast_get_context_name(c)); 01536 free(dupline); 01537 ast_unlock_context(c); 01538 ast_unlock_contexts(); 01539 return ret; 01540 } 01541 } 01542 } 01543 ip = ast_walk_context_ignorepats(c, ip); 01544 } 01545 01546 ast_unlock_context(c); 01547 } 01548 c = ast_walk_contexts(c); 01549 } 01550 01551 free(dupline); 01552 ast_unlock_contexts(); 01553 return NULL; 01554 } 01555 01556 return NULL; 01557 }
| char* description | ( | void | ) |
Provides a description of the module.
Definition at line 1837 of file pbx_config.c.
01838 { 01839 return dtext; 01840 }
| static int fix_complete_args | ( | char * | line, | |
| char ** | word, | |||
| int * | pos | |||
| ) | [static] |
Definition at line 452 of file pbx_config.c.
References free, strdup, and strsep().
Referenced by complete_context_remove_extension().
00453 { 00454 char *_line, *_strsep_line, *_previous_word = NULL, *_word = NULL; 00455 int words = 0; 00456 00457 _line = strdup(line); 00458 00459 _strsep_line = _line; 00460 while (_strsep_line) { 00461 _previous_word = _word; 00462 _word = strsep(&_strsep_line, " "); 00463 00464 if (_word && strlen(_word)) words++; 00465 } 00466 00467 00468 if (_word || _previous_word) { 00469 if (_word) { 00470 if (!strlen(_word)) words++; 00471 *word = strdup(_word); 00472 } else 00473 *word = strdup(_previous_word); 00474 *pos = words - 1; 00475 free(_line); 00476 return 0; 00477 } 00478 00479 free(_line); 00480 return -1; 00481 }
| static int handle_context_add_extension | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
ADD EXTENSION command stuff.
Definition at line 1169 of file pbx_config.c.
References app, ast_add_extension(), ast_cli(), ast_process_quotes_and_slashes(), ast_exten::cidmatch, exten, free, PRIORITY_HINT, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, strdup, and strsep().
01170 { 01171 char *whole_exten; 01172 char *exten, *prior; 01173 int iprior = -2; 01174 char *cidmatch, *app, *app_data; 01175 char *start, *end; 01176 01177 /* check for arguments at first */ 01178 if (argc != 5 && argc != 6) return RESULT_SHOWUSAGE; 01179 if (strcmp(argv[3], "into")) return RESULT_SHOWUSAGE; 01180 if (argc == 6) if (strcmp(argv[5], "replace")) return RESULT_SHOWUSAGE; 01181 01182 whole_exten = argv[2]; 01183 exten = strsep(&whole_exten,","); 01184 if (strchr(exten, '/')) { 01185 cidmatch = exten; 01186 strsep(&cidmatch,"/"); 01187 } else { 01188 cidmatch = NULL; 01189 } 01190 prior = strsep(&whole_exten,","); 01191 if (prior) { 01192 if (!strcmp(prior, "hint")) { 01193 iprior = PRIORITY_HINT; 01194 } else { 01195 if (sscanf(prior, "%30d", &iprior) != 1) { 01196 ast_cli(fd, "'%s' is not a valid priority\n", prior); 01197 prior = NULL; 01198 } 01199 } 01200 } 01201 app = whole_exten; 01202 if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) { 01203 *start = *end = '\0'; 01204 app_data = start + 1; 01205 ast_process_quotes_and_slashes(app_data, ',', '|'); 01206 } else { 01207 if (app) { 01208 app_data = strchr(app, ','); 01209 if (app_data) { 01210 *app_data = '\0'; 01211 app_data++; 01212 } 01213 } else 01214 app_data = NULL; 01215 } 01216 01217 if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT)) return RESULT_SHOWUSAGE; 01218 01219 if (!app_data) 01220 app_data=""; 01221 if (ast_add_extension(argv[4], argc == 6 ? 1 : 0, exten, iprior, NULL, cidmatch, app, 01222 (void *)strdup(app_data), free, registrar)) { 01223 switch (errno) { 01224 case ENOMEM: 01225 ast_cli(fd, "Out of free memory\n"); break; 01226 01227 case EBUSY: 01228 ast_cli(fd, "Failed to lock context(s) list, please try again later\n"); break; 01229 01230 case ENOENT: 01231 ast_cli(fd, "No existence of '%s' context\n", argv[4]); break; 01232 01233 case EEXIST: 01234 ast_cli(fd, "Extension %s@%s with priority %s already exists\n", 01235 exten, argv[4], prior); break; 01236 01237 default: 01238 ast_cli(fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n", 01239 exten, prior, app, app_data, argv[4]); break; 01240 } 01241 return RESULT_FAILURE; 01242 } 01243 01244 if (argc == 6) 01245 ast_cli(fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n", 01246 exten, argv[4], prior, exten, prior, app, app_data); 01247 else 01248 ast_cli(fd, "Extension '%s,%s,%s,%s' added into '%s' context\n", 01249 exten, prior, app, app_data, argv[4]); 01250 01251 return RESULT_SUCCESS; 01252 }
| static int handle_context_add_ignorepat | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
IGNOREPAT CLI stuff
Definition at line 1302 of file pbx_config.c.
References ast_cli(), ast_context_add_ignorepat(), RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01303 { 01304 if (argc != 5) return RESULT_SHOWUSAGE; 01305 if (strcmp(argv[3], "into")) return RESULT_SHOWUSAGE; 01306 01307 if (ast_context_add_ignorepat(argv[4], argv[2], registrar)) { 01308 switch (errno) { 01309 case ENOMEM: 01310 ast_cli(fd, "Out of free memory\n"); break; 01311 01312 case ENOENT: 01313 ast_cli(fd, "There is no existence of '%s' context\n", argv[4]); 01314 break; 01315 01316 case EEXIST: 01317 ast_cli(fd, "Ignore pattern '%s' already included in '%s' context\n", 01318 argv[2], argv[4]); 01319 break; 01320 01321 case EBUSY: 01322 ast_cli(fd, "Failed to lock context(s) list, please, try again later\n"); 01323 break; 01324 01325 default: 01326 ast_cli(fd, "Failed to add ingore pattern '%s' into '%s' context\n", 01327 argv[2], argv[4]); 01328 break; 01329 } 01330 return RESULT_FAILURE; 01331 } 01332 01333 ast_cli(fd, "Ignore pattern '%s' added into '%s' context\n", 01334 argv[2], argv[4]); 01335 return RESULT_SUCCESS; 01336 }
| static int handle_context_add_include | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Include context ...
Definition at line 710 of file pbx_config.c.
References ast_cli(), ast_context_add_include(), RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00711 { 00712 if (argc != 5) return RESULT_SHOWUSAGE; 00713 00714 /* third arg must be 'in' ... */ 00715 if (strcmp(argv[3], "in") && strcmp(argv[3], "into")) return RESULT_SHOWUSAGE; 00716 00717 if (ast_context_add_include(argv[4], argv[2], registrar)) { 00718 switch (errno) { 00719 case ENOMEM: 00720 ast_cli(fd, "Out of memory for context addition\n"); break; 00721 00722 case EBUSY: 00723 ast_cli(fd, "Failed to lock context(s) list, please try again later\n"); break; 00724 00725 case EEXIST: 00726 ast_cli(fd, "Context '%s' already included in '%s' context\n", 00727 argv[2], argv[4]); break; 00728 00729 case ENOENT: 00730 case EINVAL: 00731 ast_cli(fd, "There is no existence of context '%s'\n", 00732 errno == ENOENT ? argv[4] : argv[2]); break; 00733 00734 default: 00735 ast_cli(fd, "Failed to include '%s' in '%s' context\n", 00736 argv[2], argv[4]); break; 00737 } 00738 return RESULT_FAILURE; 00739 } 00740 00741 /* show some info ... */ 00742 ast_cli(fd, "Context '%s' included in '%s' context\n", 00743 argv[2], argv[4]); 00744 00745 return RESULT_SUCCESS; 00746 }
| static int handle_context_dont_include | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
REMOVE INCLUDE command stuff
Definition at line 127 of file pbx_config.c.
References ast_cli(), ast_context_remove_include(), RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00128 { 00129 if (argc != 5) 00130 return RESULT_SHOWUSAGE; 00131 00132 if (strcmp(argv[3], "in")) 00133 return RESULT_SHOWUSAGE; 00134 00135 if (!ast_context_remove_include(argv[4], argv[2], registrar)) { 00136 ast_cli(fd, "We are not including '%s' in '%s' now\n", 00137 argv[2], argv[4]); 00138 return RESULT_SUCCESS; 00139 } 00140 00141 ast_cli(fd, "Failed to remove '%s' include from '%s' context\n", 00142 argv[2], argv[4]); 00143 return RESULT_FAILURE; 00144 }
| static int handle_context_remove_extension | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
REMOVE EXTENSION command stuff
Definition at line 370 of file pbx_config.c.
References ast_cli(), ast_context_remove_extension(), context, exten, PRIORITY_HINT, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00371 { 00372 int removing_priority = 0; 00373 char *exten, *context; 00374 00375 if (argc != 4 && argc != 3) return RESULT_SHOWUSAGE; 00376 00377 /* 00378 * Priority input checking ... 00379 */ 00380 if (argc == 4) { 00381 char *c = argv[3]; 00382 00383 /* check for digits in whole parameter for right priority ... 00384 * why? because atoi (strtol) returns 0 if any characters in 00385 * string and whole extension will be removed, it's not good 00386 */ 00387 if (strcmp("hint", c)) { 00388 while (*c != '\0') { 00389 if (!isdigit(*c++)) { 00390 ast_cli(fd, "Invalid priority '%s'\n", argv[3]); 00391 return RESULT_FAILURE; 00392 } 00393 } 00394 removing_priority = atoi(argv[3]); 00395 } else 00396 removing_priority = PRIORITY_HINT; 00397 00398 if (removing_priority == 0) { 00399 ast_cli(fd, "If you want to remove whole extension, please " \ 00400 "omit priority argument\n"); 00401 return RESULT_FAILURE; 00402 } 00403 } 00404 00405 /* 00406 * Format exten@context checking ... 00407 */ 00408 if (!(context = strchr(argv[2], (int)'@'))) { 00409 ast_cli(fd, "First argument must be in exten@context format\n"); 00410 return RESULT_FAILURE; 00411 } 00412 00413 *context++ = '\0'; 00414 exten = argv[2]; 00415 if ((!strlen(exten)) || (!(strlen(context)))) { 00416 ast_cli(fd, "Missing extension or context name in second argument '%s@%s'\n", 00417 exten == NULL ? "?" : exten, context == NULL ? "?" : context); 00418 return RESULT_FAILURE; 00419 } 00420 00421 if (!ast_context_remove_extension(context, exten, removing_priority, registrar)) { 00422 if (!removing_priority) 00423 ast_cli(fd, "Whole extension %s@%s removed\n", 00424 exten, context); 00425 else 00426 ast_cli(fd, "Extension %s@%s with priority %d removed\n", 00427 exten, context, removing_priority); 00428 00429 return RESULT_SUCCESS; 00430 } 00431 00432 ast_cli(fd, "Failed to remove extension %s@%s\n", exten, context); 00433 00434 return RESULT_FAILURE; 00435 }
| static int handle_context_remove_ignorepat | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 1398 of file pbx_config.c.
References ast_cli(), ast_context_remove_ignorepat(), RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01399 { 01400 if (argc != 5) return RESULT_SHOWUSAGE; 01401 if (strcmp(argv[3], "from")) return RESULT_SHOWUSAGE; 01402 01403 if (ast_context_remove_ignorepat(argv[4], argv[2], registrar)) { 01404 switch (errno) { 01405 case EBUSY: 01406 ast_cli(fd, "Failed to lock context(s) list, please try again later\n"); 01407 break; 01408 01409 case ENOENT: 01410 ast_cli(fd, "There is no existence of '%s' context\n", argv[4]); 01411 break; 01412 01413 case EINVAL: 01414 ast_cli(fd, "There is no existence of '%s' ignore pattern in '%s' context\n", 01415 argv[2], argv[4]); 01416 break; 01417 01418 default: 01419 ast_cli(fd, "Failed to remove ignore pattern '%s' from '%s' context\n", argv[2], argv[4]); 01420 break; 01421 } 01422 return RESULT_FAILURE; 01423 } 01424 01425 ast_cli(fd, "Ignore pattern '%s' removed from '%s' context\n", 01426 argv[2], argv[4]); 01427 return RESULT_SUCCESS; 01428 }
| static int handle_reload_extensions | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 1432 of file pbx_config.c.
References pbx_builtin_clear_globals(), pbx_load_module(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01433 { 01434 if (argc!=2) return RESULT_SHOWUSAGE; 01435 if (clearglobalvars_config) 01436 pbx_builtin_clear_globals(); 01437 pbx_load_module(); 01438 return RESULT_SUCCESS; 01439 }
| static int handle_save_dialplan | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
'save dialplan' CLI command implementation functions ...
Definition at line 922 of file pbx_config.c.
References 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_lock_context(), ast_lock_contexts(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, 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(), cfg, el, ast_exten::label, ast_variable::name, ast_variable::next, option_priority_jumping, PRIORITY_HINT, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_variable::value.
00923 { 00924 char filename[256]; 00925 struct ast_context *c; 00926 struct ast_config *cfg; 00927 struct ast_variable *v; 00928 int context_header_written; 00929 int incomplete = 0; /* incomplete config write? */ 00930 FILE *output; 00931 00932 if (! (static_config && !write_protect_config)) { 00933 ast_cli(fd, 00934 "I can't save dialplan now, see '%s' example file.\n", 00935 config); 00936 return RESULT_FAILURE; 00937 } 00938 00939 if (argc != 2 && argc != 3) return RESULT_SHOWUSAGE; 00940 00941 if (ast_mutex_lock(&save_dialplan_lock)) { 00942 ast_cli(fd, 00943 "Failed to lock dialplan saving (another proccess saving?)\n"); 00944 return RESULT_FAILURE; 00945 } 00946 00947 /* have config path? */ 00948 if (argc == 3) { 00949 /* is there extension.conf too? */ 00950 if (!strstr(argv[2], ".conf")) { 00951 /* no, only directory path, check for last '/' occurence */ 00952 if (*(argv[2] + strlen(argv[2]) -1) == '/') 00953 snprintf(filename, sizeof(filename), "%s%s", 00954 argv[2], config); 00955 else 00956 /* without config extensions.conf, add it */ 00957 snprintf(filename, sizeof(filename), "%s/%s", 00958 argv[2], config); 00959 } else 00960 /* there is an .conf */ 00961 snprintf(filename, sizeof(filename), argv[2]); 00962 } else 00963 /* no config file, default one */ 00964 snprintf(filename, sizeof(filename), "%s/%s", 00965 (char *)ast_config_AST_CONFIG_DIR, config); 00966 00967 cfg = ast_config_load("extensions.conf"); 00968 00969 /* try to lock contexts list */ 00970 if (ast_lock_contexts()) { 00971 ast_cli(fd, "Failed to lock contexts list\n"); 00972 ast_mutex_unlock(&save_dialplan_lock); 00973 ast_config_destroy(cfg); 00974 return RESULT_FAILURE; 00975 } 00976 00977 /* create new file ... */ 00978 if (!(output = fopen(filename, "wt"))) { 00979 ast_cli(fd, "Failed to create file '%s'\n", 00980 filename); 00981 ast_unlock_contexts(); 00982 ast_mutex_unlock(&save_dialplan_lock); 00983 ast_config_destroy(cfg); 00984 return RESULT_FAILURE; 00985 } 00986 00987 /* fireout general info */ 00988 fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\npriorityjumping=%s\n\n", 00989 static_config ? "yes" : "no", 00990 write_protect_config ? "yes" : "no", 00991 autofallthrough_config ? "yes" : "no", 00992 clearglobalvars_config ? "yes" : "no", 00993 option_priority_jumping ? "yes" : "no"); 00994 00995 if ((v = ast_variable_browse(cfg, "globals"))) { 00996 fprintf(output, "[globals]\n"); 00997 while(v) { 00998 fprintf(output, "%s => %s\n", v->name, v->value); 00999 v = v->next; 01000 } 01001 fprintf(output, "\n"); 01002 } 01003 01004 ast_config_destroy(cfg); 01005 01006 /* walk all contexts */ 01007 c = ast_walk_contexts(NULL); 01008 while (c) { 01009 context_header_written = 0; 01010 01011 /* try to lock context and fireout all info */ 01012 if (!ast_lock_context(c)) { 01013 struct ast_exten *e, *last_written_e = NULL; 01014 struct ast_include *i; 01015 struct ast_ignorepat *ip; 01016 struct ast_sw *sw; 01017 01018 /* registered by this module? */ 01019 if (!strcmp(ast_get_context_registrar(c), registrar)) { 01020 fprintf(output, "[%s]\n", ast_get_context_name(c)); 01021 context_header_written = 1; 01022 } 01023 01024 /* walk extensions ... */ 01025 e = ast_walk_context_extensions(c, NULL); 01026 while (e) { 01027 struct ast_exten *p; 01028 01029 /* fireout priorities */ 01030 p = ast_walk_extension_priorities(e, NULL); 01031 while (p) { 01032 if (!strcmp(ast_get_extension_registrar(p), 01033 registrar)) { 01034 01035 /* make empty line between different extensions */ 01036 if (last_written_e != NULL && 01037 strcmp(ast_get_extension_name(last_written_e), 01038 ast_get_extension_name(p))) 01039 fprintf(output, "\n"); 01040 last_written_e = p; 01041 01042 if (!context_header_written) { 01043 fprintf(output, "[%s]\n", ast_get_context_name(c)); 01044 context_header_written = 1; 01045 } 01046 01047 if (ast_get_extension_priority(p)!=PRIORITY_HINT) { 01048 char *tempdata, *startdata; 01049 const char *el = ast_get_extension_label(p); 01050 char label[128] = ""; 01051 01052 tempdata = ast_strdupa(ast_get_extension_app_data(p)); 01053 01054 startdata = tempdata; 01055 while (*tempdata) { 01056 if (*tempdata == '|') 01057 *tempdata = ','; 01058 tempdata++; 01059 } 01060 tempdata = startdata; 01061 01062 if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2))) 01063 incomplete = 1; // error encountered or label is > 125 chars 01064 01065 if (ast_get_extension_matchcid(p)) { 01066 fprintf(output, "exten => %s/%s,%d%s,%s(%s)\n", 01067 ast_get_extension_name(p), 01068 ast_get_extension_cidmatch(p), 01069 ast_get_extension_priority(p), label, 01070 ast_get_extension_app(p), 01071 tempdata); 01072 } else { 01073 fprintf(output, "exten => %s,%d%s,%s(%s)\n", 01074 ast_get_extension_name(p), 01075 ast_get_extension_priority(p), label, 01076 ast_get_extension_app(p), 01077 tempdata); 01078 } 01079 } else { 01080 fprintf(output, "exten => %s,hint,%s\n", 01081 ast_get_extension_name(p), 01082 ast_get_extension_app(p)); 01083 } 01084 01085 } 01086 p = ast_walk_extension_priorities(e, p); 01087 } 01088 01089 e = ast_walk_context_extensions(c, e); 01090 } 01091 01092 /* written any extensions? ok, write space between exten & inc */ 01093 if (last_written_e) fprintf(output, "\n"); 01094 01095 /* walk through includes */ 01096 i = ast_walk_context_includes(c, NULL); 01097 while (i) { 01098 if (!strcmp(ast_get_include_registrar(i), registrar)) { 01099 if (!context_header_written) { 01100 fprintf(output, "[%s]\n", ast_get_context_name(c)); 01101 context_header_written = 1; 01102 } 01103 fprintf(output, "include => %s\n", 01104 ast_get_include_name(i)); 01105 } 01106 i = ast_walk_context_includes(c, i); 01107 } 01108 01109 if (ast_walk_context_includes(c, NULL)) 01110 fprintf(output, "\n"); 01111 01112 /* walk through switches */ 01113 sw = ast_walk_context_switches(c, NULL); 01114 while (sw) { 01115 if (!strcmp(ast_get_switch_registrar(sw), registrar)) { 01116 if (!context_header_written) { 01117 fprintf(output, "[%s]\n", ast_get_context_name(c)); 01118 context_header_written = 1; 01119 } 01120 fprintf(output, "switch => %s/%s\n", 01121 ast_get_switch_name(sw), 01122 ast_get_switch_data(sw)); 01123 } 01124 sw = ast_walk_context_switches(c, sw); 01125 } 01126 01127 if (ast_walk_context_switches(c, NULL)) 01128 fprintf(output, "\n"); 01129 01130 /* fireout ignorepats ... */ 01131 ip = ast_walk_context_ignorepats(c, NULL); 01132 while (ip) { 01133 if (!strcmp(ast_get_ignorepat_registrar(ip), registrar)) { 01134 if (!context_header_written) { 01135 fprintf(output, "[%s]\n", ast_get_context_name(c)); 01136 context_header_written = 1; 01137 } 01138 01139 fprintf(output, "ignorepat => %s\n", 01140 ast_get_ignorepat_name(ip)); 01141 } 01142 ip = ast_walk_context_ignorepats(c, ip); 01143 } 01144 01145 ast_unlock_context(c); 01146 } else 01147 incomplete = 1; 01148 01149 c = ast_walk_contexts(c); 01150 } 01151 01152 ast_unlock_contexts(); 01153 ast_mutex_unlock(&save_dialplan_lock); 01154 fclose(output); 01155 01156 if (incomplete) { 01157 ast_cli(fd, "Saved dialplan is incomplete\n"); 01158 return RESULT_FAILURE; 01159 } 01160 01161 ast_cli(fd, "Dialplan successfully saved into '%s'\n", 01162 filename); 01163 return RESULT_SUCCESS; 01164 }
| char* key | ( | void | ) |
Returns the ASTERISK_GPL_KEY.
This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 1842 of file pbx_config.c.
References ASTERISK_GPL_KEY.
01843 { 01844 return ASTERISK_GPL_KEY; 01845 }
| int load_module | ( | void | ) |
Initialize the module.
This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.
Definition at line 1807 of file pbx_config.c.
References ast_cli_register(), and pbx_load_module().
01808 { 01809 if (pbx_load_module()) return -1; 01810 01811 ast_cli_register(&context_remove_extension_cli); 01812 ast_cli_register(&context_dont_include_cli); 01813 ast_cli_register(&context_add_include_cli); 01814 if (static_config && !write_protect_config) 01815 ast_cli_register(&save_dialplan_cli); 01816 ast_cli_register(&context_add_extension_cli); 01817 ast_cli_register(&context_add_ignorepat_cli); 01818 ast_cli_register(&context_remove_ignorepat_cli); 01819 ast_cli_register(&reload_extensions_cli); 01820 01821 return 0; 01822 }
| static int pbx_load_module | ( | void | ) | [static] |
Definition at line 1618 of file pbx_config.c.
References ast_add_extension2(), ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_create(), ast_context_verify_includes(), ast_false(), ast_findlabel_extension2(), ast_log(), ast_merge_contexts_and_delete(), ast_process_quotes_and_slashes(), ast_shrink_phone_number(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_walk_contexts(), cfg, free, FREE, ast_variable::lineno, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, option_dontwarn, option_priority_jumping, pbx_builtin_setvar_helper(), pbx_set_autofallthrough(), pbx_substitute_variables_helper(), PRIORITY_HINT, strdup, strsep(), and ast_variable::value.
01619 { 01620 struct ast_config *cfg; 01621 struct ast_variable *v; 01622 char *cxt, *ext, *pri, *appl, *data, *tc, *cidmatch; 01623 struct ast_context *con; 01624 char *end; 01625 char *label; 01626 char realvalue[256]; 01627 int lastpri = -2; 01628 01629 cfg = ast_config_load(config); 01630 if (cfg) { 01631 /* Use existing config to populate the PBX table */ 01632 static_config = ast_true(ast_variable_retrieve(cfg, "general", 01633 "static")); 01634 write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", 01635 "writeprotect")); 01636 autofallthrough_config = ast_true(ast_variable_retrieve(cfg, "general", 01637 "autofallthrough")); 01638 clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", 01639 "clearglobalvars")); 01640 option_priority_jumping = !ast_false(ast_variable_retrieve(cfg, "general", 01641 "priorityjumping")); 01642 01643 v = ast_variable_browse(cfg, "globals"); 01644 while(v) { 01645 memset(realvalue, 0, sizeof(realvalue)); 01646 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01647 pbx_builtin_setvar_helper(NULL, v->name, realvalue); 01648 v = v->next; 01649 } 01650 cxt = ast_category_browse(cfg, NULL); 01651 while(cxt) { 01652 /* All categories but "general" or "globals" are considered contexts */ 01653 if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) { 01654 cxt = ast_category_browse(cfg, cxt); 01655 continue; 01656 } 01657 if ((con=ast_context_create(&local_contexts,cxt, registrar))) { 01658 v = ast_variable_browse(cfg, cxt); 01659 while(v) { 01660 if (!strcasecmp(v->name, "exten")) { 01661 char *stringp=NULL; 01662 int ipri = -2; 01663 char realext[256]=""; 01664 char *plus, *firstp, *firstc; 01665 tc = strdup(v->value); 01666 if(tc!=NULL){ 01667 stringp=tc; 01668 ext = strsep(&stringp, ","); 01669 if (!ext) 01670 ext=""; 01671 pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1); 01672 cidmatch = strchr(realext, '/'); 01673 if (cidmatch) { 01674 *cidmatch = '\0'; 01675 cidmatch++; 01676 ast_shrink_phone_number(cidmatch); 01677 } 01678 pri = strsep(&stringp, ","); 01679 if (!pri) 01680 pri=""; 01681 pri = ast_skip_blanks(pri); 01682 pri = ast_trim_blanks(pri); 01683 label = strchr(pri, '('); 01684 if (label) { 01685 *label = '\0'; 01686 label++; 01687 end = strchr(label, ')'); 01688 if (end) 01689 *end = '\0'; 01690 else 01691 ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno); 01692 } 01693 plus = strchr(pri, '+'); 01694 if (plus) { 01695 *plus = '\0'; 01696 plus++; 01697 } 01698 if (!strcmp(pri,"hint")) 01699 ipri=PRIORITY_HINT; 01700 else if (!strcmp(pri, "next") || !strcmp(pri, "n")) { 01701 if (lastpri > -2) 01702 ipri = lastpri + 1; 01703 else 01704 ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry!\n"); 01705 } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) { 01706 if (lastpri > -2) 01707 ipri = lastpri; 01708 else 01709 ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry!\n"); 01710 } else { 01711 if (sscanf(pri, "%30d", &ipri) != 1) { 01712 if ((ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) { 01713 ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno); 01714 ipri = 0; 01715 } 01716 } 01717 } 01718 appl = stringp; 01719 if (!appl) 01720 appl=""; 01721 /* Find the first occurrence of either '(' or ',' */ 01722 firstc = strchr(appl, ','); 01723 firstp = strchr(appl, '('); 01724 if (firstc && ((!firstp) || (firstc < firstp))) { 01725 /* comma found, no parenthesis */ 01726 /* or both found, but comma found first */ 01727 appl = strsep(&stringp, ","); 01728 data = stringp; 01729 } else if ((!firstc) && (!firstp)) { 01730 /* Neither found */ 01731 data = ""; 01732 } else { 01733 /* Final remaining case is parenthesis found first */ 01734 appl = strsep(&stringp, "("); 01735 data = stringp; 01736 end = strrchr(data, ')'); 01737 if ((end = strrchr(data, ')'))) { 01738 *end = '\0'; 01739 } else { 01740 ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s'\n", appl, data); 01741 } 01742 ast_process_quotes_and_slashes(data, ',', '|'); 01743 } 01744 01745 if (!data) 01746 data=""; 01747 while(*appl && (*appl < 33)) appl++; 01748 if (ipri) { 01749 if (plus) 01750 ipri += atoi(plus); 01751 lastpri = ipri; 01752 if(!option_dontwarn) { 01753 if (!strcmp(realext, "_.")) 01754 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); 01755 } 01756 if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), FREE, registrar)) { 01757 ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno); 01758 } 01759 } 01760 free(tc); 01761 } else { 01762 ast_log(LOG_ERROR, "Memory allocation failure\n"); 01763 } 01764 } else if(!strcasecmp(v->name, "include")) { 01765 memset(realvalue, 0, sizeof(realvalue)); 01766 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01767 if (ast_context_add_include2(con, realvalue, registrar)) 01768 ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s'\n", v->value, cxt); 01769 } else if(!strcasecmp(v->name, "ignorepat")) { 01770 memset(realvalue, 0, sizeof(realvalue)); 01771 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01772 if (ast_context_add_ignorepat2(con, realvalue, registrar)) 01773 ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt); 01774 } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) { 01775 char *stringp=NULL; 01776 memset(realvalue, 0, sizeof(realvalue)); 01777 if (!strcasecmp(v->name, "switch")) 01778 pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1); 01779 else 01780 strncpy(realvalue, v->value, sizeof(realvalue) - 1); 01781 tc = realvalue; 01782 stringp=tc; 01783 appl = strsep(&stringp, "/"); 01784 data = strsep(&stringp, ""); 01785 if (!data) 01786 data = ""; 01787 if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar)) 01788 ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt); 01789 } 01790 v = v->next; 01791 } 01792 } 01793 cxt = ast_category_browse(cfg, cxt); 01794 } 01795 ast_config_destroy(cfg); 01796 } 01797 ast_merge_contexts_and_delete(&local_contexts,registrar); 01798 01799 for (con = ast_walk_contexts(NULL); con; con = ast_walk_contexts(con)) 01800 ast_context_verify_includes(con); 01801 01802 pbx_set_autofallthrough(autofallthrough_config); 01803 01804 return 0; 01805 }
| int reload | ( | void | ) |
Reload stuff.
This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 1824 of file pbx_config.c.
References pbx_builtin_clear_globals(), and pbx_load_module().
01825 { 01826 if (clearglobalvars_config) 01827 pbx_builtin_clear_globals(); 01828 pbx_load_module(); 01829 return 0; 01830 }
| int unload_module | ( | void | ) |
Cleanup all module structures, sockets, etc.
Standard module functions ...
Definition at line 1603 of file pbx_config.c.
References ast_cli_unregister(), and ast_context_destroy().
01604 { 01605 ast_cli_unregister(&context_add_extension_cli); 01606 if (static_config && !write_protect_config) 01607 ast_cli_unregister(&save_dialplan_cli); 01608 ast_cli_unregister(&context_add_include_cli); 01609 ast_cli_unregister(&context_dont_include_cli); 01610 ast_cli_unregister(&context_remove_extension_cli); 01611 ast_cli_unregister(&context_remove_ignorepat_cli); 01612 ast_cli_unregister(&context_add_ignorepat_cli); 01613 ast_cli_unregister(&reload_extensions_cli); 01614 ast_context_destroy(NULL, registrar); 01615 return 0; 01616 }
| int usecount | ( | void | ) |
Provides a usecount.
This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 1832 of file pbx_config.c.
int autofallthrough_config = 0 [static] |
Definition at line 60 of file pbx_config.c.
int clearglobalvars_config = 0 [static] |
Definition at line 61 of file pbx_config.c.
char* config = "extensions.conf" [static] |
Definition at line 55 of file pbx_config.c.
struct ast_cli_entry context_add_extension_cli [static] |
Initial value:
{ { "add", "extension", NULL }, handle_context_add_extension,
"Add new extension into context", context_add_extension_help,
complete_context_add_extension }
Definition at line 1581 of file pbx_config.c.
char context_add_extension_help[] [static] |
Definition at line 91 of file pbx_config.c.
struct ast_cli_entry context_add_ignorepat_cli [static] |
Initial value:
{ { "add", "ignorepat", NULL }, handle_context_add_ignorepat,
"Add new ignore pattern", context_add_ignorepat_help,
complete_context_add_ignorepat }
Definition at line 1586 of file pbx_config.c.
char context_add_ignorepat_help[] [static] |
Initial value:
"Usage: add ignorepat <pattern> into <context>\n" " This command adds a new ignore pattern into context <context>\n" "\n" "Example: add ignorepat _3XX into local\n"
Definition at line 101 of file pbx_config.c.
struct ast_cli_entry context_add_include_cli [static] |
Initial value:
{ { "include", "context", NULL }, handle_context_add_include,
"Include context in other context", context_add_include_help,
complete_context_add_include }
Definition at line 1572 of file pbx_config.c.
char context_add_include_help[] [static] |
Initial value:
"Usage: include <context> in <context>\n" " Include a context in another context.\n"
Definition at line 80 of file pbx_config.c.
struct ast_cli_entry context_dont_include_cli [static] |
Initial value:
{ { "dont", "include", NULL }, handle_context_dont_include,
"Remove a specified include from context", context_dont_include_help,
complete_context_dont_include }
Definition at line 1562 of file pbx_config.c.
char context_dont_include_help[] [static] |
Initial value:
"Usage: dont include <context> in <context>\n" " Remove an included context from another context.\n"
Definition at line 70 of file pbx_config.c.
struct ast_cli_entry context_remove_extension_cli [static] |
Initial value:
{ { "remove", "extension", NULL }, handle_context_remove_extension,
"Remove a specified extension", context_remove_extension_help,
complete_context_remove_extension }
Definition at line 1567 of file pbx_config.c.
char context_remove_extension_help[] [static] |
Initial value:
"Usage: remove extension exten@context [priority]\n" " Remove an extension from a given context. If a priority\n" " is given, only that specific priority from the given extension\n" " will be removed.\n"
Definition at line 74 of file pbx_config.c.
struct ast_cli_entry context_remove_ignorepat_cli [static] |
Initial value:
{ { "remove", "ignorepat", NULL }, handle_context_remove_ignorepat,
"Remove ignore pattern from context", context_remove_ignorepat_help,
complete_context_remove_ignorepat }
Definition at line 1591 of file pbx_config.c.
char context_remove_ignorepat_help[] [static] |
Initial value:
"Usage: remove ignorepat <pattern> from <context>\n" " This command removes an ignore pattern from context <context>\n" "\n" "Example: remove ignorepat _3XX from local\n"
Definition at line 107 of file pbx_config.c.
char* dtext = "Text Extension Configuration" [static] |
Definition at line 54 of file pbx_config.c.
struct ast_context* local_contexts = NULL [static] |
Definition at line 65 of file pbx_config.c.
Referenced by ast_context_create(), and pbx_load_module().
char* registrar = "pbx_config" [static] |
Definition at line 56 of file pbx_config.c.
struct ast_cli_entry reload_extensions_cli [static] |
Initial value:
{ { "extensions", "reload", NULL}, handle_reload_extensions,
"Reload extensions and *only* extensions", reload_extensions_help }
Definition at line 1596 of file pbx_config.c.
char reload_extensions_help[] [static] |
Definition at line 113 of file pbx_config.c.
struct ast_cli_entry save_dialplan_cli [static] |
Initial value:
{ { "save", "dialplan", NULL }, handle_save_dialplan,
"Save dialplan", save_dialplan_help }
Definition at line 1577 of file pbx_config.c.
char save_dialplan_help[] [static] |
Definition at line 84 of file pbx_config.c.
int static_config = 0 [static] |
Definition at line 58 of file pbx_config.c.
int write_protect_config = 1 [static] |
Definition at line 59 of file pbx_config.c.
1.5.6