Mon Oct 8 12:39:11 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 154 of file asterisk.c.

#define AST_MAX_CONNECTS   128

Definition at line 158 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 2206 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 2208 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

Definition at line 785 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 2718 of file asterisk.c.

Referenced by ast_el_add_history(), and ast_el_read_history().

#define NUM_MSGS   64

Definition at line 159 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

Definition at line 155 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 162 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 282 of file asterisk.c.

00282              {
00283    NOT_SHUTTING_DOWN = -2,
00284    SHUTTING_DOWN = -1,
00285    /* Valid values for quit_handler niceness below: */
00286    SHUTDOWN_FAST,
00287    SHUTDOWN_NORMAL,
00288    SHUTDOWN_NICE,
00289    SHUTDOWN_REALLY_NICE
00290 } shutdown_nice_t;


Function Documentation

static void __quit_handler ( int  num  )  [static]

Definition at line 1817 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

01818 {
01819    int a = 0;
01820    sig_flags.need_quit = 1;
01821    if (sig_alert_pipe[1] != -1) {
01822       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01823          fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
01824       }
01825    }
01826    /* There is no need to restore the signal handler here, since the app
01827     * is going to exit */
01828 }

static void __remote_quit_handler ( int  num  )  [static]

Definition at line 1830 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

01831 {
01832    sig_flags.need_quit = 1;
01833 }

static void _child_handler ( int  sig  )  [static]

Definition at line 1557 of file asterisk.c.

References errno, and status.

01558 {
01559    /* Must not ever ast_log or ast_verbose within signal handler */
01560    int n, status, save_errno = errno;
01561 
01562    /*
01563     * Reap all dead children -- not just one
01564     */
01565    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01566       ;
01567    if (n == 0 && option_debug)   
01568       printf("Huh?  Child handler, but nobody there?\n");
01569    errno = save_errno;
01570 }

static void _hup_handler ( int  num  )  [static]

Definition at line 1536 of file asterisk.c.

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

01537 {
01538    int a = 0, save_errno = errno;
01539    if (option_verbose > 1) 
01540       printf("Received HUP signal -- Reloading configs\n");
01541    if (restartnow)
01542       execvp(_argv[0], _argv);
01543    sig_flags.need_reload = 1;
01544    if (sig_alert_pipe[1] != -1) {
01545       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01546          fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
01547       }
01548    }
01549    errno = save_errno;
01550 }

static void _null_sig_handler ( int  sig  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 993 of file asterisk.c.

00994 {
00995 }

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

01527 {
01528    return;
01529 }

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

support for event profiling

Returns:
Returns the identifier of the counter.

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

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

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1877 of file asterisk.c.

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

01878 {
01879    while (*s) {
01880       if (*s > 32)
01881          return 0;
01882       s++;  
01883    }
01884    return 1;
01885 }

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

Definition at line 2515 of file asterisk.c.

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

Referenced by cli_complete().

02516 {
02517    int i, idx, limit, count;
02518    int screenwidth = 0;
02519    int numoutput = 0, numoutputline = 0;
02520 
02521    screenwidth = ast_get_termcols(STDOUT_FILENO);
02522 
02523    /* find out how many entries can be put on one line, with two spaces between strings */
02524    limit = screenwidth / (max + 2);
02525    if (limit == 0)
02526       limit = 1;
02527 
02528    /* how many lines of output */
02529    count = len / limit;
02530    if (count * limit < len)
02531       count++;
02532 
02533    idx = 1;
02534 
02535    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
02536 
02537    for (; count > 0; count--) {
02538       numoutputline = 0;
02539       for (i = 0; i < limit && matches[idx]; i++, idx++) {
02540 
02541          /* Don't print dupes */
02542          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
02543             i--;
02544             ast_free(matches[idx]);
02545             matches[idx] = NULL;
02546             continue;
02547          }
02548 
02549          numoutput++;
02550          numoutputline++;
02551          fprintf(stdout, "%-*s  ", max, matches[idx]);
02552          ast_free(matches[idx]);
02553          matches[idx] = NULL;
02554       }
02555       if (numoutputline > 0)
02556          fprintf(stdout, "\n");
02557    }
02558 
02559    return numoutput;
02560 }

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

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

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

void ast_console_puts ( const char *  string  ) 

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

Definition at line 1187 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

01188 {
01189    fputs(string, stdout);
01190    fflush(stdout);
01191    ast_network_puts(string);
01192 }

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

References ast_network_puts_mutable().

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

01165 {
01166    fputs(string, stdout);
01167    fflush(stdout);
01168    ast_network_puts_mutable(string, level);
01169 }

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

References AST_MAX_CONNECTS, consoles, levels, and NUMLOGLEVELS.

Referenced by handle_logger_set_level().

01102 {
01103    int x;
01104 
01105    if (level >= NUMLOGLEVELS) {
01106       level = NUMLOGLEVELS - 1;
01107    }
01108 
01109    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01110       if (fd == consoles[x].fd) {
01111          /*
01112           * Since the logging occurs when levels are false, set to
01113           * flipped iinput because this function accepts 0 as off and 1 as on
01114           */
01115          consoles[x].levels[level] = state ? 0 : 1;
01116          return;
01117       }
01118    }
01119 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1124 of file asterisk.c.

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

Referenced by handle_logger_mute().

01125 {
01126    int x;
01127    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01128       if (fd == consoles[x].fd) {
01129          if (consoles[x].mute) {
01130             consoles[x].mute = 0;
01131             if (!silent)
01132                ast_cli(fd, "Console is not muted anymore.\n");
01133          } else {
01134             consoles[x].mute = 1;
01135             if (!silent)
01136                ast_cli(fd, "Console is muted.\n");
01137          }
01138          return;
01139       }
01140    }
01141    ast_cli(fd, "Couldn't find remote console.\n");
01142 }

static int ast_el_add_history ( char *   )  [static]

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

02721 {
02722    HistEvent ev;
02723 
02724    if (el_hist == NULL || el == NULL)
02725       ast_el_initialize();
02726    if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1))
02727       return 0;
02728    return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf))));
02729 }

static int ast_el_initialize ( void   )  [static]

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

02684 {
02685    HistEvent ev;
02686    char *editor = getenv("AST_EDITOR");
02687 
02688    if (el != NULL)
02689       el_end(el);
02690    if (el_hist != NULL)
02691       history_end(el_hist);
02692 
02693    el = el_init("asterisk", stdin, stdout, stderr);
02694    el_set(el, EL_PROMPT, cli_prompt);
02695 
02696    el_set(el, EL_EDITMODE, 1);      
02697    el_set(el, EL_EDITOR, editor ? editor : "emacs");     
02698    el_hist = history_init();
02699    if (!el || !el_hist)
02700       return -1;
02701 
02702    /* setup history with 100 entries */
02703    history(el_hist, &ev, H_SETSIZE, 100);
02704 
02705    el_set(el, EL_HIST, history, el_hist);
02706 
02707    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02708    /* Bind <tab> to command completion */
02709    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02710    /* Bind ? to command completion */
02711    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02712    /* Bind ^D to redisplay */
02713    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02714 
02715    return 0;
02716 }

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

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

02235 {
02236    int num_read = 0;
02237    int lastpos = 0;
02238    struct pollfd fds[2];
02239    int res;
02240    int max;
02241 #define EL_BUF_SIZE 512
02242    char buf[EL_BUF_SIZE];
02243 
02244    for (;;) {
02245       max = 1;
02246       fds[0].fd = ast_consock;
02247       fds[0].events = POLLIN;
02248       if (!ast_opt_exec) {
02249          fds[1].fd = STDIN_FILENO;
02250          fds[1].events = POLLIN;
02251          max++;
02252       }
02253       res = ast_poll(fds, max, -1);
02254       if (res < 0) {
02255          if (sig_flags.need_quit || sig_flags.need_quit_handler)
02256             break;
02257          if (errno == EINTR)
02258             continue;
02259          ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
02260          break;
02261       }
02262 
02263       if (!ast_opt_exec && fds[1].revents) {
02264          num_read = read(STDIN_FILENO, cp, 1);
02265          if (num_read < 1) {
02266             break;
02267          } else 
02268             return (num_read);
02269       }
02270       if (fds[0].revents) {
02271          char *tmp;
02272          res = read(ast_consock, buf, sizeof(buf) - 1);
02273          /* if the remote side disappears exit */
02274          if (res < 1) {
02275             fprintf(stderr, "\nDisconnected from Asterisk server\n");
02276             if (!ast_opt_reconnect) {
02277                quit_handler(0, SHUTDOWN_FAST, 0);
02278             } else {
02279                int tries;
02280                int reconnects_per_second = 20;
02281                fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
02282                for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
02283                   if (ast_tryconnect()) {
02284                      fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
02285                      printf("%s", term_quit());
02286                      WELCOME_MESSAGE;
02287                      if (!ast_opt_mute)
02288                         fdsend(ast_consock, "logger mute silent");
02289                      else 
02290                         printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02291                      break;
02292                   } else
02293                      usleep(1000000 / reconnects_per_second);
02294                }
02295                if (tries >= 30 * reconnects_per_second) {
02296                   fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
02297                   quit_handler(0, SHUTDOWN_FAST, 0);
02298                }
02299             }
02300             continue;
02301          }
02302 
02303          buf[res] = '\0';
02304 
02305          /* Strip preamble from asynchronous events, too */
02306          for (tmp = buf; *tmp; tmp++) {
02307             if (*tmp == 127) {
02308                memmove(tmp, tmp + 1, strlen(tmp));
02309                tmp--;
02310                res--;
02311             }
02312          }
02313 
02314          /* Write over the CLI prompt */
02315          if (!ast_opt_exec && !lastpos) {
02316             if (write(STDOUT_FILENO, "\r", 5) < 0) {
02317             }
02318          }
02319          if (write(STDOUT_FILENO, buf, res) < 0) {
02320          }
02321          if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
02322             *cp = CC_REFRESH;
02323             return(1);
02324          } else
02325             lastpos = 1;
02326       }
02327    }
02328 
02329    *cp = '\0';
02330    return (0);
02331 }

static int ast_el_read_history ( char *   )  [static]

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

02742 {
02743    char buf[MAX_HISTORY_COMMAND_LENGTH];
02744    FILE *f;
02745    int ret = -1;
02746 
02747    if (el_hist == NULL || el == NULL)
02748       ast_el_initialize();
02749 
02750    if ((f = fopen(filename, "r")) == NULL)
02751       return ret;
02752 
02753    while (!feof(f)) {
02754       if (!fgets(buf, sizeof(buf), f))
02755          break;
02756       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02757          continue;
02758       if (ast_all_zeros(buf))
02759          continue;
02760       if ((ret = ast_el_add_history(buf)) == -1)
02761          break;
02762    }
02763    fclose(f);
02764 
02765    return ret;
02766 }

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

Definition at line 2505 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02506 {
02507    char *s1, *s2;
02508 
02509    s1 = ((char **)i1)[0];
02510    s2 = ((char **)i2)[0];
02511 
02512    return strcasecmp(s1, s2);
02513 }

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

Definition at line 2462 of file asterisk.c.

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

Referenced by cli_complete().

02463 {
02464    char **match_list = NULL, **match_list_tmp, *retstr;
02465    size_t match_list_len;
02466    int matches = 0;
02467 
02468    match_list_len = 1;
02469    while ( (retstr = strsep(&buf, " ")) != NULL) {
02470 
02471       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
02472          break;
02473       if (matches + 1 >= match_list_len) {
02474          match_list_len <<= 1;
02475          if ((match_list_tmp = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
02476             match_list = match_list_tmp;
02477          } else {
02478             if (match_list)
02479                ast_free(match_list);
02480             return (char **) NULL;
02481          }
02482       }
02483 
02484       match_list[matches++] = ast_strdup(retstr);
02485    }
02486 
02487    if (!match_list)
02488       return (char **) NULL;
02489 
02490    if (matches >= match_list_len) {
02491       if ((match_list_tmp = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
02492          match_list = match_list_tmp;
02493       } else {
02494          if (match_list)
02495             ast_free(match_list);
02496          return (char **) NULL;
02497       }
02498    }
02499 
02500    match_list[matches] = (char *) NULL;
02501 
02502    return match_list;
02503 }

static int ast_el_write_history ( char *   )  [static]

Definition at line 2731 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by really_quit().

02732 {
02733    HistEvent ev;
02734 
02735    if (el_hist == NULL || el == NULL)
02736       ast_el_initialize();
02737 
02738    return (history(el_hist, &ev, H_SAVE, filename));
02739 }

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

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

static int ast_makesocket ( void   )  [static]

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

01426 {
01427    struct sockaddr_un sunaddr;
01428    int res;
01429    int x;
01430    uid_t uid = -1;
01431    gid_t gid = -1;
01432 
01433    for (x = 0; x < AST_MAX_CONNECTS; x++) 
01434       consoles[x].fd = -1;
01435    unlink(ast_config_AST_SOCKET);
01436    ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
01437    if (ast_socket < 0) {
01438       ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
01439       return -1;
01440    }     
01441    memset(&sunaddr, 0, sizeof(sunaddr));
01442    sunaddr.sun_family = AF_LOCAL;
01443    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01444    res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01445    if (res) {
01446       ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01447       close(ast_socket);
01448       ast_socket = -1;
01449       return -1;
01450    }
01451    res = listen(ast_socket, 2);
01452    if (res < 0) {
01453       ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01454       close(ast_socket);
01455       ast_socket = -1;
01456       return -1;
01457    }
01458    if (ast_register_verbose(network_verboser)) {
01459       ast_log(LOG_WARNING, "Unable to register network verboser?\n");
01460    }
01461 
01462    if (ast_pthread_create_background(&lthread, NULL, listener, NULL)) {
01463       ast_log(LOG_WARNING, "Unable to create listener thread.\n");
01464       close(ast_socket);
01465       return -1;
01466    }
01467 
01468    if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
01469       struct passwd *pw;
01470       if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
01471          ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
01472       else
01473          uid = pw->pw_uid;
01474    }
01475       
01476    if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
01477       struct group *grp;
01478       if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
01479          ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
01480       else
01481          gid = grp->gr_gid;
01482    }
01483 
01484    if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
01485       ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01486 
01487    if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
01488       int p1;
01489       mode_t p;
01490       sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
01491       p = p1;
01492       if ((chmod(ast_config_AST_SOCKET, p)) < 0)
01493          ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01494    }
01495 
01496    return 0;
01497 }

int64_t ast_mark ( int  i,
int  startstop 
)

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

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

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

write the string to all attached console clients

Definition at line 1174 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

01175 {
01176    int x;
01177    for (x = 0; x < AST_MAX_CONNECTS; x++) {
01178       if (consoles[x].fd > -1) 
01179          fdprint(consoles[x].p[1], string);
01180    }
01181 }

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

log the string to all attached console clients

Definition at line 1147 of file asterisk.c.

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

Referenced by ast_console_puts_mutable(), and network_verboser().

01148 {
01149    int x;
01150    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01151       if (consoles[x].mute)
01152          continue;
01153       if (consoles[x].fd > -1) {
01154          if (!consoles[x].levels[level]) 
01155             fdprint(consoles[x].p[1], string);
01156       }
01157    }
01158 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 734 of file asterisk.c.

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

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

static void ast_readconfig ( void   )  [static]

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

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

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

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

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

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

void ast_register_thread ( char *  name  ) 

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

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

static void ast_remotecontrol ( char *  data  )  [static]

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

02769 {
02770    char buf[80];
02771    int res;
02772    char filename[80] = "";
02773    char *hostname;
02774    char *cpid;
02775    char *version;
02776    int pid;
02777    char *stringp = NULL;
02778 
02779    char *ebuf;
02780    int num = 0;
02781 
02782    memset(&sig_flags, 0, sizeof(sig_flags));
02783    signal(SIGINT, __remote_quit_handler);
02784    signal(SIGTERM, __remote_quit_handler);
02785    signal(SIGHUP, __remote_quit_handler);
02786 
02787    if (read(ast_consock, buf, sizeof(buf)) < 0) {
02788       ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02789       return;
02790    }
02791    if (data) {
02792       char prefix[] = "cli quit after ";
02793       char *tmp = alloca(strlen(data) + strlen(prefix) + 1);
02794       sprintf(tmp, "%s%s", prefix, data);
02795       if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
02796          ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
02797          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02798             return;
02799          }
02800       }
02801    }
02802    stringp = buf;
02803    hostname = strsep(&stringp, "/");
02804    cpid = strsep(&stringp, "/");
02805    version = strsep(&stringp, "\n");
02806    if (!version)
02807       version = "<Version Unknown>";
02808    stringp = hostname;
02809    strsep(&stringp, ".");
02810    if (cpid)
02811       pid = atoi(cpid);
02812    else
02813       pid = -1;
02814    if (!data) {
02815       char tmp[80];
02816       snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
02817       fdsend(ast_consock, tmp);
02818       snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
02819       fdsend(ast_consock, tmp);
02820       if (!ast_opt_mute)
02821          fdsend(ast_consock, "logger mute silent");
02822       else 
02823          printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02824    }
02825 
02826    if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
02827       struct pollfd fds;
02828       fds.fd = ast_consock;
02829       fds.events = POLLIN;
02830       fds.revents = 0;
02831       while (ast_poll(&fds, 1, 60000) > 0) {
02832          char buffer[512] = "", *curline = buffer, *nextline;
02833          int not_written = 1;
02834 
02835          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02836             break;
02837          }
02838 
02839          if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
02840             break;
02841          }
02842 
02843          do {
02844             if ((nextline = strchr(curline, '\n'))) {
02845                nextline++;
02846             } else {
02847                nextline = strchr(curline, '\0');
02848             }
02849 
02850             /* Skip verbose lines */
02851             if (*curline != 127) {
02852                not_written = 0;
02853                if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
02854                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
02855                }
02856             }
02857             curline = nextline;
02858          } while (!ast_strlen_zero(curline));
02859 
02860          /* No non-verbose output in 60 seconds. */
02861          if (not_written) {
02862             break;
02863          }
02864       }
02865       return;
02866    }
02867 
02868    ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
02869    remotehostname = hostname;
02870    if (getenv("HOME")) 
02871       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
02872    if (el_hist == NULL || el == NULL)
02873       ast_el_initialize();
02874 
02875    el_set(el, EL_GETCFN, ast_el_read_char);
02876 
02877    if (!ast_strlen_zero(filename))
02878       ast_el_read_history(filename);
02879 
02880    for (;;) {
02881       ebuf = (char *)el_gets(el, &num);
02882 
02883       if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02884          break;
02885       }
02886 
02887       if (!ebuf && write(1, "", 1) < 0)
02888          break;
02889 
02890       if (!ast_strlen_zero(ebuf)) {
02891          if (ebuf[strlen(ebuf)-1] == '\n')
02892             ebuf[strlen(ebuf)-1] = '\0';
02893          if (!remoteconsolehandler(ebuf)) {
02894             /* Strip preamble from output */
02895             char *temp;
02896             for (temp = ebuf; *temp; temp++) {
02897                if (*temp == 127) {
02898                   memmove(temp, temp + 1, strlen(temp));
02899                   temp--;
02900                }
02901             }
02902             res = write(ast_consock, ebuf, strlen(ebuf) + 1);
02903             if (res < 1) {
02904                ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
02905                break;
02906             }
02907          }
02908       }
02909    }
02910    printf("\nDisconnected from Asterisk server\n");
02911 }

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

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

static void ast_run_atexits ( void   )  [static]

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

01650 {
01651    struct ast_atexit *ae;
01652    AST_RWLIST_RDLOCK(&atexits);
01653    AST_RWLIST_TRAVERSE(&atexits, ae, list) {
01654       if (ae->func) 
01655          ae->func();
01656    }
01657    AST_RWLIST_UNLOCK(&atexits);
01658 }

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

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

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

01616 {
01617    struct sched_param sched;
01618    memset(&sched, 0, sizeof(sched));
01619 #ifdef __linux__
01620    if (pri) {  
01621       sched.sched_priority = 10;
01622       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01623          ast_log(LOG_WARNING, "Unable to set high priority\n");
01624          return -1;
01625       } else
01626          if (option_verbose)
01627             ast_verbose("Set to realtime thread\n");
01628    } else {
01629       sched.sched_priority = 0;
01630       /* According to the manpage, these parameters can never fail. */
01631       sched_setscheduler(0, SCHED_OTHER, &sched);
01632    }
01633 #else
01634    if (pri) {
01635       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01636          ast_log(LOG_WARNING, "Unable to set high priority\n");
01637          return -1;
01638       } else
01639          if (option_verbose)
01640             ast_verbose("Set to high priority\n");
01641    } else {
01642       /* According to the manpage, these parameters can never fail. */
01643       setpriority(PRIO_PROCESS, 0, 0);
01644    }
01645 #endif
01646    return 0;
01647 }

static int ast_tryconnect ( void   )  [static]

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

01500 {
01501    struct sockaddr_un sunaddr;
01502    int res;
01503    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01504    if (ast_consock < 0) {
01505       ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
01506       return 0;
01507    }
01508    memset(&sunaddr, 0, sizeof(sunaddr));
01509    sunaddr.sun_family = AF_LOCAL;
01510    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01511    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01512    if (res) {
01513       close(ast_consock);
01514       ast_consock = -1;
01515       return 0;
01516    } else
01517       return 1;
01518 }

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

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

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

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

void ast_unregister_thread ( void *  id  ) 

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

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

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

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

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

Definition at line 1672 of file asterisk.c.

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

Referenced by quit_handler().

01673 {
01674    /* Check if someone else isn't already doing this. */
01675    ast_mutex_lock(&safe_system_lock);
01676    if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
01677       /* Already in progress and other request was less nice. */
01678       ast_mutex_unlock(&safe_system_lock);
01679       ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
01680       return 0;
01681    }
01682    shuttingdown = niceness;
01683    ast_mutex_unlock(&safe_system_lock);
01684 
01685    /* Try to get as many CDRs as possible submitted to the backend engines
01686     * (if in batch mode). really_quit happens to call it again when running
01687     * the atexit handlers, otherwise this would be a bit early. */
01688    ast_cdr_engine_term();
01689 
01690    if (niceness == SHUTDOWN_NORMAL) {
01691       time_t s, e;
01692       /* Begin shutdown routine, hanging up active channels */
01693       ast_begin_shutdown(1);
01694       if (option_verbose && ast_opt_console) {
01695          ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
01696       }
01697       time(&s);
01698       for (;;) {
01699          time(&e);
01700          /* Wait up to 15 seconds for all channels to go away */
01701          if ((e - s) > 15 || !ast_undestroyed_channels() || shuttingdown != niceness) {
01702             break;
01703          }
01704          /* Sleep 1/10 of a second */
01705          usleep(100000);
01706       }
01707    } else if (niceness >= SHUTDOWN_NICE) {
01708       if (niceness != SHUTDOWN_REALLY_NICE) {
01709          ast_begin_shutdown(0);
01710       }
01711       if (option_verbose && ast_opt_console) {
01712          ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
01713       }
01714       for (;;) {
01715          if (!ast_undestroyed_channels() || shuttingdown != niceness) {
01716             break;
01717          }
01718          sleep(1);
01719       }
01720    }
01721 
01722    /* Re-acquire lock and check if someone changed the niceness, in which
01723     * case someone else has taken over the shutdown. */
01724    ast_mutex_lock(&safe_system_lock);
01725    if (shuttingdown != niceness) {
01726       if (shuttingdown == NOT_SHUTTING_DOWN && option_verbose && ast_opt_console) {
01727          ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
01728       }
01729       ast_mutex_unlock(&safe_system_lock);
01730       return 0;
01731    }
01732    shuttingdown = SHUTTING_DOWN;
01733    ast_mutex_unlock(&safe_system_lock);
01734 
01735    return 1;
01736 }

static void canary_exit ( void   )  [static]

Definition at line 3251 of file asterisk.c.

References canary_pid.

Referenced by main().

03252 {
03253    if (canary_pid > 0)
03254       kill(canary_pid, SIGKILL);
03255 }

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

Definition at line 3222 of file asterisk.c.

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

Referenced by main().

03223 {
03224    struct stat canary_stat;
03225    struct timeval now;
03226 
03227    /* Give the canary time to sing */
03228    sleep(120);
03229 
03230    for (;;) {
03231       now = ast_tvnow();
03232       if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
03233          ast_log(LOG_WARNING,
03234             "The canary is no more.  He has ceased to be!  "
03235             "He's expired and gone to meet his maker!  "
03236             "He's a stiff!  Bereft of life, he rests in peace.  "
03237             "His metabolic processes are now history!  He's off the twig!  "
03238             "He's kicked the bucket.  He's shuffled off his mortal coil, "
03239             "run down the curtain, and joined the bleeding choir invisible!!  "
03240             "THIS is an EX-CANARY.  (Reducing priority)\n");
03241          ast_set_priority(0);
03242          pthread_exit(NULL);
03243       }
03244 
03245       /* Check the canary once a minute */
03246       sleep(60);
03247    }
03248 }

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

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

02564 {
02565    int len = 0;
02566    char *ptr;
02567    int nummatches = 0;
02568    char **matches;
02569    int retval = CC_ERROR;
02570    char buf[2048], savechr;
02571    int res;
02572 
02573    LineInfo *lf = (LineInfo *)el_line(editline);
02574 
02575    savechr = *(char *)lf->cursor;
02576    *(char *)lf->cursor = '\0';
02577    ptr = (char *)lf->cursor;
02578    if (ptr) {
02579       while (ptr > lf->buffer) {
02580          if (isspace(*ptr)) {
02581             ptr++;
02582             break;
02583          }
02584          ptr--;
02585       }
02586    }
02587 
02588    len = lf->cursor - ptr;
02589 
02590    if (ast_opt_remote) {
02591       snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 
02592       fdsend(ast_consock, buf);
02593       if ((res = read(ast_consock, buf, sizeof(buf) - 1)) < 0) {
02594          return (char*)(CC_ERROR);
02595       }
02596       buf[res] = '\0';
02597       nummatches = atoi(buf);
02598 
02599       if (nummatches > 0) {
02600          char *mbuf;
02601          int mlen = 0, maxmbuf = 2048;
02602          /* Start with a 2048 byte buffer */       
02603          if (!(mbuf = ast_malloc(maxmbuf))) {
02604             lf->cursor[0] = savechr;
02605             return (char *)(CC_ERROR);
02606          }
02607          snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 
02608          fdsend(ast_consock, buf);
02609          res = 0;
02610          mbuf[0] = '\0';
02611          while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
02612             if (mlen + 1024 > maxmbuf) {
02613                /* Every step increment buffer 1024 bytes */
02614                maxmbuf += 1024;              
02615                if (!(mbuf = ast_realloc(mbuf, maxmbuf))) {
02616                   lf->cursor[0] = savechr;
02617                   return (char *)(CC_ERROR);
02618                }
02619             }
02620             /* Only read 1024 bytes at a time */
02621             res = read(ast_consock, mbuf + mlen, 1024);
02622             if (res > 0)
02623                mlen += res;
02624          }
02625          mbuf[mlen] = '\0';
02626 
02627          matches = ast_el_strtoarr(mbuf);
02628          ast_free(mbuf);
02629       } else
02630          matches = (char **) NULL;
02631    } else {
02632       char **p, *oldbuf=NULL;
02633       nummatches = 0;
02634       matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
02635       for (p = matches; p && *p; p++) {
02636          if (!oldbuf || strcmp(*p,oldbuf))
02637             nummatches++;
02638          oldbuf = *p;
02639       }
02640    }
02641 
02642    if (matches) {
02643       int i;
02644       int matches_num, maxlen, match_len;
02645 
02646       if (matches[0][0] != '\0') {
02647          el_deletestr(editline, (int) len);
02648          el_insertstr(editline, matches[0]);
02649          retval = CC_REFRESH;
02650       }
02651 
02652       if (nummatches == 1) {
02653          /* Found an exact match */
02654          el_insertstr(editline, " ");
02655          retval = CC_REFRESH;
02656       } else {
02657          /* Must be more than one match */
02658          for (i = 1, maxlen = 0; matches[i]; i++) {
02659             match_len = strlen(matches[i]);
02660             if (match_len > maxlen)
02661                maxlen = match_len;
02662          }
02663          matches_num = i - 1;
02664          if (matches_num >1) {
02665             fprintf(stdout, "\n");
02666             ast_cli_display_match_list(matches, nummatches, maxlen);
02667             retval = CC_REDISPLAY;
02668          } else { 
02669             el_insertstr(editline," ");
02670             retval = CC_REFRESH;
02671          }
02672       }
02673       for (i = 0; matches[i]; i++)
02674          ast_free(matches[i]);
02675       ast_free(matches);
02676    }
02677 
02678    lf->cursor[0] = savechr;
02679 
02680    return (char *)(long)retval;
02681 }

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

Definition at line 2335 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, MAXHOSTNAMELEN, prompt, remotehostname, and term_color_code().

Referenced by ast_el_initialize().

02336 {
02337    char tmp[100];
02338    char *pfmt;
02339    int color_used = 0;
02340    static int cli_prompt_changes = 0;
02341    char term_code[20];
02342    struct passwd *pw;
02343    struct group *gr;
02344 
02345    if (prompt == NULL) {
02346       prompt = ast_str_create(100);
02347    } else if (!cli_prompt_changes) {
02348       return ast_str_buffer(prompt);
02349    } else {
02350       ast_str_reset(prompt);
02351    }
02352 
02353    if ((pfmt = getenv("ASTERISK_PROMPT"))) {
02354       char *t = pfmt;
02355       struct timeval ts = ast_tvnow();
02356       while (*t != '\0') {
02357          if (*t == '%') {
02358             char hostname[MAXHOSTNAMELEN] = "";
02359             int i, which;
02360             struct ast_tm tm = { 0, };
02361             int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
02362 
02363             t++;
02364             switch (*t) {
02365             case 'C': /* color */
02366                t++;
02367                if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
02368                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)));
02369                   t += i - 1;
02370                } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
02371                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code)));
02372                   t += i - 1;
02373                }
02374 
02375                /* If the color has been reset correctly, then there's no need to reset it later */
02376                color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
02377                break;
02378             case 'd': /* date */
02379                if (ast_localtime(&ts, &tm, NULL)) {
02380                   ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
02381                   ast_str_append(&prompt, 0, "%s", tmp);
02382                   cli_prompt_changes++;
02383                }
02384                break;
02385             case 'g': /* group */
02386                if ((gr = getgrgid(getgid()))) {
02387                   ast_str_append(&prompt, 0, "%s", gr->gr_name);
02388                }
02389                break;
02390             case 'h': /* hostname */
02391                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02392                   ast_str_append(&prompt, 0, "%s", hostname);
02393                } else {
02394                   ast_str_append(&prompt, 0, "%s", "localhost");
02395                }
02396                break;
02397             case 'H': /* short hostname */
02398                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02399                   char *dotptr;
02400                   if ((dotptr = strchr(hostname, '.'))) {
02401                      *dotptr = '\0';
02402                   }
02403                   ast_str_append(&prompt, 0, "%s", hostname);
02404                } else {
02405                   ast_str_append(&prompt, 0, "%s", "localhost");
02406                }
02407                break;
02408 #ifdef HAVE_GETLOADAVG
02409             case 'l': /* load avg */
02410                t++;
02411                if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
02412                   double list[3];
02413                   getloadavg(list, 3);
02414                   ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
02415                   cli_prompt_changes++;
02416                }
02417                break;
02418 #endif
02419             case 's': /* Asterisk system name (from asterisk.conf) */
02420                ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
02421                break;
02422             case 't': /* time */
02423                if (ast_localtime(&ts, &tm, NULL)) {
02424                   ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
02425                   ast_str_append(&prompt, 0, "%s", tmp);
02426                   cli_prompt_changes++;
02427                }
02428                break;
02429             case 'u': /* username */
02430                if ((pw = getpwuid(getuid()))) {
02431                   ast_str_append(&prompt, 0, "%s", pw->pw_name);
02432                }
02433                break;
02434             case '#': /* process console or remote? */
02435                ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
02436                break;
02437             case '%': /* literal % */
02438                ast_str_append(&prompt, 0, "%c", '%');
02439                break;
02440             case '\0': /* % is last character - prevent bug */
02441                t--;
02442                break;
02443             }
02444          } else {
02445             ast_str_append(&prompt, 0, "%c", *t);
02446          }
02447          t++;
02448       }
02449       if (color_used) {
02450          /* Force colors back to normal at end */
02451          ast_str_append(&prompt, 0, "%s", term_color_code(term_code, 0, 0, sizeof(term_code)));
02452       }
02453    } else if (remotehostname) {
02454       ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname);
02455    } else {
02456       ast_str_set(&prompt, 0, "%s", ASTERISK_PROMPT);
02457    }
02458 
02459    return ast_str_buffer(prompt);   
02460 }

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

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

01853 {
01854    char tmp[80];
01855    const char *c = NULL;
01856 
01857    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01858        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01859        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01860        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
01861       fputs(tmp, stdout);
01862       fputs(c, stdout);
01863    } else {
01864       if (*s == 127) {
01865          s++;
01866       }
01867       fputs(s, stdout);
01868    }
01869 
01870    fflush(stdout);
01871    
01872    /* Wake up a poll()ing console */
01873    if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
01874       pthread_kill(consolethread, SIGURG);
01875 }

static void consolehandler ( char *  s  )  [static]

Definition at line 1887 of file asterisk.c.

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

Referenced by main().

01888 {
01889    printf("%s", term_end());
01890    fflush(stdout);
01891 
01892    /* Called when readline data is available */
01893    if (!ast_all_zeros(s))
01894       ast_el_add_history(s);
01895    /* The real handler for bang */
01896    if (s[0] == '!') {
01897       if (s[1])
01898          ast_safe_system(s+1);
01899       else
01900          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01901    } else 
01902       ast_cli_command(STDOUT_FILENO, s);
01903 }

static void env_init ( void   )  [static]

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

03286 {
03287    setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
03288    setenv("AST_BUILD_HOST", ast_build_hostname, 1);
03289    setenv("AST_BUILD_DATE", ast_build_date, 1);
03290    setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
03291    setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
03292    setenv("AST_BUILD_OS", ast_build_os, 1);
03293    setenv("AST_BUILD_USER", ast_build_user, 1);
03294    setenv("AST_VERSION", ast_get_version(), 1);
03295 }

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

Definition at line 987 of file asterisk.c.

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

00988 {
00989    return write(fd, s, strlen(s));
00990 }

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

Definition at line 981 of file asterisk.c.

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

00982 {
00983    return write(fd, s, strlen(s) + 1);
00984 }

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

Definition at line 1835 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01836 {
01837    const char *c;
01838 
01839    /* Check for verboser preamble */
01840    if (*s == 127) {
01841       s++;
01842    }
01843 
01844    if (!strncmp(s, cmp, strlen(cmp))) {
01845       c = s + strlen(cmp);
01846       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01847       return c;
01848    }
01849    return NULL;
01850 }

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

Definition at line 2079 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.

02080 {
02081    int aborting_shutdown = 0;
02082 
02083    switch (cmd) {
02084    case CLI_INIT:
02085       e->command = "core abort shutdown";
02086       e->usage = 
02087          "Usage: core abort shutdown\n"
02088          "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
02089          "       call operations.\n";
02090       return NULL;
02091    case CLI_GENERATE:
02092       return NULL;
02093    }
02094 
02095    if (a->argc != e->args)
02096       return CLI_SHOWUSAGE;
02097 
02098    ast_mutex_lock(&safe_system_lock);
02099    if (shuttingdown >= SHUTDOWN_FAST) {
02100       aborting_shutdown = 1;
02101       shuttingdown = NOT_SHUTTING_DOWN;
02102    }
02103    ast_mutex_unlock(&safe_system_lock);
02104 
02105    if (aborting_shutdown) {
02106       ast_cancel_shutdown();
02107    }
02108    return CLI_SUCCESS;
02109 }

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

Definition at line 2111 of file asterisk.c.

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

02112 {
02113    switch (cmd) {
02114    case CLI_INIT:
02115       e->command = "!";
02116       e->usage = 
02117          "Usage: !<command>\n"
02118          "       Executes a given shell command\n";
02119       return NULL;
02120    case CLI_GENERATE:
02121       return NULL;
02122    }
02123 
02124    return CLI_SUCCESS;
02125 }

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

Definition at line 833 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.

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

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

Definition at line 2039 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.

02040 {
02041    switch (cmd) {
02042    case CLI_INIT:
02043       e->command = "core restart gracefully";
02044       e->usage = 
02045          "Usage: core restart gracefully\n"
02046          "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
02047          "       restart when all active calls have ended.\n";
02048       return NULL;
02049    case CLI_GENERATE:
02050       return NULL;
02051    }
02052 
02053    if (a->argc != e->args)
02054       return CLI_SHOWUSAGE;
02055    quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
02056    return CLI_SUCCESS;
02057 }

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

Definition at line 2019 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.

02020 {
02021    switch (cmd) {
02022    case CLI_INIT:
02023       e->command = "core restart now";
02024       e->usage = 
02025          "Usage: core restart now\n"
02026          "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
02027          "       restart.\n";
02028       return NULL;
02029    case CLI_GENERATE:
02030       return NULL;
02031    }
02032 
02033    if (a->argc != e->args)
02034       return CLI_SHOWUSAGE;
02035    quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
02036    return CLI_SUCCESS;
02037 }

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

Definition at line 2059 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.

02060 {
02061    switch (cmd) {
02062    case CLI_INIT:
02063       e->command = "core restart when convenient";
02064       e->usage = 
02065          "Usage: core restart when convenient\n"
02066          "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
02067       return NULL;
02068    case CLI_GENERATE:
02069       return NULL;
02070    }
02071 
02072    if (a->argc != e->args)
02073       return CLI_SHOWUSAGE;
02074    ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
02075    quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
02076    return CLI_SUCCESS;
02077 }

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

Definition at line 798 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.

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

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

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

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

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

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

Definition at line 515 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.

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

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

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

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

Definition at line 1979 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.

01980 {
01981    switch (cmd) {
01982    case CLI_INIT:
01983       e->command = "core stop gracefully";
01984       e->usage = 
01985          "Usage: core stop gracefully\n"
01986          "       Causes Asterisk to not accept new calls, and exit when all\n"
01987          "       active calls have terminated normally.\n";
01988       return NULL;
01989    case CLI_GENERATE:
01990       return NULL;
01991    }
01992 
01993    if (a->argc != e->args)
01994       return CLI_SHOWUSAGE;
01995    quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
01996    return CLI_SUCCESS;
01997 }

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

Definition at line 1960 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.

01961 {
01962    switch (cmd) {
01963    case CLI_INIT:
01964       e->command = "core stop now";
01965       e->usage = 
01966          "Usage: core stop now\n"
01967          "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
01968       return NULL;
01969    case CLI_GENERATE:
01970       return NULL;
01971    }
01972 
01973    if (a->argc != e->args)
01974       return CLI_SHOWUSAGE;
01975    quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
01976    return CLI_SUCCESS;
01977 }

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

Definition at line 1999 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.

02000 {
02001    switch (cmd) {
02002    case CLI_INIT:
02003       e->command = "core stop when convenient";
02004       e->usage = 
02005          "Usage: core stop when convenient\n"
02006          "       Causes Asterisk to perform a shutdown 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    ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
02015    quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
02016    return CLI_SUCCESS;
02017 }

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

Definition at line 1929 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.

01930 {
01931    switch (cmd) {
01932    case CLI_INIT:
01933       e->command = "core show version";
01934       e->usage = 
01935          "Usage: core show version\n"
01936          "       Shows Asterisk version information.\n";
01937       return NULL;
01938    case CLI_GENERATE:
01939       return NULL;
01940    }
01941 
01942    if (a->argc != 3)
01943       return CLI_SHOWUSAGE;
01944    ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
01945       ast_get_version(), ast_build_user, ast_build_hostname,
01946       ast_build_machine, ast_build_os, ast_build_date);
01947    return CLI_SUCCESS;
01948 }

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

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

01349 {
01350    struct sockaddr_un sunaddr;
01351    int s;
01352    socklen_t len;
01353    int x;
01354    int flags;
01355    struct pollfd fds[1];
01356    for (;;) {
01357       if (ast_socket < 0)
01358          return NULL;
01359       fds[0].fd = ast_socket;
01360       fds[0].events = POLLIN;
01361       s = ast_poll(fds, 1, -1);
01362       pthread_testcancel();
01363       if (s < 0) {
01364          if (errno != EINTR)
01365             ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
01366          continue;
01367       }
01368       len = sizeof(sunaddr);
01369       s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
01370       if (s < 0) {
01371          if (errno != EINTR)
01372             ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
01373       } else {
01374 #if !defined(SO_PASSCRED)
01375          {
01376 #else
01377          int sckopt = 1;
01378          /* turn on socket credentials passing. */
01379          if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
01380             ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
01381          } else {
01382 #endif
01383             for (x = 0; x < AST_MAX_CONNECTS; x++) {
01384                if (consoles[x].fd >= 0) {
01385                   continue;
01386                }
01387                if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
01388                   ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
01389                   consoles[x].fd = -1;
01390                   fdprint(s, "Server failed to create pipe\n");
01391                   close(s);
01392                   break;
01393                }
01394                flags = fcntl(consoles[x].p[1], F_GETFL);
01395                fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
01396                consoles[x].fd = s;
01397                consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
01398                /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
01399                   to know if the user didn't send the credentials. */
01400                consoles[x].uid = -2;
01401                consoles[x].gid = -2;
01402                if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
01403                   ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
01404                   close(consoles[x].p[0]);
01405                   close(consoles[x].p[1]);
01406                   consoles[x].fd = -1;
01407                   fdprint(s, "Server failed to spawn thread\n");
01408                   close(s);
01409                }
01410                break;
01411             }
01412             if (x >= AST_MAX_CONNECTS) {
01413                fdprint(s, "No more connections allowed\n");
01414                ast_log(LOG_WARNING, "No more connections allowed\n");
01415                close(s);
01416             } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
01417                ast_verb(3, "Remote UNIX connection\n");
01418             }
01419          }
01420       }
01421    }
01422    return NULL;
01423 }

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

Definition at line 3297 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.

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

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

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

03197 {
03198    for (;;) {
03199       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
03200       int a;
03201       ast_poll(&p, 1, -1);
03202       if (sig_flags.need_reload) {
03203          sig_flags.need_reload = 0;
03204          ast_module_reload(NULL);
03205       }
03206       if (sig_flags.need_quit) {
03207          sig_flags.need_quit = 0;
03208          if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
03209             sig_flags.need_quit_handler = 1;
03210             pthread_kill(consolethread, SIGURG);
03211          } else {
03212             quit_handler(0, SHUTDOWN_NORMAL, 0);
03213          }
03214       }
03215       if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
03216       }
03217    }
03218 
03219    return NULL;
03220 }

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

Definition at line 1260 of file asterisk.c.

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

Referenced by listener().

01261 {
01262    struct console *con = vconsole;
01263    char hostname[MAXHOSTNAMELEN] = "";
01264    char inbuf[512];
01265    char outbuf[512];
01266    const char * const end_buf = inbuf + sizeof(inbuf);
01267    char *start_read = inbuf;
01268    int res;
01269    struct pollfd fds[2];
01270 
01271    if (gethostname(hostname, sizeof(hostname)-1))
01272       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
01273    snprintf(outbuf, sizeof(outbuf), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
01274    fdprint(con->fd, outbuf);
01275    for (;;) {
01276       fds[0].fd = con->fd;
01277       fds[0].events = POLLIN;
01278       fds[0].revents = 0;
01279       fds[1].fd = con->p[0];
01280       fds[1].events = POLLIN;
01281       fds[1].revents = 0;
01282 
01283       res = ast_poll(fds, 2, -1);
01284       if (res < 0) {
01285          if (errno != EINTR)
01286             ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
01287          continue;
01288       }
01289       if (fds[0].revents) {
01290          int cmds_read, bytes_read;
01291          if ((bytes_read = read_credentials(con->fd, start_read, end_buf - start_read, con)) < 1) {
01292             break;
01293          }
01294          /* XXX This will only work if it is the first command, and I'm not sure fixing it is worth the effort. */
01295          if (strncmp(inbuf, "cli quit after ", 15) == 0) {
01296             ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read - 15, inbuf + 15);
01297             break;
01298          }
01299          /* ast_cli_command_multiple_full will only process individual commands terminated by a
01300           * NULL and not trailing partial commands. */
01301          if (!(cmds_read = ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read + start_read - inbuf, inbuf))) {
01302             /* No commands were read. We either have a short read on the first command
01303              * with space left, or a command that is too long */
01304             if (start_read + bytes_read < end_buf) {
01305                start_read += bytes_read;
01306             } else {
01307                ast_log(LOG_ERROR, "Command too long! Skipping\n");
01308                start_read = inbuf;
01309             }
01310             continue;
01311          }
01312          if (start_read[bytes_read - 1] == '\0') {
01313             /* The read ended on a command boundary, start reading again at the head of inbuf */
01314             start_read = inbuf;
01315             continue;
01316          }
01317          /* If we get this far, we have left over characters that have not been processed.
01318           * Advance to the character after the last command read by ast_cli_command_multiple_full.
01319           * We are guaranteed to have at least cmds_read NULLs */
01320          while (cmds_read-- && (start_read = strchr(start_read, '\0'))) {
01321             start_read++;
01322          }
01323          memmove(inbuf, start_read, end_buf - start_read);
01324          start_read = end_buf - start_read + inbuf;
01325       }
01326       if (fds[1].revents) {
01327          res = read_credentials(con->p[0], outbuf, sizeof(outbuf), con);
01328          if (res < 1) {
01329             ast_log(LOG_ERROR, "read returned %d\n", res);
01330             break;
01331          }
01332          res = write(con->fd, outbuf, res);
01333          if (res < 1)
01334             break;
01335       }
01336    }
01337    if (!ast_opt_hide_connect) {
01338       ast_verb(3, "Remote UNIX connection disconnected\n");
01339    }
01340    close(con->fd);
01341    close(con->p[0]);
01342    close(con->p[1]);
01343    con->fd = -1;
01344    
01345    return NULL;
01346 }

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

Definition at line 1194 of file asterisk.c.

References __LOG_VERBOSE, and ast_network_puts_mutable().

Referenced by ast_makesocket().

01195 {
01196    ast_network_puts_mutable(s, __LOG_VERBOSE);
01197 }

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

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

01664 {
01665    if (can_safely_quit(niceness, restart)) {
01666       really_quit(num, niceness, restart);
01667       /* No one gets here. */
01668    }
01669    /* It wasn't our time. */
01670 }

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 763 of file asterisk.c.

Referenced by ast_mark().

00764 {
00765    return 0;
00766 }

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

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

Referenced by netconsole().

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

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

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

01739 {
01740    if (niceness >= SHUTDOWN_NICE) {
01741       ast_module_shutdown();
01742    }
01743 
01744    if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
01745       char filename[80] = "";
01746       if (getenv("HOME")) {
01747          snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
01748       }
01749       if (!ast_strlen_zero(filename)) {
01750          ast_el_write_history(filename);
01751       }
01752       if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
01753          /* Only end if we are the consolethread, otherwise there's a race with that thread. */
01754          if (el != NULL) {
01755             el_end(el);
01756          }
01757          if (el_hist != NULL) {
01758             history_end(el_hist);
01759          }
01760       } else if (mon_sig_flags == pthread_self()) {
01761          if (consolethread != AST_PTHREADT_NULL) {
01762             pthread_kill(consolethread, SIGURG);
01763          }
01764       }
01765    }
01766    if (option_verbose)
01767       ast_verbose("Executing last minute cleanups\n");
01768    ast_run_atexits();
01769    /* Called on exit */
01770    if (option_verbose && ast_opt_console)
01771       ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
01772    ast_debug(1, "Asterisk ending (%d).\n", num);
01773    manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
01774    if (ast_socket > -1) {
01775       pthread_cancel(lthread);
01776       close(ast_socket);
01777       ast_socket = -1;
01778       unlink(ast_config_AST_SOCKET);
01779    }
01780    if (ast_consock > -1)
01781       close(ast_consock);
01782    if (!ast_opt_remote)
01783       unlink(ast_config_AST_PID);
01784    printf("%s", term_quit());
01785    if (restart) {
01786       int i;
01787       if (option_verbose || ast_opt_console)
01788          ast_verbose("Preparing for Asterisk restart...\n");
01789       /* Mark all FD's for closing on exec */
01790       for (i = 3; i < 32768; i++) {
01791          fcntl(i, F_SETFD, FD_CLOEXEC);
01792       }
01793       if (option_verbose || ast_opt_console)
01794          ast_verbose("Asterisk is now restarting...\n");
01795       restartnow = 1;
01796 
01797       /* close logger */
01798       close_logger();
01799 
01800       /* If there is a consolethread running send it a SIGHUP 
01801          so it can execvp, otherwise we can do it ourselves */
01802       if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
01803          pthread_kill(consolethread, SIGHUP);
01804          /* Give the signal handler some time to complete */
01805          sleep(2);
01806       } else
01807          execvp(_argv[0], _argv);
01808    
01809    } else {
01810       /* close logger */
01811       close_logger();
01812    }
01813 
01814    exit(0);
01815 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1905 of file asterisk.c.

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

Referenced by ast_remotecontrol().

01906 {
01907    int ret = 0;
01908 
01909    /* Called when readline data is available */
01910    if (!ast_all_zeros(s))
01911       ast_el_add_history(s);
01912    /* The real handler for bang */
01913    if (s[0] == '!') {
01914       if (s[1])
01915          ast_safe_system(s+1);
01916       else
01917          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01918       ret = 1;
01919    }
01920    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
01921        (s[4] == '\0' || isspace(s[4]))) {
01922       quit_handler(0, SHUTDOWN_FAST, 0);
01923       ret = 1;
01924    }
01925 
01926    return ret;
01927 }

static void run_startup_commands ( void   )  [static]

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

03258 {
03259    int fd;
03260    struct ast_config *cfg;
03261    struct ast_flags cfg_flags = { 0 };
03262    struct ast_variable *v;
03263 
03264    if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
03265       return;
03266    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03267       return;
03268    }
03269 
03270    fd = open("/dev/null", O_RDWR);
03271    if (fd < 0) {
03272       ast_config_destroy(cfg);
03273       return;
03274    }
03275 
03276    for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
03277       if (ast_true(v->value))
03278          ast_cli_command(fd, v->name);
03279    }
03280 
03281    close(fd);
03282    ast_config_destroy(cfg);
03283 }

static void set_icon ( char *  text  )  [static]

Definition at line 1607 of file asterisk.c.

Referenced by main().

01608 {
01609    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01610       fprintf(stdout, "\033]1;%s\007", text);
01611 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1601 of file asterisk.c.

Referenced by main().

01602 {
01603    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01604       fprintf(stdout, "\033]2;%s\007", text);
01605 }

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1578 of file asterisk.c.

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

01579 {
01580    struct rlimit l = {0, 0};
01581    
01582    if (value <= 0) {
01583       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01584       return;
01585    }
01586    
01587    l.rlim_cur = value;
01588    l.rlim_max = value;
01589    
01590    if (setrlimit(RLIMIT_NOFILE, &l)) {
01591       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01592       return;
01593    }
01594    
01595    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01596    
01597    return;
01598 }

static int show_cli_help ( void   )  [static]

Definition at line 2919 of file asterisk.c.

References ast_get_version().

Referenced by main().

02920 {
02921    printf("Asterisk %s, Copyright (C) 1999 - 2012, Digium, Inc. and others.\n", ast_get_version());
02922    printf("Usage: asterisk [OPTIONS]\n");
02923    printf("Valid Options:\n");
02924    printf("   -V              Display version number and exit\n");
02925    printf("   -C <configfile> Use an alternate configuration file\n");
02926    printf("   -G <group>      Run as a group other than the caller\n");
02927    printf("   -U <user>       Run as a user other than the caller\n");
02928    printf("   -c              Provide console CLI\n");
02929    printf("   -d              Enable extra debugging\n");
02930 #if HAVE_WORKING_FORK
02931    printf("   -f              Do not fork\n");
02932    printf("   -F              Always fork\n");
02933 #endif
02934    printf("   -g              Dump core in case of a crash\n");
02935    printf("   -h              This help screen\n");
02936    printf("   -i              Initialize crypto keys at startup\n");
02937    printf("   -I              Enable internal timing if DAHDI timer is available\n");
02938    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
02939    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
02940    printf("   -m              Mute debugging and console output on the console\n");
02941    printf("   -n              Disable console colorization\n");
02942    printf("   -p              Run as pseudo-realtime thread\n");
02943    printf("   -q              Quiet mode (suppress output)\n");
02944    printf("   -r              Connect to Asterisk on this machine\n");
02945    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
02946    printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
02947    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
02948    printf("                   belong after they are done\n");
02949    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
02950    printf("                   of output to the CLI\n");
02951    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
02952    printf("   -x <cmd>        Execute command <cmd> (implies -r)\n");
02953    printf("   -X              Execute includes by default (allows #exec in asterisk.conf)\n");
02954    printf("   -W              Adjust terminal colors to compensate for a light background\n");
02955    printf("\n");
02956    return 0;
02957 }

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

Definition at line 2188 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.

02189 {
02190    switch (cmd) {
02191    case CLI_INIT:
02192       e->command = "core show license";
02193       e->usage = 
02194          "Usage: core show license\n"
02195          "       Shows the license(s) for this copy of Asterisk.\n";
02196       return NULL;
02197    case CLI_GENERATE:
02198       return NULL;
02199    }
02200 
02201    ast_cli(a->fd, "%s", license_lines);
02202 
02203    return CLI_SUCCESS;
02204 }

static int show_version ( void   )  [static]

Definition at line 2913 of file asterisk.c.

References ast_get_version().

Referenced by main().

02914 {
02915    printf("Asterisk %s\n", ast_get_version());
02916    return 0;
02917 }

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

Definition at line 2151 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.

02152 {
02153    switch (cmd) {
02154    case CLI_INIT:
02155       e->command = "core show warranty";
02156       e->usage = 
02157          "Usage: core show warranty\n"
02158          "       Shows the warranty (if any) for this copy of Asterisk.\n";
02159       return NULL;
02160    case CLI_GENERATE:
02161       return NULL;
02162    }
02163 
02164    ast_cli(a->fd, "%s", warranty_lines);
02165 
02166    return CLI_SUCCESS;
02167 }


Variable Documentation

char* _argv[256] [static]

Definition at line 281 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 263 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 255 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 256 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 277 of file asterisk.c.

Referenced by ast_readconfig().

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

Definition at line 276 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

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

Definition at line 275 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static]

Definition at line 274 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 261 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 267 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 264 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 262 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 257 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 259 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 268 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 265 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 271 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 270 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 269 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 258 of file asterisk.c.

Referenced by app_exec(), conf_run(), dictate_exec(), filename_parse(), 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 272 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 260 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 198 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 192 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 218 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 199 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 197 of file asterisk.c.

struct timeval ast_startuptime

Definition at line 217 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 296 of file asterisk.c.

Referenced by canary_thread(), and main().

int canary_pid = 0 [static]

Definition at line 295 of file asterisk.c.

Referenced by canary_exit(), and main().

struct _cfg_paths cfg_paths [static]

Definition at line 253 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 1572 of file asterisk.c.

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 2210 of file asterisk.c.

Referenced by main().

struct console consoles[AST_MAX_CONNECTS]

Definition at line 224 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 293 of file asterisk.c.

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

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 226 of file asterisk.c.

Referenced by __ast_channel_alloc_ap(), and handle_show_settings().

EditLine* el [static]

Definition at line 221 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 220 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 1552 of file asterisk.c.

struct sigaction ignore_sig_handler [static]

Initial value:

 {
   .sa_handler = SIG_IGN,
}

Definition at line 1002 of file asterisk.c.

const char license_lines[] [static]

Definition at line 2169 of file asterisk.c.

pthread_t lthread [static]

Definition at line 1199 of file asterisk.c.

Referenced by ast_makesocket(), and really_quit().

pthread_t mon_sig_flags [static]

Definition at line 294 of file asterisk.c.

Referenced by main(), and really_quit().

unsigned int need_quit

Definition at line 303 of file asterisk.c.

unsigned int need_quit_handler

Definition at line 304 of file asterisk.c.

unsigned int need_reload

Definition at line 302 of file asterisk.c.

struct sigaction null_sig_handler [static]

Initial value:

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

Definition at line 997 of file asterisk.c.

struct profile_data* prof_data [static]

Definition at line 699 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 2333 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 298 of file asterisk.c.

Referenced by main().

char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR

Definition at line 195 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 222 of file asterisk.c.

Referenced by ast_remotecontrol(), and cli_prompt().

int restartnow [static]

Definition at line 292 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 1009 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 1006 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 1010 of file asterisk.c.

shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN [static]

Definition at line 291 of file asterisk.c.

Referenced by can_safely_quit(), and handle_abort_shutdown().

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

Definition at line 300 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 1531 of file asterisk.c.

const char warranty_lines[] [static]

Definition at line 2126 of file asterisk.c.


Generated on Mon Oct 8 12:39:11 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7