static int _while_exec(struct cw_channel *chan, int argc, char **argv, int end) { int res=0; struct localuser *u; char *while_pri = NULL; char *goto_str = NULL, *my_name = NULL; char *label = NULL; char varname[VAR_SIZE], end_varname[VAR_SIZE]; const char *prefix = "WHILE"; size_t size=0; int used_index_i = -1, x=0; char used_index[VAR_SIZE] = "0", new_index[VAR_SIZE] = "0"; if (!end && argc != 1) { cw_log(LOG_ERROR, "Syntax: %s\n", while_syntax); return -1; } if (!chan) { /* huh ? */ return -1; } LOCAL_USER_ADD(u); /* dont want run away loops if the chan isn't even up this is up for debate since it slows things down a tad ...... */ if (cw_waitfordigit(chan,1) < 0) ALL_DONE(u,-1); for (x=0;;x++) { if (get_index(chan, prefix, x)) { used_index_i = x; } else break; } snprintf(used_index, VAR_SIZE, "%d", used_index_i); snprintf(new_index, VAR_SIZE, "%d", used_index_i + 1); size = strlen(chan->context) + strlen(chan->exten) + 32; my_name = alloca(size); snprintf(my_name, size, "%s_%s_%d", chan->context, chan->exten, chan->priority); if (cw_strlen_zero(label)) { if (end) label = used_index; else if (!(label = pbx_builtin_getvar_helper(chan, my_name))) { label = new_index; pbx_builtin_setvar_helper(chan, my_name, label); } } snprintf(varname, VAR_SIZE, "%s_%s", prefix, label); while_pri = pbx_builtin_getvar_helper(chan, varname); if ((while_pri = pbx_builtin_getvar_helper(chan, varname)) && !end) { snprintf(end_varname, VAR_SIZE, "END_%s", varname); } if (!end && !cw_true(argv[0])) { /* Condition Met (clean up helper vars) */ pbx_builtin_setvar_helper(chan, varname, NULL); pbx_builtin_setvar_helper(chan, my_name, NULL); snprintf(end_varname, VAR_SIZE, "END_%s", varname); if ((goto_str=pbx_builtin_getvar_helper(chan, end_varname))) { pbx_builtin_setvar_helper(chan, end_varname, NULL); cw_parseable_goto(chan, goto_str); } else { int pri = find_matching_endwhile(chan); if (pri > 0) { if (option_verbose > 2) cw_verbose(VERBOSE_PREFIX_3 "Jumping to priority %d\n", pri); chan->priority = pri; } else { cw_log(LOG_WARNING, "Couldn't find matching EndWhile? (While at %s@%s priority %d)\n", chan->context, chan->exten, chan->priority); } } ALL_DONE(u,res); } if (!end && !while_pri) { size = strlen(chan->context) + strlen(chan->exten) + 32; goto_str = alloca(size); snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority); pbx_builtin_setvar_helper(chan, varname, goto_str); } else if (end && while_pri) { /* END of loop */ snprintf(end_varname, VAR_SIZE, "END_%s", varname); if (! pbx_builtin_getvar_helper(chan, end_varname)) { size = strlen(chan->context) + strlen(chan->exten) + 32; goto_str = alloca(size); snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority+1); pbx_builtin_setvar_helper(chan, end_varname, goto_str); } cw_parseable_goto(chan, while_pri); } ALL_DONE(u, res); }
static int _while_exec(struct ast_channel *chan, void *data, int end) { int res=0; const char *while_pri = NULL; char *my_name = NULL; const char *condition = NULL, *label = NULL; char varname[VAR_SIZE], end_varname[VAR_SIZE]; const char *prefix = "WHILE"; size_t size=0; int used_index_i = -1, x=0; char used_index[VAR_SIZE] = "0", new_index[VAR_SIZE] = "0"; if (!chan) { /* huh ? */ return -1; } #if 0 /* dont want run away loops if the chan isn't even up this is up for debate since it slows things down a tad ...... Debate is over... this prevents While/EndWhile from working within the "h" extension. Not good. */ if (ast_waitfordigit(chan,1) < 0) return -1; #endif for (x=0;;x++) { if (get_index(chan, prefix, x)) { used_index_i = x; } else break; } snprintf(used_index, VAR_SIZE, "%d", used_index_i); snprintf(new_index, VAR_SIZE, "%d", used_index_i + 1); if (!end) condition = ast_strdupa(data); size = strlen(chan->context) + strlen(chan->exten) + 32; my_name = alloca(size); memset(my_name, 0, size); snprintf(my_name, size, "%s_%s_%d", chan->context, chan->exten, chan->priority); ast_channel_lock(chan); if (end) { label = used_index; } else if (!(label = pbx_builtin_getvar_helper(chan, my_name))) { label = new_index; pbx_builtin_setvar_helper(chan, my_name, label); } snprintf(varname, VAR_SIZE, "%s_%s", prefix, label); if ((while_pri = pbx_builtin_getvar_helper(chan, varname)) && !end) { while_pri = ast_strdupa(while_pri); snprintf(end_varname,VAR_SIZE,"END_%s",varname); } ast_channel_unlock(chan); if ((!end && !pbx_checkcondition(condition)) || (end == 2)) { /* Condition Met (clean up helper vars) */ const char *goto_str; pbx_builtin_setvar_helper(chan, varname, NULL); pbx_builtin_setvar_helper(chan, my_name, NULL); snprintf(end_varname,VAR_SIZE,"END_%s",varname); ast_channel_lock(chan); if ((goto_str = pbx_builtin_getvar_helper(chan, end_varname))) { ast_parseable_goto(chan, goto_str); pbx_builtin_setvar_helper(chan, end_varname, NULL); } else { int pri = find_matching_endwhile(chan); if (pri > 0) { ast_verb(3, "Jumping to priority %d\n", pri); chan->priority = pri; } else { ast_log(LOG_WARNING, "Couldn't find matching EndWhile? (While at %s@%s priority %d)\n", chan->context, chan->exten, chan->priority); } } ast_channel_unlock(chan); return res; } if (!end && !while_pri) { char *goto_str; size = strlen(chan->context) + strlen(chan->exten) + 32; goto_str = alloca(size); memset(goto_str, 0, size); snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority); pbx_builtin_setvar_helper(chan, varname, goto_str); } else if (end && while_pri) { /* END of loop */ snprintf(end_varname, VAR_SIZE, "END_%s", varname); if (! pbx_builtin_getvar_helper(chan, end_varname)) { char *goto_str; size = strlen(chan->context) + strlen(chan->exten) + 32; goto_str = alloca(size); memset(goto_str, 0, size); snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority+1); pbx_builtin_setvar_helper(chan, end_varname, goto_str); } ast_parseable_goto(chan, while_pri); } return res; }