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/pickup.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 "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 "asterisk/uuid.h"
#include "asterisk/sorcery.h"
#include "asterisk/bucket.h"
#include "asterisk/stasis.h"
#include "asterisk/json.h"
#include "asterisk/stasis_endpoints.h"
#include "asterisk/stasis_system.h"
#include "asterisk/security_events.h"
#include "asterisk/endpoints.h"
#include "asterisk/codec.h"
#include "asterisk/format_cache.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  console_state_data
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 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 SHUTDOWN_TIMEOUT   15
#define WELCOME_MESSAGE
 Welcome message when starting a CLI interface.

Enumerations

enum  shutdown_nice_t {
  NOT_SHUTTING_DOWN, SHUTTING_DOWN_FINAL, SHUTTING_DOWN, SHUTDOWN_FAST,
  SHUTDOWN_NORMAL, SHUTDOWN_NICE, SHUTDOWN_REALLY_NICE
}

Functions

static void __ast_unregister_atexit (void(*func)(void))
static void __fini_file_versions (void)
static void __fini_thread_list (void)
static void __init_console_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 void ast_begin_shutdown (void)
int ast_cancel_shutdown (void)
 Cancel an existing shutdown and return to normal operation.
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 root console, and all attached network console clients
void ast_console_puts_mutable (const char *string, int level)
 log the string to the root console, and all attached network 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 network 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.
int ast_register_cleanup (void(*func)(void))
 Register a function to be executed before Asterisk gracefully 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 (int run_cleanups)
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.
int ast_shutdown_final (void)
int ast_shutting_down (void)
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 int console_print (const char *s, int local)
static int console_state_init (void *ptr)
static void console_verboser (const char *s)
static void consolehandler (char *s)
static void destroy_match_list (char **match_list, int matches)
static void env_init (void)
static int fdprint (int fd, const char *s)
static int fdsend (int fd, const char *s)
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 main_atexit (void)
static void * monitor_sig_flags (void *unused)
static void * netconsole (void *vconsole)
static void network_verboser (const char *string)
static void print_intro_message (const char *runuser, const char *rungroup)
static void publish_fully_booted (void)
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 register_atexit (void(*func)(void), int is_cleanup)
static int remoteconsolehandler (char *s)
static void run_startup_commands (void)
static void send_rasterisk_connect_commands (void)
static void set_header (char *outbuf, int maxout, char level)
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)
static int wait_for_channels_to_die (shutdown_nice_t niceness, int seconds)

Variables

static char * _argv [256]
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_RECORDING_DIR = cfg_paths.recording_dir
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
char ast_defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE
struct ast_eid ast_eid_default
 Global EID.
unsigned int ast_FD_SETSIZE
struct timeval ast_lastreloadtime
pid_t ast_mainpid
int ast_option_maxcalls
int ast_option_maxfiles
double ast_option_maxload
struct ast_flags ast_options = { AST_DEFAULT_OPTIONS }
static int ast_socket = -1
struct timeval ast_startuptime
int ast_verb_sys_level
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 []
static struct ast_cli_entry cli_asterisk_shutdown []
 Shutdown Asterisk CLI commands.
static struct ast_threadstorage console_state = { .once = PTHREAD_ONCE_INIT , .key_init = __init_console_state , .custom_init = console_state_init , }
struct console consoles [AST_MAX_CONNECTS]
static pthread_t consolethread = AST_PTHREADT_NULL
static EditLineel
static Historyel_hist
static struct sigaction hup_handler
static struct sigaction ignore_sig_handler
static const char license_lines []
static pthread_t lthread
static pthread_t mon_sig_flags
static int multi_thread_safe
static struct sigaction null_sig_handler
int option_debug
unsigned int option_dtmfminduration
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 int shutdown_pending
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 291 of file asterisk.c.

#define AST_MAX_CONNECTS   128

#define AST_MIN_DTMF_DURATION   80

Default minimum DTMF digit length - 80ms

Definition at line 299 of file asterisk.c.

Referenced by ast_readconfig().

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 2678 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

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

Referenced by ast_el_add_history().

#define NUM_MSGS   64

Definition at line 296 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

Definition at line 292 of file asterisk.c.

Referenced by ast_makesocket(), ast_tryconnect(), and ooh323c_start_call_thread().

#define SHUTDOWN_TIMEOUT   15

Definition at line 1934 of file asterisk.c.

Referenced by can_safely_quit().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 303 of file asterisk.c.

Referenced by ast_el_read_char(), and print_intro_message().


Enumeration Type Documentation

Enumerator:
NOT_SHUTTING_DOWN  Normal operation
SHUTTING_DOWN_FINAL  Committed to shutting down. Final phase
SHUTTING_DOWN  Committed to shutting down. Initial phase
SHUTDOWN_FAST  Valid values for quit_handler() niceness below. These shutdown/restart levels can be cancelled.

Remote console exit right now

SHUTDOWN_NORMAL  core stop/restart now
SHUTDOWN_NICE  core stop/restart gracefully
SHUTDOWN_REALLY_NICE  core stop/restart when convenient

Definition at line 434 of file asterisk.c.

00434              {
00435    /*! Normal operation */
00436    NOT_SHUTTING_DOWN,
00437    /*! Committed to shutting down.  Final phase */
00438    SHUTTING_DOWN_FINAL,
00439    /*! Committed to shutting down.  Initial phase */
00440    SHUTTING_DOWN,
00441    /*!
00442     * Valid values for quit_handler() niceness below.
00443     * These shutdown/restart levels can be cancelled.
00444     *
00445     * Remote console exit right now
00446     */
00447    SHUTDOWN_FAST,
00448    /*! core stop/restart now */
00449    SHUTDOWN_NORMAL,
00450    /*! core stop/restart gracefully */
00451    SHUTDOWN_NICE,
00452    /*! core stop/restart when convenient */
00453    SHUTDOWN_REALLY_NICE
00454 } shutdown_nice_t;


Function Documentation

static void __ast_unregister_atexit ( void(*)(void)  func  )  [static]

Definition at line 1141 of file asterisk.c.

References ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_atexit::func, and ast_atexit::list.

Referenced by ast_unregister_atexit(), and register_atexit().

01142 {
01143    struct ast_atexit *ae;
01144 
01145    AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
01146       if (ae->func == func) {
01147          AST_LIST_REMOVE_CURRENT(list);
01148          ast_free(ae);
01149          break;
01150       }
01151    }
01152    AST_LIST_TRAVERSE_SAFE_END;
01153 }

static void __fini_file_versions ( void   )  [static]

Definition at line 484 of file asterisk.c.

00487 {

static void __fini_thread_list ( void   )  [static]

Definition at line 566 of file asterisk.c.

00569 {

static void __init_console_state ( void   )  [static]

Definition at line 2223 of file asterisk.c.

02226 {

static void __init_file_versions ( void   )  [static]

Definition at line 484 of file asterisk.c.

00487 {

static void __init_thread_list ( void   )  [static]

Definition at line 566 of file asterisk.c.

00569 {

static void __quit_handler ( int  num  )  [static]

Definition at line 2160 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

02161 {
02162    int a = 0;
02163    sig_flags.need_quit = 1;
02164    if (sig_alert_pipe[1] != -1) {
02165       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
02166          fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
02167       }
02168    }
02169    /* There is no need to restore the signal handler here, since the app
02170     * is going to exit */
02171 }

static void __remote_quit_handler ( int  num  )  [static]

Definition at line 2173 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

02174 {
02175    sig_flags.need_quit = 1;
02176 }

static void _child_handler ( int  sig  )  [static]

Definition at line 1793 of file asterisk.c.

References errno, and status.

01794 {
01795    /* Must not ever ast_log or ast_verbose within signal handler */
01796    int n, status, save_errno = errno;
01797 
01798    /*
01799     * Reap all dead children -- not just one
01800     */
01801    for (n = 0; waitpid(-1, &status, WNOHANG) > 0; n++)
01802       ;
01803    if (n == 0 && option_debug)
01804       printf("Huh?  Child handler, but nobody there?\n");
01805    errno = save_errno;
01806 }

static void _hup_handler ( int  num  )  [static]

Definition at line 1773 of file asterisk.c.

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

01774 {
01775    int a = 0, save_errno = errno;
01776    printf("Received HUP signal -- Reloading configs\n");
01777    if (restartnow)
01778       execvp(_argv[0], _argv);
01779    sig_flags.need_reload = 1;
01780    if (sig_alert_pipe[1] != -1) {
01781       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01782          fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
01783       }
01784    }
01785    errno = save_errno;
01786 }

static void _null_sig_handler ( int  sig  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 1204 of file asterisk.c.

01205 {
01206 }

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

01764 {
01765    return;
01766 }

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

00878 {
00879    int l = sizeof(struct profile_data);
00880    int n = 10; /* default entries */
00881 
00882    if (prof_data == NULL) {
00883       prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
00884       if (prof_data == NULL)
00885          return -1;
00886       prof_data->entries = 0;
00887       prof_data->max_size = n;
00888    }
00889    if (prof_data->entries >= prof_data->max_size) {
00890       void *p;
00891       n = prof_data->max_size + 20;
00892       p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
00893       if (p == NULL)
00894          return -1;
00895       prof_data = p;
00896       prof_data->max_size = n;
00897    }
00898    n = prof_data->entries++;
00899    prof_data->e[n].name = ast_strdup(name);
00900    prof_data->e[n].value = 0;
00901    prof_data->e[n].events = 0;
00902    prof_data->e[n].mark = 0;
00903    prof_data->e[n].scale = scale;
00904    return n;
00905 }

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 2308 of file asterisk.c.

Referenced by consolehandler(), and remoteconsolehandler().

02309 {
02310    while (*s) {
02311       if (*s > 32)
02312          return 0;
02313       s++;
02314    }
02315    return 1;
02316 }

static void ast_begin_shutdown ( void   )  [static]

int ast_cancel_shutdown ( void   ) 

Cancel an existing shutdown and return to normal operation.

Note:
Shutdown can be cancelled while the server is waiting for any existing channels to be destroyed before shutdown becomes irreversible.
Returns:
non-zero if shutdown cancelled.

Definition at line 1895 of file asterisk.c.

References ast_mutex_lock, ast_mutex_unlock, NOT_SHUTTING_DOWN, safe_system_lock, SHUTDOWN_FAST, shutdown_pending, and shuttingdown.

Referenced by handle_abort_shutdown().

01896 {
01897    int shutdown_aborted = 0;
01898 
01899    ast_mutex_lock(&safe_system_lock);
01900    if (shuttingdown >= SHUTDOWN_FAST) {
01901       shuttingdown = NOT_SHUTTING_DOWN;
01902       shutdown_pending = 0;
01903       shutdown_aborted = 1;
01904    }
01905    ast_mutex_unlock(&safe_system_lock);
01906    return shutdown_aborted;
01907 }

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

Definition at line 3026 of file asterisk.c.

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

Referenced by cli_complete().

03027 {
03028    int i, idx, limit, count;
03029    int screenwidth = 0;
03030    int numoutput = 0, numoutputline = 0;
03031 
03032    screenwidth = ast_get_termcols(STDOUT_FILENO);
03033 
03034    /* find out how many entries can be put on one line, with two spaces between strings */
03035    limit = screenwidth / (max + 2);
03036    if (limit == 0)
03037       limit = 1;
03038 
03039    /* how many lines of output */
03040    count = len / limit;
03041    if (count * limit < len)
03042       count++;
03043 
03044    idx = 1;
03045 
03046    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
03047 
03048    for (; count > 0; count--) {
03049       numoutputline = 0;
03050       for (i = 0; i < limit && matches[idx]; i++, idx++) {
03051 
03052          /* Don't print dupes */
03053          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
03054             i--;
03055             ast_free(matches[idx]);
03056             matches[idx] = NULL;
03057             continue;
03058          }
03059 
03060          numoutput++;
03061          numoutputline++;
03062          fprintf(stdout, "%-*s  ", max, matches[idx]);
03063          ast_free(matches[idx]);
03064          matches[idx] = NULL;
03065       }
03066       if (numoutputline > 0)
03067          fprintf(stdout, "\n");
03068    }
03069 
03070    return numoutput;
03071 }

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

Definition at line 525 of file asterisk.c.

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

Referenced by handle_debug().

00526 {
00527    struct file_version *find;
00528    size_t len = strlen(partial);
00529    int count = 0;
00530    char *res = NULL;
00531 
00532    AST_RWLIST_RDLOCK(&file_versions);
00533    AST_RWLIST_TRAVERSE(&file_versions, find, list) {
00534       if (!strncasecmp(find->file, partial, len) && ++count > n) {
00535          res = ast_strdup(find->file);
00536          break;
00537       }
00538    }
00539    AST_RWLIST_UNLOCK(&file_versions);
00540    return res;
00541 }

void ast_console_puts ( const char *  string  ) 

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

Definition at line 1405 of file asterisk.c.

References ast_network_puts().

01406 {
01407    /* Send to the root console */
01408    fputs(string, stdout);
01409    fflush(stdout);
01410 
01411    /* Send to any network console clients */
01412    ast_network_puts(string);
01413 }

void ast_console_puts_mutable ( const char *  string,
int  level 
)

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

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

Definition at line 1376 of file asterisk.c.

References ast_network_puts_mutable().

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

01377 {
01378    /* Send to the root console */
01379    fputs(string, stdout);
01380    fflush(stdout);
01381 
01382    /* Send to any network console clients */
01383    ast_network_puts_mutable(string, level);
01384 }

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

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

Referenced by handle_logger_set_level().

01313 {
01314    int x;
01315 
01316    if (level >= NUMLOGLEVELS) {
01317       level = NUMLOGLEVELS - 1;
01318    }
01319 
01320    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01321       if (fd == consoles[x].fd) {
01322          /*
01323           * Since the logging occurs when levels are false, set to
01324           * flipped iinput because this function accepts 0 as off and 1 as on
01325           */
01326          consoles[x].levels[level] = state ? 0 : 1;
01327          return;
01328       }
01329    }
01330 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1335 of file asterisk.c.

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

Referenced by handle_logger_mute().

01336 {
01337    int x;
01338    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01339       if (fd == consoles[x].fd) {
01340          if (consoles[x].mute) {
01341             consoles[x].mute = 0;
01342             if (!silent)
01343                ast_cli(fd, "Console is not muted anymore.\n");
01344          } else {
01345             consoles[x].mute = 1;
01346             if (!silent)
01347                ast_cli(fd, "Console is muted.\n");
01348          }
01349          return;
01350       }
01351    }
01352    ast_cli(fd, "Couldn't find remote console.\n");
01353 }

static int ast_el_add_history ( char *  buf  )  [static]

Definition at line 3254 of file asterisk.c.

References ast_el_initialize(), ast_strdupa, ast_strip(), el, el_hist, H_ENTER, H_FIRST, history(), MAX_HISTORY_COMMAND_LENGTH, NULL, and HistEvent::str.

Referenced by consolehandler(), and remoteconsolehandler().

03255 {
03256    HistEvent ev;
03257    char *stripped_buf;
03258 
03259    if (el_hist == NULL || el == NULL) {
03260       ast_el_initialize();
03261    }
03262    if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1)) {
03263       return 0;
03264    }
03265 
03266    stripped_buf = ast_strip(ast_strdupa(buf));
03267 
03268    /* HISTCONTROL=ignoredups */
03269    if (!history(el_hist, &ev, H_FIRST) && strcmp(ev.str, stripped_buf) == 0) {
03270       return 0;
03271    }
03272 
03273    return history(el_hist, &ev, H_ENTER, stripped_buf);
03274 }

static int ast_el_initialize ( void   )  [static]

Definition at line 3199 of file asterisk.c.

References cli_complete(), cli_prompt(), el, EL_ADDFN, EL_BIND, EL_EDITMODE, EL_EDITOR, el_end(), EL_HIST, el_hist, el_init(), EL_PROMPT, el_set(), el_source(), H_SETSIZE, history(), history_end(), history_init(), and NULL.

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

03200 {
03201    HistEvent ev;
03202    char *editor, *editrc = getenv("EDITRC");
03203 
03204    if (!(editor = getenv("AST_EDITMODE"))) {
03205       if (!(editor = getenv("AST_EDITOR"))) {
03206          editor = "emacs";
03207       }
03208    }
03209 
03210    if (el != NULL)
03211       el_end(el);
03212    if (el_hist != NULL)
03213       history_end(el_hist);
03214 
03215    el = el_init("asterisk", stdin, stdout, stderr);
03216    el_set(el, EL_PROMPT, cli_prompt);
03217 
03218    el_set(el, EL_EDITMODE, 1);
03219    el_set(el, EL_EDITOR, editor);
03220    el_hist = history_init();
03221    if (!el || !el_hist)
03222       return -1;
03223 
03224    /* setup history with 100 entries */
03225    history(el_hist, &ev, H_SETSIZE, 100);
03226 
03227    el_set(el, EL_HIST, history, el_hist);
03228 
03229    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
03230    /* Bind <tab> to command completion */
03231    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
03232    /* Bind ? to command completion */
03233    el_set(el, EL_BIND, "?", "ed-complete", NULL);
03234    /* Bind ^D to redisplay */
03235    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
03236    /* Bind Delete to delete char left */
03237    el_set(el, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
03238    /* Bind Home and End to move to line start and end */
03239    el_set(el, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
03240    el_set(el, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
03241    /* Bind C-left and C-right to move by word (not all terminals) */
03242    el_set(el, EL_BIND, "\\eOC", "vi-next-word", NULL);
03243    el_set(el, EL_BIND, "\\eOD", "vi-prev-word", NULL);
03244 
03245    if (editrc) {
03246       el_source(el, editrc);
03247    }
03248 
03249    return 0;
03250 }

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

Definition at line 2740 of file asterisk.c.

References ast_opt_exec, ast_opt_reconnect, ast_poll, ast_tryconnect(), buf, CC_REFRESH, console_print(), EL_BUF_SIZE, errno, max, quit_handler(), send_rasterisk_connect_commands(), SHUTDOWN_FAST, sig_flags, term_quit(), and WELCOME_MESSAGE.

Referenced by ast_remotecontrol(), and main().

02741 {
02742    int num_read = 0;
02743    int lastpos = 0;
02744    struct pollfd fds[2];
02745    int res;
02746    int max;
02747 #define EL_BUF_SIZE 512
02748    char buf[EL_BUF_SIZE];
02749 
02750    for (;;) {
02751       max = 1;
02752       fds[0].fd = ast_consock;
02753       fds[0].events = POLLIN;
02754       if (!ast_opt_exec) {
02755          fds[1].fd = STDIN_FILENO;
02756          fds[1].events = POLLIN;
02757          max++;
02758       }
02759       res = ast_poll(fds, max, -1);
02760       if (res < 0) {
02761          if (sig_flags.need_quit || sig_flags.need_quit_handler)
02762             break;
02763          if (errno == EINTR)
02764             continue;
02765          fprintf(stderr, "poll failed: %s\n", strerror(errno));
02766          break;
02767       }
02768 
02769       if (!ast_opt_exec && fds[1].revents) {
02770          num_read = read(STDIN_FILENO, cp, 1);
02771          if (num_read < 1) {
02772             break;
02773          } else {
02774             return (num_read);
02775          }
02776       }
02777       if (fds[0].revents) {
02778          res = read(ast_consock, buf, sizeof(buf) - 1);
02779          /* if the remote side disappears exit */
02780          if (res < 1) {
02781             fprintf(stderr, "\nDisconnected from Asterisk server\n");
02782             if (!ast_opt_reconnect) {
02783                quit_handler(0, SHUTDOWN_FAST, 0);
02784             } else {
02785                int tries;
02786                int reconnects_per_second = 20;
02787                fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
02788                for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
02789                   if (ast_tryconnect()) {
02790                      fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
02791                      printf("%s", term_quit());
02792                      WELCOME_MESSAGE;
02793                      send_rasterisk_connect_commands();
02794                      break;
02795                   } else
02796                      usleep(1000000 / reconnects_per_second);
02797                }
02798                if (tries >= 30 * reconnects_per_second) {
02799                   fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
02800                   quit_handler(0, SHUTDOWN_FAST, 0);
02801                }
02802             }
02803             continue;
02804          }
02805 
02806          buf[res] = '\0';
02807 
02808          /* Write over the CLI prompt */
02809          if (!ast_opt_exec && !lastpos) {
02810             if (write(STDOUT_FILENO, "\r", 5) < 0) {
02811             }
02812          }
02813 
02814          console_print(buf, 0);
02815 
02816          if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
02817             *cp = CC_REFRESH;
02818             return(1);
02819          } else
02820             lastpos = 1;
02821       }
02822    }
02823 
02824    *cp = '\0';
02825    return (0);
02826 }

static int ast_el_read_history ( char *  filename  )  [static]

Definition at line 3286 of file asterisk.c.

References ast_el_initialize(), el, el_hist, H_LOAD, history(), and NULL.

Referenced by ast_remotecontrol(), and main().

03287 {
03288    HistEvent ev;
03289 
03290    if (el_hist == NULL || el == NULL) {
03291       ast_el_initialize();
03292    }
03293 
03294    return history(el_hist, &ev, H_LOAD, filename);
03295 }

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

Definition at line 3016 of file asterisk.c.

Referenced by ast_cli_display_match_list().

03017 {
03018    char *s1, *s2;
03019 
03020    s1 = ((char **)i1)[0];
03021    s2 = ((char **)i2)[0];
03022 
03023    return strcasecmp(s1, s2);
03024 }

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

Definition at line 2968 of file asterisk.c.

References AST_CLI_COMPLETE_EOF, ast_realloc, ast_strdup, destroy_match_list(), NULL, and strsep().

Referenced by cli_complete().

02969 {
02970    char *retstr;
02971    char **match_list = NULL;
02972    char **new_list;
02973    size_t match_list_len = 1;
02974    int matches = 0;
02975 
02976    while ((retstr = strsep(&buf, " "))) {
02977       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
02978          break;
02979       }
02980       if (matches + 1 >= match_list_len) {
02981          match_list_len <<= 1;
02982          new_list = ast_realloc(match_list, match_list_len * sizeof(char *));
02983          if (!new_list) {
02984             destroy_match_list(match_list, matches);
02985             return NULL;
02986          }
02987          match_list = new_list;
02988       }
02989 
02990       retstr = ast_strdup(retstr);
02991       if (!retstr) {
02992          destroy_match_list(match_list, matches);
02993          return NULL;
02994       }
02995       match_list[matches++] = retstr;
02996    }
02997 
02998    if (!match_list) {
02999       return NULL;
03000    }
03001 
03002    if (matches >= match_list_len) {
03003       new_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *));
03004       if (!new_list) {
03005          destroy_match_list(match_list, matches);
03006          return NULL;
03007       }
03008       match_list = new_list;
03009    }
03010 
03011    match_list[matches] = NULL;
03012 
03013    return match_list;
03014 }

static int ast_el_write_history ( char *  filename  )  [static]

Definition at line 3276 of file asterisk.c.

References ast_el_initialize(), el, el_hist, H_SAVE, history(), and NULL.

Referenced by really_quit().

03277 {
03278    HistEvent ev;
03279 
03280    if (el_hist == NULL || el == NULL)
03281       ast_el_initialize();
03282 
03283    return (history(el_hist, &ev, H_SAVE, filename));
03284 }

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

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

Referenced by manager_modulecheck().

00545 {
00546    struct file_version *iterator;
00547 
00548    AST_RWLIST_WRLOCK(&file_versions);
00549    AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
00550       if (!strcasecmp(iterator->file, file))
00551          break;
00552    }
00553    AST_RWLIST_UNLOCK(&file_versions);
00554    if (iterator)
00555       return iterator->version;
00556    return NULL;
00557 }

static int ast_makesocket ( void   )  [static]

Definition at line 1662 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(), NULL, and PF_LOCAL.

Referenced by main().

01663 {
01664    struct sockaddr_un sunaddr;
01665    int res;
01666    int x;
01667    uid_t uid = -1;
01668    gid_t gid = -1;
01669 
01670    for (x = 0; x < AST_MAX_CONNECTS; x++)
01671       consoles[x].fd = -1;
01672    unlink(ast_config_AST_SOCKET);
01673    ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
01674    if (ast_socket < 0) {
01675       ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
01676       return -1;
01677    }
01678    memset(&sunaddr, 0, sizeof(sunaddr));
01679    sunaddr.sun_family = AF_LOCAL;
01680    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01681    res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01682    if (res) {
01683       ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01684       close(ast_socket);
01685       ast_socket = -1;
01686       return -1;
01687    }
01688    res = listen(ast_socket, 2);
01689    if (res < 0) {
01690       ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01691       close(ast_socket);
01692       ast_socket = -1;
01693       return -1;
01694    }
01695    if (ast_register_verbose(network_verboser)) {
01696       ast_log(LOG_WARNING, "Unable to register network verboser?\n");
01697    }
01698 
01699    if (ast_pthread_create_background(&lthread, NULL, listener, NULL)) {
01700       ast_log(LOG_WARNING, "Unable to create listener thread.\n");
01701       close(ast_socket);
01702       return -1;
01703    }
01704 
01705    if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
01706       struct passwd *pw;
01707       if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
01708          ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
01709       else
01710          uid = pw->pw_uid;
01711    }
01712 
01713    if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
01714       struct group *grp;
01715       if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
01716          ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
01717       else
01718          gid = grp->gr_gid;
01719    }
01720 
01721    if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
01722       ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01723 
01724    if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
01725       unsigned int p1;
01726       mode_t p;
01727       sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
01728       p = p1;
01729       if ((chmod(ast_config_AST_SOCKET, p)) < 0)
01730          ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01731    }
01732 
01733    return 0;
01734 }

int64_t ast_mark ( int  i,
int  startstop 
)

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

00943 {
00944    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00945       return 0;
00946    if (startstop == 1)
00947       prof_data->e[i].mark = rdtsc();
00948    else {
00949       prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
00950       if (prof_data->e[i].scale > 1)
00951          prof_data->e[i].mark /= prof_data->e[i].scale;
00952       prof_data->e[i].value += prof_data->e[i].mark;
00953       prof_data->e[i].events++;
00954    }
00955    return prof_data->e[i].mark;
00956 }

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

write the string to all attached console clients

Definition at line 1389 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

01390 {
01391    int x;
01392 
01393    for (x = 0; x < AST_MAX_CONNECTS; ++x) {
01394       if (consoles[x].fd < 0) {
01395          continue;
01396       }
01397       fdprint(consoles[x].p[1], string);
01398    }
01399 }

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

log the string to all attached network console clients

Definition at line 1358 of file asterisk.c.

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

Referenced by ast_console_puts_mutable().

01359 {
01360    int x;
01361 
01362    for (x = 0; x < AST_MAX_CONNECTS; ++x) {
01363       if (consoles[x].fd < 0
01364          || consoles[x].mute
01365          || consoles[x].levels[level]) {
01366          continue;
01367       }
01368       fdprint(consoles[x].p[1], string);
01369    }
01370 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 907 of file asterisk.c.

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

00908 {
00909    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00910       return 0;
00911    if (prof_data->e[i].scale > 1)
00912       delta /= prof_data->e[i].scale;
00913    prof_data->e[i].value += delta;
00914    prof_data->e[i].events++;
00915    return prof_data->e[i].value;
00916 }

static void ast_readconfig ( void   )  [static]

Definition at line 3489 of file asterisk.c.

References _cfg_paths::agi_dir, AST_CACHE_DIR_LEN, ast_clear_flag, 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_defaultlanguage, 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_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_opt_remote, 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, getloadavg(), hostname, _cfg_paths::key_dir, live_dangerously, _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, pbx_live_dangerously(), _cfg_paths::pid_path, _cfg_paths::recording_dir, _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, and _cfg_paths::var_dir.

Referenced by main().

03490 {
03491    struct ast_config *cfg;
03492    struct ast_variable *v;
03493    char *config = DEFAULT_CONFIG_FILE;
03494    char hostname[MAXHOSTNAMELEN] = "";
03495    struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME };
03496    struct {
03497       unsigned int dbdir:1;
03498       unsigned int keydir:1;
03499    } found = { 0, 0 };
03500    /* Default to false for security */
03501    int live_dangerously = 0;
03502 
03503    /* Set default value */
03504    option_dtmfminduration = AST_MIN_DTMF_DURATION;
03505 
03506    if (ast_opt_override_config) {
03507       cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
03508       if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03509          fprintf(stderr, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
03510       }
03511    } else {
03512       cfg = ast_config_load2(config, "" /* core, can't reload */, config_flags);
03513    }
03514 
03515    /* init with buildtime config */
03516    ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir));
03517    ast_copy_string(cfg_paths.spool_dir, DEFAULT_SPOOL_DIR, sizeof(cfg_paths.spool_dir));
03518    ast_copy_string(cfg_paths.module_dir, DEFAULT_MODULE_DIR, sizeof(cfg_paths.module_dir));
03519    snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", cfg_paths.spool_dir);
03520    snprintf(cfg_paths.recording_dir, sizeof(cfg_paths.recording_dir), "%s/recording", cfg_paths.spool_dir);
03521    ast_copy_string(cfg_paths.var_dir, DEFAULT_VAR_DIR, sizeof(cfg_paths.var_dir));
03522    ast_copy_string(cfg_paths.data_dir, DEFAULT_DATA_DIR, sizeof(cfg_paths.data_dir));
03523    ast_copy_string(cfg_paths.log_dir, DEFAULT_LOG_DIR, sizeof(cfg_paths.log_dir));
03524    ast_copy_string(cfg_paths.agi_dir, DEFAULT_AGI_DIR, sizeof(cfg_paths.agi_dir));
03525    ast_copy_string(cfg_paths.db_path, DEFAULT_DB, sizeof(cfg_paths.db_path));
03526    ast_copy_string(cfg_paths.sbin_dir, DEFAULT_SBIN_DIR, sizeof(cfg_paths.sbin_dir));
03527    ast_copy_string(cfg_paths.key_dir, DEFAULT_KEY_DIR, sizeof(cfg_paths.key_dir));
03528    ast_copy_string(cfg_paths.pid_path, DEFAULT_PID, sizeof(cfg_paths.pid_path));
03529    ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path));
03530    ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir));
03531 
03532    ast_set_default_eid(&ast_eid_default);
03533 
03534    /* no asterisk.conf? no problem, use buildtime config! */
03535    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03536       return;
03537    }
03538 
03539    for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
03540       if (!strcasecmp(v->name, "astctlpermissions"))
03541          ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
03542       else if (!strcasecmp(v->name, "astctlowner"))
03543          ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
03544       else if (!strcasecmp(v->name, "astctlgroup"))
03545          ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
03546       else if (!strcasecmp(v->name, "astctl"))
03547          ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
03548    }
03549 
03550    for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
03551       if (!strcasecmp(v->name, "astetcdir")) {
03552          ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir));
03553       } else if (!strcasecmp(v->name, "astspooldir")) {
03554          ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir));
03555          snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value);
03556          snprintf(cfg_paths.recording_dir, sizeof(cfg_paths.recording_dir), "%s/recording", v->value);
03557       } else if (!strcasecmp(v->name, "astvarlibdir")) {
03558          ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir));
03559          if (!found.dbdir)
03560             snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
03561       } else if (!strcasecmp(v->name, "astdbdir")) {
03562          snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
03563          found.dbdir = 1;
03564       } else if (!strcasecmp(v->name, "astdatadir")) {
03565          ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir));
03566          if (!found.keydir)
03567             snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
03568       } else if (!strcasecmp(v->name, "astkeydir")) {
03569          snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
03570          found.keydir = 1;
03571       } else if (!strcasecmp(v->name, "astlogdir")) {
03572          ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir));
03573       } else if (!strcasecmp(v->name, "astagidir")) {
03574          ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir));
03575       } else if (!strcasecmp(v->name, "astrundir")) {
03576          snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid");
03577          snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", v->value, ast_config_AST_CTL);
03578          ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir));
03579       } else if (!strcasecmp(v->name, "astmoddir")) {
03580          ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir));
03581       } else if (!strcasecmp(v->name, "astsbindir")) {
03582          ast_copy_string(cfg_paths.sbin_dir, v->value, sizeof(cfg_paths.sbin_dir));
03583       }
03584    }
03585 
03586    for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
03587       /* verbose level (-v at startup) */
03588       if (!strcasecmp(v->name, "verbose")) {
03589          option_verbose = atoi(v->value);
03590       /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
03591       } else if (!strcasecmp(v->name, "timestamp")) {
03592          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
03593       /* whether or not to support #exec in config files */
03594       } else if (!strcasecmp(v->name, "execincludes")) {
03595          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
03596       /* debug level (-d at startup) */
03597       } else if (!strcasecmp(v->name, "debug")) {
03598          option_debug = 0;
03599          if (sscanf(v->value, "%30d", &option_debug) != 1) {
03600             option_debug = ast_true(v->value);
03601          }
03602 #if HAVE_WORKING_FORK
03603       /* Disable forking (-f at startup) */
03604       } else if (!strcasecmp(v->name, "nofork")) {
03605          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
03606       /* Always fork, even if verbose or debug are enabled (-F at startup) */
03607       } else if (!strcasecmp(v->name, "alwaysfork")) {
03608          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
03609 #endif
03610       /* Run quietly (-q at startup ) */
03611       } else if (!strcasecmp(v->name, "quiet")) {
03612          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
03613       /* Run as console (-c at startup, implies nofork) */
03614       } else if (!strcasecmp(v->name, "console")) {
03615          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
03616       /* Run with high priority if the O/S permits (-p at startup) */
03617       } else if (!strcasecmp(v->name, "highpriority")) {
03618          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
03619       /* Initialize RSA auth keys (IAX2) (-i at startup) */
03620       } else if (!strcasecmp(v->name, "initcrypto")) {
03621          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
03622       /* Disable ANSI colors for console (-c at startup) */
03623       } else if (!strcasecmp(v->name, "nocolor")) {
03624          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
03625       /* Disable some usage warnings for picky people :p */
03626       } else if (!strcasecmp(v->name, "dontwarn")) {
03627          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
03628       /* Dump core in case of crash (-g) */
03629       } else if (!strcasecmp(v->name, "dumpcore")) {
03630          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
03631       /* Cache recorded sound files to another directory during recording */
03632       } else if (!strcasecmp(v->name, "cache_record_files")) {
03633          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
03634       /* Specify cache directory */
03635       }  else if (!strcasecmp(v->name, "record_cache_dir")) {
03636          ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
03637       /* Build transcode paths via SLINEAR, instead of directly */
03638       } else if (!strcasecmp(v->name, "transcode_via_sln")) {
03639          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
03640       /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
03641       } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
03642          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
03643       /* Enable internal timing */
03644       } else if (!strcasecmp(v->name, "internal_timing")) {
03645          if (!ast_opt_remote) {
03646             fprintf(stderr,
03647                "NOTICE: The internal_timing option is no longer needed.\n"
03648                "  It will always be enabled if you have a timing module loaded.\n");
03649          }
03650       } else if (!strcasecmp(v->name, "mindtmfduration")) {
03651          if (sscanf(v->value, "%30u", &option_dtmfminduration) != 1) {
03652             option_dtmfminduration = AST_MIN_DTMF_DURATION;
03653          }
03654       } else if (!strcasecmp(v->name, "maxcalls")) {
03655          if ((sscanf(v->value, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) {
03656             ast_option_maxcalls = 0;
03657          }
03658       } else if (!strcasecmp(v->name, "maxload")) {
03659          double test[1];
03660 
03661          if (getloadavg(test, 1) == -1) {
03662             ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
03663             ast_option_maxload = 0.0;
03664          } else if ((sscanf(v->value, "%30lf", &ast_option_maxload) != 1) || (ast_option_maxload < 0.0)) {
03665             ast_option_maxload = 0.0;
03666          }
03667       /* Set the maximum amount of open files */
03668       } else if (!strcasecmp(v->name, "maxfiles")) {
03669          ast_option_maxfiles = atoi(v->value);
03670          set_ulimit(ast_option_maxfiles);
03671       /* What user to run as */
03672       } else if (!strcasecmp(v->name, "runuser")) {
03673          ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user));
03674       /* What group to run as */
03675       } else if (!strcasecmp(v->name, "rungroup")) {
03676          ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group));
03677       } else if (!strcasecmp(v->name, "systemname")) {
03678          ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name));
03679       } else if (!strcasecmp(v->name, "autosystemname")) {
03680          if (ast_true(v->value)) {
03681             if (!gethostname(hostname, sizeof(hostname) - 1))
03682                ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name));
03683             else {
03684                if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){
03685                   ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name));
03686                }
03687                ast_log(LOG_ERROR, "Cannot obtain hostname for this system.  Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME);
03688             }
03689          }
03690       } else if (!strcasecmp(v->name, "languageprefix")) {
03691          ast_language_is_prefix = ast_true(v->value);
03692       } else if (!strcasecmp(v->name, "defaultlanguage")) {
03693          ast_copy_string(ast_defaultlanguage, v->value, MAX_LANGUAGE);
03694       } else if (!strcasecmp(v->name, "lockmode")) {
03695          if (!strcasecmp(v->value, "lockfile")) {
03696             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03697          } else if (!strcasecmp(v->value, "flock")) {
03698             ast_set_lock_type(AST_LOCK_TYPE_FLOCK);
03699          } else {
03700             ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, "
03701                "defaulting to 'lockfile'\n", v->value);
03702             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03703          }
03704 #if defined(HAVE_SYSINFO)
03705       } else if (!strcasecmp(v->name, "minmemfree")) {
03706          /* specify the minimum amount of free memory to retain.  Asterisk should stop accepting new calls
03707           * if the amount of free memory falls below this watermark */
03708          if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
03709             option_minmemfree = 0;
03710          }
03711 #endif
03712       } else if (!strcasecmp(v->name, "entityid")) {
03713          struct ast_eid tmp_eid;
03714          if (!ast_str_to_eid(&tmp_eid, v->value)) {
03715             ast_verbose("Successfully set global EID to '%s'\n", v->value);
03716             ast_eid_default = tmp_eid;
03717          } else
03718             ast_verbose("Invalid Entity ID '%s' provided\n", v->value);
03719       } else if (!strcasecmp(v->name, "lightbackground")) {
03720          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND);
03721       } else if (!strcasecmp(v->name, "forceblackbackground")) {
03722          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03723       } else if (!strcasecmp(v->name, "hideconnect")) {
03724          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT);
03725       } else if (!strcasecmp(v->name, "lockconfdir")) {
03726          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LOCK_CONFIG_DIR);
03727       } else if (!strcasecmp(v->name, "stdexten")) {
03728          /* Choose how to invoke the extensions.conf stdexten */
03729          if (!strcasecmp(v->value, "gosub")) {
03730             ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
03731          } else if (!strcasecmp(v->value, "macro")) {
03732             ast_set_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
03733          } else {
03734             ast_log(LOG_WARNING,
03735                "'%s' is not a valid setting for the stdexten option, defaulting to 'gosub'\n",
03736                v->value);
03737             ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
03738          }
03739       } else if (!strcasecmp(v->name, "live_dangerously")) {
03740          live_dangerously = ast_true(v->value);
03741       }
03742    }
03743    if (!ast_opt_remote) {
03744       pbx_live_dangerously(live_dangerously);
03745    }
03746 
03747    ast_config_destroy(cfg);
03748 }

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.
Note:
This function should be rarely used in situations where something must be shutdown to avoid corruption, excessive data loss, or when external programs must be stopped. All other cleanup in the core should use ast_register_cleanup.

Definition at line 1174 of file asterisk.c.

References ast_atexit::func, and register_atexit().

Referenced by ast_cdr_engine_init(), astdb_init(), load_module(), and main().

01175 {
01176    return register_atexit(func, 0);
01177 }

int ast_register_cleanup ( void(*)(void)  func  ) 

Register a function to be executed before Asterisk gracefully exits.

Since:
11.9 If Asterisk is immediately shutdown (core stop now, or sending the TERM signal), the callback is not run. When the callbacks are run, they are run in sequence with ast_register_atexit() callbacks, in the reverse order of registration.
Parameters:
func The callback function to use.
Return values:
0 on success.
-1 on error.

Definition at line 1179 of file asterisk.c.

References ast_atexit::func, and register_atexit().

Referenced by __init_manager(), aco_init(), app_init(), ast_aoc_cli_init(), ast_autoservice_init(), ast_bridging_init(), ast_bucket_init(), ast_builtins_init(), ast_cc_init(), ast_cdr_engine_init(), ast_cel_engine_init(), ast_channels_init(), ast_codec_init(), ast_data_init(), ast_dns_resolver_register(), ast_endpoint_init(), ast_endpoint_stasis_init(), ast_features_init(), ast_file_init(), ast_format_cache_init(), ast_format_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_local_init(), ast_msg_init(), ast_named_acl_init(), ast_parking_stasis_init(), ast_pbx_init(), ast_pickup_init(), ast_presence_state_engine_init(), ast_rtp_engine_init(), ast_security_stasis_init(), ast_sorcery_init(), ast_sounds_index_init(), ast_stasis_bridging_init(), ast_stasis_channels_init(), ast_stasis_system_init(), ast_stun_init(), ast_test_init(), ast_timing_init(), ast_tps_init(), ast_translate_init(), ast_udptl_init(), ast_utils_init(), astobj2_init(), container_init(), devstate_init(), dnsmgr_init(), load_pbx(), main(), manager_bridging_init(), manager_channels_init(), manager_endpoints_init(), manager_mwi_init(), manager_system_init(), register_config_cli(), stasis_cache_init(), and stasis_init().

01180 {
01181    return register_atexit(func, 1);
01182 }

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

00487 {
00488    struct file_version *new;
00489    char *work;
00490    size_t version_length;
00491 
00492    work = ast_strdupa(version);
00493    work = ast_strip(ast_strip_quoted(work, "$", "$"));
00494    version_length = strlen(work) + 1;
00495 
00496    if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
00497       return;
00498 
00499    new->file = file;
00500    new->version = (char *) new + sizeof(*new);
00501    memcpy(new->version, work, version_length);
00502    AST_RWLIST_WRLOCK(&file_versions);
00503    AST_RWLIST_INSERT_HEAD(&file_versions, new, list);
00504    AST_RWLIST_UNLOCK(&file_versions);
00505 }

void ast_register_thread ( char *  name  ) 

Definition at line 568 of file asterisk.c.

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

Referenced by dummy_start().

00569 {
00570    struct thread_list_t *new = ast_calloc(1, sizeof(*new));
00571 
00572    if (!new)
00573       return;
00574 
00575    ast_assert(multi_thread_safe);
00576    new->id = pthread_self();
00577    new->lwp = ast_get_tid();
00578    new->name = name; /* steal the allocated memory for the thread name */
00579    AST_RWLIST_WRLOCK(&thread_list);
00580    AST_RWLIST_INSERT_HEAD(&thread_list, new, list);
00581    AST_RWLIST_UNLOCK(&thread_list);
00582 }

static void ast_remotecontrol ( char *  data  )  [static]

Definition at line 3297 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_poll, ast_strlen_zero, ast_verbose, buf, el, EL_GETCFN, el_gets(), el_hist, el_set(), errno, hostname, LOG_ERROR, LOG_WARNING, NULL, prefix, remoteconsolehandler(), remotehostname, send_rasterisk_connect_commands(), sig_flags, strsep(), tmp(), and version.

Referenced by main().

03298 {
03299    char buf[256] = "";
03300    int res;
03301    char filename[80] = "";
03302    char *hostname;
03303    char *cpid;
03304    char *version;
03305    int pid;
03306    char *stringp = NULL;
03307 
03308    char *ebuf;
03309    int num = 0;
03310 
03311    memset(&sig_flags, 0, sizeof(sig_flags));
03312    signal(SIGINT, __remote_quit_handler);
03313    signal(SIGTERM, __remote_quit_handler);
03314    signal(SIGHUP, __remote_quit_handler);
03315 
03316    if (read(ast_consock, buf, sizeof(buf) - 1) < 0) {
03317       ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
03318       return;
03319    }
03320    if (data) {
03321       char prefix[] = "cli quit after ";
03322       char *tmp = ast_alloca(strlen(data) + strlen(prefix) + 1);
03323       sprintf(tmp, "%s%s", prefix, data);
03324       if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
03325          ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
03326          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
03327             return;
03328          }
03329       }
03330    }
03331    stringp = buf;
03332    hostname = strsep(&stringp, "/");
03333    cpid = strsep(&stringp, "/");
03334    version = strsep(&stringp, "\n");
03335    if (!version)
03336       version = "<Version Unknown>";
03337    stringp = hostname;
03338    strsep(&stringp, ".");
03339    if (cpid)
03340       pid = atoi(cpid);
03341    else
03342       pid = -1;
03343    if (!data) {
03344       send_rasterisk_connect_commands();
03345    }
03346 
03347    if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
03348       int linefull = 1, prev_linefull = 1, prev_line_verbose = 0;
03349       struct pollfd fds;
03350       fds.fd = ast_consock;
03351       fds.events = POLLIN;
03352       fds.revents = 0;
03353 
03354       while (ast_poll(&fds, 1, 60000) > 0) {
03355          char buffer[512] = "", *curline = buffer, *nextline;
03356          int not_written = 1;
03357 
03358          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
03359             break;
03360          }
03361 
03362          if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
03363             break;
03364          }
03365 
03366          do {
03367             prev_linefull = linefull;
03368             if ((nextline = strchr(curline, '\n'))) {
03369                linefull = 1;
03370                nextline++;
03371             } else {
03372                linefull = 0;
03373                nextline = strchr(curline, '\0');
03374             }
03375 
03376             /* Skip verbose lines */
03377             /* Prev line full? | Line is verbose | Last line verbose? | Print
03378              * TRUE            | TRUE*           | TRUE               | FALSE
03379              * TRUE            | TRUE*           | FALSE              | FALSE
03380              * TRUE            | FALSE*          | TRUE               | TRUE
03381              * TRUE            | FALSE*          | FALSE              | TRUE
03382              * FALSE           | TRUE            | TRUE*              | FALSE
03383              * FALSE           | TRUE            | FALSE*             | TRUE
03384              * FALSE           | FALSE           | TRUE*              | FALSE
03385              * FALSE           | FALSE           | FALSE*             | TRUE
03386              */
03387             if ((!prev_linefull && !prev_line_verbose) || (prev_linefull && *curline > 0)) {
03388                prev_line_verbose = 0;
03389                not_written = 0;
03390                if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
03391                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
03392                }
03393             } else {
03394                prev_line_verbose = 1;
03395             }
03396             curline = nextline;
03397          } while (!ast_strlen_zero(curline));
03398 
03399          /* No non-verbose output in 60 seconds. */
03400          if (not_written) {
03401             break;
03402          }
03403       }
03404       return;
03405    }
03406 
03407    ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
03408    remotehostname = hostname;
03409    if (getenv("HOME"))
03410       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
03411    if (el_hist == NULL || el == NULL)
03412       ast_el_initialize();
03413 
03414    el_set(el, EL_GETCFN, ast_el_read_char);
03415 
03416    if (!ast_strlen_zero(filename))
03417       ast_el_read_history(filename);
03418 
03419    for (;;) {
03420       ebuf = (char *)el_gets(el, &num);
03421 
03422       if (sig_flags.need_quit || sig_flags.need_quit_handler) {
03423          break;
03424       }
03425 
03426       if (!ebuf && write(1, "", 1) < 0)
03427          break;
03428 
03429       if (!ast_strlen_zero(ebuf)) {
03430          if (ebuf[strlen(ebuf)-1] == '\n')
03431             ebuf[strlen(ebuf)-1] = '\0';
03432          if (!remoteconsolehandler(ebuf)) {
03433             res = write(ast_consock, ebuf, strlen(ebuf) + 1);
03434             if (res < 1) {
03435                ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
03436                break;
03437             }
03438          }
03439       }
03440    }
03441    printf("\nDisconnected from Asterisk server\n");
03442 }

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

01225 {
01226    unsigned int level;
01227 
01228    ast_mutex_lock(&safe_system_lock);
01229    level = safe_system_level++;
01230 
01231    /* only replace the handler if it has not already been done */
01232    if (level == 0) {
01233       sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
01234    }
01235 
01236    ast_mutex_unlock(&safe_system_lock);
01237 }

static void ast_run_atexits ( int  run_cleanups  )  [static]

Definition at line 1127 of file asterisk.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_atexit::func, ast_atexit::is_cleanup, and ast_atexit::list.

Referenced by really_quit().

01128 {
01129    struct ast_atexit *ae;
01130 
01131    AST_LIST_LOCK(&atexits);
01132    while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
01133       if (ae->func && (!ae->is_cleanup || run_cleanups)) {
01134          ae->func();
01135       }
01136       ast_free(ae);
01137    }
01138    AST_LIST_UNLOCK(&atexits);
01139 }

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 1254 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, NULL, status, WEXITSTATUS, and WIFEXITED.

Referenced by add_email_attachment(), alarmreceiver_exec(), ast_monitor_stop(), AST_TEST_DEFINE(), 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().

01255 {
01256    pid_t pid;
01257    int res;
01258    int status;
01259 
01260 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
01261    ast_replace_sigchld();
01262 
01263 #ifdef HAVE_WORKING_FORK
01264    pid = fork();
01265 #else
01266    pid = vfork();
01267 #endif
01268 
01269    if (pid == 0) {
01270 #ifdef HAVE_CAP
01271       cap_t cap = cap_from_text("cap_net_admin-eip");
01272 
01273       if (cap_set_proc(cap)) {
01274          /* Careful with order! Logging cannot happen after we close FDs */
01275          ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
01276       }
01277       cap_free(cap);
01278 #endif
01279 #ifdef HAVE_WORKING_FORK
01280       if (ast_opt_high_priority)
01281          ast_set_priority(0);
01282       /* Close file descriptors and launch system command */
01283       ast_close_fds_above_n(STDERR_FILENO);
01284 #endif
01285       execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
01286       _exit(1);
01287    } else if (pid > 0) {
01288       for (;;) {
01289          res = waitpid(pid, &status, 0);
01290          if (res > -1) {
01291             res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
01292             break;
01293          } else if (errno != EINTR)
01294             break;
01295       }
01296    } else {
01297       ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
01298       res = -1;
01299    }
01300 
01301    ast_unreplace_sigchld();
01302 #else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */
01303    res = -1;
01304 #endif
01305 
01306    return res;
01307 }

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

01854 {
01855    struct sched_param sched;
01856    memset(&sched, 0, sizeof(sched));
01857 #ifdef __linux__
01858    if (pri) {
01859       sched.sched_priority = 10;
01860       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01861          ast_log(LOG_WARNING, "Unable to set high priority\n");
01862          return -1;
01863       } else
01864          ast_verb(1, "Set to realtime thread\n");
01865    } else {
01866       sched.sched_priority = 0;
01867       /* According to the manpage, these parameters can never fail. */
01868       sched_setscheduler(0, SCHED_OTHER, &sched);
01869    }
01870 #else
01871    if (pri) {
01872       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01873          ast_log(LOG_WARNING, "Unable to set high priority\n");
01874          return -1;
01875       } else
01876          ast_verb(1, "Set to high priority\n");
01877    } else {
01878       /* According to the manpage, these parameters can never fail. */
01879       setpriority(PRIO_PROCESS, 0, 0);
01880    }
01881 #endif
01882    return 0;
01883 }

int ast_shutdown_final ( void   ) 

Returns:
non-zero if the server is actively shutting down.
Since:
13.3.0
The server is releasing resources and unloading modules. It won't be long now.

Definition at line 1885 of file asterisk.c.

References SHUTTING_DOWN_FINAL, and shuttingdown.

Referenced by httpd_process_request(), and send_notify().

01886 {
01887    return shuttingdown == SHUTTING_DOWN_FINAL;
01888 }

int ast_shutting_down ( void   ) 

The server is preventing new channel creation in preparation for shutdown and may actively be releasing resources. The shutdown process may be canceled by ast_cancel_shutdown() if it is not too late.

Note:
The preparation to shutdown phase can be quite lengthy if we are gracefully shutting down. How long existing calls will last is not up to us.
Returns:
non-zero if the server is preparing to or actively shutting down.

Definition at line 1890 of file asterisk.c.

References shutdown_pending.

Referenced by __ast_channel_alloc_ap(), confbridge_exec(), handle_request_options(), and options_on_rx_request().

01891 {
01892    return shutdown_pending;
01893 }

static int ast_tryconnect ( void   )  [static]

Definition at line 1736 of file asterisk.c.

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

Referenced by ast_el_read_char(), and main().

01737 {
01738    struct sockaddr_un sunaddr;
01739    int res;
01740    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01741    if (ast_consock < 0) {
01742       fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
01743       return 0;
01744    }
01745    memset(&sunaddr, 0, sizeof(sunaddr));
01746    sunaddr.sun_family = AF_LOCAL;
01747    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01748    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01749    if (res) {
01750       close(ast_consock);
01751       ast_consock = -1;
01752       return 0;
01753    } else
01754       return 1;
01755 }

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

References __ast_unregister_atexit(), AST_LIST_LOCK, AST_LIST_UNLOCK, and ast_atexit::func.

Referenced by unload_module().

01185 {
01186    AST_LIST_LOCK(&atexits);
01187    __ast_unregister_atexit(func);
01188    AST_LIST_UNLOCK(&atexits);
01189 }

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

00508 {
00509    struct file_version *find;
00510 
00511    AST_RWLIST_WRLOCK(&file_versions);
00512    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
00513       if (!strcasecmp(find->file, file)) {
00514          AST_RWLIST_REMOVE_CURRENT(list);
00515          break;
00516       }
00517    }
00518    AST_RWLIST_TRAVERSE_SAFE_END;
00519    AST_RWLIST_UNLOCK(&file_versions);
00520 
00521    if (find)
00522       ast_free(find);
00523 }

void ast_unregister_thread ( void *  id  ) 

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

00585 {
00586    struct thread_list_t *x;
00587 
00588    AST_RWLIST_WRLOCK(&thread_list);
00589    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
00590       if ((void *) x->id == id) {
00591          AST_RWLIST_REMOVE_CURRENT(list);
00592          break;
00593       }
00594    }
00595    AST_RWLIST_TRAVERSE_SAFE_END;
00596    AST_RWLIST_UNLOCK(&thread_list);
00597    if (x) {
00598       ast_free(x->name);
00599       ast_free(x);
00600    }
00601 }

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

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

Referenced by ast_safe_fork_cleanup(), and ast_safe_system().

01240 {
01241    unsigned int level;
01242 
01243    ast_mutex_lock(&safe_system_lock);
01244    level = --safe_system_level;
01245 
01246    /* only restore the handler if we are the last one */
01247    if (level == 0) {
01248       sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
01249    }
01250 
01251    ast_mutex_unlock(&safe_system_lock);
01252 }

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

Definition at line 1977 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_softhangup_all(), ast_verb, ast_verbose, NOT_SHUTTING_DOWN, safe_system_lock, SHUTDOWN_NICE, SHUTDOWN_NORMAL, SHUTDOWN_REALLY_NICE, SHUTDOWN_TIMEOUT, SHUTTING_DOWN, SHUTTING_DOWN_FINAL, shuttingdown, and wait_for_channels_to_die().

Referenced by quit_handler().

01978 {
01979    int waited = 0;
01980 
01981    /* Check if someone else isn't already doing this. */
01982    ast_mutex_lock(&safe_system_lock);
01983    if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
01984       /* Already in progress and other request was less nice. */
01985       ast_mutex_unlock(&safe_system_lock);
01986       ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
01987       return 0;
01988    }
01989    shuttingdown = niceness;
01990    ast_mutex_unlock(&safe_system_lock);
01991 
01992    /* Try to get as many CDRs as possible submitted to the backend engines
01993     * (if in batch mode). really_quit happens to call it again when running
01994     * the atexit handlers, otherwise this would be a bit early. */
01995    ast_cdr_engine_term();
01996 
01997    /*
01998     * Shutdown the message queue for the technology agnostic message channel.
01999     * This has to occur before we pause shutdown pending ast_undestroyed_channels.
02000     *
02001     * XXX This is not reversed on shutdown cancel.
02002     */
02003    ast_msg_shutdown();
02004 
02005    if (niceness == SHUTDOWN_NORMAL) {
02006       /* Begin shutdown routine, hanging up active channels */
02007       ast_begin_shutdown();
02008       if (ast_opt_console) {
02009          ast_verb(0, "Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
02010       }
02011       ast_softhangup_all();
02012       waited |= wait_for_channels_to_die(niceness, SHUTDOWN_TIMEOUT);
02013    } else if (niceness >= SHUTDOWN_NICE) {
02014       if (niceness != SHUTDOWN_REALLY_NICE) {
02015          ast_begin_shutdown();
02016       }
02017       if (ast_opt_console) {
02018          ast_verb(0, "Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
02019       }
02020       waited |= wait_for_channels_to_die(niceness, -1);
02021    }
02022 
02023    /* Re-acquire lock and check if someone changed the niceness, in which
02024     * case someone else has taken over the shutdown.
02025     */
02026    ast_mutex_lock(&safe_system_lock);
02027    if (shuttingdown != niceness) {
02028       if (shuttingdown == NOT_SHUTTING_DOWN && ast_opt_console) {
02029          ast_verb(0, "Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
02030       }
02031       ast_mutex_unlock(&safe_system_lock);
02032       return 0;
02033    }
02034 
02035    if (niceness >= SHUTDOWN_REALLY_NICE) {
02036       shuttingdown = SHUTTING_DOWN;
02037       ast_mutex_unlock(&safe_system_lock);
02038 
02039       /* No more Mr. Nice guy.  We are committed to shutting down now. */
02040       ast_begin_shutdown();
02041       ast_softhangup_all();
02042       waited |= wait_for_channels_to_die(SHUTTING_DOWN, SHUTDOWN_TIMEOUT);
02043 
02044       ast_mutex_lock(&safe_system_lock);
02045    }
02046    shuttingdown = SHUTTING_DOWN_FINAL;
02047    ast_mutex_unlock(&safe_system_lock);
02048 
02049    if (niceness >= SHUTDOWN_NORMAL && waited) {
02050       /*
02051        * We were not idle.  Give things in progress a chance to
02052        * recognize the final shutdown phase.
02053        */
02054       sleep(1);
02055    }
02056    return 1;
02057 }

static void canary_exit ( void   )  [static]

Definition at line 3805 of file asterisk.c.

References canary_pid.

Referenced by main().

03806 {
03807    if (canary_pid > 0)
03808       kill(canary_pid, SIGKILL);
03809 }

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

Definition at line 3776 of file asterisk.c.

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

Referenced by main().

03777 {
03778    struct stat canary_stat;
03779    struct timeval now;
03780 
03781    /* Give the canary time to sing */
03782    sleep(120);
03783 
03784    for (;;) {
03785       now = ast_tvnow();
03786       if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
03787          ast_log(LOG_WARNING,
03788             "The canary is no more.  He has ceased to be!  "
03789             "He's expired and gone to meet his maker!  "
03790             "He's a stiff!  Bereft of life, he rests in peace.  "
03791             "His metabolic processes are now history!  He's off the twig!  "
03792             "He's kicked the bucket.  He's shuffled off his mortal coil, "
03793             "run down the curtain, and joined the bleeding choir invisible!!  "
03794             "THIS is an EX-CANARY.  (Reducing priority)\n");
03795          ast_set_priority(0);
03796          pthread_exit(NULL);
03797       }
03798 
03799       /* Check the canary once a minute */
03800       sleep(60);
03801    }
03802 }

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

Definition at line 3074 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, buf, lineinfo::buffer, CC_ERROR, CC_REDISPLAY, CC_REFRESH, lineinfo::cursor, el_deletestr(), el_insertstr(), el_line(), fdsend(), NULL, and retval.

Referenced by ast_el_initialize().

03075 {
03076    int len = 0;
03077    char *ptr;
03078    int nummatches = 0;
03079    char **matches;
03080    int retval = CC_ERROR;
03081    char buf[2048], savechr;
03082    int res;
03083 
03084    LineInfo *lf = (LineInfo *)el_line(editline);
03085 
03086    savechr = *(char *)lf->cursor;
03087    *(char *)lf->cursor = '\0';
03088    ptr = (char *)lf->cursor;
03089    if (ptr) {
03090       while (ptr > lf->buffer) {
03091          if (isspace(*ptr)) {
03092             ptr++;
03093             break;
03094          }
03095          ptr--;
03096       }
03097    }
03098 
03099    len = lf->cursor - ptr;
03100 
03101    if (ast_opt_remote) {
03102       snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);
03103       fdsend(ast_consock, buf);
03104       if ((res = read(ast_consock, buf, sizeof(buf) - 1)) < 0) {
03105          return (char*)(CC_ERROR);
03106       }
03107       buf[res] = '\0';
03108       nummatches = atoi(buf);
03109 
03110       if (nummatches > 0) {
03111          char *mbuf;
03112          char *new_mbuf;
03113          int mlen = 0, maxmbuf = 2048;
03114 
03115          /* Start with a 2048 byte buffer */
03116          if (!(mbuf = ast_malloc(maxmbuf))) {
03117             *((char *) lf->cursor) = savechr;
03118             return (char *)(CC_ERROR);
03119          }
03120          snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);
03121          fdsend(ast_consock, buf);
03122          res = 0;
03123          mbuf[0] = '\0';
03124          while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
03125             if (mlen + 1024 > maxmbuf) {
03126                /* Every step increment buffer 1024 bytes */
03127                maxmbuf += 1024;
03128                new_mbuf = ast_realloc(mbuf, maxmbuf);
03129                if (!new_mbuf) {
03130                   ast_free(mbuf);
03131                   *((char *) lf->cursor) = savechr;
03132                   return (char *)(CC_ERROR);
03133                }
03134                mbuf = new_mbuf;
03135             }
03136             /* Only read 1024 bytes at a time */
03137             res = read(ast_consock, mbuf + mlen, 1024);
03138             if (res > 0)
03139                mlen += res;
03140          }
03141          mbuf[mlen] = '\0';
03142 
03143          matches = ast_el_strtoarr(mbuf);
03144          ast_free(mbuf);
03145       } else
03146          matches = (char **) NULL;
03147    } else {
03148       char **p, *oldbuf=NULL;
03149       nummatches = 0;
03150       matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
03151       for (p = matches; p && *p; p++) {
03152          if (!oldbuf || strcmp(*p,oldbuf))
03153             nummatches++;
03154          oldbuf = *p;
03155       }
03156    }
03157 
03158    if (matches) {
03159       int i;
03160       int matches_num, maxlen, match_len;
03161 
03162       if (matches[0][0] != '\0') {
03163          el_deletestr(editline, (int) len);
03164          el_insertstr(editline, matches[0]);
03165          retval = CC_REFRESH;
03166       }
03167 
03168       if (nummatches == 1) {
03169          /* Found an exact match */
03170          el_insertstr(editline, " ");
03171          retval = CC_REFRESH;
03172       } else {
03173          /* Must be more than one match */
03174          for (i = 1, maxlen = 0; matches[i]; i++) {
03175             match_len = strlen(matches[i]);
03176             if (match_len > maxlen)
03177                maxlen = match_len;
03178          }
03179          matches_num = i - 1;
03180          if (matches_num >1) {
03181             fprintf(stdout, "\n");
03182             ast_cli_display_match_list(matches, nummatches, maxlen);
03183             retval = CC_REDISPLAY;
03184          } else {
03185             el_insertstr(editline," ");
03186             retval = CC_REFRESH;
03187          }
03188       }
03189       for (i = 0; matches[i]; i++)
03190          ast_free(matches[i]);
03191       ast_free(matches);
03192    }
03193 
03194    *((char *) lf->cursor) = savechr;
03195 
03196    return (char *)(long)retval;
03197 }

static char* cli_prompt ( EditLine editline  )  [static]

Definition at line 2830 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_term_color_code(), ast_tvnow(), ASTERISK_PROMPT, COLOR_BLACK, COLOR_WHITE, getloadavg(), hostname, ast_atexit::list, MAXHOSTNAMELEN, NULL, prompt, remotehostname, and tmp().

Referenced by ast_el_initialize().

02831 {
02832    char tmp[100];
02833    char *pfmt;
02834    int color_used = 0;
02835    static int cli_prompt_changes = 0;
02836    struct passwd *pw;
02837    struct group *gr;
02838 
02839    if (prompt == NULL) {
02840       prompt = ast_str_create(100);
02841    } else if (!cli_prompt_changes) {
02842       return ast_str_buffer(prompt);
02843    } else {
02844       ast_str_reset(prompt);
02845    }
02846 
02847    if ((pfmt = getenv("ASTERISK_PROMPT"))) {
02848       char *t = pfmt;
02849       struct timeval ts = ast_tvnow();
02850       while (*t != '\0') {
02851          if (*t == '%') {
02852             char hostname[MAXHOSTNAMELEN] = "";
02853             int i, which;
02854             struct ast_tm tm = { 0, };
02855             int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
02856 
02857             t++;
02858             switch (*t) {
02859             case 'C': /* color */
02860                t++;
02861                if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
02862                   ast_term_color_code(&prompt, fgcolor, bgcolor);
02863                   t += i - 1;
02864                } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
02865                   ast_term_color_code(&prompt, fgcolor, 0);
02866                   t += i - 1;
02867                }
02868 
02869                /* If the color has been reset correctly, then there's no need to reset it later */
02870                color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
02871                break;
02872             case 'd': /* date */
02873                if (ast_localtime(&ts, &tm, NULL)) {
02874                   ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
02875                   ast_str_append(&prompt, 0, "%s", tmp);
02876                   cli_prompt_changes++;
02877                }
02878                break;
02879             case 'g': /* group */
02880                if ((gr = getgrgid(getgid()))) {
02881                   ast_str_append(&prompt, 0, "%s", gr->gr_name);
02882                }
02883                break;
02884             case 'h': /* hostname */
02885                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02886                   ast_str_append(&prompt, 0, "%s", hostname);
02887                } else {
02888                   ast_str_append(&prompt, 0, "%s", "localhost");
02889                }
02890                break;
02891             case 'H': /* short hostname */
02892                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02893                   char *dotptr;
02894                   if ((dotptr = strchr(hostname, '.'))) {
02895                      *dotptr = '\0';
02896                   }
02897                   ast_str_append(&prompt, 0, "%s", hostname);
02898                } else {
02899                   ast_str_append(&prompt, 0, "%s", "localhost");
02900                }
02901                break;
02902 #ifdef HAVE_GETLOADAVG
02903             case 'l': /* load avg */
02904                t++;
02905                if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
02906                   double list[3];
02907                   getloadavg(list, 3);
02908                   ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
02909                   cli_prompt_changes++;
02910                }
02911                break;
02912 #endif
02913             case 's': /* Asterisk system name (from asterisk.conf) */
02914                ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
02915                break;
02916             case 't': /* time */
02917                if (ast_localtime(&ts, &tm, NULL)) {
02918                   ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
02919                   ast_str_append(&prompt, 0, "%s", tmp);
02920                   cli_prompt_changes++;
02921                }
02922                break;
02923             case 'u': /* username */
02924                if ((pw = getpwuid(getuid()))) {
02925                   ast_str_append(&prompt, 0, "%s", pw->pw_name);
02926                }
02927                break;
02928             case '#': /* process console or remote? */
02929                ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
02930                break;
02931             case '%': /* literal % */
02932                ast_str_append(&prompt, 0, "%c", '%');
02933                break;
02934             case '\0': /* % is last character - prevent bug */
02935                t--;
02936                break;
02937             }
02938          } else {
02939             ast_str_append(&prompt, 0, "%c", *t);
02940          }
02941          t++;
02942       }
02943       if (color_used) {
02944          /* Force colors back to normal at end */
02945          ast_term_color_code(&prompt, 0, 0);
02946       }
02947    } else {
02948       ast_str_set(&prompt, 0, "%s%s",
02949          remotehostname ? remotehostname : "",
02950          ASTERISK_PROMPT);
02951    }
02952 
02953    return ast_str_buffer(prompt);
02954 }

static int console_print ( const char *  s,
int  local 
) [static]

Definition at line 2225 of file asterisk.c.

References ast_strlen_zero, ast_threadstorage_get(), c, console_state, prefix, set_header(), VERBOSE_HASMAGIC, console_state_data::verbose_line_level, and VERBOSE_MAGIC2LEVEL.

Referenced by ast_el_read_char(), and console_verboser().

02226 {
02227    struct console_state_data *state =
02228       ast_threadstorage_get(&console_state, sizeof(*state));
02229 
02230    char prefix[80];
02231    const char *c;
02232    int num, res = 0;
02233    unsigned int newline;
02234 
02235    do {
02236       if (VERBOSE_HASMAGIC(s)) {
02237 
02238          /* always use the given line's level, otherwise
02239             we'll use the last line's level */
02240          state->verbose_line_level = VERBOSE_MAGIC2LEVEL(s);
02241 
02242          /* move past magic */
02243          s++;
02244 
02245          set_header(prefix, sizeof(prefix), state->verbose_line_level);
02246       } else {
02247          *prefix = '\0';
02248       }
02249       c = s;
02250 
02251       /* for a given line separate on verbose magic, newline, and eol */
02252       if ((s = strchr(c, '\n'))) {
02253          ++s;
02254          newline = 1;
02255       } else {
02256          s = strchr(c, '\0');
02257          newline = 0;
02258       }
02259 
02260       /* check if we should write this line after calculating begin/end
02261          so we process the case of a higher level line embedded within
02262          two lower level lines */
02263       if (state->verbose_line_level > option_verbose) {
02264          continue;
02265       }
02266 
02267       if (!ast_strlen_zero(prefix)) {
02268          fputs(prefix, stdout);
02269       }
02270 
02271       num = s - c;
02272       if (fwrite(c, sizeof(char), num, stdout) < num) {
02273          break;
02274       }
02275 
02276       if (!res) {
02277          /* if at least some info has been written
02278             we'll want to return true */
02279          res = 1;
02280       }
02281    } while (*s);
02282 
02283    if (newline) {
02284       /* if ending on a newline then reset last level to zero
02285           since what follows may be not be logging output */
02286       state->verbose_line_level = 0;
02287    }
02288 
02289    if (res) {
02290       fflush(stdout);
02291    }
02292 
02293    return res;
02294 }

static int console_state_init ( void *  ptr  )  [static]

Definition at line 2216 of file asterisk.c.

References console_state_data::verbose_line_level.

02217 {
02218    struct console_state_data *state = ptr;
02219    state->verbose_line_level = 0;
02220    return 0;
02221 }

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

Definition at line 2296 of file asterisk.c.

References ast_opt_console, AST_PTHREADT_NULL, console_print(), and consolethread.

Referenced by print_intro_message().

02297 {
02298    if (!console_print(s, 1)) {
02299       return;
02300    }
02301 
02302    /* Wake up a poll()ing console */
02303    if (ast_opt_console && consolethread != AST_PTHREADT_NULL) {
02304       pthread_kill(consolethread, SIGURG);
02305    }
02306 }

static void consolehandler ( char *  s  )  [static]

Definition at line 2319 of file asterisk.c.

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

Referenced by main().

02320 {
02321    printf("%s", term_end());
02322    fflush(stdout);
02323 
02324    /* Called when readline data is available */
02325    if (!ast_all_zeros(s))
02326       ast_el_add_history(s);
02327    /* The real handler for bang */
02328    if (s[0] == '!') {
02329       if (s[1])
02330          ast_safe_system(s+1);
02331       else
02332          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
02333    } else
02334       ast_cli_command(STDOUT_FILENO, s);
02335 }

static void destroy_match_list ( char **  match_list,
int  matches 
) [static]

Definition at line 2956 of file asterisk.c.

References ast_free.

Referenced by ast_cli_completion_matches(), and ast_el_strtoarr().

02957 {
02958    if (match_list) {
02959       int idx;
02960 
02961       for (idx = 0; idx < matches; ++idx) {
02962          ast_free(match_list[idx]);
02963       }
02964       ast_free(match_list);
02965    }
02966 }

static void env_init ( void   )  [static]

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

03841 {
03842    setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
03843    setenv("AST_BUILD_HOST", ast_build_hostname, 1);
03844    setenv("AST_BUILD_DATE", ast_build_date, 1);
03845    setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
03846    setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
03847    setenv("AST_BUILD_OS", ast_build_os, 1);
03848    setenv("AST_BUILD_USER", ast_build_user, 1);
03849    setenv("AST_VERSION", ast_get_version(), 1);
03850 }

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

Definition at line 1198 of file asterisk.c.

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

01199 {
01200    return write(fd, s, strlen(s));
01201 }

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

Definition at line 1192 of file asterisk.c.

Referenced by cli_complete(), and send_rasterisk_connect_commands().

01193 {
01194    return write(fd, s, strlen(s) + 1);
01195 }

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

Definition at line 2561 of file asterisk.c.

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

02562 {
02563    switch (cmd) {
02564    case CLI_INIT:
02565       e->command = "core abort shutdown";
02566       e->usage =
02567          "Usage: core abort shutdown\n"
02568          "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
02569          "       call operations.\n";
02570       return NULL;
02571    case CLI_GENERATE:
02572       return NULL;
02573    }
02574 
02575    if (a->argc != e->args)
02576       return CLI_SHOWUSAGE;
02577 
02578    ast_cancel_shutdown();
02579 
02580    return CLI_SUCCESS;
02581 }

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

Definition at line 2583 of file asterisk.c.

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

02584 {
02585    switch (cmd) {
02586    case CLI_INIT:
02587       e->command = "!";
02588       e->usage =
02589          "Usage: !<command>\n"
02590          "       Executes a given shell command\n";
02591       return NULL;
02592    case CLI_GENERATE:
02593       return NULL;
02594    }
02595 
02596    return CLI_SUCCESS;
02597 }

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

Definition at line 1006 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, max, min, profile_entry::name, NULL, prof_data, ast_cli_entry::usage, and profile_entry::value.

01007 {
01008    int i, min, max;
01009    const char *search = NULL;
01010    switch (cmd) {
01011    case CLI_INIT:
01012       e->command = "core clear profile";
01013       e->usage = "Usage: core clear profile\n"
01014             "       clear profile information";
01015       return NULL;
01016    case CLI_GENERATE:
01017       return NULL;
01018    }
01019 
01020    if (prof_data == NULL)
01021       return 0;
01022 
01023    DEFINE_PROFILE_MIN_MAX_VALUES;
01024    for (i= min; i < max; i++) {
01025       if (!search || strstr(prof_data->e[i].name, search)) {
01026          prof_data->e[i].value = 0;
01027          prof_data->e[i].events = 0;
01028       }
01029    }
01030    return CLI_SUCCESS;
01031 }

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

Definition at line 2521 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, NULL, quit_handler(), SHUTDOWN_NICE, and ast_cli_entry::usage.

02522 {
02523    switch (cmd) {
02524    case CLI_INIT:
02525       e->command = "core restart gracefully";
02526       e->usage =
02527          "Usage: core restart gracefully\n"
02528          "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
02529          "       restart when all active calls have ended.\n";
02530       return NULL;
02531    case CLI_GENERATE:
02532       return NULL;
02533    }
02534 
02535    if (a->argc != e->args)
02536       return CLI_SHOWUSAGE;
02537    quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
02538    return CLI_SUCCESS;
02539 }

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

Definition at line 2501 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, NULL, quit_handler(), SHUTDOWN_NORMAL, and ast_cli_entry::usage.

02502 {
02503    switch (cmd) {
02504    case CLI_INIT:
02505       e->command = "core restart now";
02506       e->usage =
02507          "Usage: core restart now\n"
02508          "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
02509          "       restart.\n";
02510       return NULL;
02511    case CLI_GENERATE:
02512       return NULL;
02513    }
02514 
02515    if (a->argc != e->args)
02516       return CLI_SHOWUSAGE;
02517    quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
02518    return CLI_SUCCESS;
02519 }

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

Definition at line 2541 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, NULL, quit_handler(), SHUTDOWN_REALLY_NICE, and ast_cli_entry::usage.

02542 {
02543    switch (cmd) {
02544    case CLI_INIT:
02545       e->command = "core restart when convenient";
02546       e->usage =
02547          "Usage: core restart when convenient\n"
02548          "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
02549       return NULL;
02550    case CLI_GENERATE:
02551       return NULL;
02552    }
02553 
02554    if (a->argc != e->args)
02555       return CLI_SHOWUSAGE;
02556    ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
02557    quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
02558    return CLI_SUCCESS;
02559 }

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

Definition at line 971 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, max, profile_data::max_size, min, profile_entry::name, NULL, prof_data, profile_entry::scale, ast_cli_entry::usage, and profile_entry::value.

00972 {
00973    int i, min, max;
00974    const char *search = NULL;
00975    switch (cmd) {
00976    case CLI_INIT:
00977       e->command = "core show profile";
00978       e->usage = "Usage: core show profile\n"
00979             "       show profile information";
00980       return NULL;
00981    case CLI_GENERATE:
00982       return NULL;
00983    }
00984 
00985    if (prof_data == NULL)
00986       return 0;
00987 
00988    DEFINE_PROFILE_MIN_MAX_VALUES;
00989    ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
00990       prof_data->entries, prof_data->max_size);
00991    ast_cli(a->fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
00992          "Value", "Average", "Name");
00993    for (i = min; i < max; i++) {
00994       struct profile_entry *entry = &prof_data->e[i];
00995       if (!search || strstr(entry->name, search))
00996           ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
00997          i,
00998          (long)entry->scale,
00999          (long)entry->events, (long long)entry->value,
01000          (long long)(entry->events ? entry->value / entry->events : entry->value),
01001          entry->name);
01002    }
01003    return CLI_SUCCESS;
01004 }

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

References ast_active_channels(), ast_build_date, ast_build_kernel, ast_build_machine, ast_build_os, ast_build_user, ast_cdr_is_enabled(), 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_defaultlanguage, 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_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_realtime_enabled(), ast_startuptime, ast_strftime(), ast_test_flag, ast_verb_console_get(), buf, check_manager_enabled(), check_webmanager_enabled(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, S_OR, and ast_cli_entry::usage.

00605 {
00606    char buf[BUFSIZ];
00607    struct ast_tm tm;
00608    char eid_str[128];
00609 
00610    switch (cmd) {
00611    case CLI_INIT:
00612       e->command = "core show settings";
00613       e->usage = "Usage: core show settings\n"
00614             "       Show core misc settings";
00615       return NULL;
00616    case CLI_GENERATE:
00617       return NULL;
00618    }
00619 
00620    ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
00621 
00622    ast_cli(a->fd, "\nPBX Core settings\n");
00623    ast_cli(a->fd, "-----------------\n");
00624    ast_cli(a->fd, "  Version:                     %s\n", ast_get_version());
00625    ast_cli(a->fd, "  Build Options:               %s\n", S_OR(AST_BUILDOPTS, "(none)"));
00626    if (ast_option_maxcalls)
00627       ast_cli(a->fd, "  Maximum calls:               %d (Current %d)\n", ast_option_maxcalls, ast_active_channels());
00628    else
00629       ast_cli(a->fd, "  Maximum calls:               Not set\n");
00630    if (ast_option_maxfiles)
00631       ast_cli(a->fd, "  Maximum open file handles:   %d\n", ast_option_maxfiles);
00632    else
00633       ast_cli(a->fd, "  Maximum open file handles:   Not set\n");
00634    ast_cli(a->fd, "  Root console verbosity:      %d\n", option_verbose);
00635    ast_cli(a->fd, "  Current console verbosity:   %d\n", ast_verb_console_get());
00636    ast_cli(a->fd, "  Debug level:                 %d\n", option_debug);
00637    ast_cli(a->fd, "  Maximum load average:        %lf\n", ast_option_maxload);
00638 #if defined(HAVE_SYSINFO)
00639    ast_cli(a->fd, "  Minimum free memory:         %ld MB\n", option_minmemfree);
00640 #endif
00641    if (ast_localtime(&ast_startuptime, &tm, NULL)) {
00642       ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
00643       ast_cli(a->fd, "  Startup time:                %s\n", buf);
00644    }
00645    if (ast_localtime(&ast_lastreloadtime, &tm, NULL)) {
00646       ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
00647       ast_cli(a->fd, "  Last reload time:            %s\n", buf);
00648    }
00649    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);
00650    ast_cli(a->fd, "  System name:                 %s\n", ast_config_AST_SYSTEM_NAME);
00651    ast_cli(a->fd, "  Entity ID:                   %s\n", eid_str);
00652    ast_cli(a->fd, "  Default language:            %s\n", ast_defaultlanguage);
00653    ast_cli(a->fd, "  Language prefix:             %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
00654    ast_cli(a->fd, "  User name and group:         %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
00655    ast_cli(a->fd, "  Executable includes:         %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
00656    ast_cli(a->fd, "  Transcode via SLIN:          %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
00657    ast_cli(a->fd, "  Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled");
00658    ast_cli(a->fd, "  Generic PLC:                 %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");
00659    ast_cli(a->fd, "  Min DTMF duration::          %u\n", option_dtmfminduration);
00660 
00661    ast_cli(a->fd, "\n* Subsystems\n");
00662    ast_cli(a->fd, "  -------------\n");
00663    ast_cli(a->fd, "  Manager (AMI):               %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
00664    ast_cli(a->fd, "  Web Manager (AMI/HTTP):      %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled");
00665    ast_cli(a->fd, "  Call data records:           %s\n", ast_cdr_is_enabled() ? "Enabled" : "Disabled");
00666    ast_cli(a->fd, "  Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
00667 
00668    /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues  */
00669 
00670    ast_cli(a->fd, "\n* Directories\n");
00671    ast_cli(a->fd, "  -------------\n");
00672    ast_cli(a->fd, "  Configuration file:          %s\n", ast_config_AST_CONFIG_FILE);
00673    ast_cli(a->fd, "  Configuration directory:     %s\n", ast_config_AST_CONFIG_DIR);
00674    ast_cli(a->fd, "  Module directory:            %s\n", ast_config_AST_MODULE_DIR);
00675    ast_cli(a->fd, "  Spool directory:             %s\n", ast_config_AST_SPOOL_DIR);
00676    ast_cli(a->fd, "  Log directory:               %s\n", ast_config_AST_LOG_DIR);
00677    ast_cli(a->fd, "  Run/Sockets directory:       %s\n", ast_config_AST_RUN_DIR);
00678    ast_cli(a->fd, "  PID file:                    %s\n", ast_config_AST_PID);
00679    ast_cli(a->fd, "  VarLib directory:            %s\n", ast_config_AST_VAR_DIR);
00680    ast_cli(a->fd, "  Data directory:              %s\n", ast_config_AST_DATA_DIR);
00681    ast_cli(a->fd, "  ASTDB:                       %s\n", ast_config_AST_DB);
00682    ast_cli(a->fd, "  IAX2 Keys directory:         %s\n", ast_config_AST_KEY_DIR);
00683    ast_cli(a->fd, "  AGI Scripts directory:       %s\n", ast_config_AST_AGI_DIR);
00684    ast_cli(a->fd, "\n\n");
00685    return CLI_SUCCESS;
00686 }

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

Definition at line 688 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, NULL, and ast_cli_entry::usage.

00689 {
00690    int count = 0;
00691    struct thread_list_t *cur;
00692    switch (cmd) {
00693    case CLI_INIT:
00694       e->command = "core show threads";
00695       e->usage =
00696          "Usage: core show threads\n"
00697          "       List threads currently active in the system.\n";
00698       return NULL;
00699    case CLI_GENERATE:
00700       return NULL;
00701    }
00702 
00703    AST_RWLIST_RDLOCK(&thread_list);
00704    AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
00705       ast_cli(a->fd, "%p %d %s\n", (void *)cur->id, cur->lwp, cur->name);
00706       count++;
00707    }
00708    AST_RWLIST_UNLOCK(&thread_list);
00709    ast_cli(a->fd, "%d threads listed.\n", count);
00710    return CLI_SUCCESS;
00711 }

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 1035 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, NULL, ast_cli_args::pos, ast_cli_entry::usage, file_version::version, and ast_cli_args::word.

01036 {
01037 #define FORMAT "%-25.25s %-40.40s\n"
01038    struct file_version *iterator;
01039    regex_t regexbuf;
01040    int havepattern = 0;
01041    int havename = 0;
01042    int count_files = 0;
01043    char *ret = NULL;
01044    int matchlen, which = 0;
01045    struct file_version *find;
01046 
01047    switch (cmd) {
01048    case CLI_INIT:
01049       e->command = "core show file version [like]";
01050       e->usage =
01051          "Usage: core show file version [like <pattern>]\n"
01052          "       Lists the revision numbers of the files used to build this copy of Asterisk.\n"
01053          "       Optional regular expression pattern is used to filter the file list.\n";
01054       return NULL;
01055    case CLI_GENERATE:
01056       matchlen = strlen(a->word);
01057       if (a->pos != 3)
01058          return NULL;
01059       AST_RWLIST_RDLOCK(&file_versions);
01060       AST_RWLIST_TRAVERSE(&file_versions, find, list) {
01061          if (!strncasecmp(a->word, find->file, matchlen) && ++which > a->n) {
01062             ret = ast_strdup(find->file);
01063             break;
01064          }
01065       }
01066       AST_RWLIST_UNLOCK(&file_versions);
01067       return ret;
01068    }
01069 
01070 
01071    switch (a->argc) {
01072    case 6:
01073       if (!strcasecmp(a->argv[4], "like")) {
01074          if (regcomp(&regexbuf, a->argv[5], REG_EXTENDED | REG_NOSUB))
01075             return CLI_SHOWUSAGE;
01076          havepattern = 1;
01077       } else
01078          return CLI_SHOWUSAGE;
01079       break;
01080    case 5:
01081       havename = 1;
01082       break;
01083    case 4:
01084       break;
01085    default:
01086       return CLI_SHOWUSAGE;
01087    }
01088 
01089    ast_cli(a->fd, FORMAT, "File", "Revision");
01090    ast_cli(a->fd, FORMAT, "----", "--------");
01091    AST_RWLIST_RDLOCK(&file_versions);
01092    AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
01093       if (havename && strcasecmp(iterator->file, a->argv[4]))
01094          continue;
01095 
01096       if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
01097          continue;
01098 
01099       ast_cli(a->fd, FORMAT, iterator->file, iterator->version);
01100       count_files++;
01101       if (havename)
01102          break;
01103    }
01104    AST_RWLIST_UNLOCK(&file_versions);
01105    if (!havename) {
01106       ast_cli(a->fd, "%d files listed.\n", count_files);
01107    }
01108 
01109    if (havepattern)
01110       regfree(&regexbuf);
01111 
01112    return CLI_SUCCESS;
01113 #undef FORMAT
01114 }

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

Definition at line 2461 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, NULL, quit_handler(), SHUTDOWN_NICE, and ast_cli_entry::usage.

02462 {
02463    switch (cmd) {
02464    case CLI_INIT:
02465       e->command = "core stop gracefully";
02466       e->usage =
02467          "Usage: core stop gracefully\n"
02468          "       Causes Asterisk to not accept new calls, and exit when all\n"
02469          "       active calls have terminated normally.\n";
02470       return NULL;
02471    case CLI_GENERATE:
02472       return NULL;
02473    }
02474 
02475    if (a->argc != e->args)
02476       return CLI_SHOWUSAGE;
02477    quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
02478    return CLI_SUCCESS;
02479 }

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

Definition at line 2442 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, NULL, quit_handler(), SHUTDOWN_NORMAL, and ast_cli_entry::usage.

02443 {
02444    switch (cmd) {
02445    case CLI_INIT:
02446       e->command = "core stop now";
02447       e->usage =
02448          "Usage: core stop now\n"
02449          "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
02450       return NULL;
02451    case CLI_GENERATE:
02452       return NULL;
02453    }
02454 
02455    if (a->argc != e->args)
02456       return CLI_SHOWUSAGE;
02457    quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
02458    return CLI_SUCCESS;
02459 }

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

Definition at line 2481 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, NULL, quit_handler(), SHUTDOWN_REALLY_NICE, and ast_cli_entry::usage.

02482 {
02483    switch (cmd) {
02484    case CLI_INIT:
02485       e->command = "core stop when convenient";
02486       e->usage =
02487          "Usage: core stop when convenient\n"
02488          "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
02489       return NULL;
02490    case CLI_GENERATE:
02491       return NULL;
02492    }
02493 
02494    if (a->argc != e->args)
02495       return CLI_SHOWUSAGE;
02496    ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
02497    quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
02498    return CLI_SUCCESS;
02499 }

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

Definition at line 2411 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, NULL, and ast_cli_entry::usage.

02412 {
02413    switch (cmd) {
02414    case CLI_INIT:
02415       e->command = "core show version";
02416       e->usage =
02417          "Usage: core show version\n"
02418          "       Shows Asterisk version information.\n";
02419       return NULL;
02420    case CLI_GENERATE:
02421       return NULL;
02422    }
02423 
02424    if (a->argc != 3)
02425       return CLI_SHOWUSAGE;
02426    ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
02427       ast_get_version(), ast_build_user, ast_build_hostname,
02428       ast_build_machine, ast_build_os, ast_build_date);
02429    return CLI_SUCCESS;
02430 }

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

Definition at line 1585 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(), NULL, console::option_verbose, and console::uid.

Referenced by ast_makesocket(), ast_taskprocessor_get(), ast_taskprocessor_listener_alloc(), AST_TEST_DEFINE(), ast_threadpool_listener_alloc(), ast_threadpool_serializer(), default_tps_processing_function(), and taskprocessor_listener_dtor().

01586 {
01587    struct sockaddr_un sunaddr;
01588    int s;
01589    socklen_t len;
01590    int x;
01591    int flags;
01592    struct pollfd fds[1];
01593    for (;;) {
01594       if (ast_socket < 0)
01595          return NULL;
01596       fds[0].fd = ast_socket;
01597       fds[0].events = POLLIN;
01598       s = ast_poll(fds, 1, -1);
01599       pthread_testcancel();
01600       if (s < 0) {
01601          if (errno != EINTR)
01602             ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
01603          continue;
01604       }
01605       len = sizeof(sunaddr);
01606       s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
01607       if (s < 0) {
01608          if (errno != EINTR)
01609             ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
01610       } else {
01611 #if defined(SO_PASSCRED)
01612          int sckopt = 1;
01613          /* turn on socket credentials passing. */
01614          if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
01615             ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
01616          } else
01617 #endif
01618          {
01619             for (x = 0; x < AST_MAX_CONNECTS; x++) {
01620                if (consoles[x].fd >= 0) {
01621                   continue;
01622                }
01623                if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
01624                   ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
01625                   fdprint(s, "Server failed to create pipe\n");
01626                   close(s);
01627                   break;
01628                }
01629                flags = fcntl(consoles[x].p[1], F_GETFL);
01630                fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
01631                consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
01632                /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
01633                   to know if the user didn't send the credentials. */
01634                consoles[x].uid = -2;
01635                consoles[x].gid = -2;
01636                /* Server default of remote console verbosity level is OFF. */
01637                consoles[x].option_verbose = 0;
01638                consoles[x].fd = s;
01639                if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
01640                   consoles[x].fd = -1;
01641                   ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
01642                   close(consoles[x].p[0]);
01643                   close(consoles[x].p[1]);
01644                   fdprint(s, "Server failed to spawn thread\n");
01645                   close(s);
01646                }
01647                break;
01648             }
01649             if (x >= AST_MAX_CONNECTS) {
01650                fdprint(s, "No more connections allowed\n");
01651                ast_log(LOG_WARNING, "No more connections allowed\n");
01652                close(s);
01653             } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
01654                ast_verb(3, "Remote UNIX connection\n");
01655             }
01656          }
01657       }
01658    }
01659    return NULL;
01660 }

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

References __ast_mm_init_phase_1(), __ast_mm_init_phase_2(), __quit_handler(), _argv, aco_init(), app_init(), ARRAY_LEN, ast_alaw_init(), ast_aoc_cli_init(), ast_autoservice_init(), ast_bridging_init(), ast_bucket_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_codec_builtin_init(), ast_codec_init(), 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_endpoint_init(), ast_endpoint_stasis_init(), ast_enum_init(), ast_fd_init(), ast_FD_SETSIZE, ast_FDMAX, ast_features_init(), ast_file_init(), ast_format_cache_init(), ast_format_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_json_init(), ast_language_is_prefix, ast_lastreloadtime, ast_local_init(), 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_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_parking_stasis_init(), ast_pbx_init(), ast_pickup_init(), ast_presence_state_engine_init(), ast_process_pending_reloads(), ast_pthread_create_detached, ast_readconfig(), ast_register_atexit(), ast_register_cleanup(), ast_remotecontrol(), ast_rtp_engine_init(), ast_security_stasis_init(), ast_select(), ast_set_flag, ast_set_priority(), ast_sorcery_init(), ast_sounds_index_init(), ast_ssl_init(), ast_startuptime, ast_stasis_system_init(), 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_uuid_init(), ast_verb, ast_xmldoc_load_documentation(), astdb_init(), astobj2_init(), buf, c, callerid_init(), canary_exit(), canary_filename, canary_pid, canary_thread(), cfg_paths, child_handler, cli_asterisk, cli_asterisk_shutdown, COLOR_BRGREEN, COLORIZE, COLORIZE_FMT, _cfg_paths::config_file, consolehandler(), consolethread, devstate_init(), dnsmgr_init(), dnsmgr_start_refresh(), el, EL_GETCFN, el_gets(), el_hist, el_set(), env_init(), errno, f, FD_SET, FD_ZERO, hostname, hup_handler, ignore_sig_handler, init_logger(), init_manager(), load_modules(), load_pbx(), LOG_WARNING, logger_queue_start(), main_atexit(), MAXHOSTNAMELEN, mon_sig_flags, monitor_sig_flags(), multi_thread_safe, NULL, print_intro_message(), publish_fully_booted(), 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, stasis_init(), tdd_init(), term_end(), term_quit(), threadstorage_init(), and urg_handler.

03875 {
03876    int c;
03877    char filename[80] = "";
03878    char hostname[MAXHOSTNAMELEN] = "";
03879    char * xarg = NULL;
03880    int x;
03881    FILE *f;
03882    sigset_t sigs;
03883    int num;
03884    int isroot = 1, rundir_exists = 0;
03885    char *buf;
03886    const char *runuser = NULL, *rungroup = NULL;
03887    char *remotesock = NULL;
03888    int moduleresult;         /*!< Result from the module load subsystem */
03889    struct rlimit l;
03890 
03891    /* Remember original args for restart */
03892    if (argc > ARRAY_LEN(_argv) - 1) {
03893       fprintf(stderr, "Truncating argument size to %d\n", (int)ARRAY_LEN(_argv) - 1);
03894       argc = ARRAY_LEN(_argv) - 1;
03895    }
03896    for (x = 0; x < argc; x++)
03897       _argv[x] = argv[x];
03898    _argv[x] = NULL;
03899 
03900    if (geteuid() != 0)
03901       isroot = 0;
03902 
03903    /* if the progname is rasterisk consider it a remote console */
03904    if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
03905       ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03906    }
03907    if (gethostname(hostname, sizeof(hostname)-1))
03908       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
03909    ast_mainpid = getpid();
03910 
03911    if (getenv("HOME"))
03912       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
03913    /*! \brief Check for options
03914     *
03915     * \todo Document these options
03916     */
03917    while ((c = getopt(argc, argv, "BC:cde:FfG:ghIiL:M:mnpqRrs:TtU:VvWXx:")) != -1) {
03918       /*!\note Please keep the ordering here to alphabetical, capital letters
03919        * first.  This will make it easier in the future to select unused
03920        * option flags for new features. */
03921       switch (c) {
03922       case 'B': /* Force black background */
03923          ast_set_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03924          ast_clear_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
03925          break;
03926       case 'X':
03927          ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES);
03928          break;
03929       case 'C':
03930          ast_copy_string(cfg_paths.config_file, optarg, sizeof(cfg_paths.config_file));
03931          ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
03932          break;
03933       case 'c':
03934          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
03935          break;
03936       case 'd':
03937          option_debug++;
03938          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03939          break;
03940 #if defined(HAVE_SYSINFO)
03941       case 'e':
03942          if ((sscanf(&optarg[1], "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
03943             option_minmemfree = 0;
03944          }
03945          break;
03946 #endif
03947 #if HAVE_WORKING_FORK
03948       case 'F':
03949          ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
03950          break;
03951       case 'f':
03952          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03953          break;
03954 #endif
03955       case 'G':
03956          rungroup = ast_strdupa(optarg);
03957          break;
03958       case 'g':
03959          ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
03960          break;
03961       case 'h':
03962          show_cli_help();
03963          exit(0);
03964       case 'I':
03965          fprintf(stderr,
03966             "NOTICE: The -I option is no longer needed.\n"
03967             "  It will always be enabled if you have a timing module loaded.\n");
03968          break;
03969       case 'i':
03970          ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
03971          break;
03972       case 'L':
03973          if ((sscanf(optarg, "%30lf", &ast_option_maxload) != 1) || (ast_option_maxload < 0.0)) {
03974             ast_option_maxload = 0.0;
03975          }
03976          break;
03977       case 'M':
03978          if ((sscanf(optarg, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) {
03979             ast_option_maxcalls = 0;
03980          }
03981          break;
03982       case 'm':
03983          ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
03984          break;
03985       case 'n':
03986          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
03987          break;
03988       case 'p':
03989          ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
03990          break;
03991       case 'q':
03992          ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
03993          break;
03994       case 'R':
03995          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
03996          break;
03997       case 'r':
03998          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03999          break;
04000       case 's':
04001          remotesock = ast_strdupa(optarg);
04002          break;
04003       case 'T':
04004          ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
04005          break;
04006       case 't':
04007          ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
04008          break;
04009       case 'U':
04010          runuser = ast_strdupa(optarg);
04011          break;
04012       case 'V':
04013          show_version();
04014          exit(0);
04015       case 'v':
04016          option_verbose++;
04017          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
04018          break;
04019       case 'W': /* White background */
04020          ast_set_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
04021          ast_clear_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
04022          break;
04023       case 'x':
04024          /* -r is implied by -x so set the flags -r sets as well. */
04025          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
04026 
04027          ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC | AST_OPT_FLAG_NO_COLOR);
04028          xarg = ast_strdupa(optarg);
04029          break;
04030       case '?':
04031          exit(1);
04032       }
04033    }
04034 
04035    /* For remote connections, change the name of the remote connection.
04036     * We do this for the benefit of init scripts (which need to know if/when
04037     * the main asterisk process has died yet). */
04038    if (ast_opt_remote) {
04039       strcpy(argv[0], "rasterisk");
04040       for (x = 1; x < argc; x++) {
04041          argv[x] = argv[0] + 10;
04042       }
04043    }
04044 
04045    ast_readconfig();
04046    env_init();
04047 
04048    if (ast_opt_remote && remotesock != NULL)
04049       ast_copy_string((char *) cfg_paths.socket_path, remotesock, sizeof(cfg_paths.socket_path));
04050 
04051    if (!ast_language_is_prefix && !ast_opt_remote) {
04052       fprintf(stderr, "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");
04053    }
04054 
04055    if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
04056       fprintf(stderr, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
04057       ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
04058    }
04059 
04060    if (ast_opt_dump_core) {
04061       memset(&l, 0, sizeof(l));
04062       l.rlim_cur = RLIM_INFINITY;
04063       l.rlim_max = RLIM_INFINITY;
04064       if (setrlimit(RLIMIT_CORE, &l)) {
04065          fprintf(stderr, "Unable to disable core size resource limit: %s\n", strerror(errno));
04066       }
04067    }
04068 
04069    if (getrlimit(RLIMIT_NOFILE, &l)) {
04070       fprintf(stderr, "Unable to check file descriptor limit: %s\n", strerror(errno));
04071    }
04072 
04073 #if !defined(CONFIGURE_RAN_AS_ROOT)
04074    /* Check if select(2) will run with more file descriptors */
04075    do {
04076       int fd, fd2;
04077       ast_fdset readers;
04078       struct timeval tv = { 0, };
04079 
04080       if (l.rlim_cur <= FD_SETSIZE) {
04081          /* The limit of select()able FDs is irrelevant, because we'll never
04082           * open one that high. */
04083          break;
04084       }
04085 
04086       if (!(fd = open("/dev/null", O_RDONLY))) {
04087          fprintf(stderr, "Cannot open a file descriptor at boot? %s\n", strerror(errno));
04088          break; /* XXX Should we exit() here? XXX */
04089       }
04090 
04091       fd2 = ((l.rlim_cur > sizeof(readers) * 8) ? sizeof(readers) * 8 : l.rlim_cur) - 1;
04092       if (dup2(fd, fd2) < 0) {
04093          fprintf(stderr, "Cannot open maximum file descriptor %d at boot? %s\n", fd2, strerror(errno));
04094          close(fd);
04095          break;
04096       }
04097 
04098       FD_ZERO(&readers);
04099       FD_SET(fd2, &readers);
04100       if (ast_select(fd2 + 1, &readers, NULL, NULL, &tv) < 0) {
04101          fprintf(stderr, "Maximum select()able file descriptor is %d\n", FD_SETSIZE);
04102       }
04103       ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
04104       close(fd);
04105       close(fd2);
04106    } while (0);
04107 #elif defined(HAVE_VARIABLE_FDSET)
04108    ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
04109 #endif /* !defined(CONFIGURE_RAN_AS_ROOT) */
04110 
04111    if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
04112       rungroup = ast_config_AST_RUN_GROUP;
04113    if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
04114       runuser = ast_config_AST_RUN_USER;
04115 
04116    /* Must install this signal handler up here to ensure that if the canary
04117     * fails to execute that it doesn't kill the Asterisk process.
04118     */
04119    sigaction(SIGCHLD, &child_handler, NULL);
04120 
04121    /* It's common on some platforms to clear /var/run at boot.  Create the
04122     * socket file directory before we drop privileges. */
04123    if (mkdir(ast_config_AST_RUN_DIR, 0755)) {
04124       if (errno == EEXIST) {
04125          rundir_exists = 1;
04126       } else {
04127          fprintf(stderr, "Unable to create socket file directory.  Remote consoles will not be able to connect! (%s)\n", strerror(x));
04128       }
04129    }
04130 
04131 #ifndef __CYGWIN__
04132 
04133    if (isroot) {
04134       ast_set_priority(ast_opt_high_priority);
04135    }
04136 
04137    if (isroot && rungroup) {
04138       struct group *gr;
04139       gr = getgrnam(rungroup);
04140       if (!gr) {
04141          fprintf(stderr, "No such group '%s'!\n", rungroup);
04142          exit(1);
04143       }
04144       if (!rundir_exists && chown(ast_config_AST_RUN_DIR, -1, gr->gr_gid)) {
04145          fprintf(stderr, "Unable to chgrp run directory to %d (%s)\n", (int) gr->gr_gid, rungroup);
04146       }
04147       if (setgid(gr->gr_gid)) {
04148          fprintf(stderr, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
04149          exit(1);
04150       }
04151       if (setgroups(0, NULL)) {
04152          fprintf(stderr, "Unable to drop unneeded groups\n");
04153          exit(1);
04154       }
04155    }
04156 
04157    if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
04158 #ifdef HAVE_CAP
04159       int has_cap = 1;
04160 #endif /* HAVE_CAP */
04161       struct passwd *pw;
04162       pw = getpwnam(runuser);
04163       if (!pw) {
04164          fprintf(stderr, "No such user '%s'!\n", runuser);
04165          exit(1);
04166       }
04167       if (chown(ast_config_AST_RUN_DIR, pw->pw_uid, -1)) {
04168          fprintf(stderr, "Unable to chown run directory to %d (%s)\n", (int) pw->pw_uid, runuser);
04169       }
04170 #ifdef HAVE_CAP
04171       if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
04172          ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
04173          has_cap = 0;
04174       }
04175 #endif /* HAVE_CAP */
04176       if (!isroot && pw->pw_uid != geteuid()) {
04177          fprintf(stderr, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
04178          exit(1);
04179       }
04180       if (!rungroup) {
04181          if (setgid(pw->pw_gid)) {
04182             fprintf(stderr, "Unable to setgid to %d!\n", (int)pw->pw_gid);
04183             exit(1);
04184          }
04185          if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
04186             fprintf(stderr, "Unable to init groups for '%s'\n", runuser);
04187             exit(1);
04188          }
04189       }
04190       if (setuid(pw->pw_uid)) {
04191          fprintf(stderr, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
04192          exit(1);
04193       }
04194 #ifdef HAVE_CAP
04195       if (has_cap) {
04196          cap_t cap;
04197 
04198          cap = cap_from_text("cap_net_admin=eip");
04199 
04200          if (cap_set_proc(cap)) {
04201             fprintf(stderr, "Unable to install capabilities.\n");
04202          }
04203          if (cap_free(cap)) {
04204             fprintf(stderr, "Unable to drop capabilities.\n");
04205          }
04206       }
04207 #endif /* HAVE_CAP */
04208    }
04209 
04210 #endif /* __CYGWIN__ */
04211 
04212 #ifdef linux
04213    if (geteuid() && ast_opt_dump_core) {
04214       if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
04215          fprintf(stderr, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
04216       }
04217    }
04218 #endif
04219 
04220    {
04221 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
04222 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
04223 #define eaccess euidaccess
04224 #endif
04225       char dir[PATH_MAX];
04226       if (!getcwd(dir, sizeof(dir)) || eaccess(dir, R_OK | X_OK | F_OK)) {
04227          fprintf(stderr, "Unable to access the running directory (%s).  Changing to '/' for compatibility.\n", strerror(errno));
04228          /* If we cannot access the CWD, then we couldn't dump core anyway,
04229           * so chdir("/") won't break anything. */
04230          if (chdir("/")) {
04231             /* chdir(/) should never fail, so this ends up being a no-op */
04232             fprintf(stderr, "chdir(\"/\") failed?!! %s\n", strerror(errno));
04233          }
04234       } else
04235 #endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */
04236       if (!ast_opt_no_fork && !ast_opt_dump_core) {
04237          /* Backgrounding, but no cores, so chdir won't break anything. */
04238          if (chdir("/")) {
04239             fprintf(stderr, "Unable to chdir(\"/\") ?!! %s\n", strerror(errno));
04240          }
04241       }
04242    }
04243 
04244    /* Initial value of the maximum active system verbosity level. */
04245    ast_verb_sys_level = option_verbose;
04246 
04247    if (ast_tryconnect()) {
04248       /* One is already running */
04249       if (ast_opt_remote) {
04250          multi_thread_safe = 1;
04251          if (ast_opt_exec) {
04252             ast_remotecontrol(xarg);
04253             quit_handler(0, SHUTDOWN_FAST, 0);
04254             exit(0);
04255          }
04256          print_intro_message(runuser, rungroup);
04257          printf("%s", term_quit());
04258          ast_remotecontrol(NULL);
04259          quit_handler(0, SHUTDOWN_FAST, 0);
04260          exit(0);
04261       } else {
04262          fprintf(stderr, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
04263          printf("%s", term_quit());
04264          exit(1);
04265       }
04266    } else if (ast_opt_remote || ast_opt_exec) {
04267       fprintf(stderr, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
04268       printf("%s", term_quit());
04269       exit(1);
04270    }
04271 
04272    /* This needs to remain as high up in the initial start up as possible.
04273     * daemon causes a fork to occur, which has all sorts of unintended
04274     * consequences for things that interact with threads.  This call *must*
04275     * occur before anything in Asterisk spawns or manipulates thread related
04276     * primitives. */
04277 #if HAVE_WORKING_FORK
04278    if (ast_opt_always_fork || !ast_opt_no_fork) {
04279 #ifndef HAVE_SBIN_LAUNCHD
04280       if (daemon(1, 0) < 0) {
04281          fprintf(stderr, "daemon() failed: %s\n", strerror(errno));
04282       } else {
04283          ast_mainpid = getpid();
04284       }
04285 #else
04286       fprintf(stderr, "Mac OS X detected.  Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
04287 #endif
04288    }
04289 #endif
04290 
04291    /* At this point everything has been forked successfully,
04292     * we have determined that we aren't attempting to connect to
04293     * an Asterisk instance, and that there isn't one already running. */
04294    multi_thread_safe = 1;
04295 
04296 #if defined(__AST_DEBUG_MALLOC)
04297    __ast_mm_init_phase_1();
04298 #endif   /* defined(__AST_DEBUG_MALLOC) */
04299 
04300    /* Spawning of astcanary must happen AFTER the call to daemon(3) */
04301    if (isroot && ast_opt_high_priority) {
04302       snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
04303 
04304       /* Don't let the canary child kill Asterisk, if it dies immediately */
04305       sigaction(SIGPIPE, &ignore_sig_handler, NULL);
04306 
04307       canary_pid = fork();
04308       if (canary_pid == 0) {
04309          char canary_binary[PATH_MAX], ppid[12];
04310 
04311          /* Reset signal handler */
04312          signal(SIGCHLD, SIG_DFL);
04313          signal(SIGPIPE, SIG_DFL);
04314 
04315          ast_close_fds_above_n(0);
04316          ast_set_priority(0);
04317          snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid);
04318 
04319          /* Use the astcanary binary that we installed */
04320          snprintf(canary_binary, sizeof(canary_binary), "%s/astcanary", ast_config_AST_SBIN_DIR);
04321          execl(canary_binary, "astcanary", canary_filename, ppid, (char *)NULL);
04322 
04323          /* Should never happen */
04324          _exit(1);
04325       } else if (canary_pid > 0) {
04326          pthread_t dont_care;
04327          ast_pthread_create_detached(&dont_care, NULL, canary_thread, NULL);
04328       }
04329 
04330       /* Kill the canary when we exit */
04331       ast_register_atexit(canary_exit);
04332    }
04333 
04334    /* Blindly write the PID file. */
04335    unlink(ast_config_AST_PID);
04336    f = fopen(ast_config_AST_PID, "w");
04337    if (f) {
04338       fprintf(f, "%ld\n", (long)ast_mainpid);
04339       fclose(f);
04340    } else {
04341       fprintf(stderr, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
04342    }
04343 
04344    /* Initialize the terminal.  Since all processes have been forked,
04345     * we can now start using the standard log messages.
04346     */
04347    ast_term_init();
04348    printf("%s", term_end());
04349    fflush(stdout);
04350 
04351    print_intro_message(runuser, rungroup);
04352 
04353    if (ast_opt_console) {
04354       ast_verb(0, "[ Initializing Custom Configuration Options ]\n");
04355    }
04356    /* custom config setup */
04357    register_config_cli();
04358    read_config_maps();
04359 
04360    astobj2_init();
04361 
04362    if (ast_opt_console) {
04363       if (el_hist == NULL || el == NULL)
04364          ast_el_initialize();
04365 
04366       if (!ast_strlen_zero(filename))
04367          ast_el_read_history(filename);
04368    }
04369 
04370    ast_json_init();
04371    ast_ulaw_init();
04372    ast_alaw_init();
04373    tdd_init();
04374    callerid_init();
04375    ast_builtins_init();
04376 
04377    if (ast_utils_init()) {
04378       printf("Failed: ast_utils_init\n%s", term_quit());
04379       exit(1);
04380    }
04381 
04382    if (ast_tps_init()) {
04383       printf("Failed: ast_tps_init\n%s", term_quit());
04384       exit(1);
04385    }
04386 
04387    if (ast_fd_init()) {
04388       printf("Failed: ast_fd_init\n%s", term_quit());
04389       exit(1);
04390    }
04391 
04392    if (ast_pbx_init()) {
04393       printf("Failed: ast_pbx_init\n%s", term_quit());
04394       exit(1);
04395    }
04396 
04397 #ifdef TEST_FRAMEWORK
04398    if (ast_test_init()) {
04399       printf("Failed: ast_test_init\n%s", term_quit());
04400       exit(1);
04401    }
04402 #endif
04403 
04404    if (ast_translate_init()) {
04405       printf("Failed: ast_translate_init\n%s", term_quit());
04406       exit(1);
04407    }
04408 
04409    ast_aoc_cli_init();
04410    ast_uuid_init();
04411 
04412    if (ast_sorcery_init()) {
04413       printf("Failed: ast_sorcery_init\n%s", term_quit());
04414       exit(1);
04415    }
04416 
04417    if (ast_codec_init()) {
04418       printf("Failed: ast_codec_init\n%s", term_quit());
04419       exit(1);
04420    }
04421 
04422    if (ast_format_init()) {
04423       printf("Failed: ast_format_init\n%s", term_quit());
04424       exit(1);
04425    }
04426 
04427    if (ast_format_cache_init()) {
04428       printf("Failed: ast_format_cache_init\n%s", term_quit());
04429       exit(1);
04430    }
04431 
04432    if (ast_codec_builtin_init()) {
04433       printf("Failed: ast_codec_builtin_init\n%s", term_quit());
04434       exit(1);
04435    }
04436 
04437 #ifdef AST_XML_DOCS
04438    /* Load XML documentation. */
04439    ast_xmldoc_load_documentation();
04440 #endif
04441 
04442    aco_init();
04443 
04444    if (ast_bucket_init()) {
04445       printf("Failed: ast_bucket_init\n%s", term_quit());
04446       exit(1);
04447    }
04448 
04449    if (stasis_init()) {
04450       printf("Stasis initialization failed.\n%s", term_quit());
04451       exit(1);
04452    }
04453 
04454    if (ast_stasis_system_init()) {
04455       printf("Stasis system-level information initialization failed.\n%s", term_quit());
04456       exit(1);
04457    }
04458 
04459    if (ast_endpoint_stasis_init()) {
04460       printf("Endpoint initialization failed.\n%s", term_quit());
04461       exit(1);
04462    }
04463 
04464    ast_makesocket();
04465    /* GCC 4.9 gives a bogus "right-hand operand of comma expression has
04466     * no effect" warning */
04467    (void) sigemptyset(&sigs);
04468    (void) sigaddset(&sigs, SIGHUP);
04469    (void) sigaddset(&sigs, SIGTERM);
04470    (void) sigaddset(&sigs, SIGINT);
04471    (void) sigaddset(&sigs, SIGPIPE);
04472    (void) sigaddset(&sigs, SIGWINCH);
04473    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
04474    sigaction(SIGURG, &urg_handler, NULL);
04475    signal(SIGINT, __quit_handler);
04476    signal(SIGTERM, __quit_handler);
04477    sigaction(SIGHUP, &hup_handler, NULL);
04478    sigaction(SIGPIPE, &ignore_sig_handler, NULL);
04479 
04480    /* ensure that the random number generators are seeded with a different value every time
04481       Asterisk is started
04482    */
04483    srand((unsigned int) getpid() + (unsigned int) time(NULL));
04484    initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
04485 
04486    if (init_logger()) {    /* Start logging subsystem */
04487       printf("Failed: init_logger\n%s", term_quit());
04488       exit(1);
04489    }
04490 
04491    threadstorage_init();
04492 
04493    if (ast_rtp_engine_init()) {
04494       printf("Failed: ast_rtp_engine_init\n%s", term_quit());
04495       exit(1);
04496    }
04497 
04498    ast_autoservice_init();
04499 
04500    if (ast_timing_init()) {
04501       printf("Failed: ast_timing_init\n%s", term_quit());
04502       exit(1);
04503    }
04504 
04505    if (ast_ssl_init()) {
04506       printf("Failed: ast_ssl_init\n%s", term_quit());
04507       exit(1);
04508    }
04509 
04510    if (app_init()) {
04511       printf("App core initialization failed.\n%s", term_quit());
04512       exit(1);
04513    }
04514 
04515    if (devstate_init()) {
04516       printf("Device state core initialization failed.\n%s", term_quit());
04517       exit(1);
04518    }
04519 
04520    if (astdb_init()) {
04521       printf("Failed: astdb_init\n%s", term_quit());
04522       exit(1);
04523    }
04524 
04525    if (ast_msg_init()) {
04526       printf("Failed: ast_msg_init\n%s", term_quit());
04527       exit(1);
04528    }
04529 
04530    /* initialize the data retrieval API */
04531    if (ast_data_init()) {
04532       printf ("Failed: ast_data_init\n%s", term_quit());
04533       exit(1);
04534    }
04535 
04536    ast_channels_init();
04537 
04538    if (ast_endpoint_init()) {
04539       printf ("Failed: ast_endpoint_init\n%s", term_quit());
04540       exit(1);
04541    }
04542 
04543    if (ast_pickup_init()) {
04544       printf("Failed: ast_pickup_init\n%s", term_quit());
04545       exit(1);
04546    }
04547 
04548    if (ast_bridging_init()) {
04549       printf("Failed: ast_bridging_init\n%s", term_quit());
04550       exit(1);
04551    }
04552 
04553    if (ast_parking_stasis_init()) {
04554       printf("Failed: ast_parking_stasis_init\n%s", term_quit());
04555       exit(1);
04556    }
04557 
04558    if (ast_device_state_engine_init()) {
04559       printf("Failed: ast_device_state_engine_init\n%s", term_quit());
04560       exit(1);
04561    }
04562 
04563    if (ast_presence_state_engine_init()) {
04564       printf("Failed: ast_presence_state_engine_init\n%s", term_quit());
04565       exit(1);
04566    }
04567 
04568    if ((moduleresult = load_modules(1))) {      /* Load modules, pre-load only */
04569       printf("Failed: load_modules\n%s", term_quit());
04570       exit(moduleresult == -2 ? 2 : 1);
04571    }
04572 
04573    if (ast_features_init()) {
04574       printf("Failed: ast_features_init\n%s", term_quit());
04575       exit(1);
04576    }
04577 
04578    if (dnsmgr_init()) {    /* Initialize the DNS manager */
04579       printf("Failed: dnsmgr_init\n%s", term_quit());
04580       exit(1);
04581    }
04582 
04583    if (ast_security_stasis_init()) {      /* Initialize Security Stasis Topic and Events */
04584       printf("Failed: ast_security_stasis_init\n%s", term_quit());
04585       exit(1);
04586    }
04587 
04588    if (ast_named_acl_init()) { /* Initialize the Named ACL system */
04589       printf("Failed: ast_named_acl_init\n%s", term_quit());
04590       exit(1);
04591    }
04592 
04593    ast_http_init();     /* Start the HTTP server, if needed */
04594 
04595    if (ast_indications_init()) {
04596       printf("Failed: ast_indications_init\n%s", term_quit());
04597       exit(1);
04598    }
04599 
04600    if (ast_cdr_engine_init()) {
04601       printf("Failed: ast_cdr_engine_init\n%s", term_quit());
04602       exit(1);
04603    }
04604 
04605    ast_dsp_init();
04606    ast_udptl_init();
04607 
04608    if (ast_image_init()) {
04609       printf("Failed: ast_image_init\n%s", term_quit());
04610       exit(1);
04611    }
04612 
04613    if (ast_file_init()) {
04614       printf("Failed: ast_file_init\n%s", term_quit());
04615       exit(1);
04616    }
04617 
04618    if (load_pbx()) {
04619       printf("Failed: load_pbx\n%s", term_quit());
04620       exit(1);
04621    }
04622 
04623    if (ast_local_init()) {
04624       printf("Failed: ast_local_init\n%s", term_quit());
04625       exit(1);
04626    }
04627 
04628    if (ast_cel_engine_init()) {
04629       printf("Failed: ast_cel_engine_init\n%s", term_quit());
04630       exit(1);
04631    }
04632 
04633    if (init_manager()) {
04634       printf("Failed: init_manager\n%s", term_quit());
04635       exit(1);
04636    }
04637 
04638    if (ast_enum_init()) {
04639       printf("Failed: ast_enum_init\n%s", term_quit());
04640       exit(1);
04641    }
04642 
04643    if (ast_cc_init()) {
04644       printf("Failed: ast_cc_init\n%s", term_quit());
04645       exit(1);
04646    }
04647 
04648    if (ast_sounds_index_init()) {
04649       printf("Failed: ast_sounds_index_init\n%s", term_quit());
04650       exit(1);
04651    }
04652 
04653    if ((moduleresult = load_modules(0))) {      /* Load modules */
04654       printf("%s", term_quit());
04655       exit(moduleresult == -2 ? 2 : 1);
04656    }
04657 
04658    /* loads the cli_permissoins.conf file needed to implement cli restrictions. */
04659    ast_cli_perms_init(0);
04660 
04661    ast_stun_init();
04662 
04663    dnsmgr_start_refresh();
04664 
04665    if (ast_opt_no_fork) {
04666       consolethread = pthread_self();
04667    }
04668 
04669    if (pipe(sig_alert_pipe)) {
04670       sig_alert_pipe[0] = sig_alert_pipe[1] = -1;
04671    }
04672 
04673    ast_process_pending_reloads();
04674 
04675    ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
04676    publish_fully_booted();
04677 
04678    pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
04679 
04680 #if defined(__AST_DEBUG_MALLOC)
04681    __ast_mm_init_phase_2();
04682 #endif   /* defined(__AST_DEBUG_MALLOC) */
04683 
04684    ast_lastreloadtime = ast_startuptime = ast_tvnow();
04685    ast_cli_register_multiple(cli_asterisk_shutdown, ARRAY_LEN(cli_asterisk_shutdown));
04686    ast_cli_register_multiple(cli_asterisk, ARRAY_LEN(cli_asterisk));
04687    ast_register_cleanup(main_atexit);
04688 
04689    run_startup_commands();
04690 
04691    ast_verb(0, COLORIZE_FMT "\n", COLORIZE(COLOR_BRGREEN, 0, "Asterisk Ready."));
04692 
04693    logger_queue_start();
04694 
04695    if (ast_opt_console) {
04696       /* Console stuff now... */
04697       /* Register our quit function */
04698       char title[256];
04699 
04700       ast_pthread_create_detached(&mon_sig_flags, NULL, monitor_sig_flags, NULL);
04701 
04702       set_icon("Asterisk");
04703       snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
04704       set_title(title);
04705 
04706       el_set(el, EL_GETCFN, ast_el_read_char);
04707 
04708       for (;;) {
04709          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
04710             quit_handler(0, SHUTDOWN_FAST, 0);
04711             break;
04712          }
04713          buf = (char *) el_gets(el, &num);
04714 
04715          if (!buf && write(1, "", 1) < 0)
04716             goto lostterm;
04717 
04718          if (buf) {
04719             if (buf[strlen(buf)-1] == '\n')
04720                buf[strlen(buf)-1] = '\0';
04721 
04722             consolehandler((char *)buf);
04723          } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
04724                strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) {
04725             /* Whoa, stdout disappeared from under us... Make /dev/null's */
04726             int fd;
04727             fd = open("/dev/null", O_RDWR);
04728             if (fd > -1) {
04729                dup2(fd, STDOUT_FILENO);
04730                dup2(fd, STDIN_FILENO);
04731             } else
04732                ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
04733             break;
04734          }
04735       }
04736    }
04737 
04738    monitor_sig_flags(NULL);
04739 
04740 lostterm:
04741    return 0;
04742 }

static void main_atexit ( void   )  [static]

Definition at line 3869 of file asterisk.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), and cli_asterisk.

Referenced by main().

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

Definition at line 3750 of file asterisk.c.

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

Referenced by main().

03751 {
03752    for (;;) {
03753       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
03754       int a;
03755       ast_poll(&p, 1, -1);
03756       if (sig_flags.need_reload) {
03757          sig_flags.need_reload = 0;
03758          ast_module_reload(NULL);
03759       }
03760       if (sig_flags.need_quit) {
03761          sig_flags.need_quit = 0;
03762          if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
03763             sig_flags.need_quit_handler = 1;
03764             pthread_kill(consolethread, SIGURG);
03765          } else {
03766             quit_handler(0, SHUTDOWN_NORMAL, 0);
03767          }
03768       }
03769       if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
03770       }
03771    }
03772 
03773    return NULL;
03774 }

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

Definition at line 1495 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, ast_verb_console_register(), ast_verb_console_unregister(), errno, console::fd, fdprint(), console::gid, hostname, inbuf(), LOG_ERROR, LOG_WARNING, MAXHOSTNAMELEN, NULL, console::option_verbose, console::p, read_credentials(), and console::uid.

Referenced by listener().

01496 {
01497    struct console *con = vconsole;
01498    char hostname[MAXHOSTNAMELEN] = "";
01499    char inbuf[512];
01500    char outbuf[512];
01501    const char * const end_buf = inbuf + sizeof(inbuf);
01502    char *start_read = inbuf;
01503    int res;
01504    struct pollfd fds[2];
01505 
01506    if (gethostname(hostname, sizeof(hostname)-1))
01507       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
01508    snprintf(outbuf, sizeof(outbuf), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
01509    fdprint(con->fd, outbuf);
01510    ast_verb_console_register(&con->option_verbose);
01511    for (;;) {
01512       fds[0].fd = con->fd;
01513       fds[0].events = POLLIN;
01514       fds[0].revents = 0;
01515       fds[1].fd = con->p[0];
01516       fds[1].events = POLLIN;
01517       fds[1].revents = 0;
01518 
01519       res = ast_poll(fds, 2, -1);
01520       if (res < 0) {
01521          if (errno != EINTR)
01522             ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
01523          continue;
01524       }
01525       if (fds[0].revents) {
01526          int cmds_read, bytes_read;
01527          if ((bytes_read = read_credentials(con->fd, start_read, end_buf - start_read, con)) < 1) {
01528             break;
01529          }
01530          /* XXX This will only work if it is the first command, and I'm not sure fixing it is worth the effort. */
01531          if (strncmp(inbuf, "cli quit after ", 15) == 0) {
01532             ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read - 15, inbuf + 15);
01533             break;
01534          }
01535          /* ast_cli_command_multiple_full will only process individual commands terminated by a
01536           * NULL and not trailing partial commands. */
01537          if (!(cmds_read = ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read + start_read - inbuf, inbuf))) {
01538             /* No commands were read. We either have a short read on the first command
01539              * with space left, or a command that is too long */
01540             if (start_read + bytes_read < end_buf) {
01541                start_read += bytes_read;
01542             } else {
01543                ast_log(LOG_ERROR, "Command too long! Skipping\n");
01544                start_read = inbuf;
01545             }
01546             continue;
01547          }
01548          if (start_read[bytes_read - 1] == '\0') {
01549             /* The read ended on a command boundary, start reading again at the head of inbuf */
01550             start_read = inbuf;
01551             continue;
01552          }
01553          /* If we get this far, we have left over characters that have not been processed.
01554           * Advance to the character after the last command read by ast_cli_command_multiple_full.
01555           * We are guaranteed to have at least cmds_read NULLs */
01556          while (cmds_read-- && (start_read = strchr(start_read, '\0'))) {
01557             start_read++;
01558          }
01559          memmove(inbuf, start_read, end_buf - start_read);
01560          start_read = end_buf - start_read + inbuf;
01561       }
01562       if (fds[1].revents) {
01563          res = read_credentials(con->p[0], outbuf, sizeof(outbuf), con);
01564          if (res < 1) {
01565             ast_log(LOG_ERROR, "read returned %d\n", res);
01566             break;
01567          }
01568          res = write(con->fd, outbuf, res);
01569          if (res < 1)
01570             break;
01571       }
01572    }
01573    ast_verb_console_unregister();
01574    if (!ast_opt_hide_connect) {
01575       ast_verb(3, "Remote UNIX connection disconnected\n");
01576    }
01577    close(con->fd);
01578    close(con->p[0]);
01579    close(con->p[1]);
01580    con->fd = -1;
01581 
01582    return NULL;
01583 }

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

Definition at line 1415 of file asterisk.c.

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

Referenced by ast_makesocket().

01416 {
01417    int x;
01418    int verb_level;
01419 
01420    /* Send to any network console clients if client verbocity allows. */
01421    verb_level = VERBOSE_MAGIC2LEVEL(string);
01422    for (x = 0; x < AST_MAX_CONNECTS; ++x) {
01423       if (consoles[x].fd < 0
01424          || consoles[x].mute
01425          || consoles[x].levels[__LOG_VERBOSE]
01426          || consoles[x].option_verbose < verb_level) {
01427          continue;
01428       }
01429       fdprint(consoles[x].p[1], string);
01430    }
01431 }

static void print_intro_message ( const char *  runuser,
const char *  rungroup 
) [static]

Definition at line 3852 of file asterisk.c.

References ast_opt_console, ast_opt_exec, ast_opt_remote, ast_register_verbose(), ast_verbose, console_verboser(), and WELCOME_MESSAGE.

Referenced by main().

03853 {
03854    if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
03855       if (ast_register_verbose(console_verboser)) {
03856          fprintf(stderr, "Unable to register console verboser?\n");
03857          return;
03858       }
03859       WELCOME_MESSAGE;
03860       if (runuser) {
03861          ast_verbose("Running as user '%s'\n", runuser);
03862       }
03863       if (rungroup) {
03864          ast_verbose("Running under group '%s'\n", rungroup);
03865       }
03866    }
03867 }

static void publish_fully_booted ( void   )  [static]

Definition at line 1118 of file asterisk.c.

References ast_json_pack(), ast_json_unref(), ast_manager_publish_event(), EVENT_FLAG_SYSTEM, NULL, and RAII_VAR.

Referenced by main().

01119 {
01120    RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
01121 
01122    json_object = ast_json_pack("{s: s}",
01123          "Status", "Fully Booted");
01124    ast_manager_publish_event("FullyBooted", EVENT_FLAG_SYSTEM, json_object);
01125 }

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

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

01926 {
01927    if (can_safely_quit(niceness, restart)) {
01928       really_quit(num, niceness, restart);
01929       /* No one gets here. */
01930    }
01931    /* It wasn't our time. */
01932 }

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 936 of file asterisk.c.

Referenced by ast_mark().

00937 {
00938    return 0;
00939 }

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

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

Referenced by netconsole().

01446 {
01447 #if defined(SO_PEERCRED)
01448 #ifdef HAVE_STRUCT_SOCKPEERCRED_UID
01449 #define HAVE_STRUCT_UCRED_UID
01450    struct sockpeercred cred;
01451 #else
01452    struct ucred cred;
01453 #endif
01454    socklen_t len = sizeof(cred);
01455 #endif
01456 #if defined(HAVE_GETPEEREID)
01457    uid_t uid;
01458    gid_t gid;
01459 #else
01460    int uid, gid;
01461 #endif
01462    int result;
01463 
01464    result = read(fd, buffer, size);
01465    if (result < 0) {
01466       return result;
01467    }
01468 
01469 #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
01470    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
01471       return result;
01472    }
01473 #if defined(HAVE_STRUCT_UCRED_UID)
01474    uid = cred.uid;
01475    gid = cred.gid;
01476 #else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
01477    uid = cred.cr_uid;
01478    gid = cred.cr_gid;
01479 #endif /* defined(HAVE_STRUCT_UCRED_UID) */
01480 
01481 #elif defined(HAVE_GETPEEREID)
01482    if (getpeereid(fd, &uid, &gid)) {
01483       return result;
01484    }
01485 #else
01486    return result;
01487 #endif
01488    con->uid = uid;
01489    con->gid = gid;
01490 
01491    return result;
01492 }

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

Called when exiting is certain.

Definition at line 2060 of file asterisk.c.

References _argv, ast_active_channels(), ast_config_AST_PID, ast_config_AST_SOCKET, ast_debug, ast_el_write_history(), ast_json_pack(), ast_json_unref(), ast_manager_publish_event(), ast_module_shutdown(), ast_opt_console, ast_opt_exec, ast_opt_remote, AST_PTHREADT_NULL, ast_run_atexits(), ast_strlen_zero, ast_verb, clean_time_zones(), close_logger(), consolethread, el, el_end(), el_hist, EVENT_FLAG_SYSTEM, history_end(), lthread, mon_sig_flags, NULL, restartnow, SHUTDOWN_NICE, sig_alert_pipe, and term_quit().

Referenced by quit_handler().

02061 {
02062    int active_channels;
02063    struct ast_json *json_object = NULL;
02064    int run_cleanups = niceness >= SHUTDOWN_NICE;
02065 
02066    if (run_cleanups) {
02067       ast_module_shutdown();
02068    }
02069 
02070    if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
02071       char filename[80] = "";
02072       if (getenv("HOME")) {
02073          snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
02074       }
02075       if (!ast_strlen_zero(filename)) {
02076          ast_el_write_history(filename);
02077       }
02078       if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
02079          /* Only end if we are the consolethread, otherwise there's a race with that thread. */
02080          if (el != NULL) {
02081             el_end(el);
02082          }
02083          if (el_hist != NULL) {
02084             history_end(el_hist);
02085          }
02086       } else if (mon_sig_flags == pthread_self()) {
02087          if (consolethread != AST_PTHREADT_NULL) {
02088             pthread_kill(consolethread, SIGURG);
02089          }
02090       }
02091    }
02092    active_channels = ast_active_channels();
02093    /* Don't publish messages if we're a remote console - we won't have all of the Stasis
02094     * topics or message types
02095     */
02096    if (!ast_opt_remote) {
02097       json_object = ast_json_pack("{s: s, s: s}",
02098             "Shutdown", active_channels ? "Uncleanly" : "Cleanly",
02099             "Restart", restart ? "True" : "False");
02100       ast_manager_publish_event("Shutdown", EVENT_FLAG_SYSTEM, json_object);
02101       ast_json_unref(json_object);
02102       json_object = NULL;
02103    }
02104    ast_verb(0, "Asterisk %s ending (%d).\n",
02105       active_channels ? "uncleanly" : "cleanly", num);
02106 
02107    ast_verb(0, "Executing last minute cleanups\n");
02108    ast_run_atexits(run_cleanups);
02109 
02110    ast_debug(1, "Asterisk ending (%d).\n", num);
02111    if (ast_socket > -1) {
02112       pthread_cancel(lthread);
02113       close(ast_socket);
02114       ast_socket = -1;
02115       unlink(ast_config_AST_SOCKET);
02116       pthread_kill(lthread, SIGURG);
02117       pthread_join(lthread, NULL);
02118    }
02119    if (ast_consock > -1)
02120       close(ast_consock);
02121    if (!ast_opt_remote)
02122       unlink(ast_config_AST_PID);
02123    if (sig_alert_pipe[0])
02124       close(sig_alert_pipe[0]);
02125    if (sig_alert_pipe[1])
02126       close(sig_alert_pipe[1]);
02127    printf("%s", term_quit());
02128    if (restart) {
02129       int i;
02130       ast_verb(0, "Preparing for Asterisk restart...\n");
02131       /* Mark all FD's for closing on exec */
02132       for (i = 3; i < 32768; i++) {
02133          fcntl(i, F_SETFD, FD_CLOEXEC);
02134       }
02135       ast_verb(0, "Asterisk is now restarting...\n");
02136       restartnow = 1;
02137 
02138       /* close logger */
02139       close_logger();
02140       clean_time_zones();
02141 
02142       /* If there is a consolethread running send it a SIGHUP
02143          so it can execvp, otherwise we can do it ourselves */
02144       if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
02145          pthread_kill(consolethread, SIGHUP);
02146          /* Give the signal handler some time to complete */
02147          sleep(2);
02148       } else
02149          execvp(_argv[0], _argv);
02150 
02151    } else {
02152       /* close logger */
02153       close_logger();
02154       clean_time_zones();
02155    }
02156 
02157    exit(0);
02158 }

static int register_atexit ( void(*)(void)  func,
int  is_cleanup 
) [static]

Definition at line 1155 of file asterisk.c.

References __ast_unregister_atexit(), ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_atexit::func, ast_atexit::is_cleanup, and ast_atexit::list.

Referenced by ast_register_atexit(), and ast_register_cleanup().

01156 {
01157    struct ast_atexit *ae;
01158 
01159    ae = ast_calloc(1, sizeof(*ae));
01160    if (!ae) {
01161       return -1;
01162    }
01163    ae->func = func;
01164    ae->is_cleanup = is_cleanup;
01165 
01166    AST_LIST_LOCK(&atexits);
01167    __ast_unregister_atexit(func);
01168    AST_LIST_INSERT_HEAD(&atexits, ae, list);
01169    AST_LIST_UNLOCK(&atexits);
01170 
01171    return 0;
01172 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 2337 of file asterisk.c.

References ast_all_zeros(), ast_el_add_history(), ast_safe_system(), ast_strdupa, ast_verb_console_get(), ast_verb_console_set(), quit_handler(), and SHUTDOWN_FAST.

Referenced by ast_remotecontrol().

02338 {
02339    int ret = 0;
02340 
02341    /* Called when readline data is available */
02342    if (!ast_all_zeros(s))
02343       ast_el_add_history(s);
02344 
02345    while (isspace(*s)) {
02346       s++;
02347    }
02348 
02349    /* The real handler for bang */
02350    if (s[0] == '!') {
02351       if (s[1])
02352          ast_safe_system(s+1);
02353       else
02354          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
02355       ret = 1;
02356    } else if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
02357        (s[4] == '\0' || isspace(s[4]))) {
02358       quit_handler(0, SHUTDOWN_FAST, 0);
02359       ret = 1;
02360    } else if (s[0]) {
02361       char *shrunk = ast_strdupa(s);
02362       char *cur;
02363       char *prev;
02364 
02365       /*
02366        * Remove duplicate spaces from shrunk for matching purposes.
02367        *
02368        * shrunk has at least one character in it to start with or we
02369        * couldn't get here.
02370        */
02371       for (prev = shrunk, cur = shrunk + 1; *cur; ++cur) {
02372          if (*prev == ' ' && *cur == ' ') {
02373             /* Skip repeated space delimiter. */
02374             continue;
02375          }
02376          *++prev = *cur;
02377       }
02378       *++prev = '\0';
02379 
02380       if (strncasecmp(shrunk, "core set verbose ", 17) == 0) {
02381          /*
02382           * We need to still set the rasterisk option_verbose in case we are
02383           * talking to an earlier version which doesn't prefilter verbose
02384           * levels.  This is really a compromise as we should always take
02385           * whatever the server sends.
02386           */
02387 
02388          if (!strncasecmp(shrunk + 17, "off", 3)) {
02389             ast_verb_console_set(0);
02390          } else {
02391             int verbose_new;
02392             int atleast;
02393 
02394             atleast = 8;
02395             if (strncasecmp(shrunk + 17, "atleast ", atleast)) {
02396                atleast = 0;
02397             }
02398 
02399             if (sscanf(shrunk + 17 + atleast, "%30d", &verbose_new) == 1) {
02400                if (!atleast || ast_verb_console_get() < verbose_new) {
02401                   ast_verb_console_set(verbose_new);
02402                }
02403             }
02404          }
02405       }
02406    }
02407 
02408    return ret;
02409 }

static void run_startup_commands ( void   )  [static]

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

03813 {
03814    int fd;
03815    struct ast_config *cfg;
03816    struct ast_flags cfg_flags = { 0 };
03817    struct ast_variable *v;
03818 
03819    if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
03820       return;
03821    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03822       return;
03823    }
03824 
03825    fd = open("/dev/null", O_RDWR);
03826    if (fd < 0) {
03827       ast_config_destroy(cfg);
03828       return;
03829    }
03830 
03831    for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
03832       if (ast_true(v->value))
03833          ast_cli_command(fd, v->name);
03834    }
03835 
03836    close(fd);
03837    ast_config_destroy(cfg);
03838 }

static void send_rasterisk_connect_commands ( void   )  [static]

Definition at line 2715 of file asterisk.c.

References ast_opt_mute, buf, and fdsend().

Referenced by ast_el_read_char(), and ast_remotecontrol().

02716 {
02717    char buf[80];
02718 
02719    /*
02720     * Tell the server asterisk instance about the verbose level
02721     * initially desired.
02722     */
02723    if (option_verbose) {
02724       snprintf(buf, sizeof(buf), "core set verbose atleast %d silent", option_verbose);
02725       fdsend(ast_consock, buf);
02726    }
02727 
02728    if (option_debug) {
02729       snprintf(buf, sizeof(buf), "core set debug atleast %d", option_debug);
02730       fdsend(ast_consock, buf);
02731    }
02732 
02733    if (!ast_opt_mute) {
02734       fdsend(ast_consock, "logger mute silent");
02735    } else {
02736       printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02737    }
02738 }

static void set_header ( char *  outbuf,
int  maxout,
char  level 
) [static]

Definition at line 2178 of file asterisk.c.

References ast_localtime(), ast_logger_get_dateformat(), ast_opt_timestamp, ast_strftime(), ast_term_color(), ast_term_reset(), ast_tvnow(), COLOR_GRAY, NULL, VERBOSE_PREFIX_1, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.

Referenced by console_print().

02179 {
02180    const char *cmp;
02181    char date[40];
02182 
02183    switch (level) {
02184    case 0: cmp = NULL;
02185       break;
02186    case 1: cmp = VERBOSE_PREFIX_1;
02187       break;
02188    case 2: cmp = VERBOSE_PREFIX_2;
02189       break;
02190    case 3: cmp = VERBOSE_PREFIX_3;
02191       break;
02192    default: cmp = VERBOSE_PREFIX_4;
02193       break;
02194    }
02195 
02196    if (ast_opt_timestamp) {
02197       struct ast_tm tm;
02198       struct timeval now = ast_tvnow();
02199       ast_localtime(&now, &tm, NULL);
02200       ast_strftime(date, sizeof(date), ast_logger_get_dateformat(), &tm);
02201    }
02202 
02203    snprintf(outbuf, maxout, "%s%s%s%s%s%s",
02204       ast_opt_timestamp ? "[" : "",
02205       ast_opt_timestamp ? date : "",
02206       ast_opt_timestamp ? "] " : "",
02207       cmp ? ast_term_color(COLOR_GRAY, 0) : "",
02208       cmp ? cmp : "",
02209       cmp ? ast_term_reset() : "");
02210 }

static void set_icon ( char *  text  )  [static]

Definition at line 1843 of file asterisk.c.

Referenced by main().

01844 {
01845    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01846       fprintf(stdout, "\033]1;%s\007", text);
01847 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1837 of file asterisk.c.

Referenced by main().

01838 {
01839    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01840       fprintf(stdout, "\033]2;%s\007", text);
01841 }

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1814 of file asterisk.c.

References ast_log, errno, LOG_NOTICE, and LOG_WARNING.

Referenced by ast_readconfig().

01815 {
01816    struct rlimit l = {0, 0};
01817 
01818    if (value <= 0) {
01819       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01820       return;
01821    }
01822 
01823    l.rlim_cur = value;
01824    l.rlim_max = value;
01825 
01826    if (setrlimit(RLIMIT_NOFILE, &l)) {
01827       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01828       return;
01829    }
01830 
01831    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01832 
01833    return;
01834 }

static int show_cli_help ( void   )  [static]

Definition at line 3450 of file asterisk.c.

References ast_get_version().

Referenced by main().

03451 {
03452    printf("Asterisk %s, Copyright (C) 1999 - 2014, Digium, Inc. and others.\n", ast_get_version());
03453    printf("Usage: asterisk [OPTIONS]\n");
03454    printf("Valid Options:\n");
03455    printf("   -V              Display version number and exit\n");
03456    printf("   -C <configfile> Use an alternate configuration file\n");
03457    printf("   -G <group>      Run as a group other than the caller\n");
03458    printf("   -U <user>       Run as a user other than the caller\n");
03459    printf("   -c              Provide console CLI\n");
03460    printf("   -d              Enable extra debugging\n");
03461 #if HAVE_WORKING_FORK
03462    printf("   -f              Do not fork\n");
03463    printf("   -F              Always fork\n");
03464 #endif
03465    printf("   -g              Dump core in case of a crash\n");
03466    printf("   -h              This help screen\n");
03467    printf("   -i              Initialize crypto keys at startup\n");
03468    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
03469    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
03470    printf("   -m              Mute debugging and console output on the console\n");
03471    printf("   -n              Disable console colorization\n");
03472    printf("   -p              Run as pseudo-realtime thread\n");
03473    printf("   -q              Quiet mode (suppress output)\n");
03474    printf("   -r              Connect to Asterisk on this machine\n");
03475    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
03476    printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
03477    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
03478    printf("                   belong after they are done\n");
03479    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
03480    printf("                   of output to the CLI\n");
03481    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
03482    printf("   -x <cmd>        Execute command <cmd> (implies -r)\n");
03483    printf("   -X              Execute includes by default (allows #exec in asterisk.conf)\n");
03484    printf("   -W              Adjust terminal colors to compensate for a light background\n");
03485    printf("\n");
03486    return 0;
03487 }

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

Definition at line 2660 of file asterisk.c.

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

02661 {
02662    switch (cmd) {
02663    case CLI_INIT:
02664       e->command = "core show license";
02665       e->usage =
02666          "Usage: core show license\n"
02667          "       Shows the license(s) for this copy of Asterisk.\n";
02668       return NULL;
02669    case CLI_GENERATE:
02670       return NULL;
02671    }
02672 
02673    ast_cli(a->fd, "%s", license_lines);
02674 
02675    return CLI_SUCCESS;
02676 }

static int show_version ( void   )  [static]

Definition at line 3444 of file asterisk.c.

References ast_get_version().

Referenced by main().

03445 {
03446    printf("Asterisk %s\n", ast_get_version());
03447    return 0;
03448 }

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

Definition at line 2623 of file asterisk.c.

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

02624 {
02625    switch (cmd) {
02626    case CLI_INIT:
02627       e->command = "core show warranty";
02628       e->usage =
02629          "Usage: core show warranty\n"
02630          "       Shows the warranty (if any) for this copy of Asterisk.\n";
02631       return NULL;
02632    case CLI_GENERATE:
02633       return NULL;
02634    }
02635 
02636    ast_cli(a->fd, "%s", warranty_lines);
02637 
02638    return CLI_SUCCESS;
02639 }

static int wait_for_channels_to_die ( shutdown_nice_t  niceness,
int  seconds 
) [static]

Definition at line 1947 of file asterisk.c.

References ast_undestroyed_channels(), and shuttingdown.

Referenced by can_safely_quit().

01948 {
01949    time_t start;
01950    time_t now;
01951    int waited = 0;
01952 
01953    time(&start);
01954    for (;;) {
01955       if (!ast_undestroyed_channels() || shuttingdown != niceness) {
01956          break;
01957       }
01958       if (seconds < 0) {
01959          /* No timeout so just poll every second */
01960          sleep(1);
01961       } else {
01962          time(&now);
01963 
01964          /* Wait up to the given seconds for all channels to go away */
01965          if (seconds < (now - start)) {
01966             break;
01967          }
01968 
01969          /* Sleep 1/10 of a second */
01970          usleep(100000);
01971       }
01972       waited = 1;
01973    }
01974    return waited;
01975 }


Variable Documentation

char* _argv[256] [static]

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

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

Definition at line 404 of file asterisk.c.

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

Referenced by ast_readconfig().

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

Definition at line 427 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

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

Definition at line 426 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static]

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

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

const char* ast_config_AST_RECORDING_DIR = cfg_paths.recording_dir

const char* ast_config_AST_RUN_DIR = cfg_paths.run_dir

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

const char* ast_config_AST_RUN_USER = cfg_paths.run_user

const char* ast_config_AST_SBIN_DIR = cfg_paths.sbin_dir

Definition at line 416 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 420 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

Definition at line 410 of file asterisk.c.

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

Definition at line 342 of file asterisk.c.

char ast_defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

unsigned int ast_FD_SETSIZE

Definition at line 86 of file poll.c.

struct timeval ast_lastreloadtime

pid_t ast_mainpid

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

struct timeval ast_startuptime

char canary_filename[128] [static]

Definition at line 465 of file asterisk.c.

Referenced by canary_thread(), and main().

int canary_pid = 0 [static]

Definition at line 464 of file asterisk.c.

Referenced by canary_exit(), and main().

struct _cfg_paths cfg_paths [static]

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

Referenced by main().

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 2697 of file asterisk.c.

Referenced by main(), and main_atexit().

Shutdown Asterisk CLI commands.

Note:
These CLI commands cannot be unregistered at shutdown because one of them is likely the reason for the shutdown. The CLI generates a warning if a command is in-use when it is unregistered.

Definition at line 2688 of file asterisk.c.

Referenced by main().

struct ast_threadstorage console_state = { .once = PTHREAD_ONCE_INIT , .key_init = __init_console_state , .custom_init = console_state_init , } [static]

Definition at line 2223 of file asterisk.c.

Referenced by console_print().

struct console consoles[AST_MAX_CONNECTS]

pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 462 of file asterisk.c.

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

EditLine* el [static]

History* el_hist [static]

struct sigaction hup_handler [static]

Initial value:

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

Definition at line 1788 of file asterisk.c.

Referenced by main().

struct sigaction ignore_sig_handler [static]

Initial value:

 {
   .sa_handler = SIG_IGN,
}

Definition at line 1213 of file asterisk.c.

Referenced by main().

const char license_lines[] [static]

Definition at line 2641 of file asterisk.c.

Referenced by show_license().

pthread_t lthread [static]

Definition at line 1433 of file asterisk.c.

Referenced by ast_makesocket(), and really_quit().

pthread_t mon_sig_flags [static]

Definition at line 463 of file asterisk.c.

Referenced by main(), and really_quit().

int multi_thread_safe [static]

Definition at line 466 of file asterisk.c.

Referenced by ast_register_thread(), and main().

unsigned int need_quit

Definition at line 473 of file asterisk.c.

unsigned int need_quit_handler

Definition at line 474 of file asterisk.c.

unsigned int need_reload

Definition at line 472 of file asterisk.c.

struct sigaction null_sig_handler [static]

Initial value:

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

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

Referenced by main().

char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR

Definition at line 339 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 369 of file asterisk.c.

Referenced by ast_remotecontrol(), and cli_prompt().

int restartnow [static]

Definition at line 461 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 1221 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 1222 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

int shutdown_pending [static]

Prevent new channel allocation for shutdown.

Definition at line 459 of file asterisk.c.

Referenced by ast_begin_shutdown(), ast_cancel_shutdown(), and ast_shutting_down().

shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN [static]

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

Definition at line 470 of file asterisk.c.

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

struct { ... } sig_flags [static]

struct sigaction urg_handler [static]

Initial value:

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

Definition at line 1768 of file asterisk.c.

Referenced by main().

const char warranty_lines[] [static]

Definition at line 2598 of file asterisk.c.

Referenced by show_warranty().


Generated on Thu Apr 16 06:28:57 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6