![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
app.h File Reference
Definition in file app.h.
This graph shows which files directly or indirectly include this file:

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_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) - sizeof(args.argc)) / 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) - sizeof(args.argc)) / sizeof(args.argv[0])) |
| Performs the 'standard' argument separation process for an application. | |
| #define | GROUP_CATEGORY_PREFIX "GROUP" |
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, const 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_get_count (const char *group, const char *category) |
| 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_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) |
| 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. | |
|
|
Define an application argument.
Definition at line 226 of file app.h. Referenced by __login_exec(), add_agent(), astman_get_variables(), func_header_read(), function_agent(), oss_call(), oss_request(), pbx_builtin_background(), and pbx_builtin_waitexten(). |
|
|
Declares an application option that does not accept an argument.
|
|
|
Declares an application option that accepts an argument.
|
|
|
Declares an array of options for an application.
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_parseoptions(my_app_options, &opts, opt_args, options)) { LOCAL_USER_REMOVE(u); return -1; } } |
|
|
Value: struct { \ unsigned int argc; \ char *argv[0]; \ arglist \ } name
Definition at line 243 of file app.h. Referenced by __login_exec(), add_agent(), astman_get_variables(), func_header_read(), function_agent(), oss_call(), oss_request(), pbx_builtin_background(), and pbx_builtin_waitexten(). |
|
|
Value: static struct ast_ivr_option __options_##holder[] = foo;\ static struct ast_ivr_menu holder = { title, flags, __options_##holder } |
|
|
|
|
|
Performs the 'nonstandard' argument separation process for an application.
Definition at line 272 of file app.h. Referenced by add_agent(), function_agent(), oss_call(), and oss_request(). |
|
|
Performs the 'standard' argument separation process for an application.
Definition at line 259 of file app.h. Referenced by __login_exec(), astman_get_variables(), func_header_read(), pbx_builtin_background(), and pbx_builtin_waitexten(). |
|
|
Definition at line 208 of file app.h. Referenced by ast_app_group_get_count(), ast_app_group_match_get_count(), ast_app_group_split_group(), clone_variables(), and group_show_channels(). |
|
|
Callback function for IVR.
|
|
|
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;
|
|
|
Definition at line 188 of file app.h. 00188 { 00189 AST_LOCK_SUCCESS = 0, 00190 AST_LOCK_TIMEOUT = -1, 00191 AST_LOCK_PATH_NOT_FOUND = -2, 00192 AST_LOCK_FAILURE = -3, 00193 };
|
|
||||||||||||||||||||||||||||
|
Present a dialtone and collect a certain length extension.
Definition at line 63 of file app.c. References ast_get_indication_tone(), ast_ignore_pattern(), ast_log(), ast_matchmore_extension(), ast_playtones_start(), ast_playtones_stop(), ast_waitfordigit(), ind_tone_zone_sound::data, ast_pbx::dtimeout, LOG_NOTICE, ast_channel::pbx, and ast_channel::zone. Referenced by builtin_atxfer(), and builtin_blindtransfer(). 00064 { 00065 struct ind_tone_zone_sound *ts; 00066 int res=0, x=0; 00067 00068 if (maxlen > size) 00069 maxlen = size; 00070 00071 if (!timeout && chan->pbx) 00072 timeout = chan->pbx->dtimeout; 00073 else if (!timeout) 00074 timeout = 5; 00075 00076 ts = ast_get_indication_tone(chan->zone,"dial"); 00077 if (ts && ts->data[0]) 00078 res = ast_playtones_start(chan, 0, ts->data, 0); 00079 else 00080 ast_log(LOG_NOTICE,"Huh....? no dial for indications?\n"); 00081 00082 for (x = strlen(collect); x < maxlen; ) { 00083 res = ast_waitfordigit(chan, timeout); 00084 if (!ast_ignore_pattern(context, collect)) 00085 ast_playtones_stop(chan); 00086 if (res < 1) 00087 break; 00088 collect[x++] = res; 00089 if (!ast_matchmore_extension(chan, context, collect, 1, chan->cid.cid_num)) { 00090 if (collect[x-1] == '#') { 00091 /* Not a valid extension, ending in #, assume the # was to finish dialing */ 00092 collect[x-1] = '\0'; 00093 } 00094 break; 00095 } 00096 } 00097 if (res >= 0) 00098 res = ast_exists_extension(chan, context, collect, 1, chan->cid.cid_num) ? 1 : 0; 00099 return res; 00100 }
|
|
||||||||||||||||||||||||
|
Plays a stream and gets DTMF data from a channel.
Definition at line 108 of file app.c. References ast_readstring(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_pbx::dtimeout, ast_channel::pbx, ast_pbx::rtimeout, and strsep(). Referenced by __login_exec(). 00109 { 00110 int res = 0, to, fto; 00111 char *front, *filename; 00112 00113 /* XXX Merge with full version? XXX */ 00114 00115 if (maxlen) 00116 s[0] = '\0'; 00117 00118 if (!prompt) 00119 prompt=""; 00120 00121 filename = ast_strdupa(prompt); 00122 while ((front = strsep(&filename, "&"))) { 00123 if (!ast_strlen_zero(front)) { 00124 res = ast_streamfile(c, front, c->language); 00125 if (res) 00126 continue; 00127 } 00128 if (ast_strlen_zero(filename)) { 00129 /* set timeouts for the last prompt */ 00130 fto = c->pbx ? c->pbx->rtimeout * 1000 : 6000; 00131 to = c->pbx ? c->pbx->dtimeout * 1000 : 2000; 00132 00133 if (timeout > 0) 00134 fto = to = timeout; 00135 if (timeout < 0) 00136 fto = to = 1000000000; 00137 } else { 00138 /* there is more than one prompt, so 00139 get rid of the long timeout between 00140 prompts, and make it 50ms */ 00141 fto = 50; 00142 to = c->pbx ? c->pbx->dtimeout * 1000 : 2000; 00143 } 00144 res = ast_readstring(c, s, maxlen, to, fto, "#"); 00145 if (!ast_strlen_zero(s)) 00146 return res; 00147 } 00148 00149 return res; 00150 }
|
|
||||||||||||||||||||||||||||||||
|
Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions.
Definition at line 153 of file app.c. References ast_readstring_full(), and ast_streamfile(). Referenced by handle_getdata(). 00154 { 00155 int res, to, fto; 00156 if (prompt) { 00157 res = ast_streamfile(c, prompt, c->language); 00158 if (res < 0) 00159 return res; 00160 } 00161 fto = 6000; 00162 to = 2000; 00163 if (timeout > 0) 00164 fto = to = timeout; 00165 if (timeout < 0) 00166 fto = to = 1000000000; 00167 res = ast_readstring_full(c, s, maxlen, to, fto, "#", audiofd, ctrlfd); 00168 return res; 00169 }
|
|
||||||||||||
|
Get the current channel count of the specified group and category. Definition at line 832 of file app.c. References ast_channel_unlock, ast_channel_walk_locked(), ast_strlen_zero(), GROUP_CATEGORY_PREFIX, pbx_builtin_getvar_helper(), s, and S_OR. 00833 { 00834 struct ast_channel *chan; 00835 int count = 0; 00836 const char *test; 00837 char cat[80]; 00838 const char *s; 00839 00840 if (ast_strlen_zero(group)) 00841 return 0; 00842 00843 s = S_OR(category, GROUP_CATEGORY_PREFIX); 00844 ast_copy_string(cat, s, sizeof(cat)); 00845 00846 chan = NULL; 00847 while ((chan = ast_channel_walk_locked(chan)) != NULL) { 00848 test = pbx_builtin_getvar_helper(chan, cat); 00849 if (test && !strcasecmp(test, group)) 00850 count++; 00851 ast_channel_unlock(chan); 00852 } 00853 00854 return count; 00855 }
|
|
||||||||||||
|
Get the current channel count of all groups that match the specified pattern and category. Definition at line 857 of file app.c. References ast_channel_unlock, ast_channel_walk_locked(), ast_strlen_zero(), GROUP_CATEGORY_PREFIX, pbx_builtin_getvar_helper(), s, and S_OR. 00858 { 00859 regex_t regexbuf; 00860 struct ast_channel *chan; 00861 int count = 0; 00862 const char *test; 00863 char cat[80]; 00864 const char *s; 00865 00866 if (ast_strlen_zero(groupmatch)) 00867 return 0; 00868 00869 /* if regex compilation fails, return zero matches */ 00870 if (regcomp(®exbuf, groupmatch, REG_EXTENDED | REG_NOSUB)) 00871 return 0; 00872 00873 s = S_OR(category, GROUP_CATEGORY_PREFIX); 00874 ast_copy_string(cat, s, sizeof(cat)); 00875 00876 chan = NULL; 00877 while ((chan = ast_channel_walk_locked(chan)) != NULL) { 00878 test = pbx_builtin_getvar_helper(chan, cat); 00879 if (test && !regexec(®exbuf, test, 0, NULL, 0)) 00880 count++; 00881 ast_channel_unlock(chan); 00882 } 00883 00884 regfree(®exbuf); 00885 00886 return count; 00887 }
|
|
||||||||||||
|
Set the group for a channel, splitting the provided data into group and category, if specified. Definition at line 818 of file app.c. References ast_app_group_split_group(), group, and pbx_builtin_setvar_helper(). 00819 { 00820 int res=0; 00821 char group[80] = ""; 00822 char category[80] = ""; 00823 00824 if (!ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category))) { 00825 pbx_builtin_setvar_helper(chan, category, group); 00826 } else 00827 res = -1; 00828 00829 return res; 00830 }
|
|
||||||||||||||||||||||||
|
Split a group string into group and category, returning a default category if none is provided. Definition at line 789 of file app.c. References ast_strlen_zero(), and GROUP_CATEGORY_PREFIX. Referenced by ast_app_group_set_channel(). 00790 { 00791 int res=0; 00792 char tmp[256]; 00793 char *grp=NULL, *cat=NULL; 00794 00795 if (!ast_strlen_zero(data)) { 00796 ast_copy_string(tmp, data, sizeof(tmp)); 00797 grp = tmp; 00798 cat = strchr(tmp, '@'); 00799 if (cat) { 00800 *cat = '\0'; 00801 cat++; 00802 } 00803 } 00804 00805 if (!ast_strlen_zero(grp)) 00806 ast_copy_string(group, grp, group_max); 00807 else 00808 res = -1; 00809 00810 if (cat) 00811 snprintf(category, category_max, "%s_%s", GROUP_CATEGORY_PREFIX, cat); 00812 else 00813 ast_copy_string(category, GROUP_CATEGORY_PREFIX, category_max); 00814 00815 return res; 00816 }
|
|
||||||||||||
|
Determine if a given mailbox has any voicemail Definition at line 191 of file app.c. References ast_has_voicemail_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3. Referenced by action_mailboxstatus(), and has_voicemail(). 00192 { 00193 static int warned = 0; 00194 if (ast_has_voicemail_func) 00195 return ast_has_voicemail_func(mailbox, folder); 00196 00197 if ((option_verbose > 2) && !warned) { 00198 ast_verbose(VERBOSE_PREFIX_3 "Message check requested for mailbox %s/folder %s but voicemail not loaded.\n", mailbox, folder ? folder : "INBOX"); 00199 warned++; 00200 } 00201 return 0; 00202 }
|
|
||||||||||||||||
|
Determine number of new/old messages in a mailbox Definition at line 205 of file app.c. References ast_inboxcount_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3. Referenced by action_mailboxcount(), sip_send_mwi_to_peer(), and update_registry(). 00206 { 00207 static int warned = 0; 00208 if (newmsgs) 00209 *newmsgs = 0; 00210 if (oldmsgs) 00211 *oldmsgs = 0; 00212 if (ast_inboxcount_func) 00213 return ast_inboxcount_func(mailbox, newmsgs, oldmsgs); 00214 00215 if (!warned && (option_verbose > 2)) { 00216 warned++; 00217 ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s but voicemail not loaded.\n", mailbox); 00218 } 00219 00220 return 0; 00221 }
|
|
||||||||||||||||
|
Determine number of messages in a given mailbox and folder Definition at line 223 of file app.c. References ast_messagecount_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3. 00224 { 00225 static int warned = 0; 00226 if (ast_messagecount_func) 00227 return ast_messagecount_func(context, mailbox, folder); 00228 00229 if (!warned && (option_verbose > 2)) { 00230 warned++; 00231 ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s@%s/%s but voicemail not loaded.\n", mailbox, context, folder); 00232 } 00233 00234 return 0; 00235 }
|
|
||||||||||||||||||||
|
Parses a string containing application options and sets flags/arguments.
Definition at line 1324 of file app.c. References ast_app_option::arg_index, ast_clear_flag, AST_FLAGS_ALL, ast_log(), ast_set_flag, LOG_WARNING, and s. Referenced by pbx_builtin_background(), pbx_builtin_resetcdr(), and pbx_builtin_waitexten(). 01325 { 01326 char *s; 01327 int curarg; 01328 unsigned int argloc; 01329 char *arg; 01330 int res = 0; 01331 01332 ast_clear_flag(flags, AST_FLAGS_ALL); 01333 01334 if (!optstr) 01335 return 0; 01336 01337 s = optstr; 01338 while (*s) { 01339 curarg = *s++ & 0x7f; /* the array (in app.h) has 128 entries */ 01340 ast_set_flag(flags, options[curarg].flag); 01341 argloc = options[curarg].arg_index; 01342 if (*s == '(') { 01343 /* Has argument */ 01344 arg = ++s; 01345 if ((s = strchr(s, ')'))) { 01346 if (argloc) 01347 args[argloc - 1] = arg; 01348 *s++ = '\0'; 01349 } else { 01350 ast_log(LOG_WARNING, "Missing closing parenthesis for argument '%c' in string '%s'\n", curarg, arg); 01351 res = -1; 01352 break; 01353 } 01354 } else if (argloc) { 01355 args[argloc - 1] = NULL; 01356 } 01357 } 01358 01359 return res; 01360 }
|
|
||||||||||||||||||||
|
Separate a string into arguments in an array.
The array will be completely zeroed by this function before it populates any entries.
Definition at line 889 of file app.c. Referenced by pbx_builtin_setvar(). 00890 { 00891 int argc; 00892 char *scan; 00893 int paren = 0, quote = 0; 00894 00895 if (!buf || !array || !arraylen) 00896 return 0; 00897 00898 memset(array, 0, arraylen * sizeof(*array)); 00899 00900 scan = buf; 00901 00902 for (argc = 0; *scan && (argc < arraylen - 1); argc++) { 00903 array[argc] = scan; 00904 for (; *scan; scan++) { 00905 if (*scan == '(') 00906 paren++; 00907 else if (*scan == ')') { 00908 if (paren) 00909 paren--; 00910 } else if (*scan == '"' && delim != '"') { 00911 quote = quote ? 0 : 1; 00912 /* Remove quote character from argument */ 00913 memmove(scan, scan + 1, strlen(scan)); 00914 scan--; 00915 } else if (*scan == '\\') { 00916 /* Literal character, don't parse */ 00917 memmove(scan, scan + 1, strlen(scan)); 00918 } else if ((*scan == delim) && !paren && !quote) { 00919 *scan++ = '\0'; 00920 break; 00921 } 00922 } 00923 } 00924 00925 if (*scan) 00926 array[argc++] = scan; 00927 00928 return argc; 00929 }
|
|
||||||||||||||||||||||||||||||||||||
|
Stream a file with fast forward, pause, reverse, restart. Definition at line 385 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 handle_controlstreamfile(). 00389 { 00390 char *breaks = NULL; 00391 char *end = NULL; 00392 int blen = 2; 00393 int res; 00394 long pause_restart_point = 0; 00395 00396 if (stop) 00397 blen += strlen(stop); 00398 if (pause) 00399 blen += strlen(pause); 00400 if (restart) 00401 blen += strlen(restart); 00402 00403 if (blen > 2) { 00404 breaks = alloca(blen + 1); 00405 breaks[0] = '\0'; 00406 if (stop) 00407 strcat(breaks, stop); 00408 if (pause) 00409 strcat(breaks, pause); 00410 if (restart) 00411 strcat(breaks, restart); 00412 } 00413 if (chan->_state != AST_STATE_UP) 00414 res = ast_answer(chan); 00415 00416 if (file) { 00417 if ((end = strchr(file,':'))) { 00418 if (!strcasecmp(end, ":end")) { 00419 *end = '\0'; 00420 end++; 00421 } 00422 } 00423 } 00424 00425 for (;;) { 00426 ast_stopstream(chan); 00427 res = ast_streamfile(chan, file, chan->language); 00428 if (!res) { 00429 if (pause_restart_point) { 00430 ast_seekstream(chan->stream, pause_restart_point, SEEK_SET); 00431 pause_restart_point = 0; 00432 } 00433 else if (end) { 00434 ast_seekstream(chan->stream, 0, SEEK_END); 00435 end = NULL; 00436 }; 00437 res = ast_waitstream_fr(chan, breaks, fwd, rev, skipms); 00438 } 00439 00440 if (res < 1) 00441 break; 00442 00443 /* We go at next loop if we got the restart char */ 00444 if (restart && strchr(restart, res)) { 00445 if (option_debug) 00446 ast_log(LOG_DEBUG, "we'll restart the stream here at next loop\n"); 00447 pause_restart_point = 0; 00448 continue; 00449 } 00450 00451 if (pause && strchr(pause, res)) { 00452 pause_restart_point = ast_tellstream(chan->stream); 00453 for (;;) { 00454 ast_stopstream(chan); 00455 res = ast_waitfordigit(chan, 1000); 00456 if (!res) 00457 continue; 00458 else if (res == -1 || strchr(pause, res) || (stop && strchr(stop, res))) 00459 break; 00460 } 00461 if (res == *pause) { 00462 res = 0; 00463 continue; 00464 } 00465 } 00466 00467 if (res == -1) 00468 break; 00469 00470 /* if we get one of our stop chars, return it to the calling function */ 00471 if (stop && strchr(stop, res)) 00472 break; 00473 } 00474 00475 ast_stopstream(chan); 00476 00477 return res; 00478 }
|
|
||||||||||||||||||||
|
Send DTMF to a channel.
Definition at line 237 of file app.c. References ast_autoservice_start(), ast_safe_sleep(), and ast_waitfor(). Referenced by ast_bridge_call(), and misdn_send_digit(). 00238 { 00239 const char *ptr; 00240 int res = 0; 00241 00242 if (!between) 00243 between = 100; 00244 00245 if (peer) 00246 res = ast_autoservice_start(peer); 00247 00248 if (!res) 00249 res = ast_waitfor(chan, 100); 00250 00251 /* ast_waitfor will return the number of remaining ms on success */ 00252 if (res < 0) 00253 return res; 00254 00255 for (ptr = digits; *ptr; ptr++) { 00256 if (*ptr == 'w') { 00257 /* 'w' -- wait half a second */ 00258 if ((res = ast_safe_sleep(chan, 500))) 00259 break; 00260 } else if (strchr("0123456789*#abcdfABCDF", *ptr)) { 00261 /* Character represents valid DTMF */ 00262 if (*ptr == 'f' || *ptr == 'F') { 00263 /* ignore return values if not supported by channel */ 00264 ast_indicate(chan, AST_CONTROL_FLASH); 00265 } else 00266 ast_senddigit(chan, *ptr); 00267 /* pause between digits */ 00268 if ((res = ast_safe_sleep(chan, between))) 00269 break; 00270 } else 00271 ast_log(LOG_WARNING, "Illegal DTMF character '%c' in string. (0-9*#aAbBcCdD allowed)\n",*ptr); 00272 } 00273 00274 if (peer) { 00275 /* Stop autoservice on the peer channel, but don't overwrite any error condition 00276 that has occurred previously while acting on the primary channel */ 00277 if (ast_autoservice_stop(peer) && !res) 00278 res = -1; 00279 } 00280 00281 return res; 00282 }
|
|
||||||||||||||||
|
Definition at line 175 of file app.c. References ast_has_voicemail_func, ast_inboxcount_func, and ast_messagecount_func. 00178 { 00179 ast_has_voicemail_func = has_voicemail_func; 00180 ast_inboxcount_func = inboxcount_func; 00181 ast_messagecount_func = messagecount_func; 00182 }
|
|
||||||||||||||||
|
Runs an IVR menu.
Definition at line 1286 of file app.c. References ast_ivr_menu_run_internal(). 01287 { 01288 int res = ast_ivr_menu_run_internal(chan, menu, cbdata); 01289 /* Hide internal coding */ 01290 return res > 0 ? 0 : res; 01291 }
|
|
||||||||||||||||||||
|
Stream a filename (or file descriptor) as a generator. Definition at line 356 of file app.c. References ast_activate_generator(), ast_calloc, ast_config_AST_DATA_DIR, ast_log(), ast_strlen_zero(), linear_state::autoclose, linearstream, and LOG_WARNING. 00357 { 00358 struct linear_state *lin; 00359 char tmpf[256]; 00360 int res = -1; 00361 int autoclose = 0; 00362 if (fd < 0) { 00363 if (ast_strlen_zero(filename)) 00364 return -1; 00365 autoclose = 1; 00366 if (filename[0] == '/') 00367 ast_copy_string(tmpf, filename, sizeof(tmpf)); 00368 else 00369 snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", ast_config_AST_DATA_DIR, "sounds", filename); 00370 fd = open(tmpf, O_RDONLY); 00371 if (fd < 0){ 00372 ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno)); 00373 return -1; 00374 } 00375 } 00376 if ((lin = ast_calloc(1, sizeof(*lin)))) { 00377 lin->fd = fd; 00378 lin->allowoverride = allowoverride; 00379 lin->autoclose = autoclose; 00380 res = ast_activate_generator(chan, &linearstream, lin); 00381 } 00382 return res; 00383 }
|
|
|
Lock a filesystem path.
Definition at line 931 of file app.c. References AST_FILE_MODE, AST_LOCK_FAILURE, AST_LOCK_PATH_NOT_FOUND, AST_LOCK_SUCCESS, AST_LOCK_TIMEOUT, ast_log(), ast_random(), LOG_ERROR, LOG_WARNING, and s. 00932 { 00933 char *s; 00934 char *fs; 00935 int res; 00936 int fd; 00937 int lp = strlen(path); 00938 time_t start; 00939 00940 if (!(s = alloca(lp + 10)) || !(fs = alloca(lp + 20))) { 00941 ast_log(LOG_WARNING, "Out of memory!\n"); 00942 return AST_LOCK_FAILURE; 00943 } 00944 00945 snprintf(fs, strlen(path) + 19, "%s/.lock-%08lx", path, ast_random()); 00946 fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, AST_FILE_MODE); 00947 if (fd < 0) { 00948 ast_log(LOG_ERROR, "Unable to create lock file '%s': %s\n", path, strerror(errno)); 00949 return AST_LOCK_PATH_NOT_FOUND; 00950 } 00951 close(fd); 00952 00953 snprintf(s, strlen(path) + 9, "%s/.lock", path); 00954 start = time(NULL); 00955 while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5)) 00956 usleep(1); 00957 00958 unlink(fs); 00959 00960 if (res) { 00961 ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno)); 00962 return AST_LOCK_TIMEOUT; 00963 } else { 00964 if (option_debug) 00965 ast_log(LOG_DEBUG, "Locked path '%s'\n", path); 00966 return AST_LOCK_SUCCESS; 00967 } 00968 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
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 Definition at line 782 of file app.c. References __ast_play_and_record(). 00783 { 00784 return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf); 00785 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
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 Definition at line 777 of file app.c. References __ast_play_and_record(). Referenced by ast_record_review(). 00778 { 00779 return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf); 00780 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 772 of file app.c. References __ast_play_and_record(), and S_OR. 00773 { 00774 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)); 00775 }
|
|
||||||||||||
|
Play a stream and wait for a digit, returning the digit that was pressed Definition at line 480 of file app.c. References AST_DIGIT_ANY, ast_stopstream(), ast_streamfile(), and ast_waitstream(). Referenced by __ast_play_and_record(), and ast_record_review(). 00481 { 00482 int d; 00483 d = ast_streamfile(chan, fn, chan->language); 00484 if (d) 00485 return d; 00486 d = ast_waitstream(chan, AST_DIGIT_ANY); 00487 ast_stopstream(chan); 00488 return d; 00489 }
|
|
|
Read a file into asterisk Definition at line 1293 of file app.c. References ast_log(), ast_malloc, free, and LOG_WARNING. 01294 { 01295 int fd; 01296 char *output = NULL; 01297 struct stat filesize; 01298 int count = 0; 01299 int res; 01300 if (stat(filename, &filesize) == -1) { 01301 ast_log(LOG_WARNING, "Error can't stat %s\n", filename); 01302 return NULL; 01303 } 01304 count = filesize.st_size + 1; 01305 fd = open(filename, O_RDONLY); 01306 if (fd < 0) { 01307 ast_log(LOG_WARNING, "Cannot open file '%s' for reading: %s\n", filename, strerror(errno)); 01308 return NULL; 01309 } 01310 if ((output = ast_malloc(count))) { 01311 res = read(fd, output, count - 1); 01312 if (res == count - 1) { 01313 output[res] = '\0'; 01314 } else { 01315 ast_log(LOG_WARNING, "Short read of %s (%d of %d): %s\n", filename, res, count - 1, strerror(errno)); 01316 free(output); 01317 output = NULL; 01318 } 01319 } 01320 close(fd); 01321 return output; 01322 }
|
|
||||||||||||||||||||||||||||||||
|
Allow to record message and have a review option Definition at line 992 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, silencethreshold, and VERBOSE_PREFIX_3. 00993 { 00994 int silencethreshold = 128; 00995 int maxsilence=0; 00996 int res = 0; 00997 int cmd = 0; 00998 int max_attempts = 3; 00999 int attempts = 0; 01000 int recorded = 0; 01001 int message_exists = 0; 01002 /* Note that urgent and private are for flagging messages as such in the future */ 01003 01004 /* barf if no pointer passed to store duration in */ 01005 if (duration == NULL) { 01006 ast_log(LOG_WARNING, "Error ast_record_review called without duration pointer\n"); 01007 return -1; 01008 } 01009 01010 cmd = '3'; /* Want to start by recording */ 01011 01012 while ((cmd >= 0) && (cmd != 't')) { 01013 switch (cmd) { 01014 case '1': 01015 if (!message_exists) { 01016 /* In this case, 1 is to record a message */ 01017 cmd = '3'; 01018 break; 01019 } else { 01020 ast_stream_and_wait(chan, "vm-msgsaved", ""); 01021 cmd = 't'; 01022 return res; 01023 } 01024 case '2': 01025 /* Review */ 01026 ast_verbose(VERBOSE_PREFIX_3 "Reviewing the recording\n"); 01027 cmd = ast_stream_and_wait(chan, recordfile, AST_DIGIT_ANY); 01028 break; 01029 case '3': 01030 message_exists = 0; 01031 /* Record */ 01032 if (recorded == 1) 01033 ast_verbose(VERBOSE_PREFIX_3 "Re-recording\n"); 01034 else 01035 ast_verbose(VERBOSE_PREFIX_3 "Recording\n"); 01036 recorded = 1; 01037 cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, path); 01038 if (cmd == -1) { 01039 /* User has hung up, no options to give */ 01040 return cmd; 01041 } 01042 if (cmd == '0') { 01043 break; 01044 } else if (cmd == '*') { 01045 break; 01046 } 01047 else { 01048 /* If all is well, a message exists */ 01049 message_exists = 1; 01050 cmd = 0; 01051 } 01052 break; 01053 case '4': 01054 case '5': 01055 case '6': 01056 case '7': 01057 case '8': 01058 case '9': 01059 case '*': 01060 case '#': 01061 cmd = ast_play_and_wait(chan, "vm-sorry"); 01062 break; 01063 default: 01064 if (message_exists) { 01065 cmd = ast_play_and_wait(chan, "vm-review"); 01066 } 01067 else { 01068 cmd = ast_play_and_wait(chan, "vm-torerecord"); 01069 if (!cmd) 01070 cmd = ast_waitfordigit(chan, 600); 01071 } 01072 01073 if (!cmd) 01074 cmd = ast_waitfordigit(chan, 6000); 01075 if (!cmd) { 01076 attempts++; 01077 } 01078 if (attempts > max_attempts) { 01079 cmd = 't'; 01080 } 01081 } 01082 } 01083 if (cmd == 't') 01084 cmd = 0; 01085 return cmd; 01086 }
|
|
|
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 temporarily replaced. Code that executes this function *must* call ast_unreplace_sigchld() after it is finished doing the wait*(). Definition at line 617 of file asterisk.c. References ast_mutex_lock(), ast_mutex_unlock(), and null_sig_handler(). Referenced by ast_safe_system(). 00618 { 00619 unsigned int level; 00620 00621 ast_mutex_lock(&safe_system_lock); 00622 level = safe_system_level++; 00623 00624 /* only replace the handler if it has not already been done */ 00625 if (level == 0) 00626 safe_system_prev_handler = signal(SIGCHLD, null_sig_handler); 00627 00628 ast_mutex_unlock(&safe_system_lock); 00629 }
|
|
|
Safely spawn an external program while closing file descriptors
Definition at line 645 of file asterisk.c. References ast_opt_high_priority, ast_replace_sigchld(), and ast_set_priority(). Referenced by ast_closestream(), ast_monitor_change_fname(), ast_monitor_start(), ast_monitor_stop(), consolehandler(), process_text_line(), and remoteconsolehandler(). 00646 { 00647 pid_t pid; 00648 #ifdef HAVE_WORKING_FORK 00649 int x; 00650 #endif 00651 int res; 00652 struct rusage rusage; 00653 int status; 00654 00655 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK) 00656 ast_replace_sigchld(); 00657 00658 #ifdef HAVE_WORKING_FORK 00659 pid = fork(); 00660 #else 00661 pid = vfork(); 00662 #endif 00663 00664 if (pid == 0) { 00665 #ifdef HAVE_WORKING_FORK 00666 if (ast_opt_high_priority) 00667 ast_set_priority(0); 00668 /* Close file descriptors and launch system command */ 00669 for (x = STDERR_FILENO + 1; x < 4096; x++) 00670 close(x); 00671 #endif 00672 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL); 00673 _exit(1); 00674 } else if (pid > 0) { 00675 for (;;) { 00676 res = wait4(pid, &status, 0, &rusage); 00677 if (res > -1) { 00678 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1; 00679 break; 00680 } else if (errno != EINTR) 00681 break; 00682 } 00683 } else { 00684 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno)); 00685 res = -1; 00686 } 00687 00688 ast_unreplace_sigchld(); 00689 #else 00690 res = -1; 00691 #endif 00692 00693 return res; 00694 }
|
|
|
Definition at line 184 of file app.c. References ast_has_voicemail_func, ast_inboxcount_func, and ast_messagecount_func. 00185 { 00186 ast_has_voicemail_func = NULL; 00187 ast_inboxcount_func = NULL; 00188 ast_messagecount_func = NULL; 00189 }
|
|
|
Unlock a path Definition at line 970 of file app.c. References ast_log(), LOG_ERROR, LOG_WARNING, and s. 00971 { 00972 char *s; 00973 int res; 00974 00975 if (!(s = alloca(strlen(path) + 10))) { 00976 ast_log(LOG_WARNING, "Out of memory!\n"); 00977 return -1; 00978 } 00979 00980 snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock"); 00981 00982 if ((res = unlink(s))) 00983 ast_log(LOG_ERROR, "Could not unlock path '%s': %s\n", path, strerror(errno)); 00984 else { 00985 if (option_debug) 00986 ast_log(LOG_DEBUG, "Unlocked path '%s'\n", path); 00987 } 00988 00989 return res; 00990 }
|
|
|
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 631 of file asterisk.c. References ast_mutex_lock(), and ast_mutex_unlock(). Referenced by agi_exec_full(). 00632 { 00633 unsigned int level; 00634 00635 ast_mutex_lock(&safe_system_lock); 00636 level = --safe_system_level; 00637 00638 /* only restore the handler if we are the last one */ 00639 if (level == 0) 00640 signal(SIGCHLD, safe_system_prev_handler); 00641 00642 ast_mutex_unlock(&safe_system_lock); 00643 }
|