Mon Mar 19 11:30:36 2012

Asterisk developer's documentation


asterisk.c File Reference

Top level source file for Asterisk - the Open Source PBX. Implementation of PBX core functions and CLI interface. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include <sys/time.h>
#include <fcntl.h>
#include <signal.h>
#include <sched.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <ctype.h>
#include <sys/resource.h>
#include <grp.h>
#include <pwd.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <regex.h>
#include "asterisk/paths.h"
#include "asterisk/network.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/features.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/image.h"
#include "asterisk/tdd.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/cdr.h"
#include "asterisk/cel.h"
#include "asterisk/pbx.h"
#include "asterisk/enum.h"
#include "asterisk/http.h"
#include "asterisk/udptl.h"
#include "asterisk/app.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/io.h"
#include "editline/histedit.h"
#include "asterisk/config.h"
#include "asterisk/ast_version.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"
#include "asterisk/module.h"
#include "asterisk/dsp.h"
#include "asterisk/buildinfo.h"
#include "asterisk/xmldoc.h"
#include "asterisk/poll-compat.h"
#include "asterisk/ccss.h"
#include "asterisk/test.h"
#include "asterisk/aoc.h"
#include "../defaults.h"

Go to the source code of this file.

Data Structures

struct  _cfg_paths
struct  ast_atexit
struct  atexits
struct  console
struct  file_version
struct  file_versions
struct  profile_data
struct  profile_entry
struct  thread_list
struct  thread_list_t

Defines

#define AF_LOCAL   AF_UNIX
#define AST_MAX_CONNECTS   128
#define ASTERISK_PROMPT   "*CLI> "
#define ASTERISK_PROMPT2   "%s*CLI> "
#define DEFINE_PROFILE_MIN_MAX_VALUES
#define EL_BUF_SIZE   512
#define FORMAT   "%-25.25s %-40.40s\n"
#define MAX_HISTORY_COMMAND_LENGTH   256
#define NUM_MSGS   64
#define PF_LOCAL   PF_UNIX
#define WELCOME_MESSAGE
 Welcome message when starting a CLI interface.

Enumerations

enum  shutdown_nice_t {
  NOT_SHUTTING_DOWN = -2, SHUTTING_DOWN = -1, SHUTDOWN_FAST, SHUTDOWN_NORMAL,
  SHUTDOWN_NICE, SHUTDOWN_REALLY_NICE
}

Functions

static void __quit_handler (int num)
static void __remote_quit_handler (int num)
static void _child_handler (int sig)
static void _hup_handler (int num)
static void _null_sig_handler (int sig)
 NULL handler so we can collect the child exit status.
static void _urg_handler (int num)
 Urgent handler.
int ast_add_profile (const char *name, uint64_t scale)
 support for event profiling
static int ast_all_zeros (char *s)
static int ast_cli_display_match_list (char **matches, int len, int max)
char * ast_complete_source_filename (const char *partial, int n)
void ast_console_puts (const char *string)
void ast_console_puts_mutable (const char *string, int level)
 log the string to the console, and all attached console clients
void ast_console_toggle_loglevel (int fd, int level, int state)
 enables or disables logging of a specified level to the console fd specifies the index of the console receiving the level change level specifies the index of the logging level being toggled state indicates whether logging will be on or off (0 for off, 1 for on)
void ast_console_toggle_mute (int fd, int silent)
 mute or unmute a console from logging
static int ast_el_add_history (char *)
static int ast_el_initialize (void)
static int ast_el_read_char (EditLine *editline, char *cp)
static int ast_el_read_history (char *)
static int ast_el_sort_compare (const void *i1, const void *i2)
static char ** ast_el_strtoarr (char *buf)
static int ast_el_write_history (char *)
const char * ast_file_version_find (const char *file)
 Find version for given module name.
static int ast_makesocket (void)
int64_t ast_mark (int i, int startstop)
static void ast_network_puts (const char *string)
 write the string to all attached console clients
static void ast_network_puts_mutable (const char *string, int level)
 log the string to all attached console clients
int64_t ast_profile (int i, int64_t delta)
static void ast_readconfig (void)
int ast_register_atexit (void(*func)(void))
 Register a function to be executed before Asterisk exits.
void ast_register_file_version (const char *file, const char *version)
 Register the version of a source code file with the core.
void ast_register_thread (char *name)
static void ast_remotecontrol (char *data)
void ast_replace_sigchld (void)
 Replace the SIGCHLD handler.
static void ast_run_atexits (void)
int ast_safe_system (const char *s)
 Safely spawn an external program while closing file descriptors.
int ast_set_priority (int pri)
 We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy activity on it, this is a good thing.
static int ast_tryconnect (void)
void ast_unregister_atexit (void(*func)(void))
 Unregister a function registered with ast_register_atexit().
void ast_unregister_file_version (const char *file)
 Unregister a source code file from the core.
void ast_unregister_thread (void *id)
void ast_unreplace_sigchld (void)
 Restore the SIGCHLD handler.
static int can_safely_quit (shutdown_nice_t niceness, int restart)
static void canary_exit (void)
static void * canary_thread (void *unused)
static char * cli_complete (EditLine *editline, int ch)
static char * cli_prompt (EditLine *editline)
static void console_verboser (const char *s)
static void consolehandler (char *s)
static void env_init (void)
static int fdprint (int fd, const char *s)
static int fdsend (int fd, const char *s)
static const char * fix_header (char *outbuf, int maxout, const char *s, char *cmp)
static char * handle_abort_shutdown (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_bang (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_clear_profile (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_restart_gracefully (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_restart_now (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_restart_when_convenient (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_show_profile (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Give an overview of core settings.
static char * handle_show_sysinfo (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Give an overview of system statistics.
static char * handle_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_show_version_files (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to list module versions.
static char * handle_stop_gracefully (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_stop_now (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_stop_when_convenient (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_version (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void * listener (void *unused)
int main (int argc, char *argv[])
static void * monitor_sig_flags (void *unused)
static void * netconsole (void *vconsole)
static void network_verboser (const char *s)
static void quit_handler (int num, shutdown_nice_t niceness, int restart)
static __inline uint64_t rdtsc (void)
static int read_credentials (int fd, char *buffer, size_t size, struct console *con)
 read() function supporting the reception of user credentials.
static void really_quit (int num, shutdown_nice_t niceness, int restart)
static int remoteconsolehandler (char *s)
static void run_startup_commands (void)
static void set_icon (char *text)
static void set_title (char *text)
 Set an X-term or screen title.
static void set_ulimit (int value)
 Set maximum open files.
static int show_cli_help (void)
static char * show_license (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int show_version (void)
static char * show_warranty (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Variables

static char * _argv [256]
ast_flags ast_compat = { 0 }
const char * ast_config_AST_AGI_DIR = cfg_paths.agi_dir
const char * ast_config_AST_CONFIG_DIR = cfg_paths.config_dir
const char * ast_config_AST_CONFIG_FILE = cfg_paths.config_file
static char ast_config_AST_CTL [PATH_MAX] = "asterisk.ctl"
static char ast_config_AST_CTL_GROUP [PATH_MAX] = "\0"
static char ast_config_AST_CTL_OWNER [PATH_MAX] = "\0"
static char ast_config_AST_CTL_PERMISSIONS [PATH_MAX]
const char * ast_config_AST_DATA_DIR = cfg_paths.data_dir
const char * ast_config_AST_DB = cfg_paths.db_path
const char * ast_config_AST_KEY_DIR = cfg_paths.key_dir
const char * ast_config_AST_LOG_DIR = cfg_paths.log_dir
const char * ast_config_AST_MODULE_DIR = cfg_paths.module_dir
const char * ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir
const char * ast_config_AST_PID = cfg_paths.pid_path
const char * ast_config_AST_RUN_DIR = cfg_paths.run_dir
const char * ast_config_AST_RUN_GROUP = cfg_paths.run_group
const char * ast_config_AST_RUN_USER = cfg_paths.run_user
const char * ast_config_AST_SOCKET = cfg_paths.socket_path
const char * ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir
const char * ast_config_AST_SYSTEM_NAME = cfg_paths.system_name
const char * ast_config_AST_VAR_DIR = cfg_paths.var_dir
static int ast_consock = -1
ast_eid ast_eid_default
 Global EID.
unsigned int ast_FD_SETSIZE
timeval ast_lastreloadtime
pid_t ast_mainpid
ast_flags ast_options = { AST_DEFAULT_OPTIONS }
static int ast_socket = -1
timeval ast_startuptime
static char canary_filename [128]
static int canary_pid = 0
static struct _cfg_paths cfg_paths
static struct sigaction child_handler
static struct ast_cli_entry cli_asterisk []
console consoles [AST_MAX_CONNECTS]
static pthread_t consolethread = AST_PTHREADT_NULL
char defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE
static EditLine * el
static History * el_hist
static struct sigaction hup_handler
static struct sigaction ignore_sig_handler
static const char license_lines []
static pthread_t lthread
static pthread_t mon_sig_flags
static struct sigaction null_sig_handler
int option_debug
int option_maxcalls
int option_maxfiles
double option_maxload
long option_minmemfree
int option_verbose
static struct profile_dataprof_data
static struct ast_strprompt = NULL
static char randompool [256]
char record_cache_dir [AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR
static char * remotehostname
static int restartnow
static unsigned int safe_system_level = 0
 Keep track of how many threads are currently trying to wait*() on a child process.
static ast_mutex_t safe_system_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static struct sigaction safe_system_prev_handler
static shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN
static int sig_alert_pipe [2] = { -1, -1 }
struct {
   unsigned int   need_quit:1
   unsigned int   need_quit_handler:1
   unsigned int   need_reload:1
sig_flags
static struct sigaction urg_handler
static const char warranty_lines []


Detailed Description

Top level source file for Asterisk - the Open Source PBX. Implementation of PBX core functions and CLI interface.

Definition in file asterisk.c.


Define Documentation

#define AF_LOCAL   AF_UNIX

Definition at line 150 of file asterisk.c.

#define AST_MAX_CONNECTS   128

Definition at line 154 of file asterisk.c.

Referenced by ast_console_toggle_loglevel(), ast_console_toggle_mute(), ast_makesocket(), ast_network_puts(), ast_network_puts_mutable(), and listener().

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 2165 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 2167 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

Definition at line 781 of file asterisk.c.

Referenced by handle_clear_profile(), and handle_show_profile().

#define EL_BUF_SIZE   512

Referenced by ast_el_read_char().

#define FORMAT   "%-25.25s %-40.40s\n"

#define MAX_HISTORY_COMMAND_LENGTH   256

Definition at line 2674 of file asterisk.c.

Referenced by ast_el_add_history(), and ast_el_read_history().

#define NUM_MSGS   64

Definition at line 155 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

Definition at line 151 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 158 of file asterisk.c.

Referenced by ast_el_read_char(), and main().


Enumeration Type Documentation

enum shutdown_nice_t

Enumerator:
NOT_SHUTTING_DOWN 
SHUTTING_DOWN 
SHUTDOWN_FAST 
SHUTDOWN_NORMAL 
SHUTDOWN_NICE 
SHUTDOWN_REALLY_NICE 

Definition at line 278 of file asterisk.c.

00278              {
00279    NOT_SHUTTING_DOWN = -2,
00280    SHUTTING_DOWN = -1,
00281    /* Valid values for quit_handler niceness below: */
00282    SHUTDOWN_FAST,
00283    SHUTDOWN_NORMAL,
00284    SHUTDOWN_NICE,
00285    SHUTDOWN_REALLY_NICE
00286 } shutdown_nice_t;


Function Documentation

static void __quit_handler ( int  num  )  [static]

Definition at line 1776 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

01777 {
01778    int a = 0;
01779    sig_flags.need_quit = 1;
01780    if (sig_alert_pipe[1] != -1) {
01781       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01782          fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
01783       }
01784    }
01785    /* There is no need to restore the signal handler here, since the app
01786     * is going to exit */
01787 }

static void __remote_quit_handler ( int  num  )  [static]

Definition at line 1789 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

01790 {
01791    sig_flags.need_quit = 1;
01792 }

static void _child_handler ( int  sig  )  [static]

Definition at line 1516 of file asterisk.c.

References errno, and status.

01517 {
01518    /* Must not ever ast_log or ast_verbose within signal handler */
01519    int n, status, save_errno = errno;
01520 
01521    /*
01522     * Reap all dead children -- not just one
01523     */
01524    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01525       ;
01526    if (n == 0 && option_debug)   
01527       printf("Huh?  Child handler, but nobody there?\n");
01528    errno = save_errno;
01529 }

static void _hup_handler ( int  num  )  [static]

Definition at line 1495 of file asterisk.c.

References _argv, errno, restartnow, sig_alert_pipe, and sig_flags.

01496 {
01497    int a = 0, save_errno = errno;
01498    if (option_verbose > 1) 
01499       printf("Received HUP signal -- Reloading configs\n");
01500    if (restartnow)
01501       execvp(_argv[0], _argv);
01502    sig_flags.need_reload = 1;
01503    if (sig_alert_pipe[1] != -1) {
01504       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01505          fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
01506       }
01507    }
01508    errno = save_errno;
01509 }

static void _null_sig_handler ( int  sig  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 989 of file asterisk.c.

00990 {
00991 }

static void _urg_handler ( int  num  )  [static]

Urgent handler.

Called by soft_hangup to interrupt the poll, read, or other system call. We don't actually need to do anything though. Remember: Cannot EVER ast_log from within a signal handler

Definition at line 1485 of file asterisk.c.

01486 {
01487    return;
01488 }

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

support for event profiling

Returns:
Returns the identifier of the counter.

Definition at line 700 of file asterisk.c.

References ast_calloc, ast_realloc, ast_strdup, profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, profile_data::max_size, profile_entry::name, prof_data, profile_entry::scale, and profile_entry::value.

Referenced by extension_match_core().

00701 {
00702    int l = sizeof(struct profile_data);
00703    int n = 10; /* default entries */
00704 
00705    if (prof_data == NULL) {
00706       prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
00707       if (prof_data == NULL)
00708          return -1;
00709       prof_data->entries = 0;
00710       prof_data->max_size = n;
00711    }
00712    if (prof_data->entries >= prof_data->max_size) {
00713       void *p;
00714       n = prof_data->max_size + 20;
00715       p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
00716       if (p == NULL)
00717          return -1;
00718       prof_data = p;
00719       prof_data->max_size = n;
00720    }
00721    n = prof_data->entries++;
00722    prof_data->e[n].name = ast_strdup(name);
00723    prof_data->e[n].value = 0;
00724    prof_data->e[n].events = 0;
00725    prof_data->e[n].mark = 0;
00726    prof_data->e[n].scale = scale;
00727    return n;
00728 }

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1836 of file asterisk.c.

Referenced by ast_el_read_history(), consolehandler(), and remoteconsolehandler().

01837 {
01838    while (*s) {
01839       if (*s > 32)
01840          return 0;
01841       s++;  
01842    }
01843    return 1;
01844 }

static int ast_cli_display_match_list ( char **  matches,
int  len,
int  max 
) [static]

Definition at line 2473 of file asterisk.c.

References ast_el_sort_compare(), ast_free, and ast_get_termcols().

Referenced by cli_complete().

02474 {
02475    int i, idx, limit, count;
02476    int screenwidth = 0;
02477    int numoutput = 0, numoutputline = 0;
02478 
02479    screenwidth = ast_get_termcols(STDOUT_FILENO);
02480 
02481    /* find out how many entries can be put on one line, with two spaces between strings */
02482    limit = screenwidth / (max + 2);
02483    if (limit == 0)
02484       limit = 1;
02485 
02486    /* how many lines of output */
02487    count = len / limit;
02488    if (count * limit < len)
02489       count++;
02490 
02491    idx = 1;
02492 
02493    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
02494 
02495    for (; count > 0; count--) {
02496       numoutputline = 0;
02497       for (i = 0; i < limit && matches[idx]; i++, idx++) {
02498 
02499          /* Don't print dupes */
02500          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
02501             i--;
02502             ast_free(matches[idx]);
02503             matches[idx] = NULL;
02504             continue;
02505          }
02506 
02507          numoutput++;
02508          numoutputline++;
02509          fprintf(stdout, "%-*s  ", max, matches[idx]);
02510          ast_free(matches[idx]);
02511          matches[idx] = NULL;
02512       }
02513       if (numoutputline > 0)
02514          fprintf(stdout, "\n");
02515    }
02516 
02517    return numoutput;
02518 }

char* ast_complete_source_filename ( const char *  partial,
int  n 
)

Definition at line 351 of file asterisk.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, file_version::file, len(), and ast_atexit::list.

Referenced by handle_verbose().

00352 {
00353    struct file_version *find;
00354    size_t len = strlen(partial);
00355    int count = 0;
00356    char *res = NULL;
00357 
00358    AST_RWLIST_RDLOCK(&file_versions);
00359    AST_RWLIST_TRAVERSE(&file_versions, find, list) {
00360       if (!strncasecmp(find->file, partial, len) && ++count > n) {
00361          res = ast_strdup(find->file);
00362          break;
00363       }
00364    }
00365    AST_RWLIST_UNLOCK(&file_versions);
00366    return res;
00367 }

void ast_console_puts ( const char *  string  ) 

write the string to the console, and all attached console clients

Definition at line 1178 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

01179 {
01180    fputs(string, stdout);
01181    fflush(stdout);
01182    ast_network_puts(string);
01183 }

void ast_console_puts_mutable ( const char *  string,
int  level 
)

log the string to the console, and all attached console clients

Version:
1.6.1 added level parameter

Definition at line 1155 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by init_logger_chain(), logger_print_normal(), and make_logchannel().

01156 {
01157    fputs(string, stdout);
01158    fflush(stdout);
01159    ast_network_puts_mutable(string, level);
01160 }

void ast_console_toggle_loglevel ( int  fd,
int  level,
int  state 
)

enables or disables logging of a specified level to the console fd specifies the index of the console receiving the level change level specifies the index of the logging level being toggled state indicates whether logging will be on or off (0 for off, 1 for on)

Definition at line 1097 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and levels.

Referenced by handle_logger_set_level().

01098 {
01099    int x;
01100    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01101       if (fd == consoles[x].fd) {
01102          /*
01103           * Since the logging occurs when levels are false, set to
01104           * flipped iinput because this function accepts 0 as off and 1 as on
01105           */
01106          consoles[x].levels[level] = state ? 0 : 1;
01107          return;
01108       }
01109    }
01110 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1115 of file asterisk.c.

References ast_cli(), AST_MAX_CONNECTS, consoles, console::mute, and mute.

Referenced by handle_logger_mute().

01116 {
01117    int x;
01118    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01119       if (fd == consoles[x].fd) {
01120          if (consoles[x].mute) {
01121             consoles[x].mute = 0;
01122             if (!silent)
01123                ast_cli(fd, "Console is not muted anymore.\n");
01124          } else {
01125             consoles[x].mute = 1;
01126             if (!silent)
01127                ast_cli(fd, "Console is muted.\n");
01128          }
01129          return;
01130       }
01131    }
01132    ast_cli(fd, "Couldn't find remote console.\n");
01133 }

static int ast_el_add_history ( char *   )  [static]

Definition at line 2676 of file asterisk.c.

References ast_el_initialize(), ast_strdupa, ast_strip(), el, el_hist, and MAX_HISTORY_COMMAND_LENGTH.

Referenced by ast_el_read_history(), consolehandler(), and remoteconsolehandler().

02677 {
02678    HistEvent ev;
02679 
02680    if (el_hist == NULL || el == NULL)
02681       ast_el_initialize();
02682    if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1))
02683       return 0;
02684    return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf))));
02685 }

static int ast_el_initialize ( void   )  [static]

Definition at line 2639 of file asterisk.c.

References cli_complete(), cli_prompt(), el, and el_hist.

Referenced by ast_el_add_history(), ast_el_read_history(), ast_el_write_history(), ast_remotecontrol(), and main().

02640 {
02641    HistEvent ev;
02642    char *editor = getenv("AST_EDITOR");
02643 
02644    if (el != NULL)
02645       el_end(el);
02646    if (el_hist != NULL)
02647       history_end(el_hist);
02648 
02649    el = el_init("asterisk", stdin, stdout, stderr);
02650    el_set(el, EL_PROMPT, cli_prompt);
02651 
02652    el_set(el, EL_EDITMODE, 1);      
02653    el_set(el, EL_EDITOR, editor ? editor : "emacs");     
02654    el_hist = history_init();
02655    if (!el || !el_hist)
02656       return -1;
02657 
02658    /* setup history with 100 entries */
02659    history(el_hist, &ev, H_SETSIZE, 100);
02660 
02661    el_set(el, EL_HIST, history, el_hist);
02662 
02663    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02664    /* Bind <tab> to command completion */
02665    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02666    /* Bind ? to command completion */
02667    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02668    /* Bind ^D to redisplay */
02669    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02670 
02671    return 0;
02672 }

static int ast_el_read_char ( EditLine *  editline,
char *  cp 
) [static]

Definition at line 2193 of file asterisk.c.

References ast_log(), ast_opt_exec, ast_opt_mute, ast_opt_reconnect, ast_poll, ast_tryconnect(), EL_BUF_SIZE, errno, fdsend(), LOG_ERROR, quit_handler(), SHUTDOWN_FAST, sig_flags, term_quit(), and WELCOME_MESSAGE.

Referenced by ast_remotecontrol(), and main().

02194 {
02195    int num_read = 0;
02196    int lastpos = 0;
02197    struct pollfd fds[2];
02198    int res;
02199    int max;
02200 #define EL_BUF_SIZE 512
02201    char buf[EL_BUF_SIZE];
02202 
02203    for (;;) {
02204       max = 1;
02205       fds[0].fd = ast_consock;
02206       fds[0].events = POLLIN;
02207       if (!ast_opt_exec) {
02208          fds[1].fd = STDIN_FILENO;
02209          fds[1].events = POLLIN;
02210          max++;
02211       }
02212       res = ast_poll(fds, max, -1);
02213       if (res < 0) {
02214          if (sig_flags.need_quit || sig_flags.need_quit_handler)
02215             break;
02216          if (errno == EINTR)
02217             continue;
02218          ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
02219          break;
02220       }
02221 
02222       if (!ast_opt_exec && fds[1].revents) {
02223          num_read = read(STDIN_FILENO, cp, 1);
02224          if (num_read < 1) {
02225             break;
02226          } else 
02227             return (num_read);
02228       }
02229       if (fds[0].revents) {
02230          char *tmp;
02231          res = read(ast_consock, buf, sizeof(buf) - 1);
02232          /* if the remote side disappears exit */
02233          if (res < 1) {
02234             fprintf(stderr, "\nDisconnected from Asterisk server\n");
02235             if (!ast_opt_reconnect) {
02236                quit_handler(0, SHUTDOWN_FAST, 0);
02237             } else {
02238                int tries;
02239                int reconnects_per_second = 20;
02240                fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
02241                for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
02242                   if (ast_tryconnect()) {
02243                      fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
02244                      printf("%s", term_quit());
02245                      WELCOME_MESSAGE;
02246                      if (!ast_opt_mute)
02247                         fdsend(ast_consock, "logger mute silent");
02248                      else 
02249                         printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02250                      break;
02251                   } else
02252                      usleep(1000000 / reconnects_per_second);
02253                }
02254                if (tries >= 30 * reconnects_per_second) {
02255                   fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
02256                   quit_handler(0, SHUTDOWN_FAST, 0);
02257                }
02258             }
02259          }
02260 
02261          buf[res] = '\0';
02262 
02263          /* Strip preamble from asynchronous events, too */
02264          for (tmp = buf; *tmp; tmp++) {
02265             if (*tmp == 127) {
02266                memmove(tmp, tmp + 1, strlen(tmp));
02267                tmp--;
02268                res--;
02269             }
02270          }
02271 
02272          /* Write over the CLI prompt */
02273          if (!ast_opt_exec && !lastpos) {
02274             if (write(STDOUT_FILENO, "\r", 5) < 0) {
02275             }
02276          }
02277          if (write(STDOUT_FILENO, buf, res) < 0) {
02278          }
02279          if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
02280             *cp = CC_REFRESH;
02281             return(1);
02282          } else
02283             lastpos = 1;
02284       }
02285    }
02286 
02287    *cp = '\0';
02288    return (0);
02289 }

static int ast_el_read_history ( char *   )  [static]

Definition at line 2697 of file asterisk.c.

References ast_all_zeros(), ast_el_add_history(), ast_el_initialize(), el, el_hist, f, and MAX_HISTORY_COMMAND_LENGTH.

Referenced by ast_remotecontrol(), and main().

02698 {
02699    char buf[MAX_HISTORY_COMMAND_LENGTH];
02700    FILE *f;
02701    int ret = -1;
02702 
02703    if (el_hist == NULL || el == NULL)
02704       ast_el_initialize();
02705 
02706    if ((f = fopen(filename, "r")) == NULL)
02707       return ret;
02708 
02709    while (!feof(f)) {
02710       if (!fgets(buf, sizeof(buf), f))
02711          break;
02712       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02713          continue;
02714       if (ast_all_zeros(buf))
02715          continue;
02716       if ((ret = ast_el_add_history(buf)) == -1)
02717          break;
02718    }
02719    fclose(f);
02720 
02721    return ret;
02722 }

static int ast_el_sort_compare ( const void *  i1,
const void *  i2 
) [static]

Definition at line 2463 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02464 {
02465    char *s1, *s2;
02466 
02467    s1 = ((char **)i1)[0];
02468    s2 = ((char **)i2)[0];
02469 
02470    return strcasecmp(s1, s2);
02471 }

static char** ast_el_strtoarr ( char *  buf  )  [static]

Definition at line 2420 of file asterisk.c.

References AST_CLI_COMPLETE_EOF, ast_free, ast_realloc, ast_strdup, and strsep().

Referenced by cli_complete().

02421 {
02422    char **match_list = NULL, **match_list_tmp, *retstr;
02423    size_t match_list_len;
02424    int matches = 0;
02425 
02426    match_list_len = 1;
02427    while ( (retstr = strsep(&buf, " ")) != NULL) {
02428 
02429       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
02430          break;
02431       if (matches + 1 >= match_list_len) {
02432          match_list_len <<= 1;
02433          if ((match_list_tmp = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
02434             match_list = match_list_tmp;
02435          } else {
02436             if (match_list)
02437                ast_free(match_list);
02438             return (char **) NULL;
02439          }
02440       }
02441 
02442       match_list[matches++] = ast_strdup(retstr);
02443    }
02444 
02445    if (!match_list)
02446       return (char **) NULL;
02447 
02448    if (matches >= match_list_len) {
02449       if ((match_list_tmp = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
02450          match_list = match_list_tmp;
02451       } else {
02452          if (match_list)
02453             ast_free(match_list);
02454          return (char **) NULL;
02455       }
02456    }
02457 
02458    match_list[matches] = (char *) NULL;
02459 
02460    return match_list;
02461 }

static int ast_el_write_history ( char *   )  [static]

Definition at line 2687 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by really_quit().

02688 {
02689    HistEvent ev;
02690 
02691    if (el_hist == NULL || el == NULL)
02692       ast_el_initialize();
02693 
02694    return (history(el_hist, &ev, H_SAVE, filename));
02695 }

const char* ast_file_version_find ( const char *  file  ) 

Find version for given module name.

Parameters:
file Module name (i.e. chan_sip.so)
Returns:
version string or NULL if the module is not found

Definition at line 370 of file asterisk.c.

References AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, file_version::file, ast_atexit::list, and file_version::version.

Referenced by manager_modulecheck().

00371 {
00372    struct file_version *iterator;
00373 
00374    AST_RWLIST_WRLOCK(&file_versions);
00375    AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
00376       if (!strcasecmp(iterator->file, file))
00377          break;
00378    }
00379    AST_RWLIST_UNLOCK(&file_versions);
00380    if (iterator)
00381       return iterator->version;
00382    return NULL;
00383 }      

static int ast_makesocket ( void   )  [static]

Definition at line 1388 of file asterisk.c.

References AF_LOCAL, ast_config_AST_CTL_GROUP, ast_config_AST_CTL_OWNER, ast_config_AST_CTL_PERMISSIONS, ast_config_AST_SOCKET, ast_copy_string(), ast_log(), AST_MAX_CONNECTS, ast_pthread_create_background, ast_register_verbose(), ast_strlen_zero(), consoles, errno, listener(), LOG_WARNING, lthread, network_verboser(), and PF_LOCAL.

Referenced by main().

01389 {
01390    struct sockaddr_un sunaddr;
01391    int res;
01392    int x;
01393    uid_t uid = -1;
01394    gid_t gid = -1;
01395 
01396    for (x = 0; x < AST_MAX_CONNECTS; x++) 
01397       consoles[x].fd = -1;
01398    unlink(ast_config_AST_SOCKET);
01399    ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
01400    if (ast_socket < 0) {
01401       ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
01402       return -1;
01403    }     
01404    memset(&sunaddr, 0, sizeof(sunaddr));
01405    sunaddr.sun_family = AF_LOCAL;
01406    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01407    res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01408    if (res) {
01409       ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01410       close(ast_socket);
01411       ast_socket = -1;
01412       return -1;
01413    }
01414    res = listen(ast_socket, 2);
01415    if (res < 0) {
01416       ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01417       close(ast_socket);
01418       ast_socket = -1;
01419       return -1;
01420    }
01421    if (ast_register_verbose(network_verboser)) {
01422       ast_log(LOG_WARNING, "Unable to register network verboser?\n");
01423    }
01424 
01425    ast_pthread_create_background(&lthread, NULL, listener, NULL);
01426 
01427    if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
01428       struct passwd *pw;
01429       if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
01430          ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
01431       else
01432          uid = pw->pw_uid;
01433    }
01434       
01435    if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
01436       struct group *grp;
01437       if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
01438          ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
01439       else
01440          gid = grp->gr_gid;
01441    }
01442 
01443    if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
01444       ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01445 
01446    if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
01447       int p1;
01448       mode_t p;
01449       sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
01450       p = p1;
01451       if ((chmod(ast_config_AST_SOCKET, p)) < 0)
01452          ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01453    }
01454 
01455    return 0;
01456 }

int64_t ast_mark ( int  i,
int  startstop 
)

Definition at line 765 of file asterisk.c.

References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, prof_data, rdtsc(), profile_entry::scale, and profile_entry::value.

Referenced by __ast_pthread_mutex_lock(), and extension_match_core().

00766 {
00767    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00768       return 0;
00769    if (startstop == 1)
00770       prof_data->e[i].mark = rdtsc();
00771    else {
00772       prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
00773       if (prof_data->e[i].scale > 1)
00774          prof_data->e[i].mark /= prof_data->e[i].scale;
00775       prof_data->e[i].value += prof_data->e[i].mark;
00776       prof_data->e[i].events++;
00777    }
00778    return prof_data->e[i].mark;
00779 }

static void ast_network_puts ( const char *  string  )  [static]

write the string to all attached console clients

Definition at line 1165 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

01166 {
01167    int x;
01168    for (x = 0; x < AST_MAX_CONNECTS; x++) {
01169       if (consoles[x].fd > -1) 
01170          fdprint(consoles[x].p[1], string);
01171    }
01172 }

static void ast_network_puts_mutable ( const char *  string,
int  level 
) [static]

log the string to all attached console clients

Definition at line 1138 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, fdprint(), levels, and mute.

Referenced by ast_console_puts_mutable(), and network_verboser().

01139 {
01140    int x;
01141    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01142       if (consoles[x].mute)
01143          continue;
01144       if (consoles[x].fd > -1) {
01145          if (!consoles[x].levels[level]) 
01146             fdprint(consoles[x].p[1], string);
01147       }
01148    }
01149 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 730 of file asterisk.c.

References profile_data::e, profile_data::entries, profile_entry::events, prof_data, profile_entry::scale, and profile_entry::value.

00731 {
00732    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00733       return 0;
00734    if (prof_data->e[i].scale > 1)
00735       delta /= prof_data->e[i].scale;
00736    prof_data->e[i].value += delta;
00737    prof_data->e[i].events++;
00738    return prof_data->e[i].value;
00739 }

static void ast_readconfig ( void   )  [static]

Definition at line 2915 of file asterisk.c.

References _cfg_paths::agi_dir, ast_config_AST_CONFIG_FILE, ast_config_AST_CTL, ast_config_AST_CTL_GROUP, ast_config_AST_CTL_OWNER, ast_config_AST_CTL_PERMISSIONS, ast_config_load2(), ast_copy_string(), ast_eid_default, ast_log(), ast_opt_override_config, ast_set_default_eid(), ast_variable_browse(), cfg_paths, config, _cfg_paths::config_dir, CONFIG_FLAG_NOREALTIME, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, _cfg_paths::data_dir, _cfg_paths::db_path, DEFAULT_AGI_DIR, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILE, DEFAULT_DATA_DIR, DEFAULT_DB, DEFAULT_KEY_DIR, DEFAULT_LOG_DIR, DEFAULT_MODULE_DIR, DEFAULT_PID, DEFAULT_RUN_DIR, DEFAULT_SOCKET, DEFAULT_SPOOL_DIR, DEFAULT_VAR_DIR, hostname, _cfg_paths::key_dir, _cfg_paths::log_dir, LOG_WARNING, MAXHOSTNAMELEN, _cfg_paths::module_dir, _cfg_paths::monitor_dir, ast_variable::name, ast_variable::next, _cfg_paths::pid_path, _cfg_paths::run_dir, _cfg_paths::socket_path, _cfg_paths::spool_dir, ast_variable::value, and _cfg_paths::var_dir.

Referenced by main().

02916 {
02917    struct ast_config *cfg;
02918    struct ast_variable *v;
02919    char *config = DEFAULT_CONFIG_FILE;
02920    char hostname[MAXHOSTNAMELEN] = "";
02921    struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME };
02922    struct {
02923       unsigned int dbdir:1;
02924       unsigned int keydir:1;
02925    } found = { 0, 0 };
02926 
02927    if (ast_opt_override_config) {
02928       cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
02929       if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
02930          ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
02931    } else 
02932       cfg = ast_config_load2(config, "" /* core, can't reload */, config_flags);
02933 
02934    /* init with buildtime config */
02935    ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir));
02936    ast_copy_string(cfg_paths.spool_dir, DEFAULT_SPOOL_DIR, sizeof(cfg_paths.spool_dir));
02937    ast_copy_string(cfg_paths.module_dir, DEFAULT_MODULE_DIR, sizeof(cfg_paths.module_dir));
02938    snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", cfg_paths.spool_dir);
02939    ast_copy_string(cfg_paths.var_dir, DEFAULT_VAR_DIR, sizeof(cfg_paths.var_dir));
02940    ast_copy_string(cfg_paths.data_dir, DEFAULT_DATA_DIR, sizeof(cfg_paths.data_dir));
02941    ast_copy_string(cfg_paths.log_dir, DEFAULT_LOG_DIR, sizeof(cfg_paths.log_dir));
02942    ast_copy_string(cfg_paths.agi_dir, DEFAULT_AGI_DIR, sizeof(cfg_paths.agi_dir));
02943    ast_copy_string(cfg_paths.db_path, DEFAULT_DB, sizeof(cfg_paths.db_path));
02944    ast_copy_string(cfg_paths.key_dir, DEFAULT_KEY_DIR, sizeof(cfg_paths.key_dir));
02945    ast_copy_string(cfg_paths.pid_path, DEFAULT_PID, sizeof(cfg_paths.pid_path));
02946    ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path));
02947    ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir));
02948 
02949    ast_set_default_eid(&ast_eid_default);
02950 
02951    /* no asterisk.conf? no problem, use buildtime config! */
02952    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
02953       return;
02954    }
02955 
02956    for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
02957       if (!strcasecmp(v->name, "astctlpermissions"))
02958          ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
02959       else if (!strcasecmp(v->name, "astctlowner"))
02960          ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
02961       else if (!strcasecmp(v->name, "astctlgroup"))
02962          ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
02963       else if (!strcasecmp(v->name, "astctl"))
02964          ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
02965    }
02966 
02967    for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
02968       if (!strcasecmp(v->name, "astetcdir")) {
02969          ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir));
02970       } else if (!strcasecmp(v->name, "astspooldir")) {
02971          ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir));
02972          snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value);
02973       } else if (!strcasecmp(v->name, "astvarlibdir")) {
02974          ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir));
02975          if (!found.dbdir)
02976             snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
02977       } else if (!strcasecmp(v->name, "astdbdir")) {
02978          snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
02979          found.dbdir = 1;
02980       } else if (!strcasecmp(v->name, "astdatadir")) {
02981          ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir));
02982          if (!found.keydir)
02983             snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
02984       } else if (!strcasecmp(v->name, "astkeydir")) {
02985          snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
02986          found.keydir = 1;
02987       } else if (!strcasecmp(v->name, "astlogdir")) {
02988          ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir));
02989       } else if (!strcasecmp(v->name, "astagidir")) {
02990          ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir));
02991       } else if (!strcasecmp(v->name, "astrundir")) {
02992          snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid");
02993          snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", v->value, ast_config_AST_CTL);
02994          ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir));
02995       } else if (!strcasecmp(v->name, "astmoddir")) {
02996          ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir));
02997       }
02998    }
02999 
03000    for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
03001       /* verbose level (-v at startup) */
03002       if (!strcasecmp(v->name, "verbose")) {
03003          option_verbose = atoi(v->value);
03004       /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
03005       } else if (!strcasecmp(v->name, "timestamp")) {
03006          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
03007       /* whether or not to support #exec in config files */
03008       } else if (!strcasecmp(v->name, "execincludes")) {
03009          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
03010       /* debug level (-d at startup) */
03011       } else if (!strcasecmp(v->name, "debug")) {
03012          option_debug = 0;
03013          if (sscanf(v->value, "%30d", &option_debug) != 1) {
03014             option_debug = ast_true(v->value);
03015          }
03016 #if HAVE_WORKING_FORK
03017       /* Disable forking (-f at startup) */
03018       } else if (!strcasecmp(v->name, "nofork")) {
03019          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
03020       /* Always fork, even if verbose or debug are enabled (-F at startup) */
03021       } else if (!strcasecmp(v->name, "alwaysfork")) {
03022          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
03023 #endif
03024       /* Run quietly (-q at startup ) */
03025       } else if (!strcasecmp(v->name, "quiet")) {
03026          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
03027       /* Run as console (-c at startup, implies nofork) */
03028       } else if (!strcasecmp(v->name, "console")) {
03029          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
03030       /* Run with high priority if the O/S permits (-p at startup) */
03031       } else if (!strcasecmp(v->name, "highpriority")) {
03032          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
03033       /* Initialize RSA auth keys (IAX2) (-i at startup) */
03034       } else if (!strcasecmp(v->name, "initcrypto")) {
03035          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
03036       /* Disable ANSI colors for console (-c at startup) */
03037       } else if (!strcasecmp(v->name, "nocolor")) {
03038          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
03039       /* Disable some usage warnings for picky people :p */
03040       } else if (!strcasecmp(v->name, "dontwarn")) {
03041          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
03042       /* Dump core in case of crash (-g) */
03043       } else if (!strcasecmp(v->name, "dumpcore")) {
03044          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
03045       /* Cache recorded sound files to another directory during recording */
03046       } else if (!strcasecmp(v->name, "cache_record_files")) {
03047          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
03048       /* Specify cache directory */
03049       }  else if (!strcasecmp(v->name, "record_cache_dir")) {
03050          ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
03051       /* Build transcode paths via SLINEAR, instead of directly */
03052       } else if (!strcasecmp(v->name, "transcode_via_sln")) {
03053          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
03054       /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
03055       } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
03056          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
03057       /* Enable internal timing */
03058       } else if (!strcasecmp(v->name, "internal_timing")) {
03059          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING);
03060       } else if (!strcasecmp(v->name, "maxcalls")) {
03061          if ((sscanf(v->value, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
03062             option_maxcalls = 0;
03063          }
03064       } else if (!strcasecmp(v->name, "maxload")) {
03065          double test[1];
03066 
03067          if (getloadavg(test, 1) == -1) {
03068             ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
03069             option_maxload = 0.0;
03070          } else if ((sscanf(v->value, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
03071             option_maxload = 0.0;
03072          }
03073       /* Set the maximum amount of open files */
03074       } else if (!strcasecmp(v->name, "maxfiles")) {
03075          option_maxfiles = atoi(v->value);
03076          set_ulimit(option_maxfiles);
03077       /* What user to run as */
03078       } else if (!strcasecmp(v->name, "runuser")) {
03079          ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user));
03080       /* What group to run as */
03081       } else if (!strcasecmp(v->name, "rungroup")) {
03082          ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group));
03083       } else if (!strcasecmp(v->name, "systemname")) {
03084          ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name));
03085       } else if (!strcasecmp(v->name, "autosystemname")) {
03086          if (ast_true(v->value)) {
03087             if (!gethostname(hostname, sizeof(hostname) - 1))
03088                ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name));
03089             else {
03090                if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){
03091                   ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name));
03092                }
03093                ast_log(LOG_ERROR, "Cannot obtain hostname for this system.  Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME);
03094             }
03095          }
03096       } else if (!strcasecmp(v->name, "languageprefix")) {
03097          ast_language_is_prefix = ast_true(v->value);
03098       } else if (!strcasecmp(v->name, "defaultlanguage")) {
03099          ast_copy_string(defaultlanguage, v->value, MAX_LANGUAGE);
03100       } else if (!strcasecmp(v->name, "lockmode")) {
03101          if (!strcasecmp(v->value, "lockfile")) {
03102             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03103          } else if (!strcasecmp(v->value, "flock")) {
03104             ast_set_lock_type(AST_LOCK_TYPE_FLOCK);
03105          } else {
03106             ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, "
03107                "defaulting to 'lockfile'\n", v->value);
03108             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03109          }
03110 #if defined(HAVE_SYSINFO)
03111       } else if (!strcasecmp(v->name, "minmemfree")) {
03112          /* specify the minimum amount of free memory to retain.  Asterisk should stop accepting new calls
03113           * if the amount of free memory falls below this watermark */
03114          if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
03115             option_minmemfree = 0;
03116          }
03117 #endif
03118       } else if (!strcasecmp(v->name, "entityid")) {
03119          struct ast_eid tmp_eid;
03120          if (!ast_str_to_eid(&tmp_eid, v->value)) {
03121             ast_verbose("Successfully set global EID to '%s'\n", v->value);
03122             ast_eid_default = tmp_eid;
03123          } else
03124             ast_verbose("Invalid Entity ID '%s' provided\n", v->value);
03125       } else if (!strcasecmp(v->name, "lightbackground")) {
03126          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND);
03127       } else if (!strcasecmp(v->name, "forceblackbackground")) {
03128          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03129       } else if (!strcasecmp(v->name, "hideconnect")) {
03130          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT);
03131       } else if (!strcasecmp(v->name, "lockconfdir")) {
03132          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LOCK_CONFIG_DIR);
03133       }
03134    }
03135    for (v = ast_variable_browse(cfg, "compat"); v; v = v->next) {
03136       float version;
03137       if (sscanf(v->value, "%30f", &version) != 1) {
03138          ast_log(LOG_WARNING, "Compatibility version for option '%s' is not a number: '%s'\n", v->name, v->value);
03139          continue;
03140       }
03141       if (!strcasecmp(v->name, "app_set")) {
03142          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_APP_SET);
03143       } else if (!strcasecmp(v->name, "res_agi")) {
03144          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_RES_AGI);
03145       } else if (!strcasecmp(v->name, "pbx_realtime")) {
03146          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_PBX_REALTIME);
03147       }
03148    }
03149    ast_config_destroy(cfg);
03150 }

int ast_register_atexit ( void(*)(void)  func  ) 

Register a function to be executed before Asterisk exits.

Parameters:
func The callback function to use.
Return values:
0 on success.
-1 on error.

Definition at line 941 of file asterisk.c.

References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_unregister_atexit(), and ast_atexit::list.

Referenced by ast_cel_engine_init(), do_reload(), load_module(), and main().

00942 {
00943    struct ast_atexit *ae;
00944 
00945    if (!(ae = ast_calloc(1, sizeof(*ae))))
00946       return -1;
00947 
00948    ae->func = func;
00949 
00950    ast_unregister_atexit(func);  
00951 
00952    AST_RWLIST_WRLOCK(&atexits);
00953    AST_RWLIST_INSERT_HEAD(&atexits, ae, list);
00954    AST_RWLIST_UNLOCK(&atexits);
00955 
00956    return 0;
00957 }

void ast_register_file_version ( const char *  file,
const char *  version 
)

Register the version of a source code file with the core.

Parameters:
file the source file name
version the version string (typically a SVN revision keyword string)
Returns:
nothing
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to register a file with the core.

Definition at line 312 of file asterisk.c.

References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdupa, ast_strip(), ast_strip_quoted(), and ast_atexit::list.

00313 {
00314    struct file_version *new;
00315    char *work;
00316    size_t version_length;
00317 
00318    work = ast_strdupa(version);
00319    work = ast_strip(ast_strip_quoted(work, "$", "$"));
00320    version_length = strlen(work) + 1;
00321    
00322    if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
00323       return;
00324 
00325    new->file = file;
00326    new->version = (char *) new + sizeof(*new);
00327    memcpy(new->version, work, version_length);
00328    AST_RWLIST_WRLOCK(&file_versions);
00329    AST_RWLIST_INSERT_HEAD(&file_versions, new, list);
00330    AST_RWLIST_UNLOCK(&file_versions);
00331 }

void ast_register_thread ( char *  name  ) 

Definition at line 395 of file asterisk.c.

References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_atexit::list.

Referenced by dummy_start().

00396 { 
00397    struct thread_list_t *new = ast_calloc(1, sizeof(*new));
00398 
00399    if (!new)
00400       return;
00401    new->id = pthread_self();
00402    new->name = name; /* steal the allocated memory for the thread name */
00403    AST_RWLIST_WRLOCK(&thread_list);
00404    AST_RWLIST_INSERT_HEAD(&thread_list, new, list);
00405    AST_RWLIST_UNLOCK(&thread_list);
00406 }

static void ast_remotecontrol ( char *  data  )  [static]

Definition at line 2724 of file asterisk.c.

References __remote_quit_handler(), ast_el_initialize(), ast_el_read_char(), ast_el_read_history(), ast_log(), ast_opt_exec, ast_opt_mute, ast_poll, ast_strlen_zero(), ast_verbose, el, el_hist, errno, fdsend(), hostname, LOG_ERROR, LOG_WARNING, prefix, remoteconsolehandler(), remotehostname, sig_flags, strsep(), and version.

Referenced by main().

02725 {
02726    char buf[80];
02727    int res;
02728    char filename[80] = "";
02729    char *hostname;
02730    char *cpid;
02731    char *version;
02732    int pid;
02733    char *stringp = NULL;
02734 
02735    char *ebuf;
02736    int num = 0;
02737 
02738    memset(&sig_flags, 0, sizeof(sig_flags));
02739    signal(SIGINT, __remote_quit_handler);
02740    signal(SIGTERM, __remote_quit_handler);
02741    signal(SIGHUP, __remote_quit_handler);
02742 
02743    if (read(ast_consock, buf, sizeof(buf)) < 0) {
02744       ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02745       return;
02746    }
02747    if (data) {
02748       char prefix[] = "cli quit after ";
02749       char *tmp = alloca(strlen(data) + strlen(prefix) + 1);
02750       sprintf(tmp, "%s%s", prefix, data);
02751       if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
02752          ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
02753          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02754             return;
02755          }
02756       }
02757    }
02758    stringp = buf;
02759    hostname = strsep(&stringp, "/");
02760    cpid = strsep(&stringp, "/");
02761    version = strsep(&stringp, "\n");
02762    if (!version)
02763       version = "<Version Unknown>";
02764    stringp = hostname;
02765    strsep(&stringp, ".");
02766    if (cpid)
02767       pid = atoi(cpid);
02768    else
02769       pid = -1;
02770    if (!data) {
02771       char tmp[80];
02772       snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
02773       fdsend(ast_consock, tmp);
02774       snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
02775       fdsend(ast_consock, tmp);
02776       if (!ast_opt_mute)
02777          fdsend(ast_consock, "logger mute silent");
02778       else 
02779          printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02780    }
02781 
02782    if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
02783       struct pollfd fds;
02784       fds.fd = ast_consock;
02785       fds.events = POLLIN;
02786       fds.revents = 0;
02787       while (ast_poll(&fds, 1, 60000) > 0) {
02788          char buffer[512] = "", *curline = buffer, *nextline;
02789          int not_written = 1;
02790 
02791          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02792             break;
02793          }
02794 
02795          if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
02796             break;
02797          }
02798 
02799          do {
02800             if ((nextline = strchr(curline, '\n'))) {
02801                nextline++;
02802             } else {
02803                nextline = strchr(curline, '\0');
02804             }
02805 
02806             /* Skip verbose lines */
02807             if (*curline != 127) {
02808                not_written = 0;
02809                if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
02810                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
02811                }
02812             }
02813             curline = nextline;
02814          } while (!ast_strlen_zero(curline));
02815 
02816          /* No non-verbose output in 60 seconds. */
02817          if (not_written) {
02818             break;
02819          }
02820       }
02821       return;
02822    }
02823 
02824    ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
02825    remotehostname = hostname;
02826    if (getenv("HOME")) 
02827       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
02828    if (el_hist == NULL || el == NULL)
02829       ast_el_initialize();
02830 
02831    el_set(el, EL_GETCFN, ast_el_read_char);
02832 
02833    if (!ast_strlen_zero(filename))
02834       ast_el_read_history(filename);
02835 
02836    for (;;) {
02837       ebuf = (char *)el_gets(el, &num);
02838 
02839       if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02840          break;
02841       }
02842 
02843       if (!ebuf && write(1, "", 1) < 0)
02844          break;
02845 
02846       if (!ast_strlen_zero(ebuf)) {
02847          if (ebuf[strlen(ebuf)-1] == '\n')
02848             ebuf[strlen(ebuf)-1] = '\0';
02849          if (!remoteconsolehandler(ebuf)) {
02850             /* Strip preamble from output */
02851             char *temp;
02852             for (temp = ebuf; *temp; temp++) {
02853                if (*temp == 127) {
02854                   memmove(temp, temp + 1, strlen(temp));
02855                   temp--;
02856                }
02857             }
02858             res = write(ast_consock, ebuf, strlen(ebuf) + 1);
02859             if (res < 1) {
02860                ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
02861                break;
02862             }
02863          }
02864       }
02865    }
02866    printf("\nDisconnected from Asterisk server\n");
02867 }

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

References ast_mutex_lock, ast_mutex_unlock, safe_system_level, and safe_system_lock.

Referenced by ast_safe_fork(), and ast_safe_system().

01009 {
01010    unsigned int level;
01011 
01012    ast_mutex_lock(&safe_system_lock);
01013    level = safe_system_level++;
01014 
01015    /* only replace the handler if it has not already been done */
01016    if (level == 0) {
01017       sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
01018    }
01019 
01020    ast_mutex_unlock(&safe_system_lock);
01021 }

static void ast_run_atexits ( void   )  [static]

Definition at line 1608 of file asterisk.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_atexit::func, and ast_atexit::list.

Referenced by really_quit().

01609 {
01610    struct ast_atexit *ae;
01611    AST_RWLIST_RDLOCK(&atexits);
01612    AST_RWLIST_TRAVERSE(&atexits, ae, list) {
01613       if (ae->func) 
01614          ae->func();
01615    }
01616    AST_RWLIST_UNLOCK(&atexits);
01617 }

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

References ast_close_fds_above_n(), ast_log(), ast_opt_high_priority, ast_replace_sigchld(), ast_set_priority(), ast_unreplace_sigchld(), errno, LOG_WARNING, status, WEXITSTATUS, and WIFEXITED.

Referenced by add_email_attachment(), alarmreceiver_exec(), ast_monitor_stop(), consolehandler(), mixmonitor_thread(), notify_message(), process_text_line(), remoteconsolehandler(), rotate_file(), run_externnotify(), sendmail(), sendpage(), system_exec_helper(), and vm_change_password_shell().

01039 {
01040    pid_t pid;
01041    int res;
01042    struct rusage rusage;
01043    int status;
01044 
01045 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
01046    ast_replace_sigchld();
01047 
01048 #ifdef HAVE_WORKING_FORK
01049    pid = fork();
01050 #else
01051    pid = vfork();
01052 #endif   
01053 
01054    if (pid == 0) {
01055 #ifdef HAVE_CAP
01056       cap_t cap = cap_from_text("cap_net_admin-eip");
01057 
01058       if (cap_set_proc(cap)) {
01059          /* Careful with order! Logging cannot happen after we close FDs */
01060          ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
01061       }
01062       cap_free(cap);
01063 #endif
01064 #ifdef HAVE_WORKING_FORK
01065       if (ast_opt_high_priority)
01066          ast_set_priority(0);
01067       /* Close file descriptors and launch system command */
01068       ast_close_fds_above_n(STDERR_FILENO);
01069 #endif
01070       execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
01071       _exit(1);
01072    } else if (pid > 0) {
01073       for (;;) {
01074          res = wait4(pid, &status, 0, &rusage);
01075          if (res > -1) {
01076             res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
01077             break;
01078          } else if (errno != EINTR) 
01079             break;
01080       }
01081    } else {
01082       ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
01083       res = -1;
01084    }
01085 
01086    ast_unreplace_sigchld();
01087 #else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */
01088    res = -1;
01089 #endif
01090 
01091    return res;
01092 }

int ast_set_priority ( int   ) 

We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy activity on it, this is a good thing.

Provided by asterisk.c

Definition at line 1574 of file asterisk.c.

References ast_log(), ast_verbose, LOG_WARNING, sched_setscheduler, and setpriority.

Referenced by ast_safe_system(), canary_thread(), icesencode(), launch_script(), main(), mp3play(), NBScatplay(), send_waveform_to_fd(), spawn_mp3(), and spawn_ras().

01575 {
01576    struct sched_param sched;
01577    memset(&sched, 0, sizeof(sched));
01578 #ifdef __linux__
01579    if (pri) {  
01580       sched.sched_priority = 10;
01581       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01582          ast_log(LOG_WARNING, "Unable to set high priority\n");
01583          return -1;
01584       } else
01585          if (option_verbose)
01586             ast_verbose("Set to realtime thread\n");
01587    } else {
01588       sched.sched_priority = 0;
01589       /* According to the manpage, these parameters can never fail. */
01590       sched_setscheduler(0, SCHED_OTHER, &sched);
01591    }
01592 #else
01593    if (pri) {
01594       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01595          ast_log(LOG_WARNING, "Unable to set high priority\n");
01596          return -1;
01597       } else
01598          if (option_verbose)
01599             ast_verbose("Set to high priority\n");
01600    } else {
01601       /* According to the manpage, these parameters can never fail. */
01602       setpriority(PRIO_PROCESS, 0, 0);
01603    }
01604 #endif
01605    return 0;
01606 }

static int ast_tryconnect ( void   )  [static]

Definition at line 1458 of file asterisk.c.

References AF_LOCAL, ast_config_AST_SOCKET, ast_copy_string(), ast_log(), errno, LOG_WARNING, and PF_LOCAL.

Referenced by ast_el_read_char(), and main().

01459 {
01460    struct sockaddr_un sunaddr;
01461    int res;
01462    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01463    if (ast_consock < 0) {
01464       ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
01465       return 0;
01466    }
01467    memset(&sunaddr, 0, sizeof(sunaddr));
01468    sunaddr.sun_family = AF_LOCAL;
01469    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01470    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01471    if (res) {
01472       close(ast_consock);
01473       ast_consock = -1;
01474       return 0;
01475    } else
01476       return 1;
01477 }

void ast_unregister_atexit ( void(*)(void)  func  ) 

Unregister a function registered with ast_register_atexit().

Parameters:
func The callback function to unregister.

Definition at line 959 of file asterisk.c.

References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free, ast_atexit::func, and ast_atexit::list.

Referenced by ast_register_atexit(), do_reload(), and unload_module().

00960 {
00961    struct ast_atexit *ae = NULL;
00962 
00963    AST_RWLIST_WRLOCK(&atexits);
00964    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
00965       if (ae->func == func) {
00966          AST_RWLIST_REMOVE_CURRENT(list);
00967          break;
00968       }
00969    }
00970    AST_RWLIST_TRAVERSE_SAFE_END;
00971    AST_RWLIST_UNLOCK(&atexits);
00972 
00973    free(ae);
00974 }

void ast_unregister_file_version ( const char *  file  ) 

Unregister a source code file from the core.

Parameters:
file the source file name
Returns:
nothing
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to automatically unregister the file when the module is unloaded.

Definition at line 333 of file asterisk.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, file_version::file, and ast_atexit::list.

00334 {
00335    struct file_version *find;
00336 
00337    AST_RWLIST_WRLOCK(&file_versions);
00338    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
00339       if (!strcasecmp(find->file, file)) {
00340          AST_RWLIST_REMOVE_CURRENT(list);
00341          break;
00342       }
00343    }
00344    AST_RWLIST_TRAVERSE_SAFE_END;
00345    AST_RWLIST_UNLOCK(&file_versions);
00346 
00347    if (find)
00348       ast_free(find);
00349 }

void ast_unregister_thread ( void *  id  ) 

Definition at line 408 of file asterisk.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, thread_list_t::id, ast_atexit::list, and thread_list_t::name.

Referenced by dummy_start().

00409 {
00410    struct thread_list_t *x;
00411 
00412    AST_RWLIST_WRLOCK(&thread_list);
00413    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
00414       if ((void *) x->id == id) {
00415          AST_RWLIST_REMOVE_CURRENT(list);
00416          break;
00417       }
00418    }
00419    AST_RWLIST_TRAVERSE_SAFE_END;
00420    AST_RWLIST_UNLOCK(&thread_list);
00421    if (x) {
00422       ast_free(x->name);
00423       ast_free(x);
00424    }
00425 }

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

References ast_mutex_lock, ast_mutex_unlock, safe_system_level, and safe_system_lock.

Referenced by ast_safe_fork_cleanup(), and ast_safe_system().

01024 {
01025    unsigned int level;
01026 
01027    ast_mutex_lock(&safe_system_lock);
01028    level = --safe_system_level;
01029 
01030    /* only restore the handler if we are the last one */
01031    if (level == 0) {
01032       sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
01033    }
01034 
01035    ast_mutex_unlock(&safe_system_lock);
01036 }

static int can_safely_quit ( shutdown_nice_t  niceness,
int  restart 
) [static]

Definition at line 1631 of file asterisk.c.

References ast_active_channels(), ast_begin_shutdown(), ast_cdr_engine_term(), ast_mutex_lock, ast_mutex_unlock, ast_opt_console, ast_verbose, NOT_SHUTTING_DOWN, safe_system_lock, SHUTDOWN_NICE, SHUTDOWN_NORMAL, SHUTDOWN_REALLY_NICE, SHUTTING_DOWN, and shuttingdown.

Referenced by quit_handler().

01632 {
01633    /* Check if someone else isn't already doing this. */
01634    ast_mutex_lock(&safe_system_lock);
01635    if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
01636       /* Already in progress and other request was less nice. */
01637       ast_mutex_unlock(&safe_system_lock);
01638       ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
01639       return 0;
01640    }
01641    shuttingdown = niceness;
01642    ast_mutex_unlock(&safe_system_lock);
01643 
01644    /* Try to get as many CDRs as possible submitted to the backend engines
01645     * (if in batch mode). really_quit happens to call it again when running
01646     * the atexit handlers, otherwise this would be a bit early. */
01647    ast_cdr_engine_term();
01648 
01649    if (niceness == SHUTDOWN_NORMAL) {
01650       time_t s, e;
01651       /* Begin shutdown routine, hanging up active channels */
01652       ast_begin_shutdown(1);
01653       if (option_verbose && ast_opt_console) {
01654          ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
01655       }
01656       time(&s);
01657       for (;;) {
01658          time(&e);
01659          /* Wait up to 15 seconds for all channels to go away */
01660          if ((e - s) > 15 || !ast_active_channels() || shuttingdown != niceness) {
01661             break;
01662          }
01663          /* Sleep 1/10 of a second */
01664          usleep(100000);
01665       }
01666    } else if (niceness >= SHUTDOWN_NICE) {
01667       if (niceness != SHUTDOWN_REALLY_NICE) {
01668          ast_begin_shutdown(0);
01669       }
01670       if (option_verbose && ast_opt_console) {
01671          ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
01672       }
01673       for (;;) {
01674          if (!ast_active_channels() || shuttingdown != niceness) {
01675             break;
01676          }
01677          sleep(1);
01678       }
01679    }
01680 
01681    /* Re-acquire lock and check if someone changed the niceness, in which
01682     * case someone else has taken over the shutdown. */
01683    ast_mutex_lock(&safe_system_lock);
01684    if (shuttingdown != niceness) {
01685       if (shuttingdown == NOT_SHUTTING_DOWN && option_verbose && ast_opt_console) {
01686          ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
01687       }
01688       ast_mutex_unlock(&safe_system_lock);
01689       return 0;
01690    }
01691    shuttingdown = SHUTTING_DOWN;
01692    ast_mutex_unlock(&safe_system_lock);
01693 
01694    return 1;
01695 }

static void canary_exit ( void   )  [static]

Definition at line 3208 of file asterisk.c.

References canary_pid.

Referenced by main().

03209 {
03210    if (canary_pid > 0)
03211       kill(canary_pid, SIGKILL);
03212 }

static void* canary_thread ( void *  unused  )  [static]

Definition at line 3178 of file asterisk.c.

References ast_log(), ast_set_priority(), ast_tvnow(), canary_filename, and LOG_WARNING.

Referenced by main().

03179 {
03180    struct stat canary_stat;
03181    struct timeval now;
03182 
03183    /* Give the canary time to sing */
03184    sleep(120);
03185 
03186    for (;;) {
03187       stat(canary_filename, &canary_stat);
03188       now = ast_tvnow();
03189       if (now.tv_sec > canary_stat.st_mtime + 60) {
03190          ast_log(LOG_WARNING,
03191             "The canary is no more.  He has ceased to be!  "
03192             "He's expired and gone to meet his maker!  "
03193             "He's a stiff!  Bereft of life, he rests in peace.  "
03194             "His metabolic processes are now history!  He's off the twig!  "
03195             "He's kicked the bucket.  He's shuffled off his mortal coil, "
03196             "run down the curtain, and joined the bleeding choir invisible!!  "
03197             "THIS is an EX-CANARY.  (Reducing priority)\n");
03198          ast_set_priority(0);
03199          pthread_exit(NULL);
03200       }
03201 
03202       /* Check the canary once a minute */
03203       sleep(60);
03204    }
03205 }

static char* cli_complete ( EditLine *  editline,
int  ch 
) [static]

Definition at line 2521 of file asterisk.c.

References AST_CLI_COMPLETE_EOF, ast_cli_completion_matches(), ast_cli_display_match_list(), ast_el_strtoarr(), ast_free, ast_malloc, ast_opt_remote, ast_realloc, and fdsend().

Referenced by ast_el_initialize().

02522 {
02523    int len = 0;
02524    char *ptr;
02525    int nummatches = 0;
02526    char **matches;
02527    int retval = CC_ERROR;
02528    char buf[2048], savechr;
02529    int res;
02530 
02531    LineInfo *lf = (LineInfo *)el_line(editline);
02532 
02533    savechr = *(char *)lf->cursor;
02534    *(char *)lf->cursor = '\0';
02535    ptr = (char *)lf->cursor;
02536    if (ptr) {
02537       while (ptr > lf->buffer) {
02538          if (isspace(*ptr)) {
02539             ptr++;
02540             break;
02541          }
02542          ptr--;
02543       }
02544    }
02545 
02546    len = lf->cursor - ptr;
02547 
02548    if (ast_opt_remote) {
02549       snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 
02550       fdsend(ast_consock, buf);
02551       res = read(ast_consock, buf, sizeof(buf) - 1);
02552       buf[res] = '\0';
02553       nummatches = atoi(buf);
02554 
02555       if (nummatches > 0) {
02556          char *mbuf;
02557          int mlen = 0, maxmbuf = 2048;
02558          /* Start with a 2048 byte buffer */       
02559          if (!(mbuf = ast_malloc(maxmbuf))) {
02560             lf->cursor[0] = savechr;
02561             return (char *)(CC_ERROR);
02562          }
02563          snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 
02564          fdsend(ast_consock, buf);
02565          res = 0;
02566          mbuf[0] = '\0';
02567          while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
02568             if (mlen + 1024 > maxmbuf) {
02569                /* Every step increment buffer 1024 bytes */
02570                maxmbuf += 1024;              
02571                if (!(mbuf = ast_realloc(mbuf, maxmbuf))) {
02572                   lf->cursor[0] = savechr;
02573                   return (char *)(CC_ERROR);
02574                }
02575             }
02576             /* Only read 1024 bytes at a time */
02577             res = read(ast_consock, mbuf + mlen, 1024);
02578             if (res > 0)
02579                mlen += res;
02580          }
02581          mbuf[mlen] = '\0';
02582 
02583          matches = ast_el_strtoarr(mbuf);
02584          ast_free(mbuf);
02585       } else
02586          matches = (char **) NULL;
02587    } else {
02588       char **p, *oldbuf=NULL;
02589       nummatches = 0;
02590       matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
02591       for (p = matches; p && *p; p++) {
02592          if (!oldbuf || strcmp(*p,oldbuf))
02593             nummatches++;
02594          oldbuf = *p;
02595       }
02596    }
02597 
02598    if (matches) {
02599       int i;
02600       int matches_num, maxlen, match_len;
02601 
02602       if (matches[0][0] != '\0') {
02603          el_deletestr(editline, (int) len);
02604          el_insertstr(editline, matches[0]);
02605          retval = CC_REFRESH;
02606       }
02607 
02608       if (nummatches == 1) {
02609          /* Found an exact match */
02610          el_insertstr(editline, " ");
02611          retval = CC_REFRESH;
02612       } else {
02613          /* Must be more than one match */
02614          for (i = 1, maxlen = 0; matches[i]; i++) {
02615             match_len = strlen(matches[i]);
02616             if (match_len > maxlen)
02617                maxlen = match_len;
02618          }
02619          matches_num = i - 1;
02620          if (matches_num >1) {
02621             fprintf(stdout, "\n");
02622             ast_cli_display_match_list(matches, nummatches, maxlen);
02623             retval = CC_REDISPLAY;
02624          } else { 
02625             el_insertstr(editline," ");
02626             retval = CC_REFRESH;
02627          }
02628       }
02629       for (i = 0; matches[i]; i++)
02630          ast_free(matches[i]);
02631       ast_free(matches);
02632    }
02633 
02634    lf->cursor[0] = savechr;
02635 
02636    return (char *)(long)retval;
02637 }

static char* cli_prompt ( EditLine *  editline  )  [static]

Definition at line 2293 of file asterisk.c.

References ast_config_AST_SYSTEM_NAME, ast_localtime(), ast_opt_remote, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_str_set(), ast_strftime(), ast_tvnow(), ASTERISK_PROMPT, ASTERISK_PROMPT2, COLOR_BLACK, COLOR_WHITE, getloadavg(), hostname, ast_atexit::list, MAXHOSTNAMELEN, prompt, remotehostname, and term_color_code().

Referenced by ast_el_initialize().

02294 {
02295    char tmp[100];
02296    char *pfmt;
02297    int color_used = 0;
02298    static int cli_prompt_changes = 0;
02299    char term_code[20];
02300    struct passwd *pw;
02301    struct group *gr;
02302 
02303    if (prompt == NULL) {
02304       prompt = ast_str_create(100);
02305    } else if (!cli_prompt_changes) {
02306       return ast_str_buffer(prompt);
02307    } else {
02308       ast_str_reset(prompt);
02309    }
02310 
02311    if ((pfmt = getenv("ASTERISK_PROMPT"))) {
02312       char *t = pfmt;
02313       struct timeval ts = ast_tvnow();
02314       while (*t != '\0') {
02315          if (*t == '%') {
02316             char hostname[MAXHOSTNAMELEN] = "";
02317             int i, which;
02318             struct ast_tm tm = { 0, };
02319             int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
02320 
02321             t++;
02322             switch (*t) {
02323             case 'C': /* color */
02324                t++;
02325                if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
02326                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)));
02327                   t += i - 1;
02328                } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
02329                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code)));
02330                   t += i - 1;
02331                }
02332 
02333                /* If the color has been reset correctly, then there's no need to reset it later */
02334                color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
02335                break;
02336             case 'd': /* date */
02337                if (ast_localtime(&ts, &tm, NULL)) {
02338                   ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
02339                   ast_str_append(&prompt, 0, "%s", tmp);
02340                   cli_prompt_changes++;
02341                }
02342                break;
02343             case 'g': /* group */
02344                if ((gr = getgrgid(getgid()))) {
02345                   ast_str_append(&prompt, 0, "%s", gr->gr_name);
02346                }
02347                break;
02348             case 'h': /* hostname */
02349                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02350                   ast_str_append(&prompt, 0, "%s", hostname);
02351                } else {
02352                   ast_str_append(&prompt, 0, "%s", "localhost");
02353                }
02354                break;
02355             case 'H': /* short hostname */
02356                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02357                   char *dotptr;
02358                   if ((dotptr = strchr(hostname, '.'))) {
02359                      *dotptr = '\0';
02360                   }
02361                   ast_str_append(&prompt, 0, "%s", hostname);
02362                } else {
02363                   ast_str_append(&prompt, 0, "%s", "localhost");
02364                }
02365                break;
02366 #ifdef HAVE_GETLOADAVG
02367             case 'l': /* load avg */
02368                t++;
02369                if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
02370                   double list[3];
02371                   getloadavg(list, 3);
02372                   ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
02373                   cli_prompt_changes++;
02374                }
02375                break;
02376 #endif
02377             case 's': /* Asterisk system name (from asterisk.conf) */
02378                ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
02379                break;
02380             case 't': /* time */
02381                if (ast_localtime(&ts, &tm, NULL)) {
02382                   ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
02383                   ast_str_append(&prompt, 0, "%s", tmp);
02384                   cli_prompt_changes++;
02385                }
02386                break;
02387             case 'u': /* username */
02388                if ((pw = getpwuid(getuid()))) {
02389                   ast_str_append(&prompt, 0, "%s", pw->pw_name);
02390                }
02391                break;
02392             case '#': /* process console or remote? */
02393                ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
02394                break;
02395             case '%': /* literal % */
02396                ast_str_append(&prompt, 0, "%c", '%');
02397                break;
02398             case '\0': /* % is last character - prevent bug */
02399                t--;
02400                break;
02401             }
02402          } else {
02403             ast_str_append(&prompt, 0, "%c", *t);
02404          }
02405          t++;
02406       }
02407       if (color_used) {
02408          /* Force colors back to normal at end */
02409          ast_str_append(&prompt, 0, "%s", term_color_code(term_code, 0, 0, sizeof(term_code)));
02410       }
02411    } else if (remotehostname) {
02412       ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname);
02413    } else {
02414       ast_str_set(&prompt, 0, "%s", ASTERISK_PROMPT);
02415    }
02416 
02417    return ast_str_buffer(prompt);   
02418 }

static void console_verboser ( const char *  s  )  [static]

Definition at line 1811 of file asterisk.c.

References ast_opt_console, AST_PTHREADT_NULL, consolethread, fix_header(), VERBOSE_PREFIX_1, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.

Referenced by main().

01812 {
01813    char tmp[80];
01814    const char *c = NULL;
01815 
01816    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01817        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01818        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01819        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
01820       fputs(tmp, stdout);
01821       fputs(c, stdout);
01822    } else {
01823       if (*s == 127) {
01824          s++;
01825       }
01826       fputs(s, stdout);
01827    }
01828 
01829    fflush(stdout);
01830    
01831    /* Wake up a poll()ing console */
01832    if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
01833       pthread_kill(consolethread, SIGURG);
01834 }

static void consolehandler ( char *  s  )  [static]

Definition at line 1846 of file asterisk.c.

References ast_all_zeros(), ast_cli_command, ast_el_add_history(), ast_safe_system(), and term_end().

Referenced by main().

01847 {
01848    printf("%s", term_end());
01849    fflush(stdout);
01850 
01851    /* Called when readline data is available */
01852    if (!ast_all_zeros(s))
01853       ast_el_add_history(s);
01854    /* The real handler for bang */
01855    if (s[0] == '!') {
01856       if (s[1])
01857          ast_safe_system(s+1);
01858       else
01859          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01860    } else 
01861       ast_cli_command(STDOUT_FILENO, s);
01862 }

static void env_init ( void   )  [static]

Definition at line 3242 of file asterisk.c.

References ast_build_date, ast_build_hostname, ast_build_kernel, ast_build_machine, ast_build_os, ast_build_user, ast_config_AST_SYSTEM_NAME, ast_get_version(), and setenv().

Referenced by main().

03243 {
03244    setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
03245    setenv("AST_BUILD_HOST", ast_build_hostname, 1);
03246    setenv("AST_BUILD_DATE", ast_build_date, 1);
03247    setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
03248    setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
03249    setenv("AST_BUILD_OS", ast_build_os, 1);
03250    setenv("AST_BUILD_USER", ast_build_user, 1);
03251    setenv("AST_VERSION", ast_get_version(), 1);
03252 }

static int fdprint ( int  fd,
const char *  s 
) [static]

Definition at line 983 of file asterisk.c.

Referenced by ast_network_puts(), ast_network_puts_mutable(), listener(), and netconsole().

00984 {
00985    return write(fd, s, strlen(s));
00986 }

static int fdsend ( int  fd,
const char *  s 
) [static]

Definition at line 977 of file asterisk.c.

Referenced by ast_el_read_char(), ast_remotecontrol(), and cli_complete().

00978 {
00979    return write(fd, s, strlen(s) + 1);
00980 }

static const char* fix_header ( char *  outbuf,
int  maxout,
const char *  s,
char *  cmp 
) [static]

Definition at line 1794 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01795 {
01796    const char *c;
01797 
01798    /* Check for verboser preamble */
01799    if (*s == 127) {
01800       s++;
01801    }
01802 
01803    if (!strncmp(s, cmp, strlen(cmp))) {
01804       c = s + strlen(cmp);
01805       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01806       return c;
01807    }
01808    return NULL;
01809 }

static char* handle_abort_shutdown ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 2038 of file asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cancel_shutdown(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NOT_SHUTTING_DOWN, safe_system_lock, SHUTDOWN_FAST, shuttingdown, and ast_cli_entry::usage.

02039 {
02040    int aborting_shutdown = 0;
02041 
02042    switch (cmd) {
02043    case CLI_INIT:
02044       e->command = "core abort shutdown";
02045       e->usage = 
02046          "Usage: core abort shutdown\n"
02047          "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
02048          "       call operations.\n";
02049       return NULL;
02050    case CLI_GENERATE:
02051       return NULL;
02052    }
02053 
02054    if (a->argc != e->args)
02055       return CLI_SHOWUSAGE;
02056 
02057    ast_mutex_lock(&safe_system_lock);
02058    if (shuttingdown >= SHUTDOWN_FAST) {
02059       aborting_shutdown = 1;
02060       shuttingdown = NOT_SHUTTING_DOWN;
02061    }
02062    ast_mutex_unlock(&safe_system_lock);
02063 
02064    if (aborting_shutdown) {
02065       ast_cancel_shutdown();
02066    }
02067    return CLI_SUCCESS;
02068 }

static char* handle_bang ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 2070 of file asterisk.c.

References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.

02071 {
02072    switch (cmd) {
02073    case CLI_INIT:
02074       e->command = "!";
02075       e->usage = 
02076          "Usage: !<command>\n"
02077          "       Executes a given shell command\n";
02078       return NULL;
02079    case CLI_GENERATE:
02080       return NULL;
02081    }
02082 
02083    return CLI_SUCCESS;
02084 }

static char* handle_clear_profile ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 829 of file asterisk.c.

References CLI_GENERATE, CLI_INIT, DEFINE_PROFILE_MIN_MAX_VALUES, profile_data::e, profile_entry::events, profile_entry::name, prof_data, and profile_entry::value.

00830 {
00831    int i, min, max;
00832    const char *search = NULL;
00833    switch (cmd) {
00834    case CLI_INIT:
00835       e->command = "core clear profile";
00836       e->usage = "Usage: core clear profile\n"
00837             "       clear profile information";
00838       return NULL;
00839    case CLI_GENERATE:
00840       return NULL;
00841    }
00842 
00843    if (prof_data == NULL)
00844       return 0;
00845 
00846    DEFINE_PROFILE_MIN_MAX_VALUES;
00847    for (i= min; i < max; i++) {
00848       if (!search || strstr(prof_data->e[i].name, search)) {
00849          prof_data->e[i].value = 0;
00850          prof_data->e[i].events = 0;
00851       }
00852    }
00853    return CLI_SUCCESS;
00854 }

static char* handle_restart_gracefully ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1998 of file asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, quit_handler(), SHUTDOWN_NICE, and ast_cli_entry::usage.

01999 {
02000    switch (cmd) {
02001    case CLI_INIT:
02002       e->command = "core restart gracefully";
02003       e->usage = 
02004          "Usage: core restart gracefully\n"
02005          "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
02006          "       restart when all active calls have ended.\n";
02007       return NULL;
02008    case CLI_GENERATE:
02009       return NULL;
02010    }
02011 
02012    if (a->argc != e->args)
02013       return CLI_SHOWUSAGE;
02014    quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
02015    return CLI_SUCCESS;
02016 }

static char* handle_restart_now ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1978 of file asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, quit_handler(), SHUTDOWN_NORMAL, and ast_cli_entry::usage.

01979 {
01980    switch (cmd) {
01981    case CLI_INIT:
01982       e->command = "core restart now";
01983       e->usage = 
01984          "Usage: core restart now\n"
01985          "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
01986          "       restart.\n";
01987       return NULL;
01988    case CLI_GENERATE:
01989       return NULL;
01990    }
01991 
01992    if (a->argc != e->args)
01993       return CLI_SHOWUSAGE;
01994    quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
01995    return CLI_SUCCESS;
01996 }

static char* handle_restart_when_convenient ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 2018 of file asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, quit_handler(), SHUTDOWN_REALLY_NICE, and ast_cli_entry::usage.

02019 {
02020    switch (cmd) {
02021    case CLI_INIT:
02022       e->command = "core restart when convenient";
02023       e->usage = 
02024          "Usage: core restart when convenient\n"
02025          "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
02026       return NULL;
02027    case CLI_GENERATE:
02028       return NULL;
02029    }
02030 
02031    if (a->argc != e->args)
02032       return CLI_SHOWUSAGE;
02033    ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
02034    quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
02035    return CLI_SUCCESS;
02036 }

static char* handle_show_profile ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 794 of file asterisk.c.

References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, DEFINE_PROFILE_MIN_MAX_VALUES, profile_data::e, profile_data::entries, ast_cli_args::fd, profile_data::max_size, and prof_data.

00795 {
00796    int i, min, max;
00797    const char *search = NULL;
00798    switch (cmd) {
00799    case CLI_INIT:
00800       e->command = "core show profile";
00801       e->usage = "Usage: core show profile\n"
00802             "       show profile information";
00803       return NULL;
00804    case CLI_GENERATE:
00805       return NULL;
00806    }
00807 
00808    if (prof_data == NULL)
00809       return 0;
00810 
00811    DEFINE_PROFILE_MIN_MAX_VALUES;
00812    ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
00813       prof_data->entries, prof_data->max_size);
00814    ast_cli(a->fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
00815          "Value", "Average", "Name");
00816    for (i = min; i < max; i++) {
00817       struct profile_entry *entry = &prof_data->e[i];
00818       if (!search || strstr(entry->name, search))
00819           ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
00820          i,
00821          (long)entry->scale,
00822          (long)entry->events, (long long)entry->value,
00823          (long long)(entry->events ? entry->value / entry->events : entry->value),
00824          entry->name);
00825    }
00826    return CLI_SUCCESS;
00827 }

static char* handle_show_settings ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Give an overview of core settings.

Todo:
we could check musiconhold, voicemail, smdi, adsi, queues

Definition at line 428 of file asterisk.c.

References ast_active_channels(), ast_build_date, ast_build_kernel, ast_build_machine, ast_build_os, ast_build_user, AST_BUILDOPTS, ast_cli(), ast_config_AST_AGI_DIR, ast_config_AST_CONFIG_DIR, ast_config_AST_CONFIG_FILE, ast_config_AST_DATA_DIR, ast_config_AST_DB, ast_config_AST_KEY_DIR, ast_config_AST_LOG_DIR, ast_config_AST_MODULE_DIR, ast_config_AST_PID, ast_config_AST_RUN_DIR, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SPOOL_DIR, ast_config_AST_SYSTEM_NAME, ast_config_AST_VAR_DIR, ast_eid_default, ast_eid_to_str(), ast_get_version(), ast_language_is_prefix, ast_lastreloadtime, ast_localtime(), AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_GENERIC_PLC, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_options, ast_realtime_enabled(), ast_startuptime, ast_strftime(), ast_test_flag, check_cdr_enabled(), check_manager_enabled(), check_webmanager_enabled(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, defaultlanguage, ast_cli_args::fd, S_OR, and ast_cli_entry::usage.

00429 {
00430    char buf[BUFSIZ];
00431    struct ast_tm tm;
00432    char eid_str[128];
00433 
00434    switch (cmd) {
00435    case CLI_INIT:
00436       e->command = "core show settings";
00437       e->usage = "Usage: core show settings\n"
00438             "       Show core misc settings";
00439       return NULL;
00440    case CLI_GENERATE:
00441       return NULL;
00442    }
00443 
00444    ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
00445 
00446    ast_cli(a->fd, "\nPBX Core settings\n");
00447    ast_cli(a->fd, "-----------------\n");
00448    ast_cli(a->fd, "  Version:                     %s\n", ast_get_version());
00449    ast_cli(a->fd, "  Build Options:               %s\n", S_OR(AST_BUILDOPTS, "(none)"));
00450    if (option_maxcalls)
00451       ast_cli(a->fd, "  Maximum calls:               %d (Current %d)\n", option_maxcalls, ast_active_channels());
00452    else
00453       ast_cli(a->fd, "  Maximum calls:               Not set\n");
00454    if (option_maxfiles)
00455       ast_cli(a->fd, "  Maximum open file handles:   %d\n", option_maxfiles); 
00456    else
00457       ast_cli(a->fd, "  Maximum open file handles:   Not set\n");
00458    ast_cli(a->fd, "  Verbosity:                   %d\n", option_verbose);
00459    ast_cli(a->fd, "  Debug level:                 %d\n", option_debug);
00460    ast_cli(a->fd, "  Maximum load average:        %lf\n", option_maxload);
00461 #if defined(HAVE_SYSINFO)
00462    ast_cli(a->fd, "  Minimum free memory:         %ld MB\n", option_minmemfree);
00463 #endif
00464    if (ast_localtime(&ast_startuptime, &tm, NULL)) {
00465       ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
00466       ast_cli(a->fd, "  Startup time:                %s\n", buf);
00467    }
00468    if (ast_localtime(&ast_lastreloadtime, &tm, NULL)) {
00469       ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
00470       ast_cli(a->fd, "  Last reload time:            %s\n", buf);
00471    }
00472    ast_cli(a->fd, "  System:                      %s/%s built by %s on %s %s\n", ast_build_os, ast_build_kernel, ast_build_user, ast_build_machine, ast_build_date);
00473    ast_cli(a->fd, "  System name:                 %s\n", ast_config_AST_SYSTEM_NAME);
00474    ast_cli(a->fd, "  Entity ID:                   %s\n", eid_str);
00475    ast_cli(a->fd, "  Default language:            %s\n", defaultlanguage);
00476    ast_cli(a->fd, "  Language prefix:             %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
00477    ast_cli(a->fd, "  User name and group:         %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
00478    ast_cli(a->fd, "  Executable includes:         %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
00479    ast_cli(a->fd, "  Transcode via SLIN:          %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
00480    ast_cli(a->fd, "  Internal timing:             %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled");
00481    ast_cli(a->fd, "  Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled");
00482    ast_cli(a->fd, "  Generic PLC:                 %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");
00483 
00484    ast_cli(a->fd, "\n* Subsystems\n");
00485    ast_cli(a->fd, "  -------------\n");
00486    ast_cli(a->fd, "  Manager (AMI):               %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
00487    ast_cli(a->fd, "  Web Manager (AMI/HTTP):      %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled");
00488    ast_cli(a->fd, "  Call data records:           %s\n", check_cdr_enabled() ? "Enabled" : "Disabled");
00489    ast_cli(a->fd, "  Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
00490 
00491    /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues  */
00492 
00493    ast_cli(a->fd, "\n* Directories\n");
00494    ast_cli(a->fd, "  -------------\n");
00495    ast_cli(a->fd, "  Configuration file:          %s\n", ast_config_AST_CONFIG_FILE);
00496    ast_cli(a->fd, "  Configuration directory:     %s\n", ast_config_AST_CONFIG_DIR);
00497    ast_cli(a->fd, "  Module directory:            %s\n", ast_config_AST_MODULE_DIR);
00498    ast_cli(a->fd, "  Spool directory:             %s\n", ast_config_AST_SPOOL_DIR);
00499    ast_cli(a->fd, "  Log directory:               %s\n", ast_config_AST_LOG_DIR);
00500    ast_cli(a->fd, "  Run/Sockets directory:       %s\n", ast_config_AST_RUN_DIR);
00501    ast_cli(a->fd, "  PID file:                    %s\n", ast_config_AST_PID);
00502    ast_cli(a->fd, "  VarLib directory:            %s\n", ast_config_AST_VAR_DIR);
00503    ast_cli(a->fd, "  Data directory:              %s\n", ast_config_AST_DATA_DIR);
00504    ast_cli(a->fd, "  ASTDB:                       %s\n", ast_config_AST_DB);
00505    ast_cli(a->fd, "  IAX2 Keys directory:         %s\n", ast_config_AST_KEY_DIR);
00506    ast_cli(a->fd, "  AGI Scripts directory:       %s\n", ast_config_AST_AGI_DIR);
00507    ast_cli(a->fd, "\n\n");
00508    return CLI_SUCCESS;
00509 }

static char* handle_show_sysinfo ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Give an overview of system statistics.

Definition at line 583 of file asterisk.c.

References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, len(), and ast_cli_entry::usage.

00584 {
00585    uint64_t physmem, freeram;
00586    uint64_t freeswap = 0;
00587    int nprocs = 0;
00588    long uptime = 0;
00589    int totalswap = 0;
00590 #if defined(HAVE_SYSINFO)
00591    struct sysinfo sys_info;
00592    sysinfo(&sys_info);
00593    uptime = sys_info.uptime / 3600;
00594    physmem = sys_info.totalram * sys_info.mem_unit;
00595    freeram = (sys_info.freeram * sys_info.mem_unit) / 1024;
00596    totalswap = (sys_info.totalswap * sys_info.mem_unit) / 1024;
00597    freeswap = (sys_info.freeswap * sys_info.mem_unit) / 1024;
00598    nprocs = sys_info.procs;
00599 #elif defined(HAVE_SYSCTL)
00600    static int pageshift;
00601    struct vmtotal vmtotal;
00602    struct timeval boottime;
00603    time_t   now;
00604    int mib[2], pagesize, usedswap = 0;
00605    size_t len;
00606    /* calculate the uptime by looking at boottime */
00607    time(&now);
00608    mib[0] = CTL_KERN;
00609    mib[1] = KERN_BOOTTIME;
00610    len = sizeof(boottime);
00611    if (sysctl(mib, 2, &boottime, &len, NULL, 0) != -1) {
00612       uptime = now - boottime.tv_sec;
00613    }
00614    uptime = uptime/3600;
00615    /* grab total physical memory  */
00616    mib[0] = CTL_HW;
00617 #if defined(HW_PHYSMEM64)
00618    mib[1] = HW_PHYSMEM64;
00619 #else
00620    mib[1] = HW_PHYSMEM;
00621 #endif
00622    len = sizeof(physmem);
00623    sysctl(mib, 2, &physmem, &len, NULL, 0);
00624 
00625    pagesize = getpagesize();
00626    pageshift = 0;
00627    while (pagesize > 1) {
00628       pageshift++;
00629       pagesize >>= 1;
00630    }
00631 
00632    /* we only need the amount of log(2)1024 for our conversion */
00633    pageshift -= 10;
00634 
00635    /* grab vm totals */
00636    mib[0] = CTL_VM;
00637    mib[1] = VM_METER;
00638    len = sizeof(vmtotal);
00639    sysctl(mib, 2, &vmtotal, &len, NULL, 0);
00640    freeram = (vmtotal.t_free << pageshift);
00641    /* generate swap usage and totals */
00642    swapmode(&usedswap, &totalswap);
00643    freeswap = (totalswap - usedswap);
00644    /* grab number of processes */
00645 #if defined(__OpenBSD__)
00646    mib[0] = CTL_KERN;
00647    mib[1] = KERN_NPROCS;
00648    len = sizeof(nprocs);
00649    sysctl(mib, 2, &nprocs, &len, NULL, 0);
00650 #endif
00651 #endif
00652 
00653    switch (cmd) {
00654    case CLI_INIT:
00655       e->command = "core show sysinfo";
00656       e->usage =
00657          "Usage: core show sysinfo\n"
00658          "       List current system information.\n";
00659       return NULL;
00660    case CLI_GENERATE:
00661       return NULL;
00662    }
00663 
00664    ast_cli(a->fd, "\nSystem Statistics\n");
00665    ast_cli(a->fd, "-----------------\n");
00666    ast_cli(a->fd, "  System Uptime:             %lu hours\n", uptime);
00667    ast_cli(a->fd, "  Total RAM:                 %" PRIu64 " KiB\n", physmem / 1024);
00668    ast_cli(a->fd, "  Free RAM:                  %" PRIu64 " KiB\n", freeram);
00669 #if defined(HAVE_SYSINFO)
00670    ast_cli(a->fd, "  Buffer RAM:                %" PRIu64 " KiB\n", ((uint64_t) sys_info.bufferram * sys_info.mem_unit) / 1024);
00671 #endif
00672 #if defined (HAVE_SYSCTL) || defined(HAVE_SWAPCTL)
00673    ast_cli(a->fd, "  Total Swap Space:          %u KiB\n", totalswap);
00674    ast_cli(a->fd, "  Free Swap Space:           %" PRIu64 " KiB\n\n", freeswap);
00675 #endif
00676    ast_cli(a->fd, "  Number of Processes:       %d \n\n", nprocs);
00677    return CLI_SUCCESS;
00678 }

static char* handle_show_threads ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 511 of file asterisk.c.

References ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, thread_list_t::id, ast_atexit::list, thread_list_t::name, and ast_cli_entry::usage.

00512 {
00513    int count = 0;
00514    struct thread_list_t *cur;
00515    switch (cmd) {
00516    case CLI_INIT:
00517       e->command = "core show threads";
00518       e->usage = 
00519          "Usage: core show threads\n"
00520          "       List threads currently active in the system.\n";
00521       return NULL;
00522    case CLI_GENERATE:
00523       return NULL;
00524    }
00525 
00526    AST_RWLIST_RDLOCK(&thread_list);
00527    AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
00528       ast_cli(a->fd, "%p %s\n", (void *)cur->id, cur->name);
00529       count++;
00530    }
00531         AST_RWLIST_UNLOCK(&thread_list);
00532    ast_cli(a->fd, "%d threads listed.\n", count);
00533    return CLI_SUCCESS;
00534 }

static char* handle_show_version_files ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI command to list module versions.

Definition at line 858 of file asterisk.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, file_version::file, FORMAT, ast_atexit::list, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, file_version::version, and ast_cli_args::word.

00859 {
00860 #define FORMAT "%-25.25s %-40.40s\n"
00861    struct file_version *iterator;
00862    regex_t regexbuf;
00863    int havepattern = 0;
00864    int havename = 0;
00865    int count_files = 0;
00866    char *ret = NULL;
00867    int matchlen, which = 0;
00868    struct file_version *find;
00869 
00870    switch (cmd) {
00871    case CLI_INIT:
00872       e->command = "core show file version [like]";
00873       e->usage = 
00874          "Usage: core show file version [like <pattern>]\n"
00875          "       Lists the revision numbers of the files used to build this copy of Asterisk.\n"
00876          "       Optional regular expression pattern is used to filter the file list.\n";
00877       return NULL;
00878    case CLI_GENERATE:
00879       matchlen = strlen(a->word);
00880       if (a->pos != 3)
00881          return NULL;
00882       AST_RWLIST_RDLOCK(&file_versions);
00883       AST_RWLIST_TRAVERSE(&file_versions, find, list) {
00884          if (!strncasecmp(a->word, find->file, matchlen) && ++which > a->n) {
00885             ret = ast_strdup(find->file);
00886             break;
00887          }
00888       }
00889       AST_RWLIST_UNLOCK(&file_versions);
00890       return ret;
00891    }
00892 
00893 
00894    switch (a->argc) {
00895    case 6:
00896       if (!strcasecmp(a->argv[4], "like")) {
00897          if (regcomp(&regexbuf, a->argv[5], REG_EXTENDED | REG_NOSUB))
00898             return CLI_SHOWUSAGE;
00899          havepattern = 1;
00900       } else
00901          return CLI_SHOWUSAGE;
00902       break;
00903    case 5:
00904       havename = 1;
00905       break;
00906    case 4:
00907       break;
00908    default:
00909       return CLI_SHOWUSAGE;
00910    }
00911 
00912    ast_cli(a->fd, FORMAT, "File", "Revision");
00913    ast_cli(a->fd, FORMAT, "----", "--------");
00914    AST_RWLIST_RDLOCK(&file_versions);
00915    AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
00916       if (havename && strcasecmp(iterator->file, a->argv[4]))
00917          continue;
00918 
00919       if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
00920          continue;
00921 
00922       ast_cli(a->fd, FORMAT, iterator->file, iterator->version);
00923       count_files++;
00924       if (havename)
00925          break;
00926    }
00927    AST_RWLIST_UNLOCK(&file_versions);
00928    if (!havename) {
00929       ast_cli(a->fd, "%d files listed.\n", count_files);
00930    }
00931 
00932    if (havepattern)
00933       regfree(&regexbuf);
00934 
00935    return CLI_SUCCESS;
00936 #undef FORMAT
00937 }

static char* handle_stop_gracefully ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1938 of file asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, quit_handler(), SHUTDOWN_NICE, and ast_cli_entry::usage.

01939 {
01940    switch (cmd) {
01941    case CLI_INIT:
01942       e->command = "core stop gracefully";
01943       e->usage = 
01944          "Usage: core stop gracefully\n"
01945          "       Causes Asterisk to not accept new calls, and exit when all\n"
01946          "       active calls have terminated normally.\n";
01947       return NULL;
01948    case CLI_GENERATE:
01949       return NULL;
01950    }
01951 
01952    if (a->argc != e->args)
01953       return CLI_SHOWUSAGE;
01954    quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
01955    return CLI_SUCCESS;
01956 }

static char* handle_stop_now ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1919 of file asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, quit_handler(), SHUTDOWN_NORMAL, and ast_cli_entry::usage.

01920 {
01921    switch (cmd) {
01922    case CLI_INIT:
01923       e->command = "core stop now";
01924       e->usage = 
01925          "Usage: core stop now\n"
01926          "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
01927       return NULL;
01928    case CLI_GENERATE:
01929       return NULL;
01930    }
01931 
01932    if (a->argc != e->args)
01933       return CLI_SHOWUSAGE;
01934    quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
01935    return CLI_SUCCESS;
01936 }

static char* handle_stop_when_convenient ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1958 of file asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, quit_handler(), SHUTDOWN_REALLY_NICE, and ast_cli_entry::usage.

01959 {
01960    switch (cmd) {
01961    case CLI_INIT:
01962       e->command = "core stop when convenient";
01963       e->usage = 
01964          "Usage: core stop when convenient\n"
01965          "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
01966       return NULL;
01967    case CLI_GENERATE:
01968       return NULL;
01969    }
01970 
01971    if (a->argc != e->args)
01972       return CLI_SHOWUSAGE;
01973    ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
01974    quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
01975    return CLI_SUCCESS;
01976 }

static char* handle_version ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1888 of file asterisk.c.

References ast_cli_args::argc, ast_build_date, ast_build_hostname, ast_build_machine, ast_build_os, ast_build_user, ast_cli(), ast_get_version(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

01889 {
01890    switch (cmd) {
01891    case CLI_INIT:
01892       e->command = "core show version";
01893       e->usage = 
01894          "Usage: core show version\n"
01895          "       Shows Asterisk version information.\n";
01896       return NULL;
01897    case CLI_GENERATE:
01898       return NULL;
01899    }
01900 
01901    if (a->argc != 3)
01902       return CLI_SHOWUSAGE;
01903    ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
01904       ast_get_version(), ast_build_user, ast_build_hostname,
01905       ast_build_machine, ast_build_os, ast_build_date);
01906    return CLI_SUCCESS;
01907 }

static void* listener ( void *  unused  )  [static]

Definition at line 1311 of file asterisk.c.

References AF_LOCAL, ast_log(), AST_MAX_CONNECTS, ast_opt_hide_connect, ast_poll, ast_pthread_create_detached_background, ast_verb, consoles, errno, console::fd, fdprint(), console::gid, len(), LOG_ERROR, LOG_WARNING, console::mute, netconsole(), and console::uid.

Referenced by ast_makesocket().

01312 {
01313    struct sockaddr_un sunaddr;
01314    int s;
01315    socklen_t len;
01316    int x;
01317    int flags;
01318    struct pollfd fds[1];
01319    for (;;) {
01320       if (ast_socket < 0)
01321          return NULL;
01322       fds[0].fd = ast_socket;
01323       fds[0].events = POLLIN;
01324       s = ast_poll(fds, 1, -1);
01325       pthread_testcancel();
01326       if (s < 0) {
01327          if (errno != EINTR)
01328             ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
01329          continue;
01330       }
01331       len = sizeof(sunaddr);
01332       s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
01333       if (s < 0) {
01334          if (errno != EINTR)
01335             ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
01336       } else {
01337 #if !defined(SO_PASSCRED)
01338          {
01339 #else
01340          int sckopt = 1;
01341          /* turn on socket credentials passing. */
01342          if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
01343             ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
01344          } else {
01345 #endif
01346             for (x = 0; x < AST_MAX_CONNECTS; x++) {
01347                if (consoles[x].fd >= 0) {
01348                   continue;
01349                }
01350                if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
01351                   ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
01352                   consoles[x].fd = -1;
01353                   fdprint(s, "Server failed to create pipe\n");
01354                   close(s);
01355                   break;
01356                }
01357                flags = fcntl(consoles[x].p[1], F_GETFL);
01358                fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
01359                consoles[x].fd = s;
01360                consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
01361                /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
01362                   to know if the user didn't send the credentials. */
01363                consoles[x].uid = -2;
01364                consoles[x].gid = -2;
01365                if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
01366                   ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
01367                   close(consoles[x].p[0]);
01368                   close(consoles[x].p[1]);
01369                   consoles[x].fd = -1;
01370                   fdprint(s, "Server failed to spawn thread\n");
01371                   close(s);
01372                }
01373                break;
01374             }
01375             if (x >= AST_MAX_CONNECTS) {
01376                fdprint(s, "No more connections allowed\n");
01377                ast_log(LOG_WARNING, "No more connections allowed\n");
01378                close(s);
01379             } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
01380                ast_verb(3, "Remote UNIX connection\n");
01381             }
01382          }
01383       }
01384    }
01385    return NULL;
01386 }

int main ( int  argc,
char *  argv[] 
)

Definition at line 3254 of file asterisk.c.

References __ast_mm_init(), __quit_handler(), _argv, ARRAY_LEN, ast_alaw_init(), ast_aoc_cli_init(), ast_autoservice_init(), ast_builtins_init(), ast_cc_init(), ast_cdr_engine_init(), ast_cel_engine_init(), ast_channels_init(), ast_clear_flag, ast_cli_perms_init(), ast_cli_register_multiple(), ast_close_fds_above_n(), ast_config_AST_PID, ast_config_AST_RUN_DIR, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SOCKET, ast_copy_string(), ast_data_init(), ast_device_state_engine_init(), ast_dsp_init(), ast_el_initialize(), ast_el_read_char(), ast_el_read_history(), ast_enum_init(), ast_event_init(), ast_fd_init(), ast_FD_SETSIZE, ast_FDMAX, ast_features_init(), ast_file_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_language_is_prefix, ast_lastreloadtime, ast_log(), ast_makesocket(), ast_opt_always_fork, ast_opt_console, ast_opt_dump_core, ast_opt_exec, AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC, AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND, AST_OPT_FLAG_FULLY_BOOTED, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_LIGHT_BACKGROUND, AST_OPT_FLAG_MUTE, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_OVERRIDE_CONFIG, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_RECONNECT, AST_OPT_FLAG_REMOTE, AST_OPT_FLAG_TIMESTAMP, ast_opt_high_priority, ast_opt_no_fork, ast_opt_remote, ast_options, ast_pbx_init(), ast_process_pending_reloads(), ast_pthread_create_detached, ast_readconfig(), ast_register_atexit(), ast_register_verbose(), ast_remotecontrol(), ast_select(), ast_set_flag, ast_set_priority(), ast_ssl_init(), ast_startuptime, ast_strdupa, ast_strlen_zero(), ast_stun_init(), ast_term_init(), ast_test_flag, ast_test_init(), ast_timing_init(), ast_tps_init(), ast_tryconnect(), ast_tvnow(), ast_udptl_init(), ast_ulaw_init(), ast_utils_init(), ast_verbose, ast_xmldoc_load_documentation(), astdb_init(), astobj2_init(), callerid_init(), canary_exit(), canary_filename, canary_pid, canary_thread(), cfg_paths, cli_asterisk, COLOR_BLACK, COLOR_BRWHITE, _cfg_paths::config_file, console_verboser(), consolehandler(), consolethread, dnsmgr_init(), dnsmgr_start_refresh(), el, el_hist, env_init(), errno, EVENT_FLAG_SYSTEM, f, FD_SET, FD_ZERO, init_framer(), init_logger(), init_manager(), load_modules(), load_pbx(), LOG_ERROR, LOG_WARNING, manager_event, MAXHOSTNAMELEN, mon_sig_flags, monitor_sig_flags(), quit_handler(), randompool, read_config_maps(), register_config_cli(), run_startup_commands(), set_icon(), set_title(), show_cli_help(), show_version(), SHUTDOWN_FAST, sig_alert_pipe, sig_flags, _cfg_paths::socket_path, tdd_init(), term_color(), term_end(), term_quit(), threadstorage_init(), and WELCOME_MESSAGE.

03255 {
03256    int c;
03257    char filename[80] = "";
03258    char hostname[MAXHOSTNAMELEN] = "";
03259    char tmp[80];
03260    char * xarg = NULL;
03261    int x;
03262    FILE *f;
03263    sigset_t sigs;
03264    int num;
03265    int isroot = 1, rundir_exists = 0;
03266    char *buf;
03267    const char *runuser = NULL, *rungroup = NULL;
03268    char *remotesock = NULL;
03269    int moduleresult;         /*!< Result from the module load subsystem */
03270    struct rlimit l;
03271 
03272    /* Remember original args for restart */
03273    if (argc > ARRAY_LEN(_argv) - 1) {
03274       fprintf(stderr, "Truncating argument size to %d\n", (int)ARRAY_LEN(_argv) - 1);
03275       argc = ARRAY_LEN(_argv) - 1;
03276    }
03277    for (x = 0; x < argc; x++)
03278       _argv[x] = argv[x];
03279    _argv[x] = NULL;
03280 
03281    if (geteuid() != 0)
03282       isroot = 0;
03283 
03284    /* if the progname is rasterisk consider it a remote console */
03285    if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
03286       ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03287    }
03288    if (gethostname(hostname, sizeof(hostname)-1))
03289       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
03290    ast_mainpid = getpid();
03291    ast_ulaw_init();
03292    ast_alaw_init();
03293    callerid_init();
03294    ast_builtins_init();
03295    ast_utils_init();
03296    tdd_init();
03297    ast_tps_init();
03298    ast_fd_init();
03299    ast_pbx_init();
03300 
03301    if (getenv("HOME")) 
03302       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
03303    /* Check for options */
03304    while ((c = getopt(argc, argv, "BC:cde:FfG:ghIiL:M:mnpqRrs:TtU:VvWXx:")) != -1) {
03305       /*!\note Please keep the ordering here to alphabetical, capital letters
03306        * first.  This will make it easier in the future to select unused
03307        * option flags for new features. */
03308       switch (c) {
03309       case 'B': /* Force black background */
03310          ast_set_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03311          ast_clear_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
03312          break;
03313       case 'X':
03314          ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES);
03315          break;
03316       case 'C':
03317          ast_copy_string(cfg_paths.config_file, optarg, sizeof(cfg_paths.config_file));
03318          ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
03319          break;
03320       case 'c':
03321          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
03322          break;
03323       case 'd':
03324          option_debug++;
03325          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03326          break;
03327 #if defined(HAVE_SYSINFO)
03328       case 'e':
03329          if ((sscanf(&optarg[1], "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
03330             option_minmemfree = 0;
03331          }
03332          break;
03333 #endif
03334 #if HAVE_WORKING_FORK
03335       case 'F':
03336          ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
03337          break;
03338       case 'f':
03339          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03340          break;
03341 #endif
03342       case 'G':
03343          rungroup = ast_strdupa(optarg);
03344          break;
03345       case 'g':
03346          ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
03347          break;
03348       case 'h':
03349          show_cli_help();
03350          exit(0);
03351       case 'I':
03352          ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING);
03353          break;
03354       case 'i':
03355          ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
03356          break;
03357       case 'L':
03358          if ((sscanf(optarg, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
03359             option_maxload = 0.0;
03360          }
03361          break;
03362       case 'M':
03363          if ((sscanf(optarg, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
03364             option_maxcalls = 0;
03365          }
03366          break;
03367       case 'm':
03368          ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
03369          break;
03370       case 'n':
03371          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
03372          break;
03373       case 'p':
03374          ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
03375          break;
03376       case 'q':
03377          ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
03378          break;
03379       case 'R':
03380          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
03381          break;
03382       case 'r':
03383          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03384          break;
03385       case 's':
03386          remotesock = ast_strdupa(optarg);
03387          break;
03388       case 'T':
03389          ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
03390          break;
03391       case 't':
03392          ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
03393          break;
03394       case 'U':
03395          runuser = ast_strdupa(optarg);
03396          break;
03397       case 'V':
03398          show_version();
03399          exit(0);
03400       case 'v':
03401          option_verbose++;
03402          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03403          break;
03404       case 'W': /* White background */
03405          ast_set_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
03406          ast_clear_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03407          break;
03408       case 'x':
03409          /* -r is implied by -x so set the flags -r sets as well. */
03410          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03411 
03412          ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC | AST_OPT_FLAG_NO_COLOR);
03413          xarg = ast_strdupa(optarg);
03414          break;
03415       case '?':
03416          exit(1);
03417       }
03418    }
03419 
03420    if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
03421       if (ast_register_verbose(console_verboser)) {
03422          ast_log(LOG_WARNING, "Unable to register console verboser?\n");
03423       }
03424       WELCOME_MESSAGE;
03425    }
03426 
03427    if (ast_opt_console && !option_verbose) 
03428       ast_verbose("[ Booting...\n");
03429 
03430    /* For remote connections, change the name of the remote connection.
03431     * We do this for the benefit of init scripts (which need to know if/when
03432     * the main asterisk process has died yet). */
03433    if (ast_opt_remote) {
03434       strcpy(argv[0], "rasterisk");
03435       for (x = 1; x < argc; x++) {
03436          argv[x] = argv[0] + 10;
03437       }
03438    }
03439 
03440    if (ast_opt_console && !option_verbose) {
03441       ast_verbose("[ Reading Master Configuration ]\n");
03442    }
03443 
03444    ast_readconfig();
03445    env_init();
03446 
03447    if (ast_opt_remote && remotesock != NULL)
03448       ast_copy_string((char *) cfg_paths.socket_path, remotesock, sizeof(cfg_paths.socket_path));
03449 
03450    if (!ast_language_is_prefix && !ast_opt_remote)
03451       ast_log(LOG_WARNING, "The 'languageprefix' option in asterisk.conf is deprecated; in a future release it will be removed, and your sound files will need to be organized in the 'new style' language layout.\n");
03452 
03453    if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
03454       ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
03455       ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
03456    }
03457 
03458    if (ast_opt_dump_core) {
03459       memset(&l, 0, sizeof(l));
03460       l.rlim_cur = RLIM_INFINITY;
03461       l.rlim_max = RLIM_INFINITY;
03462       if (setrlimit(RLIMIT_CORE, &l)) {
03463          ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
03464       }
03465    }
03466 
03467    if (getrlimit(RLIMIT_NOFILE, &l)) {
03468       ast_log(LOG_WARNING, "Unable to check file descriptor limit: %s\n", strerror(errno));
03469    }
03470 
03471 #if !defined(CONFIGURE_RAN_AS_ROOT)
03472    /* Check if select(2) will run with more file descriptors */
03473    do {
03474       int fd, fd2;
03475       ast_fdset readers;
03476       struct timeval tv = { 0, };
03477 
03478       if (l.rlim_cur <= FD_SETSIZE) {
03479          /* The limit of select()able FDs is irrelevant, because we'll never
03480           * open one that high. */
03481          break;
03482       }
03483 
03484       if (!(fd = open("/dev/null", O_RDONLY))) {
03485          ast_log(LOG_ERROR, "Cannot open a file descriptor at boot? %s\n", strerror(errno));
03486          break; /* XXX Should we exit() here? XXX */
03487       }
03488 
03489       fd2 = (l.rlim_cur > sizeof(readers) * 8 ? sizeof(readers) * 8 : l.rlim_cur) - 1;
03490       if (dup2(fd, fd2) < 0) {
03491          ast_log(LOG_WARNING, "Cannot open maximum file descriptor %d at boot? %s\n", fd2, strerror(errno));
03492          close(fd);
03493          break;
03494       }
03495 
03496       FD_ZERO(&readers);
03497       FD_SET(fd2, &readers);
03498       if (ast_select(fd2 + 1, &readers, NULL, NULL, &tv) < 0) {
03499          ast_log(LOG_WARNING, "Maximum select()able file descriptor is %d\n", FD_SETSIZE);
03500       }
03501       ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
03502       close(fd);
03503       close(fd2);
03504    } while (0);
03505 #elif defined(HAVE_VARIABLE_FDSET)
03506    ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
03507 #endif /* !defined(CONFIGURE_RAN_AS_ROOT) */
03508 
03509    if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
03510       rungroup = ast_config_AST_RUN_GROUP;
03511    if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
03512       runuser = ast_config_AST_RUN_USER;
03513 
03514    /* Must install this signal handler up here to ensure that if the canary
03515     * fails to execute that it doesn't kill the Asterisk process.
03516     */
03517    sigaction(SIGCHLD, &child_handler, NULL);
03518 
03519    /* It's common on some platforms to clear /var/run at boot.  Create the
03520     * socket file directory before we drop privileges. */
03521    if (mkdir(ast_config_AST_RUN_DIR, 0755)) {
03522       if (errno == EEXIST) {
03523          rundir_exists = 1;
03524       } else {
03525          ast_log(LOG_WARNING, "Unable to create socket file directory.  Remote consoles will not be able to connect! (%s)\n", strerror(x));
03526       }
03527    }
03528 
03529 #ifndef __CYGWIN__
03530 
03531    if (isroot) {
03532       ast_set_priority(ast_opt_high_priority);
03533    }
03534 
03535    if (isroot && rungroup) {
03536       struct group *gr;
03537       gr = getgrnam(rungroup);
03538       if (!gr) {
03539          ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
03540          exit(1);
03541       }
03542       if (!rundir_exists && chown(ast_config_AST_RUN_DIR, -1, gr->gr_gid)) {
03543          ast_log(LOG_WARNING, "Unable to chgrp run directory to %d (%s)\n", (int) gr->gr_gid, rungroup);
03544       }
03545       if (setgid(gr->gr_gid)) {
03546          ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
03547          exit(1);
03548       }
03549       if (setgroups(0, NULL)) {
03550          ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
03551          exit(1);
03552       }
03553       if (option_verbose)
03554          ast_verbose("Running as group '%s'\n", rungroup);
03555    }
03556 
03557    if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
03558 #ifdef HAVE_CAP
03559       int has_cap = 1;
03560 #endif /* HAVE_CAP */
03561       struct passwd *pw;
03562       pw = getpwnam(runuser);
03563       if (!pw) {
03564          ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
03565          exit(1);
03566       }
03567       if (chown(ast_config_AST_RUN_DIR, pw->pw_uid, -1)) {
03568          ast_log(LOG_WARNING, "Unable to chown run directory to %d (%s)\n", (int) pw->pw_uid, runuser);
03569       }
03570 #ifdef HAVE_CAP
03571       if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
03572          ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
03573          has_cap = 0;
03574       }
03575 #endif /* HAVE_CAP */
03576       if (!isroot && pw->pw_uid != geteuid()) {
03577          ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
03578          exit(1);
03579       }
03580       if (!rungroup) {
03581          if (setgid(pw->pw_gid)) {
03582             ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
03583             exit(1);
03584          }
03585          if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
03586             ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser);
03587             exit(1);
03588          }
03589       }
03590       if (setuid(pw->pw_uid)) {
03591          ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
03592          exit(1);
03593       }
03594       if (option_verbose)
03595          ast_verbose("Running as user '%s'\n", runuser);
03596 #ifdef HAVE_CAP
03597       if (has_cap) {
03598          cap_t cap;
03599 
03600          cap = cap_from_text("cap_net_admin=eip");
03601 
03602          if (cap_set_proc(cap))
03603             ast_log(LOG_WARNING, "Unable to install capabilities.\n");
03604 
03605          if (cap_free(cap))
03606             ast_log(LOG_WARNING, "Unable to drop capabilities.\n");
03607       }
03608 #endif /* HAVE_CAP */
03609    }
03610 
03611 #endif /* __CYGWIN__ */
03612 
03613 #ifdef linux
03614    if (geteuid() && ast_opt_dump_core) {
03615       if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
03616          ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
03617       }
03618    }
03619 #endif
03620 
03621    {
03622 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
03623 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
03624 #define eaccess euidaccess
03625 #endif
03626       char dir[PATH_MAX];
03627       if (!getcwd(dir, sizeof(dir)) || eaccess(dir, R_OK | X_OK | F_OK)) {
03628          ast_log(LOG_ERROR, "Unable to access the running directory (%s).  Changing to '/' for compatibility.\n", strerror(errno));
03629          /* If we cannot access the CWD, then we couldn't dump core anyway,
03630           * so chdir("/") won't break anything. */
03631          if (chdir("/")) {
03632             /* chdir(/) should never fail, so this ends up being a no-op */
03633             ast_log(LOG_ERROR, "chdir(\"/\") failed?!! %s\n", strerror(errno));
03634          }
03635       } else
03636 #endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */
03637       if (!ast_opt_no_fork && !ast_opt_dump_core) {
03638          /* Backgrounding, but no cores, so chdir won't break anything. */
03639          if (chdir("/")) {
03640             ast_log(LOG_ERROR, "Unable to chdir(\"/\") ?!! %s\n", strerror(errno));
03641          }
03642       }
03643    }
03644 
03645    ast_term_init();
03646    printf("%s", term_end());
03647    fflush(stdout);
03648 
03649    if (ast_opt_console && !option_verbose) 
03650       ast_verbose("[ Initializing Custom Configuration Options ]\n");
03651    /* custom config setup */
03652    register_config_cli();
03653    read_config_maps();
03654    
03655    if (ast_opt_console) {
03656       if (el_hist == NULL || el == NULL)
03657          ast_el_initialize();
03658 
03659       if (!ast_strlen_zero(filename))
03660          ast_el_read_history(filename);
03661    }
03662 
03663    if (ast_tryconnect()) {
03664       /* One is already running */
03665       if (ast_opt_remote) {
03666          if (ast_opt_exec) {
03667             ast_remotecontrol(xarg);
03668             quit_handler(0, SHUTDOWN_FAST, 0);
03669             exit(0);
03670          }
03671          printf("%s", term_quit());
03672          ast_remotecontrol(NULL);
03673          quit_handler(0, SHUTDOWN_FAST, 0);
03674          exit(0);
03675       } else {
03676          ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
03677          printf("%s", term_quit());
03678          exit(1);
03679       }
03680    } else if (ast_opt_remote || ast_opt_exec) {
03681       ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
03682       printf("%s", term_quit());
03683       exit(1);
03684    }
03685    /* Blindly write pid file since we couldn't connect */
03686    unlink(ast_config_AST_PID);
03687    f = fopen(ast_config_AST_PID, "w");
03688    if (f) {
03689       fprintf(f, "%ld\n", (long)getpid());
03690       fclose(f);
03691    } else
03692       ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
03693 
03694 #if HAVE_WORKING_FORK
03695    if (ast_opt_always_fork || !ast_opt_no_fork) {
03696 #ifndef HAVE_SBIN_LAUNCHD
03697       if (daemon(1, 0) < 0) {
03698          ast_log(LOG_ERROR, "daemon() failed: %s\n", strerror(errno));
03699       }
03700       ast_mainpid = getpid();
03701       /* Blindly re-write pid file since we are forking */
03702       unlink(ast_config_AST_PID);
03703       f = fopen(ast_config_AST_PID, "w");
03704       if (f) {
03705          fprintf(f, "%ld\n", (long)ast_mainpid);
03706          fclose(f);
03707       } else
03708          ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
03709 #else
03710       ast_log(LOG_WARNING, "Mac OS X detected.  Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
03711 #endif
03712    }
03713 #endif
03714 
03715    /* Spawning of astcanary must happen AFTER the call to daemon(3) */
03716    if (isroot && ast_opt_high_priority) {
03717       snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
03718 
03719       /* Don't let the canary child kill Asterisk, if it dies immediately */
03720       sigaction(SIGPIPE, &ignore_sig_handler, NULL);
03721 
03722       canary_pid = fork();
03723       if (canary_pid == 0) {
03724          char canary_binary[128], *lastslash, ppid[12];
03725 
03726          /* Reset signal handler */
03727          signal(SIGCHLD, SIG_DFL);
03728          signal(SIGPIPE, SIG_DFL);
03729 
03730          ast_close_fds_above_n(0);
03731          ast_set_priority(0);
03732          snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid);
03733 
03734          execlp("astcanary", "astcanary", canary_filename, ppid, (char *)NULL);
03735 
03736          /* If not found, try the same path as used to execute asterisk */
03737          ast_copy_string(canary_binary, argv[0], sizeof(canary_binary));
03738          if ((lastslash = strrchr(canary_binary, '/'))) {
03739             ast_copy_string(lastslash + 1, "astcanary", sizeof(canary_binary) + canary_binary - (lastslash + 1));
03740             execl(canary_binary, "astcanary", canary_filename, ppid, (char *)NULL);
03741          }
03742 
03743          /* Should never happen */
03744          _exit(1);
03745       } else if (canary_pid > 0) {
03746          pthread_t dont_care;
03747          ast_pthread_create_detached(&dont_care, NULL, canary_thread, NULL);
03748       }
03749 
03750       /* Kill the canary when we exit */
03751       ast_register_atexit(canary_exit);
03752    }
03753 
03754    if (ast_event_init()) {
03755       printf("%s", term_quit());
03756       exit(1);
03757    }
03758 
03759 #ifdef TEST_FRAMEWORK
03760    if (ast_test_init()) {
03761       printf("%s", term_quit());
03762       exit(1);
03763    }
03764 #endif
03765 
03766    ast_aoc_cli_init();
03767 
03768    ast_makesocket();
03769    sigemptyset(&sigs);
03770    sigaddset(&sigs, SIGHUP);
03771    sigaddset(&sigs, SIGTERM);
03772    sigaddset(&sigs, SIGINT);
03773    sigaddset(&sigs, SIGPIPE);
03774    sigaddset(&sigs, SIGWINCH);
03775    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
03776    sigaction(SIGURG, &urg_handler, NULL);
03777    signal(SIGINT, __quit_handler);
03778    signal(SIGTERM, __quit_handler);
03779    sigaction(SIGHUP, &hup_handler, NULL);
03780    sigaction(SIGPIPE, &ignore_sig_handler, NULL);
03781 
03782    /* ensure that the random number generators are seeded with a different value every time
03783       Asterisk is started
03784    */
03785    srand((unsigned int) getpid() + (unsigned int) time(NULL));
03786    initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
03787 
03788    if (init_logger()) {    /* Start logging subsystem */
03789       printf("%s", term_quit());
03790       exit(1);
03791    }
03792 
03793    threadstorage_init();
03794 
03795    astobj2_init();
03796 
03797    ast_autoservice_init();
03798 
03799    if (ast_timing_init()) {
03800       printf("%s", term_quit());
03801       exit(1);
03802    }
03803 
03804    if (ast_ssl_init()) {
03805       printf("%s", term_quit());
03806       exit(1);
03807    }
03808 
03809 #ifdef AST_XML_DOCS
03810    /* Load XML documentation. */
03811    ast_xmldoc_load_documentation();
03812 #endif
03813 
03814    /* initialize the data retrieval API */
03815    if (ast_data_init()) {
03816       printf ("%s", term_quit());
03817       exit(1);
03818    }
03819 
03820    ast_channels_init();
03821 
03822    if ((moduleresult = load_modules(1))) {      /* Load modules, pre-load only */
03823       printf("%s", term_quit());
03824       exit(moduleresult == -2 ? 2 : 1);
03825    }
03826 
03827    if (dnsmgr_init()) {    /* Initialize the DNS manager */
03828       printf("%s", term_quit());
03829       exit(1);
03830    }
03831 
03832    ast_http_init();     /* Start the HTTP server, if needed */
03833 
03834    if (init_manager()) {
03835       printf("%s", term_quit());
03836       exit(1);
03837    }
03838 
03839    if (ast_cdr_engine_init()) {
03840       printf("%s", term_quit());
03841       exit(1);
03842    }
03843 
03844    if (ast_cel_engine_init()) {
03845       printf("%s", term_quit());
03846       exit(1);
03847    }
03848 
03849    if (ast_device_state_engine_init()) {
03850       printf("%s", term_quit());
03851       exit(1);
03852    }
03853 
03854    ast_dsp_init();
03855    ast_udptl_init();
03856 
03857    if (ast_image_init()) {
03858       printf("%s", term_quit());
03859       exit(1);
03860    }
03861 
03862    if (ast_file_init()) {
03863       printf("%s", term_quit());
03864       exit(1);
03865    }
03866 
03867    if (load_pbx()) {
03868       printf("%s", term_quit());
03869       exit(1);
03870    }
03871 
03872    if (ast_indications_init()) {
03873       printf("%s", term_quit());
03874       exit(1);
03875    }
03876 
03877    if (ast_features_init()) {
03878       printf("%s", term_quit());
03879       exit(1);
03880    }
03881 
03882    if (init_framer()) {
03883       printf("%s", term_quit());
03884       exit(1);
03885    }
03886 
03887    if (astdb_init()) {
03888       printf("%s", term_quit());
03889       exit(1);
03890    }
03891 
03892    if (ast_enum_init()) {
03893       printf("%s", term_quit());
03894       exit(1);
03895    }
03896 
03897    if (ast_cc_init()) {
03898       printf("%s", term_quit());
03899       exit(1);
03900    }
03901 
03902    if ((moduleresult = load_modules(0))) {      /* Load modules */
03903       printf("%s", term_quit());
03904       exit(moduleresult == -2 ? 2 : 1);
03905    }
03906 
03907    /* loads the cli_permissoins.conf file needed to implement cli restrictions. */
03908    ast_cli_perms_init(0);
03909 
03910    ast_stun_init();
03911 
03912    dnsmgr_start_refresh();
03913 
03914    /* We might have the option of showing a console, but for now just
03915       do nothing... */
03916    if (ast_opt_console && !option_verbose)
03917       ast_verbose(" ]\n");
03918    if (option_verbose || ast_opt_console)
03919       ast_verbose("%s", term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
03920    if (ast_opt_no_fork)
03921       consolethread = pthread_self();
03922 
03923    if (pipe(sig_alert_pipe))
03924       sig_alert_pipe[0] = sig_alert_pipe[1] = -1;
03925 
03926    ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
03927    manager_event(EVENT_FLAG_SYSTEM, "FullyBooted", "Status: Fully Booted\r\n");
03928 
03929    ast_process_pending_reloads();
03930 
03931    pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
03932 
03933 #ifdef __AST_DEBUG_MALLOC
03934    __ast_mm_init();
03935 #endif   
03936 
03937    ast_lastreloadtime = ast_startuptime = ast_tvnow();
03938    ast_cli_register_multiple(cli_asterisk, ARRAY_LEN(cli_asterisk));
03939 
03940    run_startup_commands();
03941 
03942    if (ast_opt_console) {
03943       /* Console stuff now... */
03944       /* Register our quit function */
03945       char title[256];
03946 
03947       ast_pthread_create_detached(&mon_sig_flags, NULL, monitor_sig_flags, NULL);
03948 
03949       set_icon("Asterisk");
03950       snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
03951       set_title(title);
03952 
03953       el_set(el, EL_GETCFN, ast_el_read_char);
03954 
03955       for (;;) {
03956          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
03957             quit_handler(0, SHUTDOWN_FAST, 0);
03958             break;
03959          }
03960          buf = (char *) el_gets(el, &num);
03961 
03962          if (!buf && write(1, "", 1) < 0)
03963             goto lostterm;
03964 
03965          if (buf) {
03966             if (buf[strlen(buf)-1] == '\n')
03967                buf[strlen(buf)-1] = '\0';
03968 
03969             consolehandler((char *)buf);
03970          } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
03971                strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) {
03972             /* Whoa, stdout disappeared from under us... Make /dev/null's */
03973             int fd;
03974             fd = open("/dev/null", O_RDWR);
03975             if (fd > -1) {
03976                dup2(fd, STDOUT_FILENO);
03977                dup2(fd, STDIN_FILENO);
03978             } else
03979                ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
03980             break;
03981          }
03982       }
03983    }
03984 
03985    monitor_sig_flags(NULL);
03986 
03987 lostterm:
03988    return 0;
03989 }

static void* monitor_sig_flags ( void *  unused  )  [static]

Definition at line 3152 of file asterisk.c.

References ast_module_reload(), ast_poll, AST_PTHREADT_NULL, consolethread, quit_handler(), SHUTDOWN_NORMAL, sig_alert_pipe, and sig_flags.

Referenced by main().

03153 {
03154    for (;;) {
03155       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
03156       int a;
03157       ast_poll(&p, 1, -1);
03158       if (sig_flags.need_reload) {
03159          sig_flags.need_reload = 0;
03160          ast_module_reload(NULL);
03161       }
03162       if (sig_flags.need_quit) {
03163          sig_flags.need_quit = 0;
03164          if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
03165             sig_flags.need_quit_handler = 1;
03166             pthread_kill(consolethread, SIGURG);
03167          } else {
03168             quit_handler(0, SHUTDOWN_NORMAL, 0);
03169          }
03170       }
03171       if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
03172       }
03173    }
03174 
03175    return NULL;
03176 }

static void* netconsole ( void *  vconsole  )  [static]

Definition at line 1251 of file asterisk.c.

References ast_cli_command_multiple_full(), ast_copy_string(), ast_get_version(), ast_log(), ast_opt_hide_connect, ast_poll, ast_verb, errno, console::fd, fdprint(), console::gid, hostname, LOG_ERROR, LOG_WARNING, MAXHOSTNAMELEN, console::p, read_credentials(), and console::uid.

Referenced by listener().

01252 {
01253    struct console *con = vconsole;
01254    char hostname[MAXHOSTNAMELEN] = "";
01255    char tmp[512];
01256    int res;
01257    struct pollfd fds[2];
01258    
01259    if (gethostname(hostname, sizeof(hostname)-1))
01260       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
01261    snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
01262    fdprint(con->fd, tmp);
01263    for (;;) {
01264       fds[0].fd = con->fd;
01265       fds[0].events = POLLIN;
01266       fds[0].revents = 0;
01267       fds[1].fd = con->p[0];
01268       fds[1].events = POLLIN;
01269       fds[1].revents = 0;
01270 
01271       res = ast_poll(fds, 2, -1);
01272       if (res < 0) {
01273          if (errno != EINTR)
01274             ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
01275          continue;
01276       }
01277       if (fds[0].revents) {
01278          res = read_credentials(con->fd, tmp, sizeof(tmp) - 1, con);
01279          if (res < 1) {
01280             break;
01281          }
01282          tmp[res] = 0;
01283          if (strncmp(tmp, "cli quit after ", 15) == 0) {
01284             ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res - 15, tmp + 15);
01285             break;
01286          }
01287          ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res, tmp);
01288       }
01289       if (fds[1].revents) {
01290          res = read_credentials(con->p[0], tmp, sizeof(tmp), con);
01291          if (res < 1) {
01292             ast_log(LOG_ERROR, "read returned %d\n", res);
01293             break;
01294          }
01295          res = write(con->fd, tmp, res);
01296          if (res < 1)
01297             break;
01298       }
01299    }
01300    if (!ast_opt_hide_connect) {
01301       ast_verb(3, "Remote UNIX connection disconnected\n");
01302    }
01303    close(con->fd);
01304    close(con->p[0]);
01305    close(con->p[1]);
01306    con->fd = -1;
01307    
01308    return NULL;
01309 }

static void network_verboser ( const char *  s  )  [static]

Definition at line 1185 of file asterisk.c.

References __LOG_VERBOSE, and ast_network_puts_mutable().

Referenced by ast_makesocket().

01186 {
01187    ast_network_puts_mutable(s, __LOG_VERBOSE);
01188 }

static void quit_handler ( int  num,
shutdown_nice_t  niceness,
int  restart 
) [static]

Definition at line 1622 of file asterisk.c.

References can_safely_quit(), and really_quit().

Referenced by ast_el_read_char(), handle_restart_gracefully(), handle_restart_now(), handle_restart_when_convenient(), handle_stop_gracefully(), handle_stop_now(), handle_stop_when_convenient(), main(), monitor_sig_flags(), and remoteconsolehandler().

01623 {
01624    if (can_safely_quit(niceness, restart)) {
01625       really_quit(num, niceness, restart);
01626       /* No one gets here. */
01627    }
01628    /* It wasn't our time. */
01629 }

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 759 of file asterisk.c.

Referenced by ast_mark().

00760 {
00761    return 0;
00762 }

static int read_credentials ( int  fd,
char *  buffer,
size_t  size,
struct console con 
) [static]

read() function supporting the reception of user credentials.

Parameters:
fd Socket file descriptor.
buffer Receive buffer.
size 'buffer' size.
con Console structure to set received credentials
Return values:
-1 on error
the number of bytes received on success.

Definition at line 1202 of file asterisk.c.

References console::gid, len(), and console::uid.

Referenced by netconsole().

01203 {
01204 #if defined(SO_PEERCRED)
01205 #ifdef HAVE_STRUCT_SOCKPEERCRED_UID
01206 #define HAVE_STRUCT_UCRED_UID
01207    struct sockpeercred cred;
01208 #else
01209    struct ucred cred;
01210 #endif
01211    socklen_t len = sizeof(cred);
01212 #endif
01213 #if defined(HAVE_GETPEEREID)
01214    uid_t uid;
01215    gid_t gid;
01216 #else
01217    int uid, gid;
01218 #endif
01219    int result;
01220 
01221    result = read(fd, buffer, size);
01222    if (result < 0) {
01223       return result;
01224    }
01225 
01226 #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
01227    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
01228       return result;
01229    }
01230 #if defined(HAVE_STRUCT_UCRED_UID)
01231    uid = cred.uid;
01232    gid = cred.gid;
01233 #else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
01234    uid = cred.cr_uid;
01235    gid = cred.cr_gid;
01236 #endif /* defined(HAVE_STRUCT_UCRED_UID) */
01237 
01238 #elif defined(HAVE_GETPEEREID)
01239    if (getpeereid(fd, &uid, &gid)) {
01240       return result;
01241    }
01242 #else
01243    return result;
01244 #endif
01245    con->uid = uid;
01246    con->gid = gid;
01247 
01248    return result;
01249 }

static void really_quit ( int  num,
shutdown_nice_t  niceness,
int  restart 
) [static]

Definition at line 1697 of file asterisk.c.

References _argv, ast_active_channels(), ast_config_AST_PID, ast_config_AST_SOCKET, ast_debug, ast_el_write_history(), ast_module_shutdown(), ast_opt_console, ast_opt_exec, ast_opt_remote, AST_PTHREADT_NULL, ast_run_atexits(), ast_strlen_zero(), ast_verbose, close_logger(), consolethread, el, el_hist, EVENT_FLAG_SYSTEM, lthread, manager_event, mon_sig_flags, restartnow, SHUTDOWN_NICE, and term_quit().

Referenced by quit_handler().

01698 {
01699    if (niceness >= SHUTDOWN_NICE) {
01700       ast_module_shutdown();
01701    }
01702 
01703    if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
01704       char filename[80] = "";
01705       if (getenv("HOME")) {
01706          snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
01707       }
01708       if (!ast_strlen_zero(filename)) {
01709          ast_el_write_history(filename);
01710       }
01711       if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
01712          /* Only end if we are the consolethread, otherwise there's a race with that thread. */
01713          if (el != NULL) {
01714             el_end(el);
01715          }
01716          if (el_hist != NULL) {
01717             history_end(el_hist);
01718          }
01719       } else if (mon_sig_flags == pthread_self()) {
01720          if (consolethread != AST_PTHREADT_NULL) {
01721             pthread_kill(consolethread, SIGURG);
01722          }
01723       }
01724    }
01725    if (option_verbose)
01726       ast_verbose("Executing last minute cleanups\n");
01727    ast_run_atexits();
01728    /* Called on exit */
01729    if (option_verbose && ast_opt_console)
01730       ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
01731    ast_debug(1, "Asterisk ending (%d).\n", num);
01732    manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
01733    if (ast_socket > -1) {
01734       pthread_cancel(lthread);
01735       close(ast_socket);
01736       ast_socket = -1;
01737       unlink(ast_config_AST_SOCKET);
01738    }
01739    if (ast_consock > -1)
01740       close(ast_consock);
01741    if (!ast_opt_remote)
01742       unlink(ast_config_AST_PID);
01743    printf("%s", term_quit());
01744    if (restart) {
01745       int i;
01746       if (option_verbose || ast_opt_console)
01747          ast_verbose("Preparing for Asterisk restart...\n");
01748       /* Mark all FD's for closing on exec */
01749       for (i = 3; i < 32768; i++) {
01750          fcntl(i, F_SETFD, FD_CLOEXEC);
01751       }
01752       if (option_verbose || ast_opt_console)
01753          ast_verbose("Asterisk is now restarting...\n");
01754       restartnow = 1;
01755 
01756       /* close logger */
01757       close_logger();
01758 
01759       /* If there is a consolethread running send it a SIGHUP 
01760          so it can execvp, otherwise we can do it ourselves */
01761       if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
01762          pthread_kill(consolethread, SIGHUP);
01763          /* Give the signal handler some time to complete */
01764          sleep(2);
01765       } else
01766          execvp(_argv[0], _argv);
01767    
01768    } else {
01769       /* close logger */
01770       close_logger();
01771    }
01772 
01773    exit(0);
01774 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1864 of file asterisk.c.

References ast_all_zeros(), ast_el_add_history(), ast_safe_system(), quit_handler(), and SHUTDOWN_FAST.

Referenced by ast_remotecontrol().

01865 {
01866    int ret = 0;
01867 
01868    /* Called when readline data is available */
01869    if (!ast_all_zeros(s))
01870       ast_el_add_history(s);
01871    /* The real handler for bang */
01872    if (s[0] == '!') {
01873       if (s[1])
01874          ast_safe_system(s+1);
01875       else
01876          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01877       ret = 1;
01878    }
01879    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
01880        (s[4] == '\0' || isspace(s[4]))) {
01881       quit_handler(0, SHUTDOWN_FAST, 0);
01882       ret = 1;
01883    }
01884 
01885    return ret;
01886 }

static void run_startup_commands ( void   )  [static]

Definition at line 3214 of file asterisk.c.

References ast_config_destroy(), ast_config_load2(), ast_true(), ast_variable_browse(), CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by main().

03215 {
03216    int fd;
03217    struct ast_config *cfg;
03218    struct ast_flags cfg_flags = { 0 };
03219    struct ast_variable *v;
03220 
03221    if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
03222       return;
03223    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03224       return;
03225    }
03226 
03227    fd = open("/dev/null", O_RDWR);
03228    if (fd < 0) {
03229       ast_config_destroy(cfg);
03230       return;
03231    }
03232 
03233    for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
03234       if (ast_true(v->value))
03235          ast_cli_command(fd, v->name);
03236    }
03237 
03238    close(fd);
03239    ast_config_destroy(cfg);
03240 }

static void set_icon ( char *  text  )  [static]

Definition at line 1566 of file asterisk.c.

Referenced by main().

01567 {
01568    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01569       fprintf(stdout, "\033]1;%s\007", text);
01570 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1560 of file asterisk.c.

Referenced by main().

01561 {
01562    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01563       fprintf(stdout, "\033]2;%s\007", text);
01564 }

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1537 of file asterisk.c.

References ast_log(), errno, LOG_NOTICE, and LOG_WARNING.

01538 {
01539    struct rlimit l = {0, 0};
01540    
01541    if (value <= 0) {
01542       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01543       return;
01544    }
01545    
01546    l.rlim_cur = value;
01547    l.rlim_max = value;
01548    
01549    if (setrlimit(RLIMIT_NOFILE, &l)) {
01550       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01551       return;
01552    }
01553    
01554    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01555    
01556    return;
01557 }

static int show_cli_help ( void   )  [static]

Definition at line 2875 of file asterisk.c.

References ast_get_version().

Referenced by main().

02876 {
02877    printf("Asterisk %s, Copyright (C) 1999 - 2012, Digium, Inc. and others.\n", ast_get_version());
02878    printf("Usage: asterisk [OPTIONS]\n");
02879    printf("Valid Options:\n");
02880    printf("   -V              Display version number and exit\n");
02881    printf("   -C <configfile> Use an alternate configuration file\n");
02882    printf("   -G <group>      Run as a group other than the caller\n");
02883    printf("   -U <user>       Run as a user other than the caller\n");
02884    printf("   -c              Provide console CLI\n");
02885    printf("   -d              Enable extra debugging\n");
02886 #if HAVE_WORKING_FORK
02887    printf("   -f              Do not fork\n");
02888    printf("   -F              Always fork\n");
02889 #endif
02890    printf("   -g              Dump core in case of a crash\n");
02891    printf("   -h              This help screen\n");
02892    printf("   -i              Initialize crypto keys at startup\n");
02893    printf("   -I              Enable internal timing if DAHDI timer is available\n");
02894    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
02895    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
02896    printf("   -m              Mute debugging and console output on the console\n");
02897    printf("   -n              Disable console colorization\n");
02898    printf("   -p              Run as pseudo-realtime thread\n");
02899    printf("   -q              Quiet mode (suppress output)\n");
02900    printf("   -r              Connect to Asterisk on this machine\n");
02901    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
02902    printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
02903    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
02904    printf("                   belong after they are done\n");
02905    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
02906    printf("                   of output to the CLI\n");
02907    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
02908    printf("   -x <cmd>        Execute command <cmd> (implies -r)\n");
02909    printf("   -X              Execute includes by default (allows #exec in asterisk.conf)\n");
02910    printf("   -W              Adjust terminal colors to compensate for a light background\n");
02911    printf("\n");
02912    return 0;
02913 }

static char* show_license ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 2147 of file asterisk.c.

References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

02148 {
02149    switch (cmd) {
02150    case CLI_INIT:
02151       e->command = "core show license";
02152       e->usage = 
02153          "Usage: core show license\n"
02154          "       Shows the license(s) for this copy of Asterisk.\n";
02155       return NULL;
02156    case CLI_GENERATE:
02157       return NULL;
02158    }
02159 
02160    ast_cli(a->fd, "%s", license_lines);
02161 
02162    return CLI_SUCCESS;
02163 }

static int show_version ( void   )  [static]

Definition at line 2869 of file asterisk.c.

References ast_get_version().

Referenced by main().

02870 {
02871    printf("Asterisk %s\n", ast_get_version());
02872    return 0;
02873 }

static char* show_warranty ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 2110 of file asterisk.c.

References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

02111 {
02112    switch (cmd) {
02113    case CLI_INIT:
02114       e->command = "core show warranty";
02115       e->usage = 
02116          "Usage: core show warranty\n"
02117          "       Shows the warranty (if any) for this copy of Asterisk.\n";
02118       return NULL;
02119    case CLI_GENERATE:
02120       return NULL;
02121    }
02122 
02123    ast_cli(a->fd, "%s", warranty_lines);
02124 
02125    return CLI_SUCCESS;
02126 }


Variable Documentation

char* _argv[256] [static]

Definition at line 277 of file asterisk.c.

Referenced by _hup_handler(), main(), and really_quit().

const char* ast_config_AST_AGI_DIR = cfg_paths.agi_dir

Definition at line 259 of file asterisk.c.

Referenced by handle_show_settings(), and launch_script().

const char* ast_config_AST_CONFIG_DIR = cfg_paths.config_dir

Definition at line 251 of file asterisk.c.

Referenced by action_createconfig(), ast_module_reload(), compile_script(), config_text_file_load(), handle_cli_dialplan_save(), handle_show_settings(), ices_exec(), launch_script(), lua_read_extensions_file(), message_template_parse_filebody(), pbx_load_module(), and set_fn().

const char* ast_config_AST_CONFIG_FILE = cfg_paths.config_file

Definition at line 252 of file asterisk.c.

Referenced by ast_readconfig(), handle_show_settings(), and launch_script().

char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl" [static]

Definition at line 273 of file asterisk.c.

Referenced by ast_readconfig().

char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0" [static]

Definition at line 272 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0" [static]

Definition at line 271 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static]

Definition at line 270 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

const char* ast_config_AST_DATA_DIR = cfg_paths.data_dir

Definition at line 257 of file asterisk.c.

Referenced by ast_linear_stream(), build_filename(), handle_show_settings(), launch_script(), make_filename(), moh_scan_files(), phoneprov_callback(), pp_each_extension_helper(), reload_firmware(), setup_privacy_args(), and static_callback().

const char* ast_config_AST_DB = cfg_paths.db_path

Definition at line 263 of file asterisk.c.

Referenced by dbinit(), and handle_show_settings().

const char* ast_config_AST_KEY_DIR = cfg_paths.key_dir

Definition at line 260 of file asterisk.c.

Referenced by crypto_load(), handle_cli_keys_init(), handle_show_settings(), launch_script(), and osp_create_provider().

const char* ast_config_AST_LOG_DIR = cfg_paths.log_dir

Definition at line 258 of file asterisk.c.

Referenced by apply_general_options(), csv_log(), dahdi_r2_set_context(), handle_show_settings(), init_logger(), launch_script(), load_config(), load_module(), logger_queue_init(), logger_queue_restart(), make_logchannel(), OpenHistory(), reload_logger(), testclient_exec(), testserver_exec(), write_history(), and writefile().

const char* ast_config_AST_MODULE_DIR = cfg_paths.module_dir

Definition at line 253 of file asterisk.c.

Referenced by complete_fn(), handle_show_settings(), launch_script(), and load_dynamic_module().

const char* ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir

Definition at line 255 of file asterisk.c.

Referenced by ast_monitor_change_fname(), ast_monitor_start(), chanspy_exec(), extenspy_exec(), launch_script(), and mixmonitor_exec().

const char* ast_config_AST_PID = cfg_paths.pid_path

Definition at line 264 of file asterisk.c.

Referenced by handle_show_settings(), main(), and really_quit().

const char* ast_config_AST_RUN_DIR = cfg_paths.run_dir

Definition at line 261 of file asterisk.c.

Referenced by handle_show_settings(), launch_script(), and main().

const char* ast_config_AST_RUN_GROUP = cfg_paths.run_group

Definition at line 267 of file asterisk.c.

Referenced by action_coresettings(), handle_show_settings(), and main().

const char* ast_config_AST_RUN_USER = cfg_paths.run_user

Definition at line 266 of file asterisk.c.

Referenced by action_coresettings(), handle_show_settings(), and main().

const char* ast_config_AST_SOCKET = cfg_paths.socket_path

Definition at line 265 of file asterisk.c.

Referenced by ast_makesocket(), ast_tryconnect(), ast_var_Config(), main(), and really_quit().

const char* ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir

Definition at line 254 of file asterisk.c.

Referenced by app_exec(), conf_run(), dictate_exec(), handle_show_settings(), launch_script(), load_module(), sms_nextoutgoing(), and sms_writefile().

const char* ast_config_AST_SYSTEM_NAME = cfg_paths.system_name

Definition at line 268 of file asterisk.c.

Referenced by __ast_channel_alloc_ap(), __init_manager(), action_coresettings(), ast_str_retrieve_variable(), cli_prompt(), env_init(), handle_show_settings(), realtime_update_peer(), and reload_config().

const char* ast_config_AST_VAR_DIR = cfg_paths.var_dir

Definition at line 256 of file asterisk.c.

Referenced by ael2_semantic_check(), handle_show_settings(), and launch_script().

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

Definition at line 194 of file asterisk.c.

struct ast_eid ast_eid_default

Global EID.

This is set in asterisk.conf, or determined automatically by taking the mac address of an Ethernet interface on the system.

Definition at line 188 of file asterisk.c.

Referenced by aji_devstate_cb(), aji_handle_pubsub_event(), aji_mwi_cb(), aji_publish_device_state(), aji_publish_mwi(), ast_event_append_eid(), ast_event_cb(), ast_readconfig(), ast_str_retrieve_variable(), evt_event_deliver_cb(), handle_show_settings(), and set_config().

unsigned int ast_FD_SETSIZE

Definition at line 86 of file poll.c.

struct timeval ast_lastreloadtime

Definition at line 214 of file asterisk.c.

Referenced by action_corestatus(), ast_module_reload(), ast_var_Config(), handle_show_settings(), handle_showuptime(), and main().

pid_t ast_mainpid

Definition at line 195 of file asterisk.c.

Referenced by safe_append(), and scan_service().

int ast_socket = -1 [static]

UNIX Socket for allowing remote control

Definition at line 193 of file asterisk.c.

struct timeval ast_startuptime

Definition at line 213 of file asterisk.c.

Referenced by action_corestatus(), ast_var_Config(), handle_show_settings(), handle_showcalls(), handle_showuptime(), and main().

char canary_filename[128] [static]

Definition at line 292 of file asterisk.c.

Referenced by canary_thread(), and main().

int canary_pid = 0 [static]

Definition at line 291 of file asterisk.c.

Referenced by canary_exit(), and main().

struct _cfg_paths cfg_paths [static]

Definition at line 249 of file asterisk.c.

Referenced by ast_readconfig(), and main().

struct sigaction child_handler [static]

Initial value:

 {
   .sa_handler = _child_handler,
   .sa_flags = SA_RESTART,
}

Definition at line 1531 of file asterisk.c.

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 2169 of file asterisk.c.

Referenced by main().

struct console consoles[AST_MAX_CONNECTS]

Definition at line 220 of file asterisk.c.

Referenced by ast_console_toggle_loglevel(), ast_console_toggle_mute(), ast_makesocket(), ast_network_puts(), ast_network_puts_mutable(), and listener().

pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 289 of file asterisk.c.

Referenced by console_verboser(), main(), monitor_sig_flags(), and really_quit().

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 222 of file asterisk.c.

Referenced by __ast_channel_alloc_ap(), and handle_show_settings().

EditLine* el [static]

Definition at line 217 of file asterisk.c.

Referenced by __ast_internal_context_destroy(), ast_add_extension2_lockopt(), ast_el_add_history(), ast_el_initialize(), ast_el_read_history(), ast_el_write_history(), ast_remotecontrol(), handle_cli_dialplan_save(), main(), really_quit(), and show_dialplan_helper().

History* el_hist [static]

Definition at line 216 of file asterisk.c.

Referenced by ast_el_add_history(), ast_el_initialize(), ast_el_read_history(), ast_el_write_history(), ast_remotecontrol(), main(), and really_quit().

struct sigaction hup_handler [static]

Initial value:

 {
   .sa_handler = _hup_handler,
   .sa_flags = SA_RESTART,
}

Definition at line 1511 of file asterisk.c.

struct sigaction ignore_sig_handler [static]

Initial value:

 {
   .sa_handler = SIG_IGN,
}

Definition at line 998 of file asterisk.c.

const char license_lines[] [static]

Definition at line 2128 of file asterisk.c.

pthread_t lthread [static]

Definition at line 1190 of file asterisk.c.

Referenced by ast_makesocket(), and really_quit().

pthread_t mon_sig_flags [static]

Definition at line 290 of file asterisk.c.

Referenced by main(), and really_quit().

unsigned int need_quit

Definition at line 299 of file asterisk.c.

unsigned int need_quit_handler

Definition at line 300 of file asterisk.c.

unsigned int need_reload

Definition at line 298 of file asterisk.c.

struct sigaction null_sig_handler [static]

Initial value:

 {
   .sa_handler = _null_sig_handler,
   .sa_flags = SA_RESTART,
}

Definition at line 993 of file asterisk.c.

struct profile_data* prof_data [static]

Definition at line 695 of file asterisk.c.

Referenced by ast_add_profile(), ast_mark(), ast_profile(), handle_clear_profile(), and handle_show_profile().

struct ast_str* prompt = NULL [static]

Definition at line 2291 of file asterisk.c.

Referenced by auth_exec(), cli_prompt(), handle_speechrecognize(), minivm_accmess_exec(), and pw_cb().

char randompool[256] [static]

Definition at line 294 of file asterisk.c.

Referenced by main().

char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR

Definition at line 191 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 218 of file asterisk.c.

Referenced by ast_remotecontrol(), and cli_prompt().

int restartnow [static]

Definition at line 288 of file asterisk.c.

Referenced by _hup_handler(), and really_quit().

unsigned int safe_system_level = 0 [static]

Keep track of how many threads are currently trying to wait*() on a child process.

Definition at line 1005 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

ast_mutex_t safe_system_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Definition at line 1002 of file asterisk.c.

Referenced by ast_replace_sigchld(), ast_unreplace_sigchld(), can_safely_quit(), and handle_abort_shutdown().

struct sigaction safe_system_prev_handler [static]

Definition at line 1006 of file asterisk.c.

shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN [static]

Definition at line 287 of file asterisk.c.

Referenced by can_safely_quit(), and handle_abort_shutdown().

int sig_alert_pipe[2] = { -1, -1 } [static]

Definition at line 296 of file asterisk.c.

Referenced by __quit_handler(), _hup_handler(), main(), and monitor_sig_flags().

struct { ... } sig_flags [static]

Referenced by __quit_handler(), __remote_quit_handler(), _hup_handler(), ast_el_read_char(), ast_remotecontrol(), main(), and monitor_sig_flags().

struct sigaction urg_handler [static]

Initial value:

 {
   .sa_handler = _urg_handler,
   .sa_flags = SA_RESTART,
}

Definition at line 1490 of file asterisk.c.

const char warranty_lines[] [static]

Definition at line 2085 of file asterisk.c.


Generated on Mon Mar 19 11:30:36 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7