Thu Oct 11 06:44:04 2012

Asterisk developer's documentation


pbx_config.c File Reference

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

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

Include dependency graph for pbx_config.c:

Go to the source code of this file.

Defines

#define 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 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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, }
static const struct
ast_module_info
ast_module_info = &__mod_info
static int autofallthrough_config = 1
static int clearglobalvars_config = 0
static struct ast_cli_entry cli_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 PUT_CTX_HDR

Referenced by handle_save_dialplan().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 2520 of file pbx_config.c.

static void __unreg_module ( void   )  [static]

Definition at line 2520 of file pbx_config.c.

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

Definition at line 2361 of file pbx_config.c.

References len().

Referenced by pbx_load_users().

02362 {
02363    int len = strlen(iface);
02364    if (strlen(add) + len < maxlen - 2) {
02365       if (strlen(iface)) {
02366          iface[len] = '&';
02367          strcpy(iface + len + 1, add);
02368       } else
02369          strcpy(iface, add);
02370    }
02371 }

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

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

01615 {
01616    int which = 0;
01617 
01618    if (pos == 4) {      /* complete 'into' word ... */
01619       return (state == 0) ? strdup("into") : NULL;
01620    } else if (pos == 5) { /* complete context */
01621       struct ast_context *c = NULL;
01622       int len = strlen(word);
01623       char *res = NULL;
01624 
01625       /* try to lock contexts list ... */
01626       if (ast_rdlock_contexts()) {
01627          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01628          return NULL;
01629       }
01630 
01631       /* walk through all contexts */
01632       while ( !res && (c = ast_walk_contexts(c)) )
01633          if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
01634             res = strdup(ast_get_context_name(c));
01635       ast_unlock_contexts();
01636       return res;
01637    } else if (pos == 6) {
01638       return state == 0 ? strdup("replace") : NULL;
01639    }
01640    return NULL;
01641 }

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

01586 {
01587    int which = 0;
01588 
01589    if (pos == 3) {      /* complete 'into' word ... */
01590       return (state == 0) ? strdup("into") : NULL;
01591    } else if (pos == 4) { /* complete context */
01592       struct ast_context *c = NULL;
01593       int len = strlen(word);
01594       char *res = NULL;
01595 
01596       /* try to lock contexts list ... */
01597       if (ast_rdlock_contexts()) {
01598          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01599          return NULL;
01600       }
01601 
01602       /* walk through all contexts */
01603       while ( !res && (c = ast_walk_contexts(c)) )
01604          if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
01605             res = strdup(ast_get_context_name(c));
01606       ast_unlock_contexts();
01607       return res;
01608    } else if (pos == 5) {
01609       return state == 0 ? strdup("replace") : NULL;
01610    }
01611    return NULL;
01612 }

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

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

01775 {
01776    if (pos == 4)
01777       return state == 0 ? strdup("into") : NULL;
01778    else if (pos == 5) {
01779       struct ast_context *c;
01780       int which = 0;
01781       char *dupline, *ignorepat = NULL;
01782       const char *s;
01783       char *ret = NULL;
01784       int len = strlen(word);
01785 
01786       /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */
01787       s = skip_words(line, 3);
01788       if (s == NULL)
01789          return NULL;
01790       dupline = strdup(s);
01791       if (!dupline) {
01792          ast_log(LOG_ERROR, "Malloc failure\n");
01793          return NULL;
01794       }
01795       ignorepat = strsep(&dupline, " ");
01796 
01797       if (ast_rdlock_contexts()) {
01798          ast_log(LOG_ERROR, "Failed to lock contexts list\n");
01799          return NULL;
01800       }
01801 
01802       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01803          int found = 0;
01804 
01805          if (!partial_match(ast_get_context_name(c), word, len))
01806             continue; /* not mine */
01807          if (ignorepat) /* there must be one, right ? */
01808             found = lookup_c_ip(c, ignorepat);
01809          if (!found && ++which > state)
01810             ret = strdup(ast_get_context_name(c));
01811       }
01812 
01813       if (ignorepat)
01814          free(ignorepat);
01815       ast_unlock_contexts();
01816       return ret;
01817    }
01818 
01819    return NULL;
01820 }

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

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

01726 {
01727    if (pos == 3)
01728       return state == 0 ? strdup("into") : NULL;
01729    else if (pos == 4) {
01730       struct ast_context *c;
01731       int which = 0;
01732       char *dupline, *ignorepat = NULL;
01733       const char *s;
01734       char *ret = NULL;
01735       int len = strlen(word);
01736 
01737       /* XXX skip first two words 'add' 'ignorepat' */
01738       s = skip_words(line, 2);
01739       if (s == NULL)
01740          return NULL;
01741       dupline = strdup(s);
01742       if (!dupline) {
01743          ast_log(LOG_ERROR, "Malloc failure\n");
01744          return NULL;
01745       }
01746       ignorepat = strsep(&dupline, " ");
01747 
01748       if (ast_rdlock_contexts()) {
01749          ast_log(LOG_ERROR, "Failed to lock contexts list\n");
01750          return NULL;
01751       }
01752 
01753       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01754          int found = 0;
01755 
01756          if (!partial_match(ast_get_context_name(c), word, len))
01757             continue; /* not mine */
01758          if (ignorepat) /* there must be one, right ? */
01759             found = lookup_c_ip(c, ignorepat);
01760          if (!found && ++which > state)
01761             ret = strdup(ast_get_context_name(c));
01762       }
01763 
01764       if (ignorepat)
01765          free(ignorepat);
01766       ast_unlock_contexts();
01767       return ret;
01768    }
01769 
01770    return NULL;
01771 }

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

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

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

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

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

00974 {
00975    struct ast_context *c;
00976    int which = 0;
00977    char *ret = NULL;
00978    int len = strlen(word);
00979 
00980    if (pos == 2) {      /* 'include context _X_' (context) ... */
00981       if (ast_rdlock_contexts()) {
00982          ast_log(LOG_ERROR, "Failed to lock context list\n");
00983          return NULL;
00984       }
00985       for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
00986          if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
00987             ret = strdup(ast_get_context_name(c));
00988       ast_unlock_contexts();
00989       return ret;
00990    } else if (pos == 3) { /* include context CTX _X_ */
00991       /* complete  as 'in' if context exists or we are unable to check */
00992       char *context, *dupline;
00993       struct ast_context *c;
00994       const char *s = skip_words(line, 2);   /* should not fail */
00995 
00996       if (state != 0)   /* only once */
00997          return NULL;
00998 
00999       /* parse context from line ... */
01000       context = dupline = strdup(s);
01001       if (!context) {
01002          ast_log(LOG_ERROR, "Out of free memory\n");
01003          return strdup("in");
01004       }
01005       strsep(&dupline, " ");
01006 
01007       /* check for context existence ... */
01008       if (ast_rdlock_contexts()) {
01009          ast_log(LOG_ERROR, "Failed to lock context list\n");
01010          /* our fault, we can't check, so complete 'in' ... */
01011          ret = strdup("in");
01012       } else {
01013          for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
01014             if (!strcmp(context, ast_get_context_name(c)))
01015                ret = strdup("in"); /* found */
01016          ast_unlock_contexts();
01017       }
01018       free(context);
01019       return ret;
01020    } else if (pos == 4) { /* 'include context CTX in _X_' (dst context) */
01021       char *context, *dupline, *in;
01022       const char *s = skip_words(line, 2); /* should not fail */
01023       context = dupline = strdup(s);
01024       if (!dupline) {
01025          ast_log(LOG_ERROR, "Out of free memory\n");
01026          return NULL;
01027       }
01028       strsep(&dupline, " "); /* skip context */
01029       in = strsep(&dupline, " ");
01030       /* error if missing context or third word is not 'in' */
01031       if (!strlen(context) || strcmp(in, "in")) {
01032          ast_log(LOG_ERROR, "bad context %s or missing in %s\n",
01033             context, in);
01034          goto error3;
01035       }
01036 
01037       if (ast_rdlock_contexts()) {
01038          ast_log(LOG_ERROR, "Failed to lock context list\n");
01039          goto error3;
01040       }
01041 
01042       for (c = NULL; (c = ast_walk_contexts(c)); )
01043          if (!strcmp(context, ast_get_context_name(c)))
01044             break;
01045       if (c) { /* first context exists, go on... */
01046          /* go through all contexts ... */
01047          for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
01048             if (!strcmp(context, ast_get_context_name(c)))
01049                continue; /* skip ourselves */
01050             if (partial_match(ast_get_context_name(c), word, len) &&
01051                   !lookup_ci(c, context) /* not included yet */ &&
01052                   ++which > state)
01053                ret = strdup(ast_get_context_name(c));
01054          }
01055       } else {
01056          ast_log(LOG_ERROR, "context %s not found\n", context);
01057       }
01058       ast_unlock_contexts();
01059    error3:
01060       free(context);
01061       return ret;
01062    }
01063 
01064    return NULL;
01065 }

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

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

00755 {
00756    char *ret = NULL;
00757    int which = 0;
00758 
00759    if (pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */
00760       struct ast_context *c = NULL;
00761       char *context = NULL, *exten = NULL, *cid = NULL;
00762       int le = 0; /* length of extension */
00763       int lc = 0; /* length of context */
00764       int lcid = 0; /* length of cid */
00765 
00766       lc = split_ec(word, &exten, &context, &cid);
00767       if (lc)  { /* error */
00768          return NULL;
00769       }
00770       le = strlen(exten);
00771       lc = strlen(context);
00772       lcid = cid ? strlen(cid) : -1;
00773 
00774       if (ast_rdlock_contexts()) {
00775          ast_log(LOG_ERROR, "Failed to lock context list\n");
00776          goto error2;
00777       }
00778 
00779       /* find our context ... */
00780       while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */
00781          struct ast_exten *e = NULL;
00782          /* XXX locking ? */
00783          if (!partial_match(ast_get_context_name(c), context, lc))
00784             continue;   /* context not matched */
00785          while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */
00786             if ( !strchr(word, '/') ||
00787                   (!strchr(word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) ||
00788                   (strchr(word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) {
00789                if ( ((strchr(word, '/') || strchr(word, '@')) && !strcmp(ast_get_extension_name(e), exten)) ||
00790                    (!strchr(word, '/') && !strchr(word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */
00791                   if (++which > state) {
00792                      /* If there is an extension then return exten@context. */
00793                      if (ast_get_extension_matchcid(e) && (!strchr(word, '@') || strchr(word, '/'))) {
00794                         if (asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)) < 0) {
00795                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00796                            ret = NULL;
00797                         }
00798                         break;
00799                      } else if (!ast_get_extension_matchcid(e) && !strchr(word, '/')) {
00800                         if (asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) {
00801                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00802                            ret = NULL;
00803                         }
00804                         break;
00805                      }
00806                   }
00807                }
00808             }
00809          }
00810          if (e)   /* got a match */
00811             break;
00812       }
00813       ast_unlock_contexts();
00814    error2:
00815       if (exten)
00816          free(exten);
00817    } else if (pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */
00818       char *exten = NULL, *context, *cid, *p;
00819       struct ast_context *c;
00820       int le, lc, lcid, len;
00821       const char *s = skip_words(line, 3); /* skip 'dialplan' 'remove' 'extension' */
00822       int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */
00823 
00824       if (i)   /* error */
00825          goto error3;
00826       if ( (p = strchr(exten, ' ')) ) /* remove space after extension */
00827          *p = '\0';
00828       if ( (p = strchr(context, ' ')) ) /* remove space after context */
00829          *p = '\0';
00830       le = strlen(exten);
00831       lc = strlen(context);
00832       lcid = cid ? strlen(cid) : -1;
00833       len = strlen(word);
00834       if (le == 0 || lc == 0)
00835          goto error3;
00836 
00837       if (ast_rdlock_contexts()) {
00838          ast_log(LOG_ERROR, "Failed to lock context list\n");
00839          goto error3;
00840       }
00841 
00842       /* walk contexts */
00843       c = NULL;
00844       while ( (c = ast_walk_contexts(c)) ) {
00845          /* XXX locking on c ? */
00846          struct ast_exten *e;
00847          if (strcmp(ast_get_context_name(c), context) != 0)
00848             continue;
00849          /* got it, we must match here */
00850          e = NULL;
00851          while ( (e = ast_walk_context_extensions(c, e)) ) {
00852             struct ast_exten *priority;
00853             char buffer[10];
00854 
00855             if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) {
00856                continue;
00857             }
00858             if (strcmp(ast_get_extension_name(e), exten) != 0)
00859                continue;
00860             /* XXX lock e ? */
00861             priority = NULL;
00862             while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) {
00863                snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority));
00864                if (partial_match(buffer, word, len) && ++which > state) /* n-th match */
00865                   ret = strdup(buffer);
00866             }
00867             break;
00868          }
00869          break;
00870       }
00871       ast_unlock_contexts();
00872    error3:
00873       if (exten)
00874          free(exten);
00875    }
00876    return ret; 
00877 }

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

Definition at line 623 of file pbx_config.c.

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

00625 {
00626    char *ret = NULL;
00627    int which = 0;
00628 
00629    if (pos == 2) { /* 'remove extension _X_' (exten/cid@context ... */
00630       struct ast_context *c = NULL;
00631       char *context = NULL, *exten = NULL, *cid = NULL;
00632       int le = 0; /* length of extension */
00633       int lc = 0; /* length of context */
00634       int lcid = 0; /* length of cid */
00635 
00636       lc = split_ec(word, &exten, &context, &cid);
00637       if (lc)  /* error */
00638          return NULL;
00639       le = strlen(exten);
00640       lc = strlen(context);
00641       lcid = cid ? strlen(cid) : -1;
00642 
00643       if (ast_rdlock_contexts()) {
00644          ast_log(LOG_ERROR, "Failed to lock context list\n");
00645          goto error2;
00646       }
00647 
00648       /* find our context ... */
00649       while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */
00650          struct ast_exten *e = NULL;
00651          /* XXX locking ? */
00652          if (!partial_match(ast_get_context_name(c), context, lc))
00653             continue;   /* context not matched */
00654          while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */
00655             if ( !strchr(word, '/') ||
00656                   (!strchr(word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) ||
00657                   (strchr(word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) {
00658                if ( ((strchr(word, '/') || strchr(word, '@')) && !strcmp(ast_get_extension_name(e), exten)) ||
00659                    (!strchr(word, '/') && !strchr(word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */
00660                   if (++which > state) {
00661                      /* If there is an extension then return exten@context. */
00662                      if (ast_get_extension_matchcid(e) && (!strchr(word, '@') || strchr(word, '/'))) {
00663                         if (asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)) < 0) {
00664                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00665                            ret = NULL;
00666                         }
00667                         break;
00668                      } else if (!ast_get_extension_matchcid(e) && !strchr(word, '/')) {
00669                         if (asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) {
00670                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00671                            ret = NULL;
00672                         }
00673                         break;
00674                      }
00675                   }
00676                }
00677             }
00678          }
00679          if (e)   /* got a match */
00680             break;
00681       }
00682 
00683       ast_unlock_contexts();
00684    error2:
00685       if (exten)
00686          free(exten);
00687    } else if (pos == 3) { /* 'remove extension EXT _X_' (priority) */
00688       char *exten = NULL, *context, *cid, *p;
00689       struct ast_context *c;
00690       int le, lc, lcid, len;
00691       const char *s = skip_words(line, 2); /* skip 'remove' 'extension' */
00692       int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */
00693 
00694       if (i)   /* error */
00695          goto error3;
00696       if ( (p = strchr(exten, ' ')) ) /* remove space after extension */
00697          *p = '\0';
00698       if ( (p = strchr(context, ' ')) ) /* remove space after context */
00699          *p = '\0';
00700       le = strlen(exten);
00701       lc = strlen(context);
00702       if (cid == NULL) {
00703          lcid = 0;
00704       } else {
00705          lcid = strlen(cid);
00706       }
00707       len = strlen(word);
00708       if (le == 0 || lc == 0)
00709          goto error3;
00710 
00711       if (ast_rdlock_contexts()) {
00712          ast_log(LOG_ERROR, "Failed to lock context list\n");
00713          goto error3;
00714       }
00715 
00716       /* walk contexts */
00717       c = NULL;
00718       while ( (c = ast_walk_contexts(c)) ) {
00719          /* XXX locking on c ? */
00720          struct ast_exten *e;
00721          if (strcmp(ast_get_context_name(c), context) != 0)
00722             continue;
00723          /* got it, we must match here */
00724          e = NULL;
00725          while ( (e = ast_walk_context_extensions(c, e)) ) {
00726             struct ast_exten *priority;
00727             char buffer[10];
00728 
00729             if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) {
00730                continue;
00731             }
00732             if (strcmp(ast_get_extension_name(e), exten) != 0)
00733                continue;
00734             /* XXX lock e ? */
00735             priority = NULL;
00736             while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) {
00737                snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority));
00738                if (partial_match(buffer, word, len) && ++which > state) /* n-th match */
00739                   ret = strdup(buffer);
00740             }
00741             break;
00742          }
00743          break;
00744       }
00745       ast_unlock_contexts();
00746    error3:
00747       if (exten)
00748          free(exten);
00749    }
00750    return ret; 
00751 }

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

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

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

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

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

01892 {
01893    struct ast_context *c;
01894    int which = 0;
01895    char *ret = NULL;
01896 
01897    if (pos == 2) {
01898       int len = strlen(word);
01899       if (ast_rdlock_contexts()) {
01900          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01901          return NULL;
01902       }
01903 
01904       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01905          struct ast_ignorepat *ip;
01906 
01907          if (ast_lock_context(c))   /* error, skip it */
01908             continue;
01909          
01910          for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) {
01911             if (partial_match(ast_get_ignorepat_name(ip), word, len) && ++which > state) {
01912                /* n-th match */
01913                struct ast_context *cw = NULL;
01914                int found = 0;
01915                while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) {
01916                   /* XXX do i stop on c, or skip it ? */
01917                   found = lookup_c_ip(cw, ast_get_ignorepat_name(ip));
01918                }
01919                if (!found)
01920                   ret = strdup(ast_get_ignorepat_name(ip));
01921             }
01922          }
01923          ast_unlock_context(c);
01924       }
01925       ast_unlock_contexts();
01926       return ret;
01927    } else if (pos == 3) {
01928        return state == 0 ? strdup("from") : NULL;
01929    } else if (pos == 4) { /* XXX check this */
01930       char *dupline, *duplinet, *ignorepat;
01931       int len = strlen(word);
01932 
01933       dupline = strdup(line);
01934       if (!dupline) {
01935          ast_log(LOG_WARNING, "Out of free memory\n");
01936          return NULL;
01937       }
01938 
01939       duplinet = dupline;
01940       strsep(&duplinet, " ");
01941       strsep(&duplinet, " ");
01942       ignorepat = strsep(&duplinet, " ");
01943 
01944       if (!ignorepat) {
01945          free(dupline);
01946          return NULL;
01947       }
01948 
01949       if (ast_rdlock_contexts()) {
01950          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01951          free(dupline);
01952          return NULL;
01953       }
01954 
01955       for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
01956          if (ast_lock_context(c))   /* fail, skip it */
01957             continue;
01958          if (!partial_match(ast_get_context_name(c), word, len))
01959             continue;
01960          if (lookup_c_ip(c, ignorepat) && ++which > state)
01961             ret = strdup(ast_get_context_name(c));
01962          ast_unlock_context(c);
01963       }
01964       ast_unlock_contexts();
01965       free(dupline);
01966       return NULL;
01967    }
01968 
01969    return NULL;
01970 }

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 handle_context_add_extension ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1490 of file pbx_config.c.

References app, ast_add_extension(), ast_cli(), ast_free_ptr, ast_process_quotes_and_slashes(), ast_exten::cidmatch, errno, exten, PRIORITY_HINT, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and strdup.

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

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

ADD EXTENSION command stuff.

Definition at line 1397 of file pbx_config.c.

References app, ast_add_extension(), ast_cli(), ast_free_ptr, ast_process_quotes_and_slashes(), ast_exten::cidmatch, errno, exten, PRIORITY_HINT, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and strdup.

01398 {
01399    char *whole_exten;
01400    char *exten, *prior;
01401    int iprior = -2;
01402    char *cidmatch, *app, *app_data;
01403    char *start, *end;
01404 
01405    /* check for arguments at first */
01406    if (argc != 5 && argc != 6)
01407       return RESULT_SHOWUSAGE;
01408    if (strcmp(argv[3], "into"))
01409       return RESULT_SHOWUSAGE;
01410    if (argc == 6) if (strcmp(argv[5], "replace")) return RESULT_SHOWUSAGE;
01411 
01412    /* XXX overwrite argv[2] */
01413    whole_exten = argv[2];
01414    exten    = strsep(&whole_exten,",");
01415    if (strchr(exten, '/')) {
01416       cidmatch = exten;
01417       strsep(&cidmatch,"/");
01418    } else {
01419       cidmatch = NULL;
01420    }
01421    prior       = strsep(&whole_exten,",");
01422    if (prior) {
01423       if (!strcmp(prior, "hint")) {
01424          iprior = PRIORITY_HINT;
01425       } else {
01426          if (sscanf(prior, "%30d", &iprior) != 1) {
01427             ast_cli(fd, "'%s' is not a valid priority\n", prior);
01428             prior = NULL;
01429          }
01430       }
01431    }
01432    app = whole_exten;
01433    if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) {
01434       *start = *end = '\0';
01435       app_data = start + 1;
01436       ast_process_quotes_and_slashes(app_data, ',', '|');
01437    } else {
01438       if (app) {
01439          app_data = strchr(app, ',');
01440          if (app_data) {
01441             *app_data = '\0';
01442             app_data++;
01443          }
01444       } else   
01445          app_data = NULL;
01446    }
01447 
01448    if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT))
01449       return RESULT_SHOWUSAGE;
01450 
01451    if (!app_data)
01452       app_data="";
01453    if (ast_add_extension(argv[4], argc == 6 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
01454       (void *)strdup(app_data), ast_free_ptr, registrar)) {
01455       switch (errno) {
01456       case ENOMEM:
01457          ast_cli(fd, "Out of free memory\n");
01458          break;
01459 
01460       case EBUSY:
01461          ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
01462          break;
01463 
01464       case ENOENT:
01465          ast_cli(fd, "No existence of '%s' context\n", argv[4]);
01466          break;
01467 
01468       case EEXIST:
01469          ast_cli(fd, "Extension %s@%s with priority %s already exists\n",
01470             exten, argv[4], prior);
01471          break;
01472 
01473       default:
01474          ast_cli(fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n",
01475                exten, prior, app, app_data, argv[4]);
01476          break;
01477       }
01478       return RESULT_FAILURE;
01479    }
01480 
01481    if (argc == 6) 
01482       ast_cli(fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n",
01483          exten, argv[4], prior, exten, prior, app, app_data);
01484    else
01485       ast_cli(fd, "Extension '%s,%s,%s,%s' added into '%s' context\n",
01486          exten, prior, app, app_data, argv[4]);
01487 
01488    return RESULT_SUCCESS;
01489 }

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

Definition at line 1685 of file pbx_config.c.

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

01686 {
01687    if (argc != 6)
01688       return RESULT_SHOWUSAGE;
01689    if (strcmp(argv[4], "into"))
01690       return RESULT_SHOWUSAGE;
01691 
01692    if (ast_context_add_ignorepat(argv[5], argv[3], registrar)) {
01693       switch (errno) {
01694       case ENOMEM:
01695          ast_cli(fd, "Out of free memory\n");
01696          break;
01697 
01698       case ENOENT:
01699          ast_cli(fd, "There is no existence of '%s' context\n", argv[5]);
01700          break;
01701 
01702       case EEXIST:
01703          ast_cli(fd, "Ignore pattern '%s' already included in '%s' context\n",
01704             argv[3], argv[5]);
01705          break;
01706 
01707       case EBUSY:
01708          ast_cli(fd, "Failed to lock context(s) list, please, try again later\n");
01709          break;
01710 
01711       default:
01712          ast_cli(fd, "Failed to add ingore pattern '%s' into '%s' context\n",
01713             argv[3], argv[5]);
01714          break;
01715       }
01716       return RESULT_FAILURE;
01717    }
01718 
01719    ast_cli(fd, "Ignore pattern '%s' added into '%s' context\n",
01720       argv[3], argv[5]);
01721    return RESULT_SUCCESS;
01722 }

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

IGNOREPAT CLI stuff

Definition at line 1646 of file pbx_config.c.

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

01647 {
01648    if (argc != 5)
01649       return RESULT_SHOWUSAGE;
01650    if (strcmp(argv[3], "into"))
01651       return RESULT_SHOWUSAGE;
01652 
01653    if (ast_context_add_ignorepat(argv[4], argv[2], registrar)) {
01654       switch (errno) {
01655       case ENOMEM:
01656          ast_cli(fd, "Out of free memory\n");
01657          break;
01658 
01659       case ENOENT:
01660          ast_cli(fd, "There is no existence of '%s' context\n", argv[4]);
01661          break;
01662 
01663       case EEXIST:
01664          ast_cli(fd, "Ignore pattern '%s' already included in '%s' context\n",
01665             argv[2], argv[4]);
01666          break;
01667 
01668       case EBUSY:
01669          ast_cli(fd, "Failed to lock context(s) list, please, try again later\n");
01670          break;
01671 
01672       default:
01673          ast_cli(fd, "Failed to add ingore pattern '%s' into '%s' context\n",
01674             argv[2], argv[4]);
01675          break;
01676       }
01677       return RESULT_FAILURE;
01678    }
01679 
01680    ast_cli(fd, "Ignore pattern '%s' added into '%s' context\n",
01681       argv[2], argv[4]);
01682    return RESULT_SUCCESS;
01683 }

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

Definition at line 927 of file pbx_config.c.

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

00928 {
00929    if (argc != 6) /* dialplan add include CTX in CTX */
00930       return RESULT_SHOWUSAGE;
00931 
00932    /* fifth arg must be 'into' ... */
00933    if (strcmp(argv[4], "into"))
00934       return RESULT_SHOWUSAGE;
00935 
00936    if (ast_context_add_include(argv[5], argv[3], registrar)) {
00937       switch (errno) {
00938       case ENOMEM:
00939          ast_cli(fd, "Out of memory for context addition\n");
00940          break;
00941 
00942       case EBUSY:
00943          ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
00944          break;
00945 
00946       case EEXIST:
00947          ast_cli(fd, "Context '%s' already included in '%s' context\n",
00948             argv[3], argv[5]);
00949          break;
00950 
00951       case ENOENT:
00952       case EINVAL:
00953          ast_cli(fd, "There is no existence of context '%s'\n",
00954             errno == ENOENT ? argv[5] : argv[3]);
00955          break;
00956 
00957       default:
00958          ast_cli(fd, "Failed to include '%s' in '%s' context\n",
00959             argv[3], argv[5]);
00960          break;
00961       }
00962       return RESULT_FAILURE;
00963    }
00964 
00965    /* show some info ... */
00966    ast_cli(fd, "Context '%s' included in '%s' context\n",
00967       argv[3], argv[5]);
00968 
00969    return RESULT_SUCCESS;
00970 }

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

Include context ...

Definition at line 882 of file pbx_config.c.

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

00883 {
00884    if (argc != 5) /* include context CTX in CTX */
00885       return RESULT_SHOWUSAGE;
00886 
00887    /* third arg must be 'in' ... */
00888    if (strcmp(argv[3], "in") && strcmp(argv[3], "into")) /* XXX why both ? */
00889       return RESULT_SHOWUSAGE;
00890 
00891    if (ast_context_add_include(argv[4], argv[2], registrar)) {
00892       switch (errno) {
00893       case ENOMEM:
00894          ast_cli(fd, "Out of memory for context addition\n");
00895          break;
00896 
00897       case EBUSY:
00898          ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
00899          break;
00900 
00901       case EEXIST:
00902          ast_cli(fd, "Context '%s' already included in '%s' context\n",
00903             argv[2], argv[4]);
00904          break;
00905 
00906       case ENOENT:
00907       case EINVAL:
00908          ast_cli(fd, "There is no existence of context '%s'\n",
00909             errno == ENOENT ? argv[4] : argv[2]);
00910          break;
00911 
00912       default:
00913          ast_cli(fd, "Failed to include '%s' in '%s' context\n",
00914             argv[2], argv[4]);
00915          break;
00916       }
00917       return RESULT_FAILURE;
00918    }
00919 
00920    /* show some info ... */
00921    ast_cli(fd, "Context '%s' included in '%s' context\n",
00922       argv[2], argv[4]);
00923 
00924    return RESULT_SUCCESS;
00925 }

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

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

01857 {
01858    if (argc != 6)
01859       return RESULT_SHOWUSAGE;
01860    if (strcmp(argv[4], "from"))
01861       return RESULT_SHOWUSAGE;
01862 
01863    if (ast_context_remove_ignorepat(argv[5], argv[3], registrar)) {
01864       switch (errno) {
01865       case EBUSY:
01866          ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
01867          break;
01868 
01869       case ENOENT:
01870          ast_cli(fd, "There is no existence of '%s' context\n", argv[5]);
01871          break;
01872 
01873       case EINVAL:
01874          ast_cli(fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
01875                argv[3], argv[5]);
01876          break;
01877 
01878       default:
01879          ast_cli(fd, "Failed to remove ignore pattern '%s' from '%s' context\n", argv[3], argv[5]);
01880          break;
01881       }
01882       return RESULT_FAILURE;
01883    }
01884 
01885    ast_cli(fd, "Ignore pattern '%s' removed from '%s' context\n",
01886       argv[3], argv[5]);
01887    return RESULT_SUCCESS;
01888 }

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

Definition at line 1822 of file pbx_config.c.

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

01823 {
01824    if (argc != 5)
01825       return RESULT_SHOWUSAGE;
01826    if (strcmp(argv[3], "from"))
01827       return RESULT_SHOWUSAGE;
01828 
01829    if (ast_context_remove_ignorepat(argv[4], argv[2], registrar)) {
01830       switch (errno) {
01831       case EBUSY:
01832          ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
01833          break;
01834 
01835       case ENOENT:
01836          ast_cli(fd, "There is no existence of '%s' context\n", argv[4]);
01837          break;
01838 
01839       case EINVAL:
01840          ast_cli(fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
01841                argv[2], argv[4]);
01842          break;
01843 
01844       default:
01845          ast_cli(fd, "Failed to remove ignore pattern '%s' from '%s' context\n", argv[2], argv[4]);
01846          break;
01847       }
01848       return RESULT_FAILURE;
01849    }
01850 
01851    ast_cli(fd, "Ignore pattern '%s' removed from '%s' context\n",
01852       argv[2], argv[4]);
01853    return RESULT_SUCCESS;
01854 }

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

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

02057 {
02058    if (argc != 2)
02059       return RESULT_SHOWUSAGE;
02060    if (clearglobalvars_config)
02061       pbx_builtin_clear_globals();
02062    pbx_load_module();
02063    ast_cli(fd, "Dialplan reloaded.\n");
02064    return RESULT_SUCCESS;
02065 }

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

'save dialplan' CLI command implementation functions ...

Definition at line 1165 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_exten::label, 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.

01166 {
01167    char filename[256];
01168    struct ast_context *c;
01169    struct ast_config *cfg;
01170    struct ast_variable *v;
01171    int incomplete = 0; /* incomplete config write? */
01172    FILE *output;
01173 
01174    const char *base, *slash, *file;
01175 
01176    if (! (static_config && !write_protect_config)) {
01177       ast_cli(fd,
01178          "I can't save dialplan now, see '%s' example file.\n",
01179          config);
01180       return RESULT_FAILURE;
01181    }
01182 
01183    if (argc != 2 && argc != 3)
01184       return RESULT_SHOWUSAGE;
01185 
01186    if (ast_mutex_lock(&save_dialplan_lock)) {
01187       ast_cli(fd,
01188          "Failed to lock dialplan saving (another proccess saving?)\n");
01189       return RESULT_FAILURE;
01190    }
01191    /* XXX the code here is quite loose, a pathname with .conf in it
01192     * is assumed to be a complete pathname
01193     */
01194    if (argc == 3) {  /* have config path. Look for *.conf */
01195       base = argv[2];
01196       if (!strstr(argv[2], ".conf")) { /*no, this is assumed to be a pathname */
01197          /* if filename ends with '/', do not add one */
01198          slash = (*(argv[2] + strlen(argv[2]) -1) == '/') ? "/" : "";
01199          file = config; /* default: 'extensions.conf' */
01200       } else { /* yes, complete file name */
01201          slash = "";
01202          file = "";
01203       }
01204    } else {
01205       /* no config file, default one */
01206       base = ast_config_AST_CONFIG_DIR;
01207       slash = "/";
01208       file = config;
01209    }
01210    snprintf(filename, sizeof(filename), "%s%s%s", base, slash, config);
01211 
01212    cfg = ast_config_load("extensions.conf");
01213 
01214    /* try to lock contexts list */
01215    if (ast_rdlock_contexts()) {
01216       ast_cli(fd, "Failed to lock contexts list\n");
01217       ast_mutex_unlock(&save_dialplan_lock);
01218       ast_config_destroy(cfg);
01219       return RESULT_FAILURE;
01220    }
01221 
01222    /* create new file ... */
01223    if (!(output = fopen(filename, "wt"))) {
01224       ast_cli(fd, "Failed to create file '%s'\n",
01225          filename);
01226       ast_unlock_contexts();
01227       ast_mutex_unlock(&save_dialplan_lock);
01228       ast_config_destroy(cfg);
01229       return RESULT_FAILURE;
01230    }
01231 
01232    /* fireout general info */
01233    fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\npriorityjumping=%s\n\n",
01234       static_config ? "yes" : "no",
01235       write_protect_config ? "yes" : "no",
01236                 autofallthrough_config ? "yes" : "no",
01237                 clearglobalvars_config ? "yes" : "no",
01238       ast_true(ast_variable_retrieve(cfg, "general", "priorityjumping")) ? "yes" : "no");
01239 
01240    if ((v = ast_variable_browse(cfg, "globals"))) {
01241       fprintf(output, "[globals]\n");
01242       while(v) {
01243          fprintf(output, "%s => %s\n", v->name, v->value);
01244          v = v->next;
01245       }
01246       fprintf(output, "\n");
01247    }
01248 
01249    ast_config_destroy(cfg);
01250    
01251 #define PUT_CTX_HDR  do { \
01252    if (!context_header_written) {   \
01253       fprintf(output, "[%s]\n", ast_get_context_name(c));   \
01254       context_header_written = 1;   \
01255    }  \
01256    } while (0)
01257 
01258    /* walk all contexts */
01259    for (c = NULL; (c = ast_walk_contexts(c)); ) {
01260       int context_header_written = 0;
01261       struct ast_exten *e, *last_written_e = NULL;
01262       struct ast_include *i;
01263       struct ast_ignorepat *ip;
01264       struct ast_sw *sw;
01265 
01266       /* try to lock context and fireout all info */  
01267       if (ast_lock_context(c)) { /* lock failure */
01268          incomplete = 1;
01269          continue;
01270       }
01271       /* registered by this module? */
01272       /* XXX do we need this ? */
01273       if (!strcmp(ast_get_context_registrar(c), registrar)) {
01274          fprintf(output, "[%s]\n", ast_get_context_name(c));
01275          context_header_written = 1;
01276       }
01277 
01278       /* walk extensions ... */
01279       for (e = NULL; (e = ast_walk_context_extensions(c, e)); ) {
01280          struct ast_exten *p = NULL;
01281 
01282          /* fireout priorities */
01283          while ( (p = ast_walk_extension_priorities(e, p)) ) {
01284             if (strcmp(ast_get_extension_registrar(p), registrar) != 0) /* not this source */
01285                continue;
01286       
01287             /* make empty line between different extensions */ 
01288             if (last_written_e != NULL &&
01289                    strcmp(ast_get_extension_name(last_written_e),
01290                       ast_get_extension_name(p)))
01291                fprintf(output, "\n");
01292             last_written_e = p;
01293          
01294             PUT_CTX_HDR;
01295 
01296             if (ast_get_extension_priority(p)==PRIORITY_HINT) { /* easy */
01297                fprintf(output, "exten => %s,hint,%s\n",
01298                       ast_get_extension_name(p),
01299                       ast_get_extension_app(p));
01300             } else { /* copy and replace '|' with ',' */
01301                const char *sep, *cid;
01302                char *tempdata = "";
01303                char *s;
01304                const char *el = ast_get_extension_label(p);
01305                char label[128] = "";
01306  
01307                s = ast_get_extension_app_data(p);
01308                if (s) {
01309                   char *t;
01310                   tempdata = alloca(strlen(tempdata) * 2 + 1);
01311 
01312                   for (t = tempdata; *s; s++, t++) {
01313                      if (*s == '|')
01314                         *t = ',';
01315                      else {
01316                         if (*s == ',' || *s == ';')
01317                            *t++ = '\\';
01318                         *t = *s;
01319                      }
01320                   }
01321                   /* Terminating NULL */
01322                   *t = *s;
01323                }
01324 
01325                if (ast_get_extension_matchcid(p)) {
01326                   sep = "/";
01327                   cid = ast_get_extension_cidmatch(p);
01328                } else
01329                   sep = cid = "";
01330             
01331                if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2)))
01332                   incomplete = 1;   /* error encountered or label > 125 chars */
01333                
01334                fprintf(output, "exten => %s%s%s,%d%s,%s(%s)\n",
01335                    ast_get_extension_name(p), (ast_strlen_zero(sep) ? "" : sep), (ast_strlen_zero(cid) ? "" : cid),
01336                    ast_get_extension_priority(p), label,
01337                    ast_get_extension_app(p), (ast_strlen_zero(tempdata) ? "" : tempdata));
01338             }
01339          }
01340       }
01341 
01342       /* written any extensions? ok, write space between exten & inc */
01343       if (last_written_e)
01344          fprintf(output, "\n");
01345 
01346       /* walk through includes */
01347       for (i = NULL; (i = ast_walk_context_includes(c, i)) ; ) {
01348          if (strcmp(ast_get_include_registrar(i), registrar) != 0)
01349             continue; /* not mine */
01350          PUT_CTX_HDR;
01351          fprintf(output, "include => %s\n", ast_get_include_name(i));
01352       }
01353       if (ast_walk_context_includes(c, NULL))
01354          fprintf(output, "\n");
01355 
01356       /* walk through switches */
01357       for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) {
01358          if (strcmp(ast_get_switch_registrar(sw), registrar) != 0)
01359             continue; /* not mine */
01360          PUT_CTX_HDR;
01361          fprintf(output, "switch => %s/%s\n",
01362                 ast_get_switch_name(sw), ast_get_switch_data(sw));
01363       }
01364 
01365       if (ast_walk_context_switches(c, NULL))
01366          fprintf(output, "\n");
01367 
01368       /* fireout ignorepats ... */
01369       for (ip = NULL; (ip = ast_walk_context_ignorepats(c, ip)); ) {
01370          if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0)
01371             continue; /* not mine */
01372          PUT_CTX_HDR;
01373          fprintf(output, "ignorepat => %s\n",
01374                   ast_get_ignorepat_name(ip));
01375       }
01376 
01377       ast_unlock_context(c);
01378    }  
01379 
01380    ast_unlock_contexts();
01381    ast_mutex_unlock(&save_dialplan_lock);
01382    fclose(output);
01383 
01384    if (incomplete) {
01385       ast_cli(fd, "Saved dialplan is incomplete\n");
01386       return RESULT_FAILURE;
01387    }
01388 
01389    ast_cli(fd, "Dialplan successfully saved into '%s'\n",
01390       filename);
01391    return RESULT_SUCCESS;
01392 }

static int load_module ( void   )  [static]

Definition at line 2495 of file pbx_config.c.

References ast_cli_register(), ast_cli_register_multiple(), AST_MODULE_LOAD_DECLINE, and pbx_load_module().

02496 {
02497 
02498    if (static_config && !write_protect_config)
02499       ast_cli_register(&cli_dialplan_save);
02500    ast_cli_register_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
02501 
02502    if (pbx_load_module())
02503       return AST_MODULE_LOAD_DECLINE;
02504 
02505    return 0;
02506 }

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]

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

Definition at line 2158 of file pbx_config.c.

References ast_add_extension2(), ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_find_or_create(), ast_copy_string(), ast_findlabel_extension2(), ast_free, ast_free_ptr, 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_strlen_zero(), ast_trim_blanks(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ext, free, ast_variable::lineno, 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().

02159 {
02160    struct ast_config *cfg;
02161    char *end;
02162    char *label;
02163 #ifdef LOW_MEMORY
02164    char realvalue[256];
02165 #else
02166    char realvalue[8192];
02167 #endif
02168    int lastpri = -2;
02169    struct ast_context *con;
02170    struct ast_variable *v;
02171    const char *cxt;
02172    const char *aft;
02173 
02174    cfg = ast_config_load(config_file);
02175    if (!cfg)
02176       return 0;
02177 
02178    /* Use existing config to populate the PBX table */
02179    static_config = ast_true(ast_variable_retrieve(cfg, "general", "static"));
02180    write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect"));
02181    if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough")))
02182       autofallthrough_config = ast_true(aft);
02183    clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars"));
02184    ast_set2_flag(&ast_options, ast_true(ast_variable_retrieve(cfg, "general", "priorityjumping")), AST_OPT_FLAG_PRIORITY_JUMPING);
02185 
02186    if ((cxt = ast_variable_retrieve(cfg, "general", "userscontext"))) 
02187       ast_copy_string(userscontext, cxt, sizeof(userscontext));
02188    else
02189       ast_copy_string(userscontext, "default", sizeof(userscontext));
02190                             
02191    for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) {
02192       memset(realvalue, 0, sizeof(realvalue));
02193       pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
02194       pbx_builtin_setvar_helper(NULL, v->name, realvalue);
02195    }
02196    for (cxt = NULL; (cxt = ast_category_browse(cfg, cxt)); ) {
02197       /* All categories but "general" or "globals" are considered contexts */
02198       if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals"))
02199          continue;
02200       con=ast_context_find_or_create(&local_contexts,cxt, registrar);
02201       if (con == NULL)
02202          continue;
02203 
02204       for (v = ast_variable_browse(cfg, cxt); v; v = v->next) {
02205          if (!strcasecmp(v->name, "exten")) {
02206             char *tc = ast_strdup(v->value);
02207             if (tc) {
02208                int ipri = -2;
02209                char realext[256]="";
02210                char *plus, *firstp, *firstc;
02211                char *pri, *appl, *data, *cidmatch;
02212                char *stringp = tc;
02213                char *ext = strsep(&stringp, ",");
02214                if (!ext) {
02215                   ast_log(LOG_WARNING, "Bogus extension at line %d\n", v->lineno);
02216                   ast_free(tc);
02217                   continue;
02218                }
02219                pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1);
02220                cidmatch = strchr(realext, '/');
02221                if (cidmatch) {
02222                   *cidmatch++ = '\0';
02223                   ast_shrink_phone_number(cidmatch);
02224                }
02225                pri = strsep(&stringp, ",");
02226                if (!pri) {
02227                   ast_log(LOG_WARNING, "Bogus extension at line %d\n", v->lineno);
02228                   ast_free(tc);
02229                   continue;
02230                }
02231                pri = ast_skip_blanks(pri);
02232                pri = ast_trim_blanks(pri);
02233                label = strchr(pri, '(');
02234                if (label) {
02235                   *label++ = '\0';
02236                   end = strchr(label, ')');
02237                   if (end)
02238                      *end = '\0';
02239                   else
02240                      ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno);
02241                }
02242                plus = strchr(pri, '+');
02243                if (plus) {
02244                   *plus++ = '\0';
02245                }
02246                if (!strcmp(pri, "hint")) {
02247                   ipri = PRIORITY_HINT;
02248                } else if (!strcmp(pri, "next") || !strcmp(pri, "n")) {
02249                   if (lastpri > -2) {
02250                      ipri = lastpri + 1;
02251                   } else {
02252                      ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry at line %d!\n", v->lineno);
02253                      ast_free(tc);
02254                      continue;
02255                   }
02256                } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) {
02257                   if (lastpri > -2) {
02258                      ipri = lastpri;
02259                   } else {
02260                      ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry at line %d!\n", v->lineno);
02261                      ast_free(tc);
02262                      continue;
02263                   }
02264                } else if (sscanf(pri, "%30d", &ipri) != 1 &&
02265                    (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) {
02266                   ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno);
02267                   ipri = 0;
02268                   ast_free(tc);
02269                   continue;
02270                }
02271                if (ast_strlen_zero(appl = S_OR(stringp, ""))) {
02272                   ast_log(LOG_WARNING, "Bogus extension at line %d\n", v->lineno);
02273                   ast_free(tc);
02274                   continue;
02275                }
02276                /* Find the first occurrence of either '(' or ',' */
02277                firstc = strchr(appl, ',');
02278                firstp = strchr(appl, '(');
02279                if (firstc && (!firstp || firstc < firstp)) {
02280                   /* comma found, no parenthesis */
02281                   /* or both found, but comma found first */
02282                   appl = strsep(&stringp, ",");
02283                   data = stringp;
02284                } else if (!firstc && !firstp) {
02285                   /* Neither found */
02286                   data = "";
02287                } else {
02288                   char *orig_appl = strdup(appl);
02289 
02290                   if (!orig_appl)
02291                      return -1;
02292 
02293                   /* Final remaining case is parenthesis found first */
02294                   appl = strsep(&stringp, "(");
02295 
02296                   /* check if there are variables or expressions without an application, like: exten => 100,hint,DAHDI/g0/${GLOBAL(var)} */
02297                   if (strstr(appl, "${") || strstr(appl, "$[")){
02298                      /* set appl to original one */
02299                      strcpy(appl, orig_appl);
02300                      data = "";
02301                   } else {
02302                      data = stringp;
02303                      end = strrchr(data, ')');
02304                      if ((end = strrchr(data, ')'))) {
02305                         *end = '\0';
02306                      } else {
02307                         ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s'\n", appl, data);
02308                      }
02309                      ast_process_quotes_and_slashes(data, ',', '|');
02310                   }
02311                   ast_free(orig_appl);
02312                }
02313 
02314                if (!data)
02315                   data="";
02316                appl = ast_skip_blanks(appl);
02317                if (ipri) {
02318                   if (plus)
02319                      ipri += atoi(plus);
02320                   lastpri = ipri;
02321                   if (!ast_opt_dont_warn && !strcmp(realext, "_."))
02322                      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);
02323                   if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free_ptr, registrar)) {
02324                      ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
02325                   }
02326                }
02327                free(tc);
02328             }
02329          } else if (!strcasecmp(v->name, "include")) {
02330             memset(realvalue, 0, sizeof(realvalue));
02331             pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
02332             if (ast_context_add_include2(con, realvalue, registrar))
02333                ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s'\n", v->value, cxt);
02334          } else if (!strcasecmp(v->name, "ignorepat")) {
02335             memset(realvalue, 0, sizeof(realvalue));
02336             pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
02337             if (ast_context_add_ignorepat2(con, realvalue, registrar))
02338                ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
02339          } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) {
02340             char *stringp= realvalue;
02341             char *appl, *data;
02342 
02343             memset(realvalue, 0, sizeof(realvalue));
02344             if (!strcasecmp(v->name, "switch"))
02345                pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
02346             else
02347                ast_copy_string(realvalue, v->value, sizeof(realvalue));
02348             appl = strsep(&stringp, "/");
02349             data = strsep(&stringp, ""); /* XXX what for ? */
02350             if (!data)
02351                data = "";
02352             if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar))
02353                ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt);
02354          }
02355       }
02356    }
02357    ast_config_destroy(cfg);
02358    return 1;
02359 }

static int pbx_load_module ( void   )  [static]

Definition at line 2476 of file pbx_config.c.

References ast_context_verify_includes(), ast_merge_contexts_and_delete(), AST_MODULE_LOAD_DECLINE, ast_walk_contexts(), pbx_load_config(), pbx_load_users(), and pbx_set_autofallthrough().

02477 {
02478    struct ast_context *con;
02479 
02480    if(!pbx_load_config(config))
02481       return AST_MODULE_LOAD_DECLINE;
02482    
02483    pbx_load_users();
02484 
02485    ast_merge_contexts_and_delete(&local_contexts, registrar);
02486 
02487    for (con = NULL; (con = ast_walk_contexts(con));)
02488       ast_context_verify_includes(con);
02489 
02490    pbx_set_autofallthrough(autofallthrough_config);
02491 
02492    return 0;
02493 }

static void pbx_load_users ( void   )  [static]

Definition at line 2373 of file pbx_config.c.

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

Referenced by pbx_load_module().

02374 {
02375    struct ast_config *cfg;
02376    char *cat, *chan;
02377    const char *dahdichan;
02378    const char *hasexten;
02379    char tmp[256];
02380    char iface[256];
02381    char zapcopy[256];
02382    char *c;
02383    int len;
02384    int hasvoicemail;
02385    int start, finish, x;
02386    struct ast_context *con = NULL;
02387    
02388    cfg = ast_config_load("users.conf");
02389    if (!cfg)
02390       return;
02391 
02392    for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
02393       if (!strcasecmp(cat, "general"))
02394          continue;
02395       iface[0] = '\0';
02396       len = sizeof(iface);
02397       if (ast_true(ast_config_option(cfg, cat, "hassip"))) {
02398          snprintf(tmp, sizeof(tmp), "SIP/%s", cat);
02399          append_interface(iface, sizeof(iface), tmp);
02400       }
02401       if (ast_true(ast_config_option(cfg, cat, "hasiax"))) {
02402          snprintf(tmp, sizeof(tmp), "IAX2/%s", cat);
02403          append_interface(iface, sizeof(iface), tmp);
02404       }
02405       if (ast_true(ast_config_option(cfg, cat, "hash323"))) {
02406          snprintf(tmp, sizeof(tmp), "H323/%s", cat);
02407          append_interface(iface, sizeof(iface), tmp);
02408       }
02409       hasexten = ast_config_option(cfg, cat, "hasexten");
02410       if (hasexten && !ast_true(hasexten))
02411          continue;
02412       hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail"));
02413       dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan");
02414       if (!dahdichan)
02415          dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan");
02416       if (!dahdichan) {
02417       /* no dahdichan, but look for zapchan too */
02418          dahdichan = ast_variable_retrieve(cfg, cat, "zapchan");
02419          if (!dahdichan) {
02420             dahdichan = ast_variable_retrieve(cfg, "general", "zapchan");
02421          }
02422          if (!ast_strlen_zero(dahdichan)) {
02423             ast_log(LOG_WARNING, "Use of zapchan in users.conf is deprecated. Please update configuration to use dahdichan instead.\n");
02424          }
02425       }
02426       if (!ast_strlen_zero(dahdichan)) {
02427          ast_copy_string(zapcopy, dahdichan, sizeof(zapcopy));
02428          c = zapcopy;
02429          chan = strsep(&c, ",");
02430          while (chan) {
02431             if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
02432                /* Range */
02433             } else if (sscanf(chan, "%30d", &start)) {
02434                /* Just one */
02435                finish = start;
02436             } else {
02437                start = 0; finish = 0;
02438             }
02439             if (finish < start) {
02440                x = finish;
02441                finish = start;
02442                start = x;
02443             }
02444             for (x = start; x <= finish; x++) {
02445                snprintf(tmp, sizeof(tmp), "%s/%d", dahdi_chan_name, x);
02446                append_interface(iface, sizeof(iface), tmp);
02447             }
02448             chan = strsep(&c, ",");
02449          }
02450       }
02451       if (!ast_strlen_zero(iface)) {
02452          /* Only create a context here when it is really needed. Otherwise default empty context
02453          created by pbx_config may conflict with the one explicitly created by pbx_ael */
02454          if (!con)
02455             con = ast_context_find_or_create(&local_contexts, userscontext, registrar);
02456 
02457          if (!con) {
02458             ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext);
02459             return;
02460          }
02461 
02462          /* Add hint */
02463          ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar);
02464          /* If voicemail, use "stdexten" else use plain old dial */
02465          if (hasvoicemail) {
02466             snprintf(tmp, sizeof(tmp), "stdexten|%s|${HINT}", cat);
02467             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", strdup(tmp), ast_free_ptr, registrar);
02468          } else {
02469             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", strdup("${HINT}"), ast_free_ptr, registrar);
02470          }
02471       }
02472    }
02473    ast_config_destroy(cfg);
02474 }

static int reload ( void   )  [static]

Definition at line 2508 of file pbx_config.c.

References pbx_builtin_clear_globals(), and pbx_load_module().

02509 {
02510    if (clearglobalvars_config)
02511       pbx_builtin_clear_globals();
02512    pbx_load_module();
02513    return 0;
02514 }

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

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

02150 {
02151    if (static_config && !write_protect_config)
02152       ast_cli_unregister(&cli_dialplan_save);
02153    ast_cli_unregister_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
02154    ast_context_destroy(NULL, registrar);
02155    return 0;
02156 }


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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 2520 of file pbx_config.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 2520 of file pbx_config.c.

int autofallthrough_config = 1 [static]

Definition at line 51 of file pbx_config.c.

int clearglobalvars_config = 0 [static]

Definition at line 52 of file pbx_config.c.

Initial value:

Definition at line 2085 of file pbx_config.c.

Initial value:

Definition at line 2090 of file pbx_config.c.

Initial value:

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

Definition at line 2141 of file pbx_config.c.

Initial value:

CLI entries for commands provided by this module

Definition at line 2070 of file pbx_config.c.

Initial value:

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

Definition at line 2100 of file pbx_config.c.

Initial value:

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

Definition at line 2080 of file pbx_config.c.

struct ast_cli_entry cli_pbx_config[] [static]

Definition at line 2110 of file pbx_config.c.

Initial value:

Definition at line 2075 of file pbx_config.c.

Initial value:

Definition at line 2095 of file pbx_config.c.

Initial value:

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

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

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.

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

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.

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.


Generated on Thu Oct 11 06:44:04 2012 for Asterisk - the Open Source PBX by  doxygen 1.5.6