Thu May 14 15:13:38 2009

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"

Go to the source code of this file.

Defines

#define BROKEN_READLINE   1
#define PUT_CTX_HDR

Functions

static void __reg_module (void)
static void __unreg_module (void)
static void append_interface (char *iface, int maxlen, char *add)
static char * complete_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 struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Text Extension Configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, }
static const struct ast_module_infoast_module_info = &__mod_info
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 ast_mutex_t save_dialplan_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
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 __reg_module ( void   )  [static]

Definition at line 2571 of file pbx_config.c.

static void __unreg_module ( void   )  [static]

Definition at line 2571 of file pbx_config.c.

static void append_interface ( char *  iface,
int  maxlen,
char *  add 
) [static]

Definition at line 2413 of file pbx_config.c.

References len().

Referenced by pbx_load_users().

02414 {
02415    int len = strlen(iface);
02416    if (strlen(add) + len < maxlen - 2) {
02417       if (strlen(iface)) {
02418          iface[len] = '&';
02419          strcpy(iface + len + 1, add);
02420       } else
02421          strcpy(iface, add);
02422    }
02423 }

static char* complete_context_add_extension ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 1699 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.

01700 {
01701    int which = 0;
01702 
01703    if (pos == 4) {      /* complete 'into' word ... */
01704       return (state == 0) ? strdup("into") : NULL;
01705    } else if (pos == 5) { /* complete context */
01706       struct ast_context *c = NULL;
01707       int len = strlen(word);
01708       char *res = NULL;
01709 
01710       /* try to lock contexts list ... */
01711       if (ast_rdlock_contexts()) {
01712          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01713          return NULL;
01714       }
01715 
01716       /* walk through all contexts */
01717       while ( !res && (c = ast_walk_contexts(c)) )
01718          if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
01719             res = strdup(ast_get_context_name(c));
01720       ast_unlock_contexts();
01721       return res;
01722    } else if (pos == 6) {
01723       return state == 0 ? strdup("replace") : NULL;
01724    }
01725    return NULL;
01726 }

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 1670 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.

01671 {
01672    int which = 0;
01673 
01674    if (pos == 3) {      /* complete 'into' word ... */
01675       return (state == 0) ? strdup("into") : NULL;
01676    } else if (pos == 4) { /* complete context */
01677       struct ast_context *c = NULL;
01678       int len = strlen(word);
01679       char *res = NULL;
01680 
01681       /* try to lock contexts list ... */
01682       if (ast_rdlock_contexts()) {
01683          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01684          return NULL;
01685       }
01686 
01687       /* walk through all contexts */
01688       while ( !res && (c = ast_walk_contexts(c)) )
01689          if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
01690             res = strdup(ast_get_context_name(c));
01691       ast_unlock_contexts();
01692       return res;
01693    } else if (pos == 5) {
01694       return state == 0 ? strdup("replace") : NULL;
01695    }
01696    return NULL;
01697 }

static char* complete_context_add_ignorepat ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 1858 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(), and strdup.

01860 {
01861    if (pos == 4)
01862       return state == 0 ? strdup("into") : NULL;
01863    else if (pos == 5) {
01864       struct ast_context *c;
01865       int which = 0;
01866       char *dupline, *ignorepat = NULL;
01867       const char *s;
01868       char *ret = NULL;
01869       int len = strlen(word);
01870 
01871       /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */
01872       s = skip_words(line, 3);
01873       if (s == NULL)
01874          return NULL;
01875       dupline = strdup(s);
01876       if (!dupline) {
01877          ast_log(LOG_ERROR, "Malloc failure\n");
01878          return NULL;
01879       }
01880       ignorepat = strsep(&dupline, " ");
01881 
01882       if (ast_rdlock_contexts()) {
01883          ast_log(LOG_ERROR, "Failed to lock contexts list\n");
01884          return NULL;
01885       }
01886 
01887       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01888          int found = 0;
01889 
01890          if (!partial_match(ast_get_context_name(c), word, len))
01891             continue; /* not mine */
01892          if (ignorepat) /* there must be one, right ? */
01893             found = lookup_c_ip(c, ignorepat);
01894          if (!found && ++which > state)
01895             ret = strdup(ast_get_context_name(c));
01896       }
01897 
01898       if (ignorepat)
01899          free(ignorepat);
01900       ast_unlock_contexts();
01901       return ret;
01902    }
01903 
01904    return NULL;
01905 }

static char* complete_context_add_ignorepat_deprecated ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 1809 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(), and strdup.

01811 {
01812    if (pos == 3)
01813       return state == 0 ? strdup("into") : NULL;
01814    else if (pos == 4) {
01815       struct ast_context *c;
01816       int which = 0;
01817       char *dupline, *ignorepat = NULL;
01818       const char *s;
01819       char *ret = NULL;
01820       int len = strlen(word);
01821 
01822       /* XXX skip first two words 'add' 'ignorepat' */
01823       s = skip_words(line, 2);
01824       if (s == NULL)
01825          return NULL;
01826       dupline = strdup(s);
01827       if (!dupline) {
01828          ast_log(LOG_ERROR, "Malloc failure\n");
01829          return NULL;
01830       }
01831       ignorepat = strsep(&dupline, " ");
01832 
01833       if (ast_rdlock_contexts()) {
01834          ast_log(LOG_ERROR, "Failed to lock contexts list\n");
01835          return NULL;
01836       }
01837 
01838       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01839          int found = 0;
01840 
01841          if (!partial_match(ast_get_context_name(c), word, len))
01842             continue; /* not mine */
01843          if (ignorepat) /* there must be one, right ? */
01844             found = lookup_c_ip(c, ignorepat);
01845          if (!found && ++which > state)
01846             ret = strdup(ast_get_context_name(c));
01847       }
01848 
01849       if (ignorepat)
01850          free(ignorepat);
01851       ast_unlock_contexts();
01852       return ret;
01853    }
01854 
01855    return NULL;
01856 }

static char* complete_context_add_include ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 1152 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(), and strdup.

01154 {
01155    struct ast_context *c;
01156    int which = 0;
01157    char *ret = NULL;
01158    int len = strlen(word);
01159 
01160    if (pos == 3) {      /* 'dialplan add include _X_' (context) ... */
01161       if (ast_rdlock_contexts()) {
01162          ast_log(LOG_ERROR, "Failed to lock context list\n");
01163          return NULL;
01164       }
01165       for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
01166          if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
01167             ret = strdup(ast_get_context_name(c));
01168       ast_unlock_contexts();
01169       return ret;
01170    } else if (pos == 4) { /* dialplan add include CTX _X_ */
01171       /* complete  as 'into' if context exists or we are unable to check */
01172       char *context, *dupline;
01173       struct ast_context *c;
01174       const char *s = skip_words(line, 3); /* should not fail */
01175 
01176       if (state != 0)   /* only once */
01177          return NULL;
01178 
01179       /* parse context from line ... */
01180       context = dupline = strdup(s);
01181       if (!context) {
01182          ast_log(LOG_ERROR, "Out of free memory\n");
01183          return strdup("into");
01184       }
01185       strsep(&dupline, " ");
01186 
01187       /* check for context existence ... */
01188       if (ast_rdlock_contexts()) {
01189          ast_log(LOG_ERROR, "Failed to lock context list\n");
01190          /* our fault, we can't check, so complete 'into' ... */
01191          ret = strdup("into");
01192       } else {
01193          for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
01194             if (!strcmp(context, ast_get_context_name(c)))
01195                ret = strdup("into"); /* found */
01196          ast_unlock_contexts();
01197       }
01198       free(context);
01199       return ret;
01200    } else if (pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */
01201       char *context, *dupline, *into;
01202       const char *s = skip_words(line, 3); /* should not fail */
01203       context = dupline = strdup(s);
01204       if (!dupline) {
01205          ast_log(LOG_ERROR, "Out of free memory\n");
01206          return NULL;
01207       }
01208       strsep(&dupline, " "); /* skip context */
01209       into = strsep(&dupline, " ");
01210       /* error if missing context or fifth word is not 'into' */
01211       if (!strlen(context) || strcmp(into, "into")) {
01212          ast_log(LOG_ERROR, "bad context %s or missing into %s\n",
01213             context, into);
01214          goto error3;
01215       }
01216 
01217       if (ast_rdlock_contexts()) {
01218          ast_log(LOG_ERROR, "Failed to lock context list\n");
01219          goto error3;
01220       }
01221 
01222       for (c = NULL; (c = ast_walk_contexts(c)); )
01223          if (!strcmp(context, ast_get_context_name(c)))
01224             break;
01225       if (c) { /* first context exists, go on... */
01226          /* go through all contexts ... */
01227          for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
01228             if (!strcmp(context, ast_get_context_name(c)))
01229                continue; /* skip ourselves */
01230             if (partial_match(ast_get_context_name(c), word, len) &&
01231                   !lookup_ci(c, context) /* not included yet */ &&
01232                   ++which > state)
01233                ret = strdup(ast_get_context_name(c));
01234          }
01235       } else {
01236          ast_log(LOG_ERROR, "context %s not found\n", context);
01237       }
01238       ast_unlock_contexts();
01239    error3:
01240       free(context);
01241       return ret;
01242    }
01243 
01244    return NULL;
01245 }

static char* complete_context_add_include_deprecated ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 1057 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(), and strdup.

01059 {
01060    struct ast_context *c;
01061    int which = 0;
01062    char *ret = NULL;
01063    int len = strlen(word);
01064 
01065    if (pos == 2) {      /* 'include context _X_' (context) ... */
01066       if (ast_rdlock_contexts()) {
01067          ast_log(LOG_ERROR, "Failed to lock context list\n");
01068          return NULL;
01069       }
01070       for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
01071          if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
01072             ret = strdup(ast_get_context_name(c));
01073       ast_unlock_contexts();
01074       return ret;
01075    } else if (pos == 3) { /* include context CTX _X_ */
01076       /* complete  as 'in' if context exists or we are unable to check */
01077       char *context, *dupline;
01078       struct ast_context *c;
01079       const char *s = skip_words(line, 2);   /* should not fail */
01080 
01081       if (state != 0)   /* only once */
01082          return NULL;
01083 
01084       /* parse context from line ... */
01085       context = dupline = strdup(s);
01086       if (!context) {
01087          ast_log(LOG_ERROR, "Out of free memory\n");
01088          return strdup("in");
01089       }
01090       strsep(&dupline, " ");
01091 
01092       /* check for context existence ... */
01093       if (ast_rdlock_contexts()) {
01094          ast_log(LOG_ERROR, "Failed to lock context list\n");
01095          /* our fault, we can't check, so complete 'in' ... */
01096          ret = strdup("in");
01097       } else {
01098          for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
01099             if (!strcmp(context, ast_get_context_name(c)))
01100                ret = strdup("in"); /* found */
01101          ast_unlock_contexts();
01102       }
01103       free(context);
01104       return ret;
01105    } else if (pos == 4) { /* 'include context CTX in _X_' (dst context) */
01106       char *context, *dupline, *in;
01107       const char *s = skip_words(line, 2); /* should not fail */
01108       context = dupline = strdup(s);
01109       if (!dupline) {
01110          ast_log(LOG_ERROR, "Out of free memory\n");
01111          return NULL;
01112       }
01113       strsep(&dupline, " "); /* skip context */
01114       in = strsep(&dupline, " ");
01115       /* error if missing context or third word is not 'in' */
01116       if (!strlen(context) || strcmp(in, "in")) {
01117          ast_log(LOG_ERROR, "bad context %s or missing in %s\n",
01118             context, in);
01119          goto error3;
01120       }
01121 
01122       if (ast_rdlock_contexts()) {
01123          ast_log(LOG_ERROR, "Failed to lock context list\n");
01124          goto error3;
01125       }
01126 
01127       for (c = NULL; (c = ast_walk_contexts(c)); )
01128          if (!strcmp(context, ast_get_context_name(c)))
01129             break;
01130       if (c) { /* first context exists, go on... */
01131          /* go through all contexts ... */
01132          for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
01133             if (!strcmp(context, ast_get_context_name(c)))
01134                continue; /* skip ourselves */
01135             if (partial_match(ast_get_context_name(c), word, len) &&
01136                   !lookup_ci(c, context) /* not included yet */ &&
01137                   ++which > state)
01138                ret = strdup(ast_get_context_name(c));
01139          }
01140       } else {
01141          ast_log(LOG_ERROR, "context %s not found\n", context);
01142       }
01143       ast_unlock_contexts();
01144    error3:
01145       free(context);
01146       return ret;
01147    }
01148 
01149    return NULL;
01150 }

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(), and strdup.

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 815 of file pbx_config.c.

References asprintf, ast_get_context_name(), ast_get_extension_cidmatch(), ast_get_extension_matchcid(), ast_get_extension_name(), ast_get_extension_priority(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), context, errno, exten, fix_complete_args(), free, len(), LOG_ERROR, LOG_WARNING, partial_match(), ast_exten::priority, s, skip_words(), split_ec(), and strdup.

00817 {
00818    char *ret = NULL;
00819    int which = 0;
00820 
00821 #ifdef BROKEN_READLINE
00822    char *word2;
00823    /*
00824     * Fix arguments, *word is a new allocated structure, REMEMBER to
00825     * free *word when you want to return from this function ...
00826     */
00827    if (fix_complete_args(line, &word2, &pos)) {
00828       ast_log(LOG_ERROR, "Out of free memory\n");
00829       return NULL;
00830    }
00831    word = word2;
00832 #endif
00833 
00834    if (pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */
00835       struct ast_context *c = NULL;
00836       char *context = NULL, *exten = NULL, *cid = NULL;
00837       int le = 0; /* length of extension */
00838       int lc = 0; /* length of context */
00839       int lcid = 0; /* length of cid */
00840 
00841       lc = split_ec(word, &exten, &context, &cid);
00842       if (lc)  { /* error */
00843 #ifdef BROKEN_READLINE
00844          free(word2);
00845 #endif
00846          return NULL;
00847       }
00848       le = strlen(exten);
00849       lc = strlen(context);
00850       lcid = cid ? strlen(cid) : -1;
00851 
00852       if (ast_rdlock_contexts()) {
00853          ast_log(LOG_ERROR, "Failed to lock context list\n");
00854          goto error2;
00855       }
00856 
00857       /* find our context ... */
00858       while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */
00859          struct ast_exten *e = NULL;
00860          /* XXX locking ? */
00861          if (!partial_match(ast_get_context_name(c), context, lc))
00862             continue;   /* context not matched */
00863          while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */
00864             if ( !strchr(word, '/') ||
00865                   (!strchr(word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) ||
00866                   (strchr(word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) {
00867                if ( ((strchr(word, '/') || strchr(word, '@')) && !strcmp(ast_get_extension_name(e), exten)) ||
00868                    (!strchr(word, '/') && !strchr(word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */
00869                   if (++which > state) {
00870                      /* If there is an extension then return exten@context. */
00871                      if (ast_get_extension_matchcid(e) && (!strchr(word, '@') || strchr(word, '/'))) {
00872                         if (asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)) < 0) {
00873                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00874                            ret = NULL;
00875                         }
00876                         break;
00877                      } else if (!ast_get_extension_matchcid(e) && !strchr(word, '/')) {
00878                         if (asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) {
00879                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00880                            ret = NULL;
00881                         }
00882                         break;
00883                      }
00884                   }
00885                }
00886             }
00887          }
00888          if (e)   /* got a match */
00889             break;
00890       }
00891 #ifdef BROKEN_READLINE
00892       free(word2);
00893 #endif
00894 
00895       ast_unlock_contexts();
00896    error2:
00897       if (exten)
00898          free(exten);
00899    } else if (pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */
00900       char *exten = NULL, *context, *cid, *p;
00901       struct ast_context *c;
00902       int le, lc, lcid, len;
00903       const char *s = skip_words(line, 3); /* skip 'dialplan' 'remove' 'extension' */
00904       int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */
00905 
00906       if (i)   /* error */
00907          goto error3;
00908       if ( (p = strchr(exten, ' ')) ) /* remove space after extension */
00909          *p = '\0';
00910       if ( (p = strchr(context, ' ')) ) /* remove space after context */
00911          *p = '\0';
00912       le = strlen(exten);
00913       lc = strlen(context);
00914       lcid = cid ? strlen(cid) : -1;
00915       len = strlen(word);
00916       if (le == 0 || lc == 0)
00917          goto error3;
00918 
00919       if (ast_rdlock_contexts()) {
00920          ast_log(LOG_ERROR, "Failed to lock context list\n");
00921          goto error3;
00922       }
00923 
00924       /* walk contexts */
00925       c = NULL;
00926       while ( (c = ast_walk_contexts(c)) ) {
00927          /* XXX locking on c ? */
00928          struct ast_exten *e;
00929          if (strcmp(ast_get_context_name(c), context) != 0)
00930             continue;
00931          /* got it, we must match here */
00932          e = NULL;
00933          while ( (e = ast_walk_context_extensions(c, e)) ) {
00934             struct ast_exten *priority;
00935             char buffer[10];
00936 
00937             if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) {
00938                continue;
00939             }
00940             if (strcmp(ast_get_extension_name(e), exten) != 0)
00941                continue;
00942             /* XXX lock e ? */
00943             priority = NULL;
00944             while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) {
00945                snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority));
00946                if (partial_match(buffer, word, len) && ++which > state) /* n-th match */
00947                   ret = strdup(buffer);
00948             }
00949             break;
00950          }
00951          break;
00952       }
00953       ast_unlock_contexts();
00954    error3:
00955       if (exten)
00956          free(exten);
00957 #ifdef BROKEN_READLINE
00958       free(word2);
00959 #endif
00960    }
00961    return ret; 
00962 }

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, errno, exten, fix_complete_args(), free, len(), LOG_ERROR, LOG_WARNING, 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 #ifdef BROKEN_READLINE
00698       free(word2);
00699 #endif
00700       if (lc)  /* error */
00701          return NULL;
00702       le = strlen(exten);
00703       lc = strlen(context);
00704       lcid = cid ? strlen(cid) : -1;
00705 
00706       if (ast_rdlock_contexts()) {
00707          ast_log(LOG_ERROR, "Failed to lock context list\n");
00708          goto error2;
00709       }
00710 
00711       /* find our context ... */
00712       while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */
00713          struct ast_exten *e = NULL;
00714          /* XXX locking ? */
00715          if (!partial_match(ast_get_context_name(c), context, lc))
00716             continue;   /* context not matched */
00717          while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */
00718             if ( !strchr(word, '/') ||
00719                   (!strchr(word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) ||
00720                   (strchr(word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) {
00721                if ( ((strchr(word, '/') || strchr(word, '@')) && !strcmp(ast_get_extension_name(e), exten)) ||
00722                    (!strchr(word, '/') && !strchr(word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */
00723                   if (++which > state) {
00724                      /* If there is an extension then return exten@context. */
00725                      if (ast_get_extension_matchcid(e) && (!strchr(word, '@') || strchr(word, '/'))) {
00726                         if (asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)) < 0) {
00727                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00728                            ret = NULL;
00729                         }
00730                         break;
00731                      } else if (!ast_get_extension_matchcid(e) && !strchr(word, '/')) {
00732                         if (asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) {
00733                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00734                            ret = NULL;
00735                         }
00736                         break;
00737                      }
00738                   }
00739                }
00740             }
00741          }
00742          if (e)   /* got a match */
00743             break;
00744       }
00745 
00746       ast_unlock_contexts();
00747    error2:
00748       if (exten)
00749          free(exten);
00750    } else if (pos == 3) { /* 'remove extension EXT _X_' (priority) */
00751       char *exten = NULL, *context, *cid, *p;
00752       struct ast_context *c;
00753       int le, lc, lcid, len;
00754       const char *s = skip_words(line, 2); /* skip 'remove' 'extension' */
00755       int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */
00756 
00757       if (i)   /* error */
00758          goto error3;
00759       if ( (p = strchr(exten, ' ')) ) /* remove space after extension */
00760          *p = '\0';
00761       if ( (p = strchr(context, ' ')) ) /* remove space after context */
00762          *p = '\0';
00763       le = strlen(exten);
00764       lc = strlen(context);
00765       lcid = strlen(cid);
00766       len = strlen(word);
00767       if (le == 0 || lc == 0)
00768          goto error3;
00769 
00770       if (ast_rdlock_contexts()) {
00771          ast_log(LOG_ERROR, "Failed to lock context list\n");
00772          goto error3;
00773       }
00774 
00775       /* walk contexts */
00776       c = NULL;
00777       while ( (c = ast_walk_contexts(c)) ) {
00778          /* XXX locking on c ? */
00779          struct ast_exten *e;
00780          if (strcmp(ast_get_context_name(c), context) != 0)
00781             continue;
00782          /* got it, we must match here */
00783          e = NULL;
00784          while ( (e = ast_walk_context_extensions(c, e)) ) {
00785             struct ast_exten *priority;
00786             char buffer[10];
00787 
00788             if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) {
00789                continue;
00790             }
00791             if (strcmp(ast_get_extension_name(e), exten) != 0)
00792                continue;
00793             /* XXX lock e ? */
00794             priority = NULL;
00795             while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) {
00796                snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority));
00797                if (partial_match(buffer, word, len) && ++which > state) /* n-th match */
00798                   ret = strdup(buffer);
00799             }
00800             break;
00801          }
00802          break;
00803       }
00804       ast_unlock_contexts();
00805    error3:
00806       if (exten)
00807          free(exten);
00808    }
00809 #ifdef BROKEN_READLINE
00810    free(word2);
00811 #endif
00812    return ret; 
00813 }

static char* complete_context_remove_ignorepat ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 2057 of file pbx_config.c.

References ast_get_context_name(), ast_get_ignorepat_name(), ast_lock_context(), ast_log(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_ignorepats(), ast_walk_contexts(), free, len(), LOG_WARNING, lookup_c_ip(), partial_match(), and strdup.

02059 {
02060    struct ast_context *c;
02061    int which = 0;
02062    char *ret = NULL;
02063 
02064    if (pos == 3) {
02065       int len = strlen(word);
02066       if (ast_rdlock_contexts()) {
02067          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
02068          return NULL;
02069       }
02070 
02071       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
02072          struct ast_ignorepat *ip;
02073 
02074          if (ast_lock_context(c))   /* error, skip it */
02075             continue;
02076          
02077          for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) {
02078             if (partial_match(ast_get_ignorepat_name(ip), word, len) && ++which > state) {
02079                /* n-th match */
02080                struct ast_context *cw = NULL;
02081                int found = 0;
02082                while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) {
02083                   /* XXX do i stop on c, or skip it ? */
02084                   found = lookup_c_ip(cw, ast_get_ignorepat_name(ip));
02085                }
02086                if (!found)
02087                   ret = strdup(ast_get_ignorepat_name(ip));
02088             }
02089          }
02090          ast_unlock_context(c);
02091       }
02092       ast_unlock_contexts();
02093       return ret;
02094    } else if (pos == 4) {
02095        return state == 0 ? strdup("from") : NULL;
02096    } else if (pos == 5) { /* XXX check this */
02097       char *dupline, *duplinet, *ignorepat;
02098       int len = strlen(word);
02099 
02100       dupline = strdup(line);
02101       if (!dupline) {
02102          ast_log(LOG_WARNING, "Out of free memory\n");
02103          return NULL;
02104       }
02105 
02106       duplinet = dupline;
02107       strsep(&duplinet, " ");
02108       strsep(&duplinet, " ");
02109       ignorepat = strsep(&duplinet, " ");
02110 
02111       if (!ignorepat) {
02112          free(dupline);
02113          return NULL;
02114       }
02115 
02116       if (ast_rdlock_contexts()) {
02117          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
02118          free(dupline);
02119          return NULL;
02120       }
02121 
02122       for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
02123          if (ast_lock_context(c))   /* fail, skip it */
02124             continue;
02125          if (!partial_match(ast_get_context_name(c), word, len))
02126             continue;
02127          if (lookup_c_ip(c, ignorepat) && ++which > state)
02128             ret = strdup(ast_get_context_name(c));
02129          ast_unlock_context(c);
02130       }
02131       ast_unlock_contexts();
02132       free(dupline);
02133       return NULL;
02134    }
02135 
02136    return NULL;
02137 }

static char* complete_context_remove_ignorepat_deprecated ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 1975 of file pbx_config.c.

References ast_get_context_name(), ast_get_ignorepat_name(), ast_lock_context(), ast_log(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_ignorepats(), ast_walk_contexts(), free, len(), LOG_WARNING, lookup_c_ip(), partial_match(), and strdup.

01977 {
01978    struct ast_context *c;
01979    int which = 0;
01980    char *ret = NULL;
01981 
01982    if (pos == 2) {
01983       int len = strlen(word);
01984       if (ast_rdlock_contexts()) {
01985          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01986          return NULL;
01987       }
01988 
01989       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01990          struct ast_ignorepat *ip;
01991 
01992          if (ast_lock_context(c))   /* error, skip it */
01993             continue;
01994          
01995          for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) {
01996             if (partial_match(ast_get_ignorepat_name(ip), word, len) && ++which > state) {
01997                /* n-th match */
01998                struct ast_context *cw = NULL;
01999                int found = 0;
02000                while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) {
02001                   /* XXX do i stop on c, or skip it ? */
02002                   found = lookup_c_ip(cw, ast_get_ignorepat_name(ip));
02003                }
02004                if (!found)
02005                   ret = strdup(ast_get_ignorepat_name(ip));
02006             }
02007          }
02008          ast_unlock_context(c);
02009       }
02010       ast_unlock_contexts();
02011       return ret;
02012    } else if (pos == 3) {
02013        return state == 0 ? strdup("from") : NULL;
02014    } else if (pos == 4) { /* XXX check this */
02015       char *dupline, *duplinet, *ignorepat;
02016       int len = strlen(word);
02017 
02018       dupline = strdup(line);
02019       if (!dupline) {
02020          ast_log(LOG_WARNING, "Out of free memory\n");
02021          return NULL;
02022       }
02023 
02024       duplinet = dupline;
02025       strsep(&duplinet, " ");
02026       strsep(&duplinet, " ");
02027       ignorepat = strsep(&duplinet, " ");
02028 
02029       if (!ignorepat) {
02030          free(dupline);
02031          return NULL;
02032       }
02033 
02034       if (ast_rdlock_contexts()) {
02035          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
02036          free(dupline);
02037          return NULL;
02038       }
02039 
02040       for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
02041          if (ast_lock_context(c))   /* fail, skip it */
02042             continue;
02043          if (!partial_match(ast_get_context_name(c), word, len))
02044             continue;
02045          if (lookup_c_ip(c, ignorepat) && ++which > state)
02046             ret = strdup(ast_get_context_name(c));
02047          ast_unlock_context(c);
02048       }
02049       ast_unlock_contexts();
02050       free(dupline);
02051       return NULL;
02052    }
02053 
02054    return NULL;
02055 }

static char* complete_context_remove_include ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 361 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(), context, free, len(), LOG_ERROR, LOG_WARNING, lookup_ci(), partial_match(), s, skip_words(), and strdup.

00363 {
00364    int which = 0;
00365    char *res = NULL;
00366    int len = strlen(word); /* how many bytes to match */
00367    struct ast_context *c = NULL;
00368 
00369    if (pos == 3) {      /* "dialplan remove include _X_" */
00370       if (ast_rdlock_contexts()) {
00371          ast_log(LOG_ERROR, "Failed to lock context list\n");
00372          return NULL;
00373       }
00374       /* walk contexts and their includes, return the n-th match */
00375       while (!res && (c = ast_walk_contexts(c))) {
00376          struct ast_include *i = NULL;
00377 
00378          if (ast_lock_context(c))   /* error ? skip this one */
00379             continue;
00380 
00381          while ( !res && (i = ast_walk_context_includes(c, i)) ) {
00382             const char *i_name = ast_get_include_name(i);
00383             struct ast_context *nc = NULL;
00384             int already_served = 0;
00385 
00386             if (!partial_match(i_name, word, len))
00387                continue;   /* not matched */
00388 
00389             /* check if this include is already served or not */
00390 
00391             /* go through all contexts again till we reach actual
00392              * context or already_served = 1
00393              */
00394             while ( (nc = ast_walk_contexts(nc)) && nc != c && !already_served)
00395                already_served = lookup_ci(nc, i_name);
00396 
00397             if (!already_served && ++which > state)
00398                res = strdup(i_name);
00399          }
00400          ast_unlock_context(c);
00401       }
00402 
00403       ast_unlock_contexts();
00404       return res;
00405    } else if (pos == 4) { /* "dialplan remove include CTX _X_" */
00406       /*
00407        * complete as 'from', but only if previous context is really
00408        * included somewhere
00409        */
00410       char *context, *dupline;
00411       const char *s = skip_words(line, 3); /* skip 'dialplan' 'remove' 'include' */
00412 
00413       if (state > 0)
00414          return NULL;
00415       context = dupline = strdup(s);
00416       if (!dupline) {
00417          ast_log(LOG_ERROR, "Out of free memory\n");
00418          return NULL;
00419       }
00420       strsep(&dupline, " ");
00421 
00422       if (ast_rdlock_contexts()) {
00423          ast_log(LOG_ERROR, "Failed to lock contexts list\n");
00424          free(context);
00425          return NULL;
00426       }
00427 
00428       /* go through all contexts and check if is included ... */
00429       while (!res && (c = ast_walk_contexts(c)))
00430          if (lookup_ci(c, context)) /* context is really included, complete "from" command */
00431             res = strdup("from");
00432       ast_unlock_contexts();
00433       if (!res)
00434          ast_log(LOG_WARNING, "%s not included anywhere\n", context);
00435       free(context);
00436       return res;
00437    } else if (pos == 5) { /* "dialplan remove include CTX from _X_" */
00438       /*
00439        * Context from which we removing include ... 
00440        */
00441       char *context, *dupline, *from;
00442       const char *s = skip_words(line, 3); /* skip 'dialplan' 'remove' 'include' */
00443       context = dupline = strdup(s);
00444       if (!dupline) {
00445          ast_log(LOG_ERROR, "Out of free memory\n");
00446          return NULL;
00447       }
00448 
00449       strsep(&dupline, " "); /* skip context */
00450 
00451       /* fourth word must be 'from' */
00452       from = strsep(&dupline, " ");
00453       if (!from || strcmp(from, "from")) {
00454          free(context);
00455          return NULL;
00456       }
00457 
00458       if (ast_rdlock_contexts()) {
00459          ast_log(LOG_ERROR, "Failed to lock context list\n");
00460          free(context);
00461          return NULL;
00462       }
00463 
00464       /* walk through all contexts ... */
00465       c = NULL;
00466       while ( !res && (c = ast_walk_contexts(c))) {
00467          const char *c_name = ast_get_context_name(c);
00468          if (!partial_match(c_name, word, len)) /* not a good target */
00469             continue;
00470          /* walk through all includes and check if it is our context */ 
00471          if (lookup_ci(c, context) && ++which > state)
00472             res = strdup(c_name);
00473       }
00474       ast_unlock_contexts();
00475       free(context);
00476       return res;
00477    }
00478 
00479    return NULL;
00480 }

static int fix_complete_args ( const char *  line,
char **  word,
int *  pos 
) [static]

Definition at line 638 of file pbx_config.c.

References free, strdup, and words.

Referenced by complete_context_remove_extension(), and complete_context_remove_extension_deprecated().

00639 {
00640    char *_line, *_strsep_line, *_previous_word = NULL, *_word = NULL;
00641    int words = 0;
00642 
00643    _line = strdup(line);
00644 
00645    _strsep_line = _line;
00646    while (_strsep_line) {
00647       _previous_word = _word;
00648       _word = strsep(&_strsep_line, " ");
00649 
00650       if (_word && strlen(_word)) words++;
00651    }
00652 
00653 
00654    if (_word || _previous_word) {
00655       if (_word) {
00656          if (!strlen(_word)) words++;
00657          *word = strdup(_word);
00658       } else
00659          *word = strdup(_previous_word);
00660       *pos = words - 1;
00661       free(_line);
00662       return 0;
00663    }
00664 
00665    free(_line);
00666    return -1;
00667 }

static int handle_context_add_extension ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1575 of file pbx_config.c.

References app, ast_add_extension(), ast_cli(), ast_free, ast_process_quotes_and_slashes(), errno, exten, PRIORITY_HINT, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and strdup.

01576 {
01577    char *whole_exten;
01578    char *exten, *prior;
01579    int iprior = -2;
01580    char *cidmatch, *app, *app_data;
01581    char *start, *end;
01582 
01583    /* check for arguments at first */
01584    if (argc != 6 && argc != 7)
01585       return RESULT_SHOWUSAGE;
01586    if (strcmp(argv[4], "into"))
01587       return RESULT_SHOWUSAGE;
01588    if (argc == 7) if (strcmp(argv[6], "replace")) return RESULT_SHOWUSAGE;
01589 
01590    /* XXX overwrite argv[3] */
01591    whole_exten = argv[3];
01592    exten    = strsep(&whole_exten,",");
01593    if (strchr(exten, '/')) {
01594       cidmatch = exten;
01595       strsep(&cidmatch,"/");
01596    } else {
01597       cidmatch = NULL;
01598    }
01599    prior = strsep(&whole_exten,",");
01600    if (prior) {
01601       if (!strcmp(prior, "hint")) {
01602          iprior = PRIORITY_HINT;
01603       } else {
01604          if (sscanf(prior, "%d", &iprior) != 1) {
01605             ast_cli(fd, "'%s' is not a valid priority\n", prior);
01606             prior = NULL;
01607          }
01608       }
01609    }
01610    app = whole_exten;
01611    if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) {
01612       *start = *end = '\0';
01613       app_data = start + 1;
01614       ast_process_quotes_and_slashes(app_data, ',', '|');
01615    } else {
01616       if (app) {
01617          app_data = strchr(app, ',');
01618          if (app_data) {
01619             *app_data = '\0';
01620             app_data++;
01621          }
01622       } else   
01623          app_data = NULL;
01624    }
01625 
01626    if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT))
01627       return RESULT_SHOWUSAGE;
01628 
01629    if (!app_data)
01630       app_data="";
01631    if (ast_add_extension(argv[5], argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
01632       (void *)strdup(app_data), ast_free, registrar)) {
01633       switch (errno) {
01634       case ENOMEM:
01635          ast_cli(fd, "Out of free memory\n");
01636          break;
01637 
01638       case EBUSY:
01639          ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
01640          break;
01641 
01642       case ENOENT:
01643          ast_cli(fd, "No existence of '%s' context\n", argv[5]);
01644          break;
01645 
01646       case EEXIST:
01647          ast_cli(fd, "Extension %s@%s with priority %s already exists\n",
01648             exten, argv[5], prior);
01649          break;
01650 
01651       default:
01652          ast_cli(fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n",
01653                exten, prior, app, app_data, argv[5]);
01654          break;
01655       }
01656       return RESULT_FAILURE;
01657    }
01658 
01659    if (argc == 7)
01660       ast_cli(fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n",
01661          exten, argv[5], prior, exten, prior, app, app_data);
01662    else
01663       ast_cli(fd, "Extension '%s,%s,%s,%s' added into '%s' context\n",
01664          exten, prior, app, app_data, argv[5]);
01665 
01666    return RESULT_SUCCESS;
01667 }

static int handle_context_add_extension_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

ADD EXTENSION command stuff.

Definition at line 1482 of file pbx_config.c.

References app, ast_add_extension(), ast_cli(), ast_free, ast_process_quotes_and_slashes(), errno, exten, PRIORITY_HINT, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and strdup.

01483 {
01484    char *whole_exten;
01485    char *exten, *prior;
01486    int iprior = -2;
01487    char *cidmatch, *app, *app_data;
01488    char *start, *end;
01489 
01490    /* check for arguments at first */
01491    if (argc != 5 && argc != 6)
01492       return RESULT_SHOWUSAGE;
01493    if (strcmp(argv[3], "into"))
01494       return RESULT_SHOWUSAGE;
01495    if (argc == 6) if (strcmp(argv[5], "replace")) return RESULT_SHOWUSAGE;
01496 
01497    /* XXX overwrite argv[2] */
01498    whole_exten = argv[2];
01499    exten    = strsep(&whole_exten,",");
01500    if (strchr(exten, '/')) {
01501       cidmatch = exten;
01502       strsep(&cidmatch,"/");
01503    } else {
01504       cidmatch = NULL;
01505    }
01506    prior       = strsep(&whole_exten,",");
01507    if (prior) {
01508       if (!strcmp(prior, "hint")) {
01509          iprior = PRIORITY_HINT;
01510       } else {
01511          if (sscanf(prior, "%d", &iprior) != 1) {
01512             ast_cli(fd, "'%s' is not a valid priority\n", prior);
01513             prior = NULL;
01514          }
01515       }
01516    }
01517    app = whole_exten;
01518    if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) {
01519       *start = *end = '\0';
01520       app_data = start + 1;
01521       ast_process_quotes_and_slashes(app_data, ',', '|');
01522    } else {
01523       if (app) {
01524          app_data = strchr(app, ',');
01525          if (app_data) {
01526             *app_data = '\0';
01527             app_data++;
01528          }
01529       } else   
01530          app_data = NULL;
01531    }
01532 
01533    if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT))
01534       return RESULT_SHOWUSAGE;
01535 
01536    if (!app_data)
01537       app_data="";
01538    if (ast_add_extension(argv[4], argc == 6 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
01539       (void *)strdup(app_data), ast_free, registrar)) {
01540       switch (errno) {
01541       case ENOMEM:
01542          ast_cli(fd, "Out of free memory\n");
01543          break;
01544 
01545       case EBUSY:
01546          ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
01547          break;
01548 
01549       case ENOENT:
01550          ast_cli(fd, "No existence of '%s' context\n", argv[4]);
01551          break;
01552 
01553       case EEXIST:
01554          ast_cli(fd, "Extension %s@%s with priority %s already exists\n",
01555             exten, argv[4], prior);
01556          break;
01557 
01558       default:
01559          ast_cli(fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n",
01560                exten, prior, app, app_data, argv[4]);
01561          break;
01562       }
01563       return RESULT_FAILURE;
01564    }
01565 
01566    if (argc == 6) 
01567       ast_cli(fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n",
01568          exten, argv[4], prior, exten, prior, app, app_data);
01569    else
01570       ast_cli(fd, "Extension '%s,%s,%s,%s' added into '%s' context\n",
01571          exten, prior, app, app_data, argv[4]);
01572 
01573    return RESULT_SUCCESS;
01574 }

static int handle_context_add_ignorepat ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1770 of file pbx_config.c.

References ast_cli(), ast_context_add_ignorepat(), errno, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01771 {
01772    if (argc != 6)
01773       return RESULT_SHOWUSAGE;
01774    if (strcmp(argv[4], "into"))
01775       return RESULT_SHOWUSAGE;
01776 
01777    if (ast_context_add_ignorepat(argv[5], argv[3], registrar)) {
01778       switch (errno) {
01779       case ENOMEM:
01780          ast_cli(fd, "Out of free memory\n");
01781          break;
01782 
01783       case ENOENT:
01784          ast_cli(fd, "There is no existence of '%s' context\n", argv[5]);
01785          break;
01786 
01787       case EEXIST:
01788          ast_cli(fd, "Ignore pattern '%s' already included in '%s' context\n",
01789             argv[3], argv[5]);
01790          break;
01791 
01792       case EBUSY:
01793          ast_cli(fd, "Failed to lock context(s) list, please, try again later\n");
01794          break;
01795 
01796       default:
01797          ast_cli(fd, "Failed to add ingore pattern '%s' into '%s' context\n",
01798             argv[3], argv[5]);
01799          break;
01800       }
01801       return RESULT_FAILURE;
01802    }
01803 
01804    ast_cli(fd, "Ignore pattern '%s' added into '%s' context\n",
01805       argv[3], argv[5]);
01806    return RESULT_SUCCESS;
01807 }

static int handle_context_add_ignorepat_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

IGNOREPAT CLI stuff

Definition at line 1731 of file pbx_config.c.

References ast_cli(), ast_context_add_ignorepat(), errno, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01732 {
01733    if (argc != 5)
01734       return RESULT_SHOWUSAGE;
01735    if (strcmp(argv[3], "into"))
01736       return RESULT_SHOWUSAGE;
01737 
01738    if (ast_context_add_ignorepat(argv[4], argv[2], registrar)) {
01739       switch (errno) {
01740       case ENOMEM:
01741          ast_cli(fd, "Out of free memory\n");
01742          break;
01743 
01744       case ENOENT:
01745          ast_cli(fd, "There is no existence of '%s' context\n", argv[4]);
01746          break;
01747 
01748       case EEXIST:
01749          ast_cli(fd, "Ignore pattern '%s' already included in '%s' context\n",
01750             argv[2], argv[4]);
01751          break;
01752 
01753       case EBUSY:
01754          ast_cli(fd, "Failed to lock context(s) list, please, try again later\n");
01755          break;
01756 
01757       default:
01758          ast_cli(fd, "Failed to add ingore pattern '%s' into '%s' context\n",
01759             argv[2], argv[4]);
01760          break;
01761       }
01762       return RESULT_FAILURE;
01763    }
01764 
01765    ast_cli(fd, "Ignore pattern '%s' added into '%s' context\n",
01766       argv[2], argv[4]);
01767    return RESULT_SUCCESS;
01768 }

static int handle_context_add_include ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1012 of file pbx_config.c.

References ast_cli(), ast_context_add_include(), errno, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01013 {
01014    if (argc != 6) /* dialplan add include CTX in CTX */
01015       return RESULT_SHOWUSAGE;
01016 
01017    /* fifth arg must be 'into' ... */
01018    if (strcmp(argv[4], "into"))
01019       return RESULT_SHOWUSAGE;
01020 
01021    if (ast_context_add_include(argv[5], argv[3], registrar)) {
01022       switch (errno) {
01023       case ENOMEM:
01024          ast_cli(fd, "Out of memory for context addition\n");
01025          break;
01026 
01027       case EBUSY:
01028          ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
01029          break;
01030 
01031       case EEXIST:
01032          ast_cli(fd, "Context '%s' already included in '%s' context\n",
01033             argv[3], argv[5]);
01034          break;
01035 
01036       case ENOENT:
01037       case EINVAL:
01038          ast_cli(fd, "There is no existence of context '%s'\n",
01039             errno == ENOENT ? argv[5] : argv[3]);
01040          break;
01041 
01042       default:
01043          ast_cli(fd, "Failed to include '%s' in '%s' context\n",
01044             argv[3], argv[5]);
01045          break;
01046       }
01047       return RESULT_FAILURE;
01048    }
01049 
01050    /* show some info ... */
01051    ast_cli(fd, "Context '%s' included in '%s' context\n",
01052       argv[3], argv[5]);
01053 
01054    return RESULT_SUCCESS;
01055 }

static int handle_context_add_include_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Include context ...

Definition at line 967 of file pbx_config.c.

References ast_cli(), ast_context_add_include(), errno, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00968 {
00969    if (argc != 5) /* include context CTX in CTX */
00970       return RESULT_SHOWUSAGE;
00971 
00972    /* third arg must be 'in' ... */
00973    if (strcmp(argv[3], "in") && strcmp(argv[3], "into")) /* XXX why both ? */
00974       return RESULT_SHOWUSAGE;
00975 
00976    if (ast_context_add_include(argv[4], argv[2], registrar)) {
00977       switch (errno) {
00978       case ENOMEM:
00979          ast_cli(fd, "Out of memory for context addition\n");
00980          break;
00981 
00982       case EBUSY:
00983          ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
00984          break;
00985 
00986       case EEXIST:
00987          ast_cli(fd, "Context '%s' already included in '%s' context\n",
00988             argv[2], argv[4]);
00989          break;
00990 
00991       case ENOENT:
00992       case EINVAL:
00993          ast_cli(fd, "There is no existence of context '%s'\n",
00994             errno == ENOENT ? argv[4] : argv[2]);
00995          break;
00996 
00997       default:
00998          ast_cli(fd, "Failed to include '%s' in '%s' context\n",
00999             argv[2], argv[4]);
01000          break;
01001       }
01002       return RESULT_FAILURE;
01003    }
01004 
01005    /* show some info ... */
01006    ast_cli(fd, "Context '%s' included in '%s' context\n",
01007       argv[2], argv[4]);
01008 
01009    return RESULT_SUCCESS;
01010 }

static int handle_context_dont_include_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

REMOVE INCLUDE command stuff

Definition at line 117 of file pbx_config.c.

References ast_cli(), ast_context_remove_include(), RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00118 {
00119    if (argc != 5)
00120       return RESULT_SHOWUSAGE;
00121 
00122    if (strcmp(argv[3], "into"))
00123       return RESULT_SHOWUSAGE;
00124 
00125    if (!ast_context_remove_include(argv[4], argv[2], registrar)) {
00126       ast_cli(fd, "We are not including '%s' into '%s' now\n",
00127          argv[2], argv[4]);
00128       return RESULT_SUCCESS;
00129    }
00130 
00131    ast_cli(fd, "Failed to remove '%s' include from '%s' context\n",
00132       argv[2], argv[4]);
00133    return RESULT_FAILURE;
00134 }

static int handle_context_remove_extension ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 554 of file pbx_config.c.

References ast_cli(), ast_context_remove_extension_callerid(), context, exten, free, PRIORITY_HINT, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and split_ec().

00555 {
00556    int removing_priority = 0;
00557    char *exten, *context, *cid;
00558    int ret = RESULT_FAILURE;
00559 
00560    if (argc != 5 && argc != 4) return RESULT_SHOWUSAGE;
00561 
00562    /*
00563     * Priority input checking ...
00564     */
00565    if (argc == 5) {
00566       char *c = argv[4];
00567 
00568       /* check for digits in whole parameter for right priority ...
00569        * why? because atoi (strtol) returns 0 if any characters in
00570        * string and whole extension will be removed, it's not good
00571        */
00572       if (!strcmp("hint", c))
00573          removing_priority = PRIORITY_HINT;
00574       else {
00575          while (*c && isdigit(*c))
00576             c++;
00577          if (*c) { /* non-digit in string */
00578             ast_cli(fd, "Invalid priority '%s'\n", argv[4]);
00579             return RESULT_FAILURE;
00580          }
00581          removing_priority = atoi(argv[4]);
00582       }
00583 
00584       if (removing_priority == 0) {
00585          ast_cli(fd, "If you want to remove whole extension, please " \
00586             "omit priority argument\n");
00587          return RESULT_FAILURE;
00588       }
00589    }
00590 
00591    /* XXX original overwrote argv[3] */
00592    /*
00593     * Format exten@context checking ...
00594     */
00595    if (split_ec(argv[3], &exten, &context, &cid))
00596       return RESULT_FAILURE; /* XXX malloc failure */
00597    if ((!strlen(exten)) || (!(strlen(context)))) {
00598       ast_cli(fd, "Missing extension or context name in third argument '%s'\n",
00599          argv[3]);
00600       free(exten);
00601       return RESULT_FAILURE;
00602    }
00603 
00604    if (!ast_context_remove_extension_callerid(context, exten, removing_priority,
00605          /* Do NOT substitute S_OR; it is NOT the same thing */
00606          cid ? cid : (removing_priority ? "" : NULL), cid ? 1 : 0, registrar)) {
00607       if (!removing_priority)
00608          ast_cli(fd, "Whole extension %s@%s removed\n",
00609             exten, context);
00610       else
00611          ast_cli(fd, "Extension %s@%s with priority %d removed\n",
00612             exten, context, removing_priority);
00613          
00614       ret = RESULT_SUCCESS;
00615    } else {
00616       ast_cli(fd, "Failed to remove extension %s@%s\n", exten, context);
00617       ret = RESULT_FAILURE;
00618    }
00619    free(exten);
00620    return ret;
00621 }

static int handle_context_remove_extension_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

REMOVE EXTENSION command stuff

Definition at line 485 of file pbx_config.c.

References ast_cli(), ast_context_remove_extension_callerid(), context, exten, free, PRIORITY_HINT, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and split_ec().

00486 {
00487    int removing_priority = 0;
00488    char *exten, *context, *cid;
00489    int ret = RESULT_FAILURE;
00490 
00491    if (argc != 4 && argc != 3) return RESULT_SHOWUSAGE;
00492 
00493    /*
00494     * Priority input checking ...
00495     */
00496    if (argc == 4) {
00497       char *c = argv[3];
00498 
00499       /* check for digits in whole parameter for right priority ...
00500        * why? because atoi (strtol) returns 0 if any characters in
00501        * string and whole extension will be removed, it's not good
00502        */
00503       if (!strcmp("hint", c))
00504          removing_priority = PRIORITY_HINT;
00505       else {
00506          while (*c && isdigit(*c))
00507             c++;
00508          if (*c) { /* non-digit in string */
00509             ast_cli(fd, "Invalid priority '%s'\n", argv[3]);
00510             return RESULT_FAILURE;
00511          }
00512          removing_priority = atoi(argv[3]);
00513       }
00514 
00515       if (removing_priority == 0) {
00516          ast_cli(fd, "If you want to remove whole extension, please " \
00517             "omit priority argument\n");
00518          return RESULT_FAILURE;
00519       }
00520    }
00521 
00522    /* XXX original overwrote argv[2] */
00523    /*
00524     * Format exten@context checking ...
00525     */
00526    if (split_ec(argv[2], &exten, &context, &cid))
00527       return RESULT_FAILURE; /* XXX malloc failure */
00528    if ((!strlen(exten)) || (!(strlen(context)))) {
00529       ast_cli(fd, "Missing extension or context name in second argument '%s'\n",
00530          argv[2]);
00531       free(exten);
00532       return RESULT_FAILURE;
00533    }
00534 
00535    if (!ast_context_remove_extension_callerid(context, exten, removing_priority,
00536          /* Do NOT substitute S_OR; it is NOT the same thing */
00537          cid ? cid : (removing_priority ? "" : NULL), cid ? 1 : 0, registrar)) {
00538       if (!removing_priority)
00539          ast_cli(fd, "Whole extension %s@%s removed\n",
00540             exten, context);
00541       else
00542          ast_cli(fd, "Extension %s@%s with priority %d removed\n",
00543             exten, context, removing_priority);
00544          
00545       ret = RESULT_SUCCESS;
00546    } else {
00547       ast_cli(fd, "Failed to remove extension %s@%s\n", exten, context);
00548       ret = RESULT_FAILURE;
00549    }
00550    free(exten);
00551    return ret;
00552 }

static int handle_context_remove_ignorepat ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1941 of file pbx_config.c.

References ast_cli(), ast_context_remove_ignorepat(), errno, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01942 {
01943    if (argc != 6)
01944       return RESULT_SHOWUSAGE;
01945    if (strcmp(argv[4], "from"))
01946       return RESULT_SHOWUSAGE;
01947 
01948    if (ast_context_remove_ignorepat(argv[5], argv[3], registrar)) {
01949       switch (errno) {
01950       case EBUSY:
01951          ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
01952          break;
01953 
01954       case ENOENT:
01955          ast_cli(fd, "There is no existence of '%s' context\n", argv[5]);
01956          break;
01957 
01958       case EINVAL:
01959          ast_cli(fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
01960                argv[3], argv[5]);
01961          break;
01962 
01963       default:
01964          ast_cli(fd, "Failed to remove ignore pattern '%s' from '%s' context\n", argv[3], argv[5]);
01965          break;
01966       }
01967       return RESULT_FAILURE;
01968    }
01969 
01970    ast_cli(fd, "Ignore pattern '%s' removed from '%s' context\n",
01971       argv[3], argv[5]);
01972    return RESULT_SUCCESS;
01973 }

static int handle_context_remove_ignorepat_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1907 of file pbx_config.c.

References ast_cli(), ast_context_remove_ignorepat(), errno, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01908 {
01909    if (argc != 5)
01910       return RESULT_SHOWUSAGE;
01911    if (strcmp(argv[3], "from"))
01912       return RESULT_SHOWUSAGE;
01913 
01914    if (ast_context_remove_ignorepat(argv[4], argv[2], registrar)) {
01915       switch (errno) {
01916       case EBUSY:
01917          ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
01918          break;
01919 
01920       case ENOENT:
01921          ast_cli(fd, "There is no existence of '%s' context\n", argv[4]);
01922          break;
01923 
01924       case EINVAL:
01925          ast_cli(fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
01926                argv[2], argv[4]);
01927          break;
01928 
01929       default:
01930          ast_cli(fd, "Failed to remove ignore pattern '%s' from '%s' context\n", argv[2], argv[4]);
01931          break;
01932       }
01933       return RESULT_FAILURE;
01934    }
01935 
01936    ast_cli(fd, "Ignore pattern '%s' removed from '%s' context\n",
01937       argv[2], argv[4]);
01938    return RESULT_SUCCESS;
01939 }

static int handle_context_remove_include ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 136 of file pbx_config.c.

References ast_cli(), ast_context_remove_include(), RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00137 {
00138    if (argc != 6) {
00139       return RESULT_SHOWUSAGE;
00140    }
00141 
00142    if (strcmp(argv[4], "from")) {
00143       return RESULT_SHOWUSAGE;
00144    }
00145 
00146    if (!ast_context_remove_include(argv[5], argv[3], registrar)) {
00147       ast_cli(fd, "The dialplan no longer includes '%s' into '%s'\n",
00148          argv[3], argv[5]);
00149       return RESULT_SUCCESS;
00150    }
00151 
00152    ast_cli(fd, "Failed to remove '%s' include from '%s' context\n",
00153       argv[3], argv[5]);
00154 
00155    return RESULT_FAILURE;
00156 }

static int handle_reload_extensions ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 2141 of file pbx_config.c.

References ast_cli(), pbx_builtin_clear_globals(), pbx_load_module(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

02142 {
02143    if (argc != 2)
02144       return RESULT_SHOWUSAGE;
02145    if (clearglobalvars_config)
02146       pbx_builtin_clear_globals();
02147    pbx_load_module();
02148    ast_cli(fd, "Dialplan reloaded.\n");
02149    return RESULT_SUCCESS;
02150 }

static int handle_save_dialplan ( int  fd,
int  argc,
char *  argv[] 
) [static]

'save dialplan' CLI command implementation functions ...

Definition at line 1250 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_mutex_lock(), ast_mutex_unlock(), ast_rdlock_contexts(), ast_strlen_zero(), ast_true(), ast_unlock_context(), ast_unlock_contexts(), ast_variable_browse(), ast_variable_retrieve(), ast_walk_context_extensions(), ast_walk_context_ignorepats(), ast_walk_context_includes(), ast_walk_context_switches(), ast_walk_contexts(), ast_walk_extension_priorities(), el, ast_variable::name, ast_variable::next, PRIORITY_HINT, PUT_CTX_HDR, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, save_dialplan_lock, t, and ast_variable::value.

01251 {
01252    char filename[256];
01253    struct ast_context *c;
01254    struct ast_config *cfg;
01255    struct ast_variable *v;
01256    int incomplete = 0; /* incomplete config write? */
01257    FILE *output;
01258 
01259    const char *base, *slash, *file;
01260 
01261    if (! (static_config && !write_protect_config)) {
01262       ast_cli(fd,
01263          "I can't save dialplan now, see '%s' example file.\n",
01264          config);
01265       return RESULT_FAILURE;
01266    }
01267 
01268    if (argc != 2 && argc != 3)
01269       return RESULT_SHOWUSAGE;
01270 
01271    if (ast_mutex_lock(&save_dialplan_lock)) {
01272       ast_cli(fd,
01273          "Failed to lock dialplan saving (another proccess saving?)\n");
01274       return RESULT_FAILURE;
01275    }
01276    /* XXX the code here is quite loose, a pathname with .conf in it
01277     * is assumed to be a complete pathname
01278     */
01279    if (argc == 3) {  /* have config path. Look for *.conf */
01280       base = argv[2];
01281       if (!strstr(argv[2], ".conf")) { /*no, this is assumed to be a pathname */
01282          /* if filename ends with '/', do not add one */
01283          slash = (*(argv[2] + strlen(argv[2]) -1) == '/') ? "/" : "";
01284          file = config; /* default: 'extensions.conf' */
01285       } else { /* yes, complete file name */
01286          slash = "";
01287          file = "";
01288       }
01289    } else {
01290       /* no config file, default one */
01291       base = ast_config_AST_CONFIG_DIR;
01292       slash = "/";
01293       file = config;
01294    }
01295    snprintf(filename, sizeof(filename), "%s%s%s", base, slash, config);
01296 
01297    cfg = ast_config_load("extensions.conf");
01298 
01299    /* try to lock contexts list */
01300    if (ast_rdlock_contexts()) {
01301       ast_cli(fd, "Failed to lock contexts list\n");
01302       ast_mutex_unlock(&save_dialplan_lock);
01303       ast_config_destroy(cfg);
01304       return RESULT_FAILURE;
01305    }
01306 
01307    /* create new file ... */
01308    if (!(output = fopen(filename, "wt"))) {
01309       ast_cli(fd, "Failed to create file '%s'\n",
01310          filename);
01311       ast_unlock_contexts();
01312       ast_mutex_unlock(&save_dialplan_lock);
01313       ast_config_destroy(cfg);
01314       return RESULT_FAILURE;
01315    }
01316 
01317    /* fireout general info */
01318    fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\npriorityjumping=%s\n\n",
01319       static_config ? "yes" : "no",
01320       write_protect_config ? "yes" : "no",
01321                 autofallthrough_config ? "yes" : "no",
01322                 clearglobalvars_config ? "yes" : "no",
01323       ast_true(ast_variable_retrieve(cfg, "general", "priorityjumping")) ? "yes" : "no");
01324 
01325    if ((v = ast_variable_browse(cfg, "globals"))) {
01326       fprintf(output, "[globals]\n");
01327       while(v) {
01328          fprintf(output, "%s => %s\n", v->name, v->value);
01329          v = v->next;
01330       }
01331       fprintf(output, "\n");
01332    }
01333 
01334    ast_config_destroy(cfg);
01335    
01336 #define PUT_CTX_HDR  do { \
01337    if (!context_header_written) {   \
01338       fprintf(output, "[%s]\n", ast_get_context_name(c));   \
01339       context_header_written = 1;   \
01340    }  \
01341    } while (0)
01342 
01343    /* walk all contexts */
01344    for (c = NULL; (c = ast_walk_contexts(c)); ) {
01345       int context_header_written = 0;
01346       struct ast_exten *e, *last_written_e = NULL;
01347       struct ast_include *i;
01348       struct ast_ignorepat *ip;
01349       struct ast_sw *sw;
01350 
01351       /* try to lock context and fireout all info */  
01352       if (ast_lock_context(c)) { /* lock failure */
01353          incomplete = 1;
01354          continue;
01355       }
01356       /* registered by this module? */
01357       /* XXX do we need this ? */
01358       if (!strcmp(ast_get_context_registrar(c), registrar)) {
01359          fprintf(output, "[%s]\n", ast_get_context_name(c));
01360          context_header_written = 1;
01361       }
01362 
01363       /* walk extensions ... */
01364       for (e = NULL; (e = ast_walk_context_extensions(c, e)); ) {
01365          struct ast_exten *p = NULL;
01366 
01367          /* fireout priorities */
01368          while ( (p = ast_walk_extension_priorities(e, p)) ) {
01369             if (strcmp(ast_get_extension_registrar(p), registrar) != 0) /* not this source */
01370                continue;
01371       
01372             /* make empty line between different extensions */ 
01373             if (last_written_e != NULL &&
01374                    strcmp(ast_get_extension_name(last_written_e),
01375                       ast_get_extension_name(p)))
01376                fprintf(output, "\n");
01377             last_written_e = p;
01378          
01379             PUT_CTX_HDR;
01380 
01381             if (ast_get_extension_priority(p)==PRIORITY_HINT) { /* easy */
01382                fprintf(output, "exten => %s,hint,%s\n",
01383                       ast_get_extension_name(p),
01384                       ast_get_extension_app(p));
01385             } else { /* copy and replace '|' with ',' */
01386                const char *sep, *cid;
01387                char *tempdata = "";
01388                char *s;
01389                const char *el = ast_get_extension_label(p);
01390                char label[128] = "";
01391  
01392                s = ast_get_extension_app_data(p);
01393                if (s) {
01394                   char *t;
01395                   tempdata = alloca(strlen(tempdata) * 2 + 1);
01396 
01397                   for (t = tempdata; *s; s++, t++) {
01398                      if (*s == '|')
01399                         *t = ',';
01400                      else {
01401                         if (*s == ',' || *s == ';')
01402                            *t++ = '\\';
01403                         *t = *s;
01404                      }
01405                   }
01406                   /* Terminating NULL */
01407                   *t = *s;
01408                }
01409 
01410                if (ast_get_extension_matchcid(p)) {
01411                   sep = "/";
01412                   cid = ast_get_extension_cidmatch(p);
01413                } else
01414                   sep = cid = "";
01415             
01416                if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2)))
01417                   incomplete = 1;   /* error encountered or label > 125 chars */
01418                
01419                fprintf(output, "exten => %s%s%s,%d%s,%s(%s)\n",
01420                    ast_get_extension_name(p), (ast_strlen_zero(sep) ? "" : sep), (ast_strlen_zero(cid) ? "" : cid),
01421                    ast_get_extension_priority(p), label,
01422                    ast_get_extension_app(p), (ast_strlen_zero(tempdata) ? "" : tempdata));
01423             }
01424          }
01425       }
01426 
01427       /* written any extensions? ok, write space between exten & inc */
01428       if (last_written_e)
01429          fprintf(output, "\n");
01430 
01431       /* walk through includes */
01432       for (i = NULL; (i = ast_walk_context_includes(c, i)) ; ) {
01433          if (strcmp(ast_get_include_registrar(i), registrar) != 0)
01434             continue; /* not mine */
01435          PUT_CTX_HDR;
01436          fprintf(output, "include => %s\n", ast_get_include_name(i));
01437       }
01438       if (ast_walk_context_includes(c, NULL))
01439          fprintf(output, "\n");
01440 
01441       /* walk through switches */
01442       for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) {
01443          if (strcmp(ast_get_switch_registrar(sw), registrar) != 0)
01444             continue; /* not mine */
01445          PUT_CTX_HDR;
01446          fprintf(output, "switch => %s/%s\n",
01447                 ast_get_switch_name(sw), ast_get_switch_data(sw));
01448       }
01449 
01450       if (ast_walk_context_switches(c, NULL))
01451          fprintf(output, "\n");
01452 
01453       /* fireout ignorepats ... */
01454       for (ip = NULL; (ip = ast_walk_context_ignorepats(c, ip)); ) {
01455          if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0)
01456             continue; /* not mine */
01457          PUT_CTX_HDR;
01458          fprintf(output, "ignorepat => %s\n",
01459                   ast_get_ignorepat_name(ip));
01460       }
01461 
01462       ast_unlock_context(c);
01463    }  
01464 
01465    ast_unlock_contexts();
01466    ast_mutex_unlock(&save_dialplan_lock);
01467    fclose(output);
01468 
01469    if (incomplete) {
01470       ast_cli(fd, "Saved dialplan is incomplete\n");
01471       return RESULT_FAILURE;
01472    }
01473 
01474    ast_cli(fd, "Dialplan successfully saved into '%s'\n",
01475       filename);
01476    return RESULT_SUCCESS;
01477 }

static int load_module ( void   )  [static]

Definition at line 2547 of file pbx_config.c.

References ast_cli_register(), ast_cli_register_multiple(), AST_MODULE_LOAD_DECLINE, cli_dialplan_save, cli_pbx_config, pbx_load_module(), static_config, and write_protect_config.

02548 {
02549    if (pbx_load_module())
02550       return AST_MODULE_LOAD_DECLINE;
02551  
02552    if (static_config && !write_protect_config)
02553       ast_cli_register(&cli_dialplan_save);
02554    ast_cli_register_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
02555 
02556    return 0;
02557 }

static int lookup_c_ip ( struct ast_context c,
const char *  name 
) [static]

return true if 'name' is in the ignorepats for context c

Definition at line 173 of file pbx_config.c.

References ast_get_ignorepat_name(), ast_lock_context(), ast_unlock_context(), and ast_walk_context_ignorepats().

Referenced by complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_remove_ignorepat(), and complete_context_remove_ignorepat_deprecated().

00174 {
00175    struct ast_ignorepat *ip = NULL;
00176 
00177    if (ast_lock_context(c))   /* error, skip */
00178       return 0;
00179    while ( (ip = ast_walk_context_ignorepats(c, ip)) )
00180       if (!strcmp(name, ast_get_ignorepat_name(ip)))
00181          break;
00182    ast_unlock_context(c);
00183    return ip ? -1 /* success */ : 0;
00184 }

static int lookup_ci ( struct ast_context c,
const char *  name 
) [static]

return true if 'name' is included by context c

Definition at line 159 of file pbx_config.c.

References ast_get_include_name(), ast_lock_context(), ast_unlock_context(), and ast_walk_context_includes().

Referenced by complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), and complete_context_remove_include().

00160 {
00161    struct ast_include *i = NULL;
00162 
00163    if (ast_lock_context(c))   /* error, skip */
00164       return 0;
00165    while ( (i = ast_walk_context_includes(c, i)) )
00166       if (!strcmp(name, ast_get_include_name(i)))
00167          break;
00168    ast_unlock_context(c);
00169    return i ? -1 /* success */ : 0;
00170 }

static int partial_match ( const char *  s,
const char *  word,
int  len 
) [static]

match the first 'len' chars of word. len==0 always succeeds

Definition at line 202 of file pbx_config.c.

Referenced by complete_context_add_extension(), complete_context_add_extension_deprecated(), complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), complete_context_remove_ignorepat(), complete_context_remove_ignorepat_deprecated(), and complete_context_remove_include().

00203 {
00204    return (len == 0 || !strncmp(s, word, len));
00205 }

static int pbx_load_config ( const char *  config_file  )  [static]

Definition at line 2243 of file pbx_config.c.

References ast_add_extension2(), ast_category_browse(), ast_config_load(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_find_or_create(), ast_copy_string(), ast_findlabel_extension2(), ast_free, ast_log(), ast_opt_dont_warn, AST_OPT_FLAG_PRIORITY_JUMPING, ast_options, ast_process_quotes_and_slashes(), ast_set2_flag, ast_shrink_phone_number(), ast_skip_blanks(), ast_strdup, ast_trim_blanks(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ext, free, ast_variable::lineno, local_contexts, LOG_WARNING, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), PRIORITY_HINT, S_OR, strdup, and ast_variable::value.

Referenced by pbx_load_module().

02244 {
02245    struct ast_config *cfg;
02246    char *end;
02247    char *label;
02248 #ifdef LOW_MEMORY
02249    char realvalue[256];
02250 #else
02251    char realvalue[8192];
02252 #endif
02253    int lastpri = -2;
02254    struct ast_context *con;
02255    struct ast_variable *v;
02256    const char *cxt;
02257    const char *aft;
02258 
02259    cfg = ast_config_load(config_file);
02260    if (!cfg)
02261       return 0;
02262 
02263    /* Use existing config to populate the PBX table */
02264    static_config = ast_true(ast_variable_retrieve(cfg, "general", "static"));
02265    write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect"));
02266    if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough")))
02267       autofallthrough_config = ast_true(aft);
02268    clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars"));
02269    ast_set2_flag(&ast_options, ast_true(ast_variable_retrieve(cfg, "general", "priorityjumping")), AST_OPT_FLAG_PRIORITY_JUMPING);
02270 
02271    if ((cxt = ast_variable_retrieve(cfg, "general", "userscontext"))) 
02272       ast_copy_string(userscontext, cxt, sizeof(userscontext));
02273    else
02274       ast_copy_string(userscontext, "default", sizeof(userscontext));
02275                             
02276    for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) {
02277       memset(realvalue, 0, sizeof(realvalue));
02278       pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
02279       pbx_builtin_setvar_helper(NULL, v->name, realvalue);
02280    }
02281    for (cxt = NULL; (cxt = ast_category_browse(cfg, cxt)); ) {
02282       /* All categories but "general" or "globals" are considered contexts */
02283       if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals"))
02284          continue;
02285       con=ast_context_find_or_create(&local_contexts,cxt, registrar);
02286       if (con == NULL)
02287          continue;
02288 
02289       for (v = ast_variable_browse(cfg, cxt); v; v = v->next) {
02290          if (!strcasecmp(v->name, "exten")) {
02291             char *tc = ast_strdup(v->value);
02292             if (tc) {
02293                int ipri = -2;
02294                char realext[256]="";
02295                char *plus, *firstp, *firstc;
02296                char *pri, *appl, *data, *cidmatch;
02297                char *stringp = tc;
02298                char *ext = strsep(&stringp, ",");
02299                if (!ext)
02300                   ext="";
02301                pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1);
02302                cidmatch = strchr(realext, '/');
02303                if (cidmatch) {
02304                   *cidmatch++ = '\0';
02305                   ast_shrink_phone_number(cidmatch);
02306                }
02307                pri = strsep(&stringp, ",");
02308                if (!pri)
02309                   pri="";
02310                pri = ast_skip_blanks(pri);
02311                pri = ast_trim_blanks(pri);
02312                label = strchr(pri, '(');
02313                if (label) {
02314                   *label++ = '\0';
02315                   end = strchr(label, ')');
02316                   if (end)
02317                      *end = '\0';
02318                   else
02319                      ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno);
02320                }
02321                plus = strchr(pri, '+');
02322                if (plus)
02323                   *plus++ = '\0';
02324                if (!strcmp(pri,"hint"))
02325                   ipri=PRIORITY_HINT;
02326                else if (!strcmp(pri, "next") || !strcmp(pri, "n")) {
02327                   if (lastpri > -2)
02328                      ipri = lastpri + 1;
02329                   else
02330                      ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry!\n");
02331                } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) {
02332                   if (lastpri > -2)
02333                      ipri = lastpri;
02334                   else
02335                      ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry!\n");
02336                } else if (sscanf(pri, "%d", &ipri) != 1 &&
02337                    (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) {
02338                   ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno);
02339                   ipri = 0;
02340                }
02341                appl = S_OR(stringp, "");
02342                /* Find the first occurrence of either '(' or ',' */
02343                firstc = strchr(appl, ',');
02344                firstp = strchr(appl, '(');
02345                if (firstc && (!firstp || firstc < firstp)) {
02346                   /* comma found, no parenthesis */
02347                   /* or both found, but comma found first */
02348                   appl = strsep(&stringp, ",");
02349                   data = stringp;
02350                } else if (!firstc && !firstp) {
02351                   /* Neither found */
02352                   data = "";
02353                } else {
02354                   /* Final remaining case is parenthesis found first */
02355                   appl = strsep(&stringp, "(");
02356                   data = stringp;
02357                   end = strrchr(data, ')');
02358                   if ((end = strrchr(data, ')'))) {
02359                      *end = '\0';
02360                   } else {
02361                      ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s'\n", appl, data);
02362                   }
02363                   ast_process_quotes_and_slashes(data, ',', '|');
02364                }
02365 
02366                if (!data)
02367                   data="";
02368                appl = ast_skip_blanks(appl);
02369                if (ipri) {
02370                   if (plus)
02371                      ipri += atoi(plus);
02372                   lastpri = ipri;
02373                   if (!ast_opt_dont_warn && !strcmp(realext, "_."))
02374                      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);
02375                   if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free, registrar)) {
02376                      ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
02377                   }
02378                }
02379                free(tc);
02380             }
02381          } else if (!strcasecmp(v->name, "include")) {
02382             memset(realvalue, 0, sizeof(realvalue));
02383             pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
02384             if (ast_context_add_include2(con, realvalue, registrar))
02385                ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s'\n", v->value, cxt);
02386          } else if (!strcasecmp(v->name, "ignorepat")) {
02387             memset(realvalue, 0, sizeof(realvalue));
02388             pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
02389             if (ast_context_add_ignorepat2(con, realvalue, registrar))
02390                ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
02391          } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) {
02392             char *stringp= realvalue;
02393             char *appl, *data;
02394 
02395             memset(realvalue, 0, sizeof(realvalue));
02396             if (!strcasecmp(v->name, "switch"))
02397                pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
02398             else
02399                ast_copy_string(realvalue, v->value, sizeof(realvalue));
02400             appl = strsep(&stringp, "/");
02401             data = strsep(&stringp, ""); /* XXX what for ? */
02402             if (!data)
02403                data = "";
02404             if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar))
02405                ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt);
02406          }
02407       }
02408    }
02409    ast_config_destroy(cfg);
02410    return 1;
02411 }

static int pbx_load_module ( void   )  [static]

Definition at line 2528 of file pbx_config.c.

References ast_context_verify_includes(), ast_merge_contexts_and_delete(), AST_MODULE_LOAD_DECLINE, ast_walk_contexts(), autofallthrough_config, config, local_contexts, pbx_load_config(), pbx_load_users(), pbx_set_autofallthrough(), and registrar.

02529 {
02530    struct ast_context *con;
02531 
02532    if(!pbx_load_config(config))
02533       return AST_MODULE_LOAD_DECLINE;
02534    
02535    pbx_load_users();
02536 
02537    ast_merge_contexts_and_delete(&local_contexts, registrar);
02538 
02539    for (con = NULL; (con = ast_walk_contexts(con));)
02540       ast_context_verify_includes(con);
02541 
02542    pbx_set_autofallthrough(autofallthrough_config);
02543 
02544    return 0;
02545 }

static void pbx_load_users ( void   )  [static]

Definition at line 2425 of file pbx_config.c.

References append_interface(), ast_add_extension2(), ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_config_option(), ast_context_find_or_create(), ast_copy_string(), ast_free, ast_log(), ast_strlen_zero(), ast_true(), ast_variable_retrieve(), dahdi_chan_name, len(), local_contexts, LOG_ERROR, LOG_WARNING, registrar, strdup, and userscontext.

Referenced by pbx_load_module().

02426 {
02427    struct ast_config *cfg;
02428    char *cat, *chan;
02429    const char *dahdichan;
02430    const char *hasexten;
02431    char tmp[256];
02432    char iface[256];
02433    char zapcopy[256];
02434    char *c;
02435    int len;
02436    int hasvoicemail;
02437    int start, finish, x;
02438    struct ast_context *con = NULL;
02439    
02440    cfg = ast_config_load("users.conf");
02441    if (!cfg)
02442       return;
02443 
02444    for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
02445       if (!strcasecmp(cat, "general"))
02446          continue;
02447       iface[0] = '\0';
02448       len = sizeof(iface);
02449       if (ast_true(ast_config_option(cfg, cat, "hassip"))) {
02450          snprintf(tmp, sizeof(tmp), "SIP/%s", cat);
02451          append_interface(iface, sizeof(iface), tmp);
02452       }
02453       if (ast_true(ast_config_option(cfg, cat, "hasiax"))) {
02454          snprintf(tmp, sizeof(tmp), "IAX2/%s", cat);
02455          append_interface(iface, sizeof(iface), tmp);
02456       }
02457       if (ast_true(ast_config_option(cfg, cat, "hash323"))) {
02458          snprintf(tmp, sizeof(tmp), "H323/%s", cat);
02459          append_interface(iface, sizeof(iface), tmp);
02460       }
02461       hasexten = ast_config_option(cfg, cat, "hasexten");
02462       if (hasexten && !ast_true(hasexten))
02463          continue;
02464       hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail"));
02465       dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan");
02466       if (!dahdichan)
02467          dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan");
02468       if (!dahdichan) {
02469       /* no dahdichan, but look for zapchan too */
02470          dahdichan = ast_variable_retrieve(cfg, cat, "zapchan");
02471          if (!dahdichan) {
02472             dahdichan = ast_variable_retrieve(cfg, "general", "zapchan");
02473          }
02474          if (!ast_strlen_zero(dahdichan)) {
02475             ast_log(LOG_WARNING, "Use of zapchan in users.conf is deprecated. Please update configuration to use dahdichan instead.\n");
02476          }
02477       }
02478       if (!ast_strlen_zero(dahdichan)) {
02479          ast_copy_string(zapcopy, dahdichan, sizeof(zapcopy));
02480          c = zapcopy;
02481          chan = strsep(&c, ",");
02482          while (chan) {
02483             if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
02484                /* Range */
02485             } else if (sscanf(chan, "%d", &start)) {
02486                /* Just one */
02487                finish = start;
02488             } else {
02489                start = 0; finish = 0;
02490             }
02491             if (finish < start) {
02492                x = finish;
02493                finish = start;
02494                start = x;
02495             }
02496             for (x = start; x <= finish; x++) {
02497                snprintf(tmp, sizeof(tmp), "%s/%d", dahdi_chan_name, x);
02498                append_interface(iface, sizeof(iface), tmp);
02499             }
02500             chan = strsep(&c, ",");
02501          }
02502       }
02503       if (!ast_strlen_zero(iface)) {
02504          /* Only create a context here when it is really needed. Otherwise default empty context
02505          created by pbx_config may conflict with the one explicitly created by pbx_ael */
02506          if (!con)
02507             con = ast_context_find_or_create(&local_contexts, userscontext, registrar);
02508 
02509          if (!con) {
02510             ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext);
02511             return;
02512          }
02513 
02514          /* Add hint */
02515          ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar);
02516          /* If voicemail, use "stdexten" else use plain old dial */
02517          if (hasvoicemail) {
02518             snprintf(tmp, sizeof(tmp), "stdexten|%s|${HINT}", cat);
02519             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", strdup(tmp), ast_free, registrar);
02520          } else {
02521             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", strdup("${HINT}"), ast_free, registrar);
02522          }
02523       }
02524    }
02525    ast_config_destroy(cfg);
02526 }

static int reload ( void   )  [static]

Definition at line 2559 of file pbx_config.c.

References clearglobalvars_config, pbx_builtin_clear_globals(), and pbx_load_module().

02560 {
02561    if (clearglobalvars_config)
02562       pbx_builtin_clear_globals();
02563    pbx_load_module();
02564    return 0;
02565 }

static const char* skip_words ( const char *  p,
int  n 
) [static]

moves to the n-th word in the string, or empty string if none

Definition at line 187 of file pbx_config.c.

Referenced by complete_context_add_ignorepat(), complete_context_add_ignorepat_deprecated(), complete_context_add_include(), complete_context_add_include_deprecated(), complete_context_dont_include_deprecated(), complete_context_remove_extension(), complete_context_remove_extension_deprecated(), and complete_context_remove_include().

00188 {
00189    int in_blank = 0;
00190    for (;n && *p; p++) {
00191       if (isblank(*p) /* XXX order is important */ && !in_blank) {
00192          n--;  /* one word is gone */
00193          in_blank = 1;
00194       } else if (/* !is_blank(*p), we know already, && */ in_blank) {
00195          in_blank = 0;
00196       }
00197    }
00198    return p;
00199 }

static int split_ec ( const char *  src,
char **  ext,
char **const   ctx,
char **const   cid 
) [static]

split extension@context in two parts, return -1 on error. The return string is malloc'ed and pointed by *ext

Definition at line 210 of file pbx_config.c.

References ast_strdup, and free.

Referenced by complete_context_remove_extension(), complete_context_remove_extension_deprecated(), handle_context_remove_extension(), and handle_context_remove_extension_deprecated().

00211 {
00212    char *i, *c, *e = ast_strdup(src); /* now src is not used anymore */
00213 
00214    if (e == NULL)
00215       return -1;  /* malloc error */
00216    /* now, parse values from 'exten@context' */
00217    *ext = e;
00218    c = strchr(e, '@');
00219    if (c == NULL) /* no context part */
00220       *ctx = "";  /* it is not overwritten, anyways */
00221    else {   /* found context, check for duplicity ... */
00222       *c++ = '\0';
00223       *ctx = c;
00224       if (strchr(c, '@')) { /* two @, not allowed */
00225          free(e);
00226          return -1;
00227       }
00228    }
00229    if (cid && (i = strchr(e, '/'))) {
00230       *i++ = '\0';
00231       *cid = i;
00232    } else if (cid) {
00233       /* Signal none detected */
00234       *cid = NULL;
00235    }
00236    return 0;
00237 }

static int unload_module ( void   )  [static]

Standard module functions ...

Definition at line 2234 of file pbx_config.c.

References ast_cli_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), cli_dialplan_save, and cli_pbx_config.

02235 {
02236    if (static_config && !write_protect_config)
02237       ast_cli_unregister(&cli_dialplan_save);
02238    ast_cli_unregister_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
02239    ast_context_destroy(NULL, registrar);
02240    return 0;
02241 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Text Extension Configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 2571 of file pbx_config.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 2571 of file pbx_config.c.

int autofallthrough_config = 1 [static]

Definition at line 51 of file pbx_config.c.

Referenced by pbx_load_module().

int clearglobalvars_config = 0 [static]

Definition at line 52 of file pbx_config.c.

Referenced by reload().

struct ast_cli_entry cli_add_extension_deprecated [static]

Initial value:

Definition at line 2170 of file pbx_config.c.

struct ast_cli_entry cli_add_ignorepat_deprecated [static]

Initial value:

Definition at line 2175 of file pbx_config.c.

struct ast_cli_entry cli_dialplan_save [static]

Initial value:

 {
   { "dialplan", "save", NULL },
   handle_save_dialplan, "Save dialplan",
   save_dialplan_help, NULL, &cli_save_dialplan_deprecated }

Definition at line 2226 of file pbx_config.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_dont_include_deprecated [static]

Initial value:

CLI entries for commands provided by this module

Definition at line 2155 of file pbx_config.c.

struct ast_cli_entry cli_extensions_reload_deprecated [static]

Initial value:

 {
   { "extensions", "reload", NULL },
   handle_reload_extensions, NULL,
   NULL }

Definition at line 2185 of file pbx_config.c.

struct ast_cli_entry cli_include_context_deprecated [static]

Initial value:

 {
   { "include", "context", NULL },
   handle_context_add_include_deprecated, NULL,
   NULL, complete_context_add_include_deprecated }

Definition at line 2165 of file pbx_config.c.

struct ast_cli_entry cli_pbx_config[] [static]

Definition at line 2195 of file pbx_config.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_remove_extension_deprecated [static]

Initial value:

Definition at line 2160 of file pbx_config.c.

struct ast_cli_entry cli_remove_ignorepat_deprecated [static]

Initial value:

Definition at line 2180 of file pbx_config.c.

struct ast_cli_entry cli_save_dialplan_deprecated [static]

Initial value:

 {
   { "save", "dialplan", NULL },
   handle_save_dialplan, NULL,
   NULL }

Definition at line 2190 of file pbx_config.c.

char* config = "extensions.conf" [static]

Definition at line 45 of file pbx_config.c.

char context_add_extension_help[] [static]

Definition at line 61 of file pbx_config.c.

char context_add_ignorepat_help[] [static]

Initial value:

"Usage: dialplan add ignorepat <pattern> into <context>\n"
"       This command adds a new ignore pattern into context <context>\n"
"\n"
"Example: dialplan add ignorepat _3XX into local\n"

Definition at line 77 of file pbx_config.c.

char context_add_include_help[] [static]

Initial value:

"Usage: dialplan add include <context> into <context>\n"
"       Include a context in another context.\n"

Definition at line 89 of file pbx_config.c.

char context_remove_extension_help[] [static]

Initial value:

"Usage: dialplan remove extension exten[/cid]@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 71 of file pbx_config.c.

char context_remove_ignorepat_help[] [static]

Initial value:

"Usage: dialplan remove ignorepat <pattern> from <context>\n"
"       This command removes an ignore pattern from context <context>\n"
"\n"
"Example: dialplan remove ignorepat _3XX from local\n"

Definition at line 83 of file pbx_config.c.

char context_remove_include_help[] [static]

Initial value:

"Usage: dialplan remove include <context> from <context>\n"
"       Remove an included context from another context.\n"

Definition at line 93 of file pbx_config.c.

struct ast_context* local_contexts = NULL [static]

Definition at line 56 of file pbx_config.c.

Referenced by __ast_context_create(), pbx_load_config(), pbx_load_module(), and pbx_load_users().

char* registrar = "pbx_config" [static]

Definition at line 46 of file pbx_config.c.

char reload_extensions_help[] [static]

Initial value:

"Usage: dialplan reload\n"
"       reload extensions.conf without reloading any other modules\n"
"       This command does not delete global variables unless\n"
"       clearglobalvars is set to yes in extensions.conf\n"

Definition at line 104 of file pbx_config.c.

char save_dialplan_help[] [static]

Definition at line 97 of file pbx_config.c.

ast_mutex_t save_dialplan_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 54 of file pbx_config.c.

Referenced by handle_save_dialplan().

int static_config = 0 [static]

Definition at line 49 of file pbx_config.c.

Referenced by load_module().

char userscontext[AST_MAX_EXTENSION] = "default" [static]

Definition at line 47 of file pbx_config.c.

int write_protect_config = 1 [static]

Definition at line 50 of file pbx_config.c.

Referenced by load_module().


Generated on Thu May 14 15:13:38 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7