42 #include "asterisk/stasis_channels.h"
110 AST_RWLOCK_DEFINE_STATIC(globalslock);
125 for (; *var; var++) {
129 }
else if (*var ==
')') {
131 }
else if (*var ==
':' && parens == 0) {
133 sscanf(var,
"%30d:%30d", offset, length);
151 static char *
substring(
const char *value,
int offset,
int length,
char *workspace,
size_t workspace_len)
153 char *ret = workspace;
161 if (offset == 0 && length >= lr)
165 offset = lr + offset;
175 if (length >= 0 && length < lr - offset)
177 else if (length < 0) {
178 if (lr > offset - length)
179 ret[lr + length - offset] =
'\0';
187 static const char *ast_str_substring(
struct ast_str *value,
int offset,
int length)
196 if (offset == 0 && length >= lr)
200 offset = lr + offset;
217 if (length >= 0 && length < lr) {
219 }
else if (length < 0) {
246 *ret = cret ? workspace : NULL;
252 const char not_found =
'\0';
257 int i, need_substring;
258 struct varshead *places[2] = { headp, &globals };
263 places[0] = ast_channel_varshead(c);
291 if (!strncmp(var,
"CALL", 4)) {
292 if (!strncmp(var + 4,
"ING", 3)) {
293 if (!strcmp(var + 7,
"PRES")) {
297 }
else if (!strcmp(var + 7,
"ANI2")) {
298 ast_str_set(str, maxlen,
"%d", ast_channel_caller(c)->ani2);
300 }
else if (!strcmp(var + 7,
"TON")) {
303 }
else if (!strcmp(var + 7,
"TNS")) {
304 ast_str_set(str, maxlen,
"%d", ast_channel_dialed(c)->transit_network_select);
308 }
else if (!strcmp(var,
"HINT")) {
310 }
else if (!strcmp(var,
"HINTNAME")) {
312 }
else if (!strcmp(var,
"EXTEN")) {
313 s = ast_channel_exten(c);
314 }
else if (!strcmp(var,
"CONTEXT")) {
315 s = ast_channel_context(c);
316 }
else if (!strcmp(var,
"PRIORITY")) {
317 ast_str_set(str, maxlen,
"%d", ast_channel_priority(c));
319 }
else if (!strcmp(var,
"CHANNEL")) {
320 s = ast_channel_name(c);
321 }
else if (!strcmp(var,
"UNIQUEID")) {
322 s = ast_channel_uniqueid(c);
323 }
else if (!strcmp(var,
"HANGUPCAUSE")) {
324 ast_str_set(str, maxlen,
"%d", ast_channel_hangupcause(c));
328 if (s == ¬_found) {
329 if (!strcmp(var,
"EPOCH")) {
332 }
else if (!strcmp(var,
"SYSTEMNAME")) {
333 s = ast_config_AST_SYSTEM_NAME;
334 }
else if (!strcmp(var,
"ASTCACHEDIR")) {
335 s = ast_config_AST_CACHE_DIR;
336 }
else if (!strcmp(var,
"ASTETCDIR")) {
337 s = ast_config_AST_CONFIG_DIR;
338 }
else if (!strcmp(var,
"ASTMODDIR")) {
339 s = ast_config_AST_MODULE_DIR;
340 }
else if (!strcmp(var,
"ASTVARLIBDIR")) {
341 s = ast_config_AST_VAR_DIR;
342 }
else if (!strcmp(var,
"ASTDBDIR")) {
343 s = ast_config_AST_DB;
344 }
else if (!strcmp(var,
"ASTKEYDIR")) {
345 s = ast_config_AST_KEY_DIR;
346 }
else if (!strcmp(var,
"ASTDATADIR")) {
347 s = ast_config_AST_DATA_DIR;
348 }
else if (!strcmp(var,
"ASTAGIDIR")) {
349 s = ast_config_AST_AGI_DIR;
350 }
else if (!strcmp(var,
"ASTSPOOLDIR")) {
351 s = ast_config_AST_SPOOL_DIR;
352 }
else if (!strcmp(var,
"ASTRUNDIR")) {
353 s = ast_config_AST_RUN_DIR;
354 }
else if (!strcmp(var,
"ASTLOGDIR")) {
355 s = ast_config_AST_LOG_DIR;
356 }
else if (!strcmp(var,
"ASTSBINDIR")) {
357 s = ast_config_AST_SBIN_DIR;
358 }
else if (!strcmp(var,
"ENTITYID")) {
364 for (i = 0; s == ¬_found && i < ARRAY_LEN(places); i++) {
368 if (places[i] == &globals)
369 ast_rwlock_rdlock(&globalslock);
371 if (!strcmp(ast_var_name(variables), var)) {
372 s = ast_var_value(variables);
376 if (places[i] == &globals)
377 ast_rwlock_unlock(&globalslock);
379 if (s == ¬_found || s == NULL) {
380 ast_debug(5,
"Result of '%s' is NULL\n", var);
383 ast_debug(5,
"Result of '%s' is '%s'\n", var, s);
388 if (need_substring) {
389 ret = ast_str_substring(*str, offset, length);
390 ast_debug(2,
"Final result of '%s' is '%s'\n", var, ret);
395 ast_channel_unlock(c);
402 size_t *used,
int use_both)
405 const char *whereweare;
407 struct ast_str *substr2 = NULL;
412 if (!substr1 || !substr3) {
422 while (!ast_strlen_zero(whereweare)) {
423 const char *nextvar = NULL;
424 const char *nextexp = NULL;
425 const char *nextthing;
438 nextthing = strchr(whereweare,
'$');
440 pos = nextthing - whereweare;
441 switch (nextthing[1]) {
457 pos = strlen(whereweare);
476 vars = vare = nextvar + 2;
481 while (brackets && *vare) {
482 if ((vare[0] ==
'$') && (vare[1] ==
'{')) {
486 }
else if (vare[0] ==
'{') {
488 }
else if (vare[0] ==
'}') {
490 }
else if ((vare[0] ==
'$') && (vare[1] ==
'[')) {
498 ast_log(LOG_WARNING,
"Error in extension logic (missing '}')\n");
509 ast_debug(5,
"Evaluating '%s' (from '%s' len %d)\n",
533 ast_debug(2,
"Function %s result is '%s' from channel\n",
536 if (!c || (c && res < 0 && use_both)) {
542 old = *ast_channel_varshead(bogus);
544 *ast_channel_varshead(bogus) = *headp;
549 *ast_channel_varshead(bogus) = old;
553 ast_log(LOG_ERROR,
"Unable to allocate bogus channel for function value substitution.\n");
556 ast_debug(2,
"Function %s result is '%s' from headp\n",
563 ast_debug(2,
"Variable %s result is '%s' from channel\n",
564 finalvars,
S_OR(result,
""));
566 if (!c || (c && !result && use_both)) {
568 ast_debug(2,
"Variable %s result is '%s' from headp\n",
569 finalvars,
S_OR(result,
""));
571 res = (result ? 0 : -1);
574 ast_str_substring(substr3, offset, offset2);
577 }
else if (nextexp) {
581 vars = vare = nextexp + 2;
586 while (brackets && *vare) {
587 if ((vare[0] ==
'$') && (vare[1] ==
'[')) {
591 }
else if (vare[0] ==
'[') {
593 }
else if (vare[0] ==
']') {
595 }
else if ((vare[0] ==
'$') && (vare[1] ==
'{')) {
603 ast_log(LOG_WARNING,
"Error in extension logic (missing ']')\n");
660 void pbx_substitute_variables_helper_full(
struct ast_channel *c,
struct varshead *headp,
const char *cp1,
char *cp2,
int count,
size_t *used)
668 #define MAX_VARIABLE_SUB_RECURSE_DEPTH 15
673 const char *whereweare;
674 const char *orig_cp2 = cp2;
675 char ltmp[VAR_BUF_SIZE];
676 char var[VAR_BUF_SIZE];
684 if (!recurse_depth) {
687 if ((*recurse_depth)++ >= MAX_VARIABLE_SUB_RECURSE_DEPTH) {
688 ast_log(LOG_ERROR,
"Exceeded maximum variable substitution recursion depth (%d) - possible infinite recursion in dialplan?\n", MAX_VARIABLE_SUB_RECURSE_DEPTH);
694 while (!ast_strlen_zero(whereweare) && count) {
695 char *nextvar = NULL;
696 char *nextexp = NULL;
707 nextthing = strchr(whereweare,
'$');
709 pos = nextthing - whereweare;
710 switch (nextthing[1]) {
726 pos = strlen(whereweare);
735 memcpy(cp2, whereweare, pos);
748 char workspace[VAR_BUF_SIZE] =
"";
753 vars = vare = nextvar + 2;
758 while (brackets && *vare) {
759 if ((vare[0] ==
'$') && (vare[1] ==
'{')) {
763 }
else if (vare[0] ==
'{') {
765 }
else if (vare[0] ==
'}') {
767 }
else if ((vare[0] ==
'$') && (vare[1] ==
'[')) {
775 ast_log(LOG_WARNING,
"Error in extension logic (missing '}')\n");
799 cp4 =
ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
806 old = *ast_channel_varshead(bogus);
807 *ast_channel_varshead(bogus) = *headp;
808 cp4 =
ast_func_read(bogus, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
810 *ast_channel_varshead(bogus) = old;
813 ast_log(LOG_ERROR,
"Unable to allocate bogus channel for function value substitution.\n");
817 ast_debug(2,
"Function %s result is '%s'\n", vars, cp4 ? cp4 :
"(null)");
821 if (exten && !strcmp(vars,
"EXTEN")) {
824 }
else if (context && !strcmp(vars,
"CONTEXT")) {
827 }
else if (pri && !strcmp(vars,
"PRIORITY")) {
828 snprintf(workspace, VAR_BUF_SIZE,
"%d", pri);
835 cp4 =
substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);
837 length = strlen(cp4);
840 memcpy(cp2, cp4, length);
845 }
else if (nextexp) {
849 vars = vare = nextexp + 2;
854 while (brackets && *vare) {
855 if ((vare[0] ==
'$') && (vare[1] ==
'[')) {
859 }
else if (vare[0] ==
'[') {
861 }
else if (vare[0] ==
']') {
863 }
else if ((vare[0] ==
'$') && (vare[1] ==
'{')) {
871 ast_log(LOG_WARNING,
"Error in extension logic (missing ']')\n");
891 length =
ast_expr(vars, cp2, count, c);
893 ast_debug(1,
"Expression result is '%s'\n", cp2);
901 *used = cp2 - orig_cp2;
906 void pbx_substitute_variables_helper(
struct ast_channel *c,
const char *cp1,
char *cp2,
int count)
908 pbx_substitute_variables_helper_full(c, (c) ? ast_channel_varshead(c) : NULL, cp1, cp2, count, NULL);
911 void pbx_substitute_variables_varshead(
struct varshead *headp,
const char *cp1,
char *cp2,
int count)
913 pbx_substitute_variables_helper_full(NULL, headp, cp1, cp2, count, NULL);
924 e->
command =
"dialplan show globals";
926 "Usage: dialplan show globals\n"
927 " List current global dialplan variables and their values\n";
933 ast_rwlock_rdlock(&globalslock);
936 ast_cli(a->fd,
" %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable));
938 ast_rwlock_unlock(&globalslock);
939 ast_cli(a->fd,
"\n -- %d variable(s)\n", i);
952 e->
command =
"dialplan show chanvar";
954 "Usage: dialplan show chanvar <channel>\n"
955 " List current channel variables and their values\n";
961 if (a->argc != e->
args + 1) {
962 return CLI_SHOWUSAGE;
967 ast_cli(a->fd,
"Channel '%s' not found\n", a->argv[e->
args]);
971 ast_channel_lock(chan);
973 ast_cli(a->fd,
"%s=%s\n", ast_var_name(var), ast_var_value(var));
975 ast_channel_unlock(chan);
987 char workspace[1024];
991 e->
command =
"dialplan eval function";
993 "Usage: dialplan eval function <name(args)>\n"
994 " Evaluate a dialplan function call\n"
995 " A dummy channel is used to evaluate\n"
996 " the function call, so only global\n"
997 " variables should be used.\n";
1003 if (a->argc != e->
args + 1) {
1004 return CLI_SHOWUSAGE;
1009 ast_cli(a->fd,
"Unable to allocate bogus channel for function evaluation.\n");
1013 fn = (
char *) a->argv[3];
1014 pbx_substitute_variables_helper(c, fn, workspace,
sizeof(workspace));
1016 workspace[0] =
'\0';
1017 ret =
ast_func_read(c, substituted, workspace,
sizeof(workspace));
1021 ast_cli(a->fd,
"Return Value: %s (%d)\n", ret ?
"Failure" :
"Success", ret);
1022 ast_cli(a->fd,
"Result: %s\n", workspace);
1031 e->
command =
"dialplan set global";
1033 "Usage: dialplan set global <name> <value>\n"
1034 " Set global dialplan variable <name> to <value>\n";
1040 if (a->argc != e->
args + 2)
1041 return CLI_SHOWUSAGE;
1044 ast_cli(a->fd,
"\n -- Global variable '%s' set to '%s'\n", a->argv[3], a->argv[4]);
1052 const char *chan_name, *var_name, *var_value;
1056 e->
command =
"dialplan set chanvar";
1058 "Usage: dialplan set chanvar <channel> <varname> <value>\n"
1059 " Set channel variable <varname> to <value>\n";
1065 if (a->argc != e->
args + 3)
1066 return CLI_SHOWUSAGE;
1068 chan_name = a->argv[e->
args];
1069 var_name = a->argv[e->
args + 1];
1070 var_value = a->argv[e->
args + 2];
1073 ast_cli(a->fd,
"Channel '%s' not found\n", chan_name);
1081 ast_cli(a->fd,
"\n -- Channel variable '%s' set to '%s' for '%s'\n", var_name, var_value, chan_name);
1089 const char *var, *
val;
1097 ast_channel_lock(chan);
1100 if ((var = ast_var_name(variables)) && (val = ast_var_value(variables))
1104 ast_log(LOG_ERROR,
"Data Buffer Size Exceeded!\n");
1112 ast_channel_unlock(chan);
1120 const char *ret = NULL;
1122 struct varshead *places[2] = { NULL, &globals };
1128 ast_channel_lock(chan);
1129 places[0] = ast_channel_varshead(chan);
1132 for (i = 0; i < 2; i++) {
1135 if (places[i] == &globals)
1136 ast_rwlock_rdlock(&globalslock);
1138 if (!strcmp(name, ast_var_name(variables))) {
1139 ret = ast_var_value(variables);
1143 if (places[i] == &globals)
1144 ast_rwlock_unlock(&globalslock);
1150 ast_channel_unlock(chan);
1160 if (name[strlen(name)-1] ==
')') {
1163 ast_log(LOG_WARNING,
"Cannot push a value onto a function\n");
1169 ast_channel_lock(chan);
1170 headp = ast_channel_varshead(chan);
1172 ast_rwlock_wrlock(&globalslock);
1176 if (value && (newvariable = ast_var_assign(name, value))) {
1177 if (headp == &globals)
1178 ast_verb(2,
"Setting global variable '%s' to '%s'\n", name, value);
1183 ast_channel_unlock(chan);
1185 ast_rwlock_unlock(&globalslock);
1192 const char *nametail = name;
1194 int old_value_existed = 0;
1196 if (name[strlen(name) - 1] ==
')') {
1203 ast_channel_lock(chan);
1204 headp = ast_channel_varshead(chan);
1206 ast_rwlock_wrlock(&globalslock);
1211 if (*nametail ==
'_') {
1213 if (*nametail ==
'_')
1218 if (strcmp(ast_var_name(newvariable), nametail) == 0) {
1221 old_value_existed = !ast_strlen_zero(ast_var_value(newvariable));
1222 ast_var_delete(newvariable);
1228 if (value && (newvariable = ast_var_assign(name, value))) {
1229 if (headp == &globals) {
1230 ast_verb(2,
"Setting global variable '%s' to '%s'\n", name, value);
1234 }
else if (old_value_existed) {
1240 ast_channel_unlock(chan);
1242 ast_rwlock_unlock(&globalslock);
1248 char *name, *value, *mydata;
1250 if (ast_strlen_zero(data)) {
1251 ast_log(LOG_WARNING,
"Set requires one variable name/value pair.\n");
1256 name = strsep(&mydata,
"=");
1259 ast_log(LOG_WARNING,
"Set requires an '=' to be a valid assignment.\n");
1263 if (strchr(name,
' ')) {
1264 ast_log(LOG_WARNING,
"Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n", name, mydata);
1284 if (ast_strlen_zero(vdata)) {
1285 ast_log(LOG_WARNING,
"MSet requires at least one variable name/value pair.\n");
1292 for (x = 0; x < args.argc; x++) {
1294 if (
pair.argc == 2) {
1296 if (strchr(
pair.name,
' '))
1297 ast_log(LOG_WARNING,
"Please avoid unnecessary spaces on variables as it may lead to unexpected results ('%s' set to '%s').\n",
pair.name,
pair.value);
1299 ast_log(LOG_WARNING,
"MSet: ignoring entry '%s' with no '='\n",
pair.name);
1301 ast_log(LOG_WARNING,
"MSet: ignoring entry '%s' with no '=' (in %s@%s:%d\n",
pair.name, ast_channel_exten(chan), ast_channel_context(chan), ast_channel_priority(chan));
1308 void pbx_builtin_clear_globals(
void)
1312 ast_rwlock_wrlock(&globalslock);
1314 ast_var_delete(vardata);
1315 ast_rwlock_unlock(&globalslock);
1318 #ifdef TEST_FRAMEWORK
1321 int i, res = AST_TEST_PASS;
1325 const char *test_strings[][5] = {
1326 {
"somevaluehere",
"CALLERID(num):0:25",
"somevaluehere"},
1327 {
"somevaluehere",
"CALLERID(num):0:5",
"somev"},
1328 {
"somevaluehere",
"CALLERID(num):4:5",
"value"},
1329 {
"somevaluehere",
"CALLERID(num):0:-4",
"somevalue"},
1330 {
"somevaluehere",
"CALLERID(num):-4",
"here"},
1335 info->name =
"variable_substrings";
1336 info->category =
"/main/pbx/";
1337 info->summary =
"Test variable substring resolution";
1338 info->description =
"Verify that variable substrings are calculated correctly";
1339 return AST_TEST_NOT_RUN;
1345 ast_test_status_update(
test,
"Unable to allocate dummy channel\n");
1346 return AST_TEST_FAIL;
1350 ast_test_status_update(
test,
"Unable to allocate dynamic string buffer\n");
1352 return AST_TEST_FAIL;
1355 for (i = 0; i < ARRAY_LEN(test_strings); i++) {
1360 snprintf(tmp,
sizeof(tmp),
"${%s}", test_strings[i][1]);
1366 ast_test_status_update(
test,
"Format string '%s' substituted to '%s' using str sub. Expected '%s'.\n", test_strings[i][0],
ast_str_buffer(str), test_strings[i][2]);
1367 res = AST_TEST_FAIL;
1371 pbx_substitute_variables_helper(chan, tmp, substituted,
sizeof(substituted) - 1);
1372 ast_debug(1,
"Comparing PBX %s with %s\n", substituted, test_strings[i][2]);
1373 if (strcmp(test_strings[i][2], substituted)) {
1374 ast_test_status_update(
test,
"Format string '%s' substituted to '%s' using pbx sub. Expected '%s'.\n", test_strings[i][0], substituted, test_strings[i][2]);
1375 res = AST_TEST_FAIL;
1390 AST_CLI_DEFINE(handle_set_global,
"Set global dialplan variable"),
1391 AST_CLI_DEFINE(handle_set_chanvar,
"Set a channel variable"),
1394 static void unload_pbx_variables(
void)
1399 pbx_builtin_clear_globals();
1400 AST_TEST_UNREGISTER(test_variable_substrings);
1411 AST_TEST_REGISTER(test_variable_substrings);
static char * substring(const char *value, int offset, int length, char *workspace, size_t workspace_len)
takes a substring. It is ok to call with value == workspace.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
Main Channel structure associated with a channel.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
Private include file for pbx.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
#define ast_channel_unref(c)
Decrease channel reference count.
void pbx_builtin_pushvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, without removing any previously set value...
int ast_func_read2(struct ast_channel *chan, const char *function, struct ast_str **str, ssize_t maxlen)
executes a read operation on a function
char context[AST_MAX_CONTEXT]
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
extract offset:length from variable name.
descriptor for a cli entry.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, struct varshead *headp, const char *templ, size_t *used)
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen, struct varshead *headp, const char *templ)
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
void pbx_substitute_variables_helper_full_location(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count, size_t *used, const char *context, const char *exten, int pri)
Substitutes variables, similar to pbx_substitute_variables_helper_full, but allows passing the contex...
int ast_str_get_hint(struct ast_str **hint, ssize_t hintsize, struct ast_str **name, ssize_t namesize, struct ast_channel *c, const char *context, const char *exten)
If an extension hint exists, return non-zero.
int ast_unregister_application(const char *app)
Unregister an application.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
int pbx_builtin_serialize_variables(struct ast_channel *chan, struct ast_str **buf)
Create a human-readable string, specifying all variables and their corresponding values.
void ast_str_substitute_variables_full2(struct ast_str **buf, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *templ, size_t *used, int use_both)
Perform variable/function/expression substitution on an ast_str.
int args
This gets set in ast_cli_register()
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Asterisk file paths, configured in asterisk.conf.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_dummy_channel_alloc()
Create a fake channel structure.
char * ast_str_append_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Append a non-NULL terminated substring to the end of a dynamic string.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
A set of macros to manage forward-linked lists.
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Core PBX routines and definitions.
static char * handle_show_chanvar(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI support for listing chanvar's variables in a parseable way.
int load_pbx_variables(void)
Support for dynamic strings.
void ast_channel_publish_varset(struct ast_channel *chan, const char *variable, const char *value)
Publish a ast_channel_publish_varset for a channel.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
int pbx_builtin_setvar_multiple(struct ast_channel *chan, const char *vdata)
Parse and set multiple channel variables, where the pairs are separated by the ',' character...
Prototypes for public functions only of internal interest,.
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
int ast_str_expr(struct ast_str **str, ssize_t maxlen, struct ast_channel *chan, char *expr)
Evaluate the given expression.
struct ast_eid ast_eid_default
Global EID.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
void ast_str_update(struct ast_str *buf)
Update the length of the buffer, after using ast_str merely as a buffer.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
#define AST_TEST_DEFINE(hdr)
int ast_register_application2(const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
Register an application.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
const char * ast_str_retrieve_variable(struct ast_str **str, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *var)
char * ast_str_set_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Set a dynamic string to a non-NULL terminated substring.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
Support for Asterisk built-in variables in the dialplan.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Asterisk module definitions.
static char * handle_eval_function(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI support for executing function.
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
static char * substituted(struct ast_channel *channel, const char *string)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan)
Evaluate the given expression.
static char * handle_show_globals(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI support for listing global variables in a parseable way.
char exten[AST_MAX_EXTENSION]
int pbx_builtin_setvar(struct ast_channel *chan, const char *data)
Parse and set a single channel variable, where the name and value are separated with an '=' character...
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define AST_APP_ARG(name)
Define an application argument.