diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c index d77fa4bbc..82c7afcef 100644 --- a/apps/app_chanspy.c +++ b/apps/app_chanspy.c @@ -596,12 +596,15 @@ static int common_exec(struct ast_channel *chan, const struct ast_flags *flags, if (ast_test_flag(flags, OPTION_EXIT)) { const char *c; - if ((c = pbx_builtin_getvar_helper(chan, "SPY_EXIT_CONTEXT"))) + ast_channel_lock(chan); + if ((c = pbx_builtin_getvar_helper(chan, "SPY_EXIT_CONTEXT"))) { ast_copy_string(exitcontext, c, sizeof(exitcontext)); - else if (!ast_strlen_zero(chan->macrocontext)) + } else if (!ast_strlen_zero(chan->macrocontext)) { ast_copy_string(exitcontext, chan->macrocontext, sizeof(exitcontext)); - else + } else { ast_copy_string(exitcontext, chan->context, sizeof(exitcontext)); + } + ast_channel_unlock(chan); } ast_mutex_init(&chanspy_ds.lock); diff --git a/apps/app_externalivr.c b/apps/app_externalivr.c index 3bf7dd1c7..a93abb4a8 100644 --- a/apps/app_externalivr.c +++ b/apps/app_externalivr.c @@ -251,10 +251,13 @@ static void ast_eivr_getvariable(struct ast_channel *chan, char *data, char *out break; } - value = pbx_builtin_getvar_helper(chan, variable); - if(!value) + ast_channel_lock(chan); + if (!(value = pbx_builtin_getvar_helper(chan, variable))) { value = ""; + } + ast_str_append(&newstring, 0, "%s=%s,", variable, value); + ast_channel_unlock(chan); ast_copy_string(outbuf, newstring->str, outbuflen); } }; diff --git a/apps/app_macro.c b/apps/app_macro.c index b087ad36b..a50dfb4bb 100644 --- a/apps/app_macro.c +++ b/apps/app_macro.c @@ -165,20 +165,24 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive) } /* does the user want a deeper rabbit hole? */ - s = pbx_builtin_getvar_helper(chan, "MACRO_RECURSION"); - if (s) + ast_channel_lock(chan); + if ((s = pbx_builtin_getvar_helper(chan, "MACRO_RECURSION"))) { sscanf(s, "%d", &maxdepth); - + } + /* Count how many levels deep the rabbit hole goes */ - s = pbx_builtin_getvar_helper(chan, "MACRO_DEPTH"); - if (s) + if ((s = pbx_builtin_getvar_helper(chan, "MACRO_DEPTH"))) { sscanf(s, "%d", &depth); + } + /* Used for detecting whether to return when a Macro is called from another Macro after hangup */ if (strcmp(chan->exten, "h") == 0) pbx_builtin_setvar_helper(chan, "MACRO_IN_HANGUP", "1"); - inhangupc = pbx_builtin_getvar_helper(chan, "MACRO_IN_HANGUP"); - if (!ast_strlen_zero(inhangupc)) + + if ((inhangupc = pbx_builtin_getvar_helper(chan, "MACRO_IN_HANGUP"))) { sscanf(inhangupc, "%d", &inhangup); + } + ast_channel_unlock(chan); if (depth >= maxdepth) { ast_log(LOG_ERROR, "Macro(): possible infinite loop detected. Returning early.\n"); @@ -247,17 +251,19 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive) ast_copy_string(chan->context, fullmacro, sizeof(chan->context)); chan->priority = 1; + ast_channel_lock(chan); while((cur = strsep(&rest, ",")) && (argc < MAX_ARGS)) { const char *s; /* Save copy of old arguments if we're overwriting some, otherwise let them pass through to the other macro */ snprintf(varname, sizeof(varname), "ARG%d", argc); - s = pbx_builtin_getvar_helper(chan, varname); - if (s) + if ((s = pbx_builtin_getvar_helper(chan, varname))) { oldargs[argc] = ast_strdup(s); + } pbx_builtin_setvar_helper(chan, varname, cur); argc++; } + ast_channel_unlock(chan); autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP); ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP); while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) { @@ -431,6 +437,7 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive) /* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */ const char *offsets; ast_copy_string(chan->exten, oldexten, sizeof(chan->exten)); + ast_channel_lock(chan); if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) { /* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue normally if there is any problem */ @@ -440,6 +447,7 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive) } } } + ast_channel_unlock(chan); } } diff --git a/apps/app_meetme.c b/apps/app_meetme.c index 5e347280a..ff52323aa 100644 --- a/apps/app_meetme.c +++ b/apps/app_meetme.c @@ -374,8 +374,8 @@ struct ast_conference { pthread_t recordthread; /*!< thread for recording */ ast_mutex_t recordthreadlock; /*!< control threads trying to start recordthread */ pthread_attr_t attr; /*!< thread attribute */ - const char *recordingfilename; /*!< Filename to record the Conference into */ - const char *recordingformat; /*!< Format to record the Conference in */ + char *recordingfilename; /*!< Filename to record the Conference into */ + char *recordingformat; /*!< Format to record the Conference in */ char pin[MAX_PIN]; /*!< If protected by a PIN */ char pinadmin[MAX_PIN]; /*!< If protected by a admin PIN */ char uniqueid[32]; @@ -1350,7 +1350,12 @@ static int conf_free(struct ast_conference *conf) ast_hangup(conf->chan); if (conf->fd >= 0) close(conf->fd); - + if (conf->recordingfilename) { + ast_free(conf->recordingfilename); + } + if (conf->recordingformat) { + ast_free(conf->recordingformat); + } ast_mutex_destroy(&conf->playlock); ast_mutex_destroy(&conf->listenlock); ast_mutex_destroy(&conf->recordthreadlock); @@ -1507,8 +1512,8 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c struct timeval now; struct ast_dsp *dsp = NULL; struct ast_app *app; - const char *agifile; - const char *agifiledefault = "conf-background.agi"; + char *agifile; + const char *agifiledefault = "conf-background.agi", *tmp; char meetmesecs[30] = ""; char exitcontext[AST_MAX_CONTEXT] = ""; char recordingtmp[AST_MAX_EXTENSION] = ""; @@ -1575,12 +1580,22 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c play_warning = warning_freq = 0; } } - - var = pbx_builtin_getvar_helper(chan, "CONF_LIMIT_WARNING_FILE"); + + ast_channel_lock(chan); + if ((var = pbx_builtin_getvar_helper(chan, "CONF_LIMIT_WARNING_FILE"))) { + var = ast_strdupa(var); + } + ast_channel_unlock(chan); + warning_sound = var ? var : "timeleft"; - var = pbx_builtin_getvar_helper(chan, "CONF_LIMIT_TIMEOUT_FILE"); - end_sound = var ? var : NULL; + ast_channel_lock(chan); + if ((var = pbx_builtin_getvar_helper(chan, "CONF_LIMIT_TIMEOUT_FILE"))) { + var = ast_strdupa(var); + } + ast_channel_unlock(chan); + + end_sound = var ? var : NULL; /* undo effect of S(x) in case they are both used */ calldurationlimit = 0; @@ -1608,15 +1623,21 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c if (confflags & CONFFLAG_RECORDCONF) { if (!conf->recordingfilename) { - conf->recordingfilename = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE"); + const char *var; + ast_channel_lock(chan); + if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE"))) { + conf->recordingfilename = ast_strdup(var); + } + if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT"))) { + conf->recordingformat = ast_strdup(var); + } + ast_channel_unlock(chan); if (!conf->recordingfilename) { snprintf(recordingtmp, sizeof(recordingtmp), "meetme-conf-rec-%s-%s", conf->confno, chan->uniqueid); - conf->recordingfilename = ast_strdupa(recordingtmp); + conf->recordingfilename = ast_strdup(recordingtmp); } - conf->recordingformat = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT"); if (!conf->recordingformat) { - ast_copy_string(recordingtmp, "wav", sizeof(recordingtmp)); - conf->recordingformat = ast_strdupa(recordingtmp); + conf->recordingformat = ast_strdup("wav"); } ast_verb(4, "Starting recording of MeetMe Conference %s into file %s.%s.\n", conf->confno, conf->recordingfilename, conf->recordingformat); @@ -1736,12 +1757,15 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c pbx_builtin_setvar_helper(chan, "MEETMEUNIQUEID", conf->uniqueid); if (confflags & CONFFLAG_EXIT_CONTEXT) { - if ((agifile = pbx_builtin_getvar_helper(chan, "MEETME_EXIT_CONTEXT"))) - ast_copy_string(exitcontext, agifile, sizeof(exitcontext)); - else if (!ast_strlen_zero(chan->macrocontext)) + ast_channel_lock(chan); + if ((tmp = pbx_builtin_getvar_helper(chan, "MEETME_EXIT_CONTEXT"))) { + ast_copy_string(exitcontext, tmp, sizeof(exitcontext)); + } else if (!ast_strlen_zero(chan->macrocontext)) { ast_copy_string(exitcontext, chan->macrocontext, sizeof(exitcontext)); - else + } else { ast_copy_string(exitcontext, chan->context, sizeof(exitcontext)); + } + ast_channel_unlock(chan); } if (!(confflags & (CONFFLAG_QUIET | CONFFLAG_NOONLYPERSON))) { @@ -1932,10 +1956,14 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c /* Get name of AGI file to run from $(MEETME_AGI_BACKGROUND) or use default filename of conf-background.agi */ - agifile = pbx_builtin_getvar_helper(chan, "MEETME_AGI_BACKGROUND"); - if (!agifile) - agifile = agifiledefault; - + ast_channel_lock(chan); + if ((tmp = pbx_builtin_getvar_helper(chan, "MEETME_AGI_BACKGROUND"))) { + agifile = ast_strdupa(tmp); + } else { + agifile = ast_strdupa(agifiledefault); + } + ast_channel_unlock(chan); + if (user->zapchannel) { /* Set CONFMUTE mode on Zap channel to mute DTMF tones */ x = 1; @@ -1944,8 +1972,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c /* Find a pointer to the agi app and execute the script */ app = pbx_findapp("agi"); if (app) { - char *s = ast_strdupa(agifile); - ret = pbx_exec(chan, app, s); + ret = pbx_exec(chan, app, agifile); } else { ast_log(LOG_WARNING, "Could not find application (agi)\n"); ret = -2; diff --git a/apps/app_minivm.c b/apps/app_minivm.c index 8a66a9579..8746aca5b 100644 --- a/apps/app_minivm.c +++ b/apps/app_minivm.c @@ -1412,7 +1412,12 @@ static int notify_new_message(struct ast_channel *chan, const char *templatename /* Read counter if available */ - counter = pbx_builtin_getvar_helper(chan, "MVM_COUNTER"); + ast_channel_lock(chan); + if ((counter = pbx_builtin_getvar_helper(chan, "MVM_COUNTER"))) { + counter = ast_strdupa(counter); + } + ast_channel_unlock(chan); + if (ast_strlen_zero(counter)) { ast_debug(2, "-_-_- MVM_COUNTER not found\n"); } else { @@ -1659,14 +1664,24 @@ static int minivm_notify_exec(struct ast_channel *chan, void *data) pbx_builtin_setvar_helper(chan, "MINIVM_NOTIFY_STATUS", "FAILED"); return -1; } - - filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME"); - format = pbx_builtin_getvar_helper(chan, "MVM_FORMAT"); - duration_string = pbx_builtin_getvar_helper(chan, "MVM_DURATION"); + + ast_channel_lock(chan); + if ((filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME"))) { + filename = ast_strdupa(filename); + } + ast_channel_unlock(chan); /* Notify of new message to e-mail and pager */ if (!ast_strlen_zero(filename)) { + ast_channel_lock(chan); + if ((format = pbx_builtin_getvar_helper(chan, "MVM_FORMAT"))) { + format = ast_strdupa(format); + } + if ((duration_string = pbx_builtin_getvar_helper(chan, "MVM_DURATION"))) { + duration_string = ast_strdupa(duration_string); + } + ast_channel_unlock(chan); res = notify_new_message(chan, template, vmu, filename, atoi(duration_string), format, chan->cid.cid_num, chan->cid.cid_name); - }; + } pbx_builtin_setvar_helper(chan, "MINIVM_NOTIFY_STATUS", res == 0 ? "SUCCESS" : "FAILED"); @@ -1928,10 +1943,13 @@ static int minivm_delete_exec(struct ast_channel *chan, void *data) int res = 0; char filename[BUFSIZ]; - if (!ast_strlen_zero(data)) + if (!ast_strlen_zero(data)) { ast_copy_string(filename, (char *) data, sizeof(filename)); - else + } else { + ast_channel_lock(chan); ast_copy_string(filename, pbx_builtin_getvar_helper(chan, "MVM_FILENAME"), sizeof(filename)); + ast_channel_unlock(chan); + } if (ast_strlen_zero(filename)) { ast_log(LOG_ERROR, "No filename given in application arguments or channel variable MVM_FILENAME\n"); diff --git a/apps/app_morsecode.c b/apps/app_morsecode.c index 6c88ed32c..455ee04c1 100644 --- a/apps/app_morsecode.c +++ b/apps/app_morsecode.c @@ -111,16 +111,20 @@ static int morsecode_exec(struct ast_channel *chan, void *data) } /* Use variable MORESEDITLEN, if set (else 80) */ + ast_channel_lock(chan); ditlenc = pbx_builtin_getvar_helper(chan, "MORSEDITLEN"); if (ast_strlen_zero(ditlenc) || (sscanf(ditlenc, "%d", &ditlen) != 1)) { ditlen = 80; } + ast_channel_unlock(chan); /* Use variable MORSETONE, if set (else 800) */ + ast_channel_lock(chan); tonec = pbx_builtin_getvar_helper(chan, "MORSETONE"); if (ast_strlen_zero(tonec) || (sscanf(tonec, "%d", &tone) != 1)) { tone = 800; } + ast_channel_unlock(chan); for (digit = data; *digit; digit++) { int digit2 = *digit; diff --git a/apps/app_speech_utils.c b/apps/app_speech_utils.c index 6033923ee..4677c33b6 100644 --- a/apps/app_speech_utils.c +++ b/apps/app_speech_utils.c @@ -559,9 +559,11 @@ static int speech_background(struct ast_channel *chan, void *data) } /* See if the maximum DTMF length variable is set... we use a variable in case they want to carry it through their entire dialplan */ - if ((tmp2 = pbx_builtin_getvar_helper(chan, "SPEECH_DTMF_MAXLEN")) && !ast_strlen_zero(tmp2)) + ast_channel_lock(chan); + if ((tmp2 = pbx_builtin_getvar_helper(chan, "SPEECH_DTMF_MAXLEN")) && !ast_strlen_zero(tmp2)) { max_dtmf_len = atoi(tmp2); - + } + /* See if a terminator is specified */ if ((tmp2 = pbx_builtin_getvar_helper(chan, "SPEECH_DTMF_TERMINATOR"))) { if (ast_strlen_zero(tmp2)) @@ -569,6 +571,7 @@ static int speech_background(struct ast_channel *chan, void *data) else dtmf_terminator = tmp2[0]; } + ast_channel_unlock(chan); /* Before we go into waiting for stuff... make sure the structure is ready, if not - start it again */ if (speech->state == AST_SPEECH_STATE_NOT_READY || speech->state == AST_SPEECH_STATE_DONE) { diff --git a/apps/app_stack.c b/apps/app_stack.c index 7f53aff15..56f946529 100644 --- a/apps/app_stack.c +++ b/apps/app_stack.c @@ -351,8 +351,11 @@ static int local_read(struct ast_channel *chan, const char *cmd, char *data, cha frame = AST_LIST_FIRST(oldlist); AST_LIST_TRAVERSE(&frame->varshead, variables, entries) { if (!strcmp(data, ast_var_name(variables))) { - const char *tmp = pbx_builtin_getvar_helper(chan, data); + const char *tmp; + ast_channel_lock(chan); + tmp = pbx_builtin_getvar_helper(chan, data); ast_copy_string(buf, S_OR(tmp, ""), len); + ast_channel_unlock(chan); break; } } diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index a7ec3711d..f588c02dd 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -3522,7 +3522,11 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_ if (tmpptr) *tmpptr++ = '\0'; - category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"); + ast_channel_lock(chan); + if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { + category = ast_strdupa(category); + } + ast_channel_unlock(chan); ast_debug(3, "Before find_user\n"); if (!(vmu = find_user(&svm, context, ext))) { @@ -4741,9 +4745,15 @@ static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, { char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; int newmsgs = 0, oldmsgs = 0; - const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"); + const char *category; char *myserveremail = serveremail; + ast_channel_lock(chan); + if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { + category = ast_strdupa(category); + } + ast_channel_unlock(chan); + make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX"); make_file(fn, sizeof(fn), todir, msgnum); snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); diff --git a/apps/app_while.c b/apps/app_while.c index 1c61d966e..36dd17c5f 100644 --- a/apps/app_while.c +++ b/apps/app_while.c @@ -184,22 +184,19 @@ static int _while_exec(struct ast_channel *chan, void *data, int end) memset(my_name, 0, size); snprintf(my_name, size, "%s_%s_%d", chan->context, chan->exten, chan->priority); - if (ast_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); - } - + 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); - while_pri = pbx_builtin_getvar_helper(chan, varname); - 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)) { @@ -208,7 +205,8 @@ static int _while_exec(struct ast_channel *chan, void *data, int end) 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))) { + 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 { @@ -220,6 +218,7 @@ static int _while_exec(struct ast_channel *chan, void *data, int end) 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; } @@ -230,7 +229,7 @@ static int _while_exec(struct ast_channel *chan, void *data, int end) 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 */