Thu Oct 11 06:34:42 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 <regex.h>
#include <histedit.h>
#include "asterisk/paths.h"
#include "asterisk/network.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/translate.h"
#include "asterisk/features.h"
#include "asterisk/acl.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/presencestate.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/rtp_engine.h"
#include "asterisk/format.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  el_read_char_state_struct
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 AST_MIN_DTMF_DURATION   80
#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 VERBOSE_HASMAGIC(x)   (*(signed char *) (x) < 0)
#define VERBOSE_MAGIC2LEVEL(x)   (((char) -*(signed char *) (x)) - 1)
#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 __fini_atexits (void)
static void __fini_file_versions (void)
static void __fini_thread_list (void)
static void __init_atexits (void)
static void __init_el_read_char_state (void)
static void __init_file_versions (void)
static void __init_thread_list (void)
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)
 allocates a counter with a given name and scale.
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)
 write the string to the console, and all attached console clients
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)
 enable or disable a logging level to a specified console
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 int el_read_char_state_init (void *ptr)
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_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]
struct 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_SBIN_DIR = cfg_paths.sbin_dir
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
struct ast_eid ast_eid_default
 Global EID.
unsigned int ast_FD_SETSIZE
struct timeval ast_lastreloadtime
pid_t ast_mainpid
struct ast_flags ast_options = { AST_DEFAULT_OPTIONS }
static int ast_socket = -1
struct 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 []
struct 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 ast_threadstorage el_read_char_state = { .once = PTHREAD_ONCE_INIT , .key_init = __init_el_read_char_state , .custom_init = el_read_char_state_init , }
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
unsigned int option_dtmfminduration
int option_maxcalls
int option_maxfiles
double option_maxload
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_MUTEX_INITIALIZER , 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 247 of file asterisk.c.

#define AST_MAX_CONNECTS   128

#define AST_MIN_DTMF_DURATION   80

Default minimum DTMF digit length - 80ms

Definition at line 255 of file asterisk.c.

Referenced by ast_readconfig().

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 2370 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 2372 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

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

Referenced by ast_el_add_history().

#define NUM_MSGS   64

Definition at line 252 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

Definition at line 248 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define VERBOSE_HASMAGIC (  )     (*(signed char *) (x) < 0)

Definition at line 1980 of file asterisk.c.

Referenced by ast_el_read_char(), and console_verboser().

#define VERBOSE_MAGIC2LEVEL (  )     (((char) -*(signed char *) (x)) - 1)

Definition at line 1979 of file asterisk.c.

Referenced by ast_el_read_char(), console_verboser(), and logger_print_normal().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 259 of file asterisk.c.

Referenced by ast_el_read_char(), and main().


Enumeration Type Documentation

Enumerator:
NOT_SHUTTING_DOWN 
SHUTTING_DOWN 
SHUTDOWN_FAST 
SHUTDOWN_NORMAL 
SHUTDOWN_NICE 
SHUTDOWN_REALLY_NICE 

Definition at line 382 of file asterisk.c.

00382              {
00383    NOT_SHUTTING_DOWN = -2,
00384    SHUTTING_DOWN = -1,
00385    /* Valid values for quit_handler niceness below: */
00386    SHUTDOWN_FAST,
00387    SHUTDOWN_NORMAL,
00388    SHUTDOWN_NICE,
00389    SHUTDOWN_REALLY_NICE
00390 } shutdown_nice_t;


Function Documentation

static void __fini_atexits ( void   )  [static]

Definition at line 313 of file asterisk.c.

00330 {

static void __fini_file_versions ( void   )  [static]

Definition at line 414 of file asterisk.c.

00417 {

static void __fini_thread_list ( void   )  [static]

Definition at line 496 of file asterisk.c.

00499 {

static void __init_atexits ( void   )  [static]

Definition at line 313 of file asterisk.c.

00330 {

static void __init_el_read_char_state ( void   )  [static]

Definition at line 2413 of file asterisk.c.

02416 {

static void __init_file_versions ( void   )  [static]

Definition at line 414 of file asterisk.c.

00417 {

static void __init_thread_list ( void   )  [static]

Definition at line 496 of file asterisk.c.

00499 {

static void __quit_handler ( int  num  )  [static]

Definition at line 1946 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

01947 {
01948    int a = 0;
01949    sig_flags.need_quit = 1;
01950    if (sig_alert_pipe[1] != -1) {
01951       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01952          fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
01953       }
01954    }
01955    /* There is no need to restore the signal handler here, since the app
01956     * is going to exit */
01957 }

static void __remote_quit_handler ( int  num  )  [static]

Definition at line 1959 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

01960 {
01961    sig_flags.need_quit = 1;
01962 }

static void _child_handler ( int  sig  )  [static]

Definition at line 1658 of file asterisk.c.

References errno, and status.

01659 {
01660    /* Must not ever ast_log or ast_verbose within signal handler */
01661    int n, status, save_errno = errno;
01662 
01663    /*
01664     * Reap all dead children -- not just one
01665     */
01666    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01667       ;
01668    if (n == 0 && option_debug)
01669       printf("Huh?  Child handler, but nobody there?\n");
01670    errno = save_errno;
01671 }

static void _hup_handler ( int  num  )  [static]

Definition at line 1638 of file asterisk.c.

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

01639 {
01640    int a = 0, save_errno = errno;
01641    printf("Received HUP signal -- Reloading configs\n");
01642    if (restartnow)
01643       execvp(_argv[0], _argv);
01644    sig_flags.need_reload = 1;
01645    if (sig_alert_pipe[1] != -1) {
01646       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01647          fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
01648       }
01649    }
01650    errno = save_errno;
01651 }

static void _null_sig_handler ( int  sig  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 1094 of file asterisk.c.

01095 {
01096 }

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

01629 {
01630    return;
01631 }

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

allocates a counter with a given name and scale.

support for event profiling

Returns:
Returns the identifier of the counter.

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

00806 {
00807    int l = sizeof(struct profile_data);
00808    int n = 10; /* default entries */
00809 
00810    if (prof_data == NULL) {
00811       prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
00812       if (prof_data == NULL)
00813          return -1;
00814       prof_data->entries = 0;
00815       prof_data->max_size = n;
00816    }
00817    if (prof_data->entries >= prof_data->max_size) {
00818       void *p;
00819       n = prof_data->max_size + 20;
00820       p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
00821       if (p == NULL)
00822          return -1;
00823       prof_data = p;
00824       prof_data->max_size = n;
00825    }
00826    n = prof_data->entries++;
00827    prof_data->e[n].name = ast_strdup(name);
00828    prof_data->e[n].value = 0;
00829    prof_data->e[n].events = 0;
00830    prof_data->e[n].mark = 0;
00831    prof_data->e[n].scale = scale;
00832    return n;
00833 }

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 2014 of file asterisk.c.

Referenced by consolehandler(), and remoteconsolehandler().

02015 {
02016    while (*s) {
02017       if (*s > 32)
02018          return 0;
02019       s++;
02020    }
02021    return 1;
02022 }

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

Definition at line 2717 of file asterisk.c.

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

Referenced by cli_complete().

02718 {
02719    int i, idx, limit, count;
02720    int screenwidth = 0;
02721    int numoutput = 0, numoutputline = 0;
02722 
02723    screenwidth = ast_get_termcols(STDOUT_FILENO);
02724 
02725    /* find out how many entries can be put on one line, with two spaces between strings */
02726    limit = screenwidth / (max + 2);
02727    if (limit == 0)
02728       limit = 1;
02729 
02730    /* how many lines of output */
02731    count = len / limit;
02732    if (count * limit < len)
02733       count++;
02734 
02735    idx = 1;
02736 
02737    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
02738 
02739    for (; count > 0; count--) {
02740       numoutputline = 0;
02741       for (i = 0; i < limit && matches[idx]; i++, idx++) {
02742 
02743          /* Don't print dupes */
02744          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
02745             i--;
02746             ast_free(matches[idx]);
02747             matches[idx] = NULL;
02748             continue;
02749          }
02750 
02751          numoutput++;
02752          numoutputline++;
02753          fprintf(stdout, "%-*s  ", max, matches[idx]);
02754          ast_free(matches[idx]);
02755          matches[idx] = NULL;
02756       }
02757       if (numoutputline > 0)
02758          fprintf(stdout, "\n");
02759    }
02760 
02761    return numoutput;
02762 }

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

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

00456 {
00457    struct file_version *find;
00458    size_t len = strlen(partial);
00459    int count = 0;
00460    char *res = NULL;
00461 
00462    AST_RWLIST_RDLOCK(&file_versions);
00463    AST_RWLIST_TRAVERSE(&file_versions, find, list) {
00464       if (!strncasecmp(find->file, partial, len) && ++count > n) {
00465          res = ast_strdup(find->file);
00466          break;
00467       }
00468    }
00469    AST_RWLIST_UNLOCK(&file_versions);
00470    return res;
00471 }

void ast_console_puts ( const char *  string  ) 

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

Definition at line 1289 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

01290 {
01291    fputs(string, stdout);
01292    fflush(stdout);
01293    ast_network_puts(string);
01294 }

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

References ast_network_puts_mutable().

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

01267 {
01268    fputs(string, stdout);
01269    fflush(stdout);
01270    ast_network_puts_mutable(string, level);
01271 }

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

enable or disable a logging level to a specified console

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

References AST_MAX_CONNECTS, consoles, console::levels, and NUMLOGLEVELS.

Referenced by handle_logger_set_level().

01204 {
01205    int x;
01206 
01207    if (level >= NUMLOGLEVELS) {
01208       level = NUMLOGLEVELS - 1;
01209    }
01210 
01211    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01212       if (fd == consoles[x].fd) {
01213          /*
01214           * Since the logging occurs when levels are false, set to
01215           * flipped iinput because this function accepts 0 as off and 1 as on
01216           */
01217          consoles[x].levels[level] = state ? 0 : 1;
01218          return;
01219       }
01220    }
01221 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1226 of file asterisk.c.

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

Referenced by handle_logger_mute().

01227 {
01228    int x;
01229    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01230       if (fd == consoles[x].fd) {
01231          if (consoles[x].mute) {
01232             consoles[x].mute = 0;
01233             if (!silent)
01234                ast_cli(fd, "Console is not muted anymore.\n");
01235          } else {
01236             consoles[x].mute = 1;
01237             if (!silent)
01238                ast_cli(fd, "Console is muted.\n");
01239          }
01240          return;
01241       }
01242    }
01243    ast_cli(fd, "Couldn't find remote console.\n");
01244 }

static int ast_el_add_history ( char *  buf  )  [static]

Definition at line 2940 of file asterisk.c.

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

Referenced by consolehandler(), and remoteconsolehandler().

02941 {
02942    HistEvent ev;
02943 
02944    if (el_hist == NULL || el == NULL)
02945       ast_el_initialize();
02946    if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1))
02947       return 0;
02948    return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf))));
02949 }

static int ast_el_initialize ( void   )  [static]

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

02886 {
02887    HistEvent ev;
02888    char *editor, *editrc = getenv("EDITRC");
02889 
02890    if (!(editor = getenv("AST_EDITMODE"))) {
02891       if (!(editor = getenv("AST_EDITOR"))) {
02892          editor = "emacs";
02893       }
02894    }
02895 
02896    if (el != NULL)
02897       el_end(el);
02898    if (el_hist != NULL)
02899       history_end(el_hist);
02900 
02901    el = el_init("asterisk", stdin, stdout, stderr);
02902    el_set(el, EL_PROMPT, cli_prompt);
02903 
02904    el_set(el, EL_EDITMODE, 1);
02905    el_set(el, EL_EDITOR, editor);
02906    el_hist = history_init();
02907    if (!el || !el_hist)
02908       return -1;
02909 
02910    /* setup history with 100 entries */
02911    history(el_hist, &ev, H_SETSIZE, 100);
02912 
02913    el_set(el, EL_HIST, history, el_hist);
02914 
02915    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02916    /* Bind <tab> to command completion */
02917    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02918    /* Bind ? to command completion */
02919    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02920    /* Bind ^D to redisplay */
02921    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02922    /* Bind Delete to delete char left */
02923    el_set(el, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
02924    /* Bind Home and End to move to line start and end */
02925    el_set(el, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
02926    el_set(el, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
02927    /* Bind C-left and C-right to move by word (not all terminals) */
02928    el_set(el, EL_BIND, "\\eOC", "vi-next-word", NULL);
02929    el_set(el, EL_BIND, "\\eOD", "vi-prev-word", NULL);
02930 
02931    if (editrc) {
02932       el_source(el, editrc);
02933    }
02934 
02935    return 0;
02936 }

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

Definition at line 2415 of file asterisk.c.

References ast_log(), ast_opt_exec, ast_opt_mute, ast_opt_reconnect, ast_poll, ast_strlen_zero(), ast_threadstorage_get(), ast_tryconnect(), EL_BUF_SIZE, el_read_char_state, errno, fdsend(), el_read_char_state_struct::line_full, LOG_ERROR, el_read_char_state_struct::prev_line_full, el_read_char_state_struct::prev_line_verbosity, quit_handler(), SHUTDOWN_FAST, sig_flags, term_quit(), VERBOSE_HASMAGIC, VERBOSE_MAGIC2LEVEL, and WELCOME_MESSAGE.

Referenced by ast_remotecontrol(), and main().

02416 {
02417    int num_read = 0;
02418    int lastpos = 0;
02419    struct pollfd fds[2];
02420    int res;
02421    int max;
02422 #define EL_BUF_SIZE 512
02423    char buf[EL_BUF_SIZE];
02424    struct el_read_char_state_struct *state = ast_threadstorage_get(&el_read_char_state, sizeof(*state));
02425 
02426    for (;;) {
02427       max = 1;
02428       fds[0].fd = ast_consock;
02429       fds[0].events = POLLIN;
02430       if (!ast_opt_exec) {
02431          fds[1].fd = STDIN_FILENO;
02432          fds[1].events = POLLIN;
02433          max++;
02434       }
02435       res = ast_poll(fds, max, -1);
02436       if (res < 0) {
02437          if (sig_flags.need_quit || sig_flags.need_quit_handler)
02438             break;
02439          if (errno == EINTR)
02440             continue;
02441          ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
02442          break;
02443       }
02444 
02445       if (!ast_opt_exec && fds[1].revents) {
02446          num_read = read(STDIN_FILENO, cp, 1);
02447          if (num_read < 1) {
02448             break;
02449          } else {
02450             return (num_read);
02451          }
02452       }
02453       if (fds[0].revents) {
02454          char level = 0;
02455          char *curline = buf, *nextline;
02456          res = read(ast_consock, buf, sizeof(buf) - 1);
02457          /* if the remote side disappears exit */
02458          if (res < 1) {
02459             fprintf(stderr, "\nDisconnected from Asterisk server\n");
02460             if (!ast_opt_reconnect) {
02461                quit_handler(0, SHUTDOWN_FAST, 0);
02462             } else {
02463                int tries;
02464                int reconnects_per_second = 20;
02465                fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
02466                for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
02467                   if (ast_tryconnect()) {
02468                      fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
02469                      printf("%s", term_quit());
02470                      WELCOME_MESSAGE;
02471                      if (!ast_opt_mute)
02472                         fdsend(ast_consock, "logger mute silent");
02473                      else
02474                         printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02475                      break;
02476                   } else
02477                      usleep(1000000 / reconnects_per_second);
02478                }
02479                if (tries >= 30 * reconnects_per_second) {
02480                   fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
02481                   quit_handler(0, SHUTDOWN_FAST, 0);
02482                }
02483             }
02484             continue;
02485          }
02486 
02487          buf[res] = '\0';
02488 
02489          /* Write over the CLI prompt */
02490          if (!ast_opt_exec && !lastpos) {
02491             if (write(STDOUT_FILENO, "\r", 5) < 0) {
02492             }
02493          }
02494 
02495          do {
02496             state->prev_line_full = state->line_full;
02497             if ((nextline = strchr(curline, '\n'))) {
02498                state->line_full = 1;
02499                nextline++;
02500             } else {
02501                state->line_full = 0;
02502                nextline = strchr(curline, '\0');
02503             }
02504 
02505             if (state->prev_line_full && VERBOSE_HASMAGIC(curline)) {
02506                level = VERBOSE_MAGIC2LEVEL(curline);
02507                curline++;
02508             } else if (state->prev_line_full && !VERBOSE_HASMAGIC(curline)) {
02509                /* Non-verbose output */
02510                level = 0;
02511             } else {
02512                level = state->prev_line_verbosity;
02513             }
02514             if ((!state->prev_line_full && state->prev_line_verbosity <= option_verbose) || (state->prev_line_full && level <= option_verbose)) {
02515                if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
02516                }
02517             }
02518 
02519             state->prev_line_verbosity = level;
02520             curline = nextline;
02521          } while (!ast_strlen_zero(curline));
02522 
02523          if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
02524             *cp = CC_REFRESH;
02525             return(1);
02526          } else
02527             lastpos = 1;
02528       }
02529    }
02530 
02531    *cp = '\0';
02532    return (0);
02533 }

static int ast_el_read_history ( char *  filename  )  [static]

Definition at line 2961 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by ast_remotecontrol(), and main().

02962 {
02963    HistEvent ev;
02964 
02965    if (el_hist == NULL || el == NULL) {
02966       ast_el_initialize();
02967    }
02968 
02969    return history(el_hist, &ev, H_LOAD, filename);
02970 }

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

Definition at line 2707 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02708 {
02709    char *s1, *s2;
02710 
02711    s1 = ((char **)i1)[0];
02712    s2 = ((char **)i2)[0];
02713 
02714    return strcasecmp(s1, s2);
02715 }

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

Definition at line 2664 of file asterisk.c.

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

Referenced by cli_complete().

02665 {
02666    char **match_list = NULL, **match_list_tmp, *retstr;
02667    size_t match_list_len;
02668    int matches = 0;
02669 
02670    match_list_len = 1;
02671    while ( (retstr = strsep(&buf, " ")) != NULL) {
02672 
02673       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
02674          break;
02675       if (matches + 1 >= match_list_len) {
02676          match_list_len <<= 1;
02677          if ((match_list_tmp = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
02678             match_list = match_list_tmp;
02679          } else {
02680             if (match_list)
02681                ast_free(match_list);
02682             return (char **) NULL;
02683          }
02684       }
02685 
02686       match_list[matches++] = ast_strdup(retstr);
02687    }
02688 
02689    if (!match_list)
02690       return (char **) NULL;
02691 
02692    if (matches >= match_list_len) {
02693       if ((match_list_tmp = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
02694          match_list = match_list_tmp;
02695       } else {
02696          if (match_list)
02697             ast_free(match_list);
02698          return (char **) NULL;
02699       }
02700    }
02701 
02702    match_list[matches] = (char *) NULL;
02703 
02704    return match_list;
02705 }

static int ast_el_write_history ( char *  filename  )  [static]

Definition at line 2951 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by really_quit().

02952 {
02953    HistEvent ev;
02954 
02955    if (el_hist == NULL || el == NULL)
02956       ast_el_initialize();
02957 
02958    return (history(el_hist, &ev, H_SAVE, filename));
02959 }

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

00475 {
00476    struct file_version *iterator;
00477 
00478    AST_RWLIST_WRLOCK(&file_versions);
00479    AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
00480       if (!strcasecmp(iterator->file, file))
00481          break;
00482    }
00483    AST_RWLIST_UNLOCK(&file_versions);
00484    if (iterator)
00485       return iterator->version;
00486    return NULL;
00487 }

static int ast_makesocket ( void   )  [static]

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

01528 {
01529    struct sockaddr_un sunaddr;
01530    int res;
01531    int x;
01532    uid_t uid = -1;
01533    gid_t gid = -1;
01534 
01535    for (x = 0; x < AST_MAX_CONNECTS; x++)
01536       consoles[x].fd = -1;
01537    unlink(ast_config_AST_SOCKET);
01538    ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
01539    if (ast_socket < 0) {
01540       ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
01541       return -1;
01542    }
01543    memset(&sunaddr, 0, sizeof(sunaddr));
01544    sunaddr.sun_family = AF_LOCAL;
01545    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01546    res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01547    if (res) {
01548       ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01549       close(ast_socket);
01550       ast_socket = -1;
01551       return -1;
01552    }
01553    res = listen(ast_socket, 2);
01554    if (res < 0) {
01555       ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01556       close(ast_socket);
01557       ast_socket = -1;
01558       return -1;
01559    }
01560    if (ast_register_verbose(network_verboser)) {
01561       ast_log(LOG_WARNING, "Unable to register network verboser?\n");
01562    }
01563 
01564    if (ast_pthread_create_background(&lthread, NULL, listener, NULL)) {
01565       ast_log(LOG_WARNING, "Unable to create listener thread.\n");
01566       close(ast_socket);
01567       return -1;
01568    }
01569 
01570    if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
01571       struct passwd *pw;
01572       if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
01573          ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
01574       else
01575          uid = pw->pw_uid;
01576    }
01577 
01578    if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
01579       struct group *grp;
01580       if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
01581          ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
01582       else
01583          gid = grp->gr_gid;
01584    }
01585 
01586    if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
01587       ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01588 
01589    if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
01590       int p1;
01591       mode_t p;
01592       sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
01593       p = p1;
01594       if ((chmod(ast_config_AST_SOCKET, p)) < 0)
01595          ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01596    }
01597 
01598    return 0;
01599 }

int64_t ast_mark ( int  i,
int  startstop 
)

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

00871 {
00872    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00873       return 0;
00874    if (startstop == 1)
00875       prof_data->e[i].mark = rdtsc();
00876    else {
00877       prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
00878       if (prof_data->e[i].scale > 1)
00879          prof_data->e[i].mark /= prof_data->e[i].scale;
00880       prof_data->e[i].value += prof_data->e[i].mark;
00881       prof_data->e[i].events++;
00882    }
00883    return prof_data->e[i].mark;
00884 }

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

write the string to all attached console clients

Definition at line 1276 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

01277 {
01278    int x;
01279    for (x = 0; x < AST_MAX_CONNECTS; x++) {
01280       if (consoles[x].fd > -1)
01281          fdprint(consoles[x].p[1], string);
01282    }
01283 }

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

log the string to all attached console clients

Definition at line 1249 of file asterisk.c.

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

Referenced by ast_console_puts_mutable(), and network_verboser().

01250 {
01251    int x;
01252    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01253       if (consoles[x].mute)
01254          continue;
01255       if (consoles[x].fd > -1) {
01256          if (!consoles[x].levels[level])
01257             fdprint(consoles[x].p[1], string);
01258       }
01259    }
01260 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 835 of file asterisk.c.

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

00836 {
00837    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00838       return 0;
00839    if (prof_data->e[i].scale > 1)
00840       delta /= prof_data->e[i].scale;
00841    prof_data->e[i].value += delta;
00842    prof_data->e[i].events++;
00843    return prof_data->e[i].value;
00844 }

static void ast_readconfig ( void   )  [static]

Definition at line 3169 of file asterisk.c.

References _cfg_paths::agi_dir, AST_CACHE_DIR_LEN, ast_clear_flag, AST_COMPAT_APP_SET, AST_COMPAT_DELIM_PBX_REALTIME, AST_COMPAT_DELIM_RES_AGI, 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_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_eid_default, ast_language_is_prefix, AST_LOCK_TYPE_FLOCK, AST_LOCK_TYPE_LOCKFILE, ast_log(), AST_MIN_DTMF_DURATION, AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DONT_WARN, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND, AST_OPT_FLAG_HIDE_CONSOLE_CONNECT, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_LIGHT_BACKGROUND, AST_OPT_FLAG_LOCK_CONFIG_DIR, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_STDEXTEN_MACRO, AST_OPT_FLAG_TIMESTAMP, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_opt_override_config, ast_set2_flag, ast_set_default_eid(), ast_set_flag, ast_set_lock_type(), ast_str_to_eid(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_verbose, 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, defaultlanguage, getloadavg(), hostname, _cfg_paths::key_dir, _cfg_paths::log_dir, LOG_ERROR, LOG_WARNING, MAX_LANGUAGE, 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::run_group, _cfg_paths::run_user, _cfg_paths::sbin_dir, set_ulimit(), _cfg_paths::socket_path, _cfg_paths::spool_dir, _cfg_paths::system_name, ast_variable::value, _cfg_paths::var_dir, and version.

Referenced by main().

03170 {
03171    struct ast_config *cfg;
03172    struct ast_variable *v;
03173    char *config = DEFAULT_CONFIG_FILE;
03174    char hostname[MAXHOSTNAMELEN] = "";
03175    struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME };
03176    struct {
03177       unsigned int dbdir:1;
03178       unsigned int keydir:1;
03179    } found = { 0, 0 };
03180 
03181    /* Set default value */
03182    option_dtmfminduration = AST_MIN_DTMF_DURATION;
03183 
03184    if (ast_opt_override_config) {
03185       cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
03186       if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
03187          ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
03188    } else
03189       cfg = ast_config_load2(config, "" /* core, can't reload */, config_flags);
03190 
03191    /* init with buildtime config */
03192    ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir));
03193    ast_copy_string(cfg_paths.spool_dir, DEFAULT_SPOOL_DIR, sizeof(cfg_paths.spool_dir));
03194    ast_copy_string(cfg_paths.module_dir, DEFAULT_MODULE_DIR, sizeof(cfg_paths.module_dir));
03195    snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", cfg_paths.spool_dir);
03196    ast_copy_string(cfg_paths.var_dir, DEFAULT_VAR_DIR, sizeof(cfg_paths.var_dir));
03197    ast_copy_string(cfg_paths.data_dir, DEFAULT_DATA_DIR, sizeof(cfg_paths.data_dir));
03198    ast_copy_string(cfg_paths.log_dir, DEFAULT_LOG_DIR, sizeof(cfg_paths.log_dir));
03199    ast_copy_string(cfg_paths.agi_dir, DEFAULT_AGI_DIR, sizeof(cfg_paths.agi_dir));
03200    ast_copy_string(cfg_paths.db_path, DEFAULT_DB, sizeof(cfg_paths.db_path));
03201    ast_copy_string(cfg_paths.sbin_dir, DEFAULT_SBIN_DIR, sizeof(cfg_paths.sbin_dir));
03202    ast_copy_string(cfg_paths.key_dir, DEFAULT_KEY_DIR, sizeof(cfg_paths.key_dir));
03203    ast_copy_string(cfg_paths.pid_path, DEFAULT_PID, sizeof(cfg_paths.pid_path));
03204    ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path));
03205    ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir));
03206 
03207    ast_set_default_eid(&ast_eid_default);
03208 
03209    /* no asterisk.conf? no problem, use buildtime config! */
03210    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03211       return;
03212    }
03213 
03214    for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
03215       if (!strcasecmp(v->name, "astctlpermissions"))
03216          ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
03217       else if (!strcasecmp(v->name, "astctlowner"))
03218          ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
03219       else if (!strcasecmp(v->name, "astctlgroup"))
03220          ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
03221       else if (!strcasecmp(v->name, "astctl"))
03222          ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
03223    }
03224 
03225    for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
03226       if (!strcasecmp(v->name, "astetcdir")) {
03227          ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir));
03228       } else if (!strcasecmp(v->name, "astspooldir")) {
03229          ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir));
03230          snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value);
03231       } else if (!strcasecmp(v->name, "astvarlibdir")) {
03232          ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir));
03233          if (!found.dbdir)
03234             snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
03235       } else if (!strcasecmp(v->name, "astdbdir")) {
03236          snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
03237          found.dbdir = 1;
03238       } else if (!strcasecmp(v->name, "astdatadir")) {
03239          ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir));
03240          if (!found.keydir)
03241             snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
03242       } else if (!strcasecmp(v->name, "astkeydir")) {
03243          snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
03244          found.keydir = 1;
03245       } else if (!strcasecmp(v->name, "astlogdir")) {
03246          ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir));
03247       } else if (!strcasecmp(v->name, "astagidir")) {
03248          ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir));
03249       } else if (!strcasecmp(v->name, "astrundir")) {
03250          snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid");
03251          snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", v->value, ast_config_AST_CTL);
03252          ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir));
03253       } else if (!strcasecmp(v->name, "astmoddir")) {
03254          ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir));
03255       } else if (!strcasecmp(v->name, "astsbindir")) {
03256          ast_copy_string(cfg_paths.sbin_dir, v->value, sizeof(cfg_paths.sbin_dir));
03257       }
03258    }
03259 
03260    for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
03261       /* verbose level (-v at startup) */
03262       if (!strcasecmp(v->name, "verbose")) {
03263          option_verbose = atoi(v->value);
03264       /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
03265       } else if (!strcasecmp(v->name, "timestamp")) {
03266          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
03267       /* whether or not to support #exec in config files */
03268       } else if (!strcasecmp(v->name, "execincludes")) {
03269          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
03270       /* debug level (-d at startup) */
03271       } else if (!strcasecmp(v->name, "debug")) {
03272          option_debug = 0;
03273          if (sscanf(v->value, "%30d", &option_debug) != 1) {
03274             option_debug = ast_true(v->value);
03275          }
03276 #if HAVE_WORKING_FORK
03277       /* Disable forking (-f at startup) */
03278       } else if (!strcasecmp(v->name, "nofork")) {
03279          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
03280       /* Always fork, even if verbose or debug are enabled (-F at startup) */
03281       } else if (!strcasecmp(v->name, "alwaysfork")) {
03282          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
03283 #endif
03284       /* Run quietly (-q at startup ) */
03285       } else if (!strcasecmp(v->name, "quiet")) {
03286          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
03287       /* Run as console (-c at startup, implies nofork) */
03288       } else if (!strcasecmp(v->name, "console")) {
03289          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
03290       /* Run with high priority if the O/S permits (-p at startup) */
03291       } else if (!strcasecmp(v->name, "highpriority")) {
03292          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
03293       /* Initialize RSA auth keys (IAX2) (-i at startup) */
03294       } else if (!strcasecmp(v->name, "initcrypto")) {
03295          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
03296       /* Disable ANSI colors for console (-c at startup) */
03297       } else if (!strcasecmp(v->name, "nocolor")) {
03298          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
03299       /* Disable some usage warnings for picky people :p */
03300       } else if (!strcasecmp(v->name, "dontwarn")) {
03301          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
03302       /* Dump core in case of crash (-g) */
03303       } else if (!strcasecmp(v->name, "dumpcore")) {
03304          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
03305       /* Cache recorded sound files to another directory during recording */
03306       } else if (!strcasecmp(v->name, "cache_record_files")) {
03307          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
03308       /* Specify cache directory */
03309       }  else if (!strcasecmp(v->name, "record_cache_dir")) {
03310          ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
03311       /* Build transcode paths via SLINEAR, instead of directly */
03312       } else if (!strcasecmp(v->name, "transcode_via_sln")) {
03313          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
03314       /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
03315       } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
03316          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
03317       /* Enable internal timing */
03318       } else if (!strcasecmp(v->name, "internal_timing")) {
03319          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING);
03320       } else if (!strcasecmp(v->name, "mindtmfduration")) {
03321          if (sscanf(v->value, "%30u", &option_dtmfminduration) != 1) {
03322             option_dtmfminduration = AST_MIN_DTMF_DURATION;
03323          }
03324       } else if (!strcasecmp(v->name, "maxcalls")) {
03325          if ((sscanf(v->value, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
03326             option_maxcalls = 0;
03327          }
03328       } else if (!strcasecmp(v->name, "maxload")) {
03329          double test[1];
03330 
03331          if (getloadavg(test, 1) == -1) {
03332             ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
03333             option_maxload = 0.0;
03334          } else if ((sscanf(v->value, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
03335             option_maxload = 0.0;
03336          }
03337       /* Set the maximum amount of open files */
03338       } else if (!strcasecmp(v->name, "maxfiles")) {
03339          option_maxfiles = atoi(v->value);
03340          set_ulimit(option_maxfiles);
03341       /* What user to run as */
03342       } else if (!strcasecmp(v->name, "runuser")) {
03343          ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user));
03344       /* What group to run as */
03345       } else if (!strcasecmp(v->name, "rungroup")) {
03346          ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group));
03347       } else if (!strcasecmp(v->name, "systemname")) {
03348          ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name));
03349       } else if (!strcasecmp(v->name, "autosystemname")) {
03350          if (ast_true(v->value)) {
03351             if (!gethostname(hostname, sizeof(hostname) - 1))
03352                ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name));
03353             else {
03354                if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){
03355                   ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name));
03356                }
03357                ast_log(LOG_ERROR, "Cannot obtain hostname for this system.  Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME);
03358             }
03359          }
03360       } else if (!strcasecmp(v->name, "languageprefix")) {
03361          ast_language_is_prefix = ast_true(v->value);
03362       } else if (!strcasecmp(v->name, "defaultlanguage")) {
03363          ast_copy_string(defaultlanguage, v->value, MAX_LANGUAGE);
03364       } else if (!strcasecmp(v->name, "lockmode")) {
03365          if (!strcasecmp(v->value, "lockfile")) {
03366             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03367          } else if (!strcasecmp(v->value, "flock")) {
03368             ast_set_lock_type(AST_LOCK_TYPE_FLOCK);
03369          } else {
03370             ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, "
03371                "defaulting to 'lockfile'\n", v->value);
03372             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03373          }
03374 #if defined(HAVE_SYSINFO)
03375       } else if (!strcasecmp(v->name, "minmemfree")) {
03376          /* specify the minimum amount of free memory to retain.  Asterisk should stop accepting new calls
03377           * if the amount of free memory falls below this watermark */
03378          if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
03379             option_minmemfree = 0;
03380          }
03381 #endif
03382       } else if (!strcasecmp(v->name, "entityid")) {
03383          struct ast_eid tmp_eid;
03384          if (!ast_str_to_eid(&tmp_eid, v->value)) {
03385             ast_verbose("Successfully set global EID to '%s'\n", v->value);
03386             ast_eid_default = tmp_eid;
03387          } else
03388             ast_verbose("Invalid Entity ID '%s' provided\n", v->value);
03389       } else if (!strcasecmp(v->name, "lightbackground")) {
03390          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND);
03391       } else if (!strcasecmp(v->name, "forceblackbackground")) {
03392          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03393       } else if (!strcasecmp(v->name, "hideconnect")) {
03394          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT);
03395       } else if (!strcasecmp(v->name, "lockconfdir")) {
03396          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LOCK_CONFIG_DIR);
03397       } else if (!strcasecmp(v->name, "stdexten")) {
03398          /* Choose how to invoke the extensions.conf stdexten */
03399          if (!strcasecmp(v->value, "gosub")) {
03400             ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
03401          } else if (!strcasecmp(v->value, "macro")) {
03402             ast_set_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
03403          } else {
03404             ast_log(LOG_WARNING,
03405                "'%s' is not a valid setting for the stdexten option, defaulting to 'gosub'\n",
03406                v->value);
03407             ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
03408          }
03409       }
03410    }
03411    for (v = ast_variable_browse(cfg, "compat"); v; v = v->next) {
03412       float version;
03413       if (sscanf(v->value, "%30f", &version) != 1) {
03414          ast_log(LOG_WARNING, "Compatibility version for option '%s' is not a number: '%s'\n", v->name, v->value);
03415          continue;
03416       }
03417       if (!strcasecmp(v->name, "app_set")) {
03418          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_APP_SET);
03419       } else if (!strcasecmp(v->name, "res_agi")) {
03420          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_RES_AGI);
03421       } else if (!strcasecmp(v->name, "pbx_realtime")) {
03422          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_PBX_REALTIME);
03423       }
03424    }
03425    ast_config_destroy(cfg);
03426 }

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

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

Referenced by __init_manager(), ast_cc_init(), ast_cel_engine_init(), ast_channels_init(), ast_data_init(), ast_event_init(), ast_features_init(), ast_format_attr_init(), ast_format_list_init(), ast_indications_init(), ast_msg_init(), ast_pbx_init(), ast_tps_init(), ast_udptl_init(), astdb_init(), astobj2_init(), do_reload(), load_module(), load_pbx(), and main().

01047 {
01048    struct ast_atexit *ae;
01049 
01050    if (!(ae = ast_calloc(1, sizeof(*ae))))
01051       return -1;
01052 
01053    ae->func = func;
01054 
01055    ast_unregister_atexit(func);
01056 
01057    AST_RWLIST_WRLOCK(&atexits);
01058    AST_RWLIST_INSERT_HEAD(&atexits, ae, list);
01059    AST_RWLIST_UNLOCK(&atexits);
01060 
01061    return 0;
01062 }

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

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

00417 {
00418    struct file_version *new;
00419    char *work;
00420    size_t version_length;
00421 
00422    work = ast_strdupa(version);
00423    work = ast_strip(ast_strip_quoted(work, "$", "$"));
00424    version_length = strlen(work) + 1;
00425 
00426    if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
00427       return;
00428 
00429    new->file = file;
00430    new->version = (char *) new + sizeof(*new);
00431    memcpy(new->version, work, version_length);
00432    AST_RWLIST_WRLOCK(&file_versions);
00433    AST_RWLIST_INSERT_HEAD(&file_versions, new, list);
00434    AST_RWLIST_UNLOCK(&file_versions);
00435 }

void ast_register_thread ( char *  name  ) 

Definition at line 498 of file asterisk.c.

References ast_calloc, ast_get_tid(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

Referenced by dummy_start().

00499 {
00500    struct thread_list_t *new = ast_calloc(1, sizeof(*new));
00501 
00502    if (!new)
00503       return;
00504    new->id = pthread_self();
00505    new->lwp = ast_get_tid();
00506    new->name = name; /* steal the allocated memory for the thread name */
00507    AST_RWLIST_WRLOCK(&thread_list);
00508    AST_RWLIST_INSERT_HEAD(&thread_list, new, list);
00509    AST_RWLIST_UNLOCK(&thread_list);
00510 }

static void ast_remotecontrol ( char *  data  )  [static]

Definition at line 2972 of file asterisk.c.

References __remote_quit_handler(), ast_alloca, 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().

02973 {
02974    char buf[80];
02975    int res;
02976    char filename[80] = "";
02977    char *hostname;
02978    char *cpid;
02979    char *version;
02980    int pid;
02981    char *stringp = NULL;
02982 
02983    char *ebuf;
02984    int num = 0;
02985 
02986    memset(&sig_flags, 0, sizeof(sig_flags));
02987    signal(SIGINT, __remote_quit_handler);
02988    signal(SIGTERM, __remote_quit_handler);
02989    signal(SIGHUP, __remote_quit_handler);
02990 
02991    if (read(ast_consock, buf, sizeof(buf)) < 0) {
02992       ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02993       return;
02994    }
02995    if (data) {
02996       char prefix[] = "cli quit after ";
02997       char *tmp = ast_alloca(strlen(data) + strlen(prefix) + 1);
02998       sprintf(tmp, "%s%s", prefix, data);
02999       if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
03000          ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
03001          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
03002             return;
03003          }
03004       }
03005    }
03006    stringp = buf;
03007    hostname = strsep(&stringp, "/");
03008    cpid = strsep(&stringp, "/");
03009    version = strsep(&stringp, "\n");
03010    if (!version)
03011       version = "<Version Unknown>";
03012    stringp = hostname;
03013    strsep(&stringp, ".");
03014    if (cpid)
03015       pid = atoi(cpid);
03016    else
03017       pid = -1;
03018    if (!data) {
03019       if (!ast_opt_mute) {
03020          fdsend(ast_consock, "logger mute silent");
03021       } else {
03022          printf("log and verbose output currently muted ('logger mute' to unmute)\n");
03023       }
03024    }
03025 
03026    if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
03027       int linefull = 1, prev_linefull = 1, prev_line_verbose = 0;
03028       struct pollfd fds;
03029       fds.fd = ast_consock;
03030       fds.events = POLLIN;
03031       fds.revents = 0;
03032 
03033       while (ast_poll(&fds, 1, 60000) > 0) {
03034          char buffer[512] = "", *curline = buffer, *nextline;
03035          int not_written = 1;
03036 
03037          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
03038             break;
03039          }
03040 
03041          if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
03042             break;
03043          }
03044 
03045          do {
03046             prev_linefull = linefull;
03047             if ((nextline = strchr(curline, '\n'))) {
03048                linefull = 1;
03049                nextline++;
03050             } else {
03051                linefull = 0;
03052                nextline = strchr(curline, '\0');
03053             }
03054 
03055             /* Skip verbose lines */
03056             /* Prev line full? | Line is verbose | Last line verbose? | Print
03057              * TRUE            | TRUE*           | TRUE               | FALSE
03058              * TRUE            | TRUE*           | FALSE              | FALSE
03059              * TRUE            | FALSE*          | TRUE               | TRUE
03060              * TRUE            | FALSE*          | FALSE              | TRUE
03061              * FALSE           | TRUE            | TRUE*              | FALSE
03062              * FALSE           | TRUE            | FALSE*             | TRUE
03063              * FALSE           | FALSE           | TRUE*              | FALSE
03064              * FALSE           | FALSE           | FALSE*             | TRUE
03065              */
03066             if ((!prev_linefull && !prev_line_verbose) || (prev_linefull && *curline > 0)) {
03067                prev_line_verbose = 0;
03068                not_written = 0;
03069                if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
03070                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03071                }
03072             } else {
03073                prev_line_verbose = 1;
03074             }
03075             curline = nextline;
03076          } while (!ast_strlen_zero(curline));
03077 
03078          /* No non-verbose output in 60 seconds. */
03079          if (not_written) {
03080             break;
03081          }
03082       }
03083       return;
03084    }
03085 
03086    ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
03087    remotehostname = hostname;
03088    if (getenv("HOME"))
03089       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
03090    if (el_hist == NULL || el == NULL)
03091       ast_el_initialize();
03092 
03093    el_set(el, EL_GETCFN, ast_el_read_char);
03094 
03095    if (!ast_strlen_zero(filename))
03096       ast_el_read_history(filename);
03097 
03098    for (;;) {
03099       ebuf = (char *)el_gets(el, &num);
03100 
03101       if (sig_flags.need_quit || sig_flags.need_quit_handler) {
03102          break;
03103       }
03104 
03105       if (!ebuf && write(1, "", 1) < 0)
03106          break;
03107 
03108       if (!ast_strlen_zero(ebuf)) {
03109          if (ebuf[strlen(ebuf)-1] == '\n')
03110             ebuf[strlen(ebuf)-1] = '\0';
03111          if (!remoteconsolehandler(ebuf)) {
03112             res = write(ast_consock, ebuf, strlen(ebuf) + 1);
03113             if (res < 1) {
03114                ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
03115                break;
03116             }
03117          }
03118       }
03119    }
03120    printf("\nDisconnected from Asterisk server\n");
03121 }

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

References ast_mutex_lock, ast_mutex_unlock, null_sig_handler, safe_system_level, safe_system_lock, and safe_system_prev_handler.

Referenced by ast_safe_fork(), and ast_safe_system().

01115 {
01116    unsigned int level;
01117 
01118    ast_mutex_lock(&safe_system_lock);
01119    level = safe_system_level++;
01120 
01121    /* only replace the handler if it has not already been done */
01122    if (level == 0) {
01123       sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
01124    }
01125 
01126    ast_mutex_unlock(&safe_system_lock);
01127 }

static void ast_run_atexits ( void   )  [static]

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

01751 {
01752    struct ast_atexit *ae;
01753    AST_RWLIST_RDLOCK(&atexits);
01754    AST_RWLIST_TRAVERSE(&atexits, ae, list) {
01755       if (ae->func)
01756          ae->func();
01757    }
01758    AST_RWLIST_UNLOCK(&atexits);
01759 }

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 1144 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(), convert_bdb_to_sqlite3(), mixmonitor_thread(), notify_message(), process_text_line(), remoteconsolehandler(), rotate_file(), run_externnotify(), sendmail(), sendpage(), system_exec_helper(), and vm_change_password_shell().

01145 {
01146    pid_t pid;
01147    int res;
01148    struct rusage rusage;
01149    int status;
01150 
01151 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
01152    ast_replace_sigchld();
01153 
01154 #ifdef HAVE_WORKING_FORK
01155    pid = fork();
01156 #else
01157    pid = vfork();
01158 #endif
01159 
01160    if (pid == 0) {
01161 #ifdef HAVE_CAP
01162       cap_t cap = cap_from_text("cap_net_admin-eip");
01163 
01164       if (cap_set_proc(cap)) {
01165          /* Careful with order! Logging cannot happen after we close FDs */
01166          ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
01167       }
01168       cap_free(cap);
01169 #endif
01170 #ifdef HAVE_WORKING_FORK
01171       if (ast_opt_high_priority)
01172          ast_set_priority(0);
01173       /* Close file descriptors and launch system command */
01174       ast_close_fds_above_n(STDERR_FILENO);
01175 #endif
01176       execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
01177       _exit(1);
01178    } else if (pid > 0) {
01179       for (;;) {
01180          res = wait4(pid, &status, 0, &rusage);
01181          if (res > -1) {
01182             res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
01183             break;
01184          } else if (errno != EINTR)
01185             break;
01186       }
01187    } else {
01188       ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
01189       res = -1;
01190    }
01191 
01192    ast_unreplace_sigchld();
01193 #else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */
01194    res = -1;
01195 #endif
01196 
01197    return res;
01198 }

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

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

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

01719 {
01720    struct sched_param sched;
01721    memset(&sched, 0, sizeof(sched));
01722 #ifdef __linux__
01723    if (pri) {
01724       sched.sched_priority = 10;
01725       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01726          ast_log(LOG_WARNING, "Unable to set high priority\n");
01727          return -1;
01728       } else
01729          ast_verb(1, "Set to realtime thread\n");
01730    } else {
01731       sched.sched_priority = 0;
01732       /* According to the manpage, these parameters can never fail. */
01733       sched_setscheduler(0, SCHED_OTHER, &sched);
01734    }
01735 #else
01736    if (pri) {
01737       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01738          ast_log(LOG_WARNING, "Unable to set high priority\n");
01739          return -1;
01740       } else
01741          ast_verb(1, "Set to high priority\n");
01742    } else {
01743       /* According to the manpage, these parameters can never fail. */
01744       setpriority(PRIO_PROCESS, 0, 0);
01745    }
01746 #endif
01747    return 0;
01748 }

static int ast_tryconnect ( void   )  [static]

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

01602 {
01603    struct sockaddr_un sunaddr;
01604    int res;
01605    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01606    if (ast_consock < 0) {
01607       ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
01608       return 0;
01609    }
01610    memset(&sunaddr, 0, sizeof(sunaddr));
01611    sunaddr.sun_family = AF_LOCAL;
01612    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01613    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01614    if (res) {
01615       close(ast_consock);
01616       ast_consock = -1;
01617       return 0;
01618    } else
01619       return 1;
01620 }

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

01065 {
01066    struct ast_atexit *ae = NULL;
01067 
01068    AST_RWLIST_WRLOCK(&atexits);
01069    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
01070       if (ae->func == func) {
01071          AST_RWLIST_REMOVE_CURRENT(list);
01072          break;
01073       }
01074    }
01075    AST_RWLIST_TRAVERSE_SAFE_END;
01076    AST_RWLIST_UNLOCK(&atexits);
01077 
01078    free(ae);
01079 }

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

00438 {
00439    struct file_version *find;
00440 
00441    AST_RWLIST_WRLOCK(&file_versions);
00442    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
00443       if (!strcasecmp(find->file, file)) {
00444          AST_RWLIST_REMOVE_CURRENT(list);
00445          break;
00446       }
00447    }
00448    AST_RWLIST_TRAVERSE_SAFE_END;
00449    AST_RWLIST_UNLOCK(&file_versions);
00450 
00451    if (find)
00452       ast_free(find);
00453 }

void ast_unregister_thread ( void *  id  ) 

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

00513 {
00514    struct thread_list_t *x;
00515 
00516    AST_RWLIST_WRLOCK(&thread_list);
00517    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
00518       if ((void *) x->id == id) {
00519          AST_RWLIST_REMOVE_CURRENT(list);
00520          break;
00521       }
00522    }
00523    AST_RWLIST_TRAVERSE_SAFE_END;
00524    AST_RWLIST_UNLOCK(&thread_list);
00525    if (x) {
00526       ast_free(x->name);
00527       ast_free(x);
00528    }
00529 }

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

References ast_mutex_lock, ast_mutex_unlock, safe_system_level, safe_system_lock, and safe_system_prev_handler.

Referenced by ast_safe_fork_cleanup(), and ast_safe_system().

01130 {
01131    unsigned int level;
01132 
01133    ast_mutex_lock(&safe_system_lock);
01134    level = --safe_system_level;
01135 
01136    /* only restore the handler if we are the last one */
01137    if (level == 0) {
01138       sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
01139    }
01140 
01141    ast_mutex_unlock(&safe_system_lock);
01142 }

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

Definition at line 1773 of file asterisk.c.

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

Referenced by quit_handler().

01774 {
01775    /* Check if someone else isn't already doing this. */
01776    ast_mutex_lock(&safe_system_lock);
01777    if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
01778       /* Already in progress and other request was less nice. */
01779       ast_mutex_unlock(&safe_system_lock);
01780       ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
01781       return 0;
01782    }
01783    shuttingdown = niceness;
01784    ast_mutex_unlock(&safe_system_lock);
01785 
01786    /* Try to get as many CDRs as possible submitted to the backend engines
01787     * (if in batch mode). really_quit happens to call it again when running
01788     * the atexit handlers, otherwise this would be a bit early. */
01789    ast_cdr_engine_term();
01790 
01791    /* Shutdown the message queue for the technology agnostic message channel.
01792     * This has to occur before we pause shutdown pending ast_undestroyed_channels. */
01793    ast_msg_shutdown();
01794 
01795    if (niceness == SHUTDOWN_NORMAL) {
01796       time_t s, e;
01797       /* Begin shutdown routine, hanging up active channels */
01798       ast_begin_shutdown(1);
01799       if (option_verbose && ast_opt_console) {
01800          ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
01801       }
01802       time(&s);
01803       for (;;) {
01804          time(&e);
01805          /* Wait up to 15 seconds for all channels to go away */
01806          if ((e - s) > 15 || !ast_undestroyed_channels() || shuttingdown != niceness) {
01807             break;
01808          }
01809          /* Sleep 1/10 of a second */
01810          usleep(100000);
01811       }
01812    } else if (niceness >= SHUTDOWN_NICE) {
01813       if (niceness != SHUTDOWN_REALLY_NICE) {
01814          ast_begin_shutdown(0);
01815       }
01816       if (option_verbose && ast_opt_console) {
01817          ast_verb(0, "Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
01818       }
01819       for (;;) {
01820          if (!ast_undestroyed_channels() || shuttingdown != niceness) {
01821             break;
01822          }
01823          sleep(1);
01824       }
01825    }
01826 
01827    /* Re-acquire lock and check if someone changed the niceness, in which
01828     * case someone else has taken over the shutdown.
01829     */
01830    ast_mutex_lock(&safe_system_lock);
01831    if (shuttingdown != niceness) {
01832       if (shuttingdown == NOT_SHUTTING_DOWN && option_verbose && ast_opt_console) {
01833          ast_verb(0, "Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
01834       }
01835       ast_mutex_unlock(&safe_system_lock);
01836       return 0;
01837    }
01838    shuttingdown = SHUTTING_DOWN;
01839    ast_mutex_unlock(&safe_system_lock);
01840 
01841    return 1;
01842 }

static void canary_exit ( void   )  [static]

Definition at line 3483 of file asterisk.c.

References canary_pid.

Referenced by main().

03484 {
03485    if (canary_pid > 0)
03486       kill(canary_pid, SIGKILL);
03487 }

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

Definition at line 3454 of file asterisk.c.

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

Referenced by main().

03455 {
03456    struct stat canary_stat;
03457    struct timeval now;
03458 
03459    /* Give the canary time to sing */
03460    sleep(120);
03461 
03462    for (;;) {
03463       now = ast_tvnow();
03464       if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
03465          ast_log(LOG_WARNING,
03466             "The canary is no more.  He has ceased to be!  "
03467             "He's expired and gone to meet his maker!  "
03468             "He's a stiff!  Bereft of life, he rests in peace.  "
03469             "His metabolic processes are now history!  He's off the twig!  "
03470             "He's kicked the bucket.  He's shuffled off his mortal coil, "
03471             "run down the curtain, and joined the bleeding choir invisible!!  "
03472             "THIS is an EX-CANARY.  (Reducing priority)\n");
03473          ast_set_priority(0);
03474          pthread_exit(NULL);
03475       }
03476 
03477       /* Check the canary once a minute */
03478       sleep(60);
03479    }
03480 }

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

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

02766 {
02767    int len = 0;
02768    char *ptr;
02769    int nummatches = 0;
02770    char **matches;
02771    int retval = CC_ERROR;
02772    char buf[2048], savechr;
02773    int res;
02774 
02775    LineInfo *lf = (LineInfo *)el_line(editline);
02776 
02777    savechr = *(char *)lf->cursor;
02778    *(char *)lf->cursor = '\0';
02779    ptr = (char *)lf->cursor;
02780    if (ptr) {
02781       while (ptr > lf->buffer) {
02782          if (isspace(*ptr)) {
02783             ptr++;
02784             break;
02785          }
02786          ptr--;
02787       }
02788    }
02789 
02790    len = lf->cursor - ptr;
02791 
02792    if (ast_opt_remote) {
02793       snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);
02794       fdsend(ast_consock, buf);
02795       if ((res = read(ast_consock, buf, sizeof(buf) - 1)) < 0) {
02796          return (char*)(CC_ERROR);
02797       }
02798       buf[res] = '\0';
02799       nummatches = atoi(buf);
02800 
02801       if (nummatches > 0) {
02802          char *mbuf;
02803          int mlen = 0, maxmbuf = 2048;
02804          /* Start with a 2048 byte buffer */
02805          if (!(mbuf = ast_malloc(maxmbuf))) {
02806             *((char *) lf->cursor) = savechr;
02807             return (char *)(CC_ERROR);
02808          }
02809          snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);
02810          fdsend(ast_consock, buf);
02811          res = 0;
02812          mbuf[0] = '\0';
02813          while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
02814             if (mlen + 1024 > maxmbuf) {
02815                /* Every step increment buffer 1024 bytes */
02816                maxmbuf += 1024;
02817                if (!(mbuf = ast_realloc(mbuf, maxmbuf))) {
02818                   *((char *) lf->cursor) = savechr;
02819                   return (char *)(CC_ERROR);
02820                }
02821             }
02822             /* Only read 1024 bytes at a time */
02823             res = read(ast_consock, mbuf + mlen, 1024);
02824             if (res > 0)
02825                mlen += res;
02826          }
02827          mbuf[mlen] = '\0';
02828 
02829          matches = ast_el_strtoarr(mbuf);
02830          ast_free(mbuf);
02831       } else
02832          matches = (char **) NULL;
02833    } else {
02834       char **p, *oldbuf=NULL;
02835       nummatches = 0;
02836       matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
02837       for (p = matches; p && *p; p++) {
02838          if (!oldbuf || strcmp(*p,oldbuf))
02839             nummatches++;
02840          oldbuf = *p;
02841       }
02842    }
02843 
02844    if (matches) {
02845       int i;
02846       int matches_num, maxlen, match_len;
02847 
02848       if (matches[0][0] != '\0') {
02849          el_deletestr(editline, (int) len);
02850          el_insertstr(editline, matches[0]);
02851          retval = CC_REFRESH;
02852       }
02853 
02854       if (nummatches == 1) {
02855          /* Found an exact match */
02856          el_insertstr(editline, " ");
02857          retval = CC_REFRESH;
02858       } else {
02859          /* Must be more than one match */
02860          for (i = 1, maxlen = 0; matches[i]; i++) {
02861             match_len = strlen(matches[i]);
02862             if (match_len > maxlen)
02863                maxlen = match_len;
02864          }
02865          matches_num = i - 1;
02866          if (matches_num >1) {
02867             fprintf(stdout, "\n");
02868             ast_cli_display_match_list(matches, nummatches, maxlen);
02869             retval = CC_REDISPLAY;
02870          } else {
02871             el_insertstr(editline," ");
02872             retval = CC_REFRESH;
02873          }
02874       }
02875       for (i = 0; matches[i]; i++)
02876          ast_free(matches[i]);
02877       ast_free(matches);
02878    }
02879 
02880    *((char *) lf->cursor) = savechr;
02881 
02882    return (char *)(long)retval;
02883 }

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

Definition at line 2537 of file asterisk.c.

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

Referenced by ast_el_initialize().

02538 {
02539    char tmp[100];
02540    char *pfmt;
02541    int color_used = 0;
02542    static int cli_prompt_changes = 0;
02543    char term_code[20];
02544    struct passwd *pw;
02545    struct group *gr;
02546 
02547    if (prompt == NULL) {
02548       prompt = ast_str_create(100);
02549    } else if (!cli_prompt_changes) {
02550       return ast_str_buffer(prompt);
02551    } else {
02552       ast_str_reset(prompt);
02553    }
02554 
02555    if ((pfmt = getenv("ASTERISK_PROMPT"))) {
02556       char *t = pfmt;
02557       struct timeval ts = ast_tvnow();
02558       while (*t != '\0') {
02559          if (*t == '%') {
02560             char hostname[MAXHOSTNAMELEN] = "";
02561             int i, which;
02562             struct ast_tm tm = { 0, };
02563             int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
02564 
02565             t++;
02566             switch (*t) {
02567             case 'C': /* color */
02568                t++;
02569                if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
02570                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)));
02571                   t += i - 1;
02572                } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
02573                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code)));
02574                   t += i - 1;
02575                }
02576 
02577                /* If the color has been reset correctly, then there's no need to reset it later */
02578                color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
02579                break;
02580             case 'd': /* date */
02581                if (ast_localtime(&ts, &tm, NULL)) {
02582                   ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
02583                   ast_str_append(&prompt, 0, "%s", tmp);
02584                   cli_prompt_changes++;
02585                }
02586                break;
02587             case 'g': /* group */
02588                if ((gr = getgrgid(getgid()))) {
02589                   ast_str_append(&prompt, 0, "%s", gr->gr_name);
02590                }
02591                break;
02592             case 'h': /* hostname */
02593                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02594                   ast_str_append(&prompt, 0, "%s", hostname);
02595                } else {
02596                   ast_str_append(&prompt, 0, "%s", "localhost");
02597                }
02598                break;
02599             case 'H': /* short hostname */
02600                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02601                   char *dotptr;
02602                   if ((dotptr = strchr(hostname, '.'))) {
02603                      *dotptr = '\0';
02604                   }
02605                   ast_str_append(&prompt, 0, "%s", hostname);
02606                } else {
02607                   ast_str_append(&prompt, 0, "%s", "localhost");
02608                }
02609                break;
02610 #ifdef HAVE_GETLOADAVG
02611             case 'l': /* load avg */
02612                t++;
02613                if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
02614                   double list[3];
02615                   getloadavg(list, 3);
02616                   ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
02617                   cli_prompt_changes++;
02618                }
02619                break;
02620 #endif
02621             case 's': /* Asterisk system name (from asterisk.conf) */
02622                ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
02623                break;
02624             case 't': /* time */
02625                if (ast_localtime(&ts, &tm, NULL)) {
02626                   ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
02627                   ast_str_append(&prompt, 0, "%s", tmp);
02628                   cli_prompt_changes++;
02629                }
02630                break;
02631             case 'u': /* username */
02632                if ((pw = getpwuid(getuid()))) {
02633                   ast_str_append(&prompt, 0, "%s", pw->pw_name);
02634                }
02635                break;
02636             case '#': /* process console or remote? */
02637                ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
02638                break;
02639             case '%': /* literal % */
02640                ast_str_append(&prompt, 0, "%c", '%');
02641                break;
02642             case '\0': /* % is last character - prevent bug */
02643                t--;
02644                break;
02645             }
02646          } else {
02647             ast_str_append(&prompt, 0, "%c", *t);
02648          }
02649          t++;
02650       }
02651       if (color_used) {
02652          /* Force colors back to normal at end */
02653          ast_str_append(&prompt, 0, "%s", term_color_code(term_code, 0, 0, sizeof(term_code)));
02654       }
02655    } else if (remotehostname) {
02656       ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname);
02657    } else {
02658       ast_str_set(&prompt, 0, "%s", ASTERISK_PROMPT);
02659    }
02660 
02661    return ast_str_buffer(prompt);
02662 }

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

Definition at line 1982 of file asterisk.c.

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

Referenced by main().

01983 {
01984    char tmp[80];
01985    const char *c = NULL;
01986    char level = 0;
01987 
01988    if (VERBOSE_HASMAGIC(s)) {
01989       level = VERBOSE_MAGIC2LEVEL(s);
01990       s++;
01991       if (level > option_verbose) {
01992          return;
01993       }
01994    }
01995 
01996    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01997        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01998        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01999        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
02000       fputs(tmp, stdout);
02001       fputs(c, stdout);
02002    } else {
02003       fputs(s, stdout);
02004    }
02005 
02006    fflush(stdout);
02007 
02008    /* Wake up a poll()ing console */
02009    if (ast_opt_console && consolethread != AST_PTHREADT_NULL) {
02010       pthread_kill(consolethread, SIGURG);
02011    }
02012 }

static void consolehandler ( char *  s  )  [static]

Definition at line 2024 of file asterisk.c.

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

Referenced by main().

02025 {
02026    printf("%s", term_end());
02027    fflush(stdout);
02028 
02029    /* Called when readline data is available */
02030    if (!ast_all_zeros(s))
02031       ast_el_add_history(s);
02032    /* The real handler for bang */
02033    if (s[0] == '!') {
02034       if (s[1])
02035          ast_safe_system(s+1);
02036       else
02037          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
02038    } else
02039       ast_cli_command(STDOUT_FILENO, s);
02040 }

static int el_read_char_state_init ( void *  ptr  )  [static]

Definition at line 2404 of file asterisk.c.

References el_read_char_state_struct::line_full, el_read_char_state_struct::prev_line_full, and el_read_char_state_struct::prev_line_verbosity.

02405 {
02406    struct el_read_char_state_struct *state = ptr;
02407    state->line_full = 1;
02408    state->prev_line_full = 1;
02409    state->prev_line_verbosity = 0;
02410    return 0;
02411 }

static void env_init ( void   )  [static]

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

03518 {
03519    setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
03520    setenv("AST_BUILD_HOST", ast_build_hostname, 1);
03521    setenv("AST_BUILD_DATE", ast_build_date, 1);
03522    setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
03523    setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
03524    setenv("AST_BUILD_OS", ast_build_os, 1);
03525    setenv("AST_BUILD_USER", ast_build_user, 1);
03526    setenv("AST_VERSION", ast_get_version(), 1);
03527 }

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

Definition at line 1088 of file asterisk.c.

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

01089 {
01090    return write(fd, s, strlen(s));
01091 }

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

Definition at line 1082 of file asterisk.c.

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

01083 {
01084    return write(fd, s, strlen(s) + 1);
01085 }

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

Definition at line 1964 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01965 {
01966    const char *c;
01967 
01968    if (!strncmp(s, cmp, strlen(cmp))) {
01969       c = s + strlen(cmp);
01970       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01971       return c;
01972    }
01973    return NULL;
01974 }

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

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

02244 {
02245    int aborting_shutdown = 0;
02246 
02247    switch (cmd) {
02248    case CLI_INIT:
02249       e->command = "core abort shutdown";
02250       e->usage =
02251          "Usage: core abort shutdown\n"
02252          "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
02253          "       call operations.\n";
02254       return NULL;
02255    case CLI_GENERATE:
02256       return NULL;
02257    }
02258 
02259    if (a->argc != e->args)
02260       return CLI_SHOWUSAGE;
02261 
02262    ast_mutex_lock(&safe_system_lock);
02263    if (shuttingdown >= SHUTDOWN_FAST) {
02264       aborting_shutdown = 1;
02265       shuttingdown = NOT_SHUTTING_DOWN;
02266    }
02267    ast_mutex_unlock(&safe_system_lock);
02268 
02269    if (aborting_shutdown) {
02270       ast_cancel_shutdown();
02271    }
02272    return CLI_SUCCESS;
02273 }

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

Definition at line 2275 of file asterisk.c.

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

02276 {
02277    switch (cmd) {
02278    case CLI_INIT:
02279       e->command = "!";
02280       e->usage =
02281          "Usage: !<command>\n"
02282          "       Executes a given shell command\n";
02283       return NULL;
02284    case CLI_GENERATE:
02285       return NULL;
02286    }
02287 
02288    return CLI_SUCCESS;
02289 }

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

Definition at line 934 of file asterisk.c.

References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, DEFINE_PROFILE_MIN_MAX_VALUES, profile_data::e, profile_entry::events, profile_entry::name, prof_data, ast_cli_entry::usage, and profile_entry::value.

00935 {
00936    int i, min, max;
00937    const char *search = NULL;
00938    switch (cmd) {
00939    case CLI_INIT:
00940       e->command = "core clear profile";
00941       e->usage = "Usage: core clear profile\n"
00942             "       clear profile information";
00943       return NULL;
00944    case CLI_GENERATE:
00945       return NULL;
00946    }
00947 
00948    if (prof_data == NULL)
00949       return 0;
00950 
00951    DEFINE_PROFILE_MIN_MAX_VALUES;
00952    for (i= min; i < max; i++) {
00953       if (!search || strstr(prof_data->e[i].name, search)) {
00954          prof_data->e[i].value = 0;
00955          prof_data->e[i].events = 0;
00956       }
00957    }
00958    return CLI_SUCCESS;
00959 }

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

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

02204 {
02205    switch (cmd) {
02206    case CLI_INIT:
02207       e->command = "core restart gracefully";
02208       e->usage =
02209          "Usage: core restart gracefully\n"
02210          "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
02211          "       restart when all active calls have ended.\n";
02212       return NULL;
02213    case CLI_GENERATE:
02214       return NULL;
02215    }
02216 
02217    if (a->argc != e->args)
02218       return CLI_SHOWUSAGE;
02219    quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
02220    return CLI_SUCCESS;
02221 }

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

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

02184 {
02185    switch (cmd) {
02186    case CLI_INIT:
02187       e->command = "core restart now";
02188       e->usage =
02189          "Usage: core restart now\n"
02190          "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
02191          "       restart.\n";
02192       return NULL;
02193    case CLI_GENERATE:
02194       return NULL;
02195    }
02196 
02197    if (a->argc != e->args)
02198       return CLI_SHOWUSAGE;
02199    quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
02200    return CLI_SUCCESS;
02201 }

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

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

02224 {
02225    switch (cmd) {
02226    case CLI_INIT:
02227       e->command = "core restart when convenient";
02228       e->usage =
02229          "Usage: core restart when convenient\n"
02230          "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
02231       return NULL;
02232    case CLI_GENERATE:
02233       return NULL;
02234    }
02235 
02236    if (a->argc != e->args)
02237       return CLI_SHOWUSAGE;
02238    ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
02239    quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
02240    return CLI_SUCCESS;
02241 }

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

Definition at line 899 of file asterisk.c.

References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, DEFINE_PROFILE_MIN_MAX_VALUES, profile_data::e, profile_data::entries, profile_entry::events, ast_cli_args::fd, profile_data::max_size, profile_entry::name, prof_data, profile_entry::scale, ast_cli_entry::usage, and profile_entry::value.

00900 {
00901    int i, min, max;
00902    const char *search = NULL;
00903    switch (cmd) {
00904    case CLI_INIT:
00905       e->command = "core show profile";
00906       e->usage = "Usage: core show profile\n"
00907             "       show profile information";
00908       return NULL;
00909    case CLI_GENERATE:
00910       return NULL;
00911    }
00912 
00913    if (prof_data == NULL)
00914       return 0;
00915 
00916    DEFINE_PROFILE_MIN_MAX_VALUES;
00917    ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
00918       prof_data->entries, prof_data->max_size);
00919    ast_cli(a->fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
00920          "Value", "Average", "Name");
00921    for (i = min; i < max; i++) {
00922       struct profile_entry *entry = &prof_data->e[i];
00923       if (!search || strstr(entry->name, search))
00924           ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
00925          i,
00926          (long)entry->scale,
00927          (long)entry->events, (long long)entry->value,
00928          (long long)(entry->events ? entry->value / entry->events : entry->value),
00929          entry->name);
00930    }
00931    return CLI_SUCCESS;
00932 }

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

References ast_active_channels(), ast_build_date, ast_build_kernel, ast_build_machine, ast_build_os, ast_build_user, 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_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.

00533 {
00534    char buf[BUFSIZ];
00535    struct ast_tm tm;
00536    char eid_str[128];
00537 
00538    switch (cmd) {
00539    case CLI_INIT:
00540       e->command = "core show settings";
00541       e->usage = "Usage: core show settings\n"
00542             "       Show core misc settings";
00543       return NULL;
00544    case CLI_GENERATE:
00545       return NULL;
00546    }
00547 
00548    ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
00549 
00550    ast_cli(a->fd, "\nPBX Core settings\n");
00551    ast_cli(a->fd, "-----------------\n");
00552    ast_cli(a->fd, "  Version:                     %s\n", ast_get_version());
00553    ast_cli(a->fd, "  Build Options:               %s\n", S_OR(AST_BUILDOPTS, "(none)"));
00554    if (option_maxcalls)
00555       ast_cli(a->fd, "  Maximum calls:               %d (Current %d)\n", option_maxcalls, ast_active_channels());
00556    else
00557       ast_cli(a->fd, "  Maximum calls:               Not set\n");
00558    if (option_maxfiles)
00559       ast_cli(a->fd, "  Maximum open file handles:   %d\n", option_maxfiles);
00560    else
00561       ast_cli(a->fd, "  Maximum open file handles:   Not set\n");
00562    ast_cli(a->fd, "  Verbosity:                   %d\n", option_verbose);
00563    ast_cli(a->fd, "  Debug level:                 %d\n", option_debug);
00564    ast_cli(a->fd, "  Maximum load average:        %lf\n", option_maxload);
00565 #if defined(HAVE_SYSINFO)
00566    ast_cli(a->fd, "  Minimum free memory:         %ld MB\n", option_minmemfree);
00567 #endif
00568    if (ast_localtime(&ast_startuptime, &tm, NULL)) {
00569       ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
00570       ast_cli(a->fd, "  Startup time:                %s\n", buf);
00571    }
00572    if (ast_localtime(&ast_lastreloadtime, &tm, NULL)) {
00573       ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
00574       ast_cli(a->fd, "  Last reload time:            %s\n", buf);
00575    }
00576    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);
00577    ast_cli(a->fd, "  System name:                 %s\n", ast_config_AST_SYSTEM_NAME);
00578    ast_cli(a->fd, "  Entity ID:                   %s\n", eid_str);
00579    ast_cli(a->fd, "  Default language:            %s\n", defaultlanguage);
00580    ast_cli(a->fd, "  Language prefix:             %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
00581    ast_cli(a->fd, "  User name and group:         %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
00582    ast_cli(a->fd, "  Executable includes:         %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
00583    ast_cli(a->fd, "  Transcode via SLIN:          %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
00584    ast_cli(a->fd, "  Internal timing:             %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled");
00585    ast_cli(a->fd, "  Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled");
00586    ast_cli(a->fd, "  Generic PLC:                 %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");
00587    ast_cli(a->fd, "  Min DTMF duration::          %u\n", option_dtmfminduration);
00588 
00589    ast_cli(a->fd, "\n* Subsystems\n");
00590    ast_cli(a->fd, "  -------------\n");
00591    ast_cli(a->fd, "  Manager (AMI):               %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
00592    ast_cli(a->fd, "  Web Manager (AMI/HTTP):      %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled");
00593    ast_cli(a->fd, "  Call data records:           %s\n", check_cdr_enabled() ? "Enabled" : "Disabled");
00594    ast_cli(a->fd, "  Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
00595 
00596    /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues  */
00597 
00598    ast_cli(a->fd, "\n* Directories\n");
00599    ast_cli(a->fd, "  -------------\n");
00600    ast_cli(a->fd, "  Configuration file:          %s\n", ast_config_AST_CONFIG_FILE);
00601    ast_cli(a->fd, "  Configuration directory:     %s\n", ast_config_AST_CONFIG_DIR);
00602    ast_cli(a->fd, "  Module directory:            %s\n", ast_config_AST_MODULE_DIR);
00603    ast_cli(a->fd, "  Spool directory:             %s\n", ast_config_AST_SPOOL_DIR);
00604    ast_cli(a->fd, "  Log directory:               %s\n", ast_config_AST_LOG_DIR);
00605    ast_cli(a->fd, "  Run/Sockets directory:       %s\n", ast_config_AST_RUN_DIR);
00606    ast_cli(a->fd, "  PID file:                    %s\n", ast_config_AST_PID);
00607    ast_cli(a->fd, "  VarLib directory:            %s\n", ast_config_AST_VAR_DIR);
00608    ast_cli(a->fd, "  Data directory:              %s\n", ast_config_AST_DATA_DIR);
00609    ast_cli(a->fd, "  ASTDB:                       %s\n", ast_config_AST_DB);
00610    ast_cli(a->fd, "  IAX2 Keys directory:         %s\n", ast_config_AST_KEY_DIR);
00611    ast_cli(a->fd, "  AGI Scripts directory:       %s\n", ast_config_AST_AGI_DIR);
00612    ast_cli(a->fd, "\n\n");
00613    return CLI_SUCCESS;
00614 }

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

Definition at line 616 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::lwp, thread_list_t::name, and ast_cli_entry::usage.

00617 {
00618    int count = 0;
00619    struct thread_list_t *cur;
00620    switch (cmd) {
00621    case CLI_INIT:
00622       e->command = "core show threads";
00623       e->usage =
00624          "Usage: core show threads\n"
00625          "       List threads currently active in the system.\n";
00626       return NULL;
00627    case CLI_GENERATE:
00628       return NULL;
00629    }
00630 
00631    AST_RWLIST_RDLOCK(&thread_list);
00632    AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
00633       ast_cli(a->fd, "%p %d %s\n", (void *)cur->id, cur->lwp, cur->name);
00634       count++;
00635    }
00636    AST_RWLIST_UNLOCK(&thread_list);
00637    ast_cli(a->fd, "%d threads listed.\n", count);
00638    return CLI_SUCCESS;
00639 }

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

00964 {
00965 #define FORMAT "%-25.25s %-40.40s\n"
00966    struct file_version *iterator;
00967    regex_t regexbuf;
00968    int havepattern = 0;
00969    int havename = 0;
00970    int count_files = 0;
00971    char *ret = NULL;
00972    int matchlen, which = 0;
00973    struct file_version *find;
00974 
00975    switch (cmd) {
00976    case CLI_INIT:
00977       e->command = "core show file version [like]";
00978       e->usage =
00979          "Usage: core show file version [like <pattern>]\n"
00980          "       Lists the revision numbers of the files used to build this copy of Asterisk.\n"
00981          "       Optional regular expression pattern is used to filter the file list.\n";
00982       return NULL;
00983    case CLI_GENERATE:
00984       matchlen = strlen(a->word);
00985       if (a->pos != 3)
00986          return NULL;
00987       AST_RWLIST_RDLOCK(&file_versions);
00988       AST_RWLIST_TRAVERSE(&file_versions, find, list) {
00989          if (!strncasecmp(a->word, find->file, matchlen) && ++which > a->n) {
00990             ret = ast_strdup(find->file);
00991             break;
00992          }
00993       }
00994       AST_RWLIST_UNLOCK(&file_versions);
00995       return ret;
00996    }
00997 
00998 
00999    switch (a->argc) {
01000    case 6:
01001       if (!strcasecmp(a->argv[4], "like")) {
01002          if (regcomp(&regexbuf, a->argv[5], REG_EXTENDED | REG_NOSUB))
01003             return CLI_SHOWUSAGE;
01004          havepattern = 1;
01005       } else
01006          return CLI_SHOWUSAGE;
01007       break;
01008    case 5:
01009       havename = 1;
01010       break;
01011    case 4:
01012       break;
01013    default:
01014       return CLI_SHOWUSAGE;
01015    }
01016 
01017    ast_cli(a->fd, FORMAT, "File", "Revision");
01018    ast_cli(a->fd, FORMAT, "----", "--------");
01019    AST_RWLIST_RDLOCK(&file_versions);
01020    AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
01021       if (havename && strcasecmp(iterator->file, a->argv[4]))
01022          continue;
01023 
01024       if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
01025          continue;
01026 
01027       ast_cli(a->fd, FORMAT, iterator->file, iterator->version);
01028       count_files++;
01029       if (havename)
01030          break;
01031    }
01032    AST_RWLIST_UNLOCK(&file_versions);
01033    if (!havename) {
01034       ast_cli(a->fd, "%d files listed.\n", count_files);
01035    }
01036 
01037    if (havepattern)
01038       regfree(&regexbuf);
01039 
01040    return CLI_SUCCESS;
01041 #undef FORMAT
01042 }

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

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

02144 {
02145    switch (cmd) {
02146    case CLI_INIT:
02147       e->command = "core stop gracefully";
02148       e->usage =
02149          "Usage: core stop gracefully\n"
02150          "       Causes Asterisk to not accept new calls, and exit when all\n"
02151          "       active calls have terminated normally.\n";
02152       return NULL;
02153    case CLI_GENERATE:
02154       return NULL;
02155    }
02156 
02157    if (a->argc != e->args)
02158       return CLI_SHOWUSAGE;
02159    quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
02160    return CLI_SUCCESS;
02161 }

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

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

02125 {
02126    switch (cmd) {
02127    case CLI_INIT:
02128       e->command = "core stop now";
02129       e->usage =
02130          "Usage: core stop now\n"
02131          "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
02132       return NULL;
02133    case CLI_GENERATE:
02134       return NULL;
02135    }
02136 
02137    if (a->argc != e->args)
02138       return CLI_SHOWUSAGE;
02139    quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
02140    return CLI_SUCCESS;
02141 }

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

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

02164 {
02165    switch (cmd) {
02166    case CLI_INIT:
02167       e->command = "core stop when convenient";
02168       e->usage =
02169          "Usage: core stop when convenient\n"
02170          "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
02171       return NULL;
02172    case CLI_GENERATE:
02173       return NULL;
02174    }
02175 
02176    if (a->argc != e->args)
02177       return CLI_SHOWUSAGE;
02178    ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
02179    quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
02180    return CLI_SUCCESS;
02181 }

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

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

02094 {
02095    switch (cmd) {
02096    case CLI_INIT:
02097       e->command = "core show version";
02098       e->usage =
02099          "Usage: core show version\n"
02100          "       Shows Asterisk version information.\n";
02101       return NULL;
02102    case CLI_GENERATE:
02103       return NULL;
02104    }
02105 
02106    if (a->argc != 3)
02107       return CLI_SHOWUSAGE;
02108    ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
02109       ast_get_version(), ast_build_user, ast_build_hostname,
02110       ast_build_machine, ast_build_os, ast_build_date);
02111    return CLI_SUCCESS;
02112 }

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

Definition at line 1450 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, LOG_ERROR, LOG_WARNING, console::mute, netconsole(), and console::uid.

Referenced by ast_makesocket().

01451 {
01452    struct sockaddr_un sunaddr;
01453    int s;
01454    socklen_t len;
01455    int x;
01456    int flags;
01457    struct pollfd fds[1];
01458    for (;;) {
01459       if (ast_socket < 0)
01460          return NULL;
01461       fds[0].fd = ast_socket;
01462       fds[0].events = POLLIN;
01463       s = ast_poll(fds, 1, -1);
01464       pthread_testcancel();
01465       if (s < 0) {
01466          if (errno != EINTR)
01467             ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
01468          continue;
01469       }
01470       len = sizeof(sunaddr);
01471       s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
01472       if (s < 0) {
01473          if (errno != EINTR)
01474             ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
01475       } else {
01476 #if !defined(SO_PASSCRED)
01477          {
01478 #else
01479          int sckopt = 1;
01480          /* turn on socket credentials passing. */
01481          if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
01482             ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
01483          } else {
01484 #endif
01485             for (x = 0; x < AST_MAX_CONNECTS; x++) {
01486                if (consoles[x].fd >= 0) {
01487                   continue;
01488                }
01489                if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
01490                   ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
01491                   consoles[x].fd = -1;
01492                   fdprint(s, "Server failed to create pipe\n");
01493                   close(s);
01494                   break;
01495                }
01496                flags = fcntl(consoles[x].p[1], F_GETFL);
01497                fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
01498                consoles[x].fd = s;
01499                consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
01500                /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
01501                   to know if the user didn't send the credentials. */
01502                consoles[x].uid = -2;
01503                consoles[x].gid = -2;
01504                if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
01505                   ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
01506                   close(consoles[x].p[0]);
01507                   close(consoles[x].p[1]);
01508                   consoles[x].fd = -1;
01509                   fdprint(s, "Server failed to spawn thread\n");
01510                   close(s);
01511                }
01512                break;
01513             }
01514             if (x >= AST_MAX_CONNECTS) {
01515                fdprint(s, "No more connections allowed\n");
01516                ast_log(LOG_WARNING, "No more connections allowed\n");
01517                close(s);
01518             } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
01519                ast_verb(3, "Remote UNIX connection\n");
01520             }
01521          }
01522       }
01523    }
01524    return NULL;
01525 }

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

< Result from the module load subsystem

Check for options

Todo:
Document these options

Note:
Please keep the ordering here to alphabetical, capital letters first. This will make it easier in the future to select unused option flags for new features.

Definition at line 3529 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_SBIN_DIR, 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_format_attr_init(), ast_format_list_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_language_is_prefix, ast_lastreloadtime, ast_log(), ast_makesocket(), ast_msg_init(), ast_named_acl_init(), 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_pbx_init(), ast_presence_state_engine_init(), ast_process_pending_reloads(), ast_pthread_create_detached, ast_readconfig(), ast_register_atexit(), ast_register_verbose(), ast_remotecontrol(), ast_rtp_engine_init(), 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_translate_init(), ast_tryconnect(), ast_tvnow(), ast_udptl_init(), ast_ulaw_init(), ast_utils_init(), ast_verb, ast_verbose, ast_xmldoc_load_documentation(), astdb_init(), astobj2_init(), callerid_init(), canary_exit(), canary_filename, canary_pid, canary_thread(), cfg_paths, 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, hostname, ignore_sig_handler, 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.

03530 {
03531    int c;
03532    char filename[80] = "";
03533    char hostname[MAXHOSTNAMELEN] = "";
03534    char tmp[80];
03535    char * xarg = NULL;
03536    int x;
03537    FILE *f;
03538    sigset_t sigs;
03539    int num;
03540    int isroot = 1, rundir_exists = 0;
03541    char *buf;
03542    const char *runuser = NULL, *rungroup = NULL;
03543    char *remotesock = NULL;
03544    int moduleresult;         /*!< Result from the module load subsystem */
03545    struct rlimit l;
03546 
03547    /* Remember original args for restart */
03548    if (argc > ARRAY_LEN(_argv) - 1) {
03549       fprintf(stderr, "Truncating argument size to %d\n", (int)ARRAY_LEN(_argv) - 1);
03550       argc = ARRAY_LEN(_argv) - 1;
03551    }
03552    for (x = 0; x < argc; x++)
03553       _argv[x] = argv[x];
03554    _argv[x] = NULL;
03555 
03556    if (geteuid() != 0)
03557       isroot = 0;
03558 
03559    /* if the progname is rasterisk consider it a remote console */
03560    if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
03561       ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03562    }
03563    if (gethostname(hostname, sizeof(hostname)-1))
03564       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
03565    ast_mainpid = getpid();
03566    ast_ulaw_init();
03567    ast_alaw_init();
03568    callerid_init();
03569    ast_builtins_init();
03570    ast_utils_init();
03571    tdd_init();
03572    ast_tps_init();
03573    ast_fd_init();
03574    ast_pbx_init();
03575 
03576    if (getenv("HOME"))
03577       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
03578    /*! \brief Check for options
03579     *
03580     * \todo Document these options
03581     */
03582    while ((c = getopt(argc, argv, "BC:cde:FfG:ghIiL:M:mnpqRrs:TtU:VvWXx:")) != -1) {
03583       /*!\note Please keep the ordering here to alphabetical, capital letters
03584        * first.  This will make it easier in the future to select unused
03585        * option flags for new features. */
03586       switch (c) {
03587       case 'B': /* Force black background */
03588          ast_set_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03589          ast_clear_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
03590          break;
03591       case 'X':
03592          ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES);
03593          break;
03594       case 'C':
03595          ast_copy_string(cfg_paths.config_file, optarg, sizeof(cfg_paths.config_file));
03596          ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
03597          break;
03598       case 'c':
03599          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
03600          break;
03601       case 'd':
03602          option_debug++;
03603          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03604          break;
03605 #if defined(HAVE_SYSINFO)
03606       case 'e':
03607          if ((sscanf(&optarg[1], "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
03608             option_minmemfree = 0;
03609          }
03610          break;
03611 #endif
03612 #if HAVE_WORKING_FORK
03613       case 'F':
03614          ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
03615          break;
03616       case 'f':
03617          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03618          break;
03619 #endif
03620       case 'G':
03621          rungroup = ast_strdupa(optarg);
03622          break;
03623       case 'g':
03624          ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
03625          break;
03626       case 'h':
03627          show_cli_help();
03628          exit(0);
03629       case 'I':
03630          ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING);
03631          break;
03632       case 'i':
03633          ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
03634          break;
03635       case 'L':
03636          if ((sscanf(optarg, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
03637             option_maxload = 0.0;
03638          }
03639          break;
03640       case 'M':
03641          if ((sscanf(optarg, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
03642             option_maxcalls = 0;
03643          }
03644          break;
03645       case 'm':
03646          ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
03647          break;
03648       case 'n':
03649          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
03650          break;
03651       case 'p':
03652          ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
03653          break;
03654       case 'q':
03655          ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
03656          break;
03657       case 'R':
03658          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
03659          break;
03660       case 'r':
03661          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03662          break;
03663       case 's':
03664          remotesock = ast_strdupa(optarg);
03665          break;
03666       case 'T':
03667          ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
03668          break;
03669       case 't':
03670          ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
03671          break;
03672       case 'U':
03673          runuser = ast_strdupa(optarg);
03674          break;
03675       case 'V':
03676          show_version();
03677          exit(0);
03678       case 'v':
03679          option_verbose++;
03680          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03681          break;
03682       case 'W': /* White background */
03683          ast_set_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
03684          ast_clear_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03685          break;
03686       case 'x':
03687          /* -r is implied by -x so set the flags -r sets as well. */
03688          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03689 
03690          ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC | AST_OPT_FLAG_NO_COLOR);
03691          xarg = ast_strdupa(optarg);
03692          break;
03693       case '?':
03694          exit(1);
03695       }
03696    }
03697 
03698    if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
03699       if (ast_register_verbose(console_verboser)) {
03700          ast_log(LOG_WARNING, "Unable to register console verboser?\n");
03701       }
03702       WELCOME_MESSAGE;
03703    }
03704 
03705    if (ast_opt_console && !option_verbose)
03706       ast_verbose("[ Booting...\n");
03707 
03708    /* For remote connections, change the name of the remote connection.
03709     * We do this for the benefit of init scripts (which need to know if/when
03710     * the main asterisk process has died yet). */
03711    if (ast_opt_remote) {
03712       strcpy(argv[0], "rasterisk");
03713       for (x = 1; x < argc; x++) {
03714          argv[x] = argv[0] + 10;
03715       }
03716    }
03717 
03718    if (ast_opt_console && !option_verbose) {
03719       ast_verbose("[ Reading Master Configuration ]\n");
03720    }
03721 
03722    ast_readconfig();
03723    env_init();
03724 
03725    if (ast_opt_remote && remotesock != NULL)
03726       ast_copy_string((char *) cfg_paths.socket_path, remotesock, sizeof(cfg_paths.socket_path));
03727 
03728    if (!ast_language_is_prefix && !ast_opt_remote)
03729       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");
03730 
03731    if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
03732       ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
03733       ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
03734    }
03735 
03736    if (ast_opt_dump_core) {
03737       memset(&l, 0, sizeof(l));
03738       l.rlim_cur = RLIM_INFINITY;
03739       l.rlim_max = RLIM_INFINITY;
03740       if (setrlimit(RLIMIT_CORE, &l)) {
03741          ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
03742       }
03743    }
03744 
03745    if (getrlimit(RLIMIT_NOFILE, &l)) {
03746       ast_log(LOG_WARNING, "Unable to check file descriptor limit: %s\n", strerror(errno));
03747    }
03748 
03749 #if !defined(CONFIGURE_RAN_AS_ROOT)
03750    /* Check if select(2) will run with more file descriptors */
03751    do {
03752       int fd, fd2;
03753       ast_fdset readers;
03754       struct timeval tv = { 0, };
03755 
03756       if (l.rlim_cur <= FD_SETSIZE) {
03757          /* The limit of select()able FDs is irrelevant, because we'll never
03758           * open one that high. */
03759          break;
03760       }
03761 
03762       if (!(fd = open("/dev/null", O_RDONLY))) {
03763          ast_log(LOG_ERROR, "Cannot open a file descriptor at boot? %s\n", strerror(errno));
03764          break; /* XXX Should we exit() here? XXX */
03765       }
03766 
03767       fd2 = ((l.rlim_cur > sizeof(readers) * 8) ? sizeof(readers) * 8 : l.rlim_cur) - 1;
03768       if (dup2(fd, fd2) < 0) {
03769          ast_log(LOG_WARNING, "Cannot open maximum file descriptor %d at boot? %s\n", fd2, strerror(errno));
03770          close(fd);
03771          break;
03772       }
03773 
03774       FD_ZERO(&readers);
03775       FD_SET(fd2, &readers);
03776       if (ast_select(fd2 + 1, &readers, NULL, NULL, &tv) < 0) {
03777          ast_log(LOG_WARNING, "Maximum select()able file descriptor is %d\n", FD_SETSIZE);
03778       }
03779       ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
03780       close(fd);
03781       close(fd2);
03782    } while (0);
03783 #elif defined(HAVE_VARIABLE_FDSET)
03784    ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
03785 #endif /* !defined(CONFIGURE_RAN_AS_ROOT) */
03786 
03787    if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
03788       rungroup = ast_config_AST_RUN_GROUP;
03789    if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
03790       runuser = ast_config_AST_RUN_USER;
03791 
03792    /* Must install this signal handler up here to ensure that if the canary
03793     * fails to execute that it doesn't kill the Asterisk process.
03794     */
03795    sigaction(SIGCHLD, &child_handler, NULL);
03796 
03797    /* It's common on some platforms to clear /var/run at boot.  Create the
03798     * socket file directory before we drop privileges. */
03799    if (mkdir(ast_config_AST_RUN_DIR, 0755)) {
03800       if (errno == EEXIST) {
03801          rundir_exists = 1;
03802       } else {
03803          ast_log(LOG_WARNING, "Unable to create socket file directory.  Remote consoles will not be able to connect! (%s)\n", strerror(x));
03804       }
03805    }
03806 
03807 #ifndef __CYGWIN__
03808 
03809    if (isroot) {
03810       ast_set_priority(ast_opt_high_priority);
03811    }
03812 
03813    if (isroot && rungroup) {
03814       struct group *gr;
03815       gr = getgrnam(rungroup);
03816       if (!gr) {
03817          ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
03818          exit(1);
03819       }
03820       if (!rundir_exists && chown(ast_config_AST_RUN_DIR, -1, gr->gr_gid)) {
03821          ast_log(LOG_WARNING, "Unable to chgrp run directory to %d (%s)\n", (int) gr->gr_gid, rungroup);
03822       }
03823       if (setgid(gr->gr_gid)) {
03824          ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
03825          exit(1);
03826       }
03827       if (setgroups(0, NULL)) {
03828          ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
03829          exit(1);
03830       }
03831       ast_verb(1, "Running as group '%s'\n", rungroup);
03832    }
03833 
03834    if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
03835 #ifdef HAVE_CAP
03836       int has_cap = 1;
03837 #endif /* HAVE_CAP */
03838       struct passwd *pw;
03839       pw = getpwnam(runuser);
03840       if (!pw) {
03841          ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
03842          exit(1);
03843       }
03844       if (chown(ast_config_AST_RUN_DIR, pw->pw_uid, -1)) {
03845          ast_log(LOG_WARNING, "Unable to chown run directory to %d (%s)\n", (int) pw->pw_uid, runuser);
03846       }
03847 #ifdef HAVE_CAP
03848       if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
03849          ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
03850          has_cap = 0;
03851       }
03852 #endif /* HAVE_CAP */
03853       if (!isroot && pw->pw_uid != geteuid()) {
03854          ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
03855          exit(1);
03856       }
03857       if (!rungroup) {
03858          if (setgid(pw->pw_gid)) {
03859             ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
03860             exit(1);
03861          }
03862          if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
03863             ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser);
03864             exit(1);
03865          }
03866       }
03867       if (setuid(pw->pw_uid)) {
03868          ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
03869          exit(1);
03870       }
03871       ast_verb(1, "Running as user '%s'\n", runuser);
03872 #ifdef HAVE_CAP
03873       if (has_cap) {
03874          cap_t cap;
03875 
03876          cap = cap_from_text("cap_net_admin=eip");
03877 
03878          if (cap_set_proc(cap))
03879             ast_log(LOG_WARNING, "Unable to install capabilities.\n");
03880 
03881          if (cap_free(cap))
03882             ast_log(LOG_WARNING, "Unable to drop capabilities.\n");
03883       }
03884 #endif /* HAVE_CAP */
03885    }
03886 
03887 #endif /* __CYGWIN__ */
03888 
03889 #ifdef linux
03890    if (geteuid() && ast_opt_dump_core) {
03891       if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
03892          ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
03893       }
03894    }
03895 #endif
03896 
03897    {
03898 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
03899 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
03900 #define eaccess euidaccess
03901 #endif
03902       char dir[PATH_MAX];
03903       if (!getcwd(dir, sizeof(dir)) || eaccess(dir, R_OK | X_OK | F_OK)) {
03904          ast_log(LOG_ERROR, "Unable to access the running directory (%s).  Changing to '/' for compatibility.\n", strerror(errno));
03905          /* If we cannot access the CWD, then we couldn't dump core anyway,
03906           * so chdir("/") won't break anything. */
03907          if (chdir("/")) {
03908             /* chdir(/) should never fail, so this ends up being a no-op */
03909             ast_log(LOG_ERROR, "chdir(\"/\") failed?!! %s\n", strerror(errno));
03910          }
03911       } else
03912 #endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */
03913       if (!ast_opt_no_fork && !ast_opt_dump_core) {
03914          /* Backgrounding, but no cores, so chdir won't break anything. */
03915          if (chdir("/")) {
03916             ast_log(LOG_ERROR, "Unable to chdir(\"/\") ?!! %s\n", strerror(errno));
03917          }
03918       }
03919    }
03920 
03921    ast_term_init();
03922    printf("%s", term_end());
03923    fflush(stdout);
03924 
03925    if (ast_opt_console && !option_verbose) {
03926       ast_verbose("[ Initializing Custom Configuration Options ]\n");
03927    }
03928    /* custom config setup */
03929    register_config_cli();
03930    read_config_maps();
03931 
03932    if (ast_opt_console) {
03933       if (el_hist == NULL || el == NULL)
03934          ast_el_initialize();
03935 
03936       if (!ast_strlen_zero(filename))
03937          ast_el_read_history(filename);
03938    }
03939 
03940    if (ast_tryconnect()) {
03941       /* One is already running */
03942       if (ast_opt_remote) {
03943          if (ast_opt_exec) {
03944             ast_remotecontrol(xarg);
03945             quit_handler(0, SHUTDOWN_FAST, 0);
03946             exit(0);
03947          }
03948          printf("%s", term_quit());
03949          ast_remotecontrol(NULL);
03950          quit_handler(0, SHUTDOWN_FAST, 0);
03951          exit(0);
03952       } else {
03953          ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
03954          printf("%s", term_quit());
03955          exit(1);
03956       }
03957    } else if (ast_opt_remote || ast_opt_exec) {
03958       ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
03959       printf("%s", term_quit());
03960       exit(1);
03961    }
03962    /* Blindly write pid file since we couldn't connect */
03963    unlink(ast_config_AST_PID);
03964    f = fopen(ast_config_AST_PID, "w");
03965    if (f) {
03966       fprintf(f, "%ld\n", (long)getpid());
03967       fclose(f);
03968    } else
03969       ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
03970 
03971 #if HAVE_WORKING_FORK
03972    if (ast_opt_always_fork || !ast_opt_no_fork) {
03973 #ifndef HAVE_SBIN_LAUNCHD
03974       if (daemon(1, 0) < 0) {
03975          ast_log(LOG_ERROR, "daemon() failed: %s\n", strerror(errno));
03976       }
03977       ast_mainpid = getpid();
03978       /* Blindly re-write pid file since we are forking */
03979       unlink(ast_config_AST_PID);
03980       f = fopen(ast_config_AST_PID, "w");
03981       if (f) {
03982          fprintf(f, "%ld\n", (long)ast_mainpid);
03983          fclose(f);
03984       } else
03985          ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
03986 #else
03987       ast_log(LOG_WARNING, "Mac OS X detected.  Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
03988 #endif
03989    }
03990 #endif
03991 
03992    /* Spawning of astcanary must happen AFTER the call to daemon(3) */
03993    if (isroot && ast_opt_high_priority) {
03994       snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
03995 
03996       /* Don't let the canary child kill Asterisk, if it dies immediately */
03997       sigaction(SIGPIPE, &ignore_sig_handler, NULL);
03998 
03999       canary_pid = fork();
04000       if (canary_pid == 0) {
04001          char canary_binary[PATH_MAX], ppid[12];
04002 
04003          /* Reset signal handler */
04004          signal(SIGCHLD, SIG_DFL);
04005          signal(SIGPIPE, SIG_DFL);
04006 
04007          ast_close_fds_above_n(0);
04008          ast_set_priority(0);
04009          snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid);
04010 
04011          /* Use the astcanary binary that we installed */
04012          snprintf(canary_binary, sizeof(canary_binary), "%s/astcanary", ast_config_AST_SBIN_DIR);
04013          execl(canary_binary, "astcanary", canary_filename, ppid, (char *)NULL);
04014 
04015          /* Should never happen */
04016          _exit(1);
04017       } else if (canary_pid > 0) {
04018          pthread_t dont_care;
04019          ast_pthread_create_detached(&dont_care, NULL, canary_thread, NULL);
04020       }
04021 
04022       /* Kill the canary when we exit */
04023       ast_register_atexit(canary_exit);
04024    }
04025 
04026    if (ast_event_init()) {
04027       printf("%s", term_quit());
04028       exit(1);
04029    }
04030 
04031 #ifdef TEST_FRAMEWORK
04032    if (ast_test_init()) {
04033       printf("%s", term_quit());
04034       exit(1);
04035    }
04036 #endif
04037 
04038    if (ast_translate_init()) {
04039       printf("%s", term_quit());
04040       exit(1);
04041    }
04042 
04043    ast_aoc_cli_init();
04044 
04045    ast_makesocket();
04046    sigemptyset(&sigs);
04047    sigaddset(&sigs, SIGHUP);
04048    sigaddset(&sigs, SIGTERM);
04049    sigaddset(&sigs, SIGINT);
04050    sigaddset(&sigs, SIGPIPE);
04051    sigaddset(&sigs, SIGWINCH);
04052    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
04053    sigaction(SIGURG, &urg_handler, NULL);
04054    signal(SIGINT, __quit_handler);
04055    signal(SIGTERM, __quit_handler);
04056    sigaction(SIGHUP, &hup_handler, NULL);
04057    sigaction(SIGPIPE, &ignore_sig_handler, NULL);
04058 
04059    /* ensure that the random number generators are seeded with a different value every time
04060       Asterisk is started
04061    */
04062    srand((unsigned int) getpid() + (unsigned int) time(NULL));
04063    initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
04064 
04065    if (init_logger()) {    /* Start logging subsystem */
04066       printf("%s", term_quit());
04067       exit(1);
04068    }
04069 
04070    threadstorage_init();
04071 
04072    astobj2_init();
04073 
04074    ast_format_attr_init();
04075    ast_format_list_init();
04076    ast_rtp_engine_init();
04077 
04078    ast_autoservice_init();
04079 
04080    if (ast_timing_init()) {
04081       printf("%s", term_quit());
04082       exit(1);
04083    }
04084 
04085    if (ast_ssl_init()) {
04086       printf("%s", term_quit());
04087       exit(1);
04088    }
04089 
04090 #ifdef AST_XML_DOCS
04091    /* Load XML documentation. */
04092    ast_xmldoc_load_documentation();
04093 #endif
04094 
04095    if (astdb_init()) {
04096       printf("%s", term_quit());
04097       exit(1);
04098    }
04099 
04100    if (ast_msg_init()) {
04101       printf("%s", term_quit());
04102       exit(1);
04103    }
04104 
04105    /* initialize the data retrieval API */
04106    if (ast_data_init()) {
04107       printf ("%s", term_quit());
04108       exit(1);
04109    }
04110 
04111    ast_channels_init();
04112 
04113    if ((moduleresult = load_modules(1))) {      /* Load modules, pre-load only */
04114       printf("%s", term_quit());
04115       exit(moduleresult == -2 ? 2 : 1);
04116    }
04117 
04118    if (dnsmgr_init()) {    /* Initialize the DNS manager */
04119       printf("%s", term_quit());
04120       exit(1);
04121    }
04122 
04123    if (ast_named_acl_init()) { /* Initialize the Named ACL system */
04124       printf("%s", term_quit());
04125       exit(1);
04126    }
04127 
04128    ast_http_init();     /* Start the HTTP server, if needed */
04129 
04130    if (init_manager()) {
04131       printf("%s", term_quit());
04132       exit(1);
04133    }
04134 
04135    if (ast_cdr_engine_init()) {
04136       printf("%s", term_quit());
04137       exit(1);
04138    }
04139 
04140    if (ast_cel_engine_init()) {
04141       printf("%s", term_quit());
04142       exit(1);
04143    }
04144 
04145    if (ast_device_state_engine_init()) {
04146       printf("%s", term_quit());
04147       exit(1);
04148    }
04149 
04150    if (ast_presence_state_engine_init()) {
04151       printf("%s", term_quit());
04152       exit(1);
04153    }
04154 
04155    ast_dsp_init();
04156    ast_udptl_init();
04157 
04158    if (ast_image_init()) {
04159       printf("%s", term_quit());
04160       exit(1);
04161    }
04162 
04163    if (ast_file_init()) {
04164       printf("%s", term_quit());
04165       exit(1);
04166    }
04167 
04168    if (load_pbx()) {
04169       printf("%s", term_quit());
04170       exit(1);
04171    }
04172 
04173    if (ast_indications_init()) {
04174       printf("%s", term_quit());
04175       exit(1);
04176    }
04177 
04178    if (ast_features_init()) {
04179       printf("%s", term_quit());
04180       exit(1);
04181    }
04182 
04183    if (init_framer()) {
04184       printf("%s", term_quit());
04185       exit(1);
04186    }
04187 
04188    if (ast_enum_init()) {
04189       printf("%s", term_quit());
04190       exit(1);
04191    }
04192 
04193    if (ast_cc_init()) {
04194       printf("%s", term_quit());
04195       exit(1);
04196    }
04197 
04198    if ((moduleresult = load_modules(0))) {      /* Load modules */
04199       printf("%s", term_quit());
04200       exit(moduleresult == -2 ? 2 : 1);
04201    }
04202 
04203    /* loads the cli_permissoins.conf file needed to implement cli restrictions. */
04204    ast_cli_perms_init(0);
04205 
04206    ast_stun_init();
04207 
04208    dnsmgr_start_refresh();
04209 
04210    /* We might have the option of showing a console, but for now just
04211       do nothing... */
04212    ast_verb(0, "%s\n", term_color(tmp, "Asterisk Ready.", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
04213    if (ast_opt_no_fork) {
04214       consolethread = pthread_self();
04215    }
04216 
04217    if (pipe(sig_alert_pipe)) {
04218       sig_alert_pipe[0] = sig_alert_pipe[1] = -1;
04219    }
04220 
04221    ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
04222    /*** DOCUMENTATION
04223       <managerEventInstance>
04224          <synopsis>Raised when all Asterisk initialization procedures have finished.</synopsis>
04225       </managerEventInstance>
04226    ***/
04227    manager_event(EVENT_FLAG_SYSTEM, "FullyBooted", "Status: Fully Booted\r\n");
04228 
04229    ast_process_pending_reloads();
04230 
04231    pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
04232 
04233 #ifdef __AST_DEBUG_MALLOC
04234    __ast_mm_init();
04235 #endif
04236 
04237    ast_lastreloadtime = ast_startuptime = ast_tvnow();
04238    ast_cli_register_multiple(cli_asterisk, ARRAY_LEN(cli_asterisk));
04239 
04240    run_startup_commands();
04241 
04242    if (ast_opt_console) {
04243       /* Console stuff now... */
04244       /* Register our quit function */
04245       char title[256];
04246 
04247       ast_pthread_create_detached(&mon_sig_flags, NULL, monitor_sig_flags, NULL);
04248 
04249       set_icon("Asterisk");
04250       snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
04251       set_title(title);
04252 
04253       el_set(el, EL_GETCFN, ast_el_read_char);
04254 
04255       for (;;) {
04256          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
04257             quit_handler(0, SHUTDOWN_FAST, 0);
04258             break;
04259          }
04260          buf = (char *) el_gets(el, &num);
04261 
04262          if (!buf && write(1, "", 1) < 0)
04263             goto lostterm;
04264 
04265          if (buf) {
04266             if (buf[strlen(buf)-1] == '\n')
04267                buf[strlen(buf)-1] = '\0';
04268 
04269             consolehandler((char *)buf);
04270          } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
04271                strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) {
04272             /* Whoa, stdout disappeared from under us... Make /dev/null's */
04273             int fd;
04274             fd = open("/dev/null", O_RDWR);
04275             if (fd > -1) {
04276                dup2(fd, STDOUT_FILENO);
04277                dup2(fd, STDIN_FILENO);
04278             } else
04279                ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
04280             break;
04281          }
04282       }
04283    }
04284 
04285    monitor_sig_flags(NULL);
04286 
04287 lostterm:
04288    return 0;
04289 }

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

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

03429 {
03430    for (;;) {
03431       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
03432       int a;
03433       ast_poll(&p, 1, -1);
03434       if (sig_flags.need_reload) {
03435          sig_flags.need_reload = 0;
03436          ast_module_reload(NULL);
03437       }
03438       if (sig_flags.need_quit) {
03439          sig_flags.need_quit = 0;
03440          if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
03441             sig_flags.need_quit_handler = 1;
03442             pthread_kill(consolethread, SIGURG);
03443          } else {
03444             quit_handler(0, SHUTDOWN_NORMAL, 0);
03445          }
03446       }
03447       if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
03448       }
03449    }
03450 
03451    return NULL;
03452 }

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

Definition at line 1362 of file asterisk.c.

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

Referenced by listener().

01363 {
01364    struct console *con = vconsole;
01365    char hostname[MAXHOSTNAMELEN] = "";
01366    char inbuf[512];
01367    char outbuf[512];
01368    const char * const end_buf = inbuf + sizeof(inbuf);
01369    char *start_read = inbuf;
01370    int res;
01371    struct pollfd fds[2];
01372 
01373    if (gethostname(hostname, sizeof(hostname)-1))
01374       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
01375    snprintf(outbuf, sizeof(outbuf), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
01376    fdprint(con->fd, outbuf);
01377    for (;;) {
01378       fds[0].fd = con->fd;
01379       fds[0].events = POLLIN;
01380       fds[0].revents = 0;
01381       fds[1].fd = con->p[0];
01382       fds[1].events = POLLIN;
01383       fds[1].revents = 0;
01384 
01385       res = ast_poll(fds, 2, -1);
01386       if (res < 0) {
01387          if (errno != EINTR)
01388             ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
01389          continue;
01390       }
01391       if (fds[0].revents) {
01392          int cmds_read, bytes_read;
01393          if ((bytes_read = read_credentials(con->fd, start_read, end_buf - start_read, con)) < 1) {
01394             break;
01395          }
01396          /* XXX This will only work if it is the first command, and I'm not sure fixing it is worth the effort. */
01397          if (strncmp(inbuf, "cli quit after ", 15) == 0) {
01398             ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read - 15, inbuf + 15);
01399             break;
01400          }
01401          /* ast_cli_command_multiple_full will only process individual commands terminated by a
01402           * NULL and not trailing partial commands. */
01403          if (!(cmds_read = ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read + start_read - inbuf, inbuf))) {
01404             /* No commands were read. We either have a short read on the first command
01405              * with space left, or a command that is too long */
01406             if (start_read + bytes_read < end_buf) {
01407                start_read += bytes_read;
01408             } else {
01409                ast_log(LOG_ERROR, "Command too long! Skipping\n");
01410                start_read = inbuf;
01411             }
01412             continue;
01413          }
01414          if (start_read[bytes_read - 1] == '\0') {
01415             /* The read ended on a command boundary, start reading again at the head of inbuf */
01416             start_read = inbuf;
01417             continue;
01418          }
01419          /* If we get this far, we have left over characters that have not been processed.
01420           * Advance to the character after the last command read by ast_cli_command_multiple_full.
01421           * We are guaranteed to have at least cmds_read NULLs */
01422          while (cmds_read-- && (start_read = strchr(start_read, '\0'))) {
01423             start_read++;
01424          }
01425          memmove(inbuf, start_read, end_buf - start_read);
01426          start_read = end_buf - start_read + inbuf;
01427       }
01428       if (fds[1].revents) {
01429          res = read_credentials(con->p[0], outbuf, sizeof(outbuf), con);
01430          if (res < 1) {
01431             ast_log(LOG_ERROR, "read returned %d\n", res);
01432             break;
01433          }
01434          res = write(con->fd, outbuf, res);
01435          if (res < 1)
01436             break;
01437       }
01438    }
01439    if (!ast_opt_hide_connect) {
01440       ast_verb(3, "Remote UNIX connection disconnected\n");
01441    }
01442    close(con->fd);
01443    close(con->p[0]);
01444    close(con->p[1]);
01445    con->fd = -1;
01446 
01447    return NULL;
01448 }

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

Definition at line 1296 of file asterisk.c.

References __LOG_VERBOSE, and ast_network_puts_mutable().

Referenced by ast_makesocket().

01297 {
01298    ast_network_puts_mutable(s, __LOG_VERBOSE);
01299 }

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

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

01765 {
01766    if (can_safely_quit(niceness, restart)) {
01767       really_quit(num, niceness, restart);
01768       /* No one gets here. */
01769    }
01770    /* It wasn't our time. */
01771 }

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 864 of file asterisk.c.

Referenced by ast_mark().

00865 {
00866    return 0;
00867 }

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

References console::gid, and console::uid.

Referenced by netconsole().

01314 {
01315 #if defined(SO_PEERCRED)
01316 #ifdef HAVE_STRUCT_SOCKPEERCRED_UID
01317 #define HAVE_STRUCT_UCRED_UID
01318    struct sockpeercred cred;
01319 #else
01320    struct ucred cred;
01321 #endif
01322    socklen_t len = sizeof(cred);
01323 #endif
01324 #if defined(HAVE_GETPEEREID)
01325    uid_t uid;
01326    gid_t gid;
01327 #else
01328    int uid, gid;
01329 #endif
01330    int result;
01331 
01332    result = read(fd, buffer, size);
01333    if (result < 0) {
01334       return result;
01335    }
01336 
01337 #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
01338    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
01339       return result;
01340    }
01341 #if defined(HAVE_STRUCT_UCRED_UID)
01342    uid = cred.uid;
01343    gid = cred.gid;
01344 #else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
01345    uid = cred.cr_uid;
01346    gid = cred.cr_gid;
01347 #endif /* defined(HAVE_STRUCT_UCRED_UID) */
01348 
01349 #elif defined(HAVE_GETPEEREID)
01350    if (getpeereid(fd, &uid, &gid)) {
01351       return result;
01352    }
01353 #else
01354    return result;
01355 #endif
01356    con->uid = uid;
01357    con->gid = gid;
01358 
01359    return result;
01360 }

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

Definition at line 1844 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_verb, 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().

01845 {
01846    if (niceness >= SHUTDOWN_NICE) {
01847       ast_module_shutdown();
01848    }
01849 
01850    if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
01851       char filename[80] = "";
01852       if (getenv("HOME")) {
01853          snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
01854       }
01855       if (!ast_strlen_zero(filename)) {
01856          ast_el_write_history(filename);
01857       }
01858       if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
01859          /* Only end if we are the consolethread, otherwise there's a race with that thread. */
01860          if (el != NULL) {
01861             el_end(el);
01862          }
01863          if (el_hist != NULL) {
01864             history_end(el_hist);
01865          }
01866       } else if (mon_sig_flags == pthread_self()) {
01867          if (consolethread != AST_PTHREADT_NULL) {
01868             pthread_kill(consolethread, SIGURG);
01869          }
01870       }
01871    }
01872    /* The manager event for shutdown must happen prior to ast_run_atexits, as
01873     * the manager interface will dispose of its sessions as part of its
01874     * shutdown.
01875     */
01876    /*** DOCUMENTATION
01877       <managerEventInstance>
01878          <synopsis>Raised when Asterisk is shutdown or restarted.</synopsis>
01879          <syntax>
01880             <parameter name="Shutdown">
01881                <enumlist>
01882                   <enum name="Uncleanly"/>
01883                   <enum name="Cleanly"/>
01884                </enumlist>
01885             </parameter>
01886             <parameter name="Restart">
01887                <enumlist>
01888                   <enum name="True"/>
01889                   <enum name="False"/>
01890                </enumlist>
01891             </parameter>
01892          </syntax>
01893       </managerEventInstance>
01894    ***/
01895    manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\n"
01896       "Restart: %s\r\n",
01897       ast_active_channels() ? "Uncleanly" : "Cleanly",
01898       restart ? "True" : "False");
01899 
01900    ast_verb(0, "Executing last minute cleanups\n");
01901    ast_run_atexits();
01902    /* Called on exit */
01903    ast_verb(0, "Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
01904    ast_debug(1, "Asterisk ending (%d).\n", num);
01905    if (ast_socket > -1) {
01906       pthread_cancel(lthread);
01907       close(ast_socket);
01908       ast_socket = -1;
01909       unlink(ast_config_AST_SOCKET);
01910    }
01911    if (ast_consock > -1)
01912       close(ast_consock);
01913    if (!ast_opt_remote)
01914       unlink(ast_config_AST_PID);
01915    printf("%s", term_quit());
01916    if (restart) {
01917       int i;
01918       ast_verb(0, "Preparing for Asterisk restart...\n");
01919       /* Mark all FD's for closing on exec */
01920       for (i = 3; i < 32768; i++) {
01921          fcntl(i, F_SETFD, FD_CLOEXEC);
01922       }
01923       ast_verb(0, "Asterisk is now restarting...\n");
01924       restartnow = 1;
01925 
01926       /* close logger */
01927       close_logger();
01928 
01929       /* If there is a consolethread running send it a SIGHUP
01930          so it can execvp, otherwise we can do it ourselves */
01931       if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
01932          pthread_kill(consolethread, SIGHUP);
01933          /* Give the signal handler some time to complete */
01934          sleep(2);
01935       } else
01936          execvp(_argv[0], _argv);
01937 
01938    } else {
01939       /* close logger */
01940       close_logger();
01941    }
01942 
01943    exit(0);
01944 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 2042 of file asterisk.c.

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

Referenced by ast_remotecontrol().

02043 {
02044    int ret = 0;
02045 
02046    /* Called when readline data is available */
02047    if (!ast_all_zeros(s))
02048       ast_el_add_history(s);
02049    /* The real handler for bang */
02050    if (s[0] == '!') {
02051       if (s[1])
02052          ast_safe_system(s+1);
02053       else
02054          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
02055       ret = 1;
02056    } else if (strncasecmp(s, "core set verbose ", 17) == 0) {
02057       int old_verbose = option_verbose;
02058       if (strncasecmp(s + 17, "atleast ", 8) == 0) {
02059          int tmp;
02060          if (sscanf(s + 25, "%d", &tmp) != 1) {
02061             fprintf(stderr, "Usage: core set verbose [atleast] <level>\n");
02062          } else {
02063             if (tmp > option_verbose) {
02064                option_verbose = tmp;
02065             }
02066             if (old_verbose != option_verbose) {
02067                fprintf(stdout, "Set remote console verbosity from %d to %d\n", old_verbose, option_verbose);
02068             } else {
02069                fprintf(stdout, "Verbosity level unchanged.\n");
02070             }
02071          }
02072       } else {
02073          if (sscanf(s + 17, "%d", &option_verbose) != 1) {
02074             fprintf(stderr, "Usage: core set verbose [atleast] <level>\n");
02075          } else {
02076             if (old_verbose != option_verbose) {
02077                fprintf(stdout, "Set remote console verbosity to %d\n", option_verbose);
02078             } else {
02079                fprintf(stdout, "Verbosity level unchanged.\n");
02080             }
02081          }
02082       }
02083       ret = 1;
02084    } else if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
02085        (s[4] == '\0' || isspace(s[4]))) {
02086       quit_handler(0, SHUTDOWN_FAST, 0);
02087       ret = 1;
02088    }
02089 
02090    return ret;
02091 }

static void run_startup_commands ( void   )  [static]

Definition at line 3489 of file asterisk.c.

References ast_cli_command, 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().

03490 {
03491    int fd;
03492    struct ast_config *cfg;
03493    struct ast_flags cfg_flags = { 0 };
03494    struct ast_variable *v;
03495 
03496    if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
03497       return;
03498    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03499       return;
03500    }
03501 
03502    fd = open("/dev/null", O_RDWR);
03503    if (fd < 0) {
03504       ast_config_destroy(cfg);
03505       return;
03506    }
03507 
03508    for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
03509       if (ast_true(v->value))
03510          ast_cli_command(fd, v->name);
03511    }
03512 
03513    close(fd);
03514    ast_config_destroy(cfg);
03515 }

static void set_icon ( char *  text  )  [static]

Definition at line 1708 of file asterisk.c.

Referenced by main().

01709 {
01710    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01711       fprintf(stdout, "\033]1;%s\007", text);
01712 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1702 of file asterisk.c.

Referenced by main().

01703 {
01704    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01705       fprintf(stdout, "\033]2;%s\007", text);
01706 }

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1679 of file asterisk.c.

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

Referenced by ast_readconfig().

01680 {
01681    struct rlimit l = {0, 0};
01682 
01683    if (value <= 0) {
01684       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01685       return;
01686    }
01687 
01688    l.rlim_cur = value;
01689    l.rlim_max = value;
01690 
01691    if (setrlimit(RLIMIT_NOFILE, &l)) {
01692       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01693       return;
01694    }
01695 
01696    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01697 
01698    return;
01699 }

static int show_cli_help ( void   )  [static]

Definition at line 3129 of file asterisk.c.

References ast_get_version().

Referenced by main().

03130 {
03131    printf("Asterisk %s, Copyright (C) 1999 - 2012, Digium, Inc. and others.\n", ast_get_version());
03132    printf("Usage: asterisk [OPTIONS]\n");
03133    printf("Valid Options:\n");
03134    printf("   -V              Display version number and exit\n");
03135    printf("   -C <configfile> Use an alternate configuration file\n");
03136    printf("   -G <group>      Run as a group other than the caller\n");
03137    printf("   -U <user>       Run as a user other than the caller\n");
03138    printf("   -c              Provide console CLI\n");
03139    printf("   -d              Enable extra debugging\n");
03140 #if HAVE_WORKING_FORK
03141    printf("   -f              Do not fork\n");
03142    printf("   -F              Always fork\n");
03143 #endif
03144    printf("   -g              Dump core in case of a crash\n");
03145    printf("   -h              This help screen\n");
03146    printf("   -i              Initialize crypto keys at startup\n");
03147    printf("   -I              Enable internal timing if DAHDI timer is available\n");
03148    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
03149    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
03150    printf("   -m              Mute debugging and console output on the console\n");
03151    printf("   -n              Disable console colorization\n");
03152    printf("   -p              Run as pseudo-realtime thread\n");
03153    printf("   -q              Quiet mode (suppress output)\n");
03154    printf("   -r              Connect to Asterisk on this machine\n");
03155    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
03156    printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
03157    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
03158    printf("                   belong after they are done\n");
03159    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
03160    printf("                   of output to the CLI\n");
03161    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
03162    printf("   -x <cmd>        Execute command <cmd> (implies -r)\n");
03163    printf("   -X              Execute includes by default (allows #exec in asterisk.conf)\n");
03164    printf("   -W              Adjust terminal colors to compensate for a light background\n");
03165    printf("\n");
03166    return 0;
03167 }

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

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

02353 {
02354    switch (cmd) {
02355    case CLI_INIT:
02356       e->command = "core show license";
02357       e->usage =
02358          "Usage: core show license\n"
02359          "       Shows the license(s) for this copy of Asterisk.\n";
02360       return NULL;
02361    case CLI_GENERATE:
02362       return NULL;
02363    }
02364 
02365    ast_cli(a->fd, "%s", license_lines);
02366 
02367    return CLI_SUCCESS;
02368 }

static int show_version ( void   )  [static]

Definition at line 3123 of file asterisk.c.

References ast_get_version().

Referenced by main().

03124 {
03125    printf("Asterisk %s\n", ast_get_version());
03126    return 0;
03127 }

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

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

02316 {
02317    switch (cmd) {
02318    case CLI_INIT:
02319       e->command = "core show warranty";
02320       e->usage =
02321          "Usage: core show warranty\n"
02322          "       Shows the warranty (if any) for this copy of Asterisk.\n";
02323       return NULL;
02324    case CLI_GENERATE:
02325       return NULL;
02326    }
02327 
02328    ast_cli(a->fd, "%s", warranty_lines);
02329 
02330    return CLI_SUCCESS;
02331 }


Variable Documentation

char* _argv[256] [static]

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

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

const char* ast_config_AST_CONFIG_DIR = cfg_paths.config_dir

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

Referenced by ast_readconfig().

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

Definition at line 376 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

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

Definition at line 375 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static]

Definition at line 374 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

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

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

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

const char* ast_config_AST_RUN_GROUP = cfg_paths.run_group

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

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

const char* ast_config_AST_SBIN_DIR = cfg_paths.sbin_dir

Definition at line 365 of file asterisk.c.

Referenced by convert_bdb_to_sqlite3(), and main().

const char* ast_config_AST_SOCKET = cfg_paths.socket_path

Definition at line 369 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

const char* ast_config_AST_SYSTEM_NAME = cfg_paths.system_name

const char* ast_config_AST_VAR_DIR = cfg_paths.var_dir

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

Definition at line 296 of file asterisk.c.

unsigned int ast_FD_SETSIZE

Definition at line 86 of file poll.c.

struct timeval ast_lastreloadtime

pid_t ast_mainpid

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

struct timeval ast_startuptime

char canary_filename[128] [static]

Definition at line 396 of file asterisk.c.

Referenced by canary_thread(), and main().

int canary_pid = 0 [static]

Definition at line 395 of file asterisk.c.

Referenced by canary_exit(), and main().

struct _cfg_paths cfg_paths [static]

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

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 2374 of file asterisk.c.

struct console consoles[AST_MAX_CONNECTS]

pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 393 of file asterisk.c.

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

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 324 of file asterisk.c.

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

EditLine* el [static]

History* el_hist [static]

struct ast_threadstorage el_read_char_state = { .once = PTHREAD_ONCE_INIT , .key_init = __init_el_read_char_state , .custom_init = el_read_char_state_init , } [static]

Definition at line 2413 of file asterisk.c.

Referenced by ast_el_read_char().

struct sigaction hup_handler [static]

Initial value:

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

Definition at line 1653 of file asterisk.c.

struct sigaction ignore_sig_handler [static]

Initial value:

 {
   .sa_handler = SIG_IGN,
}

Definition at line 1103 of file asterisk.c.

Referenced by main().

const char license_lines[] [static]

Definition at line 2333 of file asterisk.c.

pthread_t lthread [static]

Definition at line 1301 of file asterisk.c.

Referenced by ast_makesocket(), and really_quit().

pthread_t mon_sig_flags [static]

Definition at line 394 of file asterisk.c.

Referenced by main(), and really_quit().

unsigned int need_quit

Definition at line 403 of file asterisk.c.

unsigned int need_quit_handler

Definition at line 404 of file asterisk.c.

unsigned int need_reload

Definition at line 402 of file asterisk.c.

struct sigaction null_sig_handler [static]

Initial value:

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

Definition at line 1098 of file asterisk.c.

Referenced by ast_replace_sigchld().

struct profile_data* prof_data [static]

struct ast_str* prompt = NULL [static]

char randompool[256] [static]

Definition at line 398 of file asterisk.c.

Referenced by main().

char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR

Definition at line 293 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 320 of file asterisk.c.

Referenced by ast_remotecontrol(), and cli_prompt().

int restartnow [static]

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

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

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

struct sigaction safe_system_prev_handler [static]

Definition at line 1112 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN [static]

Definition at line 391 of file asterisk.c.

Referenced by can_safely_quit(), and handle_abort_shutdown().

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

Definition at line 400 of file asterisk.c.

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

struct { ... } sig_flags [static]

struct sigaction urg_handler [static]

Initial value:

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

Definition at line 1633 of file asterisk.c.

const char warranty_lines[] [static]

Definition at line 2290 of file asterisk.c.


Generated on Thu Oct 11 06:34:42 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6