Sat Nov 1 06:29:13 2008

Asterisk developer's documentation


pbx_config.c File Reference

Populate and remember extensions from static config file. More...

#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_contextlocal_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


Detailed Description

Populate and remember extensions from static config file.

Definition in file pbx_config.c.


Define Documentation

#define BROKEN_READLINE   1

Definition at line 623 of file pbx_config.c.

#define PUT_CTX_HDR

Referenced by handle_save_dialplan().


Function Documentation

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