diff --git a/pbx.c b/pbx.c index dff44915ba..df1ca7227f 100755 --- a/pbx.c +++ b/pbx.c @@ -859,7 +859,7 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp int length; char workspace[256]; char ltmp[256], var[256]; - char *nextpos; + char *nextvar, *nextexp; char *vars, *vare; int pos, brackets, needsub, len; @@ -872,11 +872,22 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp pos = strlen(whereweare); /* Look for a variable */ - nextpos = strstr(whereweare, "${"); + nextvar = strstr(whereweare, "${"); + + nextexp = strstr(whereweare, "$["); + + if (nextvar && nextexp) { + if (nextvar < nextexp) + nextexp = NULL; + else + nextvar = NULL; + } /* If there is one, we only go that far */ - if (nextpos) - pos = nextpos - whereweare; + if (nextvar) + pos = nextvar - whereweare; + else if (nextexp) + pos = nextexp - whereweare; /* Can't copy more than 'count' bytes */ if (pos > count) @@ -889,11 +900,11 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp cp2 += pos; whereweare += pos; - if (nextpos) { + if (nextvar) { /* We have a variable. Find the start and end, and determine if we are going to have to recursively call ourselves on the contents */ - vars = vare = nextpos + 2; + vars = vare = nextvar + 2; brackets = 1; needsub = 0; @@ -904,7 +915,7 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp brackets++; } else if (vare[0] == '}') { brackets--; - } else if (vare[0] == '[') + } else if ((vare[0] == '$') && (vare[1] == '[')) needsub++; vare++; } @@ -940,18 +951,70 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp cp2 += length; } + } else if (nextexp) { + /* We have an expression. Find the start and end, and determine + if we are going to have to recursively call ourselves on the + contents */ + vars = vare = nextexp + 2; + brackets = 1; + needsub = 0; + + /* Find the end of it */ + while(brackets && *vare) { + if ((vare[0] == '$') && (vare[1] == '[')) { + needsub++; + brackets++; + } else if (vare[0] == ']') { + brackets--; + } else if ((vare[0] == '$') && (vare[1] == '{')) + needsub++; + vare++; + } + if (brackets) + ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n"); + len = vare - vars - 1; + + /* Skip totally over variable name */ + whereweare += ( len + 3); + + /* Store variable name (and truncate) */ + memset(var, 0, sizeof(var)); + strncpy(var, vars, sizeof(var) - 1); + var[len] = '\0'; + + /* Substitute if necessary */ + if (needsub) { + memset(ltmp, 0, sizeof(ltmp)); + pbx_substitute_variables_helper(c, var, ltmp, sizeof(ltmp) - 1); + vars = ltmp; + } else { + vars = var; + } + + /* Evaluate expression */ + cp4 = ast_expr(vars); + + printf("Expression is '%s'\n", cp4); + + if (cp4) { + length = strlen(cp4); + if (length > count) + length = count; + memcpy(cp2, cp4, length); + count -= length; + cp2 += length; + free(cp4); + } + } else break; } } static void pbx_substitute_variables(char *passdata, int datalen, struct ast_channel *c, struct ast_exten *e) { - char *cp1,*cp3,*cp4; - char cp2[256] = ""; - char c1,c2; - int m,mve,origlen,quoted,dolsign,docopy; - char cp5[256]=""; + memset(passdata, 0, datalen); + /* No variables or expressions in e->data, so why scan it? */ if (!strstr(e->data,"${") && !strstr(e->data,"$[")) { strncpy(passdata, e->data, datalen - 1); @@ -959,177 +1022,8 @@ static void pbx_substitute_variables(char *passdata, int datalen, struct ast_cha return; } - pbx_substitute_variables_helper(c,e->data,cp2, sizeof(cp2) - 1); - - /* Second stage, expression evaluation */ - if ((strstr(cp2,"$[")==NULL)) { - strncpy(passdata, cp2, datalen - 1); - passdata[datalen-1] = '\0'; - return; - } - /* else, do expression evaluation */ - - dolsign=0; - docopy=1; - origlen=strlen(cp2)+1; - - cp4=NULL; - cp1=cp2; - quoted=0; - - do { - c1=*cp1; - mve=0; - switch (c1) { - case '$' : - dolsign=1; - docopy=0; - break; - case '[' : - if (dolsign==0) { - docopy=1; - dolsign=0; - break; - } - dolsign=0; - docopy=0; - m=0; - mve=1; - cp1++; - - while (((c2=*(cp1+m))!=']') && (c2!='\0')) { - m++; - } - cp3=malloc(m+2); - strncpy(cp3,cp1,m); - cp3[m]='\0'; - cp1+=m; - /* Now we have the expression to evaluate on cp3 */ - cp4=ast_expr(cp3); - free(cp3); - break; - default : - if (dolsign==1) { - strncat((char *)cp5,"$",1); - } - dolsign=0; - docopy=1; - mve=0; - break; - } - if (cp1!='\0') { - if (mve==0) { - if (docopy==1) { - strncat((char *)cp5,&c1,1); - } - } else { - if (cp4!=NULL) { - strncat((char *)cp5,cp4,strlen(cp4)); - } else { - ast_log(LOG_WARNING,"mve!=0 and cp4=NULL, something gone astray\n"); - } - } - } - - } while (*cp1++!='\0'); - strncpy(passdata, cp5, datalen - 1); -} -#if 0 -static void *pbx_substitute_variables(struct ast_channel *c, struct ast_exten *e) { - char *cp1,*cp3,*cp4,*cp5; - char *cp2; - char c1,c2; - int m,mve,origlen,quoted,dolsign,docopy; - - /* No variables or expressions in e->data, so why scan it? */ - if (!strstr(e->data,"${") && !strstr(e->data,"$[")) { - return strndup(e->data,strlen(e->data)+1); - } - - cp1=e->data; - cp2=malloc(sizeof(char)*256); - pbx_substitute_variables_helper(c,cp1,(char **)&cp2,0); - - /* Second stage, expression evaluation */ - if ((strstr(cp2,"$[")==NULL)) { - /* No expressions in cp2, return it */ - return(cp2); - } - /* else, do expression evaluation */ - - dolsign=0; - docopy=1; - origlen=strlen(cp2)+1; - - cp5=malloc(origlen); - memset(cp5,0,origlen); - cp4=NULL; - cp1=cp2; - quoted=0; - - do { - c1=*cp1; - mve=0; - switch (c1) { - case '$' : - dolsign=1; - docopy=0; - break; - case '[' : - if (dolsign==0) { - docopy=1; - dolsign=0; - break; - } - dolsign=0; - docopy=0; - m=0; - mve=1; - cp1++; - - while (((c2=*(cp1+m))!=']') && (c2!='\0')) { - m++; - } - cp3=malloc(m+2); - strncpy(cp3,cp1,m); - cp3[m]='\0'; - cp1+=m; - /* Now we have the expression to evaluate on cp3 */ - cp4=ast_expr(cp3); - free(cp3); - break; - default : - if (dolsign==1) { - strncat((char *)cp5,"$",1); - } - dolsign=0; - docopy=1; - mve=0; - break; - } - if (cp1!='\0') { - if (mve==0) { - if (docopy==1) { - strncat((char *)cp5,&c1,1); - } - } else { - if (cp4!=NULL) { - cp5=realloc(cp5,origlen+strlen(cp4)+1); - strncat((char *)cp5,cp4,strlen(cp4)); - free(cp4); - } else { - ast_log(LOG_WARNING,"mve!=0 and cp4=NULL, something gone astray\n"); - } - } - } - - } while (*cp1++!='\0'); - free(cp2); - return(cp5); -} -#endif - - + pbx_substitute_variables_helper(c,e->data,passdata, datalen - 1); +} static int pbx_extension_helper(struct ast_channel *c, char *context, char *exten, int priority, char *callerid, int action) {