Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
pbx_config.c File Reference

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

#include "asterisk.h"
#include <ctype.h>
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
Include dependency graph for pbx_config.c:

Go to the source code of this file.

Macros

#define AMI_EXTENSION_ADD   "DialplanExtensionAdd"
 
#define AMI_EXTENSION_REMOVE   "DialplanExtensionRemove"
 
#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)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
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_context (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. More...
 
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_context (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 ... More...
 
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 More...
 
static int lookup_ci (struct ast_context *c, const char *name)
 return true if 'name' is included by context c More...
 
static int manager_dialplan_extension_add (struct mansession *s, const struct message *m)
 
static int manager_dialplan_extension_remove (struct mansession *s, const struct message *m)
 
static int partial_match (const char *s, const char *word, int len)
 match the first 'len' chars of word. len==0 always succeeds More...
 
static int pbx_load_config (const char *config_file)
 
static int pbx_load_module (void)
 
static void pbx_load_users (void)
 
static char * pbx_strsep (char **destructible, const char *delim)
 
static int reload (void)
 
static const char * skip_words (const char *p, int n)
 moves to the n-th word in the string, or empty string if none More...
 
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 More...
 
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .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 const char config [] = "extensions.conf"
 
static int extenpatternmatchnew_config = 0
 
static struct ast_contextlocal_contexts = NULL
 
static struct ast_hashtablocal_table = NULL
 
static char * overrideswitch_config = NULL
 
static const char registrar [] = "pbx_config"
 
static ast_mutex_t reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static ast_mutex_t save_dialplan_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
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.

Macro Definition Documentation

◆ AMI_EXTENSION_ADD

#define AMI_EXTENSION_ADD   "DialplanExtensionAdd"

Definition at line 1619 of file pbx_config.c.

Referenced by load_module(), and unload_module().

◆ AMI_EXTENSION_REMOVE

#define AMI_EXTENSION_REMOVE   "DialplanExtensionRemove"

Definition at line 1620 of file pbx_config.c.

Referenced by load_module(), and unload_module().

◆ PUT_CTX_HDR

#define PUT_CTX_HDR

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 2164 of file pbx_config.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 2164 of file pbx_config.c.

◆ append_interface()

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

Definition at line 1965 of file pbx_config.c.

References len().

Referenced by pbx_load_users().

1966 {
1967  int len = strlen(iface);
1968  if (strlen(add) + len < maxlen - 2) {
1969  if (strlen(iface)) {
1970  iface[len] = '&';
1971  strcpy(iface + len + 1, add);
1972  } else
1973  strcpy(iface, add);
1974  }
1975 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 2164 of file pbx_config.c.

◆ complete_dialplan_add_extension()

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

References ast_get_context_name(), ast_log, ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), ast_walk_contexts(), c, len(), LOG_WARNING, ast_cli_args::n, NULL, partial_match(), ast_cli_args::pos, and ast_cli_args::word.

Referenced by handle_cli_dialplan_add_extension().

1307 {
1308  int which = 0;
1309 
1310  if (a->pos == 4) { /* complete 'into' word ... */
1311  return (a->n == 0) ? ast_strdup("into") : NULL;
1312  } else if (a->pos == 5) { /* complete context */
1313  struct ast_context *c = NULL;
1314  int len = strlen(a->word);
1315  char *res = NULL;
1316 
1317  /* try to lock contexts list ... */
1318  if (ast_rdlock_contexts()) {
1319  ast_log(LOG_WARNING, "Failed to lock contexts list\n");
1320  return NULL;
1321  }
1322 
1323  /* walk through all contexts */
1324  while ( !res && (c = ast_walk_contexts(c)) )
1325  if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n)
1326  res = ast_strdup(ast_get_context_name(c));
1328  return res;
1329  } else if (a->pos == 6) {
1330  return a->n == 0 ? ast_strdup("replace") : NULL;
1331  }
1332  return NULL;
1333 }
const char * ast_get_context_name(struct ast_context *con)
Definition: ael_main.c:421
#define LOG_WARNING
Definition: logger.h:274
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: conf2ael.c:618
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:8507
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static int partial_match(const char *s, const char *word, int len)
match the first &#39;len&#39; chars of word. len==0 always succeeds
Definition: pbx_config.c:251
#define ast_log
Definition: astobj2.c:42
const int n
Definition: cli.h:165
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8512
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const char * word
Definition: cli.h:163
const int pos
Definition: cli.h:164
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284

◆ complete_dialplan_add_ignorepat()

static char * complete_dialplan_add_ignorepat ( struct ast_cli_args a)
static

Definition at line 1392 of file pbx_config.c.

References ast_free, ast_get_context_name(), ast_log, ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), ast_walk_contexts(), c, len(), ast_cli_args::line, LOG_ERROR, lookup_c_ip(), ast_cli_args::n, NULL, partial_match(), ast_cli_args::pos, skip_words(), strsep(), and ast_cli_args::word.

Referenced by handle_cli_dialplan_add_ignorepat().

1393 {
1394  if (a->pos == 4)
1395  return a->n == 0 ? ast_strdup("into") : NULL;
1396  else if (a->pos == 5) {
1397  struct ast_context *c;
1398  int which = 0;
1399  char *dupline, *ignorepat = NULL;
1400  const char *s;
1401  char *ret = NULL;
1402  int len = strlen(a->word);
1403 
1404  /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */
1405  s = skip_words(a->line, 3);
1406  if (s == NULL)
1407  return NULL;
1408  dupline = ast_strdup(s);
1409  if (!dupline) {
1410  ast_log(LOG_ERROR, "Malloc failure\n");
1411  return NULL;
1412  }
1413  ignorepat = strsep(&dupline, " ");
1414 
1415  if (ast_rdlock_contexts()) {
1416  ast_log(LOG_ERROR, "Failed to lock contexts list\n");
1417  return NULL;
1418  }
1419 
1420  for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
1421  int found = 0;
1422 
1424  continue; /* not mine */
1425  if (ignorepat) /* there must be one, right ? */
1426  found = lookup_c_ip(c, ignorepat);
1427  if (!found && ++which > a->n)
1428  ret = ast_strdup(ast_get_context_name(c));
1429  }
1430 
1431  ast_free(ignorepat);
1433  return ret;
1434  }
1435 
1436  return NULL;
1437 }
const char * ast_get_context_name(struct ast_context *con)
Definition: ael_main.c:421
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: conf2ael.c:618
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:8507
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static int partial_match(const char *s, const char *word, int len)
match the first &#39;len&#39; chars of word. len==0 always succeeds
Definition: pbx_config.c:251
const char * line
Definition: cli.h:162
#define ast_log
Definition: astobj2.c:42
const int n
Definition: cli.h:165
static int lookup_c_ip(struct ast_context *c, const char *name)
return true if &#39;name&#39; is in the ignorepats for context c
Definition: pbx_config.c:212
#define LOG_ERROR
Definition: logger.h:285
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8512
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
const char * word
Definition: cli.h:163
char * strsep(char **str, const char *delims)
const int pos
Definition: cli.h:164
static const char * skip_words(const char *p, int n)
moves to the n-th word in the string, or empty string if none
Definition: pbx_config.c:236
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284

◆ complete_dialplan_add_include()

static char * complete_dialplan_add_include ( struct ast_cli_args a)
static

Definition at line 744 of file pbx_config.c.

References ast_free, ast_get_context_name(), ast_log, ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), ast_walk_contexts(), c, context, len(), ast_cli_args::line, LOG_ERROR, lookup_ci(), ast_cli_args::n, NULL, partial_match(), ast_cli_args::pos, skip_words(), strsep(), and ast_cli_args::word.

Referenced by handle_cli_dialplan_add_include().

745 {
746  struct ast_context *c;
747  int which = 0;
748  char *ret = NULL;
749  int len = strlen(a->word);
750 
751  if (a->pos == 3) { /* 'dialplan add include _X_' (context) ... */
752  if (ast_rdlock_contexts()) {
753  ast_log(LOG_ERROR, "Failed to lock context list\n");
754  return NULL;
755  }
756  for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
757  if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n)
760  return ret;
761  } else if (a->pos == 4) { /* dialplan add include CTX _X_ */
762  /* always complete as 'into' */
763  return (a->n == 0) ? ast_strdup("into") : NULL;
764  } else if (a->pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */
765  char *context, *dupline, *into;
766  const char *s = skip_words(a->line, 3); /* should not fail */
767  context = dupline = ast_strdup(s);
768 
769  if (!dupline) {
770  ast_log(LOG_ERROR, "Out of free memory\n");
771  return NULL;
772  }
773 
774  strsep(&dupline, " "); /* skip context */
775  into = strsep(&dupline, " ");
776  /* error if missing context or fifth word is not 'into' */
777  if (!strlen(context) || strcmp(into, "into")) {
778  ast_log(LOG_ERROR, "bad context %s or missing into %s\n",
779  context, into);
780  goto error3;
781  }
782 
783  if (ast_rdlock_contexts()) {
784  ast_log(LOG_ERROR, "Failed to lock context list\n");
785  goto error3;
786  }
787 
788  for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
789  if (!strcmp(context, ast_get_context_name(c)))
790  continue; /* skip ourselves */
792  !lookup_ci(c, context) /* not included yet */ &&
793  ++which > a->n) {
795  }
796  }
798  error3:
799  ast_free(context);
800  return ret;
801  }
802 
803  return NULL;
804 }
const char * ast_get_context_name(struct ast_context *con)
Definition: ael_main.c:421
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: conf2ael.c:618
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:8507
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static int partial_match(const char *s, const char *word, int len)
match the first &#39;len&#39; chars of word. len==0 always succeeds
Definition: pbx_config.c:251
const char * line
Definition: cli.h:162
static int lookup_ci(struct ast_context *c, const char *name)
return true if &#39;name&#39; is included by context c
Definition: pbx_config.c:188
#define ast_log
Definition: astobj2.c:42
const int n
Definition: cli.h:165
#define LOG_ERROR
Definition: logger.h:285
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8512
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
const char * word
Definition: cli.h:163
char * strsep(char **str, const char *delims)
const int pos
Definition: cli.h:164
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
static const char * skip_words(const char *p, int n)
moves to the n-th word in the string, or empty string if none
Definition: pbx_config.c:236
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284

◆ complete_dialplan_remove_context()

static char * complete_dialplan_remove_context ( struct ast_cli_args a)
static

Definition at line 1277 of file pbx_config.c.

References ast_get_context_name(), ast_log, ast_rdlock_contexts(), ast_strdup, ast_unlock_contexts(), ast_walk_contexts(), c, len(), LOG_WARNING, ast_cli_args::n, NULL, partial_match(), ast_cli_args::pos, and ast_cli_args::word.

Referenced by handle_cli_dialplan_remove_context().

1278 {
1279  struct ast_context *c = NULL;
1280  int len = strlen(a->word);
1281  char *res = NULL;
1282  int which = 0;
1283 
1284  if (a->pos != 3) {
1285  return NULL;
1286  }
1287 
1288 
1289  /* try to lock contexts list ... */
1290  if (ast_rdlock_contexts()) {
1291  ast_log(LOG_WARNING, "Failed to lock contexts list\n");
1292  return NULL;
1293  }
1294 
1295  /* walk through all contexts */
1296  while ( !res && (c = ast_walk_contexts(c)) ) {
1297  if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n) {
1298  res = ast_strdup(ast_get_context_name(c));
1299  }
1300  }
1302  return res;
1303 }
const char * ast_get_context_name(struct ast_context *con)
Definition: ael_main.c:421
#define LOG_WARNING
Definition: logger.h:274
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: conf2ael.c:618
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:8507
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static int partial_match(const char *s, const char *word, int len)
match the first &#39;len&#39; chars of word. len==0 always succeeds
Definition: pbx_config.c:251
#define ast_log
Definition: astobj2.c:42
const int n
Definition: cli.h:165
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8512
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const char * word
Definition: cli.h:163
const int pos
Definition: cli.h:164
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284

◆ complete_dialplan_remove_extension()

static char * complete_dialplan_remove_extension ( struct ast_cli_args a)
static

Definition at line 550 of file pbx_config.c.

References ast_asprintf, ast_free, 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_strdup, ast_unlock_contexts(), ast_walk_context_extensions(), ast_walk_contexts(), ast_walk_extension_priorities(), c, context, exten, len(), ast_cli_args::line, LOG_ERROR, ast_cli_args::n, NULL, partial_match(), ast_cli_args::pos, priority, skip_words(), split_ec(), and ast_cli_args::word.

Referenced by handle_cli_dialplan_remove_extension().

551 {
552  char *ret = NULL;
553  int which = 0;
554 
555  if (a->pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */
556  struct ast_context *c = NULL;
557  char *context = NULL, *exten = NULL, *cid = NULL;
558  int le = 0; /* length of extension */
559  int lc = 0; /* length of context */
560  int lcid = 0; /* length of cid */
561 
562  lc = split_ec(a->word, &exten, &context, &cid);
563  if (lc) { /* error */
564  return NULL;
565  }
566  le = strlen(exten);
567  lc = strlen(context);
568  lcid = cid ? strlen(cid) : -1;
569 
570  if (ast_rdlock_contexts()) {
571  ast_log(LOG_ERROR, "Failed to lock context list\n");
572  goto error2;
573  }
574 
575  /* find our context ... */
576  while ( (c = ast_walk_contexts(c)) ) { /* match our context if any */
577  struct ast_exten *e = NULL;
578  /* XXX locking ? */
579  if (!partial_match(ast_get_context_name(c), context, lc))
580  continue; /* context not matched */
581  while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */
582  if ( !strchr(a->word, '/') ||
583  (!strchr(a->word, '@') && partial_match(ast_get_extension_cidmatch(e), cid, lcid)) ||
584  (strchr(a->word, '@') && !strcmp(ast_get_extension_cidmatch(e), cid))) {
585  if ( ((strchr(a->word, '/') || strchr(a->word, '@')) && !strcmp(ast_get_extension_name(e), exten)) ||
586  (!strchr(a->word, '/') && !strchr(a->word, '@') && partial_match(ast_get_extension_name(e), exten, le))) { /* n-th match */
587  if (++which > a->n) {
588  /* If there is an extension then return exten@context. */
589  if (ast_get_extension_matchcid(e) && (!strchr(a->word, '@') || strchr(a->word, '/'))) {
591  ret = NULL;
592  }
593  break;
594  } else if (!ast_get_extension_matchcid(e) && !strchr(a->word, '/')) {
595  if (ast_asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c)) < 0) {
596  ret = NULL;
597  }
598  break;
599  }
600  }
601  }
602  }
603  }
604  if (e) /* got a match */
605  break;
606  }
607 
609  error2:
610  ast_free(exten);
611  } else if (a->pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */
612  char *exten = NULL, *context, *cid, *p;
613  struct ast_context *c;
614  int le, lc, len;
615  const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'extension' */
616  int i = split_ec(s, &exten, &context, &cid); /* parse ext@context */
617 
618  if (i) /* error */
619  goto error3;
620  if ( (p = strchr(exten, ' ')) ) /* remove space after extension */
621  *p = '\0';
622  if ( (p = strchr(context, ' ')) ) /* remove space after context */
623  *p = '\0';
624  le = strlen(exten);
625  lc = strlen(context);
626  len = strlen(a->word);
627  if (le == 0 || lc == 0)
628  goto error3;
629 
630  if (ast_rdlock_contexts()) {
631  ast_log(LOG_ERROR, "Failed to lock context list\n");
632  goto error3;
633  }
634 
635  /* walk contexts */
636  c = NULL;
637  while ( (c = ast_walk_contexts(c)) ) {
638  /* XXX locking on c ? */
639  struct ast_exten *e;
640  if (strcmp(ast_get_context_name(c), context) != 0)
641  continue;
642  /* got it, we must match here */
643  e = NULL;
644  while ( (e = ast_walk_context_extensions(c, e)) ) {
645  struct ast_exten *priority;
646  char buffer[10];
647 
648  if (cid && strcmp(ast_get_extension_cidmatch(e), cid) != 0) {
649  continue;
650  }
651  if (strcmp(ast_get_extension_name(e), exten) != 0)
652  continue;
653  /* XXX lock e ? */
654  priority = NULL;
655  while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) {
656  snprintf(buffer, sizeof(buffer), "%d", ast_get_extension_priority(priority));
657  if (partial_match(buffer, a->word, len) && ++which > a->n) /* n-th match */
658  ret = ast_strdup(buffer);
659  }
660  break;
661  }
662  break;
663  }
665  error3:
666  ast_free(exten);
667  }
668  return ret;
669 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
int ast_get_extension_priority(struct ast_exten *exten)
Definition: pbx.c:8558
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:237
const char * ast_get_context_name(struct ast_context *con)
Definition: ael_main.c:421
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: conf2ael.c:618
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:8507
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static int priority
static int partial_match(const char *s, const char *word, int len)
match the first &#39;len&#39; chars of word. len==0 always succeeds
Definition: pbx_config.c:251
const char * line
Definition: cli.h:162
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
#define ast_log
Definition: astobj2.c:42
const int n
Definition: cli.h:165
const char * ast_get_extension_cidmatch(struct ast_exten *e)
Definition: pbx.c:8591
#define LOG_ERROR
Definition: logger.h:285
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8512
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&#39;ed and pointed ...
Definition: pbx_config.c:259
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:8548
struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *priority)
Definition: ael_main.c:427
#define ast_free(a)
Definition: astmm.h:182
const char * word
Definition: cli.h:163
struct ast_exten * ast_walk_extension_priorities(struct ast_exten *exten, struct ast_exten *priority)
Definition: extconf.c:4063
const int pos
Definition: cli.h:164
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
static const char * skip_words(const char *p, int n)
moves to the n-th word in the string, or empty string if none
Definition: pbx_config.c:236
int ast_get_extension_matchcid(struct ast_exten *e)
Definition: pbx.c:8586
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284

◆ complete_dialplan_remove_ignorepat()

static char * complete_dialplan_remove_ignorepat ( struct ast_cli_args a)
static

Definition at line 1488 of file pbx_config.c.

References ast_context_ignorepats_count(), ast_context_ignorepats_get(), ast_free, ast_get_context_name(), ast_get_ignorepat_name(), ast_log, ast_rdlock_context(), ast_rdlock_contexts(), ast_strdup, ast_unlock_context(), ast_unlock_contexts(), ast_walk_contexts(), c, len(), ast_cli_args::line, LOG_WARNING, lookup_c_ip(), ast_cli_args::n, NULL, partial_match(), pbx_load_module(), ast_cli_args::pos, strsep(), and ast_cli_args::word.

Referenced by handle_cli_dialplan_remove_ignorepat().

1489 {
1490  struct ast_context *c;
1491  int which = 0;
1492  char *ret = NULL;
1493 
1494  if (a->pos == 3) {
1495  int len = strlen(a->word);
1496  if (ast_rdlock_contexts()) {
1497  ast_log(LOG_WARNING, "Failed to lock contexts list\n");
1498  return NULL;
1499  }
1500 
1501  for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
1502  int idx;
1503 
1504  if (ast_rdlock_context(c)) /* error, skip it */
1505  continue;
1506  for (idx = 0; idx < ast_context_ignorepats_count(c); idx++) {
1507  const struct ast_ignorepat *ip = ast_context_ignorepats_get(c, idx);
1508 
1509  if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) {
1510  /* n-th match */
1511  struct ast_context *cw = NULL;
1512  int found = 0;
1513  while ( (cw = ast_walk_contexts(cw)) && cw != c && !found) {
1514  /* XXX do i stop on c, or skip it ? */
1515  found = lookup_c_ip(cw, ast_get_ignorepat_name(ip));
1516  }
1517  if (!found)
1519  }
1520  }
1521  ast_unlock_context(c);
1522  }
1524  return ret;
1525  } else if (a->pos == 4) {
1526  return a->n == 0 ? ast_strdup("from") : NULL;
1527  } else if (a->pos == 5) { /* XXX check this */
1528  char *dupline, *duplinet, *ignorepat;
1529  int len = strlen(a->word);
1530 
1531  dupline = ast_strdup(a->line);
1532  if (!dupline) {
1533  ast_log(LOG_WARNING, "Out of free memory\n");
1534  return NULL;
1535  }
1536 
1537  duplinet = dupline;
1538  strsep(&duplinet, " ");
1539  strsep(&duplinet, " ");
1540  ignorepat = strsep(&duplinet, " ");
1541 
1542  if (!ignorepat) {
1543  ast_free(dupline);
1544  return NULL;
1545  }
1546 
1547  if (ast_rdlock_contexts()) {
1548  ast_log(LOG_WARNING, "Failed to lock contexts list\n");
1549  ast_free(dupline);
1550  return NULL;
1551  }
1552 
1553  for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
1554  if (ast_rdlock_context(c)) {
1555  /* fail, skip it */
1556  continue;
1557  }
1558  if (!partial_match(ast_get_context_name(c), a->word, len)) {
1559  ast_unlock_context(c);
1560  continue;
1561  }
1562  if (lookup_c_ip(c, ignorepat) && ++which > a->n)
1563  ret = ast_strdup(ast_get_context_name(c));
1564  ast_unlock_context(c);
1565  }
1567  ast_free(dupline);
1568  return ret;
1569  }
1570 
1571  return NULL;
1572 }
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8530
const char * ast_get_context_name(struct ast_context *con)
Definition: ael_main.c:421
#define LOG_WARNING
Definition: logger.h:274
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: conf2ael.c:618
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:8507
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static int partial_match(const char *s, const char *word, int len)
match the first &#39;len&#39; chars of word. len==0 always succeeds
Definition: pbx_config.c:251
const char * line
Definition: cli.h:162
#define ast_log
Definition: astobj2.c:42
const int n
Definition: cli.h:165
const char * ast_get_ignorepat_name(const struct ast_ignorepat *ip)
Definition: pbx_ignorepat.c:42
static int lookup_c_ip(struct ast_context *c, const char *name)
return true if &#39;name&#39; is in the ignorepats for context c
Definition: pbx_config.c:212
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx_ignorepat.c:37
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8512
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
const char * word
Definition: cli.h:163
char * strsep(char **str, const char *delims)
const int pos
Definition: cli.h:164
int ast_context_ignorepats_count(const struct ast_context *con)
Definition: pbx.c:8740
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284
int ast_rdlock_context(struct ast_context *con)
Read locks a given context.
Definition: pbx.c:8525
const struct ast_ignorepat * ast_context_ignorepats_get(const struct ast_context *con, int idx)
Definition: pbx.c:8745

◆ complete_dialplan_remove_include()

static char * complete_dialplan_remove_include ( struct ast_cli_args a)
static

Definition at line 289 of file pbx_config.c.

References ast_context_includes_count(), ast_context_includes_get(), ast_free, ast_get_context_name(), ast_get_include_name(), ast_log, ast_rdlock_context(), ast_rdlock_contexts(), ast_strdup, ast_unlock_context(), ast_unlock_contexts(), ast_walk_contexts(), ast_wrlock_contexts(), c, context, len(), ast_cli_args::line, LOG_ERROR, LOG_WARNING, lookup_ci(), ast_cli_args::n, NULL, partial_match(), ast_cli_args::pos, skip_words(), strsep(), and ast_cli_args::word.

Referenced by handle_cli_dialplan_remove_include().

290 {
291  int which = 0;
292  char *res = NULL;
293  int len = strlen(a->word); /* how many bytes to match */
294  struct ast_context *c = NULL;
295 
296  if (a->pos == 3) { /* "dialplan remove include _X_" */
297  if (ast_wrlock_contexts()) {
298  ast_log(LOG_ERROR, "Failed to lock context list\n");
299  return NULL;
300  }
301  /* walk contexts and their includes, return the n-th match */
302  while (!res && (c = ast_walk_contexts(c))) {
303  int idx;
304 
305  if (ast_rdlock_context(c)) /* error ? skip this one */
306  continue;
307 
308  for (idx = 0; idx < ast_context_includes_count(c); idx++) {
309  const struct ast_include *i = ast_context_includes_get(c, idx);
310  const char *i_name = ast_get_include_name(i);
311  struct ast_context *nc = NULL;
312  int already_served = 0;
313 
314  if (!partial_match(i_name, a->word, len))
315  continue; /* not matched */
316 
317  /* check if this include is already served or not */
318 
319  /* go through all contexts again till we reach actual
320  * context or already_served = 1
321  */
322  while ( (nc = ast_walk_contexts(nc)) && nc != c && !already_served)
323  already_served = lookup_ci(nc, i_name);
324 
325  if (!already_served && ++which > a->n) {
326  res = ast_strdup(i_name);
327  break;
328  }
329  }
331  }
332 
334  return res;
335  } else if (a->pos == 4) { /* "dialplan remove include CTX _X_" */
336  /*
337  * complete as 'from', but only if previous context is really
338  * included somewhere
339  */
340  char *context, *dupline;
341  const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */
342 
343  if (a->n > 0)
344  return NULL;
345  context = dupline = ast_strdup(s);
346  if (!dupline) {
347  ast_log(LOG_ERROR, "Out of free memory\n");
348  return NULL;
349  }
350  strsep(&dupline, " ");
351 
352  if (ast_rdlock_contexts()) {
353  ast_log(LOG_ERROR, "Failed to lock contexts list\n");
354  ast_free(context);
355  return NULL;
356  }
357 
358  /* go through all contexts and check if is included ... */
359  while (!res && (c = ast_walk_contexts(c)))
360  if (lookup_ci(c, context)) /* context is really included, complete "from" command */
361  res = ast_strdup("from");
363  if (!res)
364  ast_log(LOG_WARNING, "%s not included anywhere\n", context);
365  ast_free(context);
366  return res;
367  } else if (a->pos == 5) { /* "dialplan remove include CTX from _X_" */
368  /*
369  * Context from which we removing include ...
370  */
371  char *context, *dupline, *from;
372  const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */
373  context = dupline = ast_strdup(s);
374  if (!dupline) {
375  ast_log(LOG_ERROR, "Out of free memory\n");
376  return NULL;
377  }
378 
379  strsep(&dupline, " "); /* skip context */
380 
381  /* fourth word must be 'from' */
382  from = strsep(&dupline, " ");
383  if (!from || strcmp(from, "from")) {
384  ast_free(context);
385  return NULL;
386  }
387 
388  if (ast_rdlock_contexts()) {
389  ast_log(LOG_ERROR, "Failed to lock context list\n");
390  ast_free(context);
391  return NULL;
392  }
393 
394  /* walk through all contexts ... */
395  c = NULL;
396  while ( !res && (c = ast_walk_contexts(c))) {
397  const char *c_name = ast_get_context_name(c);
398  if (!partial_match(c_name, a->word, len)) /* not a good target */
399  continue;
400  /* walk through all includes and check if it is our context */
401  if (lookup_ci(c, context) && ++which > a->n)
402  res = ast_strdup(c_name);
403  }
405  ast_free(context);
406  return res;
407  }
408 
409  return NULL;
410 }
ast_include: include= support in extensions.conf
Definition: pbx_include.c:37
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8530
const char * ast_get_context_name(struct ast_context *con)
Definition: ael_main.c:421
#define LOG_WARNING
Definition: logger.h:274
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: conf2ael.c:618
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:8507
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:8502
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static int partial_match(const char *s, const char *word, int len)
match the first &#39;len&#39; chars of word. len==0 always succeeds
Definition: pbx_config.c:251
const char * line
Definition: cli.h:162
static int lookup_ci(struct ast_context *c, const char *name)
return true if &#39;name&#39; is included by context c
Definition: pbx_config.c:188
#define ast_log
Definition: astobj2.c:42
const int n
Definition: cli.h:165
int ast_context_includes_count(const struct ast_context *con)
Definition: pbx.c:8697
#define LOG_ERROR
Definition: logger.h:285
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8512
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
const char * word
Definition: cli.h:163
const char * ast_get_include_name(const struct ast_include *include)
Definition: pbx_include.c:50
char * strsep(char **str, const char *delims)
const int pos
Definition: cli.h:164
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
static const char * skip_words(const char *p, int n)
moves to the n-th word in the string, or empty string if none
Definition: pbx_config.c:236
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284
const struct ast_include * ast_context_includes_get(const struct ast_context *con, int idx)
Definition: pbx.c:8702
int ast_rdlock_context(struct ast_context *con)
Read locks a given context.
Definition: pbx.c:8525

◆ handle_cli_dialplan_add_extension()

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

References app, ast_cli_args::argc, ast_cli_args::argv, ast_add_extension(), ast_cli(), ast_context_find(), ast_context_find_or_create(), ast_free_ptr(), ast_strdup, ast_strdupa, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_extension(), end, errno, exten, ast_cli_args::fd, NULL, PRIORITY_HINT, registrar, strsep(), and ast_cli_entry::usage.

1064 {
1065  char *whole_exten;
1066  char *exten, *prior;
1067  int iprior = -2;
1068  char *cidmatch, *app, *app_data;
1069  char *start, *end;
1070  const char *into_context;
1071 
1072  switch (cmd) {
1073  case CLI_INIT:
1074  e->command = "dialplan add extension";
1075  e->usage =
1076  "Usage: dialplan add extension <exten>,<priority>,<app> into <context> [replace]\n"
1077  "\n"
1078  " app can be either:\n"
1079  " app-name\n"
1080  " app-name(app-data)\n"
1081  " app-name,<app-data>\n"
1082  "\n"
1083  " This command will add the new extension into <context>. If\n"
1084  " an extension with the same priority already exists and the\n"
1085  " 'replace' option is given we will replace the extension.\n"
1086  "\n"
1087  "Example: dialplan add extension 6123,1,Dial,IAX/216.207.245.56/6123 into local\n"
1088  " Now, you can dial 6123 and talk to Markster :)\n";
1089  return NULL;
1090  case CLI_GENERATE:
1092  }
1093 
1094  /* check for arguments at first */
1095  if (a->argc != 6 && a->argc != 7)
1096  return CLI_SHOWUSAGE;
1097  if (strcmp(a->argv[4], "into"))
1098  return CLI_SHOWUSAGE;
1099  if (a->argc == 7)
1100  if (strcmp(a->argv[6], "replace"))
1101  return CLI_SHOWUSAGE;
1102 
1103  whole_exten = ast_strdupa(a->argv[3]);
1104  exten = strsep(&whole_exten,",");
1105  if (strchr(exten, '/')) {
1106  cidmatch = exten;
1107  strsep(&cidmatch,"/");
1108  } else {
1109  cidmatch = NULL;
1110  }
1111  prior = strsep(&whole_exten,",");
1112  if (prior) {
1113  if (!strcmp(prior, "hint")) {
1114  iprior = PRIORITY_HINT;
1115  } else {
1116  if (sscanf(prior, "%30d", &iprior) != 1) {
1117  ast_cli(a->fd, "'%s' is not a valid priority\n", prior);
1118  prior = NULL;
1119  }
1120  }
1121  }
1122  app = whole_exten;
1123  if (app) {
1124  if ((start = strchr(app, '(')) && (end = strrchr(app, ')'))) {
1125  *start = *end = '\0';
1126  app_data = start + 1;
1127  } else {
1128  app_data = strchr(app, ',');
1129  if (app_data) {
1130  *app_data++ = '\0';
1131  }
1132  }
1133  } else {
1134  app_data = NULL;
1135  }
1136 
1137  if (!exten || !prior || !app) {
1138  return CLI_SHOWUSAGE;
1139  }
1140 
1141  if (!app_data) {
1142  app_data = "";
1143  }
1144  into_context = a->argv[5];
1145 
1146  if (!ast_context_find(into_context)) {
1147  ast_cli(a->fd, "Context '%s' did not exist prior to add extension - the context will be created.\n", into_context);
1148  }
1149 
1150  if (!ast_context_find_or_create(NULL, NULL, into_context, registrar)) {
1151  ast_cli(a->fd, "Failed to add '%s,%s,%s(%s)' extension into '%s' context\n",
1152  exten, prior, app, app_data, into_context);
1153  return CLI_FAILURE;
1154  }
1155 
1156  if (ast_add_extension(into_context, a->argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
1157  ast_strdup(app_data), ast_free_ptr, registrar)) {
1158  switch (errno) {
1159  case ENOMEM:
1160  ast_cli(a->fd, "Out of free memory\n");
1161  break;
1162 
1163  case EBUSY:
1164  ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
1165  break;
1166 
1167  case ENOENT:
1168  ast_cli(a->fd, "No existence of '%s' context\n", into_context);
1169  break;
1170 
1171  case EEXIST:
1172  ast_cli(a->fd, "Extension %s@%s with priority %s already exists\n",
1173  exten, into_context, prior);
1174  break;
1175 
1176  default:
1177  ast_cli(a->fd, "Failed to add '%s,%s,%s(%s)' extension into '%s' context\n",
1178  exten, prior, app, app_data, into_context);
1179  break;
1180  }
1181  return CLI_FAILURE;
1182  }
1183 
1184  if (a->argc == 7) {
1185  ast_cli(a->fd, "Extension %s@%s (%s) replace by '%s,%s,%s(%s)'\n",
1186  exten, into_context, prior, exten, prior, app, app_data);
1187  } else {
1188  ast_cli(a->fd, "Extension '%s,%s,%s(%s)' added into '%s' context\n",
1189  exten, prior, app, app_data, into_context);
1190  }
1191 
1192  return CLI_SUCCESS;
1193 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
const int argc
Definition: cli.h:160
Definition: cli.h:152
static char * complete_dialplan_add_extension(struct ast_cli_args *)
Definition: pbx_config.c:1306
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
struct ast_context * ast_context_find(const char *name)
Find a context.
Definition: extconf.c:4174
const int fd
Definition: cli.h:159
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static const char registrar[]
Definition: pbx_config.c:97
#define PRIORITY_HINT
Definition: pbx.h:54
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
int errno
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
char * strsep(char **str, const char *delims)
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition: pbx.c:6970
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6198
static const char app[]
Definition: app_mysql.c:62

◆ handle_cli_dialplan_add_ignorepat()

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 1338 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, NULL, registrar, and ast_cli_entry::usage.

1339 {
1340  switch (cmd) {
1341  case CLI_INIT:
1342  e->command = "dialplan add ignorepat";
1343  e->usage =
1344  "Usage: dialplan add ignorepat <pattern> into <context>\n"
1345  " This command adds a new ignore pattern into context <context>\n"
1346  "\n"
1347  "Example: dialplan add ignorepat _3XX into local\n";
1348  return NULL;
1349  case CLI_GENERATE:
1351  }
1352 
1353  if (a->argc != 6)
1354  return CLI_SHOWUSAGE;
1355 
1356  if (strcmp(a->argv[4], "into"))
1357  return CLI_SHOWUSAGE;
1358 
1359  if (ast_context_add_ignorepat(a->argv[5], a->argv[3], registrar)) {
1360  switch (errno) {
1361  case ENOMEM:
1362  ast_cli(a->fd, "Out of free memory\n");
1363  break;
1364 
1365  case ENOENT:
1366  ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]);
1367  break;
1368 
1369  case EEXIST:
1370  ast_cli(a->fd, "Ignore pattern '%s' already included in '%s' context\n",
1371  a->argv[3], a->argv[5]);
1372  break;
1373 
1374  case EBUSY:
1375  ast_cli(a->fd, "Failed to lock context(s) list, please, try again later\n");
1376  break;
1377 
1378  default:
1379  ast_cli(a->fd, "Failed to add ingore pattern '%s' into '%s' context\n",
1380  a->argv[3], a->argv[5]);
1381  break;
1382  }
1383  return CLI_FAILURE;
1384  }
1385 
1386  ast_cli(a->fd, "Ignore pattern '%s' added into '%s' context\n",
1387  a->argv[3], a->argv[5]);
1388 
1389  return CLI_SUCCESS;
1390 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
int ast_context_add_ignorepat(const char *context, const char *ignorepat, const char *registrar)
Add an ignorepat.
Definition: pbx.c:6877
static const char registrar[]
Definition: pbx_config.c:97
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
int errno
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static char * complete_dialplan_add_ignorepat(struct ast_cli_args *)
Definition: pbx_config.c:1392

◆ handle_cli_dialplan_add_include()

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

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_add_include(), ast_context_find(), ast_context_find_or_create(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_add_include(), errno, ast_cli_args::fd, NULL, registrar, and ast_cli_entry::usage.

675 {
676  const char *into_context;
677 
678  switch (cmd) {
679  case CLI_INIT:
680  e->command = "dialplan add include";
681  e->usage =
682  "Usage: dialplan add include <context> into <context>\n"
683  " Include a context in another context.\n";
684  return NULL;
685  case CLI_GENERATE:
687  }
688 
689  if (a->argc != 6) /* dialplan add include CTX in CTX */
690  return CLI_SHOWUSAGE;
691 
692  /* fifth arg must be 'into' ... */
693  if (strcmp(a->argv[4], "into"))
694  return CLI_SHOWUSAGE;
695 
696  into_context = a->argv[5];
697 
698  if (!ast_context_find(into_context)) {
699  ast_cli(a->fd, "Context '%s' did not exist prior to add include - the context will be created.\n", into_context);
700  }
701 
702  if (!ast_context_find_or_create(NULL, NULL, into_context, registrar)) {
703  ast_cli(a->fd, "ast_context_find_or_create() failed\n");
704  ast_cli(a->fd, "Failed to include '%s' in '%s' context\n",a->argv[3], a->argv[5]);
705  return CLI_FAILURE;
706  }
707 
708  if (ast_context_add_include(a->argv[5], a->argv[3], registrar)) {
709  switch (errno) {
710  case ENOMEM:
711  ast_cli(a->fd, "Out of memory for context addition\n");
712  break;
713 
714  case EBUSY:
715  ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
716  break;
717 
718  case EEXIST:
719  ast_cli(a->fd, "Context '%s' already included in '%s' context\n",
720  a->argv[3], a->argv[5]);
721  break;
722 
723  case ENOENT:
724  case EINVAL:
725  ast_cli(a->fd, "There is no existence of context '%s'\n",
726  errno == ENOENT ? a->argv[5] : a->argv[3]);
727  break;
728 
729  default:
730  ast_cli(a->fd, "Failed to include '%s' in '%s' context\n",
731  a->argv[3], a->argv[5]);
732  break;
733  }
734  return CLI_FAILURE;
735  }
736 
737  /* show some info ... */
738  ast_cli(a->fd, "Context '%s' included in '%s' context\n",
739  a->argv[3], a->argv[5]);
740 
741  return CLI_SUCCESS;
742 }
static char * complete_dialplan_add_include(struct ast_cli_args *)
Definition: pbx_config.c:744
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int ast_context_add_include(const char *context, const char *include, const char *registrar)
Add a context include.
Definition: pbx.c:6706
struct ast_context * ast_context_find(const char *name)
Find a context.
Definition: extconf.c:4174
const int fd
Definition: cli.h:159
static const char registrar[]
Definition: pbx_config.c:97
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
int errno
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6198

◆ handle_cli_dialplan_reload()

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

Definition at line 1576 of file pbx_config.c.

References ast_cli_args::argc, ast_cli(), clearglobalvars_config, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, pbx_builtin_clear_globals(), pbx_load_module(), and ast_cli_entry::usage.

1577 {
1578  switch (cmd) {
1579  case CLI_INIT:
1580  e->command = "dialplan reload";
1581  e->usage =
1582  "Usage: dialplan reload\n"
1583  " Reload extensions.conf without reloading any other\n"
1584  " modules. This command does not delete global variables\n"
1585  " unless clearglobalvars is set to yes in extensions.conf\n";
1586  return NULL;
1587  case CLI_GENERATE:
1588  return NULL;
1589  }
1590 
1591  if (a->argc != 2)
1592  return CLI_SHOWUSAGE;
1593 
1596 
1597  pbx_load_module();
1598  ast_cli(a->fd, "Dialplan reloaded.\n");
1599  return CLI_SUCCESS;
1600 }
static int clearglobalvars_config
Definition: pbx_config.c:103
void pbx_builtin_clear_globals(void)
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static int pbx_load_module(void)
Definition: pbx_config.c:2087
const int fd
Definition: cli.h:159
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_dialplan_remove_context()

static char* handle_cli_dialplan_remove_context ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static
  • REMOVE context command stuff

Definition at line 132 of file pbx_config.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_context_destroy_by_name(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_dialplan_remove_context(), ast_cli_args::fd, NULL, and ast_cli_entry::usage.

133 {
134  switch (cmd) {
135  case CLI_INIT:
136  e->command = "dialplan remove context";
137  e->usage =
138  "Usage: dialplan remove context <context>\n"
139  " Removes all extensions from a specified context.\n";
140  return NULL;
141  case CLI_GENERATE:
143  }
144 
145  if (a->argc != 4) {
146  return CLI_SHOWUSAGE;
147  }
148 
149  if (ast_context_destroy_by_name(a->argv[3], NULL)) {
150  ast_cli(a->fd, "There is no such context as '%s'\n", a->argv[3]);
151  return CLI_SUCCESS;
152  } else {
153  ast_cli(a->fd, "Removed context '%s'\n", a->argv[3]);
154  return CLI_SUCCESS;
155  }
156 }
static char * complete_dialplan_remove_context(struct ast_cli_args *)
Definition: pbx_config.c:1277
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int ast_context_destroy_by_name(const char *context, const char *registrar)
Destroy a context by name.
Definition: pbx.c:8244
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_dialplan_remove_extension()

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

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

416 {
417  int removing_priority = 0;
418  char *exten, *context, *cid;
419  char *ret = CLI_FAILURE;
420 
421  switch (cmd) {
422  case CLI_INIT:
423  e->command = "dialplan remove extension";
424  e->usage =
425  "Usage: dialplan remove extension exten[/cid]@context [priority]\n"
426  " Remove an extension from a given context. If a priority\n"
427  " is given, only that specific priority from the given extension\n"
428  " will be removed.\n";
429  return NULL;
430  case CLI_GENERATE:
432  }
433 
434  if (a->argc != 5 && a->argc != 4)
435  return CLI_SHOWUSAGE;
436 
437  /*
438  * Priority input checking ...
439  */
440  if (a->argc == 5) {
441  const char *c = a->argv[4];
442 
443  /* check for digits in whole parameter for right priority ...
444  * why? because atoi (strtol) returns 0 if any characters in
445  * string and whole extension will be removed, it's not good
446  */
447  if (!strcmp("hint", c))
448  removing_priority = PRIORITY_HINT;
449  else {
450  while (*c && isdigit(*c))
451  c++;
452  if (*c) { /* non-digit in string */
453  ast_cli(a->fd, "Invalid priority '%s'\n", a->argv[4]);
454  return CLI_FAILURE;
455  }
456  removing_priority = atoi(a->argv[4]);
457  }
458 
459  if (removing_priority == 0) {
460  ast_cli(a->fd, "If you want to remove whole extension, please " \
461  "omit priority argument\n");
462  return CLI_FAILURE;
463  }
464  }
465 
466  /* XXX original overwrote argv[3] */
467  /*
468  * Format exten@context checking ...
469  */
470  if (split_ec(a->argv[3], &exten, &context, &cid))
471  return CLI_FAILURE; /* XXX malloc failure */
472  if ((!strlen(exten)) || (!(strlen(context)))) {
473  ast_cli(a->fd, "Missing extension or context name in third argument '%s'\n",
474  a->argv[3]);
475  ast_free(exten);
476  return CLI_FAILURE;
477  }
478 
479  if (!ast_context_remove_extension_callerid(context, exten, removing_priority,
480  /* Do NOT substitute S_OR; it is NOT the same thing */
481  cid ? cid : (removing_priority ? "" : NULL), cid ? 1 : 0, registrar)) {
482  if (!removing_priority)
483  ast_cli(a->fd, "Whole extension %s@%s removed\n",
484  exten, context);
485  else
486  ast_cli(a->fd, "Extension %s@%s with priority %d removed\n",
487  exten, context, removing_priority);
488 
489  ret = CLI_SUCCESS;
490  } else {
491  if (cid) {
492  ast_cli(a->fd, "Failed to remove extension %s/%s@%s\n", exten, cid, context);
493  } else {
494  ast_cli(a->fd, "Failed to remove extension %s@%s\n", exten, context);
495  }
496  ret = CLI_FAILURE;
497  }
498  ast_free(exten);
499  return ret;
500 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
const int argc
Definition: cli.h:160
Definition: cli.h:152
static struct test_val c
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
static const char registrar[]
Definition: pbx_config.c:97
#define PRIORITY_HINT
Definition: pbx.h:54
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
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&#39;ed and pointed ...
Definition: pbx_config.c:259
int ast_context_remove_extension_callerid(const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar)
Definition: pbx.c:4957
#define CLI_FAILURE
Definition: cli.h:46
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
static char * complete_dialplan_remove_extension(struct ast_cli_args *)
Definition: pbx_config.c:550

◆ handle_cli_dialplan_remove_ignorepat()

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

Definition at line 1439 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, NULL, registrar, and ast_cli_entry::usage.

1440 {
1441  switch (cmd) {
1442  case CLI_INIT:
1443  e->command = "dialplan remove ignorepat";
1444  e->usage =
1445  "Usage: dialplan remove ignorepat <pattern> from <context>\n"
1446  " This command removes an ignore pattern from context <context>\n"
1447  "\n"
1448  "Example: dialplan remove ignorepat _3XX from local\n";
1449  return NULL;
1450  case CLI_GENERATE:
1452  }
1453 
1454  if (a->argc != 6)
1455  return CLI_SHOWUSAGE;
1456 
1457  if (strcmp(a->argv[4], "from"))
1458  return CLI_SHOWUSAGE;
1459 
1460  if (ast_context_remove_ignorepat(a->argv[5], a->argv[3], registrar)) {
1461  switch (errno) {
1462  case EBUSY:
1463  ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
1464  break;
1465 
1466  case ENOENT:
1467  ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]);
1468  break;
1469 
1470  case EINVAL:
1471  ast_cli(a->fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
1472  a->argv[3], a->argv[5]);
1473  break;
1474 
1475  default:
1476  ast_cli(a->fd, "Failed to remove ignore pattern '%s' from '%s' context\n",
1477  a->argv[3], a->argv[5]);
1478  break;
1479  }
1480  return CLI_FAILURE;
1481  }
1482 
1483  ast_cli(a->fd, "Ignore pattern '%s' removed from '%s' context\n",
1484  a->argv[3], a->argv[5]);
1485  return CLI_SUCCESS;
1486 }
int ast_context_remove_ignorepat(const char *context, const char *ignorepat, const char *registrar)
Definition: pbx.c:6837
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
static const char registrar[]
Definition: pbx_config.c:97
static char * complete_dialplan_remove_ignorepat(struct ast_cli_args *)
Definition: pbx_config.c:1488
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
int errno
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_dialplan_remove_include()

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

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

161 {
162  switch (cmd) {
163  case CLI_INIT:
164  e->command = "dialplan remove include";
165  e->usage =
166  "Usage: dialplan remove include <context> from <context>\n"
167  " Remove an included context from another context.\n";
168  return NULL;
169  case CLI_GENERATE:
171  }
172 
173  if (a->argc != 6 || strcmp(a->argv[4], "from"))
174  return CLI_SHOWUSAGE;
175 
176  if (!ast_context_remove_include(a->argv[5], a->argv[3], registrar)) {
177  ast_cli(a->fd, "We are not including '%s' into '%s' now\n",
178  a->argv[3], a->argv[5]);
179  return CLI_SUCCESS;
180  }
181 
182  ast_cli(a->fd, "Failed to remove '%s' include from '%s' context\n",
183  a->argv[3], a->argv[5]);
184  return CLI_FAILURE;
185 }
int ast_context_remove_include(const char *context, const char *include, const char *registrar)
Remove a context include.
Definition: pbx.c:4840
static char * complete_dialplan_remove_include(struct ast_cli_args *)
Definition: pbx_config.c:289
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
static const char registrar[]
Definition: pbx_config.c:97
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_dialplan_save()

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 809 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_context_ignorepats_count(), ast_context_ignorepats_get(), ast_context_includes_count(), ast_context_includes_get(), ast_context_switches_count(), ast_context_switches_get(), ast_escape_semicolons(), 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_contexts(), ast_walk_extension_priorities(), autofallthrough_config, c, clearglobalvars_config, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, config, el, ext, extenpatternmatchnew_config, ast_cli_args::fd, ast_exten::label, ast_variable::name, ast_variable::next, NULL, overrideswitch, overrideswitch_config, PRIORITY_HINT, PUT_CTX_HDR, registrar, save_dialplan_lock, static_config, ast_cli_entry::usage, ast_variable::value, and write_protect_config.

810 {
811  char filename[256], overrideswitch[256] = "";
812  struct ast_context *c;
813  struct ast_config *cfg;
814  struct ast_variable *v;
815  int incomplete = 0; /* incomplete config write? */
816  FILE *output;
817  struct ast_flags config_flags = { 0 };
818  const char *base, *slash;
819 
820  switch (cmd) {
821  case CLI_INIT:
822  e->command = "dialplan save";
823  e->usage =
824  "Usage: dialplan save [/path/to/extension/file]\n"
825  " Save dialplan created by pbx_config module.\n"
826  "\n"
827  "Example: dialplan save (/etc/asterisk/extensions.conf)\n"
828  " dialplan save /home/markster (/home/markster/extensions.conf)\n";
829  return NULL;
830  case CLI_GENERATE:
831  return NULL;
832  }
833 
834  if (! (static_config && !write_protect_config)) {
835  ast_cli(a->fd,
836  "I can't save dialplan now, see '%s' example file.\n",
837  config);
838  return CLI_FAILURE;
839  }
840 
841  if (a->argc != 2 && a->argc != 3)
842  return CLI_SHOWUSAGE;
843 
845  ast_cli(a->fd,
846  "Failed to lock dialplan saving (another proccess saving?)\n");
847  return CLI_FAILURE;
848  }
849  /* XXX the code here is quite loose, a pathname with .conf in it
850  * is assumed to be a complete pathname
851  */
852  if (a->argc == 3) { /* have config path. Look for *.conf */
853  base = a->argv[2];
854  if (!strstr(a->argv[2], ".conf")) { /*no, this is assumed to be a pathname */
855  /* if filename ends with '/', do not add one */
856  slash = (*(a->argv[2] + strlen(a->argv[2]) -1) == '/') ? "/" : "";
857  } else { /* yes, complete file name */
858  slash = "";
859  }
860  } else {
861  /* no config file, default one */
863  slash = "/";
864  }
865  snprintf(filename, sizeof(filename), "%s%s%s", base, slash, config);
866 
867  cfg = ast_config_load("extensions.conf", config_flags);
868  if (!cfg) {
869  ast_cli(a->fd, "Failed to load extensions.conf\n");
871  return CLI_FAILURE;
872  }
873 
874  /* try to lock contexts list */
875  if (ast_rdlock_contexts()) {
876  ast_cli(a->fd, "Failed to lock contexts list\n");
878  ast_config_destroy(cfg);
879  return CLI_FAILURE;
880  }
881 
882  /* create new file ... */
883  if (!(output = fopen(filename, "wt"))) {
884  ast_cli(a->fd, "Failed to create file '%s'\n",
885  filename);
888  ast_config_destroy(cfg);
889  return CLI_FAILURE;
890  }
891 
892  /* fireout general info */
893  if (overrideswitch_config) {
894  snprintf(overrideswitch, sizeof(overrideswitch), "overrideswitch=%s\n", overrideswitch_config);
895  }
896  fprintf(output, "[general]\nstatic=%s\nwriteprotect=%s\nautofallthrough=%s\nclearglobalvars=%s\n%sextenpatternmatchnew=%s\n\n",
897  static_config ? "yes" : "no",
898  write_protect_config ? "yes" : "no",
899  autofallthrough_config ? "yes" : "no",
900  clearglobalvars_config ? "yes" : "no",
901  overrideswitch_config ? overrideswitch : "",
902  extenpatternmatchnew_config ? "yes" : "no");
903 
904  if ((v = ast_variable_browse(cfg, "globals"))) {
905  fprintf(output, "[globals]\n");
906  while(v) {
907  int escaped_len = 2 * strlen(v->value) + 1;
908  char escaped[escaped_len];
909 
910  ast_escape_semicolons(v->value, escaped, escaped_len);
911  fprintf(output, "%s => %s\n", v->name, escaped);
912  v = v->next;
913  }
914  fprintf(output, "\n");
915  }
916 
917  ast_config_destroy(cfg);
918 
919 #define PUT_CTX_HDR do { \
920  if (!context_header_written) { \
921  fprintf(output, "[%s]\n", ast_get_context_name(c)); \
922  context_header_written = 1; \
923  } \
924  } while (0)
925 
926  /* walk all contexts */
927  for (c = NULL; (c = ast_walk_contexts(c)); ) {
928  int context_header_written = 0;
929  struct ast_exten *ext, *last_written_e = NULL;
930  int idx;
931 
932  /* try to lock context and fireout all info */
933  if (ast_rdlock_context(c)) { /* lock failure */
934  incomplete = 1;
935  continue;
936  }
937  /* registered by this module? */
938  /* XXX do we need this ? */
939  if (!strcmp(ast_get_context_registrar(c), registrar)) {
940  fprintf(output, "[%s]\n", ast_get_context_name(c));
941  context_header_written = 1;
942  }
943 
944  /* walk extensions ... */
945  for (ext = NULL; (ext = ast_walk_context_extensions(c, ext)); ) {
946  struct ast_exten *p = NULL;
947 
948  /* fireout priorities */
949  while ( (p = ast_walk_extension_priorities(ext, p)) ) {
950  if (strcmp(ast_get_extension_registrar(p), registrar) != 0) /* not this source */
951  continue;
952 
953  /* make empty line between different extensions */
954  if (last_written_e != NULL &&
955  strcmp(ast_get_extension_name(last_written_e),
957  fprintf(output, "\n");
958  last_written_e = p;
959 
960  PUT_CTX_HDR;
961 
962  if (ast_get_extension_priority(p) == PRIORITY_HINT) { /* easy */
963  fprintf(output, "exten => %s,hint,%s\n",
966  } else {
967  const char *sep, *cid;
968  const char *el = ast_get_extension_label(p);
969  char label[128] = "";
970  char *appdata = ast_get_extension_app_data(p);
971 
972  int escaped_len = (!ast_strlen_zero(appdata)) ? 2 * strlen(appdata) + 1 : 1;
973  char escaped[escaped_len];
974 
976  sep = "/";
978  } else {
979  sep = cid = "";
980  }
981 
982  if (el && (snprintf(label, sizeof(label), "(%s)", el) != (strlen(el) + 2))) {
983  incomplete = 1; /* error encountered or label > 125 chars */
984  }
985 
986  if (!ast_strlen_zero(appdata)) {
987  ast_escape_semicolons(appdata, escaped, escaped_len);
988  } else {
989  escaped[0] = '\0';
990  }
991 
992  fprintf(output, "exten => %s%s%s,%d%s,%s(%s)\n",
993  ast_get_extension_name(p), (ast_strlen_zero(sep) ? "" : sep), (ast_strlen_zero(cid) ? "" : cid),
994  ast_get_extension_priority(p), label,
995  ast_get_extension_app(p), escaped);
996  }
997  }
998  }
999 
1000  /* written any extensions? ok, write space between exten & inc */
1001  if (last_written_e)
1002  fprintf(output, "\n");
1003 
1004  /* walk through includes */
1005  for (idx = 0; idx < ast_context_includes_count(c); idx++) {
1006  const struct ast_include *i = ast_context_includes_get(c, idx);
1007 
1008  if (strcmp(ast_get_include_registrar(i), registrar) != 0)
1009  continue; /* not mine */
1010  PUT_CTX_HDR;
1011  fprintf(output, "include => %s\n", ast_get_include_name(i));
1012  }
1013  if (ast_context_includes_count(c)) {
1014  fprintf(output, "\n");
1015  }
1016 
1017  /* walk through switches */
1018  for (idx = 0; idx < ast_context_switches_count(c); idx++) {
1019  const struct ast_sw *sw = ast_context_switches_get(c, idx);
1020 
1021  if (strcmp(ast_get_switch_registrar(sw), registrar) != 0)
1022  continue; /* not mine */
1023  PUT_CTX_HDR;
1024  fprintf(output, "switch => %s/%s\n",
1026  }
1027 
1028  if (ast_context_switches_count(c)) {
1029  fprintf(output, "\n");
1030  }
1031 
1032  /* fireout ignorepats ... */
1033  for (idx = 0; idx < ast_context_ignorepats_count(c); idx++) {
1034  const struct ast_ignorepat *ip = ast_context_ignorepats_get(c, idx);
1035 
1036  if (strcmp(ast_get_ignorepat_registrar(ip), registrar) != 0)
1037  continue; /* not mine */
1038  PUT_CTX_HDR;
1039  fprintf(output, "ignorepat => %s\n",
1041  }
1042 
1043  ast_unlock_context(c);
1044  }
1045 
1048  fclose(output);
1049 
1050  if (incomplete) {
1051  ast_cli(a->fd, "Saved dialplan is incomplete\n");
1052  return CLI_FAILURE;
1053  }
1054 
1055  ast_cli(a->fd, "Dialplan successfully saved into '%s'\n",
1056  filename);
1057  return CLI_SUCCESS;
1058 }
const char * label
Definition: pbx.c:244
ast_include: include= support in extensions.conf
Definition: pbx_include.c:37
struct ast_variable * next
static int clearglobalvars_config
Definition: pbx_config.c:103
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8530
const char * ast_get_switch_name(const struct ast_sw *sw)
Definition: pbx_sw.c:48
const char * ast_get_switch_registrar(const struct ast_sw *sw)
Definition: pbx_sw.c:63
static int autofallthrough_config
Definition: pbx_config.c:102
int ast_get_extension_priority(struct ast_exten *exten)
Definition: pbx.c:8558
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:237
const char * ast_get_extension_registrar(struct ast_exten *e)
Definition: pbx.c:8571
const char * ast_get_context_name(struct ast_context *con)
Definition: ael_main.c:421
static int static_config
Definition: pbx_config.c:100
const char * ast_get_ignorepat_registrar(const struct ast_ignorepat *ip)
Definition: pbx_ignorepat.c:47
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
static int write_protect_config
Definition: pbx_config.c:101
static int extenpatternmatchnew_config
Definition: pbx_config.c:104
const int argc
Definition: cli.h:160
int ast_context_switches_count(const struct ast_context *con)
Definition: pbx.c:8652
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:8596
Structure for variables, used for configurations and for channel variables.
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: conf2ael.c:618
Definition: cli.h:152
static EditLine * el
Definition: asterisk.c:340
void * ast_get_extension_app_data(struct ast_exten *e)
Definition: pbx.c:8601
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:8507
const char * ast_get_extension_label(struct ast_exten *e)
Definition: pbx.c:8553
const char * ast_get_include_registrar(const struct ast_include *i)
Definition: pbx_include.c:60
#define ast_mutex_lock(a)
Definition: lock.h:187
char * ast_escape_semicolons(const char *string, char *outbuf, int buflen)
Escape semicolons found in a string.
Definition: main/utils.c:665
static struct test_val c
#define NULL
Definition: resample.c:96
const char * ast_get_context_registrar(struct ast_context *c)
Definition: pbx.c:8566
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * ext
Definition: http.c:147
#define ast_strlen_zero(foo)
Definition: strings.h:52
const struct ast_sw * ast_context_switches_get(const struct ast_context *con, int idx)
Definition: pbx.c:8657
#define ast_config_load(filename, flags)
Load a config file.
ast_sw: Switch statement in extensions.conf
Definition: pbx_sw.c:37
const int fd
Definition: cli.h:159
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
static const char registrar[]
Definition: pbx_config.c:97
const char * ast_get_extension_cidmatch(struct ast_exten *e)
Definition: pbx.c:8591
#define PRIORITY_HINT
Definition: pbx.h:54
const char * ast_get_ignorepat_name(const struct ast_ignorepat *ip)
Definition: pbx_ignorepat.c:42
static char * overrideswitch_config
Definition: pbx_config.c:105
const char *const * argv
Definition: cli.h:161
int ast_context_includes_count(const struct ast_context *con)
Definition: pbx.c:8697
#define CLI_SHOWUSAGE
Definition: cli.h:45
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx_ignorepat.c:37
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8512
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:8548
struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *priority)
Definition: ael_main.c:427
#define PUT_CTX_HDR
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * ast_get_switch_data(const struct ast_sw *sw)
Definition: pbx_sw.c:53
static ast_mutex_t save_dialplan_lock
Definition: pbx_config.c:107
static const char config[]
Definition: pbx_config.c:96
Structure used to handle boolean flags.
Definition: utils.h:199
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const char * ast_get_include_name(const struct ast_include *include)
Definition: pbx_include.c:50
struct ast_exten * ast_walk_extension_priorities(struct ast_exten *exten, struct ast_exten *priority)
Definition: extconf.c:4063
static char * overrideswitch
Definition: pbx.c:765
int ast_context_ignorepats_count(const struct ast_context *con)
Definition: pbx.c:8740
int ast_get_extension_matchcid(struct ast_exten *e)
Definition: pbx.c:8586
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284
const struct ast_include * ast_context_includes_get(const struct ast_context *con, int idx)
Definition: pbx.c:8702
int ast_rdlock_context(struct ast_context *con)
Read locks a given context.
Definition: pbx.c:8525
const struct ast_ignorepat * ast_context_ignorepats_get(const struct ast_context *con, int idx)
Definition: pbx.c:8745
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ load_module()

static int load_module ( void  )
static

Definition at line 2126 of file pbx_config.c.

References AMI_EXTENSION_ADD, AMI_EXTENSION_REMOVE, ARRAY_LEN, ast_cli_register, ast_cli_register_multiple, ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, EVENT_FLAG_SYSTEM, manager_dialplan_extension_add(), manager_dialplan_extension_remove(), pbx_load_module(), static_config, unload_module(), and write_protect_config.

Referenced by reload().

2127 {
2128  int res;
2129 
2130  if (pbx_load_module()) {
2131  unload_module();
2132  return AST_MODULE_LOAD_DECLINE;
2133  }
2134 
2138 
2143 
2144  if (res) {
2145  unload_module();
2146  return AST_MODULE_LOAD_DECLINE;
2147  }
2148 
2149  return AST_MODULE_LOAD_SUCCESS;
2150 }
static int manager_dialplan_extension_remove(struct mansession *s, const struct message *m)
Definition: pbx_config.c:502
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int static_config
Definition: pbx_config.c:100
static int write_protect_config
Definition: pbx_config.c:101
#define AMI_EXTENSION_REMOVE
Definition: pbx_config.c:1620
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static int pbx_load_module(void)
Definition: pbx_config.c:2087
#define ast_cli_register(e)
Registers a command or an array of commands.
Definition: cli.h:256
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define AMI_EXTENSION_ADD
Definition: pbx_config.c:1619
static struct ast_cli_entry cli_dialplan_save
Definition: pbx_config.c:1616
static int unload_module(void)
Definition: pbx_config.c:1625
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_cli_entry cli_pbx_config[]
Definition: pbx_config.c:1605
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:186
static int manager_dialplan_extension_add(struct mansession *s, const struct message *m)
Definition: pbx_config.c:1195

◆ lookup_c_ip()

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

References ast_context_ignorepats_count(), ast_context_ignorepats_get(), ast_get_ignorepat_name(), ast_rdlock_context(), and ast_unlock_context().

Referenced by complete_dialplan_add_ignorepat(), and complete_dialplan_remove_ignorepat().

213 {
214  int idx;
215  int ret = 0;
216 
217  if (ast_rdlock_context(c)) {
218  /* error, skip */
219  return 0;
220  }
221 
222  for (idx = 0; idx < ast_context_ignorepats_count(c); idx++) {
223  const struct ast_ignorepat *ip = ast_context_ignorepats_get(c, idx);
224 
225  if (!strcmp(name, ast_get_ignorepat_name(ip))) {
226  ret = -1;
227  break;
228  }
229  }
231 
232  return ret;
233 }
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8530
const char * ast_get_ignorepat_name(const struct ast_ignorepat *ip)
Definition: pbx_ignorepat.c:42
ast_ignorepat: Ignore patterns in dial plan
Definition: pbx_ignorepat.c:37
static const char name[]
Definition: cdr_mysql.c:74
int ast_context_ignorepats_count(const struct ast_context *con)
Definition: pbx.c:8740
int ast_rdlock_context(struct ast_context *con)
Read locks a given context.
Definition: pbx.c:8525
const struct ast_ignorepat * ast_context_ignorepats_get(const struct ast_context *con, int idx)
Definition: pbx.c:8745

◆ lookup_ci()

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

return true if 'name' is included by context c

Definition at line 188 of file pbx_config.c.

References ast_context_includes_count(), ast_context_includes_get(), ast_get_include_name(), ast_rdlock_context(), and ast_unlock_context().

Referenced by complete_dialplan_add_include(), and complete_dialplan_remove_include().

189 {
190  int idx;
191  int ret = 0;
192 
193  if (ast_rdlock_context(c)) {
194  /* error, skip */
195  return 0;
196  }
197 
198  for (idx = 0; idx < ast_context_includes_count(c); idx++) {
199  const struct ast_include *i = ast_context_includes_get(c, idx);
200 
201  if (!strcmp(name, ast_get_include_name(i))) {
202  ret = -1;
203  break;
204  }
205  }
207 
208  return ret;
209 }
ast_include: include= support in extensions.conf
Definition: pbx_include.c:37
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8530
int ast_context_includes_count(const struct ast_context *con)
Definition: pbx.c:8697
static const char name[]
Definition: cdr_mysql.c:74
const char * ast_get_include_name(const struct ast_include *include)
Definition: pbx_include.c:50
const struct ast_include * ast_context_includes_get(const struct ast_context *con, int idx)
Definition: pbx.c:8702
int ast_rdlock_context(struct ast_context *con)
Read locks a given context.
Definition: pbx.c:8525

◆ manager_dialplan_extension_add()

static int manager_dialplan_extension_add ( struct mansession s,
const struct message m 
)
static

Definition at line 1195 of file pbx_config.c.

References ast_add_extension2(), ast_context_find_or_create(), ast_free_ptr(), ast_strdup, ast_strdupa, ast_strlen_zero, ast_true(), ast_unlock_contexts(), ast_wrlock_contexts(), astman_get_header(), astman_send_ack(), astman_send_error(), context, errno, exten, NULL, priority, PRIORITY_HINT, registrar, replace(), and strsep().

Referenced by load_module().

1196 {
1197  const char *context = astman_get_header(m, "Context");
1198  const char *extension = astman_get_header(m, "Extension");
1199  const char *priority = astman_get_header(m, "Priority");
1200  const char *application = astman_get_header(m, "Application");
1201  const char *application_data = astman_get_header(m, "ApplicationData");
1202  int replace = ast_true(astman_get_header(m, "Replace"));
1203  int ipriority;
1204  char *exten;
1205  char *cidmatch = NULL;
1206  struct ast_context *add_context;
1207 
1208  if (ast_strlen_zero(context) || ast_strlen_zero(extension) ||
1209  ast_strlen_zero(priority) || ast_strlen_zero(application)) {
1210  astman_send_error(s, m, "Context, Extension, Priority, and "
1211  "Application must be defined for DialplanExtensionAdd.");
1212  return 0;
1213  }
1214 
1215  /* Priority conversion/validation */
1216  if (!strcmp(priority, "hint")) {
1217  ipriority = PRIORITY_HINT;
1218  } else if ((sscanf(priority, "%30d", &ipriority) != 1) || (ipriority < 0)) {
1219  astman_send_error(s, m, "The priority specified was invalid.");
1220  return 0;
1221  }
1222 
1223  /* Split extension from cidmatch */
1224  exten = ast_strdupa(extension);
1225 
1226  if (strchr(exten, '/')) {
1227  cidmatch = exten;
1228  strsep(&cidmatch, "/");
1229  }
1230 
1231  if (ast_wrlock_contexts()) {
1232  astman_send_error(s, m, "Failed to lock contexts list. Try again later.");
1233  return 0;
1234  }
1235 
1236  add_context = ast_context_find_or_create(NULL, NULL, context, registrar);
1237  if (!add_context) {
1238  astman_send_error(s, m, "Could not find or create context specified "
1239  "for the extension.");
1241  return 0;
1242  }
1243 
1244  if (ast_add_extension2(add_context, replace, exten, ipriority, NULL, cidmatch,
1245  application, ast_strdup(application_data), ast_free_ptr, registrar, NULL, 0)) {
1247  switch (errno) {
1248  case ENOMEM:
1249  astman_send_error(s, m, "Out of Memory");
1250  break;
1251 
1252  case EBUSY:
1253  astman_send_error(s, m, "Failed to lock context(s) list");
1254  break;
1255 
1256  case ENOENT:
1257  astman_send_error(s, m, "Context does not exist");
1258  break;
1259 
1260  case EEXIST:
1261  astman_send_error(s, m, "That extension and priority already exist at that context");
1262  break;
1263 
1264  default:
1265  astman_send_error(s, m, "Failed to add extension");
1266  break;
1267  }
1268  return 0;
1269  }
1271 
1272  astman_send_ack(s, m, "Added requested extension");
1273 
1274  return 0;
1275 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:8502
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static int priority
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
structure to hold extensions
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static const char registrar[]
Definition: pbx_config.c:97
#define PRIORITY_HINT
Definition: pbx.h:54
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8512
int errno
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:790
char * strsep(char **str, const char *delims)
int ast_add_extension2(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, const char *registrar_file, int registrar_line)
Add an extension to an extension context, this time with an ast_context *.
Definition: pbx.c:7299
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6198
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284

◆ manager_dialplan_extension_remove()

static int manager_dialplan_extension_remove ( struct mansession s,
const struct message m 
)
static

Definition at line 502 of file pbx_config.c.

References ast_context_remove_extension_callerid(), ast_strdupa, ast_strlen_zero, astman_get_header(), astman_send_ack(), astman_send_error(), context, exten, NULL, priority, PRIORITY_HINT, registrar, and strsep().

Referenced by load_module().

503 {
504  const char *context = astman_get_header(m, "Context");
505  const char *extension = astman_get_header(m, "Extension");
506  const char *priority = astman_get_header(m, "Priority");
507 
508  int ipriority;
509  char *exten;
510  char *cidmatch = NULL;
511 
512  if (ast_strlen_zero(context) || ast_strlen_zero(extension)) {
513  astman_send_error(s, m, "Context and Extension must be provided "
514  "for DialplanExtensionRemove");
515  return 0;
516  }
517 
518  exten = ast_strdupa(extension);
519 
520  if (strchr(exten, '/')) {
521  cidmatch = exten;
522  strsep(&cidmatch, "/");
523  }
524 
525  if (ast_strlen_zero(priority)) {
526  ipriority = 0;
527  } else if (!strcmp("hint", priority)) {
528  ipriority = PRIORITY_HINT;
529  } else if ((sscanf(priority, "%30d", &ipriority) != 1) || ipriority <= 0) {
530  astman_send_error(s, m, "The priority specified was invalid.");
531  return 0;
532  }
533 
534  if (!ast_context_remove_extension_callerid(context, exten, ipriority,
535  /* Do not substitute S_OR; it is not the same thing */
536  !ast_strlen_zero(cidmatch) ? cidmatch : (ipriority ? "" : NULL),
537  !ast_strlen_zero(cidmatch) ? 1 : 0, registrar)) {
538  if (ipriority) {
539  astman_send_ack(s, m, "Removed the requested priority from the extension");
540  } else {
541  astman_send_ack(s, m, "Removed the requested extension");
542  }
543  } else {
544  astman_send_error(s, m, "Failed to remove requested extension");
545  }
546 
547  return 0;
548 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
#define NULL
Definition: resample.c:96
static int priority
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
structure to hold extensions
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static const char registrar[]
Definition: pbx_config.c:97
#define PRIORITY_HINT
Definition: pbx.h:54
int ast_context_remove_extension_callerid(const char *context, const char *extension, int priority, const char *callerid, int matchcid, const char *registrar)
Definition: pbx.c:4957
char * strsep(char **str, const char *delims)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ partial_match()

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

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

252 {
253  return (len == 0 || !strncmp(s, word, len));
254 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
short word

◆ pbx_load_config()

static int pbx_load_config ( const char *  config_file)
static

Definition at line 1674 of file pbx_config.c.

References ast_add_extension2(), ast_category_browse(), ast_config_destroy(), ast_config_load, ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_find_or_create(), ast_context_set_autohints(), ast_copy_string(), ast_findlabel_extension2(), ast_free, ast_free_ptr(), ast_log, ast_opt_dont_warn, ast_shrink_phone_number(), ast_skip_blanks(), ast_strdup, ast_strip(), ast_strlen_zero, ast_true(), ast_variable_browse(), ast_variable_retrieve(), autofallthrough_config, clearglobalvars_config, config_file, CONFIG_STATUS_FILEINVALID, end, errno, ext, extenpatternmatchnew_config, ast_variable::file, ast_variable::lineno, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, NULL, overrideswitch_config, pbx_builtin_setvar_helper(), pbx_strsep(), pbx_substitute_variables_helper(), PRIORITY_HINT, registrar, S_OR, static_config, strsep(), userscontext, ast_variable::value, and write_protect_config.

Referenced by pbx_load_module().

1675 {
1676  struct ast_config *cfg;
1677  char *end;
1678  char *label;
1679 #ifdef LOW_MEMORY
1680  char realvalue[256];
1681 #else
1682  char realvalue[8192];
1683 #endif
1684  int lastpri = -2;
1685  struct ast_context *con;
1686  struct ast_variable *v;
1687  const char *cxt;
1688  const char *aft;
1689  const char *newpm, *ovsw;
1690  struct ast_flags config_flags = { 0 };
1691  char lastextension[256];
1692  cfg = ast_config_load(config_file, config_flags);
1693  if (!cfg || cfg == CONFIG_STATUS_FILEINVALID)
1694  return 0;
1695 
1696  /* Use existing config to populate the PBX table */
1697  static_config = ast_true(ast_variable_retrieve(cfg, "general", "static"));
1698  write_protect_config = ast_true(ast_variable_retrieve(cfg, "general", "writeprotect"));
1699  if ((aft = ast_variable_retrieve(cfg, "general", "autofallthrough")))
1701  if ((newpm = ast_variable_retrieve(cfg, "general", "extenpatternmatchnew")))
1703  clearglobalvars_config = ast_true(ast_variable_retrieve(cfg, "general", "clearglobalvars"));
1704  if ((ovsw = ast_variable_retrieve(cfg, "general", "overrideswitch"))) {
1705  if (overrideswitch_config) {
1707  }
1708  if (!ast_strlen_zero(ovsw)) {
1710  } else {
1712  }
1713  }
1714 
1715  ast_copy_string(userscontext, ast_variable_retrieve(cfg, "general", "userscontext") ?: "default", sizeof(userscontext));
1716 
1717  /* ast_variable_browse does not merge multiple [globals] sections */
1718  for (cxt = ast_category_browse(cfg, NULL);
1719  cxt;
1720  cxt = ast_category_browse(cfg, cxt)) {
1721  if (strcasecmp(cxt, "globals")) {
1722  continue;
1723  }
1724 
1725  for (v = ast_variable_browse(cfg, cxt); v; v = v->next) {
1726  pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
1727  pbx_builtin_setvar_helper(NULL, v->name, realvalue);
1728  }
1729  }
1730 
1731  for (cxt = ast_category_browse(cfg, NULL);
1732  cxt;
1733  cxt = ast_category_browse(cfg, cxt)) {
1734  /* All categories but "general" or "globals" are considered contexts */
1735  if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) {
1736  continue;
1737  }
1739  continue;
1740  }
1741 
1742  /* Reset continuation items at the beginning of each context */
1743  lastextension[0] = '\0';
1744  lastpri = -2;
1745 
1746  for (v = ast_variable_browse(cfg, cxt); v; v = v->next) {
1747  char *tc = NULL;
1748  char realext[256] = "";
1749  char *stringp, *ext;
1750  const char *vfile;
1751 
1752  /* get filename for error reporting from top level or an #include */
1753  vfile = !*v->file ? config_file : v->file;
1754 
1755  if (!strncasecmp(v->name, "same", 4)) {
1756  if (ast_strlen_zero(lastextension)) {
1758  "No previous pattern in the first entry of context '%s' to match '%s' at line %d of %s!\n",
1759  cxt, v->name, v->lineno, vfile);
1760  continue;
1761  }
1762  if ((stringp = tc = ast_strdup(v->value))) {
1763  ast_copy_string(realext, lastextension, sizeof(realext));
1764  goto process_extension;
1765  }
1766  } else if (!strcasecmp(v->name, "exten")) {
1767  int ipri;
1768  char *plus;
1769  char *pri, *appl, *data, *cidmatch;
1770 
1771  if (!(stringp = tc = ast_strdup(v->value))) {
1772  continue;
1773  }
1774 
1775  ext = S_OR(pbx_strsep(&stringp, ","), "");
1776  pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1);
1777  ast_copy_string(lastextension, realext, sizeof(lastextension));
1778 process_extension:
1779  ipri = -2;
1780  if ((cidmatch = strchr(realext, '/'))) {
1781  *cidmatch++ = '\0';
1782  ast_shrink_phone_number(cidmatch);
1783  }
1784  pri = ast_strip(S_OR(strsep(&stringp, ","), ""));
1785  if ((label = strchr(pri, '('))) {
1786  *label++ = '\0';
1787  if ((end = strchr(label, ')'))) {
1788  *end = '\0';
1789  } else {
1791  "Label missing trailing ')' at line %d of %s\n",
1792  v->lineno, vfile);
1793  ast_free(tc);
1794  continue;
1795  }
1796  }
1797  if ((plus = strchr(pri, '+'))) {
1798  *plus++ = '\0';
1799  }
1800  if (!strcmp(pri,"hint")) {
1801  ipri = PRIORITY_HINT;
1802  } else if (!strcmp(pri, "next") || !strcmp(pri, "n")) {
1803  if (lastpri > -2) {
1804  ipri = lastpri + 1;
1805  } else {
1807  "Can't use 'next' priority on the first entry at line %d of %s!\n",
1808  v->lineno, vfile);
1809  ast_free(tc);
1810  continue;
1811  }
1812  } else if (!strcmp(pri, "same") || !strcmp(pri, "s")) {
1813  if (lastpri > -2) {
1814  ipri = lastpri;
1815  } else {
1817  "Can't use 'same' priority on the first entry at line %d of %s!\n",
1818  v->lineno, vfile);
1819  ast_free(tc);
1820  continue;
1821  }
1822  } else if (sscanf(pri, "%30d", &ipri) != 1 &&
1823  (ipri = ast_findlabel_extension2(NULL, con, realext, pri, cidmatch)) < 1) {
1825  "Invalid priority/label '%s' at line %d of %s\n",
1826  pri, v->lineno, vfile);
1827  ipri = 0;
1828  ast_free(tc);
1829  continue;
1830  } else if (ipri < 1) {
1831  ast_log(LOG_WARNING, "Invalid priority '%s' at line %d of %s\n",
1832  pri, v->lineno, vfile);
1833  ast_free(tc);
1834  continue;
1835  }
1836  appl = S_OR(stringp, "");
1837  /* Find the first occurrence of '(' */
1838  if (!strchr(appl, '(')) {
1839  /* No arguments */
1840  data = "";
1841  } else {
1842  char *orig_appl = ast_strdup(appl);
1843 
1844  if (!orig_appl) {
1845  ast_free(tc);
1846  continue;
1847  }
1848 
1849  appl = strsep(&stringp, "(");
1850 
1851  /* check if there are variables or expressions without an application, like: exten => 100,hint,DAHDI/g0/${GLOBAL(var)} */
1852  if (strstr(appl, "${") || strstr(appl, "$[")){
1853  /* set appl to original one */
1854  strcpy(appl, orig_appl);
1855  /* set no data */
1856  data = "";
1857  /* no variable before application found -> go ahead */
1858  } else {
1859  data = S_OR(stringp, "");
1860  if ((end = strrchr(data, ')'))) {
1861  *end = '\0';
1862  } else {
1864  "No closing parenthesis found? '%s(%s' at line %d of %s\n",
1865  appl, data, v->lineno, vfile);
1866  }
1867  }
1868  ast_free(orig_appl);
1869  }
1870 
1871  appl = ast_skip_blanks(appl);
1872  if (ipri) {
1873  const char *registrar_file;
1874  if (plus) {
1875  ipri += atoi(plus);
1876  }
1877  lastpri = ipri;
1878  if (!ast_opt_dont_warn && (!strcmp(realext, "_.") || !strcmp(realext, "_!"))) {
1880  "The use of '%s' for an extension is strongly discouraged and can have unexpected behavior. Please use '_X%c' instead at line %d of %s\n",
1881  realext, realext[1], v->lineno, vfile);
1882  }
1883  /* Don't include full path if the configuration file includes slashes */
1884  registrar_file = strrchr(vfile, '/');
1885  if (!registrar_file) {
1886  registrar_file = vfile;
1887  } else {
1888  registrar_file++; /* Skip past the end slash */
1889  }
1890  if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, ast_strdup(data), ast_free_ptr, registrar, registrar_file, v->lineno)) {
1892  "Unable to register extension at line %d of %s\n",
1893  v->lineno, vfile);
1894  }
1895  }
1896  ast_free(tc);
1897  } else if (!strcasecmp(v->name, "include")) {
1898  pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
1899  if (ast_context_add_include2(con, realvalue, registrar)) {
1900  switch (errno) {
1901  case ENOMEM:
1902  ast_log(LOG_WARNING, "Out of memory for context addition\n");
1903  break;
1904 
1905  case EBUSY:
1906  ast_log(LOG_WARNING, "Failed to lock context(s) list, please try again later\n");
1907  break;
1908 
1909  case EEXIST:
1911  "Context '%s' already included in '%s' context on include at line %d of %s\n",
1912  v->value, cxt, v->lineno, vfile);
1913  break;
1914 
1915  case ENOENT:
1916  case EINVAL:
1918  "There is no existence of context '%s' included at line %d of %s\n",
1919  errno == ENOENT ? v->value : cxt, v->lineno, vfile);
1920  break;
1921 
1922  default:
1924  "Failed to include '%s' in '%s' context at line %d of %s\n",
1925  v->value, cxt, v->lineno, vfile);
1926  break;
1927  }
1928  }
1929  } else if (!strcasecmp(v->name, "ignorepat")) {
1930  pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
1931  if (ast_context_add_ignorepat2(con, realvalue, registrar)) {
1933  "Unable to include ignorepat '%s' in context '%s' at line %d of %s\n",
1934  v->value, cxt, v->lineno, vfile);
1935  }
1936  } else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) {
1937  char *appl, *data;
1938  stringp = realvalue;
1939 
1940  if (!strcasecmp(v->name, "switch")) {
1941  pbx_substitute_variables_helper(NULL, v->value, realvalue, sizeof(realvalue) - 1);
1942  } else {
1943  ast_copy_string(realvalue, v->value, sizeof(realvalue));
1944  }
1945  appl = strsep(&stringp, "/");
1946  data = S_OR(stringp, "");
1947  if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar)) {
1949  "Unable to include switch '%s' in context '%s' at line %d of %s\n",
1950  v->value, cxt, v->lineno, vfile);
1951  }
1952  } else if (!strcasecmp(v->name, "autohints")) {
1954  } else {
1956  "==!!== Unknown directive: %s at line %d of %s -- IGNORING!!!\n",
1957  v->name, v->lineno, vfile);
1958  }
1959  }
1960  }
1961  ast_config_destroy(cfg);
1962  return 1;
1963 }
struct ast_variable * next
static int clearglobalvars_config
Definition: pbx_config.c:103
static int autofallthrough_config
Definition: pbx_config.c:102
static const char config_file[]
Definition: cdr_odbc.c:57
static int static_config
Definition: pbx_config.c:100
int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
Find the priority of an extension that has the specified label.
Definition: extconf.c:4978
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
static int write_protect_config
Definition: pbx_config.c:101
static int extenpatternmatchnew_config
Definition: pbx_config.c:104
#define LOG_WARNING
Definition: logger.h:274
#define CONFIG_STATUS_FILEINVALID
Structure for variables, used for configurations and for channel variables.
int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
Adds a switch (first param is a ast_context)
Definition: ael_main.c:370
static char userscontext[AST_MAX_EXTENSION]
Definition: pbx_config.c:98
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
const char * ext
Definition: http.c:147
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_context_add_include2(struct ast_context *con, const char *include, const char *registrar)
Add a context include.
Definition: ael_main.c:359
#define ast_opt_dont_warn
Definition: options.h:125
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
static const char registrar[]
Definition: pbx_config.c:97
#define PRIORITY_HINT
Definition: pbx.h:54
static char * overrideswitch_config
Definition: pbx_config.c:105
#define LOG_ERROR
Definition: logger.h:285
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
int errno
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
static char * pbx_strsep(char **destructible, const char *delim)
Definition: pbx_config.c:1644
static struct ast_hashtab * local_table
Definition: pbx_config.c:112
#define ast_free(a)
Definition: astmm.h:182
Structure used to handle boolean flags.
Definition: utils.h:199
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
char * strsep(char **str, const char *delims)
int ast_add_extension2(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, const char *registrar_file, int registrar_line)
Add an extension to an extension context, this time with an ast_context *.
Definition: pbx.c:7299
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static struct ast_context * local_contexts
Definition: pbx_config.c:111
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: ael_main.c:211
int ast_context_add_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
Definition: ael_main.c:348
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6198
void ast_context_set_autohints(struct ast_context *con, int enabled)
Enable or disable autohints support on a context.
Definition: pbx.c:6272
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:947
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284

◆ pbx_load_module()

static int pbx_load_module ( void  )
static

Definition at line 2087 of file pbx_config.c.

References ast_context_verify_includes(), ast_hashtab_compare_contexts(), ast_hashtab_create, ast_hashtab_destroy(), 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_mutex_lock, ast_mutex_unlock, ast_walk_contexts(), autofallthrough_config, config, extenpatternmatchnew_config, NULL, overrideswitch_config, pbx_load_config(), pbx_load_users(), pbx_set_autofallthrough(), pbx_set_extenpatternmatchnew(), pbx_set_overrideswitch(), registrar, and reload_lock.

Referenced by complete_dialplan_remove_ignorepat(), handle_cli_dialplan_reload(), load_module(), and reload().

2088 {
2089  struct ast_context *con;
2090 
2092 
2093  if (!local_table) {
2095  if (!local_table) {
2097  return AST_MODULE_LOAD_DECLINE;
2098  }
2099  }
2100 
2101  if (!pbx_load_config(config)) {
2103  local_table = NULL;
2105  return AST_MODULE_LOAD_DECLINE;
2106  }
2107 
2108  pbx_load_users();
2109 
2111  local_table = NULL; /* the local table has been moved into the global one. */
2112  local_contexts = NULL;
2113 
2115 
2116  for (con = NULL; (con = ast_walk_contexts(con));)
2118 
2122 
2123  return AST_MODULE_LOAD_SUCCESS;
2124 }
int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b)
hashtable functions for contexts
Definition: ael_main.c:589
static int pbx_load_config(const char *config_file)
Definition: pbx_config.c:1674
static int autofallthrough_config
Definition: pbx_config.c:102
int ast_hashtab_newsize_java(struct ast_hashtab *tab)
Create a prime number roughly 2x the current table size.
Definition: hashtab.c:127
static int extenpatternmatchnew_config
Definition: pbx_config.c:104
struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: conf2ael.c:618
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
int ast_hashtab_resize_java(struct ast_hashtab *tab)
Determines if a table resize should occur using the Java algorithm (if the table load factor is 75% o...
Definition: hashtab.c:84
static void pbx_load_users(void)
Definition: pbx_config.c:1977
int pbx_set_extenpatternmatchnew(int newval)
Definition: pbx.c:4781
static const char registrar[]
Definition: pbx_config.c:97
int pbx_set_autofallthrough(int newval)
Definition: pbx.c:4774
static char * overrideswitch_config
Definition: pbx_config.c:105
void ast_merge_contexts_and_delete(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *registrar)
Merge the temporary contexts into a global contexts list and delete from the global list the ones tha...
Definition: conf2ael.c:639
static ast_mutex_t reload_lock
Definition: pbx_config.c:109
static struct ast_hashtab * local_table
Definition: pbx_config.c:112
unsigned int ast_hashtab_hash_contexts(const void *obj)
Definition: ael_main.c:596
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static const char config[]
Definition: pbx_config.c:96
static struct ast_context * local_contexts
Definition: pbx_config.c:111
void pbx_set_overrideswitch(const char *newval)
Definition: pbx.c:4788
#define ast_hashtab_create(initial_buckets, compare, resize, newsize, hash, do_locking)
Definition: hashtab.h:261
int ast_context_verify_includes(struct ast_context *con)
Verifies includes in an ast_contect structure.
Definition: conf2ael.c:632
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284
#define ast_mutex_unlock(a)
Definition: lock.h:188
void ast_hashtab_destroy(struct ast_hashtab *tab, void(*objdestroyfunc)(void *obj))
This func will free the hash table and all its memory.
Definition: hashtab.c:363

◆ pbx_load_users()

static void pbx_load_users ( void  )
static

Definition at line 1977 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_opt_stdexten_macro, ast_strdup, ast_strlen_zero, ast_true(), ast_variable_retrieve(), c, ext, LOG_ERROR, NULL, registrar, strsep(), tmp(), and userscontext.

Referenced by pbx_load_module().

1978 {
1979  struct ast_config *cfg;
1980  char *cat, *chan;
1981  const char *dahdichan;
1982  const char *hasexten, *altexts;
1983  char tmp[256];
1984  char iface[256];
1985  char dahdicopy[256];
1986  char *ext, altcopy[256];
1987  char *c;
1988  int hasvoicemail;
1989  int start, finish, x;
1990  struct ast_context *con = NULL;
1991  struct ast_flags config_flags = { 0 };
1992 
1993  cfg = ast_config_load("users.conf", config_flags);
1994  if (!cfg)
1995  return;
1996 
1997  for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
1998  if (!strcasecmp(cat, "general"))
1999  continue;
2000  iface[0] = '\0';
2001  if (ast_true(ast_config_option(cfg, cat, "hassip"))) {
2002  snprintf(tmp, sizeof(tmp), "SIP/%s", cat);
2003  append_interface(iface, sizeof(iface), tmp);
2004  }
2005  if (ast_true(ast_config_option(cfg, cat, "hasiax"))) {
2006  snprintf(tmp, sizeof(tmp), "IAX2/%s", cat);
2007  append_interface(iface, sizeof(iface), tmp);
2008  }
2009  if (ast_true(ast_config_option(cfg, cat, "hash323"))) {
2010  snprintf(tmp, sizeof(tmp), "H323/%s", cat);
2011  append_interface(iface, sizeof(iface), tmp);
2012  }
2013  hasexten = ast_config_option(cfg, cat, "hasexten");
2014  if (hasexten && !ast_true(hasexten))
2015  continue;
2016  hasvoicemail = ast_true(ast_config_option(cfg, cat, "hasvoicemail"));
2017  dahdichan = ast_variable_retrieve(cfg, cat, "dahdichan");
2018  if (!dahdichan)
2019  dahdichan = ast_variable_retrieve(cfg, "general", "dahdichan");
2020  if (!ast_strlen_zero(dahdichan)) {
2021  ast_copy_string(dahdicopy, dahdichan, sizeof(dahdicopy));
2022  c = dahdicopy;
2023  chan = strsep(&c, ",");
2024  while (chan) {
2025  if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
2026  /* Range */
2027  } else if (sscanf(chan, "%30d", &start)) {
2028  /* Just one */
2029  finish = start;
2030  } else {
2031  start = 0; finish = 0;
2032  }
2033  if (finish < start) {
2034  x = finish;
2035  finish = start;
2036  start = x;
2037  }
2038  for (x = start; x <= finish; x++) {
2039  snprintf(tmp, sizeof(tmp), "DAHDI/%d", x);
2040  append_interface(iface, sizeof(iface), tmp);
2041  }
2042  chan = strsep(&c, ",");
2043  }
2044  }
2045  if (!ast_strlen_zero(iface)) {
2046  /* Only create a context here when it is really needed. Otherwise default empty context
2047  created by pbx_config may conflict with the one explicitly created by pbx_ael */
2048  if (!con)
2050 
2051  if (!con) {
2052  ast_log(LOG_ERROR, "Can't find/create user context '%s'\n", userscontext);
2053  return;
2054  }
2055 
2056  /* Add hint */
2057  ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar, NULL, 0);
2058  /* If voicemail, use "stdexten" else use plain old dial */
2059  if (hasvoicemail) {
2060  if (ast_opt_stdexten_macro) {
2061  /* Use legacy stdexten macro method. */
2062  snprintf(tmp, sizeof(tmp), "stdexten,%s,${HINT}", cat);
2063  ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", ast_strdup(tmp), ast_free_ptr, registrar, NULL, 0);
2064  } else {
2065  snprintf(tmp, sizeof(tmp), "%s,stdexten(${HINT})", cat);
2066  ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Gosub", ast_strdup(tmp), ast_free_ptr, registrar, NULL, 0);
2067  }
2068  } else {
2069  ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", ast_strdup("${HINT}"), ast_free_ptr, registrar, NULL, 0);
2070  }
2071  altexts = ast_variable_retrieve(cfg, cat, "alternateexts");
2072  if (!ast_strlen_zero(altexts)) {
2073  snprintf(tmp, sizeof(tmp), "%s,1", cat);
2074  ast_copy_string(altcopy, altexts, sizeof(altcopy));
2075  c = altcopy;
2076  ext = strsep(&c, ",");
2077  while (ext) {
2078  ast_add_extension2(con, 0, ext, 1, NULL, NULL, "Goto", ast_strdup(tmp), ast_free_ptr, registrar, NULL, 0);
2079  ext = strsep(&c, ",");
2080  }
2081  }
2082  }
2083  }
2084  ast_config_destroy(cfg);
2085 }
static int tmp()
Definition: bt_open.c:389
static char userscontext[AST_MAX_EXTENSION]
Definition: pbx_config.c:98
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
const char * ext
Definition: http.c:147
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
static const char registrar[]
Definition: pbx_config.c:97
#define ast_opt_stdexten_macro
Definition: options.h:118
#define LOG_ERROR
Definition: logger.h:285
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
static void append_interface(char *iface, int maxlen, char *add)
Definition: pbx_config.c:1965
static struct ast_hashtab * local_table
Definition: pbx_config.c:112
Structure used to handle boolean flags.
Definition: utils.h:199
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
char * strsep(char **str, const char *delims)
int ast_add_extension2(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, const char *registrar_file, int registrar_line)
Add an extension to an extension context, this time with an ast_context *.
Definition: pbx.c:7299
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static struct ast_context * local_contexts
Definition: pbx_config.c:111
const char * ast_config_option(struct ast_config *cfg, const char *cat, const char *var)
Retrieve a configuration variable within the configuration set.
Definition: main/config.c:684
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6198
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284

◆ pbx_strsep()

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

Definition at line 1644 of file pbx_config.c.

References NULL.

Referenced by pbx_load_config().

1645 {
1646  int square = 0;
1647  char *res;
1648 
1649  if (!destructible || !*destructible) {
1650  return NULL;
1651  }
1652  res = *destructible;
1653  for (; **destructible; (*destructible)++) {
1654  if (**destructible == '[' && !strchr(delim, '[')) {
1655  square++;
1656  } else if (**destructible == ']' && !strchr(delim, ']')) {
1657  if (square) {
1658  square--;
1659  }
1660  } else if (**destructible == '\\' && !strchr(delim, '\\')) {
1661  (*destructible)++;
1662  } else if (strchr(delim, **destructible) && !square) {
1663  **destructible = '\0';
1664  (*destructible)++;
1665  break;
1666  }
1667  }
1668  if (**destructible == '\0') {
1669  *destructible = NULL;
1670  }
1671  return res;
1672 }
#define NULL
Definition: resample.c:96

◆ reload()

static int reload ( void  )
static

Definition at line 2152 of file pbx_config.c.

References AST_MODFLAG_DEFAULT, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, clearglobalvars_config, load_module(), pbx_builtin_clear_globals(), pbx_load_module(), and unload_module().

2153 {
2156  return pbx_load_module();
2157 }
static int clearglobalvars_config
Definition: pbx_config.c:103
void pbx_builtin_clear_globals(void)
static int pbx_load_module(void)
Definition: pbx_config.c:2087

◆ skip_words()

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

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

237 {
238  int in_blank = 0;
239  for (;n && *p; p++) {
240  if (isblank(*p) /* XXX order is important */ && !in_blank) {
241  n--; /* one word is gone */
242  in_blank = 1;
243  } else if (/* !is_blank(*p), we know already, && */ in_blank) {
244  in_blank = 0;
245  }
246  }
247  return p;
248 }

◆ split_ec()

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

References ast_free, ast_strdup, c, and NULL.

Referenced by complete_dialplan_remove_extension(), and handle_cli_dialplan_remove_extension().

260 {
261  char *i, *c, *e = ast_strdup(src); /* now src is not used anymore */
262 
263  if (e == NULL)
264  return -1; /* malloc error */
265  /* now, parse values from 'exten@context' */
266  *ext = e;
267  c = strchr(e, '@');
268  if (c == NULL) /* no context part */
269  *ctx = ""; /* it is not overwritten, anyways */
270  else { /* found context, check for duplicity ... */
271  *c++ = '\0';
272  *ctx = c;
273  if (strchr(c, '@')) { /* two @, not allowed */
274  ast_free(e);
275  return -1;
276  }
277  }
278  if (cid && (i = strchr(e, '/'))) {
279  *i++ = '\0';
280  *cid = i;
281  } else if (cid) {
282  /* Signal none detected */
283  *cid = NULL;
284  }
285  return 0;
286 }
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
const char * ext
Definition: http.c:147
#define ast_free(a)
Definition: astmm.h:182

◆ unload_module()

static int unload_module ( void  )
static

Standard module functions ...

Definition at line 1625 of file pbx_config.c.

References AMI_EXTENSION_ADD, AMI_EXTENSION_REMOVE, ARRAY_LEN, ast_cli_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_free, ast_manager_unregister(), NULL, overrideswitch_config, and registrar.

Referenced by load_module(), and reload().

1626 {
1630 
1635 
1636  return 0;
1637 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: main/cli.c:2397
#define AMI_EXTENSION_REMOVE
Definition: pbx_config.c:1620
#define NULL
Definition: resample.c:96
#define AMI_EXTENSION_ADD
Definition: pbx_config.c:1619
static const char registrar[]
Definition: pbx_config.c:97
static char * overrideswitch_config
Definition: pbx_config.c:105
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
static struct ast_cli_entry cli_dialplan_save
Definition: pbx_config.c:1616
#define ast_free(a)
Definition: astmm.h:182
static struct ast_cli_entry cli_pbx_config[]
Definition: pbx_config.c:1605
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context or ANY context if NULL)
Definition: conf2ael.c:625

Variable Documentation

◆ __mod_info

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, }
static

Definition at line 2164 of file pbx_config.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 2164 of file pbx_config.c.

◆ autofallthrough_config

int autofallthrough_config = 1
static

Definition at line 102 of file pbx_config.c.

Referenced by handle_cli_dialplan_save(), pbx_load_config(), and pbx_load_module().

◆ clearglobalvars_config

int clearglobalvars_config = 0
static

◆ cli_dialplan_save

struct ast_cli_entry cli_dialplan_save
static
Initial value:
=
{ .handler = handle_cli_dialplan_save , .summary = "Save current dialplan into a file" ,}
static char * handle_cli_dialplan_save(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
&#39;save dialplan&#39; CLI command implementation functions ...
Definition: pbx_config.c:809

Definition at line 1616 of file pbx_config.c.

◆ cli_pbx_config

struct ast_cli_entry cli_pbx_config[]
static

CLI entries for commands provided by this module

Definition at line 1605 of file pbx_config.c.

◆ config

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

Definition at line 96 of file pbx_config.c.

Referenced by handle_cli_dialplan_save(), and pbx_load_module().

◆ extenpatternmatchnew_config

int extenpatternmatchnew_config = 0
static

Definition at line 104 of file pbx_config.c.

Referenced by handle_cli_dialplan_save(), pbx_load_config(), and pbx_load_module().

◆ local_contexts

struct ast_context* local_contexts = NULL
static

Definition at line 111 of file pbx_config.c.

◆ local_table

struct ast_hashtab* local_table = NULL
static

Definition at line 112 of file pbx_config.c.

Referenced by pbx_load_module().

◆ overrideswitch_config

char* overrideswitch_config = NULL
static

◆ registrar

const char registrar[] = "pbx_config"
static

◆ reload_lock

ast_mutex_t reload_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 109 of file pbx_config.c.

Referenced by pbx_load_module().

◆ save_dialplan_lock

ast_mutex_t save_dialplan_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 107 of file pbx_config.c.

Referenced by handle_cli_dialplan_save().

◆ static_config

int static_config = 0
static

Definition at line 100 of file pbx_config.c.

Referenced by handle_cli_dialplan_save(), load_module(), and pbx_load_config().

◆ userscontext

char userscontext[AST_MAX_EXTENSION] = "default"
static

Definition at line 98 of file pbx_config.c.

Referenced by pbx_load_config(), and pbx_load_users().

◆ write_protect_config

int write_protect_config = 1
static

Definition at line 101 of file pbx_config.c.

Referenced by handle_cli_dialplan_save(), load_module(), and pbx_load_config().