Wed Aug 18 22:34:29 2010

Asterisk developer's documentation


pbx_config.c File Reference

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

#include "asterisk.h"
#include <ctype.h>
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"

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_dialplan_add_extension (struct ast_cli_args *)
static char * complete_dialplan_add_ignorepat (struct ast_cli_args *)
static char * complete_dialplan_add_include (struct ast_cli_args *)
static char * complete_dialplan_remove_extension (struct ast_cli_args *)
static char * complete_dialplan_remove_ignorepat (struct ast_cli_args *)
static char * complete_dialplan_remove_include (struct ast_cli_args *)
static char * handle_cli_dialplan_add_extension (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 ADD EXTENSION command stuff.
static char * handle_cli_dialplan_add_ignorepat (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_add_include (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_remove_extension (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_remove_ignorepat (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_remove_include (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_save (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 '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 , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, }
static struct ast_module_infoast_module_info = &__mod_info
static int autofallthrough_config = 1
static int clearglobalvars_config = 0
static struct ast_cli_entry cli_dialplan_save
static struct ast_cli_entry cli_pbx_config []
static char * config = "extensions.conf"
static int extenpatternmatchnew_config = 0
static struct ast_contextlocal_contexts = NULL
static struct ast_hashtablocal_table = NULL
static char * overrideswitch_config = NULL
static char * registrar = "pbx_config"
static ast_mutex_t save_dialplan_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
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_cli_dialplan_save().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 1689 of file pbx_config.c.

static void __unreg_module ( void   )  [static]

Definition at line 1689 of file pbx_config.c.

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

Definition at line 1522 of file pbx_config.c.

References len().

Referenced by pbx_load_users().

01523 {
01524    int len = strlen(iface);
01525    if (strlen(add) + len < maxlen - 2) {
01526       if (strlen(iface)) {
01527          iface[len] = '&';
01528          strcpy(iface + len + 1, add);
01529       } else
01530          strcpy(iface, add);
01531    }
01532 }

static char * complete_dialplan_add_extension ( struct ast_cli_args a  )  [static]

dialplan add extension 6123,1,Dial,IAX/212.71.138.13/6123 into local

Definition at line 1015 of file pbx_config.c.

References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), len(), LOG_WARNING, ast_cli_args::n, partial_match(), ast_cli_args::pos, strdup, and ast_cli_args::word.

Referenced by handle_cli_dialplan_add_extension().

01016 {
01017    int which = 0;
01018 
01019    if (a->pos == 4) {      /* complete 'into' word ... */
01020       return (a->n == 0) ? strdup("into") : NULL;
01021    } else if (a->pos == 5) { /* complete context */
01022       struct ast_context *c = NULL;
01023       int len = strlen(a->word);
01024       char *res = NULL;
01025 
01026       /* try to lock contexts list ... */
01027       if (ast_rdlock_contexts()) {
01028          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01029          return NULL;
01030       }
01031 
01032       /* walk through all contexts */
01033       while ( !res && (c = ast_walk_contexts(c)) )
01034          if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n)
01035             res = strdup(ast_get_context_name(c));
01036       ast_unlock_contexts();
01037       return res;
01038    } else if (a->pos == 6) {
01039       return a->n == 0 ? strdup("replace") : NULL;
01040    }
01041    return NULL;
01042 }

static char * complete_dialplan_add_ignorepat ( struct ast_cli_args  )  [static]

Definition at line 1101 of file pbx_config.c.

References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), free, len(), ast_cli_args::line, LOG_ERROR, lookup_c_ip(), ast_cli_args::n, partial_match(), ast_cli_args::pos, s, skip_words(), strdup, strsep(), and ast_cli_args::word.

Referenced by handle_cli_dialplan_add_ignorepat().

01102 {
01103    if (a->pos == 4)
01104       return a->n == 0 ? strdup("into") : NULL;
01105    else if (a->pos == 5) {
01106       struct ast_context *c;
01107       int which = 0;
01108       char *dupline, *ignorepat = NULL;
01109       const char *s;
01110       char *ret = NULL;
01111       int len = strlen(a->word);
01112 
01113       /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */
01114       s = skip_words(a->line, 3);
01115       if (s == NULL)
01116          return NULL;
01117       dupline = strdup(s);
01118       if (!dupline) {
01119          ast_log(LOG_ERROR, "Malloc failure\n");
01120          return NULL;
01121       }
01122       ignorepat = strsep(&dupline, " ");
01123 
01124       if (ast_rdlock_contexts()) {
01125          ast_log(LOG_ERROR, "Failed to lock contexts list\n");
01126          return NULL;
01127       }
01128 
01129       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01130          int found = 0;
01131 
01132          if (!partial_match(ast_get_context_name(c), a->word, len))
01133             continue; /* not mine */
01134          if (ignorepat) /* there must be one, right ? */
01135             found = lookup_c_ip(c, ignorepat);
01136          if (!found && ++which > a->n)
01137             ret = strdup(ast_get_context_name(c));
01138       }
01139 
01140       free(ignorepat);
01141       ast_unlock_contexts();
01142       return ret;
01143    }
01144 
01145    return NULL;
01146 }

static char * complete_dialplan_add_include ( struct ast_cli_args  )  [static]

Definition at line 575 of file pbx_config.c.

References ast_get_context_name(), ast_log(), ast_rdlock_contexts(), ast_unlock_contexts(), ast_walk_contexts(), context, free, len(), ast_cli_args::line, LOG_ERROR, lookup_ci(), ast_cli_args::n, partial_match(), ast_cli_args::pos, s, skip_words(), strdup, strsep(), and ast_cli_args::word.

Referenced by handle_cli_dialplan_add_include().

00576 {
00577    struct ast_context *c;
00578    int which = 0;
00579    char *ret = NULL;
00580    int len = strlen(a->word);
00581 
00582    if (a->pos == 3) {      /* 'dialplan add include _X_' (context) ... */
00583       if (ast_rdlock_contexts()) {
00584          ast_log(LOG_ERROR, "Failed to lock context list\n");
00585          return NULL;
00586       }
00587       for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
00588          if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n)
00589             ret = strdup(ast_get_context_name(c));
00590       ast_unlock_contexts();
00591       return ret;
00592    } else if (a->pos == 4) { /* dialplan add include CTX _X_ */
00593       /* complete  as 'into' if context exists or we are unable to check */
00594       char *context, *dupline;
00595       const char *s = skip_words(a->line, 3); /* should not fail */
00596 
00597       if (a->n != 0) /* only once */
00598          return NULL;
00599 
00600       /* parse context from line ... */
00601       context = dupline = strdup(s);
00602       if (!context) {
00603          ast_log(LOG_ERROR, "Out of free memory\n");
00604          return strdup("into");
00605       }
00606       strsep(&dupline, " ");
00607 
00608       /* check for context existence ... */
00609       if (ast_rdlock_contexts()) {
00610          ast_log(LOG_ERROR, "Failed to lock context list\n");
00611          /* our fault, we can't check, so complete 'into' ... */
00612          ret = strdup("into");
00613       } else {
00614          struct ast_context *ctx;
00615          for (ctx = NULL; !ret && (ctx = ast_walk_contexts(ctx)); )
00616             if (!strcmp(context, ast_get_context_name(ctx)))
00617                ret = strdup("into"); /* found */
00618          ast_unlock_contexts();
00619       }
00620       free(context);
00621       return ret;
00622    } else if (a->pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */
00623       char *context, *dupline, *into;
00624       const char *s = skip_words(a->line, 3); /* should not fail */
00625       context = dupline = strdup(s);
00626       if (!dupline) {
00627          ast_log(LOG_ERROR, "Out of free memory\n");
00628          return NULL;
00629       }
00630       strsep(&dupline, " "); /* skip context */
00631       into = strsep(&dupline, " ");
00632       /* error if missing context or fifth word is not 'into' */
00633       if (!strlen(context) || strcmp(into, "into")) {
00634          ast_log(LOG_ERROR, "bad context %s or missing into %s\n",
00635             context, into);
00636          goto error3;
00637       }
00638 
00639       if (ast_rdlock_contexts()) {
00640          ast_log(LOG_ERROR, "Failed to lock context list\n");
00641          goto error3;
00642       }
00643 
00644       for (c = NULL; (c = ast_walk_contexts(c)); )
00645          if (!strcmp(context, ast_get_context_name(c)))
00646             break;
00647       if (c) { /* first context exists, go on... */
00648          /* go through all contexts ... */
00649          for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
00650             if (!strcmp(context, ast_get_context_name(c)))
00651                continue; /* skip ourselves */
00652             if (partial_match(ast_get_context_name(c), a->word, len) &&
00653                   !lookup_ci(c, context) /* not included yet */ &&
00654                   ++which > a->n)
00655                ret = strdup(ast_get_context_name(c));
00656          }
00657       } else {
00658          ast_log(LOG_ERROR, "context %s not found\n", context);
00659       }
00660       ast_unlock_contexts();
00661    error3:
00662       free(context);
00663       return ret;
00664    }
00665 
00666    return NULL;
00667 }

static char * complete_dialplan_remove_extension ( struct ast_cli_args  )  [static]

Definition at line 392 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(), ast_cli_args::line, LOG_ERROR, LOG_WARNING, ast_cli_args::n, partial_match(), ast_cli_args::pos, ast_exten::priority, s, skip_words(), split_ec(), strdup, and ast_cli_args::word.

Referenced by handle_cli_dialplan_remove_extension().

00393 {
00394    char *ret = NULL;
00395    int which = 0;
00396 
00397    if (a->pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */
00398       struct ast_context *c = NULL;
00399       char *context = NULL, *exten = NULL, *cid = NULL;
00400       int le = 0; /* length of extension */
00401       int lc = 0; /* length of context */
00402       int lcid = 0; /* length of cid */
00403 
00404       lc = split_ec(a->word, &exten, &context, &cid);
00405       if (lc)  { /* error */
00406          return NULL;
00407       }
00408       le = strlen(exten);
00409       lc = strlen(context);
00410       lcid = cid ? strlen(cid) : -1;
00411 
00412       if (ast_rdlock_contexts()) {
00413          ast_log(LOG_ERROR, "Failed to lock context list\n");
00414          goto error2;
00415       }
00416 
00417       /* find our context ... */
00418       while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */
00419          struct ast_exten *e = NULL;
00420          /* XXX locking ? */
00421          if (!partial_match(ast_get_context_name(c), context, lc))
00422             continue;   /* context not matched */
00423          while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */
00424             if ( !strchr(a->word, '/') ||
00425                   (!strchr(a->word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) ||
00426                   (strchr(a->word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) {
00427                if ( ((strchr(a->word, '/') || strchr(a->word, '@')) && !strcmp(ast_get_extension_name(e), exten)) ||
00428                    (!strchr(a->word, '/') && !strchr(a->word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */
00429                   if (++which > a->n) {
00430                      /* If there is an extension then return exten@context. */
00431                      if (ast_get_extension_matchcid(e) && (!strchr(a->word, '@') || strchr(a->word, '/'))) {
00432                         if (asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)) < 0) {
00433                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00434                            ret = NULL;
00435                         }
00436                         break;
00437                      } else if (!ast_get_extension_matchcid(e) && !strchr(a->word, '/')) {
00438                         if (asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) {
00439                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00440                            ret = NULL;
00441                         }
00442                         break;
00443                      }
00444                   }
00445                }
00446             }
00447          }
00448          if (e)   /* got a match */
00449             break;
00450       }
00451 
00452       ast_unlock_contexts();
00453    error2:
00454       free(exten);
00455    } else if (a->pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */
00456       char *exten = NULL, *context, *cid, *p;
00457       struct ast_context *c;
00458       int le, lc, lcid, len;
00459       const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'extension' */
00460       int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */
00461 
00462       if (i)   /* error */
00463          goto error3;
00464       if ( (p = strchr(exten, ' ')) ) /* remove space after extension */
00465          *p = '\0';
00466       if ( (p = strchr(context, ' ')) ) /* remove space after context */
00467          *p = '\0';
00468       le = strlen(exten);
00469       lc = strlen(context);
00470       lcid = strlen(cid);
00471       len = strlen(a->word);
00472       if (le == 0 || lc == 0)
00473          goto error3;
00474 
00475       if (ast_rdlock_contexts()) {
00476          ast_log(LOG_ERROR, "Failed to lock context list\n");
00477          goto error3;
00478       }
00479 
00480       /* walk contexts */
00481       c = NULL;
00482       while ( (c = ast_walk_contexts(c)) ) {
00483          /* XXX locking on c ? */
00484          struct ast_exten *e;
00485          if (strcmp(ast_get_context_name(c), context) != 0)
00486             continue;
00487          /* got it, we must match here */
00488          e = NULL;
00489          while ( (e = ast_walk_context_extensions(c, e)) ) {
00490             struct ast_exten *priority;
00491             char buffer[10];
00492 
00493             if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) {
00494                continue;
00495             }
00496             if (strcmp(ast_get_extension_name(e), exten) != 0)
00497                continue;
00498             /* XXX lock e ? */
00499             priority = NULL;
00500             while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) {
00501                snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority));
00502                if (partial_match(buffer, a->word, len) && ++which > a->n) /* n-th match */
00503                   ret = strdup(buffer);
00504             }
00505             break;
00506          }
00507          break;
00508       }
00509       ast_unlock_contexts();
00510    error3:
00511       free(exten);
00512    }
00513    return ret; 
00514 }

static char * complete_dialplan_remove_ignorepat ( struct ast_cli_args  )  [static]

Definition at line 1197 of file pbx_config.c.

References ast_get_context_name(), ast_get_ignorepat_name(), ast_log(), ast_rdlock_context(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_ignorepats(), ast_walk_contexts(), free, len(), ast_cli_args::line, LOG_WARNING, lookup_c_ip(), ast_cli_args::n, partial_match(), ast_cli_args::pos, strdup, strsep(), and ast_cli_args::word.

Referenced by handle_cli_dialplan_remove_ignorepat().

01198 {
01199    struct ast_context *c;
01200    int which = 0;
01201    char *ret = NULL;
01202 
01203    if (a->pos == 3) {
01204       int len = strlen(a->word);
01205       if (ast_rdlock_contexts()) {
01206          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01207          return NULL;
01208       }
01209 
01210       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01211          struct ast_ignorepat *ip;
01212 
01213          if (ast_rdlock_context(c)) /* error, skip it */
01214             continue;
01215          
01216          for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) {
01217             if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) {
01218                /* n-th match */
01219                struct ast_context *cw = NULL;
01220                int found = 0;
01221                while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) {
01222                   /* XXX do i stop on c, or skip it ? */
01223                   found = lookup_c_ip(cw, ast_get_ignorepat_name(ip));
01224                }
01225                if (!found)
01226                   ret = strdup(ast_get_ignorepat_name(ip));
01227             }
01228          }
01229          ast_unlock_context(c);
01230       }
01231       ast_unlock_contexts();
01232       return ret;
01233    } else if (a->pos == 4) {
01234        return a->n == 0 ? strdup("from") : NULL;
01235    } else if (a->pos == 5) { /* XXX check this */
01236       char *dupline, *duplinet, *ignorepat;
01237       int len = strlen(a->word);
01238 
01239       dupline = strdup(a->line);
01240       if (!dupline) {
01241          ast_log(LOG_WARNING, "Out of free memory\n");
01242          return NULL;
01243       }
01244 
01245       duplinet = dupline;
01246       strsep(&duplinet, " ");
01247       strsep(&duplinet, " ");
01248       ignorepat = strsep(&duplinet, " ");
01249 
01250       if (!ignorepat) {
01251          free(dupline);
01252          return NULL;
01253       }
01254 
01255       if (ast_rdlock_contexts()) {
01256          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01257          free(dupline);
01258          return NULL;
01259       }
01260 
01261       for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
01262          if (ast_rdlock_context(c)) /* fail, skip it */
01263             continue;
01264          if (!partial_match(ast_get_context_name(c), a->word, len))
01265             continue;
01266          if (lookup_c_ip(c, ignorepat) && ++which > a->n)
01267             ret = strdup(ast_get_context_name(c));
01268          ast_unlock_context(c);
01269       }
01270       ast_unlock_contexts();
01271       free(dupline);
01272       return NULL;
01273    }
01274 
01275    return NULL;
01276 }

static char * complete_dialplan_remove_include ( struct ast_cli_args  )  [static]

Definition at line 182 of file pbx_config.c.

References ast_get_context_name(), ast_get_include_name(), ast_log(), ast_rdlock_context(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_includes(), ast_walk_contexts(), ast_wrlock_contexts(), context, free, len(), ast_cli_args::line, LOG_ERROR, LOG_WARNING, lookup_ci(), ast_cli_args::n, partial_match(), ast_cli_args::pos, s, skip_words(), strdup, strsep(), and ast_cli_args::word.

Referenced by handle_cli_dialplan_remove_include().

00183 {
00184    int which = 0;
00185    char *res = NULL;
00186    int len = strlen(a->word); /* how many bytes to match */
00187    struct ast_context *c = NULL;
00188 
00189    if (a->pos == 3) {      /* "dialplan remove include _X_" */
00190       if (ast_wrlock_contexts()) {
00191          ast_log(LOG_ERROR, "Failed to lock context list\n");
00192          return NULL;
00193       }
00194       /* walk contexts and their includes, return the n-th match */
00195       while (!res && (c = ast_walk_contexts(c))) {
00196          struct ast_include *i = NULL;
00197 
00198          if (ast_rdlock_context(c)) /* error ? skip this one */
00199             continue;
00200 
00201          while ( !res && (i = ast_walk_context_includes(c, i)) ) {
00202             const char *i_name = ast_get_include_name(i);
00203             struct ast_context *nc = NULL;
00204             int already_served = 0;
00205 
00206             if (!partial_match(i_name, a->word, len))
00207                continue;   /* not matched */
00208 
00209             /* check if this include is already served or not */
00210 
00211             /* go through all contexts again till we reach actual
00212              * context or already_served = 1
00213              */
00214             while ( (nc = ast_walk_contexts(nc)) && nc != c && !already_served)
00215                already_served = lookup_ci(nc, i_name);
00216 
00217             if (!already_served && ++which > a->n)
00218                res = strdup(i_name);
00219          }
00220          ast_unlock_context(c);
00221       }
00222 
00223       ast_unlock_contexts();
00224       return res;
00225    } else if (a->pos == 4) { /* "dialplan remove include CTX _X_" */
00226       /*
00227        * complete as 'from', but only if previous context is really
00228        * included somewhere
00229        */
00230       char *context, *dupline;
00231       const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */
00232 
00233       if (a->n > 0)
00234          return NULL;
00235       context = dupline = strdup(s);
00236       if (!dupline) {
00237          ast_log(LOG_ERROR, "Out of free memory\n");
00238          return NULL;
00239       }
00240       strsep(&dupline, " ");
00241 
00242       if (ast_rdlock_contexts()) {
00243          ast_log(LOG_ERROR, "Failed to lock contexts list\n");
00244          free(context);
00245          return NULL;
00246       }
00247 
00248       /* go through all contexts and check if is included ... */
00249       while (!res && (c = ast_walk_contexts(c)))
00250          if (lookup_ci(c, context)) /* context is really included, complete "from" command */
00251             res = strdup("from");
00252       ast_unlock_contexts();
00253       if (!res)
00254          ast_log(LOG_WARNING, "%s not included anywhere\n", context);
00255       free(context);
00256       return res;
00257    } else if (a->pos == 5) { /* "dialplan remove include CTX from _X_" */
00258       /*
00259        * Context from which we removing include ... 
00260        */
00261       char *context, *dupline, *from;
00262       const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */
00263       context = dupline = strdup(s);
00264       if (!dupline) {
00265          ast_log(LOG_ERROR, "Out of free memory\n");
00266          return NULL;
00267       }
00268 
00269       strsep(&dupline, " "); /* skip context */
00270 
00271       /* fourth word must be 'from' */
00272       from = strsep(&dupline, " ");
00273       if (!from || strcmp(from, "from")) {
00274          free(context);
00275          return NULL;
00276       }
00277 
00278       if (ast_rdlock_contexts()) {
00279          ast_log(LOG_ERROR, "Failed to lock context list\n");
00280          free(context);
00281          return NULL;
00282       }
00283 
00284       /* walk through all contexts ... */
00285       c = NULL;
00286       while ( !res && (c = ast_walk_contexts(c))) {
00287          const char *c_name = ast_get_context_name(c);
00288          if (!partial_match(c_name, a->word, len)) /* not a good target */
00289             continue;
00290          /* walk through all includes and check if it is our context */ 
00291          if (lookup_ci(c, context) && ++which > a->n)
00292             res = strdup(c_name);
00293       }
00294       ast_unlock_contexts();
00295       free(context);
00296       return res;
00297    }
00298 
00299    return NULL;
00300 }

static char* handle_cli_dialplan_add_extension ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

ADD EXTENSION command stuff.

Definition at line 902 of file pbx_config.c.

References app, ast_cli_args::argc, ast_cli_args::argv, ast_add_extension(), ast_cli(), ast_free_ptr, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_extension(), errno, exten, ast_cli_args::fd, PRIORITY_HINT, strdup, strsep(), and ast_cli_entry::usage.

00903 {
00904    char *whole_exten;
00905    char *exten, *prior;
00906    int iprior = -2;
00907    char *cidmatch, *app, *app_data;
00908    char *start, *end;
00909 
00910    switch (cmd) {
00911    case CLI_INIT:
00912       e->command = "dialplan add extension";
00913       e->usage =
00914          "Usage: dialplan add extension <exten>,<priority>,<app>,<app-data>\n"
00915          "       into <context> [replace]\n\n"
00916          "       This command will add new extension into <context>. If there is an\n"
00917          "       existence of extension with the same priority and last 'replace'\n"
00918          "       arguments is given here we simply replace this extension.\n"
00919          "\n"
00920          "Example: dialplan add extension 6123,1,Dial,IAX/216.207.245.56/6123 into local\n"
00921          "         Now, you can dial 6123 and talk to Markster :)\n";
00922       return NULL;
00923    case CLI_GENERATE:
00924       return complete_dialplan_add_extension(a);
00925    }
00926 
00927    /* check for arguments at first */
00928    if (a->argc != 6 && a->argc != 7)
00929       return CLI_SHOWUSAGE;
00930    if (strcmp(a->argv[4], "into"))
00931       return CLI_SHOWUSAGE;
00932    if (a->argc == 7)
00933       if (strcmp(a->argv[6], "replace"))
00934          return CLI_SHOWUSAGE;
00935 
00936    /* XXX overwrite argv[3] */
00937    whole_exten = a->argv[3];
00938    exten = strsep(&whole_exten,",");
00939    if (strchr(exten, '/')) {
00940       cidmatch = exten;
00941       strsep(&cidmatch,"/");
00942    } else {
00943       cidmatch = NULL;
00944    }
00945    prior = strsep(&whole_exten,",");
00946    if (prior) {
00947       if (!strcmp(prior, "hint")) {
00948          iprior = PRIORITY_HINT;
00949       } else {
00950          if (sscanf(prior, "%30d", &iprior) != 1) {
00951             ast_cli(a->fd, "'%s' is not a valid priority\n", prior);
00952             prior = NULL;
00953          }
00954       }
00955    }
00956    app = whole_exten;
00957    if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) {
00958       *start = *end = '\0';
00959       app_data = start + 1;
00960    } else {
00961       if (app) {
00962          app_data = strchr(app, ',');
00963          if (app_data) {
00964             *app_data = '\0';
00965             app_data++;
00966          }
00967       } else   
00968          app_data = NULL;
00969    }
00970 
00971    if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT))
00972       return CLI_SHOWUSAGE;
00973 
00974    if (!app_data)
00975       app_data="";
00976    if (ast_add_extension(a->argv[5], a->argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
00977       (void *)strdup(app_data), ast_free_ptr, registrar)) {
00978       switch (errno) {
00979       case ENOMEM:
00980          ast_cli(a->fd, "Out of free memory\n");
00981          break;
00982 
00983       case EBUSY:
00984          ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
00985          break;
00986 
00987       case ENOENT:
00988          ast_cli(a->fd, "No existence of '%s' context\n", a->argv[5]);
00989          break;
00990 
00991       case EEXIST:
00992          ast_cli(a->fd, "Extension %s@%s with priority %s already exists\n",
00993             exten, a->argv[5], prior);
00994          break;
00995 
00996       default:
00997          ast_cli(a->fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n",
00998                exten, prior, app, app_data, a->argv[5]);
00999          break;
01000       }
01001       return CLI_FAILURE;
01002    }
01003 
01004    if (a->argc == 7)
01005       ast_cli(a->fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n",
01006          exten, a->argv[5], prior, exten, prior, app, app_data);
01007    else
01008       ast_cli(a->fd, "Extension '%s,%s,%s,%s' added into '%s' context\n",
01009          exten, prior, app, app_data, a->argv[5]);
01010 
01011    return CLI_SUCCESS;
01012 }

static char* handle_cli_dialplan_add_ignorepat ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

IGNOREPAT CLI stuff

Definition at line 1047 of file pbx_config.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_add_ignorepat(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_ignorepat(), errno, ast_cli_args::fd, and ast_cli_entry::usage.

01048 {
01049    switch (cmd) {
01050    case CLI_INIT:
01051       e->command = "dialplan add ignorepat";
01052       e->usage =
01053          "Usage: dialplan add ignorepat <pattern> into <context>\n"
01054          "       This command adds a new ignore pattern into context <context>\n"
01055          "\n"
01056          "Example: dialplan add ignorepat _3XX into local\n";
01057       return NULL;
01058    case CLI_GENERATE:
01059       return complete_dialplan_add_ignorepat(a);
01060    }
01061 
01062    if (a->argc != 6)
01063       return CLI_SHOWUSAGE;
01064 
01065    if (strcmp(a->argv[4], "into"))
01066       return CLI_SHOWUSAGE;
01067 
01068    if (ast_context_add_ignorepat(a->argv[5], a->argv[3], registrar)) {
01069       switch (errno) {
01070       case ENOMEM:
01071          ast_cli(a->fd, "Out of free memory\n");
01072          break;
01073 
01074       case ENOENT:
01075          ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]);
01076          break;
01077 
01078       case EEXIST:
01079          ast_cli(a->fd, "Ignore pattern '%s' already included in '%s' context\n",
01080             a->argv[3], a->argv[5]);
01081          break;
01082 
01083       case EBUSY:
01084          ast_cli(a->fd, "Failed to lock context(s) list, please, try again later\n");
01085          break;
01086 
01087       default:
01088          ast_cli(a->fd, "Failed to add ingore pattern '%s' into '%s' context\n",
01089             a->argv[3], a->argv[5]);
01090          break;
01091       }
01092       return CLI_FAILURE;
01093    }
01094 
01095    ast_cli(a->fd, "Ignore pattern '%s' added into '%s' context\n",
01096       a->argv[3], a->argv[5]);
01097 
01098    return CLI_SUCCESS;
01099 }

static char* handle_cli_dialplan_add_include ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Include context ...

Definition at line 519 of file pbx_config.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_add_include(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_include(), errno, ast_cli_args::fd, and ast_cli_entry::usage.

00520 {
00521    switch (cmd) {
00522    case CLI_INIT:
00523       e->command = "dialplan add include";
00524       e->usage =
00525          "Usage: dialplan add include <context> into <context>\n"
00526          "       Include a context in another context.\n";
00527       return NULL;
00528    case CLI_GENERATE:
00529       return complete_dialplan_add_include(a);
00530    }
00531 
00532    if (a->argc != 6) /* dialplan add include CTX in CTX */
00533       return CLI_SHOWUSAGE;
00534 
00535    /* fifth arg must be 'into' ... */
00536    if (strcmp(a->argv[4], "into"))
00537       return CLI_SHOWUSAGE;
00538 
00539    if (ast_context_add_include(a->argv[5], a->argv[3], registrar)) {
00540       switch (errno) {
00541       case ENOMEM:
00542          ast_cli(a->fd, "Out of memory for context addition\n");
00543          break;
00544 
00545       case EBUSY:
00546          ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
00547          break;
00548 
00549       case EEXIST:
00550          ast_cli(a->fd, "Context '%s' already included in '%s' context\n",
00551             a->argv[3], a->argv[5]);
00552          break;
00553 
00554       case ENOENT:
00555       case EINVAL:
00556          ast_cli(a->fd, "There is no existence of context '%s'\n",
00557             errno == ENOENT ? a->argv[5] : a->argv[3]);
00558          break;
00559 
00560       default:
00561          ast_cli(a->fd, "Failed to include '%s' in '%s' context\n",
00562             a->argv[3], a->argv[5]);
00563          break;
00564       }
00565       return CLI_FAILURE;
00566    }
00567 
00568    /* show some info ... */
00569    ast_cli(a->fd, "Context '%s' included in '%s' context\n",
00570       a->argv[3], a->argv[5]);
00571 
00572    return CLI_SUCCESS;
00573 }

static char* handle_cli_dialplan_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1280 of file pbx_config.c.

References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, pbx_builtin_clear_globals(), pbx_load_module(), and ast_cli_entry::usage.

01281 {
01282    switch (cmd) {
01283    case CLI_INIT:
01284       e->command = "dialplan reload";
01285       e->usage =
01286          "Usage: dialplan reload\n"
01287          "       Reload extensions.conf without reloading any other\n"
01288          "       modules.  This command does not delete global variables\n"
01289          "       unless clearglobalvars is set to yes in extensions.conf\n";
01290       return NULL;
01291    case CLI_GENERATE:
01292       return NULL;
01293    }
01294 
01295    if (a->argc != 2)
01296       return CLI_SHOWUSAGE;
01297 
01298    if (clearglobalvars_config)
01299       pbx_builtin_clear_globals();
01300 
01301    pbx_load_module();
01302    ast_cli(a->fd, "Dialplan reloaded.\n");
01303    return CLI_SUCCESS;
01304 }

static char* handle_cli_dialplan_remove_extension ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

REMOVE EXTENSION command stuff

Definition at line 305 of file pbx_config.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_remove_extension_callerid(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_remove_extension(), context, exten, ast_cli_args::fd, free, PRIORITY_HINT, split_ec(), and ast_cli_entry::usage.

00306 {
00307    int removing_priority = 0;
00308    char *exten, *context, *cid;
00309    char *ret = CLI_FAILURE;
00310 
00311    switch (cmd) {
00312    case CLI_INIT:
00313       e->command = "dialplan remove extension";
00314       e->usage =
00315          "Usage: dialplan remove extension exten[/cid]@context [priority]\n"
00316          "       Remove an extension from a given context. If a priority\n"
00317          "       is given, only that specific priority from the given extension\n"
00318          "       will be removed.\n";
00319       return NULL;
00320    case CLI_GENERATE:
00321       return complete_dialplan_remove_extension(a);
00322    }
00323 
00324    if (a->argc != 5 && a->argc != 4)
00325       return CLI_SHOWUSAGE;
00326 
00327    /*
00328     * Priority input checking ...
00329     */
00330    if (a->argc == 5) {
00331       char *c = a->argv[4];
00332 
00333       /* check for digits in whole parameter for right priority ...
00334        * why? because atoi (strtol) returns 0 if any characters in
00335        * string and whole extension will be removed, it's not good
00336        */
00337       if (!strcmp("hint", c))
00338          removing_priority = PRIORITY_HINT;
00339       else {
00340          while (*c && isdigit(*c))
00341             c++;
00342          if (*c) { /* non-digit in string */
00343             ast_cli(a->fd, "Invalid priority '%s'\n", a->argv[4]);
00344             return CLI_FAILURE;
00345          }
00346          removing_priority = atoi(a->argv[4]);
00347       }
00348 
00349       if (removing_priority == 0) {
00350          ast_cli(a->fd, "If you want to remove whole extension, please " \
00351             "omit priority argument\n");
00352          return CLI_FAILURE;
00353       }
00354    }
00355 
00356    /* XXX original overwrote argv[3] */
00357    /*
00358     * Format exten@context checking ...
00359     */
00360    if (split_ec(a->argv[3], &exten, &context, &cid))
00361       return CLI_FAILURE; /* XXX malloc failure */
00362    if ((!strlen(exten)) || (!(strlen(context)))) {
00363       ast_cli(a->fd, "Missing extension or context name in third argument '%s'\n",
00364          a->argv[3]);
00365       free(exten);
00366       return CLI_FAILURE;
00367    }
00368 
00369    if (!ast_context_remove_extension_callerid(context, exten, removing_priority,
00370          /* Do NOT substitute S_OR; it is NOT the same thing */
00371          cid ? cid : (removing_priority ? "" : NULL), cid ? 1 : 0, registrar)) {
00372       if (!removing_priority)
00373          ast_cli(a->fd, "Whole extension %s@%s removed\n",
00374             exten, context);
00375       else
00376          ast_cli(a->fd, "Extension %s@%s with priority %d removed\n",
00377             exten, context, removing_priority);
00378          
00379       ret = CLI_SUCCESS;
00380    } else {
00381       if (cid) {
00382          ast_cli(a->fd, "Failed to remove extension %s/%s@%s\n", exten, cid, context);
00383       } else {
00384          ast_cli(a->fd, "Failed to remove extension %s@%s\n", exten, context);
00385       }
00386       ret = CLI_FAILURE;
00387    }
00388    free(exten);
00389    return ret;
00390 }

static char* handle_cli_dialplan_remove_ignorepat ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1148 of file pbx_config.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_remove_ignorepat(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_remove_ignorepat(), errno, ast_cli_args::fd, and ast_cli_entry::usage.

01149 {
01150    switch (cmd) {
01151    case CLI_INIT:
01152       e->command = "dialplan remove ignorepat";
01153       e->usage =
01154          "Usage: dialplan remove ignorepat <pattern> from <context>\n"
01155          "       This command removes an ignore pattern from context <context>\n"
01156          "\n"
01157          "Example: dialplan remove ignorepat _3XX from local\n";
01158       return NULL;
01159    case CLI_GENERATE:
01160       return complete_dialplan_remove_ignorepat(a);
01161    }
01162 
01163    if (a->argc != 6)
01164       return CLI_SHOWUSAGE;
01165 
01166    if (strcmp(a->argv[4], "from"))
01167       return CLI_SHOWUSAGE;
01168 
01169    if (ast_context_remove_ignorepat(a->argv[5], a->argv[3], registrar)) {
01170       switch (errno) {
01171       case EBUSY:
01172          ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
01173          break;
01174 
01175       case ENOENT:
01176          ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]);
01177          break;
01178 
01179       case EINVAL:
01180          ast_cli(a->fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
01181                a->argv[3], a->argv[5]);
01182          break;
01183 
01184       default:
01185          ast_cli(a->fd, "Failed to remove ignore pattern '%s' from '%s' context\n",
01186                a->argv[3], a->argv[5]);
01187          break;
01188       }
01189       return CLI_FAILURE;
01190    }
01191 
01192    ast_cli(a->fd, "Ignore pattern '%s' removed from '%s' context\n",
01193       a->argv[3], a->argv[5]);
01194    return CLI_SUCCESS;
01195 }

static char* handle_cli_dialplan_remove_include ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

REMOVE INCLUDE command stuff

Definition at line 73 of file pbx_config.c.

References ast_cli_args::argv, ast_cli(), ast_context_remove_include(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_remove_include(), ast_cli_args::fd, and ast_cli_entry::usage.

00074 {
00075    switch (cmd) {
00076    case CLI_INIT:
00077       e->command = "dialplan remove include";
00078       e->usage =
00079          "Usage: dialplan remove include <context> from <context>\n"
00080          "       Remove an included context from another context.\n";
00081       return NULL;
00082    case CLI_GENERATE:
00083       return complete_dialplan_remove_include(a);
00084    }
00085 
00086    if (strcmp(a->argv[4], "from"))
00087       return CLI_SHOWUSAGE;
00088 
00089    if (!ast_context_remove_include(a->argv[5], a->argv[3], registrar)) {
00090       ast_cli(a->fd, "We are not including '%s' into '%s' now\n",
00091          a->argv[3], a->argv[5]);
00092       return CLI_SUCCESS;
00093    }
00094 
00095    ast_cli(a->fd, "Failed to remove '%s' include from '%s' context\n",
00096       a->argv[3], a->argv[5]);
00097    return CLI_FAILURE;
00098 }

static char* handle_cli_dialplan_save ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

'save dialplan' CLI command implementation functions ...

Definition at line 672 of file pbx_config.c.

References ast_cli_args::argc, ast_cli_args::argv, 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_mutex_lock(), ast_mutex_unlock(), ast_rdlock_context(), ast_rdlock_contexts(), ast_strlen_zero(), ast_unlock_context(), ast_unlock_contexts(), ast_variable_browse(), ast_walk_context_extensions(), ast_walk_context_ignorepats(), ast_walk_context_includes(), ast_walk_context_switches(), ast_walk_contexts(), ast_walk_extension_priorities(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, config_flags, el, ext, ast_cli_args::fd, ast_variable::name, ast_variable::next, overrideswitch, PRIORITY_HINT, PUT_CTX_HDR, save_dialplan_lock, ast_cli_entry::usage, and ast_variable::value.

00673 {
00674    char filename[256], overrideswitch[256] = "";
00675    struct ast_context *c;
00676    struct ast_config *cfg;
00677    struct ast_variable *v;
00678    int incomplete = 0; /* incomplete config write? */
00679    FILE *output;
00680    struct ast_flags config_flags = { 0 };
00681    const char *base, *slash, *file;
00682 
00683    switch (cmd) {
00684    case CLI_INIT:
00685       e->command = "dialplan save";
00686       e->usage =
00687          "Usage: dialplan save [/path/to/extension/file]\n"
00688          "       Save dialplan created by pbx_config module.\n"
00689          "\n"
00690          "Example: dialplan save                 (/etc/asterisk/extensions.conf)\n"
00691          "         dialplan save /home/markster  (/home/markster/extensions.conf)\n";
00692       return NULL;
00693    case CLI_GENERATE:
00694       return NULL;
00695    }
00696 
00697    if (! (static_config && !write_protect_config)) {
00698       ast_cli(a->fd,
00699          "I can't save dialplan now, see '%s' example file.\n",
00700          config);
00701       return CLI_FAILURE;
00702    }
00703 
00704    if (a->argc != 2 && a->argc != 3)
00705       return CLI_SHOWUSAGE;
00706 
00707    if (ast_mutex_lock(&save_dialplan_lock)) {
00708       ast_cli(a->fd,
00709          "Failed to lock dialplan saving (another proccess saving?)\n");
00710       return CLI_FAILURE;
00711    }
00712    /* XXX the code here is quite loose, a pathname with .conf in it
00713     * is assumed to be a complete pathname
00714     */
00715    if (a->argc == 3) {  /* have config path. Look for *.conf */
00716       base = a->argv[2];
00717       if (!strstr(a->argv[2], ".conf")) { /*no, this is assumed to be a pathname */
00718          /* if filename ends with '/', do not add one */
00719          slash = (*(a->argv[2] + strlen(a->argv[2]) -1) == '/') ? "/" : "";
00720          file = config; /* default: 'extensions.conf' */
00721       } else { /* yes, complete file name */
00722          slash = "";
00723          file = "";
00724       }
00725    } else {
00726       /* no config file, default one */
00727       base = ast_config_AST_CONFIG_DIR;
00728       slash = "/";
00729       file = config;
00730    }
00731    snprintf(filename, sizeof(filename), "%s%s%s", base, slash, config);
00732 
00733    cfg = ast_config_load("extensions.conf", config_flags);
00734 
00735    /* try to lock contexts list */
00736    if (ast_rdlock_contexts()) {
00737       ast_cli(a->fd, "Failed to lock contexts list\n");
00738       ast_mutex_unlock(&save_dialplan_lock);
00739       ast_config_destroy(cfg);
00740       return CLI_FAILURE;
00741    }
00742 
00743    /* create new file ... */
00744    if (!(output = fopen(filename, "wt"))) {
00745       ast_cli(a->fd, "Failed to create file '%s'\n",
00746          filename);
00747       ast_unlock_contexts();
00748       ast_mutex_unlock(&save_dialplan_lock);
00749       ast_config_destroy(cfg);
00750       return CLI_FAILURE;
00751    }
00752 
00753    /* fireout general info */
00754    if (overrideswitch_config) {
00755       snprintf(overrideswitch, sizeof(overrideswitch), "overrideswitch=%s\n", overrideswitch_config);
00756    }
00757    fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\n%sextenpatternmatchnew=%s\n\n",
00758       static_config ? "yes" : "no",
00759       write_protect_config ? "yes" : "no",
00760                 autofallthrough_config ? "yes" : "no",
00761             clearglobalvars_config ? "yes" : "no",
00762             overrideswitch_config ? overrideswitch : "",
00763             extenpatternmatchnew_config ? "yes" : "no");
00764 
00765    if ((v = ast_variable_browse(cfg, "globals"))) {
00766       fprintf(output, "[globals]\n");
00767       while(v) {
00768          fprintf(output, "%s => %s\n", v->name, v->value);
00769          v = v->next;
00770       }
00771       fprintf(output, "\n");
00772    }
00773 
00774    ast_config_destroy(cfg);
00775    
00776 #define PUT_CTX_HDR  do { \
00777    if (!context_header_written) {   \
00778       fprintf(output, "[%s]\n", ast_get_context_name(c));   \
00779       context_header_written = 1;   \
00780    }  \
00781    } while (0)
00782 
00783    /* walk all contexts */
00784    for (c = NULL; (c = ast_walk_contexts(c)); ) {
00785       int context_header_written = 0;
00786       struct ast_exten *ext, *last_written_e = NULL;
00787       struct ast_include *i;
00788       struct ast_ignorepat *ip;
00789       struct ast_sw *sw;
00790 
00791       /* try to lock context and fireout all info */  
00792       if (ast_rdlock_context(c)) { /* lock failure */
00793          incomplete = 1;
00794          continue;
00795       }
00796       /* registered by this module? */
00797       /* XXX do we need this ? */
00798       if (!strcmp(ast_get_context_registrar(c), registrar)) {
00799          fprintf(output, "[%s]\n", ast_get_context_name(c));
00800          context_header_written = 1;
00801       }
00802 
00803       /* walk extensions ... */
00804       for (ext = NULL; (ext = ast_walk_context_extensions(c, ext)); ) {
00805          struct ast_exten *p = NULL;
00806 
00807          /* fireout priorities */
00808          while ( (p = ast_walk_extension_priorities(ext, p)) ) {
00809             if (strcmp(ast_get_extension_registrar(p), registrar) != 0) /* not this source */
00810                continue;
00811       
00812             /* make empty line between different extensions */ 
00813             if (last_written_e != NULL &&
00814                    strcmp(ast_get_extension_name(last_written_e),
00815                       ast_get_extension_name(p)))
00816                fprintf(output, "\n");
00817             last_written_e = p;
00818          
00819             PUT_CTX_HDR;
00820 
00821             if (ast_get_extension_priority(p) == PRIORITY_HINT) { /* easy */
00822                fprintf(output, "exten => %s,hint,%s\n",
00823                       ast_get_extension_name(p),
00824                       ast_get_extension_app(p));
00825             } else {
00826                const char *sep, *cid;
00827                const char *el = ast_get_extension_label(p);
00828                char label[128] = "";
00829  
00830                if (ast_get_extension_matchcid(p)) {
00831                   sep = "/";
00832                   cid = ast_get_extension_cidmatch(p);
00833                } else
00834                   sep = cid = "";
00835             
00836                if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2)))
00837                   incomplete = 1;   /* error encountered or label > 125 chars */
00838                
00839                fprintf(output, "exten => %s%s%s,%d%s,%s(%s)\n",
00840                    ast_get_extension_name(p), (ast_strlen_zero(sep) ? "" : sep), (ast_strlen_zero(cid) ? "" : cid),
00841                    ast_get_extension_priority(p), label,
00842                    ast_get_extension_app(p), (ast_strlen_zero(ast_get_extension_app_data(p)) ? "" : (const char *)ast_get_extension_app_data(p)));
00843             }
00844          }
00845       }
00846 
00847       /* written any extensions? ok, write space between exten & inc */
00848       if (last_written_e)
00849          fprintf(output, "\n");
00850 
00851       /* walk through includes */
00852       for (i = NULL; (i = ast_walk_context_includes(c, i)) ; ) {
00853          if (strcmp(ast_get_include_registrar(i), registrar) != 0)
00854             continue; /* not mine */
00855          PUT_CTX_HDR;
00856          fprintf(output, "include => %s\n", ast_get_include_name(i));
00857       }
00858       if (ast_walk_context_includes(c, NULL))
00859          fprintf(output, "\n");
00860 
00861       /* walk through switches */
00862       for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) {
00863          if (strcmp(ast_get_switch_registrar(sw), registrar) != 0)
00864             continue; /* not mine */
00865          PUT_CTX_HDR;
00866          fprintf(output, "switch => %s/%s\n",
00867                 ast_get_switch_name(sw), ast_get_switch_data(sw));
00868       }
00869 
00870       if (ast_walk_context_switches(c, NULL))
00871          fprintf(output, "\n");
00872 
00873       /* fireout ignorepats ... */
00874       for (ip = NULL; (ip = ast_walk_context_ignorepats(c, ip)); ) {
00875          if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0)
00876             continue; /* not mine */
00877          PUT_CTX_HDR;
00878          fprintf(output, "ignorepat => %s\n",
00879                   ast_get_ignorepat_name(ip));
00880       }
00881 
00882       ast_unlock_context(c);
00883    }  
00884 
00885    ast_unlock_contexts();
00886    ast_mutex_unlock(&save_dialplan_lock);
00887    fclose(output);
00888 
00889    if (incomplete) {
00890       ast_cli(a->fd, "Saved dialplan is incomplete\n");
00891       return CLI_FAILURE;
00892    }
00893 
00894    ast_cli(a->fd, "Dialplan successfully saved into '%s'\n",
00895       filename);
00896    return CLI_SUCCESS;
00897 }

static int load_module ( void   )  [static]

Definition at line 1666 of file pbx_config.c.

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

01667 {
01668    if (pbx_load_module())
01669       return AST_MODULE_LOAD_DECLINE;
01670  
01671    if (static_config && !write_protect_config)
01672       ast_cli_register(&cli_dialplan_save);
01673    ast_cli_register_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
01674 
01675    return AST_MODULE_LOAD_SUCCESS;
01676 }

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

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

Referenced by complete_dialplan_add_ignorepat(), and complete_dialplan_remove_ignorepat().

00116 {
00117    struct ast_ignorepat *ip = NULL;
00118 
00119    if (ast_rdlock_context(c)) /* error, skip */
00120       return 0;
00121    while ( (ip = ast_walk_context_ignorepats(c, ip)) )
00122       if (!strcmp(name, ast_get_ignorepat_name(ip)))
00123          break;
00124    ast_unlock_context(c);
00125    return ip ? -1 /* success */ : 0;
00126 }

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

return true if 'name' is included by context c

Definition at line 101 of file pbx_config.c.

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

Referenced by complete_dialplan_add_include(), and complete_dialplan_remove_include().

00102 {
00103    struct ast_include *i = NULL;
00104 
00105    if (ast_rdlock_context(c)) /* error, skip */
00106       return 0;
00107    while ( (i = ast_walk_context_includes(c, i)) )
00108       if (!strcmp(name, ast_get_include_name(i)))
00109          break;
00110    ast_unlock_context(c);
00111    return i ? -1 /* success */ : 0;
00112 }

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

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

Definition at line 144 of file pbx_config.c.

Referenced by complete_dialplan_add_extension(), complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_ignorepat(), and complete_dialplan_remove_include().

00145 {
00146    return (len == 0 || !strncmp(s, word, len));
00147 }

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

Definition at line 1337 of file pbx_config.c.

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

Referenced by pbx_load_module().

01338 {
01339    struct ast_config *cfg;
01340    char *end;
01341    char *label;
01342 #ifdef LOW_MEMORY
01343    char realvalue[256];
01344 #else
01345    char realvalue[8192];
01346 #endif
01347    int lastpri = -2;
01348    struct ast_context *con;
01349    struct ast_variable *v;
01350    const char *cxt;
01351    const char *aft;
01352    const char *newpm, *ovsw;
01353    struct ast_flags config_flags = { 0 };
01354    cfg = ast_config_load(config_file, config_flags);
01355    if (!cfg)
01356       return 0;
01357 
01358    /* Use existing config to populate the PBX table */
01359    static_config = ast_true(ast_variable_retrieve(cfg, "general", "static"));
01360    write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect"));
01361    if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough")))
01362       autofallthrough_config = ast_true(aft);
01363    if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew")))
01364       extenpatternmatchnew_config = ast_true(newpm);
01365    clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars"));
01366    if ((ovsw = ast_variable_retrieve(cfg, "general", "overrideswitch"))) {
01367       if (overrideswitch_config) {
01368          ast_free(overrideswitch_config);
01369       }
01370       if (!ast_strlen_zero(ovsw)) {
01371          overrideswitch_config = ast_strdup(ovsw);
01372       } else {
01373          overrideswitch_config = NULL;
01374       }
01375    }
01376 
01377    if ((cxt = ast_variable_retrieve(cfg, "general", "userscontext"))) 
01378       ast_copy_string(userscontext, cxt, sizeof(userscontext));
01379    else
01380       ast_copy_string(userscontext, "default", sizeof(userscontext));
01381                             
01382    for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) {
01383       pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01384       pbx_builtin_setvar_helper(NULL, v->name, realvalue);
01385    }
01386    for (cxt = NULL; (cxt = ast_category_browse(cfg, cxt)); ) {
01387       /* All categories but "general" or "globals" are considered contexts */
01388       if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals"))
01389          continue;
01390       con=ast_context_find_or_create(&local_contexts, local_table, cxt, registrar);
01391       if (con == NULL)
01392          continue;
01393 
01394       for (v = ast_variable_browse(cfg, cxt); v; v = v->next) {
01395          if (!strcasecmp(v->name, "exten")) {
01396             char *tc = ast_strdup(v->value);
01397             if (tc) {
01398                int ipri = -2;
01399                char realext[256]="";
01400                char *plus, *firstp;
01401                char *pri, *appl, *data, *cidmatch;
01402                char *stringp = tc;
01403                char *ext = strsep(&stringp, ",");
01404                if (!ext)
01405                   ext="";
01406                pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1);
01407                cidmatch = strchr(realext, '/');
01408                if (cidmatch) {
01409                   *cidmatch++ = '\0';
01410                   ast_shrink_phone_number(cidmatch);
01411                }
01412                pri = strsep(&stringp, ",");
01413                if (!pri)
01414                   pri="";
01415                pri = ast_skip_blanks(pri);
01416                pri = ast_trim_blanks(pri);
01417                label = strchr(pri, '(');
01418                if (label) {
01419                   *label++ = '\0';
01420                   end = strchr(label, ')');
01421                   if (end)
01422                      *end = '\0';
01423                   else
01424                      ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno);
01425                }
01426                plus = strchr(pri, '+');
01427                if (plus)
01428                   *plus++ = '\0';
01429                if (!strcmp(pri,"hint"))
01430                   ipri=PRIORITY_HINT;
01431                else if (!strcmp(pri, "next") || !strcmp(pri, "n")) {
01432                   if (lastpri > -2)
01433                      ipri = lastpri + 1;
01434                   else
01435                      ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry!\n");
01436                } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) {
01437                   if (lastpri > -2)
01438                      ipri = lastpri;
01439                   else
01440                      ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry!\n");
01441                } else if (sscanf(pri, "%30d", &ipri) != 1 &&
01442                    (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) {
01443                   ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno);
01444                   ipri = 0;
01445                }
01446                appl = S_OR(stringp, "");
01447                /* Find the first occurrence of '(' */
01448                firstp = strchr(appl, '(');
01449                if (!firstp) {
01450                   /* No arguments */
01451                   data = "";
01452                } else {
01453                   char *orig_appl = ast_strdup(appl);
01454 
01455                   if (!orig_appl)
01456                      return -1;
01457 
01458                   appl = strsep(&stringp, "(");
01459 
01460                   /* check if there are variables or expressions without an application, like: exten => 100,hint,DAHDI/g0/${GLOBAL(var)}  */
01461                   if (strstr(appl, "${") || strstr(appl, "$[")){
01462                      /* set appl to original one */
01463                      strcpy(appl, orig_appl);
01464                      /* set no data */
01465                      data = "";
01466                   /* no variable before application found -> go ahead */
01467                   } else {
01468                      data = S_OR(stringp, "");
01469                      if ((end = strrchr(data, ')'))) {
01470                         *end = '\0';
01471                      } else {
01472                         ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s' at line %d\n", appl, data, v->lineno);
01473                      }
01474                   }
01475                   ast_free(orig_appl);
01476                }
01477 
01478                if (!data)
01479                   data = "";
01480                appl = ast_skip_blanks(appl);
01481                if (ipri) {
01482                   if (plus)
01483                      ipri += atoi(plus);
01484                   lastpri = ipri;
01485                   if (!ast_opt_dont_warn && !strcmp(realext, "_."))
01486                      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);
01487                   if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free_ptr, registrar)) {
01488                      ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
01489                   }
01490                }
01491                free(tc);
01492             }
01493          } else if (!strcasecmp(v->name, "include")) {
01494             pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01495             if (ast_context_add_include2(con, realvalue, registrar))
01496                ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s' at line %d\n", v->value, cxt, v->lineno);
01497          } else if (!strcasecmp(v->name, "ignorepat")) {
01498             pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01499             if (ast_context_add_ignorepat2(con, realvalue, registrar))
01500                ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s' at line %d\n", v->value, cxt, v->lineno);
01501          } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) {
01502             char *stringp = realvalue;
01503             char *appl, *data;
01504             
01505             if (!strcasecmp(v->name, "switch"))
01506                pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01507             else
01508                ast_copy_string(realvalue, v->value, sizeof(realvalue));
01509             appl = strsep(&stringp, "/");
01510             data = S_OR(stringp, "");
01511             if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar))
01512                ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s' at line %d\n", v->value, cxt, v->lineno);
01513          } else {
01514             ast_log(LOG_WARNING, "==!!== Unknown directive: %s at line %d -- IGNORING!!!\n", v->name, v->lineno);
01515          }
01516       }
01517    }
01518    ast_config_destroy(cfg);
01519    return 1;
01520 }

static int pbx_load_module ( void   )  [static]

Definition at line 1640 of file pbx_config.c.

References ast_context_verify_includes(), ast_hashtab_compare_contexts(), ast_hashtab_create(), ast_hashtab_hash_contexts(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), ast_merge_contexts_and_delete(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_walk_contexts(), autofallthrough_config, config, extenpatternmatchnew_config, local_contexts, local_table, overrideswitch_config, pbx_load_config(), pbx_load_users(), pbx_set_autofallthrough(), pbx_set_extenpatternmatchnew(), pbx_set_overrideswitch(), and registrar.

01641 {
01642    struct ast_context *con;
01643 
01644    if (!local_table)
01645       local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
01646 
01647    if (!pbx_load_config(config))
01648       return AST_MODULE_LOAD_DECLINE;
01649    
01650    pbx_load_users();
01651 
01652    ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
01653    local_table = NULL; /* the local table has been moved into the global one. */
01654    local_contexts = NULL;
01655 
01656    for (con = NULL; (con = ast_walk_contexts(con));)
01657       ast_context_verify_includes(con);
01658 
01659    pbx_set_overrideswitch(overrideswitch_config);
01660    pbx_set_autofallthrough(autofallthrough_config);
01661    pbx_set_extenpatternmatchnew(extenpatternmatchnew_config);
01662 
01663    return AST_MODULE_LOAD_SUCCESS;
01664 }

static void pbx_load_users ( void   )  [static]

Definition at line 1534 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(), chan, config_flags, ext, len(), local_contexts, local_table, LOG_ERROR, registrar, strdup, strsep(), and userscontext.

Referenced by pbx_load_module().

01535 {
01536    struct ast_config *cfg;
01537    char *cat, *chan;
01538    const char *dahdichan;
01539    const char *hasexten, *altexts;
01540    char tmp[256];
01541    char iface[256];
01542    char dahdicopy[256];
01543    char *ext, altcopy[256];
01544    char *c;
01545    int len;
01546    int hasvoicemail;
01547    int start, finish, x;
01548    struct ast_context *con = NULL;
01549    struct ast_flags config_flags = { 0 };
01550    
01551    cfg = ast_config_load("users.conf", config_flags);
01552    if (!cfg)
01553       return;
01554 
01555    for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
01556       if (!strcasecmp(cat, "general"))
01557          continue;
01558       iface[0] = '\0';
01559       len = sizeof(iface);
01560       if (ast_true(ast_config_option(cfg, cat, "hassip"))) {
01561          snprintf(tmp, sizeof(tmp), "SIP/%s", cat);
01562          append_interface(iface, sizeof(iface), tmp);
01563       }
01564       if (ast_true(ast_config_option(cfg, cat, "hasiax"))) {
01565          snprintf(tmp, sizeof(tmp), "IAX2/%s", cat);
01566          append_interface(iface, sizeof(iface), tmp);
01567       }
01568       if (ast_true(ast_config_option(cfg, cat, "hash323"))) {
01569          snprintf(tmp, sizeof(tmp), "H323/%s", cat);
01570          append_interface(iface, sizeof(iface), tmp);
01571       }
01572       hasexten = ast_config_option(cfg, cat, "hasexten");
01573       if (hasexten && !ast_true(hasexten))
01574          continue;
01575       hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail"));
01576       dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan");
01577       if (!dahdichan)
01578          dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan");
01579       if (!ast_strlen_zero(dahdichan)) {
01580          ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy));
01581          c = dahdicopy;
01582          chan = strsep(&c, ",");
01583          while (chan) {
01584             if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
01585                /* Range */
01586             } else if (sscanf(chan, "%30d", &start)) {
01587                /* Just one */
01588                finish = start;
01589             } else {
01590                start = 0; finish = 0;
01591             }
01592             if (finish < start) {
01593                x = finish;
01594                finish = start;
01595                start = x;
01596             }
01597             for (x = start; x <= finish; x++) {
01598                snprintf(tmp, sizeof(tmp), "DAHDI/%d", x);
01599                append_interface(iface, sizeof(iface), tmp);
01600             }
01601             chan = strsep(&c, ",");
01602          }
01603       }
01604       if (!ast_strlen_zero(iface)) {
01605          /* Only create a context here when it is really needed. Otherwise default empty context
01606          created by pbx_config may conflict with the one explicitly created by pbx_ael */
01607          if (!con)
01608             con = ast_context_find_or_create(&local_contexts, local_table, userscontext, registrar);
01609 
01610          if (!con) {
01611             ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext);
01612             return;
01613          }
01614 
01615          /* Add hint */
01616          ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar);
01617          /* If voicemail, use "stdexten" else use plain old dial */
01618          if (hasvoicemail) {
01619             snprintf(tmp, sizeof(tmp), "stdexten,%s,${HINT}", cat);
01620             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", strdup(tmp), ast_free_ptr, registrar);
01621          } else {
01622             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", strdup("${HINT}"), ast_free_ptr, registrar);
01623          }
01624          altexts = ast_variable_retrieve(cfg, cat, "alternateexts");
01625          if (!ast_strlen_zero(altexts)) {
01626             snprintf(tmp, sizeof(tmp), "%s,1", cat);
01627             ast_copy_string(altcopy, altexts, sizeof(altcopy));
01628             c = altcopy;
01629             ext = strsep(&c, ",");
01630             while (ext) {
01631                ast_add_extension2(con, 0, ext, 1, NULL, NULL, "Goto", strdup(tmp), ast_free_ptr, registrar);
01632                ext = strsep(&c, ",");
01633             }
01634          }
01635       }
01636    }
01637    ast_config_destroy(cfg);
01638 }

static int reload ( void   )  [static]

Definition at line 1678 of file pbx_config.c.

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

01679 {
01680    if (clearglobalvars_config)
01681       pbx_builtin_clear_globals();
01682    return pbx_load_module();
01683 }

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

Referenced by complete_dialplan_add_ignorepat(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), and complete_dialplan_remove_include().

00130 {
00131    int in_blank = 0;
00132    for (;n && *p; p++) {
00133       if (isblank(*p) /* XXX order is important */ && !in_blank) {
00134          n--;  /* one word is gone */
00135          in_blank = 1;
00136       } else if (/* !is_blank(*p), we know already, && */ in_blank) {
00137          in_blank = 0;
00138       }
00139    }
00140    return p;
00141 }

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

References ast_strdup, and free.

Referenced by complete_dialplan_remove_extension(), and handle_cli_dialplan_remove_extension().

00153 {
00154    char *i, *c, *e = ast_strdup(src); /* now src is not used anymore */
00155 
00156    if (e == NULL)
00157       return -1;  /* malloc error */
00158    /* now, parse values from 'exten@context' */
00159    *ext = e;
00160    c = strchr(e, '@');
00161    if (c == NULL) /* no context part */
00162       *ctx = "";  /* it is not overwritten, anyways */
00163    else {   /* found context, check for duplicity ... */
00164       *c++ = '\0';
00165       *ctx = c;
00166       if (strchr(c, '@')) { /* two @, not allowed */
00167          free(e);
00168          return -1;
00169       }
00170    }
00171    if (cid && (i = strchr(e, '/'))) {
00172       *i++ = '\0';
00173       *cid = i;
00174    } else if (cid) {
00175       /* Signal none detected */
00176       *cid = NULL;
00177    }
00178    return 0;
00179 }

static int unload_module ( void   )  [static]

Standard module functions ...

Definition at line 1325 of file pbx_config.c.

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

01326 {
01327    if (static_config && !write_protect_config)
01328       ast_cli_unregister(&cli_dialplan_save);
01329    if (overrideswitch_config) {
01330       ast_free(overrideswitch_config);
01331    }
01332    ast_cli_unregister_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
01333    ast_context_destroy(NULL, registrar);
01334    return 0;
01335 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 1689 of file pbx_config.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 1689 of file pbx_config.c.

int autofallthrough_config = 1 [static]

Definition at line 47 of file pbx_config.c.

Referenced by pbx_load_module().

int clearglobalvars_config = 0 [static]

Definition at line 48 of file pbx_config.c.

Referenced by reload().

struct ast_cli_entry cli_dialplan_save [static]

Initial value:

   { .handler =  handle_cli_dialplan_save , .summary =  "Save dialplan" ,__VA_ARGS__ }

Definition at line 1319 of file pbx_config.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_pbx_config[] [static]

CLI entries for commands provided by this module

Definition at line 1309 of file pbx_config.c.

Referenced by load_module(), and unload_module().

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

Definition at line 41 of file pbx_config.c.

int extenpatternmatchnew_config = 0 [static]

Definition at line 49 of file pbx_config.c.

Referenced by pbx_load_module().

struct ast_context* local_contexts = NULL [static]

Definition at line 54 of file pbx_config.c.

Referenced by ast_context_find_or_create(), lua_register_switches(), lua_reload_extensions(), pbx_load_config(), pbx_load_module(), and pbx_load_users().

struct ast_hashtab* local_table = NULL [static]

Definition at line 55 of file pbx_config.c.

Referenced by lua_register_switches(), lua_reload_extensions(), pbx_load_config(), pbx_load_module(), and pbx_load_users().

char* overrideswitch_config = NULL [static]

Definition at line 50 of file pbx_config.c.

Referenced by pbx_load_module().

char* registrar = "pbx_config" [static]

Definition at line 42 of file pbx_config.c.

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

Definition at line 52 of file pbx_config.c.

Referenced by handle_cli_dialplan_save().

int static_config = 0 [static]

Definition at line 45 of file pbx_config.c.

Referenced by load_module().

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

Definition at line 43 of file pbx_config.c.

int write_protect_config = 1 [static]

Definition at line 46 of file pbx_config.c.

Referenced by load_module().


Generated on Wed Aug 18 22:34:29 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7