Thu Jul 9 13:41:27 2009

Asterisk developer's documentation


pbx_config.c File Reference

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

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

Go to the source code of this file.

Defines

#define PUT_CTX_HDR

Functions

static void __reg_module (void)
static void __unreg_module (void)
static void append_interface (char *iface, int maxlen, char *add)
static char * complete_dialplan_add_extension (struct ast_cli_args *)
static char * complete_dialplan_add_ignorepat (struct ast_cli_args *)
static char * complete_dialplan_add_include (struct ast_cli_args *)
static char * complete_dialplan_remove_extension (struct ast_cli_args *)
static char * complete_dialplan_remove_ignorepat (struct ast_cli_args *)
static char * complete_dialplan_remove_include (struct ast_cli_args *)
static char * handle_cli_dialplan_add_extension (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 ADD EXTENSION command stuff.
static char * handle_cli_dialplan_add_ignorepat (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_add_include (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_remove_extension (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_remove_ignorepat (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_remove_include (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_save (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 'save dialplan' CLI command implementation functions ...
static int load_module (void)
static int lookup_c_ip (struct ast_context *c, const char *name)
 return true if 'name' is in the ignorepats for context c
static int lookup_ci (struct ast_context *c, const char *name)
 return true if 'name' is included by context c
static int partial_match (const char *s, const char *word, int len)
 match the first 'len' chars of word. len==0 always succeeds
static int pbx_load_config (const char *config_file)
static int pbx_load_module (void)
static void pbx_load_users (void)
static int reload (void)
static const char * skip_words (const char *p, int n)
 moves to the n-th word in the string, or empty string if none
static int split_ec (const char *src, char **ext, char **const ctx, char **const cid)
 split extension@context in two parts, return -1 on error. The return string is malloc'ed and pointed by *ext
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Text Extension Configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload, }
static const struct ast_module_infoast_module_info = &__mod_info
static int autofallthrough_config = 1
static int clearglobalvars_config = 0
static struct ast_cli_entry cli_dialplan_save
static struct ast_cli_entry cli_pbx_config []
static char * config = "extensions.conf"
static int extenpatternmatchnew_config = 0
static struct ast_contextlocal_contexts = NULL
static struct ast_hashtablocal_table = NULL
static char * registrar = "pbx_config"
static ast_mutex_t save_dialplan_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
static int static_config = 0
static char userscontext [AST_MAX_EXTENSION] = "default"
static int write_protect_config = 1


Detailed Description

Populate and remember extensions from static config file.

Definition in file pbx_config.c.


Define Documentation

#define PUT_CTX_HDR

Referenced by handle_cli_dialplan_save().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 1644 of file pbx_config.c.

static void __unreg_module ( void   )  [static]

Definition at line 1644 of file pbx_config.c.

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

Definition at line 1490 of file pbx_config.c.

References len().

Referenced by pbx_load_users().

01491 {
01492    int len = strlen(iface);
01493    if (strlen(add) + len < maxlen - 2) {
01494       if (strlen(iface)) {
01495          iface[len] = '&';
01496          strcpy(iface + len + 1, add);
01497       } else
01498          strcpy(iface, add);
01499    }
01500 }

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

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

static char * complete_dialplan_add_ignorepat ( struct ast_cli_args  )  [static]

Definition at line 1096 of file pbx_config.c.

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

Referenced by handle_cli_dialplan_add_ignorepat().

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

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, s, 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       struct ast_context *c;
00595       const char *s = skip_words(a->line, 3); /* should not fail */
00596 
00597       if (a->n != 0) /* only once */
00598          return NULL;
00599 
00600       /* parse context from line ... */
00601       context = dupline = strdup(s);
00602       if (!context) {
00603          ast_log(LOG_ERROR, "Out of free memory\n");
00604          return strdup("into");
00605       }
00606       strsep(&dupline, " ");
00607 
00608       /* check for context existence ... */
00609       if (ast_rdlock_contexts()) {
00610          ast_log(LOG_ERROR, "Failed to lock context list\n");
00611          /* our fault, we can't check, so complete 'into' ... */
00612          ret = strdup("into");
00613       } else {
00614          for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
00615             if (!strcmp(context, ast_get_context_name(c)))
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 391 of file pbx_config.c.

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

Referenced by handle_cli_dialplan_remove_extension().

00392 {
00393    char *ret = NULL;
00394    int which = 0;
00395 
00396    if (a->pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */
00397       struct ast_context *c = NULL;
00398       char *context = NULL, *exten = NULL, *cid = NULL;
00399       int le = 0; /* length of extension */
00400       int lc = 0; /* length of context */
00401       int lcid = 0; /* length of cid */
00402 
00403       lc = split_ec(a->word, &exten, &context, &cid);
00404       if (lc)  { /* error */
00405          return NULL;
00406       }
00407       le = strlen(exten);
00408       lc = strlen(context);
00409       lcid = cid ? strlen(cid) : -1;
00410 
00411       if (ast_rdlock_contexts()) {
00412          ast_log(LOG_ERROR, "Failed to lock context list\n");
00413          goto error2;
00414       }
00415 
00416       /* find our context ... */
00417       while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */
00418          struct ast_exten *e = NULL;
00419          /* XXX locking ? */
00420          if (!partial_match(ast_get_context_name(c), context, lc))
00421             continue;   /* context not matched */
00422          while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */
00423             if ( !strchr(a->word, '/') ||
00424                   (!strchr(a->word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) ||
00425                   (strchr(a->word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) {
00426                if ( ((strchr(a->word, '/') || strchr(a->word, '@')) && !strcmp(ast_get_extension_name(e), exten)) ||
00427                    (!strchr(a->word, '/') && !strchr(a->word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */
00428                   if (++which > a->n) {
00429                      /* If there is an extension then return exten@context. */
00430                      if (ast_get_extension_matchcid(e) && (!strchr(a->word, '@') || strchr(a->word, '/'))) {
00431                         if (asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)) < 0) {
00432                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00433                            ret = NULL;
00434                         }
00435                         break;
00436                      } else if (!ast_get_extension_matchcid(e) && !strchr(a->word, '/')) {
00437                         if (asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) {
00438                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00439                            ret = NULL;
00440                         }
00441                         break;
00442                      }
00443                   }
00444                }
00445             }
00446          }
00447          if (e)   /* got a match */
00448             break;
00449       }
00450 
00451       ast_unlock_contexts();
00452    error2:
00453       free(exten);
00454    } else if (a->pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */
00455       char *exten = NULL, *context, *cid, *p;
00456       struct ast_context *c;
00457       int le, lc, lcid, len;
00458       const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'extension' */
00459       int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */
00460 
00461       if (i)   /* error */
00462          goto error3;
00463       if ( (p = strchr(exten, ' ')) ) /* remove space after extension */
00464          *p = '\0';
00465       if ( (p = strchr(context, ' ')) ) /* remove space after context */
00466          *p = '\0';
00467       le = strlen(exten);
00468       lc = strlen(context);
00469       lcid = strlen(cid);
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 1192 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().

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

static char * complete_dialplan_remove_include ( struct ast_cli_args  )  [static]

Definition at line 181 of file pbx_config.c.

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

Referenced by handle_cli_dialplan_remove_include().

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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, el, ast_cli_args::fd, ast_variable::name, ast_variable::next, PRIORITY_HINT, PUT_CTX_HDR, save_dialplan_lock, ast_cli_entry::usage, and ast_variable::value.

00672 {
00673    char filename[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    fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\nextenpatternmatchnew=%s\n\n",
00754       static_config ? "yes" : "no",
00755       write_protect_config ? "yes" : "no",
00756                 autofallthrough_config ? "yes" : "no",
00757             clearglobalvars_config ? "yes" : "no",
00758             extenpatternmatchnew_config ? "yes" : "no");
00759 
00760    if ((v = ast_variable_browse(cfg, "globals"))) {
00761       fprintf(output, "[globals]\n");
00762       while(v) {
00763          fprintf(output, "%s => %s\n", v->name, v->value);
00764          v = v->next;
00765       }
00766       fprintf(output, "\n");
00767    }
00768 
00769    ast_config_destroy(cfg);
00770    
00771 #define PUT_CTX_HDR  do { \
00772    if (!context_header_written) {   \
00773       fprintf(output, "[%s]\n", ast_get_context_name(c));   \
00774       context_header_written = 1;   \
00775    }  \
00776    } while (0)
00777 
00778    /* walk all contexts */
00779    for (c = NULL; (c = ast_walk_contexts(c)); ) {
00780       int context_header_written = 0;
00781       struct ast_exten *e, *last_written_e = NULL;
00782       struct ast_include *i;
00783       struct ast_ignorepat *ip;
00784       struct ast_sw *sw;
00785 
00786       /* try to lock context and fireout all info */  
00787       if (ast_rdlock_context(c)) { /* lock failure */
00788          incomplete = 1;
00789          continue;
00790       }
00791       /* registered by this module? */
00792       /* XXX do we need this ? */
00793       if (!strcmp(ast_get_context_registrar(c), registrar)) {
00794          fprintf(output, "[%s]\n", ast_get_context_name(c));
00795          context_header_written = 1;
00796       }
00797 
00798       /* walk extensions ... */
00799       for (e = NULL; (e = ast_walk_context_extensions(c, e)); ) {
00800          struct ast_exten *p = NULL;
00801 
00802          /* fireout priorities */
00803          while ( (p = ast_walk_extension_priorities(e, p)) ) {
00804             if (strcmp(ast_get_extension_registrar(p), registrar) != 0) /* not this source */
00805                continue;
00806       
00807             /* make empty line between different extensions */ 
00808             if (last_written_e != NULL &&
00809                    strcmp(ast_get_extension_name(last_written_e),
00810                       ast_get_extension_name(p)))
00811                fprintf(output, "\n");
00812             last_written_e = p;
00813          
00814             PUT_CTX_HDR;
00815 
00816             if (ast_get_extension_priority(p) == PRIORITY_HINT) { /* easy */
00817                fprintf(output, "exten => %s,hint,%s\n",
00818                       ast_get_extension_name(p),
00819                       ast_get_extension_app(p));
00820             } else {
00821                const char *sep, *cid;
00822                const char *el = ast_get_extension_label(p);
00823                char label[128] = "";
00824  
00825                if (ast_get_extension_matchcid(p)) {
00826                   sep = "/";
00827                   cid = ast_get_extension_cidmatch(p);
00828                } else
00829                   sep = cid = "";
00830             
00831                if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2)))
00832                   incomplete = 1;   /* error encountered or label > 125 chars */
00833                
00834                fprintf(output, "exten => %s%s%s,%d%s,%s(%s)\n",
00835                    ast_get_extension_name(p), (ast_strlen_zero(sep) ? "" : sep), (ast_strlen_zero(cid) ? "" : cid),
00836                    ast_get_extension_priority(p), label,
00837                    ast_get_extension_app(p), (ast_strlen_zero(ast_get_extension_app_data(p)) ? "" : (const char *)ast_get_extension_app_data(p)));
00838             }
00839          }
00840       }
00841 
00842       /* written any extensions? ok, write space between exten & inc */
00843       if (last_written_e)
00844          fprintf(output, "\n");
00845 
00846       /* walk through includes */
00847       for (i = NULL; (i = ast_walk_context_includes(c, i)) ; ) {
00848          if (strcmp(ast_get_include_registrar(i), registrar) != 0)
00849             continue; /* not mine */
00850          PUT_CTX_HDR;
00851          fprintf(output, "include => %s\n", ast_get_include_name(i));
00852       }
00853       if (ast_walk_context_includes(c, NULL))
00854          fprintf(output, "\n");
00855 
00856       /* walk through switches */
00857       for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) {
00858          if (strcmp(ast_get_switch_registrar(sw), registrar) != 0)
00859             continue; /* not mine */
00860          PUT_CTX_HDR;
00861          fprintf(output, "switch => %s/%s\n",
00862                 ast_get_switch_name(sw), ast_get_switch_data(sw));
00863       }
00864 
00865       if (ast_walk_context_switches(c, NULL))
00866          fprintf(output, "\n");
00867 
00868       /* fireout ignorepats ... */
00869       for (ip = NULL; (ip = ast_walk_context_ignorepats(c, ip)); ) {
00870          if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0)
00871             continue; /* not mine */
00872          PUT_CTX_HDR;
00873          fprintf(output, "ignorepat => %s\n",
00874                   ast_get_ignorepat_name(ip));
00875       }
00876 
00877       ast_unlock_context(c);
00878    }  
00879 
00880    ast_unlock_contexts();
00881    ast_mutex_unlock(&save_dialplan_lock);
00882    fclose(output);
00883 
00884    if (incomplete) {
00885       ast_cli(a->fd, "Saved dialplan is incomplete\n");
00886       return CLI_FAILURE;
00887    }
00888 
00889    ast_cli(a->fd, "Dialplan successfully saved into '%s'\n",
00890       filename);
00891    return CLI_SUCCESS;
00892 }

static int load_module ( void   )  [static]

Definition at line 1621 of file pbx_config.c.

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

01622 {
01623    if (pbx_load_module())
01624       return AST_MODULE_LOAD_DECLINE;
01625  
01626    if (static_config && !write_protect_config)
01627       ast_cli_register(&cli_dialplan_save);
01628    ast_cli_register_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
01629 
01630    return AST_MODULE_LOAD_SUCCESS;
01631 }

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

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

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

return true if 'name' is included by context c

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

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

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

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

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

Definition at line 1329 of file pbx_config.c.

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

Referenced by pbx_load_module().

01330 {
01331    struct ast_config *cfg;
01332    char *end;
01333    char *label;
01334 #ifdef LOW_MEMORY
01335    char realvalue[256];
01336 #else
01337    char realvalue[8192];
01338 #endif
01339    int lastpri = -2;
01340    struct ast_context *con;
01341    struct ast_variable *v;
01342    const char *cxt;
01343    const char *aft;
01344    const char *newpm;
01345    struct ast_flags config_flags = { 0 };
01346    cfg = ast_config_load(config_file, config_flags);
01347    if (!cfg)
01348       return 0;
01349 
01350    /* Use existing config to populate the PBX table */
01351    static_config = ast_true(ast_variable_retrieve(cfg, "general", "static"));
01352    write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect"));
01353    if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough")))
01354       autofallthrough_config = ast_true(aft);
01355    if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew")))
01356       extenpatternmatchnew_config = ast_true(newpm);
01357    clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars"));
01358    
01359 
01360    if ((cxt = ast_variable_retrieve(cfg, "general", "userscontext"))) 
01361       ast_copy_string(userscontext, cxt, sizeof(userscontext));
01362    else
01363       ast_copy_string(userscontext, "default", sizeof(userscontext));
01364                             
01365    for (v = ast_variable_browse(cfg, "globals"); v; v = v->next) {
01366       pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01367       pbx_builtin_setvar_helper(NULL, v->name, realvalue);
01368    }
01369    for (cxt = NULL; (cxt = ast_category_browse(cfg, cxt)); ) {
01370       /* All categories but "general" or "globals" are considered contexts */
01371       if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals"))
01372          continue;
01373       con=ast_context_find_or_create(&local_contexts, local_table, cxt, registrar);
01374       if (con == NULL)
01375          continue;
01376 
01377       for (v = ast_variable_browse(cfg, cxt); v; v = v->next) {
01378          if (!strcasecmp(v->name, "exten")) {
01379             char *tc = ast_strdup(v->value);
01380             if (tc) {
01381                int ipri = -2;
01382                char realext[256]="";
01383                char *plus, *firstp;
01384                char *pri, *appl, *data, *cidmatch;
01385                char *stringp = tc;
01386                char *ext = strsep(&stringp, ",");
01387                if (!ext)
01388                   ext="";
01389                pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1);
01390                cidmatch = strchr(realext, '/');
01391                if (cidmatch) {
01392                   *cidmatch++ = '\0';
01393                   ast_shrink_phone_number(cidmatch);
01394                }
01395                pri = strsep(&stringp, ",");
01396                if (!pri)
01397                   pri="";
01398                pri = ast_skip_blanks(pri);
01399                pri = ast_trim_blanks(pri);
01400                label = strchr(pri, '(');
01401                if (label) {
01402                   *label++ = '\0';
01403                   end = strchr(label, ')');
01404                   if (end)
01405                      *end = '\0';
01406                   else
01407                      ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno);
01408                }
01409                plus = strchr(pri, '+');
01410                if (plus)
01411                   *plus++ = '\0';
01412                if (!strcmp(pri,"hint"))
01413                   ipri=PRIORITY_HINT;
01414                else if (!strcmp(pri, "next") || !strcmp(pri, "n")) {
01415                   if (lastpri > -2)
01416                      ipri = lastpri + 1;
01417                   else
01418                      ast_log(LOG_WARNING, "Can't use 'next' priority on the first entry!\n");
01419                } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) {
01420                   if (lastpri > -2)
01421                      ipri = lastpri;
01422                   else
01423                      ast_log(LOG_WARNING, "Can't use 'same' priority on the first entry!\n");
01424                } else if (sscanf(pri, "%d", &ipri) != 1 &&
01425                    (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) {
01426                   ast_log(LOG_WARNING, "Invalid priority/label '%s' at line %d\n", pri, v->lineno);
01427                   ipri = 0;
01428                }
01429                appl = S_OR(stringp, "");
01430                /* Find the first occurrence of '(' */
01431                firstp = strchr(appl, '(');
01432                if (!firstp) {
01433                   /* No arguments */
01434                   data = "";
01435                } else {
01436                   appl = strsep(&stringp, "(");
01437                   data = stringp;
01438                   end = strrchr(data, ')');
01439                   if ((end = strrchr(data, ')'))) {
01440                      *end = '\0';
01441                   } else {
01442                      ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s'\n", appl, data);
01443                   }
01444                }
01445 
01446                if (!data)
01447                   data = "";
01448                appl = ast_skip_blanks(appl);
01449                if (ipri) {
01450                   if (plus)
01451                      ipri += atoi(plus);
01452                   lastpri = ipri;
01453                   if (!ast_opt_dont_warn && !strcmp(realext, "_."))
01454                      ast_log(LOG_WARNING, "The use of '_.' for an extension is strongly discouraged and can have unexpected behavior.  Please use '_X.' instead at line %d\n", v->lineno);
01455                   if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), ast_free_ptr, registrar)) {
01456                      ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
01457                   }
01458                }
01459                free(tc);
01460             }
01461          } else if (!strcasecmp(v->name, "include")) {
01462             pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01463             if (ast_context_add_include2(con, realvalue, registrar))
01464                ast_log(LOG_WARNING, "Unable to include context '%s' in context '%s'\n", v->value, cxt);
01465          } else if (!strcasecmp(v->name, "ignorepat")) {
01466             pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01467             if (ast_context_add_ignorepat2(con, realvalue, registrar))
01468                ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
01469          } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) {
01470             char *stringp = realvalue;
01471             char *appl, *data;
01472             
01473             if (!strcasecmp(v->name, "switch"))
01474                pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
01475             else
01476                ast_copy_string(realvalue, v->value, sizeof(realvalue));
01477             appl = strsep(&stringp, "/");
01478             data = S_OR(stringp, "");
01479             if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar))
01480                ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt);
01481          } else {
01482             ast_log(LOG_WARNING, "==!!== Unknown directive: %s at line %d -- IGNORING!!!\n", v->name, v->lineno);
01483          }
01484       }
01485    }
01486    ast_config_destroy(cfg);
01487    return 1;
01488 }

static int pbx_load_module ( void   )  [static]

Definition at line 1596 of file pbx_config.c.

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

01597 {
01598    struct ast_context *con;
01599 
01600    if (!local_table)
01601       local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
01602 
01603    if (!pbx_load_config(config))
01604       return AST_MODULE_LOAD_DECLINE;
01605    
01606    pbx_load_users();
01607 
01608    ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
01609    local_table = NULL; /* the local table has been moved into the global one. */
01610    local_contexts = NULL;
01611 
01612    for (con = NULL; (con = ast_walk_contexts(con));)
01613       ast_context_verify_includes(con);
01614 
01615    pbx_set_autofallthrough(autofallthrough_config);
01616    pbx_set_extenpatternmatchnew(extenpatternmatchnew_config);
01617 
01618    return AST_MODULE_LOAD_SUCCESS;
01619 }

static void pbx_load_users ( void   )  [static]

Definition at line 1502 of file pbx_config.c.

References append_interface(), ast_add_extension2(), ast_category_browse(), ast_config_destroy(), ast_config_load, ast_config_option(), ast_context_find_or_create(), ast_copy_string(), ast_free_ptr, ast_log(), ast_strlen_zero(), ast_true(), ast_variable_retrieve(), chan, len(), local_contexts, local_table, LOG_ERROR, registrar, strdup, strsep(), and userscontext.

Referenced by pbx_load_module().

01503 {
01504    struct ast_config *cfg;
01505    char *cat, *chan;
01506    const char *dahdichan;
01507    const char *hasexten;
01508    char tmp[256];
01509    char iface[256];
01510    char dahdicopy[256];
01511    char *c;
01512    int len;
01513    int hasvoicemail;
01514    int start, finish, x;
01515    struct ast_context *con = NULL;
01516    struct ast_flags config_flags = { 0 };
01517    
01518    cfg = ast_config_load("users.conf", config_flags);
01519    if (!cfg)
01520       return;
01521 
01522    for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
01523       if (!strcasecmp(cat, "general"))
01524          continue;
01525       iface[0] = '\0';
01526       len = sizeof(iface);
01527       if (ast_true(ast_config_option(cfg, cat, "hassip"))) {
01528          snprintf(tmp, sizeof(tmp), "SIP/%s", cat);
01529          append_interface(iface, sizeof(iface), tmp);
01530       }
01531       if (ast_true(ast_config_option(cfg, cat, "hasiax"))) {
01532          snprintf(tmp, sizeof(tmp), "IAX2/%s", cat);
01533          append_interface(iface, sizeof(iface), tmp);
01534       }
01535       if (ast_true(ast_config_option(cfg, cat, "hash323"))) {
01536          snprintf(tmp, sizeof(tmp), "H323/%s", cat);
01537          append_interface(iface, sizeof(iface), tmp);
01538       }
01539       hasexten = ast_config_option(cfg, cat, "hasexten");
01540       if (hasexten && !ast_true(hasexten))
01541          continue;
01542       hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail"));
01543       dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan");
01544       if (!dahdichan)
01545          dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan");
01546       if (!ast_strlen_zero(dahdichan)) {
01547          ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy));
01548          c = dahdicopy;
01549          chan = strsep(&c, ",");
01550          while (chan) {
01551             if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
01552                /* Range */
01553             } else if (sscanf(chan, "%d", &start)) {
01554                /* Just one */
01555                finish = start;
01556             } else {
01557                start = 0; finish = 0;
01558             }
01559             if (finish < start) {
01560                x = finish;
01561                finish = start;
01562                start = x;
01563             }
01564             for (x = start; x <= finish; x++) {
01565                snprintf(tmp, sizeof(tmp), "DAHDI/%d", x);
01566                append_interface(iface, sizeof(iface), tmp);
01567             }
01568             chan = strsep(&c, ",");
01569          }
01570       }
01571       if (!ast_strlen_zero(iface)) {
01572          /* Only create a context here when it is really needed. Otherwise default empty context
01573          created by pbx_config may conflict with the one explicitly created by pbx_ael */
01574          if (!con)
01575             con = ast_context_find_or_create(&local_contexts, local_table, userscontext, registrar);
01576 
01577          if (!con) {
01578             ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext);
01579             return;
01580          }
01581 
01582          /* Add hint */
01583          ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar);
01584          /* If voicemail, use "stdexten" else use plain old dial */
01585          if (hasvoicemail) {
01586             snprintf(tmp, sizeof(tmp), "stdexten,%s,${HINT}", cat);
01587             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", strdup(tmp), ast_free_ptr, registrar);
01588          } else {
01589             ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", strdup("${HINT}"), ast_free_ptr, registrar);
01590          }
01591       }
01592    }
01593    ast_config_destroy(cfg);
01594 }

static int reload ( void   )  [static]

Definition at line 1633 of file pbx_config.c.

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

01634 {
01635    if (clearglobalvars_config)
01636       pbx_builtin_clear_globals();
01637    return pbx_load_module();
01638 }

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

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

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

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

References ast_strdup, and free.

Referenced by complete_dialplan_remove_extension(), and handle_cli_dialplan_remove_extension().

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

static int unload_module ( void   )  [static]

Standard module functions ...

Definition at line 1320 of file pbx_config.c.

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

01321 {
01322    if (static_config && !write_protect_config)
01323       ast_cli_unregister(&cli_dialplan_save);
01324    ast_cli_unregister_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
01325    ast_context_destroy(NULL, registrar);
01326    return 0;
01327 }


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

Definition at line 1644 of file pbx_config.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 1644 of file pbx_config.c.

int autofallthrough_config = 1 [static]

Definition at line 47 of file pbx_config.c.

Referenced by pbx_load_module().

int clearglobalvars_config = 0 [static]

Definition at line 48 of file pbx_config.c.

Referenced by reload().

struct ast_cli_entry cli_dialplan_save [static]

Initial value:

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

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

Referenced by load_module(), and unload_module().

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

Definition at line 41 of file pbx_config.c.

int extenpatternmatchnew_config = 0 [static]

Definition at line 49 of file pbx_config.c.

Referenced by pbx_load_module().

struct ast_context* local_contexts = NULL [static]

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

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

char* registrar = "pbx_config" [static]

Definition at line 42 of file pbx_config.c.

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

Definition at line 51 of file pbx_config.c.

Referenced by handle_cli_dialplan_save().

int static_config = 0 [static]

Definition at line 45 of file pbx_config.c.

Referenced by load_module().

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

Definition at line 43 of file pbx_config.c.

int write_protect_config = 1 [static]

Definition at line 46 of file pbx_config.c.

Referenced by load_module().


Generated on Thu Jul 9 13:41:27 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7