Sat Feb 11 06:36:11 2012

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 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_MUTEX_INITIALIZER , 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


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 1824 of file pbx_config.c.

static void __unreg_module ( void   )  [static]

Definition at line 1824 of file pbx_config.c.

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

Definition at line 1659 of file pbx_config.c.

References len().

Referenced by pbx_load_users().

01660 {
01661    int len = strlen(iface);
01662    if (strlen(add) + len < maxlen - 2) {
01663       if (strlen(iface)) {
01664          iface[len] = '&';
01665          strcpy(iface + len + 1, add);
01666       } else
01667          strcpy(iface, add);
01668    }
01669 }

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

01036 {
01037    int which = 0;
01038 
01039    if (a->pos == 4) {      /* complete 'into' word ... */
01040       return (a->n == 0) ? strdup("into") : NULL;
01041    } else if (a->pos == 5) { /* complete context */
01042       struct ast_context *c = NULL;
01043       int len = strlen(a->word);
01044       char *res = NULL;
01045 
01046       /* try to lock contexts list ... */
01047       if (ast_rdlock_contexts()) {
01048          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01049          return NULL;
01050       }
01051 
01052       /* walk through all contexts */
01053       while ( !res && (c = ast_walk_contexts(c)) )
01054          if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n)
01055             res = strdup(ast_get_context_name(c));
01056       ast_unlock_contexts();
01057       return res;
01058    } else if (a->pos == 6) {
01059       return a->n == 0 ? strdup("replace") : NULL;
01060    }
01061    return NULL;
01062 }

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

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

01122 {
01123    if (a->pos == 4)
01124       return a->n == 0 ? strdup("into") : NULL;
01125    else if (a->pos == 5) {
01126       struct ast_context *c;
01127       int which = 0;
01128       char *dupline, *ignorepat = NULL;
01129       const char *s;
01130       char *ret = NULL;
01131       int len = strlen(a->word);
01132 
01133       /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */
01134       s = skip_words(a->line, 3);
01135       if (s == NULL)
01136          return NULL;
01137       dupline = strdup(s);
01138       if (!dupline) {
01139          ast_log(LOG_ERROR, "Malloc failure\n");
01140          return NULL;
01141       }
01142       ignorepat = strsep(&dupline, " ");
01143 
01144       if (ast_rdlock_contexts()) {
01145          ast_log(LOG_ERROR, "Failed to lock contexts list\n");
01146          return NULL;
01147       }
01148 
01149       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01150          int found = 0;
01151 
01152          if (!partial_match(ast_get_context_name(c), a->word, len))
01153             continue; /* not mine */
01154          if (ignorepat) /* there must be one, right ? */
01155             found = lookup_c_ip(c, ignorepat);
01156          if (!found && ++which > a->n)
01157             ret = strdup(ast_get_context_name(c));
01158       }
01159 
01160       free(ignorepat);
01161       ast_unlock_contexts();
01162       return ret;
01163    }
01164 
01165    return NULL;
01166 }

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

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

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

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

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

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

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

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

01218 {
01219    struct ast_context *c;
01220    int which = 0;
01221    char *ret = NULL;
01222 
01223    if (a->pos == 3) {
01224       int len = strlen(a->word);
01225       if (ast_rdlock_contexts()) {
01226          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01227          return NULL;
01228       }
01229 
01230       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01231          struct ast_ignorepat *ip;
01232 
01233          if (ast_rdlock_context(c)) /* error, skip it */
01234             continue;
01235          
01236          for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) {
01237             if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) {
01238                /* n-th match */
01239                struct ast_context *cw = NULL;
01240                int found = 0;
01241                while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) {
01242                   /* XXX do i stop on c, or skip it ? */
01243                   found = lookup_c_ip(cw, ast_get_ignorepat_name(ip));
01244                }
01245                if (!found)
01246                   ret = strdup(ast_get_ignorepat_name(ip));
01247             }
01248          }
01249          ast_unlock_context(c);
01250       }
01251       ast_unlock_contexts();
01252       return ret;
01253    } else if (a->pos == 4) {
01254        return a->n == 0 ? strdup("from") : NULL;
01255    } else if (a->pos == 5) { /* XXX check this */
01256       char *dupline, *duplinet, *ignorepat;
01257       int len = strlen(a->word);
01258 
01259       dupline = strdup(a->line);
01260       if (!dupline) {
01261          ast_log(LOG_WARNING, "Out of free memory\n");
01262          return NULL;
01263       }
01264 
01265       duplinet = dupline;
01266       strsep(&duplinet, " ");
01267       strsep(&duplinet, " ");
01268       ignorepat = strsep(&duplinet, " ");
01269 
01270       if (!ignorepat) {
01271          free(dupline);
01272          return NULL;
01273       }
01274 
01275       if (ast_rdlock_contexts()) {
01276          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01277          free(dupline);
01278          return NULL;
01279       }
01280 
01281       for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
01282          if (ast_rdlock_context(c)) /* fail, skip it */
01283             continue;
01284          if (!partial_match(ast_get_context_name(c), a->word, len))
01285             continue;
01286          if (lookup_c_ip(c, ignorepat) && ++which > a->n)
01287             ret = strdup(ast_get_context_name(c));
01288          ast_unlock_context(c);
01289       }
01290       ast_unlock_contexts();
01291       free(dupline);
01292       return NULL;
01293    }
01294 
01295    return NULL;
01296 }

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

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

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

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

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

01068 {
01069    switch (cmd) {
01070    case CLI_INIT:
01071       e->command = "dialplan add ignorepat";
01072       e->usage =
01073          "Usage: dialplan add ignorepat <pattern> into <context>\n"
01074          "       This command adds a new ignore pattern into context <context>\n"
01075          "\n"
01076          "Example: dialplan add ignorepat _3XX into local\n";
01077       return NULL;
01078    case CLI_GENERATE:
01079       return complete_dialplan_add_ignorepat(a);
01080    }
01081 
01082    if (a->argc != 6)
01083       return CLI_SHOWUSAGE;
01084 
01085    if (strcmp(a->argv[4], "into"))
01086       return CLI_SHOWUSAGE;
01087 
01088    if (ast_context_add_ignorepat(a->argv[5], a->argv[3], registrar)) {
01089       switch (errno) {
01090       case ENOMEM:
01091          ast_cli(a->fd, "Out of free memory\n");
01092          break;
01093 
01094       case ENOENT:
01095          ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]);
01096          break;
01097 
01098       case EEXIST:
01099          ast_cli(a->fd, "Ignore pattern '%s' already included in '%s' context\n",
01100             a->argv[3], a->argv[5]);
01101          break;
01102 
01103       case EBUSY:
01104          ast_cli(a->fd, "Failed to lock context(s) list, please, try again later\n");
01105          break;
01106 
01107       default:
01108          ast_cli(a->fd, "Failed to add ingore pattern '%s' into '%s' context\n",
01109             a->argv[3], a->argv[5]);
01110          break;
01111       }
01112       return CLI_FAILURE;
01113    }
01114 
01115    ast_cli(a->fd, "Ignore pattern '%s' added into '%s' context\n",
01116       a->argv[3], a->argv[5]);
01117 
01118    return CLI_SUCCESS;
01119 }

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

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

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

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

01301 {
01302    switch (cmd) {
01303    case CLI_INIT:
01304       e->command = "dialplan reload";
01305       e->usage =
01306          "Usage: dialplan reload\n"
01307          "       Reload extensions.conf without reloading any other\n"
01308          "       modules.  This command does not delete global variables\n"
01309          "       unless clearglobalvars is set to yes in extensions.conf\n";
01310       return NULL;
01311    case CLI_GENERATE:
01312       return NULL;
01313    }
01314 
01315    if (a->argc != 2)
01316       return CLI_SHOWUSAGE;
01317 
01318    if (clearglobalvars_config)
01319       pbx_builtin_clear_globals();
01320 
01321    pbx_load_module();
01322    ast_cli(a->fd, "Dialplan reloaded.\n");
01323    return CLI_SUCCESS;
01324 }

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

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

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

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

01169 {
01170    switch (cmd) {
01171    case CLI_INIT:
01172       e->command = "dialplan remove ignorepat";
01173       e->usage =
01174          "Usage: dialplan remove ignorepat <pattern> from <context>\n"
01175          "       This command removes an ignore pattern from context <context>\n"
01176          "\n"
01177          "Example: dialplan remove ignorepat _3XX from local\n";
01178       return NULL;
01179    case CLI_GENERATE:
01180       return complete_dialplan_remove_ignorepat(a);
01181    }
01182 
01183    if (a->argc != 6)
01184       return CLI_SHOWUSAGE;
01185 
01186    if (strcmp(a->argv[4], "from"))
01187       return CLI_SHOWUSAGE;
01188 
01189    if (ast_context_remove_ignorepat(a->argv[5], a->argv[3], registrar)) {
01190       switch (errno) {
01191       case EBUSY:
01192          ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
01193          break;
01194 
01195       case ENOENT:
01196          ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]);
01197          break;
01198 
01199       case EINVAL:
01200          ast_cli(a->fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
01201                a->argv[3], a->argv[5]);
01202          break;
01203 
01204       default:
01205          ast_cli(a->fd, "Failed to remove ignore pattern '%s' from '%s' context\n",
01206                a->argv[3], a->argv[5]);
01207          break;
01208       }
01209       return CLI_FAILURE;
01210    }
01211 
01212    ast_cli(a->fd, "Ignore pattern '%s' removed from '%s' context\n",
01213       a->argv[3], a->argv[5]);
01214    return CLI_SUCCESS;
01215 }

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

References ast_cli_args::argc, 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.

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

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

00676 {
00677    char filename[256], overrideswitch[256] = "";
00678    struct ast_context *c;
00679    struct ast_config *cfg;
00680    struct ast_variable *v;
00681    int incomplete = 0; /* incomplete config write? */
00682    FILE *output;
00683    struct ast_flags config_flags = { 0 };
00684    const char *base, *slash;
00685 
00686    switch (cmd) {
00687    case CLI_INIT:
00688       e->command = "dialplan save";
00689       e->usage =
00690          "Usage: dialplan save [/path/to/extension/file]\n"
00691          "       Save dialplan created by pbx_config module.\n"
00692          "\n"
00693          "Example: dialplan save                 (/etc/asterisk/extensions.conf)\n"
00694          "         dialplan save /home/markster  (/home/markster/extensions.conf)\n";
00695       return NULL;
00696    case CLI_GENERATE:
00697       return NULL;
00698    }
00699 
00700    if (! (static_config && !write_protect_config)) {
00701       ast_cli(a->fd,
00702          "I can't save dialplan now, see '%s' example file.\n",
00703          config);
00704       return CLI_FAILURE;
00705    }
00706 
00707    if (a->argc != 2 && a->argc != 3)
00708       return CLI_SHOWUSAGE;
00709 
00710    if (ast_mutex_lock(&save_dialplan_lock)) {
00711       ast_cli(a->fd,
00712          "Failed to lock dialplan saving (another proccess saving?)\n");
00713       return CLI_FAILURE;
00714    }
00715    /* XXX the code here is quite loose, a pathname with .conf in it
00716     * is assumed to be a complete pathname
00717     */
00718    if (a->argc == 3) {  /* have config path. Look for *.conf */
00719       base = a->argv[2];
00720       if (!strstr(a->argv[2], ".conf")) { /*no, this is assumed to be a pathname */
00721          /* if filename ends with '/', do not add one */
00722          slash = (*(a->argv[2] + strlen(a->argv[2]) -1) == '/') ? "/" : "";
00723       } else { /* yes, complete file name */
00724          slash = "";
00725       }
00726    } else {
00727       /* no config file, default one */
00728       base = ast_config_AST_CONFIG_DIR;
00729       slash = "/";
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 119 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().

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

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

return true if 'name' is included by context c

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

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

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

00149 {
00150    return (len == 0 || !strncmp(s, word, len));
00151 }

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

Definition at line 1388 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_strip(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), CONFIG_STATUS_FILEINVALID, errno, ext, ast_variable::file, 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, strsep(), and ast_variable::value.

Referenced by pbx_load_module().

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

static int pbx_load_module ( void   )  [static]

static void pbx_load_users ( void   )  [static]

Definition at line 1671 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_strdup, ast_strlen_zero(), ast_true(), ast_variable_retrieve(), ext, LOG_ERROR, and strsep().

Referenced by pbx_load_module().

01672 {
01673    struct ast_config *cfg;
01674    char *cat, *chan;
01675    const char *dahdichan;
01676    const char *hasexten, *altexts;
01677    char tmp[256];
01678    char iface[256];
01679    char dahdicopy[256];
01680    char *ext, altcopy[256];
01681    char *c;
01682    int hasvoicemail;
01683    int start, finish, x;
01684    struct ast_context *con = NULL;
01685    struct ast_flags config_flags = { 0 };
01686    
01687    cfg = ast_config_load("users.conf", config_flags);
01688    if (!cfg)
01689       return;
01690 
01691    for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
01692       if (!strcasecmp(cat, "general"))
01693          continue;
01694       iface[0] = '\0';
01695       if (ast_true(ast_config_option(cfg, cat, "hassip"))) {
01696          snprintf(tmp, sizeof(tmp), "SIP/%s", cat);
01697          append_interface(iface, sizeof(iface), tmp);
01698       }
01699       if (ast_true(ast_config_option(cfg, cat, "hasiax"))) {
01700          snprintf(tmp, sizeof(tmp), "IAX2/%s", cat);
01701          append_interface(iface, sizeof(iface), tmp);
01702       }
01703       if (ast_true(ast_config_option(cfg, cat, "hash323"))) {
01704          snprintf(tmp, sizeof(tmp), "H323/%s", cat);
01705          append_interface(iface, sizeof(iface), tmp);
01706       }
01707       hasexten = ast_config_option(cfg, cat, "hasexten");
01708       if (hasexten && !ast_true(hasexten))
01709          continue;
01710       hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail"));
01711       dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan");
01712       if (!dahdichan)
01713          dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan");
01714       if (!ast_strlen_zero(dahdichan)) {
01715          ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy));
01716          c = dahdicopy;
01717          chan = strsep(&c, ",");
01718          while (chan) {
01719             if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
01720                /* Range */
01721             } else if (sscanf(chan, "%30d", &start)) {
01722                /* Just one */
01723                finish = start;
01724             } else {
01725                start = 0; finish = 0;
01726             }
01727             if (finish < start) {
01728                x = finish;
01729                finish = start;
01730                start = x;
01731             }
01732             for (x = start; x <= finish; x++) {
01733                snprintf(tmp, sizeof(tmp), "DAHDI/%d", x);
01734                append_interface(iface, sizeof(iface), tmp);
01735             }
01736             chan = strsep(&c, ",");
01737          }
01738       }
01739       if (!ast_strlen_zero(iface)) {
01740          /* Only create a context here when it is really needed. Otherwise default empty context
01741          created by pbx_config may conflict with the one explicitly created by pbx_ael */
01742          if (!con)
01743             con = ast_context_find_or_create(&local_contexts, local_table, userscontext, registrar);
01744 
01745          if (!con) {
01746             ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext);
01747             return;
01748          }
01749 
01750          /* Add hint */
01751          ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar);
01752          /* If voicemail, use "stdexten" else use plain old dial */
01753          if (hasvoicemail) {
01754             snprintf(tmp, sizeof(tmp), "%s,stdexten(${HINT})", cat);
01755             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Gosub", ast_strdup(tmp), ast_free_ptr, registrar);
01756          } else {
01757             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", ast_strdup("${HINT}"), ast_free_ptr, registrar);
01758          }
01759          altexts = ast_variable_retrieve(cfg, cat, "alternateexts");
01760          if (!ast_strlen_zero(altexts)) {
01761             snprintf(tmp, sizeof(tmp), "%s,1", cat);
01762             ast_copy_string(altcopy, altexts, sizeof(altcopy));
01763             c = altcopy;
01764             ext = strsep(&c, ",");
01765             while (ext) {
01766                ast_add_extension2(con, 0, ext, 1, NULL, NULL, "Goto", ast_strdup(tmp), ast_free_ptr, registrar);
01767                ext = strsep(&c, ",");
01768             }
01769          }
01770       }
01771    }
01772    ast_config_destroy(cfg);
01773 }

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

Referenced by pbx_load_config().

01364 {
01365    int square = 0;
01366    char *res = *destructible;
01367    for (; destructible && *destructible && **destructible; (*destructible)++) {
01368       if (**destructible == '[' && !strchr(delim, '[')) {
01369          square++;
01370       } else if (**destructible == ']' && !strchr(delim, ']')) {
01371          if (square) {
01372             square--;
01373          }
01374       } else if (**destructible == '\\' && !strchr(delim, '\\')) {
01375          (*destructible)++;
01376       } else if (strchr(delim, **destructible) && !square) {
01377          **destructible = '\0';
01378          (*destructible)++;
01379          break;
01380       }
01381    }
01382    if (destructible && *destructible && **destructible == '\0') {
01383       *destructible = NULL;
01384    }
01385    return res;
01386 }

static int reload ( void   )  [static]

Definition at line 1813 of file pbx_config.c.

References pbx_builtin_clear_globals(), and pbx_load_module().

01814 {
01815    if (clearglobalvars_config)
01816       pbx_builtin_clear_globals();
01817    return pbx_load_module();
01818 }

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

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

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

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

References ast_strdup, and free.

Referenced by complete_dialplan_remove_extension(), and handle_cli_dialplan_remove_extension().

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

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

Definition at line 1824 of file pbx_config.c.

int autofallthrough_config = 1 [static]

Definition at line 51 of file pbx_config.c.

int clearglobalvars_config = 0 [static]

Definition at line 52 of file pbx_config.c.

Initial value:

Definition at line 1340 of file pbx_config.c.

struct ast_cli_entry cli_pbx_config[] [static]

CLI entries for commands provided by this module

Definition at line 1329 of file pbx_config.c.

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

Definition at line 45 of file pbx_config.c.

int extenpatternmatchnew_config = 0 [static]

Definition at line 53 of file pbx_config.c.

struct ast_context* local_contexts = NULL [static]

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

Referenced by pbx_load_module().

char* overrideswitch_config = NULL [static]

Definition at line 54 of file pbx_config.c.

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

Definition at line 46 of file pbx_config.c.

ast_mutex_t save_dialplan_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static]

Definition at line 56 of file pbx_config.c.

Referenced by handle_cli_dialplan_save().

int static_config = 0 [static]

Definition at line 49 of file pbx_config.c.

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

Definition at line 47 of file pbx_config.c.

int write_protect_config = 1 [static]

Definition at line 50 of file pbx_config.c.


Generated on Sat Feb 11 06:36:12 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6