Mon Jun 27 16:51:17 2011

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 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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 const 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 const char registrar [] = "pbx_config"
static ast_mutex_t save_dialplan_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
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 1773 of file pbx_config.c.

static void __unreg_module ( void   )  [static]

Definition at line 1773 of file pbx_config.c.

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

Definition at line 1606 of file pbx_config.c.

References len().

Referenced by pbx_load_users().

01607 {
01608    int len = strlen(iface);
01609    if (strlen(add) + len < maxlen - 2) {
01610       if (strlen(iface)) {
01611          iface[len] = '&';
01612          strcpy(iface + len + 1, add);
01613       } else
01614          strcpy(iface, add);
01615    }
01616 }

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

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

static char * complete_dialplan_add_ignorepat ( struct ast_cli_args  )  [static]

Definition at line 1099 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, skip_words(), strdup, strsep(), and ast_cli_args::word.

Referenced by handle_cli_dialplan_add_ignorepat().

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

static char * complete_dialplan_add_include ( struct ast_cli_args  )  [static]

Definition at line 574 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, skip_words(), strdup, strsep(), and ast_cli_args::word.

Referenced by handle_cli_dialplan_add_include().

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

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, 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, 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       len = strlen(a->word);
00471       if (le == 0 || lc == 0)
00472          goto error3;
00473 
00474       if (ast_rdlock_contexts()) {
00475          ast_log(LOG_ERROR, "Failed to lock context list\n");
00476          goto error3;
00477       }
00478 
00479       /* walk contexts */
00480       c = NULL;
00481       while ( (c = ast_walk_contexts(c)) ) {
00482          /* XXX locking on c ? */
00483          struct ast_exten *e;
00484          if (strcmp(ast_get_context_name(c), context) != 0)
00485             continue;
00486          /* got it, we must match here */
00487          e = NULL;
00488          while ( (e = ast_walk_context_extensions(c, e)) ) {
00489             struct ast_exten *priority;
00490             char buffer[10];
00491 
00492             if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) {
00493                continue;
00494             }
00495             if (strcmp(ast_get_extension_name(e), exten) != 0)
00496                continue;
00497             /* XXX lock e ? */
00498             priority = NULL;
00499             while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) {
00500                snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority));
00501                if (partial_match(buffer, a->word, len) && ++which > a->n) /* n-th match */
00502                   ret = strdup(buffer);
00503             }
00504             break;
00505          }
00506          break;
00507       }
00508       ast_unlock_contexts();
00509    error3:
00510       free(exten);
00511    }
00512    return ret; 
00513 }

static char * complete_dialplan_remove_ignorepat ( struct ast_cli_args  )  [static]

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

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

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, 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 901 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, 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.

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

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

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

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

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

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

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

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

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

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

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

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

static int load_module ( void   )  [static]

Definition at line 1750 of file pbx_config.c.

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

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

References ast_category_browse(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), config_flags, CONFIG_STATUS_FILEINVALID, ext, ast_variable::lineno, local_contexts, local_table, LOG_ERROR, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), and ast_variable::value.

Referenced by pbx_load_module().

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

static int pbx_load_module ( void   )  [static]

Definition at line 1724 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(), local_contexts, local_table, pbx_load_config(), pbx_load_users(), pbx_set_autofallthrough(), pbx_set_extenpatternmatchnew(), and pbx_set_overrideswitch().

01725 {
01726    struct ast_context *con;
01727 
01728    if (!local_table)
01729       local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
01730 
01731    if (!pbx_load_config(config))
01732       return AST_MODULE_LOAD_DECLINE;
01733    
01734    pbx_load_users();
01735 
01736    ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
01737    local_table = NULL; /* the local table has been moved into the global one. */
01738    local_contexts = NULL;
01739 
01740    for (con = NULL; (con = ast_walk_contexts(con));)
01741       ast_context_verify_includes(con);
01742 
01743    pbx_set_overrideswitch(overrideswitch_config);
01744    pbx_set_autofallthrough(autofallthrough_config);
01745    pbx_set_extenpatternmatchnew(extenpatternmatchnew_config);
01746 
01747    return AST_MODULE_LOAD_SUCCESS;
01748 }

static void pbx_load_users ( void   )  [static]

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

Referenced by pbx_load_module().

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

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

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

static int reload ( void   )  [static]

Definition at line 1762 of file pbx_config.c.

References pbx_builtin_clear_globals(), and pbx_load_module().

01763 {
01764    if (clearglobalvars_config)
01765       pbx_builtin_clear_globals();
01766    return pbx_load_module();
01767 }

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

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


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

Definition at line 1773 of file pbx_config.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

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

struct ast_cli_entry cli_dialplan_save [static]

Initial value:

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

Definition at line 1317 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 1307 of file pbx_config.c.

Referenced by load_module(), and unload_module().

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

const char registrar[] = "pbx_config" [static]

Definition at line 42 of file pbx_config.c.

ast_mutex_t save_dialplan_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [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 Mon Jun 27 16:51:17 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7