Application convenience functions, designed to give consistent look and feel to Asterisk apps. More...
Go to the source code of this file.
Data Structures | |
struct | ast_app_option |
A structure to hold the description of an application 'option'. More... | |
struct | ast_group_info |
struct | ast_ivr_menu |
struct | ast_ivr_option |
Defines | |
#define | AST_APP_ARG(name) char *name |
Define an application argument. | |
#define | AST_APP_OPTION(option, flagno) [option] = { .flag = flagno } |
Declares an application option that does not accept an argument. | |
#define | AST_APP_OPTION_ARG(option, flagno, argno) [option] = { .flag = flagno, .arg_index = argno + 1 } |
Declares an application option that accepts an argument. | |
#define | AST_APP_OPTIONS(holder, options...) static const struct ast_app_option holder[128] = options |
Declares an array of options for an application. | |
#define | AST_DECLARE_APP_ARGS(name, arglist) |
Declare a structure to hold the application's arguments. | |
#define | AST_IVR_DECLARE_MENU(holder, title, flags, foo...) |
#define | AST_IVR_FLAG_AUTORESTART (1 << 0) |
#define | AST_NONSTANDARD_APP_ARGS(args, parse, sep) args.argc = ast_app_separate_args(parse, sep, args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0]))) |
Performs the 'nonstandard' argument separation process for an application. | |
#define | AST_STANDARD_APP_ARGS(args, parse) args.argc = ast_app_separate_args(parse, '|', args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0]))) |
Performs the 'standard' argument separation process for an application. | |
#define | BEGIN_OPTIONS { |
#define | END_OPTIONS } |
Typedefs | |
typedef int(* | ast_ivr_callback )(struct ast_channel *chan, char *option, void *cbdata) |
Callback function for IVR. | |
Enumerations | |
enum | ast_ivr_action { AST_ACTION_UPONE, AST_ACTION_EXIT, AST_ACTION_CALLBACK, AST_ACTION_PLAYBACK, AST_ACTION_BACKGROUND, AST_ACTION_PLAYLIST, AST_ACTION_MENU, AST_ACTION_REPEAT, AST_ACTION_RESTART, AST_ACTION_TRANSFER, AST_ACTION_WAITOPTION, AST_ACTION_NOOP, AST_ACTION_BACKLIST } |
enum | AST_LOCK_RESULT { AST_LOCK_SUCCESS = 0, AST_LOCK_TIMEOUT = -1, AST_LOCK_PATH_NOT_FOUND = -2, AST_LOCK_FAILURE = -3 } |
Functions | |
int | ast_app_dtget (struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout) |
Present a dialtone and collect a certain length extension. | |
int | ast_app_getdata (struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout) |
Plays a stream and gets DTMF data from a channel. | |
int | ast_app_getdata_full (struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd) |
Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions. | |
int | ast_app_group_discard (struct ast_channel *chan) |
int | ast_app_group_get_count (const char *group, const char *category) |
struct ast_group_info * | ast_app_group_list_head (void) |
int | ast_app_group_list_lock (void) |
int | ast_app_group_list_unlock (void) |
int | ast_app_group_match_get_count (const char *groupmatch, const char *category) |
int | ast_app_group_set_channel (struct ast_channel *chan, const char *data) |
int | ast_app_group_split_group (const char *data, char *group, int group_max, char *category, int category_max) |
int | ast_app_group_update (struct ast_channel *oldchan, struct ast_channel *newchan) |
int | ast_app_has_voicemail (const char *mailbox, const char *folder) |
int | ast_app_inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs) |
int | ast_app_messagecount (const char *context, const char *mailbox, const char *folder) |
void | ast_app_options2str (const struct ast_app_option *options, struct ast_flags *flags, char *buf, size_t len) |
Given a list of options array, return an option string based on passed flags. | |
int | ast_app_parse_options (const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr) |
Parses a string containing application options and sets flags/arguments. | |
unsigned int | ast_app_separate_args (char *buf, char delim, char **array, int arraylen) |
Separate a string into arguments in an array. | |
int | ast_control_streamfile (struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *pause, const char *restart, int skipms) |
int | ast_dtmf_stream (struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between) |
Send DTMF to a channel. | |
void | ast_install_vm_functions (int(*has_voicemail_func)(const char *mailbox, const char *folder), int(*inboxcount_func)(const char *mailbox, int *newmsgs, int *oldmsgs), int(*messagecount_func)(const char *context, const char *mailbox, const char *folder)) |
int | ast_ivr_menu_run (struct ast_channel *c, struct ast_ivr_menu *menu, void *cbdata) |
Runs an IVR menu. | |
int | ast_linear_stream (struct ast_channel *chan, const char *filename, int fd, int allowoverride) |
enum AST_LOCK_RESULT | ast_lock_path (const char *path) |
Lock a filesystem path. | |
int | ast_play_and_prepend (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime_sec, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence_ms) |
int | ast_play_and_record (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms, const char *path) |
int | ast_play_and_record_full (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf) |
int | ast_play_and_wait (struct ast_channel *chan, const char *fn) |
char * | ast_read_textfile (const char *file) |
int | ast_record_review (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path) |
void | ast_replace_sigchld (void) |
Replace the SIGCHLD handler. | |
int | ast_safe_system (const char *s) |
void | ast_uninstall_vm_functions (void) |
int | ast_unlock_path (const char *path) |
void | ast_unreplace_sigchld (void) |
Restore the SIGCHLD handler. |
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
Definition in file app.h.
Define an application argument.
name | The name of the argument |
Definition at line 244 of file app.h.
Referenced by __login_exec(), acf_channel_read(), acf_curl_exec(), acf_if(), acf_odbc_read(), acf_odbc_write(), acf_rand_exec(), acf_sprintf(), acf_strftime(), acf_strptime(), acf_vmcount_exec(), add_agent(), admin_exec(), app_exec(), aqm_exec(), array(), astman_get_variables(), asyncgoto_exec(), auth_exec(), cdr_read(), cdr_write(), chanavail_exec(), checkmd5(), conf_exec(), count_exec(), cut_internal(), dahdi_accept_r2_call_exec(), dictate_exec(), directory_exec(), disa_exec(), filter(), find_conf(), forkcdr_exec(), func_header_read(), function_agent(), function_db_delete(), function_db_exists(), function_db_read(), function_db_write(), function_enum(), function_fieldqty(), function_realtime_read(), function_realtime_write(), hasvoicemail_exec(), isAnsweringMachine(), math(), misdn_check_l2l1(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), pbx_builtin_background(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_waitexten(), playback_exec(), pqm_exec(), privacy_exec(), ql_exec(), queue_exec(), read_exec(), record_exec(), regex(), reload_queues(), rqm_exec(), sayunixtime_exec(), sendimage_exec(), sendtext_exec(), smdi_msg_read(), smdi_msg_retrieve_read(), transfer_exec(), upqm_exec(), userevent_exec(), vm_box_exists(), vm_exec(), and vm_execmain().
#define AST_APP_OPTION | ( | option, | |||
flagno | ) | [option] = { .flag = flagno } |
Declares an application option that does not accept an argument.
option | The single character representing the option | |
flagno | The flag index to be set if this option is present |
#define AST_APP_OPTION_ARG | ( | option, | |||
flagno, | |||||
argno | ) | [option] = { .flag = flagno, .arg_index = argno + 1 } |
Declares an application option that accepts an argument.
option | The single character representing the option | |
flagno | The flag index to be set if this option is present | |
argno | The index into the argument array where the argument should be placed |
#define AST_APP_OPTIONS | ( | holder, | |||
options... | ) | static const struct ast_app_option holder[128] = options |
Declares an array of options for an application.
holder | The name of the array to be created | |
options | The actual options to be placed into the array |
This macro declares a 'static const' array of struct
ast_option
elements to hold the list of available options for an application. Each option must be declared using either the AST_APP_OPTION() or AST_APP_OPTION_ARG() macros.
Example usage:
enum { OPT_JUMP = (1 << 0), OPT_BLAH = (1 << 1), OPT_BLORT = (1 << 2), } my_app_option_flags; enum { OPT_ARG_BLAH = 0, OPT_ARG_BLORT, !! this entry tells how many possible arguments there are, and must be the last entry in the list OPT_ARG_ARRAY_SIZE, } my_app_option_args; AST_APP_OPTIONS(my_app_options, { AST_APP_OPTION('j', OPT_JUMP), AST_APP_OPTION_ARG('b', OPT_BLAH, OPT_ARG_BLAH), AST_APP_OPTION_BLORT('B', OPT_BLORT, OPT_ARG_BLORT), }); static int my_app_exec(struct ast_channel *chan, void *data) { char *options; struct ast_flags opts = { 0, }; char *opt_args[OPT_ARG_ARRAY_SIZE]; ... do any argument parsing here ... if (ast_app_parse_options(my_app_options, &opts, opt_args, options)) { LOCAL_USER_REMOVE(u); return -1; } }
#define AST_DECLARE_APP_ARGS | ( | name, | |||
arglist | ) |
struct { \ unsigned int argc; \ char *argv[0]; \ arglist \ } name
Declare a structure to hold the application's arguments.
name | The name of the structure | |
arglist | The list of arguments, defined using AST_APP_ARG |
This macro defines a structure intended to be used in a call to ast_app_separate_args(). The structure includes all the arguments specified, plus an argv array that overlays them and an argc argument counter. The arguments must be declared using AST_APP_ARG, and they will all be character pointers (strings).
Definition at line 261 of file app.h.
Referenced by __login_exec(), acf_channel_read(), acf_curl_exec(), acf_if(), acf_odbc_read(), acf_odbc_write(), acf_rand_exec(), acf_sprintf(), acf_strftime(), acf_strptime(), acf_vmcount_exec(), add_agent(), admin_exec(), app_exec(), aqm_exec(), array(), astman_get_variables(), asyncgoto_exec(), auth_exec(), cdr_read(), cdr_write(), chanavail_exec(), checkmd5(), conf_exec(), count_exec(), cut_internal(), dahdi_accept_r2_call_exec(), dictate_exec(), directory_exec(), disa_exec(), filter(), find_conf(), forkcdr_exec(), func_header_read(), function_agent(), function_db_delete(), function_db_exists(), function_db_read(), function_db_write(), function_enum(), function_fieldqty(), function_realtime_read(), function_realtime_write(), hasvoicemail_exec(), isAnsweringMachine(), math(), misdn_check_l2l1(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), pbx_builtin_background(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_waitexten(), playback_exec(), pqm_exec(), privacy_exec(), ql_exec(), queue_exec(), read_exec(), record_exec(), regex(), reload_queues(), rqm_exec(), sayunixtime_exec(), sendimage_exec(), sendtext_exec(), smdi_msg_read(), smdi_msg_retrieve_read(), transfer_exec(), upqm_exec(), userevent_exec(), vm_box_exists(), vm_exec(), and vm_execmain().
#define AST_IVR_DECLARE_MENU | ( | holder, | |||
title, | |||||
flags, | |||||
foo... | ) |
static struct ast_ivr_option __options_##holder[] = foo;\ static struct ast_ivr_menu holder = { title, flags, __options_##holder }
#define AST_NONSTANDARD_APP_ARGS | ( | args, | |||
parse, | |||||
sep | ) | args.argc = ast_app_separate_args(parse, sep, args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0]))) |
Performs the 'nonstandard' argument separation process for an application.
args | An argument structure defined using AST_DECLARE_APP_ARGS | |
parse | A modifiable buffer containing the input to be parsed | |
sep | A nonstandard separator character |
This function will separate the input string using the nonstandard argument separator character and fill in the provided structure, including the argc argument counter field.
Definition at line 290 of file app.h.
Referenced by acf_if(), acf_odbc_write(), add_agent(), array(), find_conf(), function_agent(), function_db_delete(), function_db_exists(), function_db_read(), function_db_write(), record_exec(), regex(), and reload_queues().
#define AST_STANDARD_APP_ARGS | ( | args, | |||
parse | ) | args.argc = ast_app_separate_args(parse, '|', args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0]))) |
Performs the 'standard' argument separation process for an application.
args | An argument structure defined using AST_DECLARE_APP_ARGS | |
parse | A modifiable buffer containing the input to be parsed |
This function will separate the input string using the standard argument separator character '|' and fill in the provided structure, including the argc argument counter field.
Definition at line 277 of file app.h.
Referenced by __login_exec(), acf_channel_read(), acf_curl_exec(), acf_odbc_read(), acf_odbc_write(), acf_rand_exec(), acf_sprintf(), acf_strftime(), acf_strptime(), acf_vmcount_exec(), admin_exec(), app_exec(), aqm_exec(), array(), astman_get_variables(), asyncgoto_exec(), auth_exec(), cdr_read(), cdr_write(), chanavail_exec(), checkmd5(), conf_exec(), count_exec(), cut_internal(), dahdi_accept_r2_call_exec(), dictate_exec(), directory_exec(), disa_exec(), filter(), forkcdr_exec(), func_header_read(), function_enum(), function_fieldqty(), function_realtime_read(), function_realtime_write(), hasvoicemail_exec(), isAnsweringMachine(), math(), misdn_check_l2l1(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), pbx_builtin_background(), pbx_builtin_saydate(), pbx_builtin_saytime(), pbx_builtin_waitexten(), playback_exec(), pqm_exec(), privacy_exec(), ql_exec(), queue_exec(), read_exec(), rqm_exec(), sayunixtime_exec(), sendimage_exec(), sendtext_exec(), smdi_msg_read(), smdi_msg_retrieve_read(), transfer_exec(), upqm_exec(), userevent_exec(), vm_box_exists(), vm_exec(), and vm_execmain().
typedef int(* ast_ivr_callback)(struct ast_channel *chan, char *option, void *cbdata) |
enum ast_ivr_action |
AST_ACTION_UPONE |
adata is unused |
AST_ACTION_EXIT |
adata is the return value for ast_ivr_menu_run if channel was not hungup |
AST_ACTION_CALLBACK |
adata is an ast_ivr_callback |
AST_ACTION_PLAYBACK |
adata is file to play |
AST_ACTION_BACKGROUND |
adata is file to play |
AST_ACTION_PLAYLIST |
adata is list of files, separated by ; to play |
AST_ACTION_MENU |
adata is a pointer to an ast_ivr_menu |
AST_ACTION_REPEAT |
adata is max # of repeats, cast to a pointer |
AST_ACTION_RESTART |
adata is like repeat, but resets repeats to 0 |
AST_ACTION_TRANSFER |
adata is a string with exten[] |
AST_ACTION_WAITOPTION |
adata is a timeout, or 0 for defaults |
AST_ACTION_NOOP |
adata is unused |
AST_ACTION_BACKLIST |
adata is list of files separated by ; allows interruption |
Definition at line 37 of file app.h.
00037 { 00038 AST_ACTION_UPONE, /*!< adata is unused */ 00039 AST_ACTION_EXIT, /*!< adata is the return value for ast_ivr_menu_run if channel was not hungup */ 00040 AST_ACTION_CALLBACK, /*!< adata is an ast_ivr_callback */ 00041 AST_ACTION_PLAYBACK, /*!< adata is file to play */ 00042 AST_ACTION_BACKGROUND, /*!< adata is file to play */ 00043 AST_ACTION_PLAYLIST, /*!< adata is list of files, separated by ; to play */ 00044 AST_ACTION_MENU, /*!< adata is a pointer to an ast_ivr_menu */ 00045 AST_ACTION_REPEAT, /*!< adata is max # of repeats, cast to a pointer */ 00046 AST_ACTION_RESTART, /*!< adata is like repeat, but resets repeats to 0 */ 00047 AST_ACTION_TRANSFER, /*!< adata is a string with exten[@context] */ 00048 AST_ACTION_WAITOPTION, /*!< adata is a timeout, or 0 for defaults */ 00049 AST_ACTION_NOOP, /*!< adata is unused */ 00050 AST_ACTION_BACKLIST, /*!< adata is list of files separated by ; allows interruption */ 00051 } ast_ivr_action;
enum AST_LOCK_RESULT |
Definition at line 186 of file app.h.
00186 { 00187 AST_LOCK_SUCCESS = 0, 00188 AST_LOCK_TIMEOUT = -1, 00189 AST_LOCK_PATH_NOT_FOUND = -2, 00190 AST_LOCK_FAILURE = -3, 00191 };
int ast_app_dtget | ( | struct ast_channel * | chan, | |
const char * | context, | |||
char * | collect, | |||
size_t | size, | |||
int | maxlen, | |||
int | timeout | |||
) |
Present a dialtone and collect a certain length extension.
Definition at line 65 of file app.c.
References ast_exists_extension(), ast_get_indication_tone(), ast_ignore_pattern(), ast_log(), ast_matchmore_extension(), ast_playtones_start(), ast_playtones_stop(), ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_num, tone_zone_sound::data, ast_pbx::dtimeout, LOG_NOTICE, ast_channel::pbx, and ast_channel::zone.
Referenced by builtin_atxfer(), and builtin_blindtransfer().
00066 { 00067 struct tone_zone_sound *ts; 00068 int res=0, x=0; 00069 00070 if (maxlen > size) 00071 maxlen = size; 00072 00073 if (!timeout && chan->pbx) 00074 timeout = chan->pbx->dtimeout; 00075 else if (!timeout) 00076 timeout = 5; 00077 00078 ts = ast_get_indication_tone(chan->zone,"dial"); 00079 if (ts && ts->data[0]) 00080 res = ast_playtones_start(chan, 0, ts->data, 0); 00081 else 00082 ast_log(LOG_NOTICE,"Huh....? no dial for indications?\n"); 00083 00084 for (x = strlen(collect); x < maxlen; ) { 00085 res = ast_waitfordigit(chan, timeout); 00086 if (!ast_ignore_pattern(context, collect)) 00087 ast_playtones_stop(chan); 00088 if (res < 1) 00089 break; 00090 if (res == '#') 00091 break; 00092 collect[x++] = res; 00093 if (!ast_matchmore_extension(chan, context, collect, 1, chan->cid.cid_num)) 00094 break; 00095 } 00096 if (res >= 0) 00097 res = ast_exists_extension(chan, context, collect, 1, chan->cid.cid_num) ? 1 : 0; 00098 return res; 00099 }
int ast_app_getdata | ( | struct ast_channel * | c, | |
char * | prompt, | |||
char * | s, | |||
int | maxlen, | |||
int | timeout | |||
) |
Plays a stream and gets DTMF data from a channel.
c | Which channel one is interacting with | |
prompt | File to pass to ast_streamfile (the one that you wish to play) | |
s | The location where the DTMF data will be stored | |
maxlen | Max Length of the data | |
timeout | Timeout length waiting for data(in milliseconds). Set to 0 for standard timeout(six seconds), or -1 for no time out. |
This function was designed for application programmers for situations where they need to play a message and then get some DTMF data in response to the message. If a digit is pressed during playback, it will immediately break out of the message and continue execution of your code.
c | The channel to read from | |
prompt | The file to stream to the channel | |
s | The string to read in to. Must be at least the size of your length | |
maxlen | How many digits to read (maximum) | |
timeout | set timeout to 0 for "standard" timeouts. Set timeout to -1 for "ludicrous time" (essentially never times out) |
Definition at line 107 of file app.c.
References ast_readstring(), ast_streamfile(), ast_pbx::dtimeout, ast_channel::pbx, and ast_pbx::rtimeout.
Referenced by __login_exec(), auth_exec(), conf_exec(), dictate_exec(), exec(), find_conf(), read_exec(), testclient_exec(), testserver_exec(), and vm_exec().
00108 { 00109 int res,to,fto; 00110 /* XXX Merge with full version? XXX */ 00111 if (maxlen) 00112 s[0] = '\0'; 00113 if (prompt) { 00114 res = ast_streamfile(c, prompt, c->language); 00115 if (res < 0) 00116 return res; 00117 } 00118 fto = c->pbx ? c->pbx->rtimeout * 1000 : 6000; 00119 to = c->pbx ? c->pbx->dtimeout * 1000 : 2000; 00120 00121 if (timeout > 0) 00122 fto = to = timeout; 00123 if (timeout < 0) 00124 fto = to = 1000000000; 00125 res = ast_readstring(c, s, maxlen, to, fto, "#"); 00126 return res; 00127 }
int ast_app_getdata_full | ( | struct ast_channel * | c, | |
char * | prompt, | |||
char * | s, | |||
int | maxlen, | |||
int | timeout, | |||
int | audiofd, | |||
int | ctrlfd | |||
) |
Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions.
Definition at line 130 of file app.c.
References ast_readstring_full(), and ast_streamfile().
Referenced by handle_getdata().
00131 { 00132 int res, to, fto; 00133 if (prompt) { 00134 res = ast_streamfile(c, prompt, c->language); 00135 if (res < 0) 00136 return res; 00137 } 00138 fto = 6000; 00139 to = 2000; 00140 if (timeout > 0) 00141 fto = to = timeout; 00142 if (timeout < 0) 00143 fto = to = 1000000000; 00144 res = ast_readstring_full(c, s, maxlen, to, fto, "#", audiofd, ctrlfd); 00145 return res; 00146 }
int ast_app_group_discard | ( | struct ast_channel * | chan | ) |
Discard all group counting for a channel
Definition at line 940 of file app.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_group_info::chan, and free.
Referenced by ast_channel_free().
00941 { 00942 struct ast_group_info *gi = NULL; 00943 00944 AST_LIST_LOCK(&groups); 00945 AST_LIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) { 00946 if (gi->chan == chan) { 00947 AST_LIST_REMOVE_CURRENT(&groups, list); 00948 free(gi); 00949 } 00950 } 00951 AST_LIST_TRAVERSE_SAFE_END 00952 AST_LIST_UNLOCK(&groups); 00953 00954 return 0; 00955 }
int ast_app_group_get_count | ( | const char * | group, | |
const char * | category | |||
) |
Get the current channel count of the specified group and category.
Definition at line 878 of file app.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_group_info::category, and ast_group_info::group.
Referenced by group_count_function_read().
00879 { 00880 struct ast_group_info *gi = NULL; 00881 int count = 0; 00882 00883 if (ast_strlen_zero(group)) 00884 return 0; 00885 00886 AST_LIST_LOCK(&groups); 00887 AST_LIST_TRAVERSE(&groups, gi, list) { 00888 if (!strcasecmp(gi->group, group) && (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) 00889 count++; 00890 } 00891 AST_LIST_UNLOCK(&groups); 00892 00893 return count; 00894 }
struct ast_group_info* ast_app_group_list_head | ( | void | ) | [read] |
Get the head of the group count list
Definition at line 962 of file app.c.
References AST_LIST_FIRST.
Referenced by group_count_function_read(), group_function_read(), group_list_function_read(), and group_show_channels().
00963 { 00964 return AST_LIST_FIRST(&groups); 00965 }
int ast_app_group_list_lock | ( | void | ) |
Lock the group count list
Definition at line 957 of file app.c.
References AST_LIST_LOCK.
Referenced by group_count_function_read(), group_function_read(), group_list_function_read(), and group_show_channels().
00958 { 00959 return AST_LIST_LOCK(&groups); 00960 }
int ast_app_group_list_unlock | ( | void | ) |
Unlock the group count list
Definition at line 967 of file app.c.
References AST_LIST_UNLOCK.
Referenced by group_count_function_read(), group_function_read(), group_list_function_read(), and group_show_channels().
00968 { 00969 return AST_LIST_UNLOCK(&groups); 00970 }
int ast_app_group_match_get_count | ( | const char * | groupmatch, | |
const char * | category | |||
) |
Get the current channel count of all groups that match the specified pattern and category.
Definition at line 896 of file app.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_group_info::category, and ast_group_info::group.
Referenced by group_match_count_function_read().
00897 { 00898 struct ast_group_info *gi = NULL; 00899 regex_t regexbuf; 00900 int count = 0; 00901 00902 if (ast_strlen_zero(groupmatch)) 00903 return 0; 00904 00905 /* if regex compilation fails, return zero matches */ 00906 if (regcomp(®exbuf, groupmatch, REG_EXTENDED | REG_NOSUB)) 00907 return 0; 00908 00909 AST_LIST_LOCK(&groups); 00910 AST_LIST_TRAVERSE(&groups, gi, list) { 00911 if (!regexec(®exbuf, gi->group, 0, NULL, 0) && (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) 00912 count++; 00913 } 00914 AST_LIST_UNLOCK(&groups); 00915 00916 regfree(®exbuf); 00917 00918 return count; 00919 }
int ast_app_group_set_channel | ( | struct ast_channel * | chan, | |
const char * | data | |||
) |
Set the group for a channel, splitting the provided data into group and category, if specified.
Definition at line 833 of file app.c.
References ast_app_group_split_group(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_strlen_zero(), calloc, ast_group_info::category, ast_group_info::chan, free, ast_group_info::group, group, and len().
Referenced by group_function_write().
00834 { 00835 int res = 0; 00836 char group[80] = "", category[80] = ""; 00837 struct ast_group_info *gi = NULL; 00838 size_t len = 0; 00839 00840 if (ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category))) 00841 return -1; 00842 00843 /* Calculate memory we will need if this is new */ 00844 len = sizeof(*gi) + strlen(group) + 1; 00845 if (!ast_strlen_zero(category)) 00846 len += strlen(category) + 1; 00847 00848 AST_LIST_LOCK(&groups); 00849 AST_LIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) { 00850 if ((gi->chan == chan) && ((ast_strlen_zero(category) && ast_strlen_zero(gi->category)) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) { 00851 AST_LIST_REMOVE_CURRENT(&groups, list); 00852 free(gi); 00853 break; 00854 } 00855 } 00856 AST_LIST_TRAVERSE_SAFE_END 00857 00858 if (ast_strlen_zero(group)) { 00859 /* Enable unsetting the group */ 00860 } else if ((gi = calloc(1, len))) { 00861 gi->chan = chan; 00862 gi->group = (char *) gi + sizeof(*gi); 00863 strcpy(gi->group, group); 00864 if (!ast_strlen_zero(category)) { 00865 gi->category = (char *) gi + sizeof(*gi) + strlen(group) + 1; 00866 strcpy(gi->category, category); 00867 } 00868 AST_LIST_INSERT_TAIL(&groups, gi, list); 00869 } else { 00870 res = -1; 00871 } 00872 00873 AST_LIST_UNLOCK(&groups); 00874 00875 return res; 00876 }
int ast_app_group_split_group | ( | const char * | data, | |
char * | group, | |||
int | group_max, | |||
char * | category, | |||
int | category_max | |||
) |
Split a group string into group and category, returning a default category if none is provided.
Definition at line 806 of file app.c.
References ast_copy_string(), and ast_strlen_zero().
Referenced by ast_app_group_set_channel(), group_count_function_read(), and group_match_count_function_read().
00807 { 00808 int res=0; 00809 char tmp[256]; 00810 char *grp=NULL, *cat=NULL; 00811 00812 if (!ast_strlen_zero(data)) { 00813 ast_copy_string(tmp, data, sizeof(tmp)); 00814 grp = tmp; 00815 cat = strchr(tmp, '@'); 00816 if (cat) { 00817 *cat = '\0'; 00818 cat++; 00819 } 00820 } 00821 00822 if (!ast_strlen_zero(grp)) 00823 ast_copy_string(group, grp, group_max); 00824 else 00825 *group = '\0'; 00826 00827 if (!ast_strlen_zero(cat)) 00828 ast_copy_string(category, cat, category_max); 00829 00830 return res; 00831 }
int ast_app_group_update | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) |
Update all group counting for a channel to a new one
Definition at line 921 of file app.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_group_info::chan, and free.
Referenced by ast_do_masquerade(), and check_bridge().
00922 { 00923 struct ast_group_info *gi = NULL; 00924 00925 AST_LIST_LOCK(&groups); 00926 AST_LIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) { 00927 if (gi->chan == old) { 00928 gi->chan = new; 00929 } else if (gi->chan == new) { 00930 AST_LIST_REMOVE_CURRENT(&groups, list); 00931 free(gi); 00932 } 00933 } 00934 AST_LIST_TRAVERSE_SAFE_END 00935 AST_LIST_UNLOCK(&groups); 00936 00937 return 0; 00938 }
int ast_app_has_voicemail | ( | const char * | mailbox, | |
const char * | folder | |||
) |
Determine if a given mailbox has any voicemail
Definition at line 168 of file app.c.
References ast_has_voicemail_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3.
Referenced by action_mailboxstatus(), do_monitor(), has_voicemail(), notify_new_message(), play_dialtone(), poll_mailbox(), and run_externnotify().
00169 { 00170 static int warned = 0; 00171 if (ast_has_voicemail_func) 00172 return ast_has_voicemail_func(mailbox, folder); 00173 00174 if ((option_verbose > 2) && !warned) { 00175 ast_verbose(VERBOSE_PREFIX_3 "Message check requested for mailbox %s/folder %s but voicemail not loaded.\n", mailbox, folder ? folder : "INBOX"); 00176 warned++; 00177 } 00178 return 0; 00179 }
int ast_app_inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) |
Determine number of new/old messages in a mailbox
Definition at line 182 of file app.c.
References ast_inboxcount_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3.
Referenced by action_mailboxcount(), notify_new_message(), sip_send_mwi_to_peer(), and update_registry().
00183 { 00184 static int warned = 0; 00185 if (newmsgs) 00186 *newmsgs = 0; 00187 if (oldmsgs) 00188 *oldmsgs = 0; 00189 if (ast_inboxcount_func) 00190 return ast_inboxcount_func(mailbox, newmsgs, oldmsgs); 00191 00192 if (!warned && (option_verbose > 2)) { 00193 warned++; 00194 ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s but voicemail not loaded.\n", mailbox); 00195 } 00196 00197 return 0; 00198 }
int ast_app_messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) |
Determine number of messages in a given mailbox and folder
Definition at line 200 of file app.c.
References ast_messagecount_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3.
Referenced by acf_vmcount_exec(), and hasvoicemail_exec().
00201 { 00202 static int warned = 0; 00203 if (ast_messagecount_func) 00204 return ast_messagecount_func(context, mailbox, folder); 00205 00206 if (!warned && (option_verbose > 2)) { 00207 warned++; 00208 ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s@%s/%s but voicemail not loaded.\n", mailbox, context, folder); 00209 } 00210 00211 return 0; 00212 }
void ast_app_options2str | ( | const struct ast_app_option * | options, | |
struct ast_flags * | flags, | |||
char * | buf, | |||
size_t | len | |||
) |
Given a list of options array, return an option string based on passed flags.
options | The array of possible options declared with AST_APP_OPTIONS | |
flags | The flags of the options that you wish to populate the buffer with | |
buf | The buffer to fill with the string of options | |
len | The maximum length of buf |
Definition at line 1411 of file app.c.
References ast_test_flag.
01412 { 01413 unsigned int i, found = 0; 01414 01415 for (i = 32; i < 128 && found < len;i++) { 01416 if (ast_test_flag(flags, options[i].flag)) { 01417 buf[found++] = i; 01418 } 01419 } 01420 buf[found] = '\0'; 01421 }
int ast_app_parse_options | ( | const struct ast_app_option * | options, | |
struct ast_flags * | flags, | |||
char ** | args, | |||
char * | optstr | |||
) |
Parses a string containing application options and sets flags/arguments.
options | The array of possible options declared with AST_APP_OPTIONS | |
flags | The flag structure to have option flags set | |
args | The array of argument pointers to hold arguments found | |
optstr | The string containing the options to be parsed |
Definition at line 1423 of file app.c.
References ast_app_option::arg_index, ast_clear_flag, ast_copy_string(), AST_FLAGS_ALL, ast_log(), ast_set_flag, LOG_WARNING, quote(), and s.
Referenced by app_exec(), auth_exec(), cdr_read(), cdr_write(), chanspy_exec(), conf_exec(), extenspy_exec(), forkcdr_exec(), mixmonitor_exec(), page_exec(), pbx_builtin_background(), pbx_builtin_resetcdr(), pbx_builtin_waitexten(), read_exec(), smdi_msg_retrieve_read(), vm_exec(), and vm_execmain().
01424 { 01425 char *s; 01426 int curarg; 01427 unsigned int argloc; 01428 char *arg; 01429 int res = 0; 01430 01431 ast_clear_flag(flags, AST_FLAGS_ALL); 01432 01433 if (!optstr) 01434 return 0; 01435 01436 s = optstr; 01437 while (*s) { 01438 curarg = *s++ & 0x7f; /* the array (in app.h) has 128 entries */ 01439 argloc = options[curarg].arg_index; 01440 if (*s == '(') { 01441 int paren = 1, quote = 0; 01442 int parsequotes = (s[1] == '"') ? 1 : 0; 01443 01444 /* Has argument */ 01445 arg = ++s; 01446 for (; *s; s++) { 01447 if (*s == '(' && !quote) { 01448 paren++; 01449 } else if (*s == ')' && !quote) { 01450 /* Count parentheses, unless they're within quotes (or backslashed, below) */ 01451 paren--; 01452 } else if (*s == '"' && parsequotes) { 01453 /* Leave embedded quotes alone, unless they are the first character */ 01454 quote = quote ? 0 : 1; 01455 ast_copy_string(s, s + 1, INT_MAX); 01456 s--; 01457 } else if (*s == '\\') { 01458 if (!quote) { 01459 /* If a backslash is found outside of quotes, remove it */ 01460 ast_copy_string(s, s + 1, INT_MAX); 01461 } else if (quote && s[1] == '"') { 01462 /* Backslash for a quote character within quotes, remove the backslash */ 01463 ast_copy_string(s, s + 1, INT_MAX); 01464 } else { 01465 /* Backslash within quotes, keep both characters */ 01466 s++; 01467 } 01468 } 01469 01470 if (paren == 0) { 01471 break; 01472 } 01473 } 01474 /* This will find the closing paren we found above, or none, if the string ended before we found one. */ 01475 if ((s = strchr(s, ')'))) { 01476 if (argloc) 01477 args[argloc - 1] = arg; 01478 *s++ = '\0'; 01479 } else { 01480 ast_log(LOG_WARNING, "Missing closing parenthesis for argument '%c' in string '%s'\n", curarg, arg); 01481 res = -1; 01482 break; 01483 } 01484 } else if (argloc) { 01485 args[argloc - 1] = ""; 01486 } 01487 ast_set_flag(flags, options[curarg].flag); 01488 } 01489 01490 return res; 01491 }
unsigned int ast_app_separate_args | ( | char * | buf, | |
char | delim, | |||
char ** | array, | |||
int | arraylen | |||
) |
Separate a string into arguments in an array.
buf | The string to be parsed (this must be a writable copy, as it will be modified) | |
delim | The character to be used to delimit arguments | |
array | An array of 'char *' to be filled in with pointers to the found arguments | |
arraylen | The number of elements in the array (i.e. the number of arguments you will accept) |
Note: if there are more arguments in the string than the array will hold, the last element of the array will contain the remaining arguments, not separated.
The array will be completely zeroed by this function before it populates any entries.
Definition at line 972 of file app.c.
References quote().
Referenced by app_exec(), chanspy_exec(), common_exec(), controlplayback_exec(), extenspy_exec(), pbx_builtin_setvar(), speech_background(), and speech_load().
00973 { 00974 int argc; 00975 char *scan, *wasdelim = NULL; 00976 int paren = 0, quote = 0; 00977 00978 if (!buf || !array || !arraylen) 00979 return 0; 00980 00981 memset(array, 0, arraylen * sizeof(*array)); 00982 00983 scan = buf; 00984 00985 for (argc = 0; *scan && (argc < arraylen - 1); argc++) { 00986 array[argc] = scan; 00987 for (; *scan; scan++) { 00988 if (*scan == '(') 00989 paren++; 00990 else if (*scan == ')') { 00991 if (paren) 00992 paren--; 00993 } else if (*scan == '"' && delim != '"') { 00994 quote = quote ? 0 : 1; 00995 /* Remove quote character from argument */ 00996 memmove(scan, scan + 1, strlen(scan)); 00997 scan--; 00998 } else if (*scan == '\\') { 00999 /* Literal character, don't parse */ 01000 memmove(scan, scan + 1, strlen(scan)); 01001 } else if ((*scan == delim) && !paren && !quote) { 01002 wasdelim = scan; 01003 *scan++ = '\0'; 01004 break; 01005 } 01006 } 01007 } 01008 01009 /* If the last character in the original string was the delimiter, then 01010 * there is one additional argument. */ 01011 if (*scan || (scan > buf && (scan - 1) == wasdelim)) { 01012 array[argc++] = scan; 01013 } 01014 01015 return argc; 01016 }
int ast_control_streamfile | ( | struct ast_channel * | chan, | |
const char * | file, | |||
const char * | fwd, | |||
const char * | rev, | |||
const char * | stop, | |||
const char * | pause, | |||
const char * | restart, | |||
int | skipms | |||
) |
Stream a file with fast forward, pause, reverse, restart.
Definition at line 375 of file app.c.
References ast_channel::_state, ast_answer(), ast_log(), ast_seekstream(), AST_STATE_UP, ast_stopstream(), ast_streamfile(), ast_tellstream(), ast_waitfordigit(), ast_waitstream_fr(), LOG_DEBUG, option_debug, and ast_channel::stream.
Referenced by controlplayback_exec(), handle_controlstreamfile(), and wait_file().
00379 { 00380 char *breaks = NULL; 00381 char *end = NULL; 00382 int blen = 2; 00383 int res; 00384 long pause_restart_point = 0; 00385 00386 if (stop) 00387 blen += strlen(stop); 00388 if (pause) 00389 blen += strlen(pause); 00390 if (restart) 00391 blen += strlen(restart); 00392 00393 if (blen > 2) { 00394 breaks = alloca(blen + 1); 00395 breaks[0] = '\0'; 00396 if (stop) 00397 strcat(breaks, stop); 00398 if (pause) 00399 strcat(breaks, pause); 00400 if (restart) 00401 strcat(breaks, restart); 00402 } 00403 if (chan->_state != AST_STATE_UP) 00404 res = ast_answer(chan); 00405 00406 if (file) { 00407 if ((end = strchr(file,':'))) { 00408 if (!strcasecmp(end, ":end")) { 00409 *end = '\0'; 00410 end++; 00411 } 00412 } 00413 } 00414 00415 for (;;) { 00416 ast_stopstream(chan); 00417 res = ast_streamfile(chan, file, chan->language); 00418 if (!res) { 00419 if (pause_restart_point) { 00420 ast_seekstream(chan->stream, pause_restart_point, SEEK_SET); 00421 pause_restart_point = 0; 00422 } 00423 else if (end) { 00424 ast_seekstream(chan->stream, 0, SEEK_END); 00425 end = NULL; 00426 }; 00427 res = ast_waitstream_fr(chan, breaks, fwd, rev, skipms); 00428 } 00429 00430 if (res < 1) 00431 break; 00432 00433 /* We go at next loop if we got the restart char */ 00434 if (restart && strchr(restart, res)) { 00435 if (option_debug) 00436 ast_log(LOG_DEBUG, "we'll restart the stream here at next loop\n"); 00437 pause_restart_point = 0; 00438 continue; 00439 } 00440 00441 if (pause && strchr(pause, res)) { 00442 pause_restart_point = ast_tellstream(chan->stream); 00443 for (;;) { 00444 ast_stopstream(chan); 00445 res = ast_waitfordigit(chan, 1000); 00446 if (!res) 00447 continue; 00448 else if (res == -1 || strchr(pause, res) || (stop && strchr(stop, res))) 00449 break; 00450 } 00451 if (res == *pause) { 00452 res = 0; 00453 continue; 00454 } 00455 } 00456 00457 if (res == -1) 00458 break; 00459 00460 /* if we get one of our stop chars, return it to the calling function */ 00461 if (stop && strchr(stop, res)) 00462 break; 00463 } 00464 00465 /* If we are returning a digit cast it as char */ 00466 if (res > 0 || chan->stream) 00467 res = (char)res; 00468 00469 ast_stopstream(chan); 00470 00471 return res; 00472 }
int ast_dtmf_stream | ( | struct ast_channel * | chan, | |
struct ast_channel * | peer, | |||
const char * | digits, | |||
int | between | |||
) |
Send DTMF to a channel.
chan | The channel that will receive the DTMF frames | |
peer | (optional) Peer channel that will be autoserviced while the primary channel is receiving DTMF | |
digits | This is a string of characters representing the DTMF digits to be sent to the channel. Valid characters are "0123456789*#abcdABCD". Note: You can pass arguments 'f' or 'F', if you want to Flash the channel (if supported by the channel), or 'w' to add a 500 millisecond pause to the DTMF sequence. | |
between | This is the number of milliseconds to wait in between each DTMF digit. If zero milliseconds is specified, then the default value of 100 will be used. |
Definition at line 214 of file app.c.
References ast_autoservice_start(), ast_autoservice_stop(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), AST_CONTROL_FLASH, ast_indicate(), ast_log(), ast_opt_transmit_silence, ast_safe_sleep(), ast_senddigit(), ast_waitfor(), and LOG_WARNING.
Referenced by ast_bridge_call(), misdn_send_digit(), senddtmf_exec(), testclient_exec(), and testserver_exec().
00215 { 00216 const char *ptr; 00217 int res = 0; 00218 struct ast_silence_generator *silgen = NULL; 00219 00220 if (!between) 00221 between = 100; 00222 00223 if (peer) 00224 res = ast_autoservice_start(peer); 00225 00226 if (!res) 00227 res = ast_waitfor(chan, 100); 00228 00229 /* ast_waitfor will return the number of remaining ms on success */ 00230 if (res < 0) { 00231 if (peer) { 00232 ast_autoservice_stop(peer); 00233 } 00234 return res; 00235 } 00236 00237 if (ast_opt_transmit_silence) { 00238 silgen = ast_channel_start_silence_generator(chan); 00239 } 00240 00241 for (ptr = digits; *ptr; ptr++) { 00242 if (*ptr == 'w') { 00243 /* 'w' -- wait half a second */ 00244 if ((res = ast_safe_sleep(chan, 500))) 00245 break; 00246 } else if (strchr("0123456789*#abcdfABCDF", *ptr)) { 00247 /* Character represents valid DTMF */ 00248 if (*ptr == 'f' || *ptr == 'F') { 00249 /* ignore return values if not supported by channel */ 00250 ast_indicate(chan, AST_CONTROL_FLASH); 00251 } else 00252 ast_senddigit(chan, *ptr); 00253 /* pause between digits */ 00254 if ((res = ast_safe_sleep(chan, between))) 00255 break; 00256 } else 00257 ast_log(LOG_WARNING, "Illegal DTMF character '%c' in string. (0-9*#aAbBcCdD allowed)\n",*ptr); 00258 } 00259 00260 if (peer) { 00261 /* Stop autoservice on the peer channel, but don't overwrite any error condition 00262 that has occurred previously while acting on the primary channel */ 00263 if (ast_autoservice_stop(peer) && !res) 00264 res = -1; 00265 } 00266 00267 if (silgen) { 00268 ast_channel_stop_silence_generator(chan, silgen); 00269 } 00270 00271 return res; 00272 }
void ast_install_vm_functions | ( | int(*)(const char *mailbox, const char *folder) | has_voicemail_func, | |
int(*)(const char *mailbox, int *newmsgs, int *oldmsgs) | inboxcount_func, | |||
int(*)(const char *context, const char *mailbox, const char *folder) | messagecount_func | |||
) |
Definition at line 152 of file app.c.
References ast_has_voicemail_func, ast_inboxcount_func, and ast_messagecount_func.
Referenced by load_module().
00155 { 00156 ast_has_voicemail_func = has_voicemail_func; 00157 ast_inboxcount_func = inboxcount_func; 00158 ast_messagecount_func = messagecount_func; 00159 }
int ast_ivr_menu_run | ( | struct ast_channel * | c, | |
struct ast_ivr_menu * | menu, | |||
void * | cbdata | |||
) |
Runs an IVR menu.
Definition at line 1373 of file app.c.
References ast_ivr_menu_run_internal().
Referenced by skel_exec().
01374 { 01375 int res = ast_ivr_menu_run_internal(chan, menu, cbdata); 01376 /* Hide internal coding */ 01377 return res > 0 ? 0 : res; 01378 }
int ast_linear_stream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
int | fd, | |||
int | allowoverride | |||
) |
Stream a filename (or file descriptor) as a generator.
Definition at line 346 of file app.c.
References linear_state::allowoverride, ast_activate_generator(), ast_calloc, ast_config_AST_DATA_DIR, ast_copy_string(), ast_log(), ast_strlen_zero(), linear_state::autoclose, errno, linear_state::fd, and LOG_WARNING.
00347 { 00348 struct linear_state *lin; 00349 char tmpf[256]; 00350 int res = -1; 00351 int autoclose = 0; 00352 if (fd < 0) { 00353 if (ast_strlen_zero(filename)) 00354 return -1; 00355 autoclose = 1; 00356 if (filename[0] == '/') 00357 ast_copy_string(tmpf, filename, sizeof(tmpf)); 00358 else 00359 snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", (char *)ast_config_AST_DATA_DIR, "sounds", filename); 00360 fd = open(tmpf, O_RDONLY); 00361 if (fd < 0){ 00362 ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno)); 00363 return -1; 00364 } 00365 } 00366 if ((lin = ast_calloc(1, sizeof(*lin)))) { 00367 lin->fd = fd; 00368 lin->allowoverride = allowoverride; 00369 lin->autoclose = autoclose; 00370 res = ast_activate_generator(chan, &linearstream, lin); 00371 } 00372 return res; 00373 }
enum AST_LOCK_RESULT ast_lock_path | ( | const char * | path | ) |
Lock a filesystem path.
path | the path to be locked |
Definition at line 1018 of file app.c.
References AST_LOCK_FAILURE, AST_LOCK_PATH_NOT_FOUND, AST_LOCK_SUCCESS, AST_LOCK_TIMEOUT, ast_log(), ast_random(), errno, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, and s.
Referenced by vm_lock_path().
01019 { 01020 char *s; 01021 char *fs; 01022 int res; 01023 int fd; 01024 int lp = strlen(path); 01025 time_t start; 01026 01027 if (!(s = alloca(lp + 10)) || !(fs = alloca(lp + 20))) { 01028 ast_log(LOG_WARNING, "Out of memory!\n"); 01029 return AST_LOCK_FAILURE; 01030 } 01031 01032 snprintf(fs, strlen(path) + 19, "%s/.lock-%08lx", path, ast_random()); 01033 fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, 0600); 01034 if (fd < 0) { 01035 ast_log(LOG_ERROR, "Unable to create lock file '%s': %s\n", path, strerror(errno)); 01036 return AST_LOCK_PATH_NOT_FOUND; 01037 } 01038 close(fd); 01039 01040 snprintf(s, strlen(path) + 9, "%s/.lock", path); 01041 start = time(NULL); 01042 while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5)) 01043 usleep(1); 01044 01045 unlink(fs); 01046 01047 if (res) { 01048 ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno)); 01049 return AST_LOCK_TIMEOUT; 01050 } else { 01051 if (option_debug) 01052 ast_log(LOG_DEBUG, "Locked path '%s'\n", path); 01053 return AST_LOCK_SUCCESS; 01054 } 01055 }
int ast_play_and_prepend | ( | struct ast_channel * | chan, | |
char * | playfile, | |||
char * | recordfile, | |||
int | maxtime_sec, | |||
char * | fmt, | |||
int * | duration, | |||
int | beep, | |||
int | silencethreshold, | |||
int | maxsilence_ms | |||
) |
Record a message and prepend the message to the given record file after playing the optional playfile (or a beep), storing the duration in 'duration' and with a maximum
permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults.
Definition at line 799 of file app.c.
References __ast_play_and_record().
Referenced by vm_forwardoptions().
00800 { 00801 return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf); 00802 }
int ast_play_and_record | ( | struct ast_channel * | chan, | |
const char * | playfile, | |||
const char * | recordfile, | |||
int | maxtime_sec, | |||
const char * | fmt, | |||
int * | duration, | |||
int | silencethreshold, | |||
int | maxsilence_ms, | |||
const char * | path | |||
) |
Record a file for a max amount of time (in seconds), in a given list of formats separated by '|', outputting the duration of the recording, and with a maximum
permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults. calls ast_unlock_path() on 'path' if passed
Definition at line 794 of file app.c.
References __ast_play_and_record().
Referenced by app_exec(), ast_record_review(), and conf_run().
00795 { 00796 return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf); 00797 }
int ast_play_and_record_full | ( | struct ast_channel * | chan, | |
const char * | playfile, | |||
const char * | recordfile, | |||
int | maxtime_sec, | |||
const char * | fmt, | |||
int * | duration, | |||
int | silencethreshold, | |||
int | maxsilence_ms, | |||
const char * | path, | |||
const char * | acceptdtmf, | |||
const char * | canceldtmf | |||
) |
Definition at line 789 of file app.c.
References __ast_play_and_record(), and S_OR.
Referenced by play_record_review().
00790 { 00791 return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, default_acceptdtmf), S_OR(canceldtmf, default_canceldtmf)); 00792 }
int ast_play_and_wait | ( | struct ast_channel * | chan, | |
const char * | fn | |||
) |
Play a stream and wait for a digit, returning the digit that was pressed
Definition at line 474 of file app.c.
References AST_DIGIT_ANY, ast_stopstream(), ast_streamfile(), and ast_waitstream().
Referenced by __ast_play_and_record(), advanced_options(), ast_record_review(), ast_say_counted_adjective(), ast_say_counted_noun(), dialout(), forward_message(), get_folder(), get_folder2(), leave_voicemail(), play_message_category(), play_message_duration(), play_record_review(), vm_authenticate(), vm_browse_messages_en(), vm_browse_messages_he(), vm_browse_messages_latin(), vm_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions(), vm_intro(), vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_he(), vm_intro_it(), vm_intro_multilang(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_se(), vm_newuser(), vm_options(), vm_play_folder_name(), vm_play_folder_name_gr(), vm_play_folder_name_pl(), vm_play_folder_name_ua(), vm_tempgreeting(), and vmauthenticate().
00475 { 00476 int d; 00477 d = ast_streamfile(chan, fn, chan->language); 00478 if (d) 00479 return d; 00480 d = ast_waitstream(chan, AST_DIGIT_ANY); 00481 ast_stopstream(chan); 00482 return d; 00483 }
char* ast_read_textfile | ( | const char * | file | ) |
Read a file into asterisk
Definition at line 1380 of file app.c.
References ast_log(), ast_malloc, errno, free, and LOG_WARNING.
Referenced by readfile_exec().
01381 { 01382 int fd; 01383 char *output = NULL; 01384 struct stat filesize; 01385 int count = 0; 01386 int res; 01387 if (stat(filename, &filesize) == -1) { 01388 ast_log(LOG_WARNING, "Error can't stat %s\n", filename); 01389 return NULL; 01390 } 01391 count = filesize.st_size + 1; 01392 fd = open(filename, O_RDONLY); 01393 if (fd < 0) { 01394 ast_log(LOG_WARNING, "Cannot open file '%s' for reading: %s\n", filename, strerror(errno)); 01395 return NULL; 01396 } 01397 if ((output = ast_malloc(count))) { 01398 res = read(fd, output, count - 1); 01399 if (res == count - 1) { 01400 output[res] = '\0'; 01401 } else { 01402 ast_log(LOG_WARNING, "Short read of %s (%d of %d): %s\n", filename, res, count - 1, strerror(errno)); 01403 free(output); 01404 output = NULL; 01405 } 01406 } 01407 close(fd); 01408 return output; 01409 }
int ast_record_review | ( | struct ast_channel * | chan, | |
const char * | playfile, | |||
const char * | recordfile, | |||
int | maxtime, | |||
const char * | fmt, | |||
int * | duration, | |||
const char * | path | |||
) |
Allow to record message and have a review option
Definition at line 1079 of file app.c.
References AST_DIGIT_ANY, ast_log(), ast_play_and_record(), ast_play_and_wait(), ast_stream_and_wait(), ast_verbose(), ast_waitfordigit(), LOG_WARNING, maxsilence, silencethreshold, and VERBOSE_PREFIX_3.
Referenced by conf_run().
01080 { 01081 int silencethreshold = 128; 01082 int maxsilence=0; 01083 int res = 0; 01084 int cmd = 0; 01085 int max_attempts = 3; 01086 int attempts = 0; 01087 int recorded = 0; 01088 int message_exists = 0; 01089 /* Note that urgent and private are for flagging messages as such in the future */ 01090 01091 /* barf if no pointer passed to store duration in */ 01092 if (duration == NULL) { 01093 ast_log(LOG_WARNING, "Error ast_record_review called without duration pointer\n"); 01094 return -1; 01095 } 01096 01097 cmd = '3'; /* Want to start by recording */ 01098 01099 while ((cmd >= 0) && (cmd != 't')) { 01100 switch (cmd) { 01101 case '1': 01102 if (!message_exists) { 01103 /* In this case, 1 is to record a message */ 01104 cmd = '3'; 01105 break; 01106 } else { 01107 ast_stream_and_wait(chan, "vm-msgsaved", chan->language, ""); 01108 cmd = 't'; 01109 return res; 01110 } 01111 case '2': 01112 /* Review */ 01113 ast_verbose(VERBOSE_PREFIX_3 "Reviewing the recording\n"); 01114 cmd = ast_stream_and_wait(chan, recordfile, chan->language, AST_DIGIT_ANY); 01115 break; 01116 case '3': 01117 message_exists = 0; 01118 /* Record */ 01119 if (recorded == 1) 01120 ast_verbose(VERBOSE_PREFIX_3 "Re-recording\n"); 01121 else 01122 ast_verbose(VERBOSE_PREFIX_3 "Recording\n"); 01123 recorded = 1; 01124 cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, path); 01125 if (cmd == -1) { 01126 /* User has hung up, no options to give */ 01127 return cmd; 01128 } 01129 if (cmd == '0') { 01130 break; 01131 } else if (cmd == '*') { 01132 break; 01133 } 01134 else { 01135 /* If all is well, a message exists */ 01136 message_exists = 1; 01137 cmd = 0; 01138 } 01139 break; 01140 case '4': 01141 case '5': 01142 case '6': 01143 case '7': 01144 case '8': 01145 case '9': 01146 case '*': 01147 case '#': 01148 cmd = ast_play_and_wait(chan, "vm-sorry"); 01149 break; 01150 default: 01151 if (message_exists) { 01152 cmd = ast_play_and_wait(chan, "vm-review"); 01153 } 01154 else { 01155 cmd = ast_play_and_wait(chan, "vm-torerecord"); 01156 if (!cmd) 01157 cmd = ast_waitfordigit(chan, 600); 01158 } 01159 01160 if (!cmd) 01161 cmd = ast_waitfordigit(chan, 6000); 01162 if (!cmd) { 01163 attempts++; 01164 } 01165 if (attempts > max_attempts) { 01166 cmd = 't'; 01167 } 01168 } 01169 } 01170 if (cmd == 't') 01171 cmd = 0; 01172 return cmd; 01173 }
void ast_replace_sigchld | ( | void | ) |
Replace the SIGCHLD handler.
Normally, Asterisk has a SIGCHLD handler that is cleaning up all zombie processes from forking elsewhere in Asterisk. However, if you want to wait*() on the process to retrieve information about it's exit status, then this signal handler needs to be temporaraly replaced.
Code that executes this function *must* call ast_unreplace_sigchld() after it is finished doing the wait*().
Definition at line 896 of file asterisk.c.
References ast_mutex_lock, ast_mutex_unlock, and safe_system_prev_handler.
Referenced by agi_exec_full(), and ast_safe_system().
00897 { 00898 unsigned int level; 00899 00900 ast_mutex_lock(&safe_system_lock); 00901 level = safe_system_level++; 00902 00903 /* only replace the handler if it has not already been done */ 00904 if (level == 0) { 00905 sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler); 00906 } 00907 00908 ast_mutex_unlock(&safe_system_lock); 00909 }
int ast_safe_system | ( | const char * | s | ) |
Safely spawn an external program while closing file descriptors
Definition at line 926 of file asterisk.c.
References ast_log(), ast_opt_high_priority, ast_replace_sigchld(), ast_set_priority(), ast_unreplace_sigchld(), errno, LOG_WARNING, WEXITSTATUS, and WIFEXITED.
Referenced by alarmreceiver_exec(), ast_monitor_change_fname(), ast_monitor_start(), ast_monitor_stop(), consolehandler(), filestream_destructor(), make_email_file(), mixmonitor_thread(), process_text_line(), remoteconsolehandler(), run_externnotify(), sendmail(), sendpage(), system_exec_helper(), and vm_change_password_shell().
00927 { 00928 pid_t pid; 00929 #ifdef HAVE_WORKING_FORK 00930 int x; 00931 #endif 00932 int res; 00933 struct rusage rusage; 00934 int status; 00935 00936 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK) 00937 ast_replace_sigchld(); 00938 00939 #ifdef HAVE_WORKING_FORK 00940 pid = fork(); 00941 #else 00942 pid = vfork(); 00943 #endif 00944 00945 if (pid == 0) { 00946 #ifdef HAVE_CAP 00947 cap_t cap = cap_from_text("cap_net_admin-eip"); 00948 00949 if (cap_set_proc(cap)) { 00950 /* Careful with order! Logging cannot happen after we close FDs */ 00951 ast_log(LOG_WARNING, "Unable to remove capabilities.\n"); 00952 } 00953 cap_free(cap); 00954 #endif 00955 #ifdef HAVE_WORKING_FORK 00956 if (ast_opt_high_priority) 00957 ast_set_priority(0); 00958 /* Close file descriptors and launch system command */ 00959 for (x = STDERR_FILENO + 1; x < 4096; x++) 00960 close(x); 00961 #endif 00962 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL); 00963 _exit(1); 00964 } else if (pid > 0) { 00965 for(;;) { 00966 res = wait4(pid, &status, 0, &rusage); 00967 if (res > -1) { 00968 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1; 00969 break; 00970 } else if (errno != EINTR) 00971 break; 00972 } 00973 } else { 00974 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno)); 00975 res = -1; 00976 } 00977 00978 ast_unreplace_sigchld(); 00979 #else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */ 00980 res = -1; 00981 #endif 00982 00983 return res; 00984 }
void ast_uninstall_vm_functions | ( | void | ) |
Definition at line 161 of file app.c.
References ast_has_voicemail_func, ast_inboxcount_func, and ast_messagecount_func.
Referenced by unload_module().
00162 { 00163 ast_has_voicemail_func = NULL; 00164 ast_inboxcount_func = NULL; 00165 ast_messagecount_func = NULL; 00166 }
int ast_unlock_path | ( | const char * | path | ) |
Unlock a path
Definition at line 1057 of file app.c.
References ast_log(), errno, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, and s.
Referenced by __ast_play_and_record(), close_mailbox(), copy_message(), count_messages(), leave_voicemail(), resequence_mailbox(), and save_to_folder().
01058 { 01059 char *s; 01060 int res; 01061 01062 if (!(s = alloca(strlen(path) + 10))) { 01063 ast_log(LOG_WARNING, "Out of memory!\n"); 01064 return -1; 01065 } 01066 01067 snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock"); 01068 01069 if ((res = unlink(s))) 01070 ast_log(LOG_ERROR, "Could not unlock path '%s': %s\n", path, strerror(errno)); 01071 else { 01072 if (option_debug) 01073 ast_log(LOG_DEBUG, "Unlocked path '%s'\n", path); 01074 } 01075 01076 return res; 01077 }
void ast_unreplace_sigchld | ( | void | ) |
Restore the SIGCHLD handler.
This function is called after a call to ast_replace_sigchld. It restores the SIGCHLD handler that cleans up any zombie processes.
Definition at line 911 of file asterisk.c.
References ast_mutex_lock, ast_mutex_unlock, and safe_system_prev_handler.
Referenced by agi_exec_full(), and ast_safe_system().
00912 { 00913 unsigned int level; 00914 00915 ast_mutex_lock(&safe_system_lock); 00916 level = --safe_system_level; 00917 00918 /* only restore the handler if we are the last one */ 00919 if (level == 0) { 00920 sigaction(SIGCHLD, &safe_system_prev_handler, NULL); 00921 } 00922 00923 ast_mutex_unlock(&safe_system_lock); 00924 }