aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--UPGRADE.txt10
-rw-r--r--apps/app_channelredirect.c41
-rw-r--r--apps/app_chanspy.c60
-rw-r--r--apps/app_controlplayback.c63
-rw-r--r--apps/app_dial.c68
-rw-r--r--apps/app_exec.c63
-rw-r--r--apps/app_externalivr.c12
-rw-r--r--apps/app_macro.c4
-rw-r--r--apps/app_page.c6
-rw-r--r--apps/app_parkandannounce.c133
-rw-r--r--apps/app_queue.c6
-rw-r--r--apps/app_readfile.c2
-rw-r--r--apps/app_record.c161
-rw-r--r--apps/app_skel.c2
-rw-r--r--apps/app_softhangup.c61
-rw-r--r--apps/app_talkdetect.c205
-rw-r--r--apps/app_url.c33
-rw-r--r--apps/app_verbose.c73
-rw-r--r--apps/app_voicemail.c6
-rw-r--r--apps/app_zapras.c6
-rw-r--r--channels/chan_local.c4
-rw-r--r--funcs/func_callerid.c4
-rw-r--r--funcs/func_cut.c4
-rw-r--r--funcs/func_env.c2
-rw-r--r--funcs/func_logic.c37
-rw-r--r--funcs/func_odbc.c3
-rw-r--r--funcs/func_rand.c4
-rw-r--r--funcs/func_realtime.c12
-rw-r--r--funcs/func_strings.c36
-rw-r--r--funcs/func_vmcount.c2
-rw-r--r--include/asterisk/app.h2
-rw-r--r--main/pbx.c107
-rw-r--r--pbx/pbx_config.c24
33 files changed, 612 insertions, 644 deletions
diff --git a/UPGRADE.txt b/UPGRADE.txt
index f98654452..1e76c4130 100644
--- a/UPGRADE.txt
+++ b/UPGRADE.txt
@@ -35,6 +35,16 @@ Core:
like sin, cos, tan, log, pow, etc. The ability to call external functions
like CDR(), etc. was also added, without having to use the ${...} notation.
+* The delimiter passed to applications has been changed to the comma (','), as
+ that is what people are used to using within extensions.conf. If you are
+ using realtime extensions, you will need to translate your existing dialplan
+ to use this separator. To use a literal comma, you need merely to escape it
+ with a backslash ('\'). Another possible side effect is that you may need to
+ remove the obscene level of backslashing that was necessary for the dialplan
+ to work correctly in 1.4 and previous versions. This should make writing
+ dialplans less painful in the future, albeit with the pain of a one-time
+ conversion.
+
Voicemail:
* The voicemail configuration values 'maxmessage' and 'minmessage' have
diff --git a/apps/app_channelredirect.c b/apps/app_channelredirect.c
index 2164521a4..0f654251f 100644
--- a/apps/app_channelredirect.c
+++ b/apps/app_channelredirect.c
@@ -45,15 +45,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
static char *app = "ChannelRedirect";
static char *synopsis = "Redirects given channel to a dialplan target.";
static char *descrip =
-"ChannelRedirect(channel|[[context|]extension|]priority):\n"
+"ChannelRedirect(channel,[[context,]extension,]priority)\n"
" Sends the specified channel to the specified extension priority\n";
static int asyncgoto_exec(struct ast_channel *chan, void *data)
{
int res = -1;
- char *info, *context, *exten, *priority;
- int prio = 1;
+ char *info;
struct ast_channel *chan2 = NULL;
AST_DECLARE_APP_ARGS(args,
@@ -62,7 +61,7 @@ static int asyncgoto_exec(struct ast_channel *chan, void *data)
);
if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "%s requires an argument (channel|[[context|]exten|]priority)\n", app);
+ ast_log(LOG_WARNING, "%s requires an argument (channel,[[context,]exten,]priority)\n", app);
return -1;
}
@@ -70,7 +69,7 @@ static int asyncgoto_exec(struct ast_channel *chan, void *data)
AST_STANDARD_APP_ARGS(args, info);
if (ast_strlen_zero(args.channel) || ast_strlen_zero(args.label)) {
- ast_log(LOG_WARNING, "%s requires an argument (channel|[[context|]exten|]priority)\n", app);
+ ast_log(LOG_WARNING, "%s requires an argument (channel,[[context,]exten,]priority)\n", app);
goto quit;
}
@@ -80,38 +79,10 @@ static int asyncgoto_exec(struct ast_channel *chan, void *data)
goto quit;
}
- /* Parsed right to left, so standard parsing won't work */
- context = strsep(&args.label, "|");
- exten = strsep(&args.label, "|");
- if (exten) {
- priority = strsep(&args.label, "|");
- if (!priority) {
- priority = exten;
- exten = context;
- context = NULL;
- }
- } else {
- priority = context;
- context = NULL;
- }
-
- /* ast_findlabel_extension does not convert numeric priorities; it only does a lookup */
- if (!(prio = atoi(priority)) && !(prio = ast_findlabel_extension(chan2, S_OR(context, chan2->context),
- S_OR(exten, chan2->exten), priority, chan2->cid.cid_num))) {
- ast_log(LOG_WARNING, "'%s' is not a known priority or label\n", priority);
- goto chanquit;
- }
-
- ast_debug(2, "Attempting async goto (%s) to %s|%s|%d\n", args.channel, S_OR(context, chan2->context), S_OR(exten, chan2->exten), prio);
-
- if (ast_async_goto_if_exists(chan2, S_OR(context, chan2->context), S_OR(exten, chan2->exten), prio))
- ast_log(LOG_WARNING, "%s failed for %s\n", app, args.channel);
- else
- res = 0;
+ res = ast_parseable_goto(chan2, args.label);
- chanquit:
ast_mutex_unlock(&chan2->lock);
- quit:
+quit:
return res;
}
diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c
index 80f3c530c..788174515 100644
--- a/apps/app_chanspy.c
+++ b/apps/app_chanspy.c
@@ -626,33 +626,27 @@ exit:
static int chanspy_exec(struct ast_channel *chan, void *data)
{
- char *options = NULL;
- char *spec = NULL;
- char *argv[2];
char *mygroup = NULL;
char *recbase = NULL;
int fd = 0;
struct ast_flags flags;
int oldwf = 0;
- int argc = 0;
int volfactor = 0;
int res;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(spec);
+ AST_APP_ARG(options);
+ );
+ char *opts[OPT_ARG_ARRAY_SIZE];
data = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, data);
- if ((argc = ast_app_separate_args(data, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
- spec = argv[0];
- if (argc > 1)
- options = argv[1];
+ if (args.spec && !strcmp(args.spec, "all"))
+ args.spec = NULL;
- if (ast_strlen_zero(spec) || !strcmp(spec, "all"))
- spec = NULL;
- }
-
- if (options) {
- char *opts[OPT_ARG_ARRAY_SIZE];
-
- ast_app_parse_options(spy_opts, &flags, opts, options);
+ if (args.options) {
+ ast_app_parse_options(spy_opts, &flags, opts, args.options);
if (ast_test_flag(&flags, OPTION_GROUP))
mygroup = opts[OPT_ARG_GROUP];
@@ -690,7 +684,7 @@ static int chanspy_exec(struct ast_channel *chan, void *data)
}
}
- res = common_exec(chan, &flags, volfactor, fd, mygroup, spec, NULL, NULL);
+ res = common_exec(chan, &flags, volfactor, fd, mygroup, args.spec, NULL, NULL);
if (fd)
close(fd);
@@ -703,35 +697,35 @@ static int chanspy_exec(struct ast_channel *chan, void *data)
static int extenspy_exec(struct ast_channel *chan, void *data)
{
- char *options = NULL;
- char *exten = NULL;
- char *context = NULL;
- char *argv[2];
+ char *ptr, *exten = NULL;
char *mygroup = NULL;
char *recbase = NULL;
int fd = 0;
struct ast_flags flags;
int oldwf = 0;
- int argc = 0;
int volfactor = 0;
int res;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(context);
+ AST_APP_ARG(options);
+ );
data = ast_strdupa(data);
- if ((argc = ast_app_separate_args(data, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
- context = argv[0];
- if (!ast_strlen_zero(argv[0]))
- exten = strsep(&context, "@");
- if (ast_strlen_zero(context))
- context = ast_strdupa(chan->context);
- if (argc > 1)
- options = argv[1];
+ AST_STANDARD_APP_ARGS(args, data);
+ if (!ast_strlen_zero(args.context) && (ptr = strchr(args.context, '@'))) {
+ exten = args.context;
+ *ptr++ = '\0';
+ args.context = ptr;
}
- if (options) {
+ if (ast_strlen_zero(args.context))
+ args.context = ast_strdupa(chan->context);
+
+ if (args.options) {
char *opts[OPT_ARG_ARRAY_SIZE];
- ast_app_parse_options(spy_opts, &flags, opts, options);
+ ast_app_parse_options(spy_opts, &flags, opts, args.options);
if (ast_test_flag(&flags, OPTION_GROUP))
mygroup = opts[OPT_ARG_GROUP];
@@ -769,7 +763,7 @@ static int extenspy_exec(struct ast_channel *chan, void *data)
}
}
- res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, exten, context);
+ res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, exten, args.context);
if (fd)
close(fd);
diff --git a/apps/app_controlplayback.c b/apps/app_controlplayback.c
index 8f7a7fd61..113cf25fa 100644
--- a/apps/app_controlplayback.c
+++ b/apps/app_controlplayback.c
@@ -94,20 +94,18 @@ static int controlplayback_exec(struct ast_channel *chan, void *data)
long offsetms = 0;
char offsetbuf[20];
char *tmp;
- int argc;
- char *argv[8] = { NULL, };
- enum arg_ids {
- arg_file = 0,
- arg_skip = 1,
- arg_fwd = 2,
- arg_rev = 3,
- arg_stop = 4,
- arg_pause = 5,
- arg_restart = 6,
- options = 7,
- };
struct ast_flags opts = { 0, };
char *opt_args[OPT_ARG_ARRAY_LEN];
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(filename);
+ AST_APP_ARG(skip);
+ AST_APP_ARG(fwd);
+ AST_APP_ARG(rev);
+ AST_APP_ARG(stop);
+ AST_APP_ARG(pause);
+ AST_APP_ARG(restart);
+ AST_APP_ARG(options);
+ );
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "ControlPlayback requires an argument (filename)\n");
@@ -115,39 +113,36 @@ static int controlplayback_exec(struct ast_channel *chan, void *data)
}
tmp = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, tmp);
- argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
-
- if (argc < 1) {
+ if (args.argc < 1) {
ast_log(LOG_WARNING, "ControlPlayback requires an argument (filename)\n");
return -1;
}
- skipms = argv[arg_skip] ? atoi(argv[arg_skip]) : 3000;
- if (!skipms)
- skipms = 3000;
-
- if (!argv[arg_fwd] || !is_on_phonepad(*argv[arg_fwd]))
- argv[arg_fwd] = "#";
- if (!argv[arg_rev] || !is_on_phonepad(*argv[arg_rev]))
- argv[arg_rev] = "*";
- if (argv[arg_stop] && !is_on_phonepad(*argv[arg_stop]))
- argv[arg_stop] = NULL;
- if (argv[arg_pause] && !is_on_phonepad(*argv[arg_pause]))
- argv[arg_pause] = NULL;
- if (argv[arg_restart] && !is_on_phonepad(*argv[arg_restart]))
- argv[arg_restart] = NULL;
-
- if (argv[options]) {
- ast_app_parse_options(cpb_opts, &opts, opt_args, argv[options]);
+ skipms = args.skip ? (atoi(args.skip) ? atoi(args.skip) : 3000) : 3000;
+
+ if (!args.fwd || !is_on_phonepad(*args.fwd))
+ args.fwd = "#";
+ if (!args.rev || !is_on_phonepad(*args.rev))
+ args.rev = "*";
+ if (args.stop && !is_on_phonepad(*args.stop))
+ args.stop = NULL;
+ if (args.pause && !is_on_phonepad(*args.pause))
+ args.pause = NULL;
+ if (args.restart && !is_on_phonepad(*args.restart))
+ args.restart = NULL;
+
+ if (args.options) {
+ ast_app_parse_options(cpb_opts, &opts, opt_args, args.options);
if (ast_test_flag(&opts, OPT_OFFSET))
offsetms = atol(opt_args[OPT_ARG_OFFSET]);
}
- res = ast_control_streamfile(chan, argv[arg_file], argv[arg_fwd], argv[arg_rev], argv[arg_stop], argv[arg_pause], argv[arg_restart], skipms, &offsetms);
+ res = ast_control_streamfile(chan, args.filename, args.fwd, args.rev, args.stop, args.pause, args.restart, skipms, &offsetms);
/* If we stopped on one of our stop keys, return 0 */
- if (argv[arg_stop] && strchr(argv[arg_stop], res)) {
+ if (args.stop && strchr(args.stop, res)) {
res = 0;
pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "USERSTOPPED");
} else {
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 29f059a02..0acdc1751 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -66,7 +66,7 @@ static char *app = "Dial";
static char *synopsis = "Place a call and connect to the current channel";
static char *descrip =
-" Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
+" Dial(Technology/resource[&Tech2/resource2...][,timeout][,options][,URL]):\n"
"This application will place calls to one or more specified channels. As soon\n"
"as one of the requested channels answers, the originating channel will be\n"
"answered, if it has not already been answered. These two channels will then\n"
@@ -215,7 +215,7 @@ static char *descrip =
static char *rapp = "RetryDial";
static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
static char *rdescrip =
-" RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
+" RetryDial(announce,sleep,retries,dialargs): This application will attempt to\n"
"place a call using the normal Dial application. If no channel can be reached,\n"
"the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
"seconds before retying the call. After 'retires' number of attempts, the\n"
@@ -840,7 +840,7 @@ static void replace_macro_delimiter(char *s)
{
for (; *s; s++)
if (*s == '^')
- *s = '|';
+ *s = ',';
}
@@ -1856,41 +1856,33 @@ static int dial_exec(struct ast_channel *chan, void *data)
static int retrydial_exec(struct ast_channel *chan, void *data)
{
- char *announce = NULL, *dialdata = NULL;
+ char *parse;
const char *context = NULL;
int sleep = 0, loops = 0, res = -1;
- struct ast_flags64 peerflags;
-
+ struct ast_flags64 peerflags = { 0, };
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(announce);
+ AST_APP_ARG(sleep);
+ AST_APP_ARG(retries);
+ AST_APP_ARG(dialdata);
+ );
+
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
return -1;
}
- announce = ast_strdupa(data);
-
- memset(&peerflags, 0, sizeof(peerflags));
+ parse = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parse);
- if ((dialdata = strchr(announce, '|'))) {
- *dialdata++ = '\0';
- if (sscanf(dialdata, "%d", &sleep) == 1) {
- sleep *= 1000;
- } else {
- ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
- goto done;
- }
- if ((dialdata = strchr(dialdata, '|'))) {
- *dialdata++ = '\0';
- if (sscanf(dialdata, "%d", &loops) != 1) {
- ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
- goto done;
- }
- }
+ if ((sleep = atoi(args.sleep))) {
+ sleep *= 1000;
}
-
- if ((dialdata = strchr(dialdata, '|'))) {
- *dialdata++ = '\0';
- } else {
- ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
+
+ loops = atoi(args.retries);
+
+ if (!args.dialdata) {
+ ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
goto done;
}
@@ -1910,18 +1902,18 @@ static int retrydial_exec(struct ast_channel *chan, void *data)
if (ast_test_flag(chan, AST_FLAG_MOH))
ast_moh_stop(chan);
- res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
+ res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
if (continue_exec)
break;
if (res == 0) {
if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
- if (!ast_strlen_zero(announce)) {
- if (ast_fileexists(announce, NULL, chan->language) > 0) {
- if(!(res = ast_streamfile(chan, announce, chan->language)))
+ if (!ast_strlen_zero(args.announce)) {
+ if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
+ if(!(res = ast_streamfile(chan, args.announce, chan->language)))
ast_waitstream(chan, AST_DIGIT_ANY);
} else
- ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
+ ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
}
if (!res && sleep) {
if (!ast_test_flag(chan, AST_FLAG_MOH))
@@ -1929,12 +1921,12 @@ static int retrydial_exec(struct ast_channel *chan, void *data)
res = ast_waitfordigit(chan, sleep);
}
} else {
- if (!ast_strlen_zero(announce)) {
- if (ast_fileexists(announce, NULL, chan->language) > 0) {
- if (!(res = ast_streamfile(chan, announce, chan->language)))
+ if (!ast_strlen_zero(args.announce)) {
+ if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
+ if (!(res = ast_streamfile(chan, args.announce, chan->language)))
res = ast_waitstream(chan, "");
} else
- ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
+ ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
}
if (sleep) {
if (!ast_test_flag(chan, AST_FLAG_MOH))
diff --git a/apps/app_exec.c b/apps/app_exec.c
index b953e8129..2423580fe 100644
--- a/apps/app_exec.c
+++ b/apps/app_exec.c
@@ -41,6 +41,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
+#include "asterisk/app.h"
/* Maximum length of any variable */
#define MAXRESULT 1024
@@ -83,7 +84,7 @@ static char *tryexec_descrip =
static char *app_execif = "ExecIf";
static char *execif_synopsis = "Executes dialplan application, conditionally";
static char *execif_descrip =
-"Usage: ExecIF (<expr>|<app>|<data>)\n"
+"Usage: ExecIF (<expr>?<app>(<data>):<app2>(<data2>))\n"
"If <expr> is true, execute and return the result of <app>(<data>).\n"
"If <expr> is true, but <app> is not found, then the application\n"
"will return a non-zero value.\n";
@@ -152,33 +153,47 @@ static int tryexec_exec(struct ast_channel *chan, void *data)
static int execif_exec(struct ast_channel *chan, void *data)
{
int res = 0;
- char *myapp = NULL;
- char *mydata = NULL;
- char *expr = NULL;
+ char *truedata = NULL, *falsedata = NULL, *end;
struct ast_app *app = NULL;
+ AST_DECLARE_APP_ARGS(expr,
+ AST_APP_ARG(expr);
+ AST_APP_ARG(remainder);
+ );
+ AST_DECLARE_APP_ARGS(apps,
+ AST_APP_ARG(true);
+ AST_APP_ARG(false);
+ );
+ char *parse = ast_strdupa(data);
+
+ AST_NONSTANDARD_APP_ARGS(expr, parse, '?');
+ AST_NONSTANDARD_APP_ARGS(apps, expr.remainder, ':');
+
+ if (apps.true && (truedata = strchr(apps.true, '('))) {
+ *truedata++ = '\0';
+ if ((end = strrchr(truedata, ')')))
+ *end = '\0';
+ }
+
+ if (apps.false && (falsedata = strchr(apps.false, '('))) {
+ *falsedata++ = '\0';
+ if ((end = strrchr(falsedata, ')')))
+ *end = '\0';
+ }
- expr = ast_strdupa(data);
-
- if ((myapp = strchr(expr,'|'))) {
- *myapp = '\0';
- myapp++;
- if ((mydata = strchr(myapp,'|'))) {
- *mydata = '\0';
- mydata++;
- } else
- mydata = "";
-
- if (pbx_checkcondition(expr)) {
- if ((app = pbx_findapp(myapp))) {
- res = pbx_exec(chan, app, mydata);
- } else {
- ast_log(LOG_WARNING, "Count not find application! (%s)\n", myapp);
- res = -1;
- }
+ if (pbx_checkcondition(expr.expr)) {
+ if (!ast_strlen_zero(apps.true) && (app = pbx_findapp(apps.true))) {
+ res = pbx_exec(chan, app, S_OR(truedata, ""));
+ } else {
+ ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.true);
+ res = -1;
}
} else {
- ast_log(LOG_ERROR,"Invalid Syntax.\n");
- res = -1;
+ if (!ast_strlen_zero(apps.false) && (app = pbx_findapp(apps.false))) {
+ res = pbx_exec(chan, app, S_OR(falsedata, ""));
+ } else {
+ ast_log(LOG_WARNING, "Could not find application! (%s)\n", apps.false);
+ res = -1;
+ }
}
return res;
diff --git a/apps/app_externalivr.c b/apps/app_externalivr.c
index 63c182337..31cdafd0a 100644
--- a/apps/app_externalivr.c
+++ b/apps/app_externalivr.c
@@ -58,7 +58,7 @@ static const char *app = "ExternalIVR";
static const char *synopsis = "Interfaces with an external IVR application";
static const char *descrip =
-" ExternalIVR(command[|arg[|arg...]]): Forks an process to run the supplied command,\n"
+" ExternalIVR(command[,arg[,arg...]]): Forks an process to run the supplied command,\n"
"and starts a generator on the channel. The generator's play list is\n"
"controlled by the external application, which can add and clear entries\n"
"via simple commands issued over its stdout. The external application\n"
@@ -244,7 +244,6 @@ static struct playlist_entry *make_entry(const char *filename)
static int app_exec(struct ast_channel *chan, void *data)
{
struct playlist_entry *entry;
- const char *args = data;
int child_stdin[2] = { 0,0 };
int child_stdout[2] = { 0,0 };
int child_stderr[2] = { 0,0 };
@@ -252,7 +251,6 @@ static int app_exec(struct ast_channel *chan, void *data)
int gen_active = 0;
int pid;
char *argv[32];
- int argc = 1;
char *buf, *command;
FILE *child_commands = NULL;
FILE *child_errors = NULL;
@@ -263,6 +261,9 @@ static int app_exec(struct ast_channel *chan, void *data)
};
struct ivr_localuser *u = &foo;
sigset_t fullset, oldset;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(cmd)[32];
+ );
sigfillset(&fullset);
pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
@@ -270,14 +271,13 @@ static int app_exec(struct ast_channel *chan, void *data)
u->abort_current_sound = 0;
u->chan = chan;
- if (ast_strlen_zero(args)) {
+ if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "ExternalIVR requires a command to execute\n");
return -1;
}
buf = ast_strdupa(data);
-
- argc = ast_app_separate_args(buf, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ AST_STANDARD_APP_ARGS(args, buf);
if (pipe(child_stdin)) {
ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child input: %s\n", strerror(errno));
diff --git a/apps/app_macro.c b/apps/app_macro.c
index 5f71bcd7f..aa24dd94c 100644
--- a/apps/app_macro.c
+++ b/apps/app_macro.c
@@ -197,7 +197,7 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
tmp = ast_strdupa(data);
rest = tmp;
- macro = strsep(&rest, "|");
+ macro = strsep(&rest, ",");
if (ast_strlen_zero(macro)) {
ast_log(LOG_WARNING, "Invalid macro name specified\n");
return 0;
@@ -255,7 +255,7 @@ static int _macro_exec(struct ast_channel *chan, void *data, int exclusive)
ast_copy_string(chan->context, fullmacro, sizeof(chan->context));
chan->priority = 1;
- while((cur = strsep(&rest, "|")) && (argc < MAX_ARGS)) {
+ 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 */
diff --git a/apps/app_page.c b/apps/app_page.c
index 8edb15833..8b90fc0b4 100644
--- a/apps/app_page.c
+++ b/apps/app_page.c
@@ -86,7 +86,7 @@ AST_APP_OPTIONS(page_opts, {
static int page_exec(struct ast_channel *chan, void *data)
{
char *options, *tech, *resource, *tmp;
- char meetmeopts[88], originator[AST_CHANNEL_NAME];
+ char meetmeopts[88], originator[AST_CHANNEL_NAME], *opts[0];
struct ast_flags flags = { 0 };
unsigned int confid = ast_random();
struct ast_app *app;
@@ -109,9 +109,9 @@ static int page_exec(struct ast_channel *chan, void *data)
if ((tmp = strchr(originator, '-')))
*tmp = '\0';
- tmp = strsep(&options, "|");
+ tmp = strsep(&options, ",");
if (options)
- ast_app_parse_options(page_opts, &flags, NULL, options);
+ ast_app_parse_options(page_opts, &flags, opts, options);
snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe|%ud|%s%sqxdw(5)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"),
(ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") );
diff --git a/apps/app_parkandannounce.c b/apps/app_parkandannounce.c
index 138694c5a..d7d5fc787 100644
--- a/apps/app_parkandannounce.c
+++ b/apps/app_parkandannounce.c
@@ -50,6 +50,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/say.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
+#include "asterisk/app.h"
static char *app = "ParkAndAnnounce";
@@ -76,113 +77,72 @@ static char *descrip =
static int parkandannounce_exec(struct ast_channel *chan, void *data)
{
- int res=0;
- char *return_context;
+ int res = -1;
int lot, timeout = 0, dres;
- char *working, *context, *exten, *priority, *dial, *dialtech, *dialstr;
- char *template, *tpl_working, *tpl_current;
- char *tmp[100];
- char buf[13];
- int looptemp=0,i=0;
+ char *dialtech, *tmp[100], buf[13];
+ int looptemp, i;
char *s;
struct ast_channel *dchan;
- struct outgoing_helper oh;
+ struct outgoing_helper oh = { 0, };
int outstate;
-
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(template);
+ AST_APP_ARG(timeout);
+ AST_APP_ARG(dial);
+ AST_APP_ARG(return_context);
+ );
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
return -1;
}
s = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, s);
- template=strsep(&s,"|");
- if(! template) {
- ast_log(LOG_WARNING, "PARK: An announce template must be defined\n");
- return -1;
- }
-
- if(s) {
- timeout = atoi(strsep(&s, "|"));
- timeout *= 1000;
- }
- dial=strsep(&s, "|");
- if(!dial) {
+ if (args.timeout)
+ timeout = atoi(args.timeout) * 1000;
+
+ if (ast_strlen_zero(args.dial)) {
ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or Zap/g1/5551212\n");
return -1;
- } else {
- dialtech=strsep(&dial, "/");
- dialstr=dial;
- ast_verbose( VERBOSE_PREFIX_3 "Dial Tech,String: (%s,%s)\n", dialtech,dialstr);
}
- return_context = s;
-
- if(return_context != NULL) {
- /* set the return context. Code borrowed from the Goto builtin */
-
- working = return_context;
- context = strsep(&working, "|");
- exten = strsep(&working, "|");
- if(!exten) {
- /* Only a priority in this one */
- priority = context;
- exten = NULL;
- context = NULL;
- } else {
- priority = strsep(&working, "|");
- if(!priority) {
- /* Only an extension and priority in this one */
- priority = exten;
- exten = context;
- context = NULL;
- }
- }
- if(atoi(priority) < 0) {
- ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority);
- return -1;
- }
- /* At this point we have a priority and maybe an extension and a context */
- chan->priority = atoi(priority);
- if (exten)
- ast_copy_string(chan->exten, exten, sizeof(chan->exten));
- if (context)
- ast_copy_string(chan->context, context, sizeof(chan->context));
- } else { /* increment the priority by default*/
- chan->priority++;
- }
+ dialtech = strsep(&args.dial, "/");
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Dial Tech,String: (%s,%s)\n", dialtech, args.dial);
+
+ if (!ast_strlen_zero(args.return_context))
+ ast_parseable_goto(chan, args.return_context);
- if(option_verbose > 2) {
- ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num);
- if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
- ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n");
+ if (option_verbose > 2) {
+ ast_verbose(VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context, chan->exten, chan->priority, chan->cid.cid_num);
+ if (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
+ ast_verbose(VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n");
}
}
-
+
/* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout
before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */
ast_masq_park_call(chan, NULL, timeout, &lot);
- res=-1;
-
- ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context);
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, args.return_context);
- /* Now place the call to the extention */
+ /* Now place the call to the extension */
snprintf(buf, sizeof(buf), "%d", lot);
- memset(&oh, 0, sizeof(oh));
oh.parent_channel = chan;
oh.vars = ast_variable_new("_PARKEDAT", buf);
- dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, chan->cid.cid_num, chan->cid.cid_name, &oh);
+ dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, args.dial, 30000, &outstate, chan->cid.cid_num, chan->cid.cid_name, &oh);
- if(dchan) {
- if(dchan->_state == AST_STATE_UP) {
- if(option_verbose > 3)
+ if (dchan) {
+ if (dchan->_state == AST_STATE_UP) {
+ if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", dchan->name);
} else {
- if(option_verbose > 3)
+ if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", dchan->name);
ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
ast_hangup(dchan);
@@ -197,24 +157,21 @@ static int parkandannounce_exec(struct ast_channel *chan, void *data)
/* now we have the call placed and are ready to play stuff to it */
- ast_verbose(VERBOSE_PREFIX_4 "Announce Template:%s\n", template);
+ if (option_verbose > 3)
+ ast_verbose(VERBOSE_PREFIX_4 "Announce Template:%s\n", args.template);
- tpl_working = template;
- tpl_current=strsep(&tpl_working, ":");
-
- while(tpl_current && looptemp < sizeof(tmp)) {
- tmp[looptemp]=tpl_current;
- looptemp++;
- tpl_current=strsep(&tpl_working,":");
- }
+ for (looptemp = 0, tmp[looptemp++] = strsep(&args.template, ":");
+ looptemp < sizeof(tmp) / sizeof(tmp[0]);
+ tmp[looptemp++] = strsep(&args.template, ":"));
- for(i=0; i<looptemp; i++) {
- ast_verbose(VERBOSE_PREFIX_4 "Announce:%s\n", tmp[i]);
- if(!strcmp(tmp[i], "PARKED")) {
+ for (i = 0; i < looptemp; i++) {
+ if (option_verbose > 3)
+ ast_verbose(VERBOSE_PREFIX_4 "Announce:%s\n", tmp[i]);
+ if (!strcmp(tmp[i], "PARKED")) {
ast_say_digits(dchan, lot, "", dchan->language);
} else {
dres = ast_streamfile(dchan, tmp[i], dchan->language);
- if(!dres) {
+ if (!dres) {
dres = ast_waitstream(dchan, "");
} else {
ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], dchan->name);
diff --git a/apps/app_queue.c b/apps/app_queue.c
index a99b38593..dafbafb8a 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -930,11 +930,11 @@ static void queue_set_param(struct call_queue *q, const char *param, const char
else
q->announceholdtime = 0;
} else if (!strcasecmp(param, "periodic-announce")) {
- if (strchr(val, '|')) {
+ if (strchr(val, ',')) {
char *s, *buf = ast_strdupa(val);
unsigned int i = 0;
- while ((s = strsep(&buf, "|"))) {
+ while ((s = strsep(&buf, ",|"))) {
ast_copy_string(q->sound_periodicannounce[i], s, sizeof(q->sound_periodicannounce[i]));
i++;
if (i == MAX_PERIODIC_ANNOUNCEMENTS)
@@ -3179,7 +3179,7 @@ static void reload_queue_members(void)
continue;
cur_ptr = queue_data;
- while ((member = strsep(&cur_ptr, "|"))) {
+ while ((member = strsep(&cur_ptr, ",|"))) {
if (ast_strlen_zero(member))
continue;
diff --git a/apps/app_readfile.c b/apps/app_readfile.c
index e857f8318..c23037610 100644
--- a/apps/app_readfile.c
+++ b/apps/app_readfile.c
@@ -67,7 +67,7 @@ static int readfile_exec(struct ast_channel *chan, void *data)
s = ast_strdupa(data);
varname = strsep(&s, "=");
- file = strsep(&s, "|");
+ file = strsep(&s, ",");
length = s;
if (!varname || !file) {
diff --git a/apps/app_record.c b/apps/app_record.c
index 0bbe0b008..1742e0796 100644
--- a/apps/app_record.c
+++ b/apps/app_record.c
@@ -74,19 +74,35 @@ static char *descrip =
"If the user should hangup during a recording, all data will be lost and the\n"
"application will teminate. \n";
+enum {
+ OPTION_APPEND = (1 << 0),
+ OPTION_NOANSWER = (1 << 1),
+ OPTION_QUIET = (1 << 2),
+ OPTION_SKIP = (1 << 3),
+ OPTION_STAR_TERMINATE = (1 << 4),
+ OPTION_IGNORE_TERMINATE = (1 << 5),
+ FLAG_HAS_PERCENT = (1 << 6),
+};
+
+AST_APP_OPTIONS(app_opts,{
+ AST_APP_OPTION('a', OPTION_APPEND),
+ AST_APP_OPTION('n', OPTION_NOANSWER),
+ AST_APP_OPTION('q', OPTION_QUIET),
+ AST_APP_OPTION('s', OPTION_SKIP),
+ AST_APP_OPTION('t', OPTION_STAR_TERMINATE),
+ AST_APP_OPTION('x', OPTION_IGNORE_TERMINATE),
+});
static int record_exec(struct ast_channel *chan, void *data)
{
int res = 0;
int count = 0;
- int percentflag = 0;
- char *filename, *ext = NULL, *silstr, *maxstr, *options;
- char *file, *dir;
- char *vdata, *p;
+ char *ext = NULL, *opts[0];
+ char *parse, *dir, *file;
int i = 0;
char tmp[256];
- struct ast_filestream *s = '\0';
+ struct ast_filestream *s = NULL;
struct ast_frame *f = NULL;
struct ast_dsp *sildet = NULL; /* silence detector dsp */
@@ -96,15 +112,18 @@ static int record_exec(struct ast_channel *chan, void *data)
int gotsilence = 0; /* did we timeout for silence? */
int maxduration = 0; /* max duration of recording in milliseconds */
int gottimeout = 0; /* did we timeout for maxduration exceeded? */
- int option_skip = 0;
- int option_noanswer = 0;
- int option_append = 0;
int terminator = '#';
- int option_quiet = 0;
int rfmt = 0;
- int flags;
+ int ioflags;
int waitres;
struct ast_silence_generator *silgen = NULL;
+ struct ast_flags flags;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(filename);
+ AST_APP_ARG(silence);
+ AST_APP_ARG(maxduration);
+ AST_APP_ARG(options);
+ );
/* The next few lines of code parse out the filename and header from the input string */
if (ast_strlen_zero(data)) { /* no data implies no filename or anything is present */
@@ -112,21 +131,17 @@ static int record_exec(struct ast_channel *chan, void *data)
return -1;
}
- /* Yay for strsep being easy */
- vdata = ast_strdupa(data);
+ parse = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parse);
+ if (args.argc == 4)
+ ast_app_parse_options(app_opts, &flags, opts, args.options);
- p = vdata;
- filename = strsep(&p, "|");
- silstr = strsep(&p, "|");
- maxstr = strsep(&p, "|");
- options = strsep(&p, "|");
-
- if (filename) {
- if (strstr(filename, "%d"))
- percentflag = 1;
- ext = strrchr(filename, '.'); /* to support filename with a . in the filename, not format */
+ if (!ast_strlen_zero(args.filename)) {
+ if (strstr(args.filename, "%d"))
+ ast_set_flag(&flags, FLAG_HAS_PERCENT);
+ ext = strrchr(args.filename, '.'); /* to support filename with a . in the filename, not format */
if (!ext)
- ext = strchr(filename, ':');
+ ext = strchr(args.filename, ':');
if (ext) {
*ext = '\0';
ext++;
@@ -136,52 +151,36 @@ static int record_exec(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "No extension specified to filename!\n");
return -1;
}
- if (silstr) {
- if ((sscanf(silstr, "%d", &i) == 1) && (i > -1)) {
+ if (args.silence) {
+ if ((sscanf(args.silence, "%d", &i) == 1) && (i > -1)) {
silence = i * 1000;
- } else if (!ast_strlen_zero(silstr)) {
- ast_log(LOG_WARNING, "'%s' is not a valid silence duration\n", silstr);
+ } else if (!ast_strlen_zero(args.silence)) {
+ ast_log(LOG_WARNING, "'%s' is not a valid silence duration\n", args.silence);
}
}
- if (maxstr) {
- if ((sscanf(maxstr, "%d", &i) == 1) && (i > -1))
+ if (args.maxduration) {
+ if ((sscanf(args.maxduration, "%d", &i) == 1) && (i > -1))
/* Convert duration to milliseconds */
maxduration = i * 1000;
- else if (!ast_strlen_zero(maxstr))
- ast_log(LOG_WARNING, "'%s' is not a valid maximum duration\n", maxstr);
+ else if (!ast_strlen_zero(args.maxduration))
+ ast_log(LOG_WARNING, "'%s' is not a valid maximum duration\n", args.maxduration);
}
- if (options) {
- /* Retain backwards compatibility with old style options */
- if (!strcasecmp(options, "skip"))
- option_skip = 1;
- else if (!strcasecmp(options, "noanswer"))
- option_noanswer = 1;
- else {
- if (strchr(options, 's'))
- option_skip = 1;
- if (strchr(options, 'n'))
- option_noanswer = 1;
- if (strchr(options, 'a'))
- option_append = 1;
- if (strchr(options, 't'))
- terminator = '*';
- if (strchr(options, 'x'))
- terminator = 0;
- if (strchr(options, 'q'))
- option_quiet = 1;
- }
- }
-
+
+ if (ast_test_flag(&flags, OPTION_STAR_TERMINATE))
+ terminator = '*';
+ if (ast_test_flag(&flags, OPTION_IGNORE_TERMINATE))
+ terminator = '\0';
+
/* done parsing */
-
+
/* these are to allow the use of the %d in the config file for a wild card of sort to
create a new file with the inputed name scheme */
- if (percentflag) {
+ if (ast_test_flag(&flags, FLAG_HAS_PERCENT)) {
AST_DECLARE_APP_ARGS(fname,
AST_APP_ARG(piece)[100];
);
- char *tmp2 = ast_strdupa(filename);
+ char *tmp2 = ast_strdupa(args.filename);
char countstring[15];
int i;
@@ -210,27 +209,25 @@ static int record_exec(struct ast_channel *chan, void *data)
} while (ast_fileexists(tmp, ext, chan->language) > 0);
pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp);
} else
- ast_copy_string(tmp, filename, sizeof(tmp));
+ ast_copy_string(tmp, args.filename, sizeof(tmp));
/* end of routine mentioned */
-
-
-
+
if (chan->_state != AST_STATE_UP) {
- if (option_skip) {
+ if (ast_test_flag(&flags, OPTION_SKIP)) {
/* At the user's option, skip if the line is not up */
return 0;
- } else if (!option_noanswer) {
+ } else if (!ast_test_flag(&flags, OPTION_NOANSWER)) {
/* Otherwise answer unless we're supposed to record while on-hook */
res = ast_answer(chan);
}
}
-
+
if (res) {
ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
goto out;
}
-
- if (!option_quiet) {
+
+ if (!ast_test_flag(&flags, OPTION_QUIET)) {
/* Some code to play a nice little beep to signify the start of the record operation */
res = ast_streamfile(chan, "beep", chan->language);
if (!res) {
@@ -240,9 +237,9 @@ static int record_exec(struct ast_channel *chan, void *data)
}
ast_stopstream(chan);
}
-
+
/* The end of beep code. Now the recording starts */
-
+
if (silence > 0) {
rfmt = chan->readformat;
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
@@ -264,23 +261,23 @@ static int record_exec(struct ast_channel *chan, void *data)
*file++ = '\0';
ast_mkdir (dir, 0777);
- flags = option_append ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY;
- s = ast_writefile( tmp, ext, NULL, flags , 0, AST_FILE_MODE);
-
+ ioflags = ast_test_flag(&flags, OPTION_APPEND) ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY;
+ s = ast_writefile(tmp, ext, NULL, ioflags, 0, AST_FILE_MODE);
+
if (!s) {
- ast_log(LOG_WARNING, "Could not create file %s\n", filename);
+ ast_log(LOG_WARNING, "Could not create file %s\n", args.filename);
goto out;
}
if (ast_opt_transmit_silence)
silgen = ast_channel_start_silence_generator(chan);
-
+
/* Request a video update */
ast_indicate(chan, AST_CONTROL_VIDUPDATE);
-
+
if (maxduration <= 0)
maxduration = -1;
-
+
while ((waitres = ast_waitfor(chan, maxduration)) > -1) {
if (maxduration > 0) {
if (waitres == 0) {
@@ -289,7 +286,7 @@ static int record_exec(struct ast_channel *chan, void *data)
}
maxduration = waitres;
}
-
+
f = ast_read(chan);
if (!f) {
res = -1;
@@ -297,13 +294,13 @@ static int record_exec(struct ast_channel *chan, void *data)
}
if (f->frametype == AST_FRAME_VOICE) {
res = ast_writestream(s, f);
-
+
if (res) {
ast_log(LOG_WARNING, "Problem writing frame\n");
ast_frfree(f);
break;
}
-
+
if (silence > 0) {
dspsilence = 0;
ast_dsp_silence(sildet, f, &dspsilence);
@@ -321,7 +318,7 @@ static int record_exec(struct ast_channel *chan, void *data)
}
} else if (f->frametype == AST_FRAME_VIDEO) {
res = ast_writestream(s, f);
-
+
if (res) {
ast_log(LOG_WARNING, "Problem writing frame\n");
ast_frfree(f);
@@ -338,9 +335,9 @@ static int record_exec(struct ast_channel *chan, void *data)
ast_debug(1, "Got hangup\n");
res = -1;
}
-
+
if (gotsilence) {
- ast_stream_rewind(s, silence-1000);
+ ast_stream_rewind(s, silence - 1000);
ast_truncstream(s);
} else if (!gottimeout) {
/* Strip off the last 1/4 second of it */
@@ -351,8 +348,8 @@ static int record_exec(struct ast_channel *chan, void *data)
if (silgen)
ast_channel_stop_silence_generator(chan, silgen);
-
- out:
+
+out:
if ((silence > 0) && rfmt) {
res = ast_set_read_format(chan, rfmt);
if (res)
diff --git a/apps/app_skel.c b/apps/app_skel.c
index 9cd759c69..527fc776d 100644
--- a/apps/app_skel.c
+++ b/apps/app_skel.c
@@ -84,7 +84,7 @@ static int app_exec(struct ast_channel *chan, void *data)
);
if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "%s requires an argument (dummy|[options])\n", app);
+ ast_log(LOG_WARNING, "%s requires an argument (dummy[,options])\n", app);
return -1;
}
diff --git a/apps/app_softhangup.c b/apps/app_softhangup.c
index 42f48aac7..5bc90fdfe 100644
--- a/apps/app_softhangup.c
+++ b/apps/app_softhangup.c
@@ -41,10 +41,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
+#include "asterisk/app.h"
static char *synopsis = "Soft Hangup Application";
-static char *desc = " SoftHangup(Technology/resource|options)\n"
+static char *desc = "SoftHangup(Technology/resource[,options])\n"
"Hangs up the requested channel. If there are no channels to hangup,\n"
"the application will report it.\n"
"- 'options' may contain the following letter:\n"
@@ -52,46 +53,62 @@ static char *desc = " SoftHangup(Technology/resource|options)\n"
static char *app = "SoftHangup";
+enum {
+ OPTION_ALL = (1 << 0),
+};
+
+AST_APP_OPTIONS(app_opts,{
+ AST_APP_OPTION('a', OPTION_ALL),
+});
static int softhangup_exec(struct ast_channel *chan, void *data)
{
- struct ast_channel *c=NULL;
- char *options, *cut, *cdata, *match;
- char name[AST_CHANNEL_NAME] = "";
- int all = 0;
+ struct ast_channel *c = NULL;
+ char *cut, *opts[0];
+ char name[AST_CHANNEL_NAME] = "", *parse;
+ struct ast_flags flags;
+ int lenmatch;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(channel);
+ AST_APP_ARG(options);
+ );
if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "SoftHangup requires an argument (Technology/resource)\n");
+ ast_log(LOG_WARNING, "SoftHangup requires an argument (Technology/resource)\n");
return 0;
}
-
- cdata = ast_strdupa(data);
- match = strsep(&cdata, "|");
- options = strsep(&cdata, "|");
- all = options && strchr(options,'a');
- c = ast_channel_walk_locked(NULL);
- while (c) {
+
+ parse = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ if (args.argc == 2)
+ ast_app_parse_options(app_opts, &flags, opts, args.options);
+ lenmatch = strlen(args.channel);
+
+ for (c = ast_walk_channel_by_name_prefix_locked(NULL, args.channel, lenmatch);
+ c;
+ c = ast_walk_channel_by_name_prefix_locked(c, args.channel, lenmatch)) {
ast_copy_string(name, c->name, sizeof(name));
- ast_mutex_unlock(&c->lock);
- /* XXX watch out, i think it is wrong to access c-> after unlocking! */
- if (all) {
+ if (ast_test_flag(&flags, OPTION_ALL)) {
/* CAPI is set up like CAPI[foo/bar]/clcnt */
if (!strcmp(c->tech->type, "CAPI"))
- cut = strrchr(name,'/');
+ cut = strrchr(name, '/');
/* Basically everything else is Foo/Bar-Z */
else
- cut = strchr(name,'-');
+ cut = strchr(name, '-');
/* Get rid of what we've cut */
if (cut)
*cut = 0;
}
- if (!strcasecmp(name, match)) {
- ast_log(LOG_WARNING, "Soft hanging %s up.\n",c->name);
+ if (!strcasecmp(name, args.channel)) {
+ ast_log(LOG_WARNING, "Soft hanging %s up.\n", c->name);
ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
- if(!all)
+ if (!ast_test_flag(&flags, OPTION_ALL)) {
+ ast_mutex_unlock(&c->lock);
break;
+ }
}
- c = ast_channel_walk_locked(c);
+ ast_mutex_unlock(&c->lock);
}
return 0;
diff --git a/apps/app_talkdetect.c b/apps/app_talkdetect.c
index 9e4d2a4ee..0438111c5 100644
--- a/apps/app_talkdetect.c
+++ b/apps/app_talkdetect.c
@@ -43,6 +43,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/utils.h"
#include "asterisk/dsp.h"
#include "asterisk/options.h"
+#include "asterisk/app.h"
static char *app = "BackgroundDetect";
@@ -64,17 +65,21 @@ static int background_detect_exec(struct ast_channel *chan, void *data)
{
int res = 0;
char *tmp;
- char *options;
- char *stringp;
struct ast_frame *fr;
- int notsilent=0;
+ int notsilent = 0;
struct timeval start = { 0, 0};
int sil = 1000;
int min = 100;
int max = -1;
int x;
int origrformat=0;
- struct ast_dsp *dsp;
+ struct ast_dsp *dsp = NULL;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(filename);
+ AST_APP_ARG(silence);
+ AST_APP_ARG(min);
+ AST_APP_ARG(max);
+ );
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "BackgroundDetect requires an argument (filename)\n");
@@ -82,118 +87,112 @@ static int background_detect_exec(struct ast_channel *chan, void *data)
}
tmp = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, tmp);
- stringp=tmp;
- strsep(&stringp, "|");
- options = strsep(&stringp, "|");
- if (options) {
- if ((sscanf(options, "%d", &x) == 1) && (x > 0))
- sil = x;
- options = strsep(&stringp, "|");
- if (options) {
- if ((sscanf(options, "%d", &x) == 1) && (x > 0))
- min = x;
- options = strsep(&stringp, "|");
- if (options) {
- if ((sscanf(options, "%d", &x) == 1) && (x > 0))
- max = x;
- }
+ if ((sscanf(args.silence, "%d", &x) == 1) && (x > 0))
+ sil = x;
+ if ((sscanf(args.min, "%d", &x) == 1) && (x > 0))
+ min = x;
+ if ((sscanf(args.max, "%d", &x) == 1) && (x > 0))
+ max = x;
+
+ ast_debug(1, "Preparing detect of '%s', sil=%d, min=%d, max=%d\n", args.filename, sil, min, max);
+ do {
+ if (chan->_state != AST_STATE_UP) {
+ if ((res = ast_answer(chan)))
+ break;
}
- }
- ast_debug(1, "Preparing detect of '%s', sil=%d,min=%d,max=%d\n", tmp, sil, min, max);
- if (chan->_state != AST_STATE_UP) {
- /* Otherwise answer unless we're supposed to send this while on-hook */
- res = ast_answer(chan);
- }
- if (!res) {
+
origrformat = chan->readformat;
- if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)))
+ if ((ast_set_read_format(chan, AST_FORMAT_SLINEAR))) {
ast_log(LOG_WARNING, "Unable to set read format to linear!\n");
- }
- if (!(dsp = ast_dsp_new())) {
- ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
- res = -1;
- }
- if (!res) {
+ res = -1;
+ break;
+ }
+
+ if (!(dsp = ast_dsp_new())) {
+ ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
+ res = -1;
+ break;
+ }
ast_stopstream(chan);
- res = ast_streamfile(chan, tmp, chan->language);
- if (!res) {
- while(chan->stream) {
- res = ast_sched_wait(chan->sched);
- if ((res < 0) && !chan->timingfunc) {
- res = 0;
- break;
- }
- if (res < 0)
- res = 1000;
- res = ast_waitfor(chan, res);
- if (res < 0) {
- ast_log(LOG_WARNING, "Waitfor failed on %s\n", chan->name);
+ if (ast_streamfile(chan, tmp, chan->language)) {
+ ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
+ break;
+ }
+
+ while (chan->stream) {
+ res = ast_sched_wait(chan->sched);
+ if ((res < 0) && !chan->timingfunc) {
+ res = 0;
+ break;
+ }
+ if (res < 0)
+ res = 1000;
+ res = ast_waitfor(chan, res);
+ if (res < 0) {
+ ast_log(LOG_WARNING, "Waitfor failed on %s\n", chan->name);
+ break;
+ } else if (res > 0) {
+ fr = ast_read(chan);
+ if (!fr) {
+ res = -1;
break;
- } else if (res > 0) {
- fr = ast_read(chan);
- if (!fr) {
- res = -1;
+ } else if (fr->frametype == AST_FRAME_DTMF) {
+ char t[2];
+ t[0] = fr->subclass;
+ t[1] = '\0';
+ if (ast_canmatch_extension(chan, chan->context, t, 1, chan->cid.cid_num)) {
+ /* They entered a valid extension, or might be anyhow */
+ res = fr->subclass;
+ ast_frfree(fr);
break;
- } else if (fr->frametype == AST_FRAME_DTMF) {
- char t[2];
- t[0] = fr->subclass;
- t[1] = '\0';
- if (ast_canmatch_extension(chan, chan->context, t, 1, chan->cid.cid_num)) {
- /* They entered a valid extension, or might be anyhow */
- res = fr->subclass;
- ast_frfree(fr);
- break;
- }
- } else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR)) {
- int totalsilence;
- int ms;
- res = ast_dsp_silence(dsp, fr, &totalsilence);
- if (res && (totalsilence > sil)) {
- /* We've been quiet a little while */
- if (notsilent) {
- /* We had heard some talking */
- ms = ast_tvdiff_ms(ast_tvnow(), start);
- ms -= sil;
- if (ms < 0)
- ms = 0;
- if ((ms > min) && ((max < 0) || (ms < max))) {
- char ms_str[10];
- ast_debug(1, "Found qualified token of %d ms\n", ms);
-
- /* Save detected talk time (in milliseconds) */
- sprintf(ms_str, "%d", ms );
- pbx_builtin_setvar_helper(chan, "TALK_DETECTED", ms_str);
-
- ast_goto_if_exists(chan, chan->context, "talk", 1);
- res = 0;
- ast_frfree(fr);
- break;
- } else {
- ast_debug(1, "Found unqualified token of %d ms\n", ms);
- }
- notsilent = 0;
- }
- } else {
- if (!notsilent) {
- /* Heard some audio, mark the begining of the token */
- start = ast_tvnow();
- ast_debug(1, "Start of voice token!\n");
- notsilent = 1;
+ }
+ } else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR)) {
+ int totalsilence;
+ int ms;
+ res = ast_dsp_silence(dsp, fr, &totalsilence);
+ if (res && (totalsilence > sil)) {
+ /* We've been quiet a little while */
+ if (notsilent) {
+ /* We had heard some talking */
+ ms = ast_tvdiff_ms(ast_tvnow(), start);
+ ms -= sil;
+ if (ms < 0)
+ ms = 0;
+ if ((ms > min) && ((max < 0) || (ms < max))) {
+ char ms_str[10];
+ ast_debug(1, "Found qualified token of %d ms\n", ms);
+
+ /* Save detected talk time (in milliseconds) */
+ sprintf(ms_str, "%d", ms );
+ pbx_builtin_setvar_helper(chan, "TALK_DETECTED", ms_str);
+
+ ast_goto_if_exists(chan, chan->context, "talk", 1);
+ res = 0;
+ ast_frfree(fr);
+ break;
+ } else {
+ ast_debug(1, "Found unqualified token of %d ms\n", ms);
}
+ notsilent = 0;
+ }
+ } else {
+ if (!notsilent) {
+ /* Heard some audio, mark the begining of the token */
+ start = ast_tvnow();
+ ast_debug(1, "Start of voice token!\n");
+ notsilent = 1;
}
-
}
- ast_frfree(fr);
}
- ast_sched_runq(chan->sched);
+ ast_frfree(fr);
}
- ast_stopstream(chan);
- } else {
- ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
- res = 0;
+ ast_sched_runq(chan->sched);
}
- }
+ ast_stopstream(chan);
+ } while (0);
+
if (res > -1) {
if (origrformat && ast_set_read_format(chan, origrformat)) {
ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n",
diff --git a/apps/app_url.c b/apps/app_url.c
index 46db0d37e..e0ec68e44 100644
--- a/apps/app_url.c
+++ b/apps/app_url.c
@@ -42,6 +42,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/translate.h"
#include "asterisk/image.h"
#include "asterisk/options.h"
+#include "asterisk/app.h"
static char *app = "SendURL";
@@ -56,22 +57,32 @@ static char *descrip =
" NOLOAD Client failed to load URL (wait enabled)\n"
" UNSUPPORTED Channel does not support URL transport\n"
"\n"
-"If the option 'wait' is specified, execution will wait for an\n"
+"If the option 'w' is specified, execution will wait for an\n"
"acknowledgement that the URL has been loaded before continuing\n"
"\n"
"SendURL continues normally if the URL was sent correctly or if the channel\n"
"does not support HTML transport. Otherwise, the channel is hung up.\n";
+enum {
+ OPTION_WAIT = (1 << 0),
+} option_flags;
+
+AST_APP_OPTIONS(app_opts,{
+ AST_APP_OPTION('w', OPTION_WAIT),
+});
static int sendurl_exec(struct ast_channel *chan, void *data)
{
int res = 0;
char *tmp;
- char *options;
- int local_option_wait=0;
struct ast_frame *f;
- char *stringp=NULL;
char *status = "FAILURE";
+ char *opts[0];
+ struct ast_flags flags;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(url);
+ AST_APP_ARG(options);
+ );
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "SendURL requires an argument (URL)\n");
@@ -81,24 +92,22 @@ static int sendurl_exec(struct ast_channel *chan, void *data)
tmp = ast_strdupa(data);
- stringp=tmp;
- strsep(&stringp, "|");
- options = strsep(&stringp, "|");
- if (options && !strcasecmp(options, "wait"))
- local_option_wait = 1;
+ AST_STANDARD_APP_ARGS(args, tmp);
+ if (args.argc == 2)
+ ast_app_parse_options(app_opts, &flags, opts, args.options);
if (!ast_channel_supports_html(chan)) {
/* Does not support transport */
pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", "UNSUPPORTED");
return 0;
}
- res = ast_channel_sendurl(chan, tmp);
+ res = ast_channel_sendurl(chan, args.url);
if (res == -1) {
pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", "FAILURE");
return res;
}
status = "SUCCESS";
- if (local_option_wait) {
+ if (ast_test_flag(&flags, OPTION_WAIT)) {
for(;;) {
/* Wait for an event */
res = ast_waitfor(chan, -1);
@@ -120,7 +129,7 @@ static int sendurl_exec(struct ast_channel *chan, void *data)
break;
case AST_HTML_NOSUPPORT:
/* Does not support transport */
- status ="UNSUPPORTED";
+ status = "UNSUPPORTED";
res = 0;
ast_frfree(f);
goto out;
diff --git a/apps/app_verbose.c b/apps/app_verbose.c
index e4808b49d..97e441afc 100644
--- a/apps/app_verbose.c
+++ b/apps/app_verbose.c
@@ -38,55 +38,61 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
+#include "asterisk/app.h"
static char *app_verbose = "Verbose";
static char *verbose_synopsis = "Send arbitrary text to verbose output";
static char *verbose_descrip =
-"Verbose([<level>|]<message>)\n"
+"Verbose([<level>,]<message>)\n"
" level must be an integer value. If not specified, defaults to 0.\n";
static char *app_log = "Log";
static char *log_synopsis = "Send arbitrary text to a selected log level";
static char *log_descrip =
-"Log(<level>|<message>)\n"
+"Log(<level>,<message>)\n"
" level must be one of ERROR, WARNING, NOTICE, DEBUG, VERBOSE, DTMF\n";
static int verbose_exec(struct ast_channel *chan, void *data)
{
- char *vtext, *tmp;
int vsize;
+ char *parse;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(level);
+ AST_APP_ARG(msg);
+ );
- if (ast_strlen_zero(data))
+ if (ast_strlen_zero(data)) {
return 0;
-
- vtext = ast_strdupa(data);
- tmp = strsep(&vtext, "|");
- if (vtext) {
- if (sscanf(tmp, "%d", &vsize) != 1) {
- vsize = 0;
- ast_log(LOG_WARNING, "'%s' is not a verboser number\n", vtext);
- }
- } else {
- vtext = tmp;
+ }
+
+ parse = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parse);
+ if (args.argc == 1) {
+ args.msg = args.level;
+ args.level = "0";
+ }
+
+ if (sscanf(args.level, "%d", &vsize) != 1) {
vsize = 0;
+ ast_log(LOG_WARNING, "'%s' is not a verboser number\n", args.level);
}
if (option_verbose >= vsize) {
switch (vsize) {
case 0:
- ast_verbose("%s\n", vtext);
+ ast_verbose("%s\n", args.msg);
break;
case 1:
- ast_verbose(VERBOSE_PREFIX_1 "%s\n", vtext);
+ ast_verbose(VERBOSE_PREFIX_1 "%s\n", args.msg);
break;
case 2:
- ast_verbose(VERBOSE_PREFIX_2 "%s\n", vtext);
+ ast_verbose(VERBOSE_PREFIX_2 "%s\n", args.msg);
break;
case 3:
- ast_verbose(VERBOSE_PREFIX_3 "%s\n", vtext);
+ ast_verbose(VERBOSE_PREFIX_3 "%s\n", args.msg);
break;
default:
- ast_verbose(VERBOSE_PREFIX_4 "%s\n", vtext);
+ ast_verbose(VERBOSE_PREFIX_4 "%s\n", args.msg);
}
}
@@ -95,40 +101,43 @@ static int verbose_exec(struct ast_channel *chan, void *data)
static int log_exec(struct ast_channel *chan, void *data)
{
- char *level, *ltext;
+ char *parse;
int lnum = -1;
char extension[AST_MAX_EXTENSION + 5], context[AST_MAX_EXTENSION + 2];
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(level);
+ AST_APP_ARG(msg);
+ );
if (ast_strlen_zero(data))
return 0;
- ltext = ast_strdupa(data);
-
- level = strsep(&ltext, "|");
+ parse = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parse);
- if (!strcasecmp(level, "ERROR")) {
+ if (!strcasecmp(args.level, "ERROR")) {
lnum = __LOG_ERROR;
- } else if (!strcasecmp(level, "WARNING")) {
+ } else if (!strcasecmp(args.level, "WARNING")) {
lnum = __LOG_WARNING;
- } else if (!strcasecmp(level, "NOTICE")) {
+ } else if (!strcasecmp(args.level, "NOTICE")) {
lnum = __LOG_NOTICE;
- } else if (!strcasecmp(level, "DEBUG")) {
+ } else if (!strcasecmp(args.level, "DEBUG")) {
lnum = __LOG_DEBUG;
- } else if (!strcasecmp(level, "VERBOSE")) {
+ } else if (!strcasecmp(args.level, "VERBOSE")) {
lnum = __LOG_VERBOSE;
- } else if (!strcasecmp(level, "DTMF")) {
+ } else if (!strcasecmp(args.level, "DTMF")) {
lnum = __LOG_DTMF;
- } else if (!strcasecmp(level, "EVENT")) {
+ } else if (!strcasecmp(args.level, "EVENT")) {
lnum = __LOG_EVENT;
} else {
- ast_log(LOG_ERROR, "Unknown log level: '%s'\n", level);
+ ast_log(LOG_ERROR, "Unknown log level: '%s'\n", args.level);
}
if (lnum > -1) {
snprintf(context, sizeof(context), "@ %s", chan->context);
snprintf(extension, sizeof(extension), "Ext. %s", chan->exten);
- ast_log(lnum, extension, chan->priority, context, "%s\n", ltext);
+ ast_log(lnum, extension, chan->priority, context, "%s\n", args.msg);
}
return 0;
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index f12c5cb45..de3b72dc5 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -7465,8 +7465,8 @@ static int vmauthenticate(struct ast_channel *chan, void *data)
if (s) {
s = ast_strdupa(s);
- user = strsep(&s, "|");
- options = strsep(&s, "|");
+ user = strsep(&s, ",");
+ options = strsep(&s, ",");
if (user) {
s = user;
user = strsep(&s, "@");
@@ -8159,7 +8159,7 @@ static int load_config(void)
stringp = ast_strdupa(s);
for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
if (!ast_strlen_zero(stringp)) {
- q = strsep(&stringp,",");
+ q = strsep(&stringp, ",");
while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
q++;
ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
diff --git a/apps/app_zapras.c b/apps/app_zapras.c
index 5456ffb29..95b34d820 100644
--- a/apps/app_zapras.c
+++ b/apps/app_zapras.c
@@ -68,7 +68,7 @@ static char *descrip =
"The channel must be a clear channel (i.e. PRI source) and a Zaptel\n"
"channel to be able to use this function (No modem emulation is included).\n"
"Your pppd must be patched to be zaptel aware. Arguments should be\n"
-"separated by | characters.\n";
+"separated by , characters.\n";
#define PPP_MAX_ARGS 32
@@ -122,10 +122,10 @@ static pid_t spawn_ras(struct ast_channel *chan, char *args)
/* And all the other arguments */
stringp=args;
- c = strsep(&stringp, "|");
+ c = strsep(&stringp, ",");
while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
argv[argc++] = c;
- c = strsep(&stringp, "|");
+ c = strsep(&stringp, ",");
}
argv[argc++] = "plugin";
diff --git a/channels/chan_local.c b/channels/chan_local.c
index b4072cecc..3d814d177 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -608,8 +608,8 @@ static struct ast_channel *local_new(struct local_pvt *p, int state)
ama = p->owner->amaflags;
else
ama = 0;
- if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x,1", p->exten, p->context, randnum))
- || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x,2", p->exten, p->context, randnum))) {
+ if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x;1", p->exten, p->context, randnum))
+ || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x;2", p->exten, p->context, randnum))) {
if (tmp)
ast_channel_free(tmp);
if (tmp2)
diff --git a/funcs/func_callerid.c b/funcs/func_callerid.c
index 462f887b5..f218c8edd 100644
--- a/funcs/func_callerid.c
+++ b/funcs/func_callerid.c
@@ -63,10 +63,10 @@ static int callerid_read(struct ast_channel *chan, const char *cmd, char *data,
if (!chan)
return -1;
- if (strchr(opt, '|')) {
+ if (strchr(opt, ',')) {
char name[80], num[80];
- data = strsep(&opt, "|");
+ data = strsep(&opt, ",");
ast_callerid_split(opt, name, sizeof(name), num, sizeof(num));
if (!strncasecmp("all", data, 3)) {
diff --git a/funcs/func_cut.c b/funcs/func_cut.c
index 41710b978..4466e3269 100644
--- a/funcs/func_cut.c
+++ b/funcs/func_cut.c
@@ -78,7 +78,7 @@ static int sort_internal(struct ast_channel *chan, char *data, char *buffer, siz
strings = ast_strdupa(data);
for (ptrkey = strings; *ptrkey; ptrkey++) {
- if (*ptrkey == '|')
+ if (*ptrkey == ',')
count++;
}
@@ -88,7 +88,7 @@ static int sort_internal(struct ast_channel *chan, char *data, char *buffer, siz
/* Parse each into a struct */
count2 = 0;
- while ((ptrkey = strsep(&strings, "|"))) {
+ while ((ptrkey = strsep(&strings, ","))) {
ptrvalue = index(ptrkey, ':');
if (!ptrvalue) {
count--;
diff --git a/funcs/func_env.c b/funcs/func_env.c
index 20af01636..3e69666ce 100644
--- a/funcs/func_env.c
+++ b/funcs/func_env.c
@@ -76,7 +76,7 @@ static int stat_read(struct ast_channel *chan, const char *cmd, char *data,
*buf = '\0';
- action = strsep(&data, "|");
+ action = strsep(&data, ",");
if (stat(data, &s)) {
return -1;
} else {
diff --git a/funcs/func_logic.c b/funcs/func_logic.c
index 24080cc37..92c4f8b17 100644
--- a/funcs/func_logic.c
+++ b/funcs/func_logic.c
@@ -140,6 +140,29 @@ static int set(struct ast_channel *chan, const char *cmd, char *data, char *buf,
return 0;
}
+static int acf_import(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(channel);
+ AST_APP_ARG(varname);
+ );
+ AST_STANDARD_APP_ARGS(args, data);
+ memset(buf, 0, len);
+
+ if (!ast_strlen_zero(args.varname)) {
+ struct ast_channel *chan2 = ast_get_channel_by_name_locked(args.channel);
+ if (chan2) {
+ char *s = alloca(strlen(args.varname) + 4);
+ if (s) {
+ sprintf(s, "${%s}", args.varname);
+ pbx_substitute_variables_helper(chan2, s, buf, len);
+ }
+ ast_channel_unlock(chan2);
+ }
+ }
+ return 0;
+}
+
static struct ast_custom_function isnull_function = {
.name = "ISNULL",
.synopsis = "NULL Test: Returns 1 if NULL or 0 otherwise",
@@ -164,7 +187,7 @@ static struct ast_custom_function exists_function = {
static struct ast_custom_function if_function = {
.name = "IF",
.synopsis =
- "Conditional: Returns the data following '?' if true else the data following ':'",
+ "Conditional: Returns the data following '?' if true, else the data following ':'",
.syntax = "IF(<expr>?[<true>][:<false>])",
.read = acf_if,
};
@@ -172,11 +195,19 @@ static struct ast_custom_function if_function = {
static struct ast_custom_function if_time_function = {
.name = "IFTIME",
.synopsis =
- "Temporal Conditional: Returns the data following '?' if true else the data following ':'",
+ "Temporal Conditional: Returns the data following '?' if true, else the data following ':'",
.syntax = "IFTIME(<timespec>?[<true>][:<false>])",
.read = iftime,
};
+static struct ast_custom_function import_function = {
+ .name = "IMPORT",
+ .synopsis =
+ "Retrieve the value of a variable from another channel\n",
+ .syntax = "IMPORT(channel,variable)",
+ .read = acf_import,
+};
+
static int unload_module(void)
{
int res = 0;
@@ -186,6 +217,7 @@ static int unload_module(void)
res |= ast_custom_function_unregister(&exists_function);
res |= ast_custom_function_unregister(&if_function);
res |= ast_custom_function_unregister(&if_time_function);
+ res |= ast_custom_function_unregister(&import_function);
return res;
}
@@ -199,6 +231,7 @@ static int load_module(void)
res |= ast_custom_function_register(&exists_function);
res |= ast_custom_function_register(&if_function);
res |= ast_custom_function_register(&if_time_function);
+ res |= ast_custom_function_register(&import_function);
return res;
}
diff --git a/funcs/func_odbc.c b/funcs/func_odbc.c
index 4852a0867..2eac1eeb9 100644
--- a/funcs/func_odbc.c
+++ b/funcs/func_odbc.c
@@ -179,8 +179,7 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
}
/* Parse values, just like arguments */
- /* Can't use the pipe, because app Set removes them */
- AST_NONSTANDARD_APP_ARGS(values, t, ',');
+ AST_STANDARD_APP_ARGS(values, t);
for (i = 0; i < values.argc; i++) {
snprintf(varname, sizeof(varname), "VAL%d", i + 1);
pbx_builtin_pushvar_helper(chan, varname, values.field[i]);
diff --git a/funcs/func_rand.c b/funcs/func_rand.c
index 8885904a9..d989b0ad6 100644
--- a/funcs/func_rand.c
+++ b/funcs/func_rand.c
@@ -76,11 +76,11 @@ static int acf_rand_exec(struct ast_channel *chan, const char *cmd,
static struct ast_custom_function acf_rand = {
.name = "RAND",
.synopsis = "Choose a random number in a range",
- .syntax = "RAND([min][|max])",
+ .syntax = "RAND([min][,max])",
.desc =
"Choose a random number between min and max. Min defaults to 0, if not\n"
"specified, while max defaults to RAND_MAX (2147483647 on many systems).\n"
- " Example: Set(junky=${RAND(1|8)}); \n"
+ " Example: Set(junky=${RAND(1,8)}); \n"
" Sets junky to a random number between 1 and 8, inclusive.\n",
.read = acf_rand_exec,
};
diff --git a/funcs/func_realtime.c b/funcs/func_realtime.c
index 611e6ecc6..1f67fcb46 100644
--- a/funcs/func_realtime.c
+++ b/funcs/func_realtime.c
@@ -60,14 +60,14 @@ static int function_realtime_read(struct ast_channel *chan, const char *cmd, cha
);
if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Syntax: REALTIME(family|fieldmatch[|value[|delim1[|delim2]]]) - missing argument!\n");
+ ast_log(LOG_WARNING, "Syntax: REALTIME(family,fieldmatch[,value[,delim1[,delim2]]]) - missing argument!\n");
return -1;
}
AST_STANDARD_APP_ARGS(args, data);
if (!args.delim1)
- args.delim1 = "|";
+ args.delim1 = ",";
if (!args.delim2)
args.delim2 = "=";
@@ -102,7 +102,7 @@ static int function_realtime_write(struct ast_channel *chan, const char *cmd, ch
);
if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Syntax: REALTIME(family|fieldmatch|value|newcol) - missing argument!\n");
+ ast_log(LOG_WARNING, "Syntax: REALTIME(family,fieldmatch,value,newcol) - missing argument!\n");
return -1;
}
@@ -120,14 +120,14 @@ static int function_realtime_write(struct ast_channel *chan, const char *cmd, ch
struct ast_custom_function realtime_function = {
.name = "REALTIME",
.synopsis = "RealTime Read/Write Functions",
- .syntax = "REALTIME(family|fieldmatch[|value[|delim1[|delim2]]]) on read\n"
- "REALTIME(family|fieldmatch|value|field) on write\n",
+ .syntax = "REALTIME(family,fieldmatch[,value[,delim1[,delim2]]]) on read\n"
+ "REALTIME(family,fieldmatch,value,field) on write",
.desc = "This function will read or write values from/to a RealTime repository.\n"
"REALTIME(....) will read names/values from the repository, and \n"
"REALTIME(....)= will write a new value/field to the repository. On a\n"
"read, this function returns a delimited text string. The name/value \n"
"pairs are delimited by delim1, and the name and value are delimited \n"
- "between each other with delim2. The default for delim1 is '|' and \n"
+ "between each other with delim2. The default for delim1 is ',' and \n"
"the default for delim2 is '='. If there is no match, NULL will be \n"
"returned by the function. On a write, this function will always \n"
"return NULL. \n",
diff --git a/funcs/func_strings.c b/funcs/func_strings.c
index c44c49921..5eab9930f 100644
--- a/funcs/func_strings.c
+++ b/funcs/func_strings.c
@@ -88,7 +88,7 @@ static int function_fieldqty(struct ast_channel *chan, const char *cmd,
static struct ast_custom_function fieldqty_function = {
.name = "FIELDQTY",
.synopsis = "Count the fields, with an arbitrary delimiter",
- .syntax = "FIELDQTY(<varname>|<delim>)",
+ .syntax = "FIELDQTY(<varname>,<delim>)",
.read = function_fieldqty,
};
@@ -104,7 +104,7 @@ static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *
AST_STANDARD_APP_ARGS(args, parse);
if (!args.string) {
- ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>|<string>)\n");
+ ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>,<string>)\n");
return -1;
}
@@ -120,7 +120,7 @@ static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *
static struct ast_custom_function filter_function = {
.name = "FILTER",
.synopsis = "Filter the string to include only the allowed characters",
- .syntax = "FILTER(<allowed-chars>|<string>)",
+ .syntax = "FILTER(<allowed-chars>,<string>)",
.read = filter,
};
@@ -237,15 +237,9 @@ static int array(struct ast_channel *chan, const char *cmd, char *var,
* delimiter, but we'll fall back to vertical bars if commas aren't found.
*/
ast_debug(1, "array (%s=%s)\n", var, value2);
- if (strchr(var, ','))
- AST_NONSTANDARD_APP_ARGS(arg1, var, ',');
- else
- AST_STANDARD_APP_ARGS(arg1, var);
+ AST_STANDARD_APP_ARGS(arg1, var);
- if (strchr(value2, ','))
- AST_NONSTANDARD_APP_ARGS(arg2, value2, ',');
- else
- AST_STANDARD_APP_ARGS(arg2, value2);
+ AST_STANDARD_APP_ARGS(arg2, value2);
for (i = 0; i < arg1.argc; i++) {
ast_debug(1, "array set value (%s=%s)\n", arg1.var[i],
@@ -302,7 +296,7 @@ static int hash_write(struct ast_channel *chan, const char *cmd, char *var, cons
AST_APP_ARG(hashkey);
);
- if (!strchr(var, '|')) {
+ if (!strchr(var, ',')) {
/* Single argument version */
return array(chan, "HASH", var, value);
}
@@ -363,7 +357,7 @@ static int hash_read(struct ast_channel *chan, const char *cmd, char *data, char
static struct ast_custom_function hash_function = {
.name = "HASH",
.synopsis = "Implementation of a dialplan associative array",
- .syntax = "HASH(hashname[|hashkey])",
+ .syntax = "HASH(hashname[,hashkey])",
.write = hash_write,
.read = hash_read,
.desc =
@@ -387,15 +381,13 @@ static struct ast_custom_function hashkeys_function = {
static struct ast_custom_function array_function = {
.name = "ARRAY",
.synopsis = "Allows setting multiple variables at once",
- .syntax = "ARRAY(var1[|var2[...][|varN]])",
+ .syntax = "ARRAY(var1[,var2[...][,varN]])",
.write = array,
.desc =
"The comma-separated list passed as a value to which the function is set will\n"
"be interpreted as a set of values to which the comma-separated list of\n"
"variable names in the argument should be set.\n"
- "Hence, Set(ARRAY(var1|var2)=1\\,2) will set var1 to 1 and var2 to 2\n"
- "Note: remember to either backslash your commas in extensions.conf or quote the\n"
- "entire argument, since Set can take multiple arguments itself.\n",
+ "Hence, Set(ARRAY(var1,var2)=1,2) will set var1 to 1 and var2 to 2.\n",
};
static int acf_sprintf(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
@@ -533,7 +525,7 @@ sprintf_fail:
static struct ast_custom_function sprintf_function = {
.name = "SPRINTF",
.synopsis = "Format a variable according to a format string",
- .syntax = "SPRINTF(<format>|<arg1>[|...<argN>])",
+ .syntax = "SPRINTF(<format>,<arg1>[,...<argN>])",
.read = acf_sprintf,
.desc =
"Parses the format string specified and returns a string matching that format.\n"
@@ -623,7 +615,7 @@ static int acf_strftime(struct ast_channel *chan, const char *cmd, char *parse,
static struct ast_custom_function strftime_function = {
.name = "STRFTIME",
.synopsis = "Returns the current date/time in a specified format.",
- .syntax = "STRFTIME([<epoch>][|[timezone][|format]])",
+ .syntax = "STRFTIME([<epoch>][,[timezone][,format]])",
.desc =
"STRFTIME sports all of the same formats as the underlying C function\n"
"strftime(3) - see the man page for details. It also supports the\n"
@@ -660,7 +652,7 @@ static int acf_strptime(struct ast_channel *chan, const char *cmd, char *data,
if (ast_strlen_zero(args.format)) {
ast_log(LOG_ERROR,
- "No format supplied to STRPTIME(<timestring>|<timezone>|<format>)");
+ "No format supplied to STRPTIME(<timestring>,<timezone>,<format>)");
return -1;
}
@@ -677,14 +669,14 @@ static struct ast_custom_function strptime_function = {
.name = "STRPTIME",
.synopsis =
"Returns the epoch of the arbitrary date/time string structured as described in the format.",
- .syntax = "STRPTIME(<datetime>|<timezone>|<format>)",
+ .syntax = "STRPTIME(<datetime>,<timezone>,<format>)",
.desc =
"This is useful for converting a date into an EPOCH time, possibly to pass to\n"
"an application like SayUnixTime or to calculate the difference between two\n"
"date strings.\n"
"\n"
"Example:\n"
- " ${STRPTIME(2006-03-01 07:30:35|America/Chicago|%Y-%m-%d %H:%M:%S)} returns 1141219835\n",
+ " ${STRPTIME(2006-03-01 07:30:35,America/Chicago,%Y-%m-%d %H:%M:%S)} returns 1141219835\n",
.read = acf_strptime,
};
diff --git a/funcs/func_vmcount.c b/funcs/func_vmcount.c
index 8183b8c74..0e6cfef1e 100644
--- a/funcs/func_vmcount.c
+++ b/funcs/func_vmcount.c
@@ -76,7 +76,7 @@ static int acf_vmcount_exec(struct ast_channel *chan, const char *cmd, char *arg
struct ast_custom_function acf_vmcount = {
.name = "VMCOUNT",
.synopsis = "Counts the voicemail in a specified mailbox",
- .syntax = "VMCOUNT(vmbox[@context][|folder])",
+ .syntax = "VMCOUNT(vmbox[@context][,folder])",
.desc =
" context - defaults to \"default\"\n"
" folder - defaults to \"INBOX\"\n",
diff --git a/include/asterisk/app.h b/include/asterisk/app.h
index 1fb0e04eb..1d3fcdfb5 100644
--- a/include/asterisk/app.h
+++ b/include/asterisk/app.h
@@ -289,7 +289,7 @@ int ast_app_group_list_unlock(void);
the argc argument counter field.
*/
#define AST_STANDARD_APP_ARGS(args, parse) \
- args.argc = ast_app_separate_args(parse, '|', args.argv, (sizeof(args) - sizeof(args.argc)) / sizeof(args.argv[0]))
+ args.argc = ast_app_separate_args(parse, ',', args.argv, (sizeof(args) - sizeof(args.argc)) / sizeof(args.argv[0]))
/*!
\brief Performs the 'nonstandard' argument separation process for an application.
diff --git a/main/pbx.c b/main/pbx.c
index bb9692ab1..34b3eeeb9 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -303,7 +303,7 @@ static struct pbx_builtin {
{ "BackGround", pbx_builtin_background,
"Play an audio file while waiting for digits of an extension to go to.",
- " Background(filename1[&filename2...][|options[|langoverride][|context]]):\n"
+ " Background(filename1[&filename2...][,options[,langoverride][,context]]):\n"
"This application will play the given list of files while waiting for an\n"
"extension to be dialed by the calling channel. To continue waiting for digits\n"
"after this application has finished playing files, the WaitExten application\n"
@@ -344,14 +344,14 @@ static struct pbx_builtin {
{ "ExecIfTime", pbx_builtin_execiftime,
"Conditional application execution based on the current time",
- " ExecIfTime(<times>|<weekdays>|<mdays>|<months>?appname[|appargs]):\n"
+ " ExecIfTime(<times>,<weekdays>,<mdays>,<months>?appname[(appargs)]):\n"
"This application will execute the specified dialplan application, with optional\n"
"arguments, if the current time matches the given time specification.\n"
},
{ "Goto", pbx_builtin_goto,
"Jump to a particular priority, extension, or context",
- " Goto([[context|]extension|]priority): This application will set the current\n"
+ " Goto([[context,]extension,]priority): This application will set the current\n"
"context, extension, and priority in the channel structure. After it completes, the\n"
"pbx engine will continue dialplan execution at the specified location.\n"
"If no specific extension, or extension and context, are specified, then this\n"
@@ -391,7 +391,7 @@ static struct pbx_builtin {
{ "GotoIfTime", pbx_builtin_gotoiftime,
"Conditional Goto based on the current time",
- " GotoIfTime(<times>|<weekdays>|<mdays>|<months>?[[context|]exten|]priority):\n"
+ " GotoIfTime(<times>,<weekdays>,<mdays>,<months>?[[context,]exten,]priority):\n"
"This application will set the context, extension, and priority in the channel structure\n"
"if the current time matches the given time specification. Otherwise, nothing is done.\n"
"Further information on the time specification can be found in examples\n"
@@ -401,7 +401,7 @@ static struct pbx_builtin {
{ "ImportVar", pbx_builtin_importvar,
"Import a variable from a channel into a new variable",
- " ImportVar(newvar=channelname|variable): This application imports a variable\n"
+ " ImportVar(newvar=channelname,variable): This application imports a variable\n"
"from the specified channel (as opposed to the current one) and stores it as\n"
"a variable in the current channel (the channel that is calling this\n"
"application). Variables created by this application have the same inheritance\n"
@@ -476,16 +476,13 @@ static struct pbx_builtin {
{ "Set", pbx_builtin_setvar,
"Set channel variable(s) or function value(s)",
- " Set(name1=value1|name2=value2|..[|options])\n"
+ " Set(name1=value1)\n"
"This function can be used to set the value of channel variables or dialplan\n"
"functions. It will accept up to 24 name/value pairs. When setting variables,\n"
"if the variable name is prefixed with _, the variable will be inherited into\n"
"channels created from the current channel. If the variable name is prefixed\n"
"with __, the variable will be inherited into channels created from the current\n"
"channel and all children channels.\n"
- " Options:\n"
- " g - Set variable globally instead of on the channel\n"
- " (applies only to variables, not functions)\n"
},
{ "SetAMAFlags", pbx_builtin_setamaflags,
@@ -504,7 +501,7 @@ static struct pbx_builtin {
{ "WaitExten", pbx_builtin_waitexten,
"Waits for an extension to be entered",
- " WaitExten([seconds][|options]): This application waits for the user to enter\n"
+ " WaitExten([seconds][,options]): This application waits for the user to enter\n"
"a new extension for a specified number of seconds.\n"
" Note that the seconds can be passed with fractions of a second. For example,\n"
"'1.5' will ask the application to wait for 1.5 seconds.\n"
@@ -4252,13 +4249,13 @@ int ast_build_timing(struct ast_timing *i, const char *info_in)
i->daymask = 0x7fffffffU; /* 31 bits */
i->dowmask = 0x7f; /* 7 bits */
/* on each call, use strsep() to move info to the next argument */
- get_timerange(i, strsep(&info, "|"));
+ get_timerange(i, strsep(&info, "|,"));
if (info)
- i->dowmask = get_range(strsep(&info, "|"), 7, days, "day of week");
+ i->dowmask = get_range(strsep(&info, "|,"), 7, days, "day of week");
if (info)
- i->daymask = get_range(strsep(&info, "|"), 31, NULL, "day");
+ i->daymask = get_range(strsep(&info, "|,"), 31, NULL, "day");
if (info)
- i->monthmask = get_range(strsep(&info, "|"), 12, months, "month");
+ i->monthmask = get_range(strsep(&info, "|,"), 12, months, "month");
return 1;
}
@@ -4329,7 +4326,7 @@ int ast_context_add_include2(struct ast_context *con, const char *value,
new_include->rname = p;
strcpy(p, value);
/* Strip off timing info, and process if it is there */
- if ( (c = strchr(p, '|')) ) {
+ if ( (c = strchr(p, ',')) ) {
*c++ = '\0';
new_include->hastime = ast_build_timing(&(new_include->timing), c);
}
@@ -5499,14 +5496,14 @@ static int pbx_builtin_gotoiftime(struct ast_channel *chan, void *data)
struct ast_timing timing;
if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n <time range>|<days of week>|<days of month>|<months>?[[context|]extension|]priority\n");
+ ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>?[[context,]extension,]priority\n");
return -1;
}
ts = s = ast_strdupa(data);
/* Separate the Goto path */
- strsep(&ts,"?");
+ strsep(&ts, "?");
/* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
if (ast_build_timing(&timing, s) && ast_check_timing(&timing))
@@ -5523,7 +5520,7 @@ static int pbx_builtin_execiftime(struct ast_channel *chan, void *data)
char *s, *appname;
struct ast_timing timing;
struct ast_app *app;
- static const char *usage = "ExecIfTime requires an argument:\n <time range>|<days of week>|<days of month>|<months>?<appname>[|<appargs>]";
+ static const char *usage = "ExecIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>?<appname>[(<appargs>)]";
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "%s\n", usage);
@@ -5532,7 +5529,7 @@ static int pbx_builtin_execiftime(struct ast_channel *chan, void *data)
appname = ast_strdupa(data);
- s = strsep(&appname,"?"); /* Separate the timerange and application name/data */
+ s = strsep(&appname, "?"); /* Separate the timerange and application name/data */
if (!appname) { /* missing application */
ast_log(LOG_WARNING, "%s\n", usage);
return -1;
@@ -5546,9 +5543,16 @@ static int pbx_builtin_execiftime(struct ast_channel *chan, void *data)
if (!ast_check_timing(&timing)) /* outside the valid time window, just return */
return 0;
- /* now split appname|appargs */
- if ((s = strchr(appname, '|')))
+ /* now split appname(appargs) */
+ if ((s = strchr(appname, '('))) {
+ char *e;
*s++ = '\0';
+ if ((e = strrchr(s, ')')))
+ *e = '\0';
+ else
+ ast_log(LOG_WARNING, "Failed to find closing parenthesis\n");
+ }
+
if ((app = pbx_findapp(appname))) {
return pbx_exec(chan, app, S_OR(s, ""));
@@ -5568,7 +5572,7 @@ static int pbx_builtin_wait(struct ast_channel *chan, void *data)
/* Wait for "n" seconds */
if (data && (s = atof(data)) > 0.0) {
- ms = s*1000.0;
+ ms = s * 1000.0;
return ast_safe_sleep(chan, ms);
}
return 0;
@@ -5720,7 +5724,7 @@ static int pbx_builtin_goto(struct ast_channel *chan, void *data)
{
int res = ast_parseable_goto(chan, data);
if (!res)
- ast_verb(3, "Goto (%s,%s,%d)\n", chan->context,chan->exten, chan->priority+1);
+ ast_verb(3, "Goto (%s,%s,%d)\n", chan->context, chan->exten, chan->priority + 1);
return res;
}
@@ -5738,7 +5742,7 @@ int pbx_builtin_serialize_variables(struct ast_channel *chan, struct ast_str **b
(*buf)->str[0] = '\0';
AST_LIST_TRAVERSE(&chan->varshead, variables, entries) {
- if ((var=ast_var_name(variables)) && (val=ast_var_value(variables))
+ if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))
/* && !ast_strlen_zero(var) && !ast_strlen_zero(val) */
) {
if (ast_str_append(buf, 0, "%s=%s\n", var, val) < 0) {
@@ -5819,7 +5823,7 @@ void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const
const char *nametail = name;
/* XXX may need locking on the channel ? */
- if (name[strlen(name)-1] == ')') {
+ if (name[strlen(name) - 1] == ')') {
char *function = ast_strdupa(name);
ast_func_write(chan, function, value);
@@ -5867,35 +5871,17 @@ void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const
int pbx_builtin_setvar(struct ast_channel *chan, void *data)
{
char *name, *value, *mydata;
- int argc;
- char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */
- int global = 0;
- int x;
if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
+ ast_log(LOG_WARNING, "Set requires one variable name/value pair.\n");
return 0;
}
mydata = ast_strdupa(data);
- argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
-
- /* check for a trailing flags argument */
- if ((argc > 1) && !strchr(argv[argc-1], '=')) {
- argc--;
- if (strchr(argv[argc], 'g'))
- global = 1;
- }
-
- for (x = 0; x < argc; x++) {
- name = argv[x];
- if ((value = strchr(name, '='))) {
- *value++ = '\0';
- pbx_builtin_setvar_helper((global) ? NULL : chan, name, value);
- } else
- ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
- }
+ name = strsep(&mydata, "=");
+ value = mydata;
+ pbx_builtin_setvar_helper(chan, name, value);
return(0);
}
@@ -5905,15 +5891,21 @@ int pbx_builtin_importvar(struct ast_channel *chan, void *data)
char *value;
char *channel;
char tmp[VAR_BUF_SIZE]="";
+ static int deprecation_warning = 0;
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
return 0;
}
+ if (!deprecation_warning) {
+ ast_log(LOG_WARNING, "ImportVar is deprecated. Please use Set(varname=${IMPORT(channel,variable)}) instead.\n");
+ deprecation_warning = 1;
+ }
+
value = ast_strdupa(data);
name = strsep(&value,"=");
- channel = strsep(&value,"|");
+ channel = strsep(&value,",");
if (channel && value && name) { /*! \todo XXX should do !ast_strlen_zero(..) of the args ? */
struct ast_channel *chan2 = ast_get_channel_by_name_locked(channel);
if (chan2) {
@@ -5958,7 +5950,6 @@ int pbx_checkcondition(const char *condition)
static int pbx_builtin_gotoif(struct ast_channel *chan, void *data)
{
char *condition, *branch1, *branch2, *branch;
- int rc;
char *stringp;
if (ast_strlen_zero(data)) {
@@ -5977,9 +5968,7 @@ static int pbx_builtin_gotoif(struct ast_channel *chan, void *data)
return 0;
}
- rc = pbx_builtin_goto(chan, branch);
-
- return rc;
+ return pbx_builtin_goto(chan, branch);
}
static int pbx_builtin_saynumber(struct ast_channel *chan, void *data)
@@ -5993,10 +5982,10 @@ static int pbx_builtin_saynumber(struct ast_channel *chan, void *data)
return -1;
}
ast_copy_string(tmp, data, sizeof(tmp));
- strsep(&number, "|");
- options = strsep(&number, "|");
+ strsep(&number, ",");
+ options = strsep(&number, ",");
if (options) {
- if ( strcasecmp(options, "f") && strcasecmp(options,"m") &&
+ if ( strcasecmp(options, "f") && strcasecmp(options, "m") &&
strcasecmp(options, "c") && strcasecmp(options, "n") ) {
ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
return -1;
@@ -6313,13 +6302,13 @@ int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
int mode = 0;
if (ast_strlen_zero(goto_string)) {
- ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
+ ast_log(LOG_WARNING, "Goto requires an argument ([[context,]extension,]priority)\n");
return -1;
}
stringp = ast_strdupa(goto_string);
- context = strsep(&stringp, "|"); /* guaranteed non-null */
- exten = strsep(&stringp, "|");
- pri = strsep(&stringp, "|");
+ context = strsep(&stringp, ","); /* guaranteed non-null */
+ exten = strsep(&stringp, ",");
+ pri = strsep(&stringp, ",");
if (!exten) { /* Only a priority in this one */
pri = context;
exten = NULL;
diff --git a/pbx/pbx_config.c b/pbx/pbx_config.c
index 799892ba9..5a7280c9a 100644
--- a/pbx/pbx_config.c
+++ b/pbx/pbx_config.c
@@ -1386,7 +1386,7 @@ static int pbx_load_config(const char *config_file)
if (tc) {
int ipri = -2;
char realext[256]="";
- char *plus, *firstp, *firstc;
+ char *plus, *firstp;
char *pri, *appl, *data, *cidmatch;
char *stringp = tc;
char *ext = strsep(&stringp, ",");
@@ -1433,19 +1433,12 @@ static int pbx_load_config(const char *config_file)
ipri = 0;
}
appl = S_OR(stringp, "");
- /* Find the first occurrence of either '(' or ',' */
- firstc = strchr(appl, ',');
+ /* Find the first occurrence of '(' */
firstp = strchr(appl, '(');
- if (firstc && (!firstp || firstc < firstp)) {
- /* comma found, no parenthesis */
- /* or both found, but comma found first */
- appl = strsep(&stringp, ",");
- data = stringp;
- } else if (!firstc && !firstp) {
- /* Neither found */
+ if (!firstp) {
+ /* No arguments */
data = "";
} else {
- /* Final remaining case is parenthesis found first */
appl = strsep(&stringp, "(");
data = stringp;
end = strrchr(data, ')');
@@ -1454,11 +1447,10 @@ static int pbx_load_config(const char *config_file)
} else {
ast_log(LOG_WARNING, "No closing parenthesis found? '%s(%s'\n", appl, data);
}
- ast_process_quotes_and_slashes(data, ',', '|');
}
if (!data)
- data="";
+ data = "";
appl = ast_skip_blanks(appl);
if (ipri) {
if (plus)
@@ -1483,7 +1475,7 @@ static int pbx_load_config(const char *config_file)
if (ast_context_add_ignorepat2(con, realvalue, registrar))
ast_log(LOG_WARNING, "Unable to include ignorepat '%s' in context '%s'\n", v->value, cxt);
} else if (!strcasecmp(v->name, "switch") || !strcasecmp(v->name, "lswitch") || !strcasecmp(v->name, "eswitch")) {
- char *stringp= realvalue;
+ char *stringp = realvalue;
char *appl, *data;
memset(realvalue, 0, sizeof(realvalue));
@@ -1492,9 +1484,7 @@ static int pbx_load_config(const char *config_file)
else
ast_copy_string(realvalue, v->value, sizeof(realvalue));
appl = strsep(&stringp, "/");
- data = strsep(&stringp, ""); /* XXX what for ? */
- if (!data)
- data = "";
+ data = S_OR(stringp, "");
if (ast_context_add_switch2(con, appl, data, !strcasecmp(v->name, "eswitch"), registrar))
ast_log(LOG_WARNING, "Unable to include switch '%s' in context '%s'\n", v->value, cxt);
} else {