Wed Oct 28 13:33:16 2009

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"

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_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 char * pbx_strsep (char **destructible, const char *delim)
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 = AST_BUILDOPT_SUM, .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_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


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 1746 of file pbx_config.c.

static void __unreg_module ( void   )  [static]

Definition at line 1746 of file pbx_config.c.

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

Definition at line 1579 of file pbx_config.c.

References len().

Referenced by pbx_load_users().

01580 {
01581    int len = strlen(iface);
01582    if (strlen(add) + len < maxlen - 2) {
01583       if (strlen(iface)) {
01584          iface[len] = '&';
01585          strcpy(iface + len + 1, add);
01586       } else
01587          strcpy(iface, add);
01588    }
01589 }

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 1014 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().

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

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

Definition at line 1100 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().

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

static char * complete_dialplan_add_include ( struct ast_cli_args a  )  [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 a  )  [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 a  )  [static]

Definition at line 1196 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().

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

static char * complete_dialplan_remove_include ( struct ast_cli_args a  )  [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, ast_strdupa, ast_exten::cidmatch, 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    whole_exten = ast_strdupa(a->argv[3]);
00937    exten = strsep(&whole_exten,",");
00938    if (strchr(exten, '/')) {
00939       cidmatch = exten;
00940       strsep(&cidmatch,"/");
00941    } else {
00942       cidmatch = NULL;
00943    }
00944    prior = strsep(&whole_exten,",");
00945    if (prior) {
00946       if (!strcmp(prior, "hint")) {
00947          iprior = PRIORITY_HINT;
00948       } else {
00949          if (sscanf(prior, "%30d", &iprior) != 1) {
00950             ast_cli(a->fd, "'%s' is not a valid priority\n", prior);
00951             prior = NULL;
00952          }
00953       }
00954    }
00955    app = whole_exten;
00956    if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) {
00957       *start = *end = '\0';
00958       app_data = start + 1;
00959    } else {
00960       if (app) {
00961          app_data = strchr(app, ',');
00962          if (app_data) {
00963             *app_data = '\0';
00964             app_data++;
00965          }
00966       } else   
00967          app_data = NULL;
00968    }
00969 
00970    if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT))
00971       return CLI_SHOWUSAGE;
00972 
00973    if (!app_data)
00974       app_data="";
00975    if (ast_add_extension(a->argv[5], a->argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
00976       (void *)strdup(app_data), ast_free_ptr, registrar)) {
00977       switch (errno) {
00978       case ENOMEM:
00979          ast_cli(a->fd, "Out of free memory\n");
00980          break;
00981 
00982       case EBUSY:
00983          ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
00984          break;
00985 
00986       case ENOENT:
00987          ast_cli(a->fd, "No existence of '%s' context\n", a->argv[5]);
00988          break;
00989 
00990       case EEXIST:
00991          ast_cli(a->fd, "Extension %s@%s with priority %s already exists\n",
00992             exten, a->argv[5], prior);
00993          break;
00994 
00995       default:
00996          ast_cli(a->fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n",
00997                exten, prior, app, app_data, a->argv[5]);
00998          break;
00999       }
01000       return CLI_FAILURE;
01001    }
01002 
01003    if (a->argc == 7)
01004       ast_cli(a->fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n",
01005          exten, a->argv[5], prior, exten, prior, app, app_data);
01006    else
01007       ast_cli(a->fd, "Extension '%s,%s,%s,%s' added into '%s' context\n",
01008          exten, prior, app, app_data, a->argv[5]);
01009 
01010    return CLI_SUCCESS;
01011 }

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

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

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

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

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       const 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 1147 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.

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

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, el, ext, ast_cli_args::fd, ast_exten::label, 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]

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 1366 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_shrink_phone_number(), ast_skip_blanks(), ast_strdup, ast_strlen_zero(), ast_trim_blanks(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), CONFIG_STATUS_FILEINVALID, errno, ext, free, ast_variable::lineno, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), pbx_strsep(), pbx_substitute_variables_helper(), PRIORITY_HINT, S_OR, strdup, strsep(), and ast_variable::value.

Referenced by pbx_load_module().

01367 {
01368    struct ast_config *cfg;
01369    char *end;
01370    char *label;
01371 #ifdef LOW_MEMORY
01372    char realvalue[256];
01373 #else
01374    char realvalue[8192];
01375 #endif
01376    int lastpri = -2;
01377    struct ast_context *con;
01378    struct ast_variable *v;
01379    const char *cxt;
01380    const char *aft;
01381    const char *newpm, *ovsw;
01382    struct ast_flags config_flags = { 0 };
01383    char lastextension[256];
01384    cfg = ast_config_load(config_file, config_flags);
01385    if (!cfg || cfg == CONFIG_STATUS_FILEINVALID)
01386       return 0;
01387 
01388    /* Use existing config to populate the PBX table */
01389    static_config = ast_true(ast_variable_retrieve(cfg, "general", "static"));
01390    write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect"));
01391    if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough")))
01392       autofallthrough_config = ast_true(aft);
01393    if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew")))
01394       extenpatternmatchnew_config = ast_true(newpm);
01395    clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars"));
01396    if ((ovsw = ast_variable_retrieve(cfg, "general", "overrideswitch"))) {
01397       if (overrideswitch_config) {
01398          ast_free(overrideswitch_config);
01399       }
01400       if (!ast_strlen_zero(ovsw)) {
01401          overrideswitch_config = ast_strdup(ovsw);
01402       } else {
01403          overrideswitch_config = NULL;
01404       }
01405    }
01406 
01407    ast_copy_string(userscontext, ast_variable_retrieve(cfg, "general", "userscontext") ?: "default", sizeof(userscontext));
01408                             
01409    for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) {
01410       pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01411       pbx_builtin_setvar_helper(NULL, v->name, realvalue);
01412    }
01413    for (cxt = ast_category_browse(cfg, NULL);
01414         cxt;
01415         cxt = ast_category_browse(cfg, cxt)) {
01416       /* All categories but "general" or "globals" are considered contexts */
01417       if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) {
01418          continue;
01419       }
01420       if (!(con = ast_context_find_or_create(&local_contexts, local_table, cxt, registrar))) {
01421          continue;
01422       }
01423 
01424       /* Reset continuation items at the beginning of each context */
01425       lastextension[0] = '\0';
01426       lastpri = -2;
01427 
01428       for (v = ast_variable_browse(cfg, cxt); v; v = v->next) {
01429          char *tc = NULL;
01430          char realext[256] = "";
01431          char *stringp, *ext;
01432 
01433          if (!strncasecmp(v->name, "same", 4)) {
01434             if (ast_strlen_zero(lastextension)) {
01435                ast_log(LOG_ERROR, "No previous pattern in the first entry of context '%s' to match '%s'!\n", cxt, v->name);
01436                continue;
01437             }
01438             if ((stringp = tc = ast_strdup(v->value))) {
01439                ast_copy_string(realext, lastextension, sizeof(realext));
01440                goto process_extension;
01441             }
01442          } else if (!strcasecmp(v->name, "exten")) {
01443             int ipri;
01444             char *plus, *firstp;
01445             char *pri, *appl, *data, *cidmatch;
01446 
01447             if (!(stringp = tc = ast_strdup(v->value))) {
01448                continue;
01449             }
01450 
01451             ext = S_OR(pbx_strsep(&stringp, ","), "");
01452             pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1);
01453             ast_copy_string(lastextension, realext, sizeof(lastextension));
01454 process_extension:
01455             ipri = -2;
01456             if ((cidmatch = strchr(realext, '/'))) {
01457                *cidmatch++ = '\0';
01458                ast_shrink_phone_number(cidmatch);
01459             }
01460             pri = S_OR(strsep(&stringp, ","), "");
01461             pri = ast_skip_blanks(pri);
01462             pri = ast_trim_blanks(pri);
01463             if ((label = strchr(pri, '('))) {
01464                *label++ = '\0';
01465                if ((end = strchr(label, ')'))) {
01466                   *end = '\0';
01467                } else {
01468                   ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno);
01469                }
01470             }
01471             if ((plus = strchr(pri, '+'))) {
01472                *plus++ = '\0';
01473             }
01474             if (!strcmp(pri,"hint")) {
01475                ipri = PRIORITY_HINT;
01476             } else if (!strcmp(pri, "next") || !strcmp(pri, "n")) {
01477                if (lastpri > -2) {
01478                   ipri = lastpri + 1;
01479                } else {
01480                   ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry!\n");
01481                }
01482             } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) {
01483                if (lastpri > -2) {
01484                   ipri = lastpri;
01485                } else {
01486                   ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry!\n");
01487                }
01488             } else if (sscanf(pri, "%30d", &ipri) != 1 &&
01489                   (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) {
01490                ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno);
01491                ipri = 0;
01492             }
01493             appl = S_OR(stringp, "");
01494             /* Find the first occurrence of '(' */
01495             if (!(firstp = strchr(appl, '('))) {
01496                /* No arguments */
01497                data = "";
01498             } else {
01499                appl = strsep(&stringp, "(");
01500                data = S_OR(stringp, "");
01501                if ((end = strrchr(data, ')'))) {
01502                   *end = '\0';
01503                } else {
01504                   ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s'\n", appl, data);
01505                }
01506             }
01507 
01508             appl = ast_skip_blanks(appl);
01509             if (ipri) {
01510                if (plus) {
01511                   ipri += atoi(plus);
01512                }
01513                lastpri = ipri;
01514                if (!ast_opt_dont_warn && !strcmp(realext, "_.")) {
01515                   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);
01516                }
01517                if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free_ptr, registrar)) {
01518                   ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
01519                }
01520             }
01521             free(tc);
01522          } else if (!strcasecmp(v->name, "include")) {
01523             pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01524             if (ast_context_add_include2(con, realvalue, registrar)) {
01525                switch (errno) {
01526                   case ENOMEM:
01527                      ast_log(LOG_WARNING, "Out of memory for context addition\n");
01528                      break;
01529 
01530                   case EBUSY:
01531                      ast_log(LOG_WARNING, "Failed to lock context(s) list, please try again later\n");
01532                      break;
01533 
01534                   case EEXIST:
01535                      ast_log(LOG_WARNING, "Context '%s' already included in '%s' context\n",
01536                            v->value, cxt);
01537                      break;
01538 
01539                   case ENOENT:
01540                   case EINVAL:
01541                      ast_log(LOG_WARNING, "There is no existence of context '%s'\n",
01542                            errno == ENOENT ? v->value : cxt);
01543                      break;
01544 
01545                   default:
01546                      ast_log(LOG_WARNING, "Failed to include '%s' in '%s' context\n",
01547                            v->value, cxt);
01548                      break;
01549                }
01550             }
01551          } else if (!strcasecmp(v->name, "ignorepat")) {
01552             pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01553             if (ast_context_add_ignorepat2(con, realvalue, registrar)) {
01554                ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
01555             }
01556          } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) {
01557             char *stringp = realvalue;
01558             char *appl, *data;
01559             
01560             if (!strcasecmp(v->name, "switch")) {
01561                pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01562             } else {
01563                ast_copy_string(realvalue, v->value, sizeof(realvalue));
01564             }
01565             appl = strsep(&stringp, "/");
01566             data = S_OR(stringp, "");
01567             if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar)) {
01568                ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt);
01569             }
01570          } else {
01571             ast_log(LOG_WARNING, "==!!== Unknown directive: %s at line %d -- IGNORING!!!\n", v->name, v->lineno);
01572          }
01573       }
01574    }
01575    ast_config_destroy(cfg);
01576    return 1;
01577 }

static int pbx_load_module ( void   )  [static]

static void pbx_load_users ( void   )  [static]

Definition at line 1591 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, ext, len(), LOG_ERROR, strdup, and strsep().

Referenced by pbx_load_module().

01592 {
01593    struct ast_config *cfg;
01594    char *cat, *chan;
01595    const char *dahdichan;
01596    const char *hasexten, *altexts;
01597    char tmp[256];
01598    char iface[256];
01599    char dahdicopy[256];
01600    char *ext, altcopy[256];
01601    char *c;
01602    int len;
01603    int hasvoicemail;
01604    int start, finish, x;
01605    struct ast_context *con = NULL;
01606    struct ast_flags config_flags = { 0 };
01607    
01608    cfg = ast_config_load("users.conf", config_flags);
01609    if (!cfg)
01610       return;
01611 
01612    for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
01613       if (!strcasecmp(cat, "general"))
01614          continue;
01615       iface[0] = '\0';
01616       len = sizeof(iface);
01617       if (ast_true(ast_config_option(cfg, cat, "hassip"))) {
01618          snprintf(tmp, sizeof(tmp), "SIP/%s", cat);
01619          append_interface(iface, sizeof(iface), tmp);
01620       }
01621       if (ast_true(ast_config_option(cfg, cat, "hasiax"))) {
01622          snprintf(tmp, sizeof(tmp), "IAX2/%s", cat);
01623          append_interface(iface, sizeof(iface), tmp);
01624       }
01625       if (ast_true(ast_config_option(cfg, cat, "hash323"))) {
01626          snprintf(tmp, sizeof(tmp), "H323/%s", cat);
01627          append_interface(iface, sizeof(iface), tmp);
01628       }
01629       hasexten = ast_config_option(cfg, cat, "hasexten");
01630       if (hasexten && !ast_true(hasexten))
01631          continue;
01632       hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail"));
01633       dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan");
01634       if (!dahdichan)
01635          dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan");
01636       if (!ast_strlen_zero(dahdichan)) {
01637          ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy));
01638          c = dahdicopy;
01639          chan = strsep(&c, ",");
01640          while (chan) {
01641             if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
01642                /* Range */
01643             } else if (sscanf(chan, "%30d", &start)) {
01644                /* Just one */
01645                finish = start;
01646             } else {
01647                start = 0; finish = 0;
01648             }
01649             if (finish < start) {
01650                x = finish;
01651                finish = start;
01652                start = x;
01653             }
01654             for (x = start; x <= finish; x++) {
01655                snprintf(tmp, sizeof(tmp), "DAHDI/%d", x);
01656                append_interface(iface, sizeof(iface), tmp);
01657             }
01658             chan = strsep(&c, ",");
01659          }
01660       }
01661       if (!ast_strlen_zero(iface)) {
01662          /* Only create a context here when it is really needed. Otherwise default empty context
01663          created by pbx_config may conflict with the one explicitly created by pbx_ael */
01664          if (!con)
01665             con = ast_context_find_or_create(&local_contexts, local_table, userscontext, registrar);
01666 
01667          if (!con) {
01668             ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext);
01669             return;
01670          }
01671 
01672          /* Add hint */
01673          ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar);
01674          /* If voicemail, use "stdexten" else use plain old dial */
01675          if (hasvoicemail) {
01676             snprintf(tmp, sizeof(tmp), "stdexten,%s,${HINT}", cat);
01677             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", strdup(tmp), ast_free_ptr, registrar);
01678          } else {
01679             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", strdup("${HINT}"), ast_free_ptr, registrar);
01680          }
01681          altexts = ast_variable_retrieve(cfg, cat, "alternateexts");
01682          if (!ast_strlen_zero(altexts)) {
01683             snprintf(tmp, sizeof(tmp), "%s,1", cat);
01684             ast_copy_string(altcopy, altexts, sizeof(altcopy));
01685             c = altcopy;
01686             ext = strsep(&c, ",");
01687             while (ext) {
01688                ast_add_extension2(con, 0, ext, 1, NULL, NULL, "Goto", strdup(tmp), ast_free_ptr, registrar);
01689                ext = strsep(&c, ",");
01690             }
01691          }
01692       }
01693    }
01694    ast_config_destroy(cfg);
01695 }

static char* pbx_strsep ( char **  destructible,
const char *  delim 
) [static]

Note:
Protect against misparsing based upon commas in the middle of fields like character classes. We've taken steps to permit pretty much every other printable character in a character class, so properly handling a comma at this level is a natural extension. This is almost like the standard application parser in app.c, except that it handles square brackets.

Definition at line 1341 of file pbx_config.c.

Referenced by pbx_load_config().

01342 {
01343    int square = 0;
01344    char *res = *destructible;
01345    for (; destructible && *destructible && **destructible; (*destructible)++) {
01346       if (**destructible == '[' && !strchr(delim, '[')) {
01347          square++;
01348       } else if (**destructible == ']' && !strchr(delim, ']')) {
01349          if (square) {
01350             square--;
01351          }
01352       } else if (**destructible == '\\' && !strchr(delim, '\\')) {
01353          (*destructible)++;
01354       } else if (strchr(delim, **destructible) && !square) {
01355          **destructible = '\0';
01356          (*destructible)++;
01357          break;
01358       }
01359    }
01360    if (destructible && *destructible && **destructible == '\0') {
01361       *destructible = NULL;
01362    }
01363    return res;
01364 }

static int reload ( void   )  [static]

Definition at line 1735 of file pbx_config.c.

References pbx_builtin_clear_globals(), and pbx_load_module().

01736 {
01737    if (clearglobalvars_config)
01738       pbx_builtin_clear_globals();
01739    return pbx_load_module();
01740 }

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]


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

Definition at line 1746 of file pbx_config.c.

Definition at line 1746 of file pbx_config.c.

int autofallthrough_config = 1 [static]

Definition at line 47 of file pbx_config.c.

int clearglobalvars_config = 0 [static]

Definition at line 48 of file pbx_config.c.

Initial value:

Definition at line 1318 of file pbx_config.c.

struct ast_cli_entry cli_pbx_config[] [static]

CLI entries for commands provided by this module

Definition at line 1308 of file pbx_config.c.

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.

struct ast_context* local_contexts = NULL [static]

Definition at line 54 of file pbx_config.c.

Referenced by ast_context_find_or_create(), and pbx_load_module().

struct ast_hashtab* local_table = NULL [static]

Definition at line 55 of file pbx_config.c.

Referenced by pbx_load_module().

char* overrideswitch_config = NULL [static]

Definition at line 50 of file pbx_config.c.

char* registrar = "pbx_config" [static]

Definition at line 42 of file pbx_config.c.

ast_mutex_t save_dialplan_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [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.

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.


Generated on Wed Oct 28 13:33:17 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6