Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:00:59 2007

Asterisk developer's documentation :: Codename Pineapple


app.h File Reference


Detailed Description

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

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 Documentation

#define AST_APP_ARG name   )     char *name
 

Define an application argument.

Parameters:
name The name of the 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().

#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 368 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 379 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 359 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 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().

#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) - sizeof(args.argc)) / 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 272 of file app.h.

Referenced by add_agent(), function_agent(), oss_call(), and oss_request().

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

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 259 of file app.h.

Referenced by __login_exec(), astman_get_variables(), func_header_read(), pbx_builtin_background(), and pbx_builtin_waitexten().

#define GROUP_CATEGORY_PREFIX   "GROUP"
 

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


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


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

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.

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

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

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

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 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(&regexbuf, 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(&regexbuf, test, 0, NULL, 0))
00880          count++;
00881       ast_channel_unlock(chan);
00882    }
00883 
00884    regfree(&regexbuf);
00885 
00886    return count;
00887 }

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

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

int ast_app_has_voicemail const char *  mailbox,
const char *  folder
 

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 }

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

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 }

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

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

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

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

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

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

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

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

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

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

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

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

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

char* ast_read_textfile const char *  file  ) 
 

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 }

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

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

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

void ast_uninstall_vm_functions void   ) 
 

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 }

int ast_unlock_path const char *  path  ) 
 

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 }

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


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen