aboutsummaryrefslogtreecommitdiffstats
path: root/pbx.c
diff options
context:
space:
mode:
authormatteo <matteo@f38db490-d61c-443f-a65b-d21fe96a405b>2003-02-12 13:59:15 +0000
committermatteo <matteo@f38db490-d61c-443f-a65b-d21fe96a405b>2003-02-12 13:59:15 +0000
commit6f8508e0dc91d74f9c126759b28d711eeffca2ac (patch)
tree9345a8b61da436462f1b95c568b836a0e4174e6a /pbx.c
parent34e6118176bb9e9f3244bddef34632a779baafac (diff)
mer feb 12 14:56:57 CET 2003
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@612 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'pbx.c')
-rwxr-xr-xpbx.c229
1 files changed, 144 insertions, 85 deletions
diff --git a/pbx.c b/pbx.c
index cd6389f8a..59cb83bad 100755
--- a/pbx.c
+++ b/pbx.c
@@ -145,10 +145,12 @@ static int pbx_builtin_ringing(struct ast_channel *, void *);
static int pbx_builtin_congestion(struct ast_channel *, void *);
static int pbx_builtin_busy(struct ast_channel *, void *);
static int pbx_builtin_setvar(struct ast_channel *, void *);
+static int pbx_builtin_noop(struct ast_channel *, void *);
static int pbx_builtin_gotoif(struct ast_channel *, void *);
void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value);
char *pbx_builtin_getvar_helper(struct ast_channel *chan, char *name);
+static struct varshead globals = AST_LIST_HEAD_INITIALIZER(varshead);
static struct pbx_builtin {
char name[AST_MAX_APP];
@@ -261,6 +263,10 @@ static struct pbx_builtin {
"Set variable to value",
" Setvar(#n=value): Sets variable n to value" },
+ { "NoOp", pbx_builtin_noop,
+"No operation",
+" NoOp(): No-operation; Does nothing." },
+
{ "GotoIf", pbx_builtin_gotoif,
"Conditional goto",
" GotoIf(Condition?label1:label2): Go to label 1 if condition is\n"
@@ -417,47 +423,83 @@ static void pbx_destroy(struct ast_pbx *p)
free(p);
}
+#define EXTENSION_MATCH_CORE(data,pattern,match) {\
+ /* All patterns begin with _ */\
+ if (pattern[0] != '_') \
+ return 0;\
+ /* Start optimistic */\
+ match=1;\
+ pattern++;\
+ while(match && *data && *pattern && (*pattern != '/')) {\
+ switch(toupper(*pattern)) {\
+ case '[': \
+ {\
+ int i,border=0;\
+ char *where;\
+ match=0;\
+ pattern++;\
+ where=strchr(pattern,']');\
+ if (where)\
+ border=(int)(where-pattern);\
+ if (!where || border > strlen(pattern)) {\
+ ast_log(LOG_WARNING, "Wrong usage of [] in the extension\n");\
+ return match;\
+ }\
+ for (i=0; i<border; i++) {\
+ int res=0;\
+ if (i+2<border)\
+ if (pattern[i+1]=='-') {\
+ if (*data >= pattern[i] && *data <= pattern[i+2]) {\
+ res=1;\
+ } else {\
+ i+=2;\
+ continue;\
+ }\
+ }\
+ if (res==1 || *data==pattern[i]) {\
+ match = 1;\
+ break;\
+ }\
+ }\
+ pattern+=border;\
+ break;\
+ }\
+ case 'N':\
+ if ((*data < '2') || (*data > '9'))\
+ match=0;\
+ break;\
+ case 'X':\
+ if ((*data < '0') || (*data > '9'))\
+ match = 0;\
+ break;\
+ case 'Z':\
+ if ((*data < '1') || (*data > '9'))\
+ match = 0;\
+ break;\
+ case '.':\
+ /* Must match */\
+ return 1;\
+ case ' ':\
+ case '-':\
+ /* Ignore these characters */\
+ data--;\
+ break;\
+ default:\
+ if (*data != *pattern)\
+ match =0;\
+ }\
+ data++;\
+ pattern++;\
+ }\
+}
+
int ast_extension_match(char *pattern, char *data)
{
int match;
/* If they're the same return */
if (!strcasecmp(pattern, data))
return 1;
- /* All patterns begin with _ */
- if (pattern[0] != '_')
- return 0;
- /* Start optimistic */
- match=1;
- pattern++;
- while(match && *data && *pattern && (*pattern != '/')) {
- switch(toupper(*pattern)) {
- case 'N':
- if ((*data < '2') || (*data > '9'))
- match=0;
- break;
- case 'X':
- if ((*data < '0') || (*data > '9'))
- match = 0;
- break;
- case 'Z':
- if ((*data < '1') || (*data > '9'))
- match = 0;
- break;
- case '.':
- /* Must match */
- return 1;
- case ' ':
- case '-':
- /* Ignore these characters */
- data--;
- break;
- default:
- if (*data != *pattern)
- match =0;
- }
- data++;
- pattern++;
- }
+ EXTENSION_MATCH_CORE(data,pattern,match);
/* Must be at the end of both */
if (*data || (*pattern && (*pattern != '/')))
match = 0;
@@ -476,41 +518,7 @@ static int extension_close(char *pattern, char *data, int needmore)
(!needmore || (strlen(pattern) > strlen(data)))) {
return 1;
}
- /* All patterns begin with _ */
- if (pattern[0] != '_')
- return 0;
- /* Start optimistic */
- match=1;
- pattern++;
- while(match && *data && *pattern && (*pattern != '/')) {
- switch(toupper(*pattern)) {
- case 'N':
- if ((*data < '2') || (*data > '9'))
- match=0;
- break;
- case 'X':
- if ((*data < '0') || (*data > '9'))
- match = 0;
- break;
- case 'Z':
- if ((*data < '1') || (*data > '9'))
- match = 0;
- break;
- case '.':
- /* Must match instantly */
- return 1;
- case ' ':
- case '-':
- /* Ignore these characters */
- data--;
- break;
- default:
- if (*data != *pattern)
- match =0;
- }
- data++;
- pattern++;
- }
+ EXTENSION_MATCH_CORE(data,pattern,match);
/* If there's more or we don't care about more, return non-zero, otlherwise it's a miss */
if (!needmore || *pattern) {
return match;
@@ -665,7 +673,7 @@ static void *pbx_substitute_variables(struct ast_channel *c, struct ast_exten *e
char *cp1,*cp3,*cp4,*cp5;
void *cp2;
char c1,c2;
- int m,mve,origlen,quoted,dolsign,docopy;
+ int m,mve,origlen,quoted,dolsign,docopy,offset;
struct ast_var_t *variables;
struct varshead *headp;
char pri[80];
@@ -767,6 +775,13 @@ static void *pbx_substitute_variables(struct ast_channel *c, struct ast_exten *e
} else if (!strcmp(cp3, "EXTEN")) {
cp4 = c->exten;
break;
+ } else if (!strncmp(cp3, "EXTEN-", strlen("EXTEN-")) &&
+ (sscanf(cp3 + strlen("EXTEN-"), "%d", &offset) == 1)) {
+ if (offset < 0)
+ offset=0;
+ if (offset > strlen(c->exten))
+ offset = strlen(c->exten);
+ cp4 = c->exten + offset;
} else if (!strcmp(cp3, "RDNIS")) {
cp4 = c->rdnis;
if (!cp4)
@@ -782,12 +797,22 @@ static void *pbx_substitute_variables(struct ast_channel *c, struct ast_exten *e
} else {
AST_LIST_TRAVERSE(headp,variables,entries) {
// ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",cp3,ast_var_name(variables));
- if (strncasecmp(ast_var_name(variables),cp3,m)==0) {
- cp4=ast_var_value(variables);
- break;
+ if (strncasecmp(ast_var_name(variables),cp3,m)==0) {
+ cp4=ast_var_value(variables);
+ break;
+ }
+ }
+ if (!cp4) {
+ /* Try globals */
+ AST_LIST_TRAVERSE(&globals,variables,entries) {
+ // ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",cp3,ast_var_name(variables));
+ if (strncasecmp(ast_var_name(variables),cp3,m)==0) {
+ cp4=ast_var_value(variables);
+ break;
+ }
+ }
}
}
- }
free(cp3);
break;
default :
@@ -811,12 +836,13 @@ static void *pbx_substitute_variables(struct ast_channel *c, struct ast_exten *e
if (cp4!=NULL) {
cp2=realloc(cp2,origlen+strlen(cp4)+1);
strncat((char *)cp2,cp4,strlen(cp4));
+ origlen += strlen(cp4);
} else {
ast_log(LOG_WARNING,"mve!=0 and cp4=NULL, something gone astray\n");
}
}
}
-
+ cp4 = NULL;
} while (*cp1++!='\0');
/* Second stage, expression evaluation */
@@ -2764,6 +2790,7 @@ int ast_async_goto(struct ast_channel *chan, char *context, char *exten, int pri
struct ast_frame *f;
tmpchan = ast_channel_alloc(0);
if (tmpchan) {
+ ast_setstate(tmpchan, chan->_state);
snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name);
/* Make formats okay */
tmpchan->readformat = chan->readformat;
@@ -2826,7 +2853,8 @@ static void ext_strncpy(char *dst, char *src, int len)
while(*src && (count < len - 1)) {
switch(*src) {
case ' ':
- case '-':
+//otherwise exten => [a-b],1,... doesn't work
+// case '-':
/* Ignore */
break;
default:
@@ -3485,21 +3513,35 @@ char *pbx_builtin_getvar_helper(struct ast_channel *chan, char *name) {
struct ast_var_t *variables;
struct varshead *headp;
- headp = &chan->varshead;
+ if (chan)
+ headp=&chan->varshead;
+ else
+ headp=&globals;
- if (name)
+ if (name) {
AST_LIST_TRAVERSE(headp,variables,entries) {
if (!strcmp(name, ast_var_name(variables)))
return ast_var_value(variables);
}
+ if (headp != &globals) {
+ /* Check global variables if we haven't already */
+ headp = &globals;
+ AST_LIST_TRAVERSE(headp,variables,entries) {
+ if (!strcmp(name, ast_var_name(variables)))
+ return ast_var_value(variables);
+ }
+ }
+ }
return NULL;
}
void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value) {
struct ast_var_t *newvariable;
struct varshead *headp;
-
+ if (chan)
headp=&chan->varshead;
+ else
+ headp=&globals;
AST_LIST_TRAVERSE (headp,newvariable,entries) {
if (strncasecmp(ast_var_name(newvariable),name,strlen(name))==0) {
@@ -3510,10 +3552,12 @@ void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value
}
}
- newvariable=ast_var_assign(name,value);
- AST_LIST_INSERT_HEAD(headp,newvariable,entries);
-
- return;
+ if (value) {
+ if ((option_verbose > 1) && (headp == &globals))
+ ast_verbose(VERBOSE_PREFIX_3 "Setting global variable '%s' to '%s'\n",name, value);
+ newvariable=ast_var_assign(name,value);
+ AST_LIST_INSERT_HEAD(headp,newvariable,entries);
+ }
}
static int pbx_builtin_setvar(struct ast_channel *chan, void *data)
@@ -3536,6 +3580,22 @@ static int pbx_builtin_setvar(struct ast_channel *chan, void *data)
return(0);
}
+static int pbx_builtin_noop(struct ast_channel *chan, void *data)
+{
+ return 0;
+}
+
+
+void pbx_builtin_clear_globals(void)
+{
+ struct ast_var_t *vardata;
+ while (!AST_LIST_EMPTY(&globals)) {
+ vardata = AST_LIST_FIRST(&globals);
+ AST_LIST_REMOVE_HEAD(&globals, entries);
+ ast_var_delete(vardata);
+ }
+}
+
static int pbx_checkcondition(char *condition) {
char *s;
int ret;
@@ -3552,7 +3612,6 @@ static int pbx_checkcondition(char *condition) {
return(ret);
}
-
static int pbx_builtin_gotoif(struct ast_channel *chan, void *data)
{
char *condition,*branch1,*branch2,*branch;