![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
app.c File Reference
Definition in file app.c.
#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/file.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/indications.h"
Include dependency graph for app.c:

Go to the source code of this file.
Data Structures | |
| struct | linear_state |
Defines | |
| #define | MAX_OTHER_FORMATS 10 |
| #define | RES_EXIT (1 << 17) |
| #define | RES_REPEAT (1 << 18) |
| #define | RES_RESTART ((1 << 19) | RES_REPEAT) |
| #define | RES_UPONE (1 << 16) |
Functions | |
| static int | __ast_play_and_record (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf) |
| 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 *chan, struct ast_ivr_menu *menu, void *cbdata) |
| Runs an IVR menu. | |
| static int | ast_ivr_menu_run_internal (struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata) |
| 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, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence) |
| int | ast_play_and_record (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, const char *path) |
| int | ast_play_and_record_full (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int silencethreshold, int maxsilence, 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 *filename) |
| 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_uninstall_vm_functions (void) |
| int | ast_unlock_path (const char *path) |
| static int | ivr_dispatch (struct ast_channel *chan, struct ast_ivr_option *option, char *exten, void *cbdata) |
| static void * | linear_alloc (struct ast_channel *chan, void *params) |
| static int | linear_generator (struct ast_channel *chan, void *data, int len, int samples) |
| static void | linear_release (struct ast_channel *chan, void *params) |
| static int | option_exists (struct ast_ivr_menu *menu, char *option) |
| static int | option_matchmore (struct ast_ivr_menu *menu, char *option) |
| static int | read_newoption (struct ast_channel *chan, struct ast_ivr_menu *menu, char *exten, int maxexten) |
Variables | |
| static int(* | ast_has_voicemail_func )(const char *mailbox, const char *folder) = NULL |
| static int(* | ast_inboxcount_func )(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL |
| static int(* | ast_messagecount_func )(const char *context, const char *mailbox, const char *folder) = NULL |
| static char | default_acceptdtmf [] = "#" |
| static char | default_canceldtmf [] = "" |
| static int | global_maxsilence = 0 |
| static int | global_silence_threshold = 128 |
| static struct ast_generator | linearstream |
|
|
Definition at line 53 of file app.c. Referenced by __ast_play_and_record(). |
|
|
Definition at line 1089 of file app.c. Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch(). |
|
|
Definition at line 1090 of file app.c. Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch(). |
|
|
Definition at line 1091 of file app.c. Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch(). |
|
|
Definition at line 1088 of file app.c. Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch(). |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Optionally play a sound file or a beep, then record audio and video from the channel.
Definition at line 510 of file app.c. References AST_FILE_MODE, ast_log(), ast_play_and_wait(), ast_strdupa, ast_stream_and_wait(), ast_verbose(), ast_writefile(), LOG_DEBUG, LOG_WARNING, MAX_OTHER_FORMATS, option_debug, option_verbose, strsep(), ast_dsp::totalsilence, and VERBOSE_PREFIX_3. Referenced by ast_play_and_prepend(), ast_play_and_record(), and ast_play_and_record_full(). 00511 { 00512 int d = 0; 00513 char *fmts; 00514 char comment[256]; 00515 int x, fmtcnt = 1, res = -1, outmsg = 0; 00516 struct ast_filestream *others[MAX_OTHER_FORMATS]; 00517 char *sfmt[MAX_OTHER_FORMATS]; 00518 char *stringp = NULL; 00519 time_t start, end; 00520 struct ast_dsp *sildet = NULL; /* silence detector dsp */ 00521 int totalsilence = 0; 00522 int rfmt = 0; 00523 struct ast_silence_generator *silgen = NULL; 00524 char prependfile[80]; 00525 00526 if (silencethreshold < 0) 00527 silencethreshold = global_silence_threshold; 00528 00529 if (maxsilence < 0) 00530 maxsilence = global_maxsilence; 00531 00532 /* barf if no pointer passed to store duration in */ 00533 if (duration == NULL) { 00534 ast_log(LOG_WARNING, "Error play_and_record called without duration pointer\n"); 00535 return -1; 00536 } 00537 00538 if (option_debug) 00539 ast_log(LOG_DEBUG,"play_and_record: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt); 00540 snprintf(comment, sizeof(comment), "Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, chan->name); 00541 00542 if (playfile || beep) { 00543 if (!beep) 00544 d = ast_play_and_wait(chan, playfile); 00545 if (d > -1) 00546 d = ast_stream_and_wait(chan, "beep", ""); 00547 if (d < 0) 00548 return -1; 00549 } 00550 00551 if (prepend) { 00552 ast_copy_string(prependfile, recordfile, sizeof(prependfile)); 00553 strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1); 00554 } 00555 00556 fmts = ast_strdupa(fmt); 00557 00558 stringp = fmts; 00559 strsep(&stringp, "|"); 00560 if (option_debug) 00561 ast_log(LOG_DEBUG, "Recording Formats: sfmts=%s\n", fmts); 00562 sfmt[0] = ast_strdupa(fmts); 00563 00564 while ((fmt = strsep(&stringp, "|"))) { 00565 if (fmtcnt > MAX_OTHER_FORMATS - 1) { 00566 ast_log(LOG_WARNING, "Please increase MAX_OTHER_FORMATS in app.c\n"); 00567 break; 00568 } 00569 sfmt[fmtcnt++] = ast_strdupa(fmt); 00570 } 00571 00572 end = start = time(NULL); /* pre-initialize end to be same as start in case we never get into loop */ 00573 for (x = 0; x < fmtcnt; x++) { 00574 others[x] = ast_writefile(prepend ? prependfile : recordfile, sfmt[x], comment, O_TRUNC, 0, AST_FILE_MODE); 00575 if (option_verbose > 2) 00576 ast_verbose(VERBOSE_PREFIX_3 "x=%d, open writing: %s format: %s, %p\n", x, prepend ? prependfile : recordfile, sfmt[x], others[x]); 00577 00578 if (!others[x]) 00579 break; 00580 } 00581 00582 if (path) 00583 ast_unlock_path(path); 00584 00585 if (maxsilence > 0) { 00586 sildet = ast_dsp_new(); /* Create the silence detector */ 00587 if (!sildet) { 00588 ast_log(LOG_WARNING, "Unable to create silence detector :(\n"); 00589 return -1; 00590 } 00591 ast_dsp_set_threshold(sildet, silencethreshold); 00592 rfmt = chan->readformat; 00593 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00594 if (res < 0) { 00595 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n"); 00596 ast_dsp_free(sildet); 00597 return -1; 00598 } 00599 } 00600 00601 if (!prepend) { 00602 /* Request a video update */ 00603 ast_indicate(chan, AST_CONTROL_VIDUPDATE); 00604 00605 if (ast_opt_transmit_silence) 00606 silgen = ast_channel_start_silence_generator(chan); 00607 } 00608 00609 if (x == fmtcnt) { 00610 /* Loop forever, writing the packets we read to the writer(s), until 00611 we read a digit or get a hangup */ 00612 struct ast_frame *f; 00613 for (;;) { 00614 res = ast_waitfor(chan, 2000); 00615 if (!res) { 00616 if (option_debug) 00617 ast_log(LOG_DEBUG, "One waitfor failed, trying another\n"); 00618 /* Try one more time in case of masq */ 00619 res = ast_waitfor(chan, 2000); 00620 if (!res) { 00621 ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name); 00622 res = -1; 00623 } 00624 } 00625 00626 if (res < 0) { 00627 f = NULL; 00628 break; 00629 } 00630 f = ast_read(chan); 00631 if (!f) 00632 break; 00633 if (f->frametype == AST_FRAME_VOICE) { 00634 /* write each format */ 00635 for (x = 0; x < fmtcnt; x++) { 00636 if (prepend && !others[x]) 00637 break; 00638 res = ast_writestream(others[x], f); 00639 } 00640 00641 /* Silence Detection */ 00642 if (maxsilence > 0) { 00643 int dspsilence = 0; 00644 ast_dsp_silence(sildet, f, &dspsilence); 00645 if (dspsilence) 00646 totalsilence = dspsilence; 00647 else 00648 totalsilence = 0; 00649 00650 if (totalsilence > maxsilence) { 00651 /* Ended happily with silence */ 00652 if (option_verbose > 2) 00653 ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000); 00654 res = 'S'; 00655 outmsg = 2; 00656 break; 00657 } 00658 } 00659 /* Exit on any error */ 00660 if (res) { 00661 ast_log(LOG_WARNING, "Error writing frame\n"); 00662 break; 00663 } 00664 } else if (f->frametype == AST_FRAME_VIDEO) { 00665 /* Write only once */ 00666 ast_writestream(others[0], f); 00667 } else if (f->frametype == AST_FRAME_DTMF) { 00668 if (prepend) { 00669 /* stop recording with any digit */ 00670 if (option_verbose > 2) 00671 ast_verbose(VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass); 00672 res = 't'; 00673 outmsg = 2; 00674 break; 00675 } 00676 if (strchr(acceptdtmf, f->subclass)) { 00677 if (option_verbose > 2) 00678 ast_verbose(VERBOSE_PREFIX_3 "User ended message by pressing %c\n", f->subclass); 00679 res = f->subclass; 00680 outmsg = 2; 00681 break; 00682 } 00683 if (strchr(canceldtmf, f->subclass)) { 00684 if (option_verbose > 2) 00685 ast_verbose(VERBOSE_PREFIX_3 "User cancelled message by pressing %c\n", f->subclass); 00686 res = f->subclass; 00687 outmsg = 0; 00688 break; 00689 } 00690 } 00691 if (maxtime) { 00692 end = time(NULL); 00693 if (maxtime < (end - start)) { 00694 if (option_verbose > 2) 00695 ast_verbose(VERBOSE_PREFIX_3 "Took too long, cutting it short...\n"); 00696 res = 't'; 00697 outmsg = 2; 00698 break; 00699 } 00700 } 00701 ast_frfree(f); 00702 } 00703 if (!f) { 00704 if (option_verbose > 2) 00705 ast_verbose(VERBOSE_PREFIX_3 "User hung up\n"); 00706 res = -1; 00707 outmsg = 1; 00708 } else { 00709 ast_frfree(f); 00710 } 00711 if (end == start) 00712 end = time(NULL); 00713 } else { 00714 ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", recordfile, sfmt[x]); 00715 } 00716 00717 if (!prepend) { 00718 if (silgen) 00719 ast_channel_stop_silence_generator(chan, silgen); 00720 } 00721 *duration = end - start; 00722 00723 if (!prepend) { 00724 for (x = 0; x < fmtcnt; x++) { 00725 if (!others[x]) 00726 break; 00727 if (res > 0) 00728 ast_stream_rewind(others[x], totalsilence ? totalsilence - 200 : 200); 00729 ast_truncstream(others[x]); 00730 ast_closestream(others[x]); 00731 } 00732 } 00733 00734 if (prepend && outmsg) { 00735 struct ast_filestream *realfiles[MAX_OTHER_FORMATS]; 00736 struct ast_frame *fr; 00737 00738 for (x = 0; x < fmtcnt; x++) { 00739 snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]); 00740 realfiles[x] = ast_readfile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0); 00741 if (!others[x] || !realfiles[x]) 00742 break; 00743 ast_stream_rewind(others[x], totalsilence ? totalsilence - 200 : 200); 00744 ast_truncstream(others[x]); 00745 /* add the original file too */ 00746 while ((fr = ast_readframe(realfiles[x]))) { 00747 ast_writestream(others[x], fr); 00748 ast_frfree(fr); 00749 } 00750 ast_closestream(others[x]); 00751 ast_closestream(realfiles[x]); 00752 ast_filerename(prependfile, recordfile, sfmt[x]); 00753 if (option_verbose > 3) 00754 ast_verbose(VERBOSE_PREFIX_4 "Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x], prependfile, recordfile); 00755 ast_filedelete(prependfile, sfmt[x]); 00756 } 00757 } 00758 if (rfmt && ast_set_read_format(chan, rfmt)) { 00759 ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name); 00760 } 00761 if (outmsg == 2) { 00762 ast_stream_and_wait(chan, "auth-thankyou", ""); 00763 } 00764 if (sildet) 00765 ast_dsp_free(sildet); 00766 return res; 00767 }
|
|
||||||||||||||||||||||||||||
|
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 }
|
|
||||||||||||||||||||||||||||||||||||