Mon Mar 31 07:38:10 2008

Asterisk developer's documentation


app.h File Reference

Application convenience functions, designed to give consistent look and feel to Asterisk apps. More...

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_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)
ast_group_infoast_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)
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.


Detailed Description

Application convenience functions, designed to give consistent look and feel to Asterisk apps.

Definition in file app.h.


Define Documentation

#define AST_APP_ARG ( name   )     char *name

Define an application argument.

Parameters:
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(), bridge_exec(), cdr_read(), cdr_write(), chanavail_exec(), checkmd5(), conf_exec(), count_exec(), cut_internal(), dictate_exec(), directory_exec(), disa_exec(), filter(), find_conf(), 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(), gosub_exec(), gosubif_exec(), hasvoicemail_exec(), isAnsweringMachine(), math(), misdn_check_l2l1(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), pbx_builtin_background(), 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.

Parameters:
option The single character representing the option
flagno The flag index to be set if this option is present
See also:
AST_APP_OPTIONS, ast_app_parse_options

Definition at line 389 of file app.h.

#define AST_APP_OPTION_ARG ( option,
flagno,
argno   )     [option] = { .flag = flagno, .arg_index = argno + 1 }

Declares an application option that accepts an argument.

Parameters:
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
See also:
AST_APP_OPTIONS, ast_app_parse_options

Definition at line 400 of file app.h.

#define AST_APP_OPTIONS ( holder,
options...   )     static const struct ast_app_option holder[128] = options

Declares an array of options for an application.

Parameters:
holder The name of the array to be created
options The actual options to be placed into the array
See also:
ast_app_parse_options
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_parseoptions(my_app_options, &opts, opt_args, options)) {
      LOCAL_USER_REMOVE(u);
      return -1;
   }
  }

Definition at line 380 of file app.h.

#define AST_DECLARE_APP_ARGS ( name,
arglist   ) 

Value:

struct { \
      unsigned int argc; \
      char *argv[0]; \
      arglist \
   } name
Declare a structure to hold the application's arguments.

Parameters:
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).

Note:
The structure is not initialized, as the call to ast_app_separate_args() will perform that function before parsing the arguments.

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(), bridge_exec(), cdr_read(), cdr_write(), chanavail_exec(), checkmd5(), conf_exec(), count_exec(), cut_internal(), dictate_exec(), directory_exec(), disa_exec(), filter(), find_conf(), 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(), gosub_exec(), gosubif_exec(), hasvoicemail_exec(), isAnsweringMachine(), math(), misdn_check_l2l1(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), pbx_builtin_background(), 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...   ) 

Value:

static struct ast_ivr_option __options_##holder[] = foo;\
   static struct ast_ivr_menu holder = { title, flags, __options_##holder }

Definition at line 76 of file app.h.

#define AST_IVR_FLAG_AUTORESTART   (1 << 0)

Definition at line 74 of file app.h.

#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.

Parameters:
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(), gosubif_exec(), 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.

Parameters:
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(), bridge_exec(), cdr_read(), cdr_write(), chanavail_exec(), checkmd5(), conf_exec(), count_exec(), cut_internal(), dictate_exec(), directory_exec(), disa_exec(), filter(), func_header_read(), function_enum(), function_fieldqty(), function_realtime_read(), function_realtime_write(), gosub_exec(), hasvoicemail_exec(), isAnsweringMachine(), math(), misdn_check_l2l1(), mixmonitor_exec(), ospauth_exec(), ospfinished_exec(), osplookup_exec(), ospnext_exec(), pbx_builtin_background(), 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().

#define BEGIN_OPTIONS   {

Definition at line 329 of file app.h.

#define END_OPTIONS   }

Definition at line 330 of file app.h.


Typedef Documentation

typedef int(*) ast_ivr_callback(struct ast_channel *chan, char *option, void *cbdata)

Callback function for IVR.

Returns:
returns 0 on completion, -1 on hangup or digit if interrupted

Definition at line 35 of file app.h.


Enumeration Type Documentation

enum ast_ivr_action

Enumerator:
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

Enumerator:
AST_LOCK_SUCCESS 
AST_LOCK_TIMEOUT 
AST_LOCK_PATH_NOT_FOUND 
AST_LOCK_FAILURE 

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 };


Function Documentation

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.

Returns:
Returns 1 on valid extension entered, -1 on hangup, or 0 on invalid extension.
Note:
Note that if 'collect' holds digits already, new digits will be appended, so be sure it's initialized properly

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.

Parameters:
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_DIGIT_ANY, ast_readstring(), ast_stopstream(), ast_strdupa, ast_streamfile(), ast_waitstream(), ast_pbx::dtimeout, ast_channel::pbx, result, ast_pbx::rtimeout, and strsep().

Referenced by __login_exec(), auth_exec(), conf_exec(), dictate_exec(), find_conf(), read_exec(), testclient_exec(), testserver_exec(), and vm_exec().

00108 {
00109    int res=0,to,fto, result=0;
00110    /* XXX Merge with full version? XXX */
00111    if (maxlen)
00112       s[0] = '\0';
00113    if (prompt) {
00114                 char *front;
00115                 char *temp = ast_strdupa(prompt);
00116                 while(!res && (front = strsep(&temp, "&"))) {
00117                         if( (res = ast_streamfile(c, front, c->language)) ) {
00118             res = 0;
00119             break;
00120          }
00121          if(!res && !result)
00122             result = ast_waitstream(c, AST_DIGIT_ANY);
00123          if(result)
00124             break;
00125          ast_stopstream(c);
00126                 }
00127    }
00128    fto = c->pbx ? c->pbx->rtimeout * 1000 : 6000;
00129    to = c->pbx ? c->pbx->dtimeout * 1000 : 2000;
00130 
00131    if (timeout > 0) 
00132       fto = to = timeout;
00133    if (timeout < 0) 
00134       fto = to = 1000000000;
00135    res = ast_readstring(c, s, maxlen, to, fto, "#");
00136    if(result) {
00137       char tmp[256];
00138       snprintf(tmp, sizeof(tmp), "%c%s", result, s);
00139       snprintf(s, sizeof(tmp), "%s", tmp);
00140    }
00141    return res;
00142 }

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 145 of file app.c.

References ast_readstring_full(), and ast_streamfile().

Referenced by handle_getdata().

00146 {
00147    int res, to, fto;
00148    if (prompt) {
00149       res = ast_streamfile(c, prompt, c->language);
00150       if (res < 0)
00151          return res;
00152    }
00153    fto = 6000;
00154    to = 2000;
00155    if (timeout > 0) 
00156       fto = to = timeout;
00157    if (timeout < 0) 
00158       fto = to = 1000000000;
00159    res = ast_readstring_full(c, s, maxlen, to, fto, "#", audiofd, ctrlfd);
00160    return res;
00161 }

int ast_app_group_discard ( struct ast_channel chan  ) 

Discard all group counting for a channel

Definition at line 946 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().

00947 {
00948    struct ast_group_info *gi = NULL;
00949    
00950    AST_LIST_LOCK(&groups);
00951    AST_LIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) {
00952       if (gi->chan == chan) {
00953          AST_LIST_REMOVE_CURRENT(&groups, list);
00954          free(gi);
00955       }
00956    }
00957         AST_LIST_TRAVERSE_SAFE_END
00958    AST_LIST_UNLOCK(&groups);
00959    
00960    return 0;
00961 }

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 889 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().

00890 {
00891    struct ast_group_info *gi = NULL;
00892    int count = 0;
00893 
00894    if (ast_strlen_zero(group))
00895       return 0;
00896    
00897    AST_LIST_LOCK(&groups);
00898    AST_LIST_TRAVERSE(&groups, gi, list) {
00899       if (!strcasecmp(gi->group, group) && (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category))))
00900          count++;
00901    }
00902    AST_LIST_UNLOCK(&groups);
00903 
00904    return count;
00905 }

struct ast_group_info* ast_app_group_list_head ( void   ) 

Get the head of the group count list

Definition at line 968 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().

00969 {
00970    return AST_LIST_FIRST(&groups);
00971 }

int ast_app_group_list_lock ( void   ) 

Lock the group count list

Definition at line 963 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().

00964 {
00965    return AST_LIST_LOCK(&groups);
00966 }

int ast_app_group_list_unlock ( void   ) 

Unlock the group count list

Definition at line 973 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().

00974 {
00975    return AST_LIST_UNLOCK(&groups);
00976 }

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 907 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().

00908 {
00909    struct ast_group_info *gi = NULL;
00910    regex_t regexbuf;
00911    int count = 0;
00912 
00913    if (ast_strlen_zero(groupmatch))
00914       return 0;
00915 
00916    /* if regex compilation fails, return zero matches */
00917    if (regcomp(&regexbuf, groupmatch, REG_EXTENDED | REG_NOSUB))
00918       return 0;
00919 
00920    AST_LIST_LOCK(&groups);
00921    AST_LIST_TRAVERSE(&groups, gi, list) {
00922       if (!regexec(&regexbuf, gi->group, 0, NULL, 0) && (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category))))
00923          count++;
00924    }
00925    AST_LIST_UNLOCK(&groups);
00926 
00927    regfree(&regexbuf);
00928 
00929    return count;
00930 }

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 844 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().

00845 {
00846    int res = 0;
00847    char group[80] = "", category[80] = "";
00848    struct ast_group_info *gi = NULL;
00849    size_t len = 0;
00850    
00851    if (ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category)))
00852       return -1;
00853    
00854    /* Calculate memory we will need if this is new */
00855    len = sizeof(*gi) + strlen(group) + 1;
00856    if (!ast_strlen_zero(category))
00857       len += strlen(category) + 1;
00858    
00859    AST_LIST_LOCK(&groups);
00860    AST_LIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) {
00861       if ((gi->chan == chan) && ((ast_strlen_zero(category) && ast_strlen_zero(gi->category)) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) {
00862          AST_LIST_REMOVE_CURRENT(&groups, list);
00863          free(gi);
00864          break;
00865       }
00866    }
00867    AST_LIST_TRAVERSE_SAFE_END
00868 
00869    if (ast_strlen_zero(group)) {
00870       /* Enable unsetting the group */
00871    } else if ((gi = calloc(1, len))) {
00872       gi->chan = chan;
00873       gi->group = (char *) gi + sizeof(*gi);
00874       strcpy(gi->group, group);
00875       if (!ast_strlen_zero(category)) {
00876          gi->category = (char *) gi + sizeof(*gi) + strlen(group) + 1;
00877          strcpy(gi->category, category);
00878       }
00879       AST_LIST_INSERT_TAIL(&groups, gi, list);
00880    } else {
00881       res = -1;
00882    }
00883    
00884    AST_LIST_UNLOCK(&groups);
00885    
00886    return res;
00887 }

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 817 of file app.c.

References ast_strlen_zero().

Referenced by ast_app_group_set_channel(), group_count_function_read(), and group_match_count_function_read().

00818 {
00819    int res=0;
00820    char tmp[256];
00821    char *grp=NULL, *cat=NULL;
00822 
00823    if (!ast_strlen_zero(data)) {
00824       ast_copy_string(tmp, data, sizeof(tmp));
00825       grp = tmp;
00826       cat = strchr(tmp, '@');
00827       if (cat) {
00828          *cat = '\0';
00829          cat++;
00830       }
00831    }
00832 
00833    if (!ast_strlen_zero(grp))
00834       ast_copy_string(group, grp, group_max);
00835    else
00836       *group = '\0';
00837 
00838    if (!ast_strlen_zero(cat))
00839       ast_copy_string(category, cat, category_max);
00840 
00841    return res;
00842 }

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 932 of file app.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_group_info::chan.

Referenced by ast_do_masquerade().

00933 {
00934    struct ast_group_info *gi = NULL;
00935 
00936    AST_LIST_LOCK(&groups);
00937    AST_LIST_TRAVERSE(&groups, gi, list) {
00938       if (gi->chan == old)
00939          gi->chan = new;
00940    }
00941    AST_LIST_UNLOCK(&groups);
00942 
00943    return 0;
00944 }

int ast_app_has_voicemail ( const char *  mailbox,
const char *  folder 
)

Determine if a given mailbox has any voicemail

Definition at line 183 of file app.c.

References ast_has_voicemail_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3.

Referenced by action_mailboxstatus(), has_voicemail(), notify_new_message(), play_dialtone(), poll_mailbox(), and run_externnotify().

00184 {
00185    static int warned = 0;
00186    if (ast_has_voicemail_func)
00187       return ast_has_voicemail_func(mailbox, folder);
00188 
00189    if ((option_verbose > 2) && !warned) {
00190       ast_verbose(VERBOSE_PREFIX_3 "Message check requested for mailbox %s/folder %s but voicemail not loaded.\n", mailbox, folder ? folder : "INBOX");
00191       warned++;
00192    }
00193    return 0;
00194 }

int ast_app_inboxcount ( const char *  mailbox,
int *  newmsgs,
int *  oldmsgs 
)

Determine number of new/old messages in a mailbox

Definition at line 197 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().

00198 {
00199    static int warned = 0;
00200    if (newmsgs)
00201       *newmsgs = 0;
00202    if (oldmsgs)
00203       *oldmsgs = 0;
00204    if (ast_inboxcount_func)
00205       return ast_inboxcount_func(mailbox, newmsgs, oldmsgs);
00206 
00207    if (!warned && (option_verbose > 2)) {
00208       warned++;
00209       ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s but voicemail not loaded.\n", mailbox);
00210    }
00211 
00212    return 0;
00213 }

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 215 of file app.c.

References ast_messagecount_func, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3.

Referenced by acf_vmcount_exec(), and hasvoicemail_exec().

00216 {
00217    static int warned = 0;
00218    if (ast_messagecount_func)
00219       return ast_messagecount_func(context, mailbox, folder);
00220 
00221    if (!warned && (option_verbose > 2)) {
00222       warned++;
00223       ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s@%s/%s but voicemail not loaded.\n", mailbox, context, folder);
00224    }
00225 
00226    return 0;
00227 }

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.

Parameters:
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
Returns:
zero for success, non-zero if an error occurs
See also:
AST_APP_OPTIONS

Definition at line 1413 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 app_exec(), auth_exec(), bridge_exec(), cdr_read(), cdr_write(), chanspy_exec(), conf_exec(), extenspy_exec(), mixmonitor_exec(), page_exec(), pbx_builtin_background(), pbx_builtin_resetcdr(), pbx_builtin_waitexten(), read_exec(), vm_exec(), and vm_execmain().

01414 {
01415    char *s;
01416    int curarg;
01417    unsigned int argloc;
01418    char *arg;
01419    int res = 0;
01420 
01421    ast_clear_flag(flags, AST_FLAGS_ALL);
01422 
01423    if (!optstr)
01424       return 0;
01425 
01426    s = optstr;
01427    while (*s) {
01428       curarg = *s++ & 0x7f;   /* the array (in app.h) has 128 entries */
01429       argloc = options[curarg].arg_index;
01430       if (*s == '(') {
01431          /* Has argument */
01432          arg = ++s;
01433          if ((s = strchr(s, ')'))) {
01434             if (argloc)
01435                args[argloc - 1] = arg;
01436             *s++ = '\0';
01437          } else {
01438             ast_log(LOG_WARNING, "Missing closing parenthesis for argument '%c' in string '%s'\n", curarg, arg);
01439             res = -1;
01440             break;
01441          }
01442       } else if (argloc) {
01443          args[argloc - 1] = "";
01444       }
01445       ast_set_flag(flags, options[curarg].flag);
01446    }
01447 
01448    return res;
01449 }

unsigned int ast_app_separate_args ( char *  buf,
char  delim,
char **  array,
int  arraylen 
)

Separate a string into arguments in an array.

Parameters:
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.

Returns:
The number of arguments found, or zero if the function arguments are not valid.

Definition at line 978 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().

00979 {
00980    int argc;
00981    char *scan;
00982    int paren = 0, quote = 0;
00983 
00984    if (!buf || !array || !arraylen)
00985       return 0;
00986 
00987    memset(array, 0, arraylen * sizeof(*array));
00988 
00989    scan = buf;
00990 
00991    for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
00992       array[argc] = scan;
00993       for (; *scan; scan++) {
00994          if (*scan == '(')
00995             paren++;
00996          else if (*scan == ')') {
00997             if (paren)
00998                paren--;
00999          } else if (*scan == '"' && delim != '"') {
01000             quote = quote ? 0 : 1;
01001             /* Remove quote character from argument */
01002             memmove(scan, scan + 1, strlen(scan));
01003             scan--;
01004          } else if (*scan == '\\') {
01005             /* Literal character, don't parse */
01006             memmove(scan, scan + 1, strlen(scan));
01007          } else if ((*scan == delim) && !paren && !quote) {
01008             *scan++ = '\0';
01009             break;
01010          }
01011       }
01012    }
01013 
01014    if (*scan)
01015       array[argc++] = scan;
01016 
01017    return argc;
01018 }

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 386 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().

00390 {
00391    char *breaks = NULL;
00392    char *end = NULL;
00393    int blen = 2;
00394    int res;
00395    long pause_restart_point = 0;
00396 
00397    if (stop)
00398       blen += strlen(stop);
00399    if (pause)
00400       blen += strlen(pause);
00401    if (restart)
00402       blen += strlen(restart);
00403 
00404    if (blen > 2) {
00405       breaks = alloca(blen + 1);
00406       breaks[0] = '\0';
00407       if (stop)
00408          strcat(breaks, stop);
00409       if (pause)
00410          strcat(breaks, pause);
00411       if (restart)
00412          strcat(breaks, restart);
00413    }
00414    if (chan->_state != AST_STATE_UP)
00415       res = ast_answer(chan);
00416 
00417    if (file) {
00418       if ((end = strchr(file,':'))) {
00419          if (!strcasecmp(end, ":end")) {
00420             *end = '\0';
00421             end++;
00422          }
00423       }
00424    }
00425 
00426    for (;;) {
00427       ast_stopstream(chan);
00428       res = ast_streamfile(chan, file, chan->language);
00429       if (!res) {
00430          if (pause_restart_point) {
00431             ast_seekstream(chan->stream, pause_restart_point, SEEK_SET);
00432             pause_restart_point = 0;
00433          }
00434          else if (end) {
00435             ast_seekstream(chan->stream, 0, SEEK_END);
00436             end = NULL;
00437          };
00438          res = ast_waitstream_fr(chan, breaks, fwd, rev, skipms);
00439       }
00440 
00441       if (res < 1)
00442          break;
00443 
00444       /* We go at next loop if we got the restart char */
00445       if (restart && strchr(restart, res)) {
00446          if (option_debug)
00447             ast_log(LOG_DEBUG, "we'll restart the stream here at next loop\n");
00448          pause_restart_point = 0;
00449          continue;
00450       }
00451 
00452       if (pause && strchr(pause, res)) {
00453          pause_restart_point = ast_tellstream(chan->stream);
00454          for (;;) {
00455             ast_stopstream(chan);
00456             res = ast_waitfordigit(chan, 1000);
00457             if (!res)
00458                continue;
00459             else if (res == -1 || strchr(pause, res) || (stop && strchr(stop, res)))
00460                break;
00461          }
00462          if (res == *pause) {
00463             res = 0;
00464             continue;
00465          }
00466       }
00467 
00468       if (res == -1)
00469          break;
00470 
00471       /* if we get one of our stop chars, return it to the calling function */
00472       if (stop && strchr(stop, res))
00473          break;
00474    }
00475 
00476    /* If we are returning a digit cast it as char */
00477    if (res > 0 || chan->stream)
00478       res = (char)res;
00479 
00480    ast_stopstream(chan);
00481 
00482    return res;
00483 }

int ast_dtmf_stream ( struct ast_channel chan,
struct ast_channel peer,
const char *  digits,
int  between 
)

Send DTMF to a channel.

Parameters:
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 229 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(), test1_client(), test1_server(), testclient_exec(), and testserver_exec().

00230 {
00231    const char *ptr;
00232    int res = 0;
00233    struct ast_silence_generator *silgen = NULL;
00234 
00235    if (!between)
00236       between = 100;
00237 
00238    if (peer)
00239       res = ast_autoservice_start(peer);
00240 
00241    if (!res)
00242       res = ast_waitfor(chan, 100);
00243 
00244    /* ast_waitfor will return the number of remaining ms on success */
00245    if (res < 0)
00246       return res;
00247 
00248    if (ast_opt_transmit_silence) {
00249       silgen = ast_channel_start_silence_generator(chan);
00250    }
00251 
00252    for (ptr = digits; *ptr; ptr++) {
00253       if (*ptr == 'w') {
00254          /* 'w' -- wait half a second */
00255          if ((res = ast_safe_sleep(chan, 500)))
00256             break;
00257       } else if (strchr("0123456789*#abcdfABCDF", *ptr)) {
00258          /* Character represents valid DTMF */
00259          if (*ptr == 'f' || *ptr == 'F') {
00260             /* ignore return values if not supported by channel */
00261             ast_indicate(chan, AST_CONTROL_FLASH);
00262          } else
00263             ast_senddigit(chan, *ptr);
00264          /* pause between digits */
00265          if ((res = ast_safe_sleep(chan, between)))
00266             break;
00267       } else
00268          ast_log(LOG_WARNING, "Illegal DTMF character '%c' in string. (0-9*#aAbBcCdD allowed)\n",*ptr);
00269    }
00270 
00271    if (peer) {
00272       /* Stop autoservice on the peer channel, but don't overwrite any error condition 
00273          that has occurred previously while acting on the primary channel */
00274       if (ast_autoservice_stop(peer) && !res)
00275          res = -1;
00276    }
00277 
00278    if (silgen) {
00279       ast_channel_stop_silence_generator(chan, silgen);
00280    }
00281 
00282    return res;
00283 }

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 167 of file app.c.

References ast_has_voicemail_func, ast_inboxcount_func, and ast_messagecount_func.

Referenced by load_module().

00170 {
00171    ast_has_voicemail_func = has_voicemail_func;
00172    ast_inboxcount_func = inboxcount_func;
00173    ast_messagecount_func = messagecount_func;
00174 }

int ast_ivr_menu_run ( struct ast_channel c,
struct ast_ivr_menu menu,
void *  cbdata 
)

Runs an IVR menu.

Returns:
returns 0 on successful completion, -1 on hangup, or -2 on user error in menu

Definition at line 1375 of file app.c.

References ast_ivr_menu_run_internal().

Referenced by skel_exec().

01376 {
01377    int res = ast_ivr_menu_run_internal(chan, menu, cbdata);
01378    /* Hide internal coding */
01379    return res > 0 ? 0 : res;
01380 }

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 357 of file app.c.

References ast_activate_generator(), ast_calloc, ast_config_AST_DATA_DIR, ast_log(), ast_strlen_zero(), linear_state::autoclose, errno, linearstream, and LOG_WARNING.

00358 {
00359    struct linear_state *lin;
00360    char tmpf[256];
00361    int res = -1;
00362    int autoclose = 0;
00363    if (fd < 0) {
00364       if (ast_strlen_zero(filename))
00365          return -1;
00366       autoclose = 1;
00367       if (filename[0] == '/') 
00368          ast_copy_string(tmpf, filename, sizeof(tmpf));
00369       else
00370          snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", (char *)ast_config_AST_DATA_DIR, "sounds", filename);
00371       fd = open(tmpf, O_RDONLY);
00372       if (fd < 0){
00373          ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno));
00374          return -1;
00375       }
00376    }
00377    if ((lin = ast_calloc(1, sizeof(*lin)))) {
00378       lin->fd = fd;
00379       lin->allowoverride = allowoverride;
00380       lin->autoclose = autoclose;
00381       res = ast_activate_generator(chan, &linearstream, lin);
00382    }
00383    return res;
00384 }

enum AST_LOCK_RESULT ast_lock_path ( const char *  path  ) 

Lock a filesystem path.

Parameters:
path the path to be locked
Returns:
one of AST_LOCK_RESULT values

Definition at line 1020 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().

01021 {
01022    char *s;
01023    char *fs;
01024    int res;
01025    int fd;
01026    int lp = strlen(path);
01027    time_t start;
01028 
01029    if (!(s = alloca(lp + 10)) || !(fs = alloca(lp + 20))) {
01030       ast_log(LOG_WARNING, "Out of memory!\n");
01031       return AST_LOCK_FAILURE;
01032    }
01033 
01034    snprintf(fs, strlen(path) + 19, "%s/.lock-%08lx", path, ast_random());
01035    fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, 0600);
01036    if (fd < 0) {
01037       ast_log(LOG_ERROR, "Unable to create lock file '%s': %s\n", path, strerror(errno));
01038       return AST_LOCK_PATH_NOT_FOUND;
01039    }
01040    close(fd);
01041 
01042    snprintf(s, strlen(path) + 9, "%s/.lock", path);
01043    start = time(NULL);
01044    while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5))
01045       usleep(1);
01046 
01047    unlink(fs);
01048 
01049    if (res) {
01050       ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno));
01051       return AST_LOCK_TIMEOUT;
01052    } else {
01053       if (option_debug)
01054          ast_log(LOG_DEBUG, "Locked path '%s'\n", path);
01055       return AST_LOCK_SUCCESS;
01056    }
01057 }

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 810 of file app.c.

References __ast_play_and_record().

Referenced by vm_forwardoptions().

00811 {
00812    return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf);
00813 }

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 805 of file app.c.

References __ast_play_and_record().

Referenced by app_exec(), ast_record_review(), and conf_run().

00806 {
00807    return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf);
00808 }

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 800 of file app.c.

References __ast_play_and_record(), and S_OR.

Referenced by play_record_review().

00801 {
00802    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));
00803 }

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 485 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(), 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_es(), vm_browse_messages_gr(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_execmain(), vm_forwardoptions(), vm_instructions(), vm_intro(), vm_intro_cz(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_it(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_ru(), vm_intro_se(), vm_intro_ua(), 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().

00486 {
00487    int d;
00488    d = ast_streamfile(chan, fn, chan->language);
00489    if (d)
00490       return d;
00491    d = ast_waitstream(chan, AST_DIGIT_ANY);
00492    ast_stopstream(chan);
00493    return d;
00494 }

char* ast_read_textfile ( const char *  file  ) 

Read a file into asterisk

Definition at line 1382 of file app.c.

References ast_log(), ast_malloc, errno, free, and LOG_WARNING.

Referenced by readfile_exec().

01383 {
01384    int fd;
01385    char *output = NULL;
01386    struct stat filesize;
01387    int count = 0;
01388    int res;
01389    if (stat(filename, &filesize) == -1) {
01390       ast_log(LOG_WARNING, "Error can't stat %s\n", filename);
01391       return NULL;
01392    }
01393    count = filesize.st_size + 1;
01394    fd = open(filename, O_RDONLY);
01395    if (fd < 0) {
01396       ast_log(LOG_WARNING, "Cannot open file '%s' for reading: %s\n", filename, strerror(errno));
01397       return NULL;
01398    }
01399    if ((output = ast_malloc(count))) {
01400       res = read(fd, output, count - 1);
01401       if (res == count - 1) {
01402          output[res] = '\0';
01403       } else {
01404          ast_log(LOG_WARNING, "Short read of %s (%d of %d): %s\n", filename, res, count - 1, strerror(errno));
01405          free(output);
01406          output = NULL;
01407       }
01408    }
01409    close(fd);
01410    return output;
01411 }

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 1081 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(), ast_group_info::chan, LOG_WARNING, maxsilence, silencethreshold, and VERBOSE_PREFIX_3.

Referenced by conf_run().

01082 {
01083    int silencethreshold = 128; 
01084    int maxsilence=0;
01085    int res = 0;
01086    int cmd = 0;
01087    int max_attempts = 3;
01088    int attempts = 0;
01089    int recorded = 0;
01090    int message_exists = 0;
01091    /* Note that urgent and private are for flagging messages as such in the future */
01092 
01093    /* barf if no pointer passed to store duration in */
01094    if (duration == NULL) {
01095       ast_log(LOG_WARNING, "Error ast_record_review called without duration pointer\n");
01096       return -1;
01097    }
01098 
01099    cmd = '3';   /* Want to start by recording */
01100 
01101    while ((cmd >= 0) && (cmd != 't')) {
01102       switch (cmd) {
01103       case '1':
01104          if (!message_exists) {
01105             /* In this case, 1 is to record a message */
01106             cmd = '3';
01107             break;
01108          } else {
01109             ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
01110             cmd = 't';
01111             return res;
01112          }
01113       case '2':
01114          /* Review */
01115          ast_verbose(VERBOSE_PREFIX_3 "Reviewing the recording\n");
01116          cmd = ast_stream_and_wait(chan, recordfile, chan->language, AST_DIGIT_ANY);
01117          break;
01118       case '3':
01119          message_exists = 0;
01120          /* Record */
01121          if (recorded == 1)
01122             ast_verbose(VERBOSE_PREFIX_3 "Re-recording\n");
01123          else  
01124             ast_verbose(VERBOSE_PREFIX_3 "Recording\n");
01125          recorded = 1;
01126          cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, path);
01127          if (cmd == -1) {
01128          /* User has hung up, no options to give */
01129             return cmd;
01130          }
01131          if (cmd == '0') {
01132             break;
01133          } else if (cmd == '*') {
01134             break;
01135          } 
01136          else {
01137             /* If all is well, a message exists */
01138             message_exists = 1;
01139             cmd = 0;
01140          }
01141          break;
01142       case '4':
01143       case '5':
01144       case '6':
01145       case '7':
01146       case '8':
01147       case '9':
01148       case '*':
01149       case '#':
01150          cmd = ast_play_and_wait(chan, "vm-sorry");
01151          break;
01152       default:
01153          if (message_exists) {
01154             cmd = ast_play_and_wait(chan, "vm-review");
01155          }
01156          else {
01157             cmd = ast_play_and_wait(chan, "vm-torerecord");
01158             if (!cmd)
01159                cmd = ast_waitfordigit(chan, 600);
01160          }
01161          
01162          if (!cmd)
01163             cmd = ast_waitfordigit(chan, 6000);
01164          if (!cmd) {
01165             attempts++;
01166          }
01167          if (attempts > max_attempts) {
01168             cmd = 't';
01169          }
01170       }
01171    }
01172    if (cmd == 't')
01173       cmd = 0;
01174    return cmd;
01175 }

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 752 of file asterisk.c.

References ast_mutex_lock(), ast_mutex_unlock(), and null_sig_handler().

Referenced by ast_safe_system().

00753 {
00754    unsigned int level;
00755 
00756    ast_mutex_lock(&safe_system_lock);
00757    level = safe_system_level++;
00758 
00759    /* only replace the handler if it has not already been done */
00760    if (level == 0)
00761       safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
00762 
00763    ast_mutex_unlock(&safe_system_lock);
00764 }

int ast_safe_system ( const char *  s  ) 

Safely spawn an external program while closing file descriptors

Note:
This replaces the system call in all Asterisk modules

Definition at line 780 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_closestream(), ast_monitor_change_fname(), ast_monitor_start(), ast_monitor_stop(), consolehandler(), make_email_file(), mixmonitor_thread(), process_text_line(), remoteconsolehandler(), run_externnotify(), sendmail(), sendpage(), system_exec_helper(), and vm_change_password_shell().

00781 {
00782    pid_t pid;
00783 #ifdef HAVE_WORKING_FORK
00784    int x;
00785 #endif
00786    int res;
00787    struct rusage rusage;
00788    int status;
00789 
00790 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
00791    ast_replace_sigchld();
00792 
00793 #ifdef HAVE_WORKING_FORK
00794    pid = fork();
00795 #else
00796    pid = vfork();
00797 #endif   
00798 
00799    if (pid == 0) {
00800 #ifdef HAVE_WORKING_FORK
00801       if (ast_opt_high_priority)
00802          ast_set_priority(0);
00803       /* Close file descriptors and launch system command */
00804       for (x = STDERR_FILENO + 1; x < 4096; x++)
00805          close(x);
00806 #endif
00807       execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
00808       _exit(1);
00809    } else if (pid > 0) {
00810       for(;;) {
00811          res = wait4(pid, &status, 0, &rusage);
00812          if (res > -1) {
00813             res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
00814             break;
00815          } else if (errno != EINTR) 
00816             break;
00817       }
00818    } else {
00819       ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
00820       res = -1;
00821    }
00822 
00823    ast_unreplace_sigchld();
00824 #else
00825    res = -1;
00826 #endif
00827 
00828    return res;
00829 }

void ast_uninstall_vm_functions ( void   ) 

Definition at line 176 of file app.c.

References ast_has_voicemail_func, ast_inboxcount_func, and ast_messagecount_func.

Referenced by unload_module().

00177 {
00178    ast_has_voicemail_func = NULL;
00179    ast_inboxcount_func = NULL;
00180    ast_messagecount_func = NULL;
00181 }

int ast_unlock_path ( const char *  path  ) 

Unlock a path

Definition at line 1059 of file app.c.

References ast_log(), errno, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, and s.

Referenced by __ast_play_and_record(), copy_message(), count_messages(), last_message_index(), leave_voicemail(), resequence_mailbox(), and save_to_folder().

01060 {
01061    char *s;
01062    int res;
01063 
01064    if (!(s = alloca(strlen(path) + 10))) {
01065       ast_log(LOG_WARNING, "Out of memory!\n");
01066       return -1;
01067    }
01068 
01069    snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock");
01070 
01071    if ((res = unlink(s)))
01072       ast_log(LOG_ERROR, "Could not unlock path '%s': %s\n", path, strerror(errno));
01073    else {
01074       if (option_debug)
01075          ast_log(LOG_DEBUG, "Unlocked path '%s'\n", path);
01076    }
01077 
01078    return res;
01079 }

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 766 of file asterisk.c.

References ast_mutex_lock(), and ast_mutex_unlock().

Referenced by agi_exec_full(), and ast_safe_system().

00767 {
00768    unsigned int level;
00769 
00770    ast_mutex_lock(&safe_system_lock);
00771    level = --safe_system_level;
00772 
00773    /* only restore the handler if we are the last one */
00774    if (level == 0)
00775       signal(SIGCHLD, safe_system_prev_handler);
00776 
00777    ast_mutex_unlock(&safe_system_lock);
00778 }


Generated on Mon Mar 31 07:38:12 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1