#include "asterisk.h"
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.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"
Include dependency graph for pbx_config.c:

Go to the source code of this file.
Defines | |
| #define | BROKEN_READLINE 1 |
| #define | PUT_CTX_HDR |
Functions | |
| static void | append_interface (char *iface, int maxlen, char *add) |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Text Extension Configuration",.load=load_module,.unload=unload_module,.reload=reload,) | |
| AST_MUTEX_DEFINE_STATIC (save_dialplan_lock) | |
| static char * | complete_context_add_extension (const char *line, const char *word, int pos, int state) |
| static char * | complete_context_add_extension_deprecated (const char *line, const char *word, int pos, int state) |
| static char * | complete_context_add_ignorepat (const char *line, const char *word, int pos, int state) |
| static char * | complete_context_add_ignorepat_deprecated (const char *line, const char *word, int pos, int state) |
| static char * | complete_context_add_include (const char *line, const char *word, int pos, int state) |
| static char * | complete_context_add_include_deprecated (const char *line, const char *word, int pos, int state) |
| static char * | complete_context_dont_include_deprecated (const char *line, const char *word, int pos, int state) |
| static char * | complete_context_remove_extension (const char *line, const char *word, int pos, int state) |
| static char * | complete_context_remove_extension_deprecated (const char *line, const char *word, int pos, int state) |
| static char * | complete_context_remove_ignorepat (const char *line, const char *word, int pos, int state) |
| static char * | complete_context_remove_ignorepat_deprecated (const char *line, const char *word, int pos, int state) |
| static char * | complete_context_remove_include (const char *line, const char *word, int pos, int state) |
| static int | fix_complete_args (const char *line, char **word, int *pos) |
| static int | handle_context_add_extension (int fd, int argc, char *argv[]) |
| static int | handle_context_add_extension_deprecated (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_ignorepat_deprecated (int fd, int argc, char *argv[]) |
| static int | handle_context_add_include (int fd, int argc, char *argv[]) |
| static int | handle_context_add_include_deprecated (int fd, int argc, char *argv[]) |
| static int | handle_context_dont_include_deprecated (int fd, int argc, char *argv[]) |
| static int | handle_context_remove_extension (int fd, int argc, char *argv[]) |
| static int | handle_context_remove_extension_deprecated (int fd, int argc, char *argv[]) |
| static int | handle_context_remove_ignorepat (int fd, int argc, char *argv[]) |
| static int | handle_context_remove_ignorepat_deprecated (int fd, int argc, char *argv[]) |
| static int | handle_context_remove_include (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 ... | |
| static int | load_module (void) |
| static int | lookup_c_ip (struct ast_context *c, const char *name) |
| return true if 'name' is in the ignorepats for context c | |
| static int | lookup_ci (struct ast_context *c, const char *name) |
| return true if 'name' is included by context c | |
| static int | partial_match (const char *s, const char *word, int len) |
| match the first 'len' chars of word. len==0 always succeeds | |
| static int | pbx_load_config (const char *config_file) |
| static int | pbx_load_module (void) |
| static void | pbx_load_users (void) |
| static int | reload (void) |
| static const char * | skip_words (const char *p, int n) |
| moves to the n-th word in the string, or empty string if none | |
| static int | split_ec (const char *src, char **ext, char **const ctx, char **const cid) |
| split extension@context in two parts, return -1 on error. The return string is malloc'ed and pointed by *ext | |
| static int | unload_module (void) |
Variables | |
| static int | autofallthrough_config = 1 |
| static int | clearglobalvars_config = 0 |
| static struct ast_cli_entry | cli_add_extension_deprecated |
| static struct ast_cli_entry | cli_add_ignorepat_deprecated |
| static struct ast_cli_entry | cli_dialplan_save |
| static struct ast_cli_entry | cli_dont_include_deprecated |
| static struct ast_cli_entry | cli_extensions_reload_deprecated |
| static struct ast_cli_entry | cli_include_context_deprecated |
| static struct ast_cli_entry | cli_pbx_config [] |
| static struct ast_cli_entry | cli_remove_extension_deprecated |
| static struct ast_cli_entry | cli_remove_ignorepat_deprecated |
| static struct ast_cli_entry | cli_save_dialplan_deprecated |
| static char * | config = "extensions.conf" |
| static char | context_add_extension_help [] |
| static char | context_add_ignorepat_help [] |
| static char | context_add_include_help [] |
| static char | context_remove_extension_help [] |
| static char | context_remove_ignorepat_help [] |
| static char | context_remove_include_help [] |
| static struct ast_context * | local_contexts = NULL |
| static char * | registrar = "pbx_config" |
| static char | reload_extensions_help [] |
| static char | save_dialplan_help [] |
| static int | static_config = 0 |
| static char | userscontext [AST_MAX_EXTENSION] = "default" |
| static int | write_protect_config = 1 |
Definition in file pbx_config.c.
| #define BROKEN_READLINE 1 |
Definition at line 623 of file pbx_config.c.
| #define PUT_CTX_HDR |
Referenced by handle_save_dialplan().
| static void append_interface | ( | char * | iface, | |
| int | maxlen, | |||
| char * | add | |||
| ) | [static] |
Definition at line 2397 of file pbx_config.c.
References len.
Referenced by pbx_load_users().
02398 { 02399 int len = strlen(iface); 02400 if (strlen(add) + len < maxlen - 2) { 02401 if (strlen(iface)) { 02402 iface[len] = '&'; 02403 strcpy(iface + len + 1, add); 02404 } else 02405 strcpy(iface, add); 02406 } 02407 }
| AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
| AST_MODFLAG_DEFAULT | , | |||
| "Text Extension Configuration" | , | |||
| . | load = load_module, |
|||
| . | unload = unload_module, |
|||
| . | reload = reload | |||
| ) |
| AST_MUTEX_DEFINE_STATIC | ( | save_dialplan_lock | ) |
| static char* complete_context_add_extension | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 1687 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), len, LOG_WARNING, partial_match(), and strdup.
01688 { 01689 int which = 0; 01690 01691 if (pos == 4) { /* complete 'into' word ... */ 01692 return (state == 0) ? strdup("into") : NULL; 01693 } else if (pos == 5) { /* complete context */ 01694 struct ast_context *c = NULL; 01695 int len = strlen(word); 01696 char *res = NULL; 01697 01698 /* try to lock contexts list ... */ 01699 if (ast_rdlock_contexts()) { 01700 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01701 return NULL; 01702 } 01703 01704 /* walk through all contexts */ 01705 while ( !res && (c = ast_walk_contexts(c)) ) 01706 if (partial_match(ast_get_context_name(c), word, len) && ++which > state) 01707 res = strdup(ast_get_context_name(c)); 01708 ast_unlock_contexts(); 01709 return res; 01710 } else if (pos == 6) { 01711 return state == 0 ? strdup("replace") : NULL; 01712 } 01713 return NULL; 01714 }
| static char* complete_context_add_extension_deprecated | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
dialplan add extension 6123,1,Dial,IAX/212.71.138.13/6123 into local
Definition at line 1658 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), len, LOG_WARNING, partial_match(), and strdup.
01659 { 01660 int which = 0; 01661 01662 if (pos == 3) { /* complete 'into' word ... */ 01663 return (state == 0) ? strdup("into") : NULL; 01664 } else if (pos == 4) { /* complete context */ 01665 struct ast_context *c = NULL; 01666 int len = strlen(word); 01667 char *res = NULL; 01668 01669 /* try to lock contexts list ... */ 01670 if (ast_rdlock_contexts()) { 01671 ast_log(LOG_WARNING, "Failed to lock contexts list\n"); 01672 return NULL; 01673 } 01674 01675 /* walk through all contexts */ 01676 while ( !res && (c = ast_walk_contexts(c)) ) 01677 if (partial_match(ast_get_context_name(c), word, len) && ++which > state) 01678 res = strdup(ast_get_context_name(c)); 01679 ast_unlock_contexts(); 01680 return res; 01681 } else if (pos == 5) { 01682 return state == 0 ? strdup("replace") : NULL; 01683 } 01684 return NULL; 01685 }
| static char* complete_context_add_ignorepat | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 1846 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), free, len, LOG_ERROR, lookup_c_ip(), partial_match(), s, skip_words(), strdup, and strsep().
01848 { 01849 if (pos == 4) 01850 return state == 0 ? strdup("into") : NULL; 01851 else if (pos == 5) { 01852 struct ast_context *c; 01853 int which = 0; 01854 char *dupline, *ignorepat = NULL; 01855 const char *s; 01856 char *ret = NULL; 01857 int len = strlen(word); 01858 01859 /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */ 01860 s = skip_words(line, 3); 01861 if (s == NULL) 01862 return NULL; 01863 dupline = strdup(s); 01864 if (!dupline) { 01865 ast_log(LOG_ERROR, "Malloc failure\n"); 01866 return NULL; 01867 } 01868 ignorepat = strsep(&dupline, " "); 01869 01870 if (ast_rdlock_contexts()) { 01871 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 01872 return NULL; 01873 } 01874 01875 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01876 int found = 0; 01877 01878 if (!partial_match(ast_get_context_name(c), word, len)) 01879 continue; /* not mine */ 01880 if (ignorepat) /* there must be one, right ? */ 01881 found = lookup_c_ip(c, ignorepat); 01882 if (!found && ++which > state) 01883 ret = strdup(ast_get_context_name(c)); 01884 } 01885 01886 if (ignorepat) 01887 free(ignorepat); 01888 ast_unlock_contexts(); 01889 return ret; 01890 } 01891 01892 return NULL; 01893 }
| static char* complete_context_add_ignorepat_deprecated | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 1797 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), free, len, LOG_ERROR, lookup_c_ip(), partial_match(), s, skip_words(), strdup, and strsep().
01799 { 01800 if (pos == 3) 01801 return state == 0 ? strdup("into") : NULL; 01802 else if (pos == 4) { 01803 struct ast_context *c; 01804 int which = 0; 01805 char *dupline, *ignorepat = NULL; 01806 const char *s; 01807 char *ret = NULL; 01808 int len = strlen(word); 01809 01810 /* XXX skip first two words 'add' 'ignorepat' */ 01811 s = skip_words(line, 2); 01812 if (s == NULL) 01813 return NULL; 01814 dupline = strdup(s); 01815 if (!dupline) { 01816 ast_log(LOG_ERROR, "Malloc failure\n"); 01817 return NULL; 01818 } 01819 ignorepat = strsep(&dupline, " "); 01820 01821 if (ast_rdlock_contexts()) { 01822 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 01823 return NULL; 01824 } 01825 01826 for (c = NULL; !ret && (c = ast_walk_contexts(c));) { 01827 int found = 0; 01828 01829 if (!partial_match(ast_get_context_name(c), word, len)) 01830 continue; /* not mine */ 01831 if (ignorepat) /* there must be one, right ? */ 01832 found = lookup_c_ip(c, ignorepat); 01833 if (!found && ++which > state) 01834 ret = strdup(ast_get_context_name(c)); 01835 } 01836 01837 if (ignorepat) 01838 free(ignorepat); 01839 ast_unlock_contexts(); 01840 return ret; 01841 } 01842 01843 return NULL; 01844 }
| static char* complete_context_add_include | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 1140 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), context, free, len, LOG_ERROR, lookup_ci(), partial_match(), s, skip_words(), strdup, and strsep().
01142 { 01143 struct ast_context *c; 01144 int which = 0; 01145 char *ret = NULL; 01146 int len = strlen(word); 01147 01148 if (pos == 3) { /* 'dialplan add include _X_' (context) ... */ 01149 if (ast_rdlock_contexts()) { 01150 ast_log(LOG_ERROR, "Failed to lock context list\n"); 01151 return NULL; 01152 } 01153 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) 01154 if (partial_match(ast_get_context_name(c), word, len) && ++which > state) 01155 ret = strdup(ast_get_context_name(c)); 01156 ast_unlock_contexts(); 01157 return ret; 01158 } else if (pos == 4) { /* dialplan add include CTX _X_ */ 01159 /* complete as 'into' if context exists or we are unable to check */ 01160 char *context, *dupline; 01161 struct ast_context *c; 01162 const char *s = skip_words(line, 3); /* should not fail */ 01163 01164 if (state != 0) /* only once */ 01165 return NULL; 01166 01167 /* parse context from line ... */ 01168 context = dupline = strdup(s); 01169 if (!context) { 01170 ast_log(LOG_ERROR, "Out of free memory\n"); 01171 return strdup("into"); 01172 } 01173 strsep(&dupline, " "); 01174 01175 /* check for context existence ... */ 01176 if (ast_rdlock_contexts()) { 01177 ast_log(LOG_ERROR, "Failed to lock context list\n"); 01178 /* our fault, we can't check, so complete 'into' ... */ 01179 ret = strdup("into"); 01180 } else { 01181 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) 01182 if (!strcmp(context, ast_get_context_name(c))) 01183 ret = strdup("into"); /* found */ 01184 ast_unlock_contexts(); 01185 } 01186 free(context); 01187 return ret; 01188 } else if (pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */ 01189 char *context, *dupline, *into; 01190 const char *s = skip_words(line, 3); /* should not fail */ 01191 context = dupline = strdup(s); 01192 if (!dupline) { 01193 ast_log(LOG_ERROR, "Out of free memory\n"); 01194 return NULL; 01195 } 01196 strsep(&dupline, " "); /* skip context */ 01197 into = strsep(&dupline, " "); 01198 /* error if missing context or fifth word is not 'into' */ 01199 if (!strlen(context) || strcmp(into, "into")) { 01200 ast_log(LOG_ERROR, "bad context %s or missing into %s\n", 01201 context, into); 01202 goto error3; 01203 } 01204 01205 if (ast_rdlock_contexts()) { 01206 ast_log(LOG_ERROR, "Failed to lock context list\n"); 01207 goto error3; 01208 } 01209 01210 for (c = NULL; (c = ast_walk_contexts(c)); ) 01211 if (!strcmp(context, ast_get_context_name(c))) 01212 break; 01213 if (c) { /* first context exists, go on... */ 01214 /* go through all contexts ... */ 01215 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 01216 if (!strcmp(context, ast_get_context_name(c))) 01217 continue; /* skip ourselves */ 01218 if (partial_match(ast_get_context_name(c), word, len) && 01219 !lookup_ci(c, context) /* not included yet */ && 01220 ++which > state) 01221 ret = strdup(ast_get_context_name(c)); 01222 } 01223 } else { 01224 ast_log(LOG_ERROR, "context %s not found\n", context); 01225 } 01226 ast_unlock_contexts(); 01227 error3: 01228 free(context); 01229 return ret; 01230 } 01231 01232 return NULL; 01233 }
| static char* complete_context_add_include_deprecated | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 1045 of file pbx_config.c.
References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), context, free, len, LOG_ERROR, lookup_ci(), partial_match(), s, skip_words(), strdup, and strsep().
01047 { 01048 struct ast_context *c; 01049 int which = 0; 01050 char *ret = NULL; 01051 int len = strlen(word); 01052 01053 if (pos == 2) { /* 'include context _X_' (context) ... */ 01054 if (ast_rdlock_contexts()) { 01055 ast_log(LOG_ERROR, "Failed to lock context list\n"); 01056 return NULL; 01057 } 01058 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) 01059 if (partial_match(ast_get_context_name(c), word, len) && ++which > state) 01060 ret = strdup(ast_get_context_name(c)); 01061 ast_unlock_contexts(); 01062 return ret; 01063 } else if (pos == 3) { /* include context CTX _X_ */ 01064 /* complete as 'in' if context exists or we are unable to check */ 01065 char *context, *dupline; 01066 struct ast_context *c; 01067 const char *s = skip_words(line, 2); /* should not fail */ 01068 01069 if (state != 0) /* only once */ 01070 return NULL; 01071 01072 /* parse context from line ... */ 01073 context = dupline = strdup(s); 01074 if (!context) { 01075 ast_log(LOG_ERROR, "Out of free memory\n"); 01076 return strdup("in"); 01077 } 01078 strsep(&dupline, " "); 01079 01080 /* check for context existence ... */ 01081 if (ast_rdlock_contexts()) { 01082 ast_log(LOG_ERROR, "Failed to lock context list\n"); 01083 /* our fault, we can't check, so complete 'in' ... */ 01084 ret = strdup("in"); 01085 } else { 01086 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) 01087 if (!strcmp(context, ast_get_context_name(c))) 01088 ret = strdup("in"); /* found */ 01089 ast_unlock_contexts(); 01090 } 01091 free(context); 01092 return ret; 01093 } else if (pos == 4) { /* 'include context CTX in _X_' (dst context) */ 01094 char *context, *dupline, *in; 01095 const char *s = skip_words(line, 2); /* should not fail */ 01096 context = dupline = strdup(s); 01097 if (!dupline) { 01098 ast_log(LOG_ERROR, "Out of free memory\n"); 01099 return NULL; 01100 } 01101 strsep(&dupline, " "); /* skip context */ 01102 in = strsep(&dupline, " "); 01103 /* error if missing context or third word is not 'in' */ 01104 if (!strlen(context) || strcmp(in, "in")) { 01105 ast_log(LOG_ERROR, "bad context %s or missing in %s\n", 01106 context, in); 01107 goto error3; 01108 } 01109 01110 if (ast_rdlock_contexts()) { 01111 ast_log(LOG_ERROR, "Failed to lock context list\n"); 01112 goto error3; 01113 } 01114 01115 for (c = NULL; (c = ast_walk_contexts(c)); ) 01116 if (!strcmp(context, ast_get_context_name(c))) 01117 break; 01118 if (c) { /* first context exists, go on... */ 01119 /* go through all contexts ... */ 01120 for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) { 01121 if (!strcmp(context, ast_get_context_name(c))) 01122 continue; /* skip ourselves */ 01123 if (partial_match(ast_get_context_name(c), word, len) && 01124 !lookup_ci(c, context) /* not included yet */ && 01125 ++which > state) 01126 ret = strdup(ast_get_context_name(c)); 01127 } 01128 } else { 01129 ast_log(LOG_ERROR, "context %s not found\n", context); 01130 } 01131 ast_unlock_contexts(); 01132 error3: 01133 free(context); 01134 return ret; 01135 } 01136 01137 return NULL; 01138 }
| static char* complete_context_dont_include_deprecated | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 240 of file pbx_config.c.
References ast_get_context_name(), ast_get_include_name(), ast_lock_context(), ast_log(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_includes(), ast_walk_contexts(), ast_wrlock_contexts(), context, free, len, LOG_ERROR, LOG_WARNING, lookup_ci(), partial_match(), s, skip_words(), strdup, and strsep().
00242 { 00243 int which = 0; 00244 char *res = NULL; 00245 int len = strlen(word); /* how many bytes to match */ 00246 struct ast_context *c = NULL; 00247 00248 if (pos == 2) { /* "dont include _X_" */ 00249 if (ast_wrlock_contexts()) { 00250 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00251 return NULL; 00252 } 00253 /* walk contexts and their includes, return the n-th match */ 00254 while (!res && (c = ast_walk_contexts(c))) { 00255 struct ast_include *i = NULL; 00256 00257 if (ast_lock_context(c)) /* error ? skip this one */ 00258 continue; 00259 00260 while ( !res && (i = ast_walk_context_includes(c, i)) ) { 00261 const char *i_name = ast_get_include_name(i); 00262 struct ast_context *nc = NULL; 00263 int already_served = 0; 00264 00265 if (!partial_match(i_name, word, len)) 00266 continue; /* not matched */ 00267 00268 /* check if this include is already served or not */ 00269 00270 /* go through all contexts again till we reach actual 00271 * context or already_served = 1 00272 */ 00273 while ( (nc = ast_walk_contexts(nc)) && nc != c && !already_served) 00274 already_served = lookup_ci(nc, i_name); 00275 00276 if (!already_served && ++which > state) 00277 res = strdup(i_name); 00278 } 00279 ast_unlock_context(c); 00280 } 00281 00282 ast_unlock_contexts(); 00283 return res; 00284 } else if (pos == 3) { /* "dont include CTX _X_" */ 00285 /* 00286 * complete as 'in', but only if previous context is really 00287 * included somewhere 00288 */ 00289 char *context, *dupline; 00290 const char *s = skip_words(line, 2); /* skip 'dont' 'include' */ 00291 00292 if (state > 0) 00293 return NULL; 00294 context = dupline = strdup(s); 00295 if (!dupline) { 00296 ast_log(LOG_ERROR, "Out of free memory\n"); 00297 return NULL; 00298 } 00299 strsep(&dupline, " "); 00300 00301 if (ast_rdlock_contexts()) { 00302 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 00303 free(context); 00304 return NULL; 00305 } 00306 00307 /* go through all contexts and check if is included ... */ 00308 while (!res && (c = ast_walk_contexts(c))) 00309 if (lookup_ci(c, context)) /* context is really included, complete "in" command */ 00310 res = strdup("in"); 00311 ast_unlock_contexts(); 00312 if (!res) 00313 ast_log(LOG_WARNING, "%s not included anywhere\n", context); 00314 free(context); 00315 return res; 00316 } else if (pos == 4) { /* "dont include CTX in _X_" */ 00317 /* 00318 * Context from which we removing include ... 00319 */ 00320 char *context, *dupline, *in; 00321 const char *s = skip_words(line, 2); /* skip 'dont' 'include' */ 00322 context = dupline = strdup(s); 00323 if (!dupline) { 00324 ast_log(LOG_ERROR, "Out of free memory\n"); 00325 return NULL; 00326 } 00327 00328 strsep(&dupline, " "); /* skip context */ 00329 00330 /* third word must be 'in' */ 00331 in = strsep(&dupline, " "); 00332 if (!in || strcmp(in, "in")) { 00333 free(context); 00334 return NULL; 00335 } 00336 00337 if (ast_rdlock_contexts()) { 00338 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00339 free(context); 00340 return NULL; 00341 } 00342 00343 /* walk through all contexts ... */ 00344 c = NULL; 00345 while ( !res && (c = ast_walk_contexts(c))) { 00346 const char *c_name = ast_get_context_name(c); 00347 if (!partial_match(c_name, word, len)) /* not a good target */ 00348 continue; 00349 /* walk through all includes and check if it is our context */ 00350 if (lookup_ci(c, context) && ++which > state) 00351 res = strdup(c_name); 00352 } 00353 ast_unlock_contexts(); 00354 free(context); 00355 return res; 00356 } 00357 00358 return NULL; 00359 }
| static char* complete_context_remove_extension | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 809 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, exten, fix_complete_args(), free, len, LOG_ERROR, partial_match(), ast_exten::priority, s, skip_words(), split_ec(), and strdup.
00811 { 00812 char *ret = NULL; 00813 int which = 0; 00814 00815 #ifdef BROKEN_READLINE 00816 char *word2; 00817 /* 00818 * Fix arguments, *word is a new allocated structure, REMEMBER to 00819 * free *word when you want to return from this function ... 00820 */ 00821 if (fix_complete_args(line, &word2, &pos)) { 00822 ast_log(LOG_ERROR, "Out of free memory\n"); 00823 return NULL; 00824 } 00825 word = word2; 00826 #endif 00827 00828 if (pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */ 00829 struct ast_context *c = NULL; 00830 char *context = NULL, *exten = NULL, *cid = NULL; 00831 int le = 0; /* length of extension */ 00832 int lc = 0; /* length of context */ 00833 int lcid = 0; /* length of cid */ 00834 00835 lc = split_ec(word, &exten, &context, &cid); 00836 if (lc) { /* error */ 00837 #ifdef BROKEN_READLINE 00838 free(word2); 00839 #endif 00840 return NULL; 00841 } 00842 le = strlen(exten); 00843 lc = strlen(context); 00844 lcid = cid ? strlen(cid) : -1; 00845 00846 if (ast_rdlock_contexts()) { 00847 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00848 goto error2; 00849 } 00850 00851 /* find our context ... */ 00852 while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */ 00853 struct ast_exten *e = NULL; 00854 /* XXX locking ? */ 00855 if (!partial_match(ast_get_context_name(c), context, lc)) 00856 continue; /* context not matched */ 00857 while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */ 00858 if ( !strchr(word, '/') || 00859 (!strchr(word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) || 00860 (strchr(word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) { 00861 if ( ((strchr(word, '/') || strchr(word, '@')) && !strcmp(ast_get_extension_name(e), exten)) || 00862 (!strchr(word, '/') && !strchr(word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */ 00863 if (++which > state) { 00864 /* If there is an extension then return exten@context. */ 00865 if (ast_get_extension_matchcid(e) && (!strchr(word, '@') || strchr(word, '/'))) { 00866 asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)); 00867 break; 00868 } else if (!ast_get_extension_matchcid(e) && !strchr(word, '/')) { 00869 asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)); 00870 break; 00871 } 00872 } 00873 } 00874 } 00875 } 00876 if (e) /* got a match */ 00877 break; 00878 } 00879 #ifdef BROKEN_READLINE 00880 free(word2); 00881 #endif 00882 00883 ast_unlock_contexts(); 00884 error2: 00885 if (exten) 00886 free(exten); 00887 } else if (pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */ 00888 char *exten = NULL, *context, *cid, *p; 00889 struct ast_context *c; 00890 int le, lc, lcid, len; 00891 const char *s = skip_words(line, 3); /* skip 'dialplan' 'remove' 'extension' */ 00892 int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */ 00893 00894 if (i) /* error */ 00895 goto error3; 00896 if ( (p = strchr(exten, ' ')) ) /* remove space after extension */ 00897 *p = '\0'; 00898 if ( (p = strchr(context, ' ')) ) /* remove space after context */ 00899 *p = '\0'; 00900 le = strlen(exten); 00901 lc = strlen(context); 00902 lcid = cid ? strlen(cid) : -1; 00903 len = strlen(word); 00904 if (le == 0 || lc == 0) 00905 goto error3; 00906 00907 if (ast_rdlock_contexts()) { 00908 ast_log(LOG_ERROR, "Failed to lock context list\n"); 00909 goto error3; 00910 } 00911 00912 /* walk contexts */ 00913 c = NULL; 00914 while ( (c = ast_walk_contexts(c)) ) { 00915 /* XXX locking on c ? */ 00916 struct ast_exten *e; 00917 if (strcmp(ast_get_context_name(c), context) != 0) 00918 continue; 00919 /* got it, we must match here */ 00920 e = NULL; 00921 while ( (e = ast_walk_context_extensions(c, e)) ) { 00922 struct ast_exten *priority; 00923 char buffer[10]; 00924 00925 if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) { 00926 continue; 00927 } 00928 if (strcmp(ast_get_extension_name(e), exten) != 0) 00929 continue; 00930 /* XXX lock e ? */ 00931 priority = NULL; 00932 while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) { 00933 snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority)); 00934 if (partial_match(buffer, word, len) && ++which > state) /* n-th match */ 00935 ret = strdup(buffer); 00936 } 00937 break; 00938 } 00939 break; 00940 } 00941 ast_unlock_contexts(); 00942 error3: 00943 if (exten) 00944 free(exten); 00945 #ifdef BROKEN_READLINE 00946 free(word2); 00947 #endif 00948 } 00949 return ret; 00950 }
| static char* complete_context_remove_extension_deprecated | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 670 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, exten, fix_complete_args(), free, len, LOG_ERROR, partial_match(), ast_exten::priority, s, skip_words(), split_ec(), and strdup.
00672 { 00673 char *ret = NULL; 00674 int which = 0; 00675 00676 #ifdef BROKEN_READLINE 00677 char *word2; 00678 /* 00679 * Fix arguments, *word is a new allocated structure, REMEMBER to 00680 * free *word when you want to return from this function ... 00681 */ 00682 if (fix_complete_args(line, &word2, &pos)) { 00683 ast_log(LOG_ERROR, "Out of free memory\n"); 00684 return NULL; 00685 } 00686 word = word2; 00687 #endif 00688 00689 if (pos == 2) { /* 'remove extension _X_' (exten/cid@context ... */ 00690 struct ast_context *c = NULL; 00691 char *context = NULL, *exten = NULL, *cid = NULL; 00692 int le = 0; /* length of extension */ 00693 int lc = 0; /* length of context */ 00694 int lcid = 0; /* length of cid */ 00695 00696 lc = split_ec(word, &exten, &context, &cid); 00697