Fri Jun 19 12:10:45 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 BROKEN_READLINE   1
#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 int fix_complete_args (const char *line, char **word, int *pos)
static char * handle_cli_dialplan_add_extension (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 ADD EXTENSION command stuff.
static char * handle_cli_dialplan_add_ignorepat (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_add_include (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_remove_extension (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_remove_ignorepat (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_remove_include (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dialplan_save (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 'save dialplan' CLI command implementation functions ...
static int load_module (void)
static int lookup_c_ip (struct ast_context *c, const char *name)
 return true if 'name' is in the ignorepats for context c
static int lookup_ci (struct ast_context *c, const char *name)
 return true if 'name' is included by context c
static int partial_match (const char *s, const char *word, int len)
 match the first 'len' chars of word. len==0 always succeeds
static int pbx_load_config (const char *config_file)
static int pbx_load_module (void)
static void pbx_load_users (void)
static int reload (void)
static const char * skip_words (const char *p, int n)
 moves to the n-th word in the string, or empty string if none
static int split_ec (const char *src, char **ext, char **const ctx, char **const cid)
 split extension@context in two parts, return -1 on error. The return string is malloc'ed and pointed by *ext
static int unload_module (void)

Variables

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


Detailed Description

Populate and remember extensions from static config file.

Definition in file pbx_config.c.


Define Documentation

#define BROKEN_READLINE   1

Definition at line 392 of file pbx_config.c.

#define PUT_CTX_HDR

Referenced by handle_cli_dialplan_save().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 1743 of file pbx_config.c.

static void __unreg_module ( void   )  [static]

Definition at line 1743 of file pbx_config.c.

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

Definition at line 1576 of file pbx_config.c.

References len().

Referenced by pbx_load_users().

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

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

01084 {
01085    int which = 0;
01086 
01087    if (a->pos == 4) {      /* complete 'into' word ... */
01088       return (a->n == 0) ? strdup("into") : NULL;
01089    } else if (a->pos == 5) { /* complete context */
01090       struct ast_context *c = NULL;
01091       int len = strlen(a->word);
01092       char *res = NULL;
01093 
01094       /* try to lock contexts list ... */
01095       if (ast_rdlock_contexts()) {
01096          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01097          return NULL;
01098       }
01099 
01100       /* walk through all contexts */
01101       while ( !res && (c = ast_walk_contexts(c)) )
01102          if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n)
01103             res = strdup(ast_get_context_name(c));
01104       ast_unlock_contexts();
01105       return res;
01106    } else if (a->pos == 6) {
01107       return a->n == 0 ? strdup("replace") : NULL;
01108    }
01109    return NULL;
01110 }

static char * complete_dialplan_add_ignorepat ( struct ast_cli_args  )  [static]

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

01170 {
01171    if (a->pos == 4)
01172       return a->n == 0 ? strdup("into") : NULL;
01173    else if (a->pos == 5) {
01174       struct ast_context *c;
01175       int which = 0;
01176       char *dupline, *ignorepat = NULL;
01177       const char *s;
01178       char *ret = NULL;
01179       int len = strlen(a->word);
01180 
01181       /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */
01182       s = skip_words(a->line, 3);
01183       if (s == NULL)
01184          return NULL;
01185       dupline = strdup(s);
01186       if (!dupline) {
01187          ast_log(LOG_ERROR, "Malloc failure\n");
01188          return NULL;
01189       }
01190       ignorepat = strsep(&dupline, " ");
01191 
01192       if (ast_rdlock_contexts()) {
01193          ast_log(LOG_ERROR, "Failed to lock contexts list\n");
01194          return NULL;
01195       }
01196 
01197       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01198          int found = 0;
01199 
01200          if (!partial_match(ast_get_context_name(c), a->word, len))
01201             continue; /* not mine */
01202          if (ignorepat) /* there must be one, right ? */
01203             found = lookup_c_ip(c, ignorepat);
01204          if (!found && ++which > a->n)
01205             ret = strdup(ast_get_context_name(c));
01206       }
01207 
01208       if (ignorepat)
01209          free(ignorepat);
01210       ast_unlock_contexts();
01211       return ret;
01212    }
01213 
01214    return NULL;
01215 }

static char * complete_dialplan_add_include ( struct ast_cli_args  )  [static]

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

00644 {
00645    struct ast_context *c;
00646    int which = 0;
00647    char *ret = NULL;
00648    int len = strlen(a->word);
00649 
00650    if (a->pos == 3) {      /* 'dialplan add include _X_' (context) ... */
00651       if (ast_rdlock_contexts()) {
00652          ast_log(LOG_ERROR, "Failed to lock context list\n");
00653          return NULL;
00654       }
00655       for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
00656          if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n)
00657             ret = strdup(ast_get_context_name(c));
00658       ast_unlock_contexts();
00659       return ret;
00660    } else if (a->pos == 4) { /* dialplan add include CTX _X_ */
00661       /* complete  as 'into' if context exists or we are unable to check */
00662       char *context, *dupline;
00663       const char *s = skip_words(a->line, 3); /* should not fail */
00664 
00665       if (a->n != 0) /* only once */
00666          return NULL;
00667 
00668       /* parse context from line ... */
00669       context = dupline = strdup(s);
00670       if (!context) {
00671          ast_log(LOG_ERROR, "Out of free memory\n");
00672          return strdup("into");
00673       }
00674       strsep(&dupline, " ");
00675 
00676       /* check for context existence ... */
00677       if (ast_rdlock_contexts()) {
00678          ast_log(LOG_ERROR, "Failed to lock context list\n");
00679          /* our fault, we can't check, so complete 'into' ... */
00680          ret = strdup("into");
00681       } else {
00682          struct ast_context *ctx;
00683          for (ctx = NULL; !ret && (ctx = ast_walk_contexts(ctx)); )
00684             if (!strcmp(context, ast_get_context_name(ctx)))
00685                ret = strdup("into"); /* found */
00686          ast_unlock_contexts();
00687       }
00688       free(context);
00689       return ret;
00690    } else if (a->pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */
00691       char *context, *dupline, *into;
00692       const char *s = skip_words(a->line, 3); /* should not fail */
00693       context = dupline = strdup(s);
00694       if (!dupline) {
00695          ast_log(LOG_ERROR, "Out of free memory\n");
00696          return NULL;
00697       }
00698       strsep(&dupline, " "); /* skip context */
00699       into = strsep(&dupline, " ");
00700       /* error if missing context or fifth word is not 'into' */
00701       if (!strlen(context) || strcmp(into, "into")) {
00702          ast_log(LOG_ERROR, "bad context %s or missing into %s\n",
00703             context, into);
00704          goto error3;
00705       }
00706 
00707       if (ast_rdlock_contexts()) {
00708          ast_log(LOG_ERROR, "Failed to lock context list\n");
00709          goto error3;
00710       }
00711 
00712       for (c = NULL; (c = ast_walk_contexts(c)); )
00713          if (!strcmp(context, ast_get_context_name(c)))
00714             break;
00715       if (c) { /* first context exists, go on... */
00716          /* go through all contexts ... */
00717          for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
00718             if (!strcmp(context, ast_get_context_name(c)))
00719                continue; /* skip ourselves */
00720             if (partial_match(ast_get_context_name(c), a->word, len) &&
00721                   !lookup_ci(c, context) /* not included yet */ &&
00722                   ++which > a->n)
00723                ret = strdup(ast_get_context_name(c));
00724          }
00725       } else {
00726          ast_log(LOG_ERROR, "context %s not found\n", context);
00727       }
00728       ast_unlock_contexts();
00729    error3:
00730       free(context);
00731       return ret;
00732    }
00733 
00734    return NULL;
00735 }

static char * complete_dialplan_remove_extension ( struct ast_cli_args  )  [static]

Definition at line 439 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, fix_complete_args(), 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().

00440 {
00441    char *ret = NULL;
00442    int which = 0;
00443 
00444 #ifdef BROKEN_READLINE
00445    char *word2;
00446    /*
00447     * Fix arguments, *word is a new allocated structure, REMEMBER to
00448     * free *word when you want to return from this function ...
00449     */
00450    if (fix_complete_args(a->line, &word2, &a->pos)) {
00451       ast_log(LOG_ERROR, "Out of free memory\n");
00452       return NULL;
00453    }
00454    a->word = word2;
00455 #endif
00456 
00457    if (a->pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */
00458       struct ast_context *c = NULL;
00459       char *context = NULL, *exten = NULL, *cid = NULL;
00460       int le = 0; /* length of extension */
00461       int lc = 0; /* length of context */
00462       int lcid = 0; /* length of cid */
00463 
00464       lc = split_ec(a->word, &exten, &context, &cid);
00465       if (lc)  { /* error */
00466 #ifdef BROKEN_READLINE
00467          free(word2);
00468 #endif
00469          return NULL;
00470       }
00471       le = strlen(exten);
00472       lc = strlen(context);
00473       lcid = cid ? strlen(cid) : -1;
00474 
00475       if (ast_rdlock_contexts()) {
00476          ast_log(LOG_ERROR, "Failed to lock context list\n");
00477          goto error2;
00478       }
00479 
00480       /* find our context ... */
00481       while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */
00482          struct ast_exten *e = NULL;
00483          /* XXX locking ? */
00484          if (!partial_match(ast_get_context_name(c), context, lc))
00485             continue;   /* context not matched */
00486          while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */
00487             if ( !strchr(a->word, '/') ||
00488                   (!strchr(a->word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) ||
00489                   (strchr(a->word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) {
00490                if ( ((strchr(a->word, '/') || strchr(a->word, '@')) && !strcmp(ast_get_extension_name(e), exten)) ||
00491                    (!strchr(a->word, '/') && !strchr(a->word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */
00492                   if (++which > a->n) {
00493                      /* If there is an extension then return exten@context. */
00494                      if (ast_get_extension_matchcid(e) && (!strchr(a->word, '@') || strchr(a->word, '/'))) {
00495                         if (asprintf(&ret, "%s/%s@%s", ast_get_extension_name(e), ast_get_extension_cidmatch(e), ast_get_context_name(c)) < 0) {
00496                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00497                            ret = NULL;
00498                         }
00499                         break;
00500                      } else if (!ast_get_extension_matchcid(e) && !strchr(a->word, '/')) {
00501                         if (asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) {
00502                            ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00503                            ret = NULL;
00504                         }
00505                         break;
00506                      }
00507                   }
00508                }
00509             }
00510          }
00511          if (e)   /* got a match */
00512             break;
00513       }
00514 
00515       ast_unlock_contexts();
00516    error2:
00517       if (exten)
00518          free(exten);
00519    } else if (a->pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */
00520       char *exten = NULL, *context, *cid, *p;
00521       struct ast_context *c;
00522       int le, lc, lcid, len;
00523       const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'extension' */
00524       int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */
00525 
00526       if (i)   /* error */
00527          goto error3;
00528       if ( (p = strchr(exten, ' ')) ) /* remove space after extension */
00529          *p = '\0';
00530       if ( (p = strchr(context, ' ')) ) /* remove space after context */
00531          *p = '\0';
00532       le = strlen(exten);
00533       lc = strlen(context);
00534       lcid = strlen(cid);
00535       len = strlen(a->word);
00536       if (le == 0 || lc == 0)
00537          goto error3;
00538 
00539       if (ast_rdlock_contexts()) {
00540          ast_log(LOG_ERROR, "Failed to lock context list\n");
00541          goto error3;
00542       }
00543 
00544       /* walk contexts */
00545       c = NULL;
00546       while ( (c = ast_walk_contexts(c)) ) {
00547          /* XXX locking on c ? */
00548          struct ast_exten *e;
00549          if (strcmp(ast_get_context_name(c), context) != 0)
00550             continue;
00551          /* got it, we must match here */
00552          e = NULL;
00553          while ( (e = ast_walk_context_extensions(c, e)) ) {
00554             struct ast_exten *priority;
00555             char buffer[10];
00556 
00557             if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) {
00558                continue;
00559             }
00560             if (strcmp(ast_get_extension_name(e), exten) != 0)
00561                continue;
00562             /* XXX lock e ? */
00563             priority = NULL;
00564             while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) {
00565                snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority));
00566                if (partial_match(buffer, a->word, len) && ++which > a->n) /* n-th match */
00567                   ret = strdup(buffer);
00568             }
00569             break;
00570          }
00571          break;
00572       }
00573       ast_unlock_contexts();
00574    error3:
00575       if (exten)
00576          free(exten);
00577    }
00578 #ifdef BROKEN_READLINE
00579    free(word2);
00580 #endif
00581    return ret; 
00582 }

static char * complete_dialplan_remove_ignorepat ( struct ast_cli_args  )  [static]

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

01267 {
01268    struct ast_context *c;
01269    int which = 0;
01270    char *ret = NULL;
01271 
01272    if (a->pos == 3) {
01273       int len = strlen(a->word);
01274       if (ast_rdlock_contexts()) {
01275          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01276          return NULL;
01277       }
01278 
01279       for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
01280          struct ast_ignorepat *ip;
01281 
01282          if (ast_rdlock_context(c)) /* error, skip it */
01283             continue;
01284          
01285          for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) {
01286             if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) {
01287                /* n-th match */
01288                struct ast_context *cw = NULL;
01289                int found = 0;
01290                while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) {
01291                   /* XXX do i stop on c, or skip it ? */
01292                   found = lookup_c_ip(cw, ast_get_ignorepat_name(ip));
01293                }
01294                if (!found)
01295                   ret = strdup(ast_get_ignorepat_name(ip));
01296             }
01297          }
01298          ast_unlock_context(c);
01299       }
01300       ast_unlock_contexts();
01301       return ret;
01302    } else if (a->pos == 4) {
01303        return a->n == 0 ? strdup("from") : NULL;
01304    } else if (a->pos == 5) { /* XXX check this */
01305       char *dupline, *duplinet, *ignorepat;
01306       int len = strlen(a->word);
01307 
01308       dupline = strdup(a->line);
01309       if (!dupline) {
01310          ast_log(LOG_WARNING, "Out of free memory\n");
01311          return NULL;
01312       }
01313 
01314       duplinet = dupline;
01315       strsep(&duplinet, " ");
01316       strsep(&duplinet, " ");
01317       ignorepat = strsep(&duplinet, " ");
01318 
01319       if (!ignorepat) {
01320          free(dupline);
01321          return NULL;
01322       }
01323 
01324       if (ast_rdlock_contexts()) {
01325          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
01326          free(dupline);
01327          return NULL;
01328       }
01329 
01330       for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
01331          if (ast_rdlock_context(c)) /* fail, skip it */
01332             continue;
01333          if (!partial_match(ast_get_context_name(c), a->word, len))
01334             continue;
01335          if (lookup_c_ip(c, ignorepat) && ++which > a->n)
01336             ret = strdup(ast_get_context_name(c));
01337          ast_unlock_context(c);
01338       }
01339       ast_unlock_contexts();
01340       free(dupline);
01341       return NULL;
01342    }
01343 
01344    return NULL;
01345 }

static char * complete_dialplan_remove_include ( struct ast_cli_args  )  [static]

Definition at line 182 of file pbx_config.c.

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

Referenced by handle_cli_dialplan_remove_include().

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

static int fix_complete_args ( const char *  line,
char **  word,
int *  pos 
) [static]

Definition at line 407 of file pbx_config.c.

References free, strdup, strsep(), and words.

Referenced by complete_dialplan_remove_extension().

00408 {
00409    char *_line, *_strsep_line, *_previous_word = NULL, *_word = NULL;
00410    int words = 0;
00411 
00412    _line = strdup(line);
00413 
00414    _strsep_line = _line;
00415    while (_strsep_line) {
00416       _previous_word = _word;
00417       _word = strsep(&_strsep_line, " ");
00418 
00419       if (_word && strlen(_word)) words++;
00420    }
00421 
00422 
00423    if (_word || _previous_word) {
00424       if (_word) {
00425          if (!strlen(_word)) words++;
00426          *word = strdup(_word);
00427       } else
00428          *word = strdup(_previous_word);
00429       *pos = words - 1;
00430       free(_line);
00431       return 0;
00432    }
00433 
00434    free(_line);
00435    return -1;
00436 }

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

00971 {
00972    char *whole_exten;
00973    char *exten, *prior;
00974    int iprior = -2;
00975    char *cidmatch, *app, *app_data;
00976    char *start, *end;
00977 
00978    switch (cmd) {
00979    case CLI_INIT:
00980       e->command = "dialplan add extension";
00981       e->usage =
00982          "Usage: dialplan add extension <exten>,<priority>,<app>,<app-data>\n"
00983          "       into <context> [replace]\n\n"
00984          "       This command will add new extension into <context>. If there is an\n"
00985          "       existence of extension with the same priority and last 'replace'\n"
00986          "       arguments is given here we simply replace this extension.\n"
00987          "\n"
00988          "Example: dialplan add extension 6123,1,Dial,IAX/216.207.245.56/6123 into local\n"
00989          "         Now, you can dial 6123 and talk to Markster :)\n";
00990       return NULL;
00991    case CLI_GENERATE:
00992       return complete_dialplan_add_extension(a);
00993    }
00994 
00995    /* check for arguments at first */
00996    if (a->argc != 6 && a->argc != 7)
00997       return CLI_SHOWUSAGE;
00998    if (strcmp(a->argv[4], "into"))
00999       return CLI_SHOWUSAGE;
01000    if (a->argc == 7)
01001       if (strcmp(a->argv[6], "replace"))
01002          return CLI_SHOWUSAGE;
01003 
01004    /* XXX overwrite argv[3] */
01005    whole_exten = a->argv[3];
01006    exten = strsep(&whole_exten,",");
01007    if (strchr(exten, '/')) {
01008       cidmatch = exten;
01009       strsep(&cidmatch,"/");
01010    } else {
01011       cidmatch = NULL;
01012    }
01013    prior = strsep(&whole_exten,",");
01014    if (prior) {
01015       if (!strcmp(prior, "hint")) {
01016          iprior = PRIORITY_HINT;
01017       } else {
01018          if (sscanf(prior, "%d", &iprior) != 1) {
01019             ast_cli(a->fd, "'%s' is not a valid priority\n", prior);
01020             prior = NULL;
01021          }
01022       }
01023    }
01024    app = whole_exten;
01025    if (app && (start = strchr(app, '(')) && (end = strrchr(app, ')'))) {
01026       *start = *end = '\0';
01027       app_data = start + 1;
01028    } else {
01029       if (app) {
01030          app_data = strchr(app, ',');
01031          if (app_data) {
01032             *app_data = '\0';
01033             app_data++;
01034          }
01035       } else   
01036          app_data = NULL;
01037    }
01038 
01039    if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT))
01040       return CLI_SHOWUSAGE;
01041 
01042    if (!app_data)
01043       app_data="";
01044    if (ast_add_extension(a->argv[5], a->argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
01045       (void *)strdup(app_data), ast_free_ptr, registrar)) {
01046       switch (errno) {
01047       case ENOMEM:
01048          ast_cli(a->fd, "Out of free memory\n");
01049          break;
01050 
01051       case EBUSY:
01052          ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
01053          break;
01054 
01055       case ENOENT:
01056          ast_cli(a->fd, "No existence of '%s' context\n", a->argv[5]);
01057          break;
01058 
01059       case EEXIST:
01060          ast_cli(a->fd, "Extension %s@%s with priority %s already exists\n",
01061             exten, a->argv[5], prior);
01062          break;
01063 
01064       default:
01065          ast_cli(a->fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n",
01066                exten, prior, app, app_data, a->argv[5]);
01067          break;
01068       }
01069       return CLI_FAILURE;
01070    }
01071 
01072    if (a->argc == 7)
01073       ast_cli(a->fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n",
01074          exten, a->argv[5], prior, exten, prior, app, app_data);
01075    else
01076       ast_cli(a->fd, "Extension '%s,%s,%s,%s' added into '%s' context\n",
01077          exten, prior, app, app_data, a->argv[5]);
01078 
01079    return CLI_SUCCESS;
01080 }

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

01116 {
01117    switch (cmd) {
01118    case CLI_INIT:
01119       e->command = "dialplan add ignorepat";
01120       e->usage =
01121          "Usage: dialplan add ignorepat <pattern> into <context>\n"
01122          "       This command adds a new ignore pattern into context <context>\n"
01123          "\n"
01124          "Example: dialplan add ignorepat _3XX into local\n";
01125       return NULL;
01126    case CLI_GENERATE:
01127       return complete_dialplan_add_ignorepat(a);
01128    }
01129 
01130    if (a->argc != 6)
01131       return CLI_SHOWUSAGE;
01132 
01133    if (strcmp(a->argv[4], "into"))
01134       return CLI_SHOWUSAGE;
01135 
01136    if (ast_context_add_ignorepat(a->argv[5], a->argv[3], registrar)) {
01137       switch (errno) {
01138       case ENOMEM:
01139          ast_cli(a->fd, "Out of free memory\n");
01140          break;
01141 
01142       case ENOENT:
01143          ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]);
01144          break;
01145 
01146       case EEXIST:
01147          ast_cli(a->fd, "Ignore pattern '%s' already included in '%s' context\n",
01148             a->argv[3], a->argv[5]);
01149          break;
01150 
01151       case EBUSY:
01152          ast_cli(a->fd, "Failed to lock context(s) list, please, try again later\n");
01153          break;
01154 
01155       default:
01156          ast_cli(a->fd, "Failed to add ingore pattern '%s' into '%s' context\n",
01157             a->argv[3], a->argv[5]);
01158          break;
01159       }
01160       return CLI_FAILURE;
01161    }
01162 
01163    ast_cli(a->fd, "Ignore pattern '%s' added into '%s' context\n",
01164       a->argv[3], a->argv[5]);
01165 
01166    return CLI_SUCCESS;
01167 }

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

00588 {
00589    switch (cmd) {
00590    case CLI_INIT:
00591       e->command = "dialplan add include";
00592       e->usage =
00593          "Usage: dialplan add include <context> into <context>\n"
00594          "       Include a context in another context.\n";
00595       return NULL;
00596    case CLI_GENERATE:
00597       return complete_dialplan_add_include(a);
00598    }
00599 
00600    if (a->argc != 6) /* dialplan add include CTX in CTX */
00601       return CLI_SHOWUSAGE;
00602 
00603    /* fifth arg must be 'into' ... */
00604    if (strcmp(a->argv[4], "into"))
00605       return CLI_SHOWUSAGE;
00606 
00607    if (ast_context_add_include(a->argv[5], a->argv[3], registrar)) {
00608       switch (errno) {
00609       case ENOMEM:
00610          ast_cli(a->fd, "Out of memory for context addition\n");
00611          break;
00612 
00613       case EBUSY:
00614          ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
00615          break;
00616 
00617       case EEXIST:
00618          ast_cli(a->fd, "Context '%s' already included in '%s' context\n",
00619             a->argv[3], a->argv[5]);
00620          break;
00621 
00622       case ENOENT:
00623       case EINVAL:
00624          ast_cli(a->fd, "There is no existence of context '%s'\n",
00625             errno == ENOENT ? a->argv[5] : a->argv[3]);
00626          break;
00627 
00628       default:
00629          ast_cli(a->fd, "Failed to include '%s' in '%s' context\n",
00630             a->argv[3], a->argv[5]);
00631          break;
00632       }
00633       return CLI_FAILURE;
00634    }
00635 
00636    /* show some info ... */
00637    ast_cli(a->fd, "Context '%s' included in '%s' context\n",
00638       a->argv[3], a->argv[5]);
00639 
00640    return CLI_SUCCESS;
00641 }

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

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

01350 {
01351    switch (cmd) {
01352    case CLI_INIT:
01353       e->command = "dialplan reload";
01354       e->usage =
01355          "Usage: dialplan reload\n"
01356          "       Reload extensions.conf without reloading any other\n"
01357          "       modules.  This command does not delete global variables\n"
01358          "       unless clearglobalvars is set to yes in extensions.conf\n";
01359       return NULL;
01360    case CLI_GENERATE:
01361       return NULL;
01362    }
01363 
01364    if (a->argc != 2)
01365       return CLI_SHOWUSAGE;
01366 
01367    if (clearglobalvars_config)
01368       pbx_builtin_clear_globals();
01369 
01370    pbx_load_module();
01371    ast_cli(a->fd, "Dialplan reloaded.\n");
01372    return CLI_SUCCESS;
01373 }

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

REMOVE EXTENSION command stuff

Definition at line 305 of file pbx_config.c.

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

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

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

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

01218 {
01219    switch (cmd) {
01220    case CLI_INIT:
01221       e->command = "dialplan remove ignorepat";
01222       e->usage =
01223          "Usage: dialplan remove ignorepat <pattern> from <context>\n"
01224          "       This command removes an ignore pattern from context <context>\n"
01225          "\n"
01226          "Example: dialplan remove ignorepat _3XX from local\n";
01227       return NULL;
01228    case CLI_GENERATE:
01229       return complete_dialplan_remove_ignorepat(a);
01230    }
01231 
01232    if (a->argc != 6)
01233       return CLI_SHOWUSAGE;
01234 
01235    if (strcmp(a->argv[4], "from"))
01236       return CLI_SHOWUSAGE;
01237 
01238    if (ast_context_remove_ignorepat(a->argv[5], a->argv[3], registrar)) {
01239       switch (errno) {
01240       case EBUSY:
01241          ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
01242          break;
01243 
01244       case ENOENT:
01245          ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]);
01246          break;
01247 
01248       case EINVAL:
01249          ast_cli(a->fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
01250                a->argv[3], a->argv[5]);
01251          break;
01252 
01253       default:
01254          ast_cli(a->fd, "Failed to remove ignore pattern '%s' from '%s' context\n",
01255                a->argv[3], a->argv[5]);
01256          break;
01257       }
01258       return CLI_FAILURE;
01259    }
01260 
01261    ast_cli(a->fd, "Ignore pattern '%s' removed from '%s' context\n",
01262       a->argv[3], a->argv[5]);
01263    return CLI_SUCCESS;
01264 }

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

REMOVE INCLUDE command stuff

Definition at line 73 of file pbx_config.c.

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

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

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

'save dialplan' CLI command implementation functions ...

Definition at line 740 of file pbx_config.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_config_AST_CONFIG_DIR, ast_config_destroy(), ast_config_load, ast_get_context_name(), ast_get_context_registrar(), ast_get_extension_app(), ast_get_extension_app_data(), ast_get_extension_cidmatch(), ast_get_extension_label(), ast_get_extension_matchcid(), ast_get_extension_name(), ast_get_extension_priority(), ast_get_extension_registrar(), ast_get_ignorepat_name(), ast_get_ignorepat_registrar(), ast_get_include_name(), ast_get_include_registrar(), ast_get_switch_data(), ast_get_switch_name(), ast_get_switch_registrar(), ast_mutex_lock(), ast_mutex_unlock(), ast_rdlock_context(), ast_rdlock_contexts(), ast_strlen_zero(), ast_unlock_context(), ast_unlock_contexts(), ast_variable_browse(), ast_walk_context_extensions(), ast_walk_context_ignorepats(), ast_walk_context_includes(), ast_walk_context_switches(), ast_walk_contexts(), ast_walk_extension_priorities(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, config_flags, el, ext, ast_cli_args::fd, ast_variable::name, ast_variable::next, overrideswitch, PRIORITY_HINT, PUT_CTX_HDR, save_dialplan_lock, ast_cli_entry::usage, and ast_variable::value.

00741 {
00742    char filename[256], overrideswitch[256] = "";
00743    struct ast_context *c;
00744    struct ast_config *cfg;
00745    struct ast_variable *v;
00746    int incomplete = 0; /* incomplete config write? */
00747    FILE *output;
00748    struct ast_flags config_flags = { 0 };
00749    const char *base, *slash, *file;
00750 
00751    switch (cmd) {
00752    case CLI_INIT:
00753       e->command = "dialplan save";
00754       e->usage =
00755          "Usage: dialplan save [/path/to/extension/file]\n"
00756          "       Save dialplan created by pbx_config module.\n"
00757          "\n"
00758          "Example: dialplan save                 (/etc/asterisk/extensions.conf)\n"
00759          "         dialplan save /home/markster  (/home/markster/extensions.conf)\n";
00760       return NULL;
00761    case CLI_GENERATE:
00762       return NULL;
00763    }
00764 
00765    if (! (static_config && !write_protect_config)) {
00766       ast_cli(a->fd,
00767          "I can't save dialplan now, see '%s' example file.\n",
00768          config);
00769       return CLI_FAILURE;
00770    }
00771 
00772    if (a->argc != 2 && a->argc != 3)
00773       return CLI_SHOWUSAGE;
00774 
00775    if (ast_mutex_lock(&save_dialplan_lock)) {
00776       ast_cli(a->fd,
00777          "Failed to lock dialplan saving (another proccess saving?)\n");
00778       return CLI_FAILURE;
00779    }
00780    /* XXX the code here is quite loose, a pathname with .conf in it
00781     * is assumed to be a complete pathname
00782     */
00783    if (a->argc == 3) {  /* have config path. Look for *.conf */
00784       base = a->argv[2];
00785       if (!strstr(a->argv[2], ".conf")) { /*no, this is assumed to be a pathname */
00786          /* if filename ends with '/', do not add one */
00787          slash = (*(a->argv[2] + strlen(a->argv[2]) -1) == '/') ? "/" : "";
00788          file = config; /* default: 'extensions.conf' */
00789       } else { /* yes, complete file name */
00790          slash = "";
00791          file = "";
00792       }
00793    } else {
00794       /* no config file, default one */
00795       base = ast_config_AST_CONFIG_DIR;
00796       slash = "/";
00797       file = config;
00798    }
00799    snprintf(filename, sizeof(filename), "%s%s%s", base, slash, config);
00800 
00801    cfg = ast_config_load("extensions.conf", config_flags);
00802 
00803    /* try to lock contexts list */
00804    if (ast_rdlock_contexts()) {
00805       ast_cli(a->fd, "Failed to lock contexts list\n");
00806       ast_mutex_unlock(&save_dialplan_lock);
00807       ast_config_destroy(cfg);
00808       return CLI_FAILURE;
00809    }
00810 
00811    /* create new file ... */
00812    if (!(output = fopen(filename, "wt"))) {
00813       ast_cli(a->fd, "Failed to create file '%s'\n",
00814          filename);
00815       ast_unlock_contexts();
00816       ast_mutex_unlock(&save_dialplan_lock);
00817       ast_config_destroy(cfg);
00818       return CLI_FAILURE;
00819    }
00820 
00821    /* fireout general info */
00822    if (overrideswitch_config) {
00823       snprintf(overrideswitch, sizeof(overrideswitch), "overrideswitch=%s\n", overrideswitch_config);
00824    }
00825    fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\n%sextenpatternmatchnew=%s\n\n",
00826       static_config ? "yes" : "no",
00827       write_protect_config ? "yes" : "no",
00828                 autofallthrough_config ? "yes" : "no",
00829             clearglobalvars_config ? "yes" : "no",
00830             overrideswitch_config ? overrideswitch : "",
00831             extenpatternmatchnew_config ? "yes" : "no");
00832 
00833    if ((v = ast_variable_browse(cfg, "globals"))) {
00834       fprintf(output, "[globals]\n");
00835       while(v) {
00836          fprintf(output, "%s => %s\n", v->name, v->value);
00837          v = v->next;
00838       }
00839       fprintf(output, "\n");
00840    }
00841 
00842    ast_config_destroy(cfg);
00843    
00844 #define PUT_CTX_HDR  do { \
00845    if (!context_header_written) {   \
00846       fprintf(output, "[%s]\n", ast_get_context_name(c));   \
00847       context_header_written = 1;   \
00848    }  \
00849    } while (0)
00850 
00851    /* walk all contexts */
00852    for (c = NULL; (c = ast_walk_contexts(c)); ) {
00853       int context_header_written = 0;
00854       struct ast_exten *ext, *last_written_e = NULL;
00855       struct ast_include *i;
00856       struct ast_ignorepat *ip;
00857       struct ast_sw *sw;
00858 
00859       /* try to lock context and fireout all info */  
00860       if (ast_rdlock_context(c)) { /* lock failure */
00861          incomplete = 1;
00862          continue;
00863       }
00864       /* registered by this module? */
00865       /* XXX do we need this ? */
00866       if (!strcmp(ast_get_context_registrar(c), registrar)) {
00867          fprintf(output, "[%s]\n", ast_get_context_name(c));
00868          context_header_written = 1;
00869       }
00870 
00871       /* walk extensions ... */
00872       for (ext = NULL; (ext = ast_walk_context_extensions(c, ext)); ) {
00873          struct ast_exten *p = NULL;
00874 
00875          /* fireout priorities */
00876          while ( (p = ast_walk_extension_priorities(ext, p)) ) {
00877             if (strcmp(ast_get_extension_registrar(p), registrar) != 0) /* not this source */
00878                continue;
00879       
00880             /* make empty line between different extensions */ 
00881             if (last_written_e != NULL &&
00882                    strcmp(ast_get_extension_name(last_written_e),
00883                       ast_get_extension_name(p)))
00884                fprintf(output, "\n");
00885             last_written_e = p;
00886          
00887             PUT_CTX_HDR;
00888 
00889             if (ast_get_extension_priority(p) == PRIORITY_HINT) { /* easy */
00890                fprintf(output, "exten => %s,hint,%s\n",
00891                       ast_get_extension_name(p),
00892                       ast_get_extension_app(p));
00893             } else {
00894                const char *sep, *cid;
00895                const char *el = ast_get_extension_label(p);
00896                char label[128] = "";
00897  
00898                if (ast_get_extension_matchcid(p)) {
00899                   sep = "/";
00900                   cid = ast_get_extension_cidmatch(p);
00901                } else
00902                   sep = cid = "";
00903             
00904                if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2)))
00905                   incomplete = 1;   /* error encountered or label > 125 chars */
00906                
00907                fprintf(output, "exten => %s%s%s,%d%s,%s(%s)\n",
00908                    ast_get_extension_name(p), (ast_strlen_zero(sep) ? "" : sep), (ast_strlen_zero(cid) ? "" : cid),
00909                    ast_get_extension_priority(p), label,
00910                    ast_get_extension_app(p), (ast_strlen_zero(ast_get_extension_app_data(p)) ? "" : (const char *)ast_get_extension_app_data(p)));
00911             }
00912          }
00913       }
00914 
00915       /* written any extensions? ok, write space between exten & inc */
00916       if (last_written_e)
00917          fprintf(output, "\n");
00918 
00919       /* walk through includes */
00920       for (i = NULL; (i = ast_walk_context_includes(c, i)) ; ) {
00921          if (strcmp(ast_get_include_registrar(i), registrar) != 0)
00922             continue; /* not mine */
00923          PUT_CTX_HDR;
00924          fprintf(output, "include => %s\n", ast_get_include_name(i));
00925       }
00926       if (ast_walk_context_includes(c, NULL))
00927          fprintf(output, "\n");
00928 
00929       /* walk through switches */
00930       for (sw = NULL; (sw = ast_walk_context_switches(c, sw)) ; ) {
00931          if (strcmp(ast_get_switch_registrar(sw), registrar) != 0)
00932             continue; /* not mine */
00933          PUT_CTX_HDR;
00934          fprintf(output, "switch => %s/%s\n",
00935                 ast_get_switch_name(sw), ast_get_switch_data(sw));
00936       }
00937 
00938       if (ast_walk_context_switches(c, NULL))
00939          fprintf(output, "\n");
00940 
00941       /* fireout ignorepats ... */
00942       for (ip = NULL; (ip = ast_walk_context_ignorepats(c, ip)); ) {
00943          if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0)
00944             continue; /* not mine */
00945          PUT_CTX_HDR;
00946          fprintf(output, "ignorepat => %s\n",
00947                   ast_get_ignorepat_name(ip));
00948       }
00949 
00950       ast_unlock_context(c);
00951    }  
00952 
00953    ast_unlock_contexts();
00954    ast_mutex_unlock(&save_dialplan_lock);
00955    fclose(output);
00956 
00957    if (incomplete) {
00958       ast_cli(a->fd, "Saved dialplan is incomplete\n");
00959       return CLI_FAILURE;
00960    }
00961 
00962    ast_cli(a->fd, "Dialplan successfully saved into '%s'\n",
00963       filename);
00964    return CLI_SUCCESS;
00965 }

static int load_module ( void   )  [static]

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

01721 {
01722    if (pbx_load_module())
01723       return AST_MODULE_LOAD_DECLINE;
01724  
01725    if (static_config && !write_protect_config)
01726       ast_cli_register(&cli_dialplan_save);
01727    ast_cli_register_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
01728 
01729    return AST_MODULE_LOAD_SUCCESS;
01730 }

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

return true if 'name' is in the ignorepats for context c

Definition at line 115 of file pbx_config.c.

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

Referenced by complete_dialplan_add_ignorepat(), and complete_dialplan_remove_ignorepat().

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

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

return true if 'name' is included by context c

Definition at line 101 of file pbx_config.c.

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

Referenced by complete_dialplan_add_include(), and complete_dialplan_remove_include().

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

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

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

Definition at line 144 of file pbx_config.c.

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

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

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

Definition at line 1406 of file pbx_config.c.

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

Referenced by pbx_load_module().

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

static int pbx_load_module ( void   )  [static]

Definition at line 1694 of file pbx_config.c.

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

01695 {
01696    struct ast_context *con;
01697 
01698    if (!local_table)
01699       local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
01700 
01701    if (!pbx_load_config(config))
01702       return AST_MODULE_LOAD_DECLINE;
01703    
01704    pbx_load_users();
01705 
01706    ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
01707    local_table = NULL; /* the local table has been moved into the global one. */
01708    local_contexts = NULL;
01709 
01710    for (con = NULL; (con = ast_walk_contexts(con));)
01711       ast_context_verify_includes(con);
01712 
01713    pbx_set_overrideswitch(overrideswitch_config);
01714    pbx_set_autofallthrough(autofallthrough_config);
01715    pbx_set_extenpatternmatchnew(extenpatternmatchnew_config);
01716 
01717    return AST_MODULE_LOAD_SUCCESS;
01718 }

static void pbx_load_users ( void   )  [static]

Definition at line 1588 of file pbx_config.c.

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

Referenced by pbx_load_module().

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

static int reload ( void   )  [static]

Definition at line 1732 of file pbx_config.c.

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

01733 {
01734    if (clearglobalvars_config)
01735       pbx_builtin_clear_globals();
01736    return pbx_load_module();
01737 }

static const char* skip_words ( const char *  p,
int  n 
) [static]

moves to the n-th word in the string, or empty string if none

Definition at line 129 of file pbx_config.c.

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

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

static int split_ec ( const char *  src,
char **  ext,
char **const   ctx,
char **const   cid 
) [static]

split extension@context in two parts, return -1 on error. The return string is malloc'ed and pointed by *ext

Definition at line 152 of file pbx_config.c.

References ast_strdup, and free.

Referenced by complete_dialplan_remove_extension(), and handle_cli_dialplan_remove_extension().

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

static int unload_module ( void   )  [static]

Standard module functions ...

Definition at line 1394 of file pbx_config.c.

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

01395 {
01396    if (static_config && !write_protect_config)
01397       ast_cli_unregister(&cli_dialplan_save);
01398    if (overrideswitch_config) {
01399       ast_free(overrideswitch_config);
01400    }
01401    ast_cli_unregister_multiple(cli_pbx_config, sizeof(cli_pbx_config) / sizeof(struct ast_cli_entry));
01402    ast_context_destroy(NULL, registrar);
01403    return 0;
01404 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Text Extension Configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 1743 of file pbx_config.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 1743 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 1388 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 1378 of file pbx_config.c.

Referenced by load_module(), and unload_module().

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

Definition at line 41 of file pbx_config.c.

int extenpatternmatchnew_config = 0 [static]

Definition at line 49 of file pbx_config.c.

Referenced by pbx_load_module().

struct ast_context* local_contexts = NULL [static]

Definition at line 54 of file pbx_config.c.

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

struct ast_hashtab* local_table = NULL [static]

Definition at line 55 of file pbx_config.c.

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

char* overrideswitch_config = NULL [static]

Definition at line 50 of file pbx_config.c.

Referenced by pbx_load_module().

char* registrar = "pbx_config" [static]

Definition at line 42 of file pbx_config.c.

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

Definition at line 52 of file pbx_config.c.

Referenced by handle_cli_dialplan_save().

int static_config = 0 [static]

Definition at line 45 of file pbx_config.c.

Referenced by load_module().

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

Definition at line 43 of file pbx_config.c.

int write_protect_config = 1 [static]

Definition at line 46 of file pbx_config.c.

Referenced by load_module().


Generated on Fri Jun 19 12:10:45 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7