Thu Sep 7 01:03:12 2017

Asterisk developer's documentation


asterisk.c File Reference

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

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

Go to the source code of this file.

Data Structures

struct  _cfg_paths
struct  agimaskvars
struct  ast_atexit
struct  atexits
struct  console
struct  file_version
struct  file_versions
struct  profile_data
struct  profile_entry
struct  readmaskvars
struct  setmaskvars
struct  thread_list
struct  thread_list_t

Defines

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

Enumerations

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

Functions

static void __ast_unregister_atexit (void(*func)(void))
static void __quit_handler (int num)
static void __remote_quit_handler (int num)
static void _child_handler (int sig)
static void _hup_handler (int num)
static void _null_sig_handler (int sig)
 NULL handler so we can collect the child exit status.
static void _urg_handler (int num)
 Urgent handler.
int ast_add_profile (const char *name, uint64_t scale)
 allocates a counter with a given name and scale.
static int ast_all_zeros (char *s)
static int ast_cli_display_match_list (char **matches, int len, int max)
char * ast_complete_source_filename (const char *partial, int n)
void ast_console_puts (const char *string)
void ast_console_puts_mutable (const char *string, int level)
 log the string to the console, and all attached console clients
void ast_console_toggle_loglevel (int fd, int level, int state)
 enable or disable a logging level to a specified console
void ast_console_toggle_mute (int fd, int silent)
 mute or unmute a console from logging
static int ast_el_add_history (char *)
static int ast_el_initialize (void)
static int ast_el_read_char (EditLine *editline, char *cp)
static int ast_el_read_history (char *)
static int ast_el_sort_compare (const void *i1, const void *i2)
static char ** ast_el_strtoarr (char *buf)
static int ast_el_write_history (char *)
const char * ast_file_version_find (const char *file)
 Find version for given module name.
static int ast_makesocket (void)
int64_t ast_mark (int i, int startstop)
static void ast_network_puts (const char *string)
 write the string to all attached console clients
static void ast_network_puts_mutable (const char *string, int level)
 log the string to all attached console clients
int64_t ast_profile (int i, int64_t delta)
static void ast_readconfig (void)
int ast_register_atexit (void(*func)(void))
 Register a function to be executed before Asterisk exits.
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.
static int ast_tryconnect (void)
void ast_unregister_atexit (void(*func)(void))
 Unregister a function registered with ast_register_atexit().
void ast_unregister_file_version (const char *file)
 Unregister a source code file from the core.
void ast_unregister_thread (void *id)
void ast_unreplace_sigchld (void)
 Restore the SIGCHLD handler.
static int can_safely_quit (shutdown_nice_t niceness, int restart)
static void canary_exit (void)
static void * canary_thread (void *unused)
static char * cli_complete (EditLine *editline, int ch)
static char * cli_prompt (EditLine *editline)
static void console_verboser (const char *s)
static void consolehandler (char *s)
static void 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 const char * fix_header (char *outbuf, int maxout, const char *s, char *cmp)
static char * handle_abort_shutdown (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_bang (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_clear_profile (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_restart_gracefully (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_restart_now (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_restart_when_convenient (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_show_profile (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Give an overview of core settings.
static char * handle_show_sysinfo (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Give an overview of system statistics.
static char * handle_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_show_version_files (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to list module versions.
static char * handle_stop_gracefully (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_stop_now (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_stop_when_convenient (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_version (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void * listener (void *unused)
int main (int argc, char *argv[])
static void main_atexit (void)
static void * monitor_sig_flags (void *unused)
static void * netconsole (void *vconsole)
static void network_verboser (const char *s)
static void print_intro_message (const char *runuser, const char *rungroup)
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 set_icon (char *text)
static void set_title (char *text)
 Set an X-term or screen title.
static void set_ulimit (int value)
 Set maximum open files.
static int show_cli_help (void)
static char * show_license (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int show_version (void)
static char * show_warranty (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Variables

static char * _argv [256]
char agimaskvar [PATH_MAX] = ""
int agimaskvarend = 0
int agimaskvarini = 0
static int agivar_count = 0
struct ast_flags ast_compat = { 0 }
const char * ast_config_AST_AGI_DIR = cfg_paths.agi_dir
const char * ast_config_AST_CONFIG_DIR = cfg_paths.config_dir
const char * ast_config_AST_CONFIG_FILE = cfg_paths.config_file
static char ast_config_AST_CTL [PATH_MAX] = "asterisk.ctl"
static char ast_config_AST_CTL_GROUP [PATH_MAX] = "\0"
static char ast_config_AST_CTL_OWNER [PATH_MAX] = "\0"
static char ast_config_AST_CTL_PERMISSIONS [PATH_MAX]
const char * ast_config_AST_DATA_DIR = cfg_paths.data_dir
const char * ast_config_AST_DB = cfg_paths.db_path
const char * ast_config_AST_KEY_DIR = cfg_paths.key_dir
const char * ast_config_AST_LOG_DIR = cfg_paths.log_dir
const char * ast_config_AST_MODULE_DIR = cfg_paths.module_dir
const char * ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir
const char * ast_config_AST_PID = cfg_paths.pid_path
const char * ast_config_AST_RUN_DIR = cfg_paths.run_dir
const char * ast_config_AST_RUN_GROUP = cfg_paths.run_group
const char * ast_config_AST_RUN_USER = cfg_paths.run_user
const char * ast_config_AST_SOCKET = cfg_paths.socket_path
const char * ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir
const char * ast_config_AST_SYSTEM_NAME = cfg_paths.system_name
const char * ast_config_AST_VAR_DIR = cfg_paths.var_dir
static int ast_consock = -1
struct ast_eid ast_eid_default
 Global EID.
unsigned int ast_FD_SETSIZE
struct timeval ast_lastreloadtime
pid_t ast_mainpid
struct ast_flags ast_options = { AST_DEFAULT_OPTIONS }
static int ast_socket = -1
struct timeval ast_startuptime
static char canary_filename [128]
static int canary_pid = 0
static struct _cfg_paths cfg_paths
static struct sigaction child_handler
static struct ast_cli_entry cli_asterisk []
static struct ast_cli_entry cli_asterisk_shutdown []
 Shutdown Asterisk CLI commands.
struct console consoles [AST_MAX_CONNECTS]
static pthread_t consolethread = AST_PTHREADT_NULL
char defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE
static EditLine * el
static History * el_hist
static struct 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
int option_maxcalls
int option_maxfiles
double option_maxload
long option_minmemfree
int option_verbose
static struct profile_dataprof_data
static struct ast_strprompt = NULL
static char randompool [256]
char readmaskvar [PATH_MAX] = ""
int readmaskvarend = 0
int readmaskvarini = 0
static int readvar_count = 0
char record_cache_dir [AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR
static char * remotehostname
static int restartnow
static unsigned int safe_system_level = 0
 Keep track of how many threads are currently trying to wait*() on a child process.
static ast_mutex_t safe_system_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static struct sigaction safe_system_prev_handler
char setmaskvar [PATH_MAX] = ""
int setmaskvarend = 0
int setmaskvarini = 0
static int setvar_count = 0
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 AST_MAX_CONNECTS   128
#define ASTERISK_PROMPT   "*CLI> "

Definition at line 2271 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 2273 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

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

Referenced by ast_el_add_history(), and ast_el_read_history().

#define NUM_MSGS   64

Definition at line 159 of file asterisk.c.

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 162 of file asterisk.c.

Referenced by ast_el_read_char(), and print_intro_message().


Enumeration Type Documentation

Enumerator:
NOT_SHUTTING_DOWN 
SHUTTING_DOWN 
SHUTDOWN_FAST 
SHUTDOWN_NORMAL 
SHUTDOWN_NICE 
SHUTDOWN_REALLY_NICE 

Definition at line 297 of file asterisk.c.

00297              {
00298    NOT_SHUTTING_DOWN = -2,
00299    SHUTTING_DOWN = -1,
00300    /* Valid values for quit_handler niceness below: */
00301    SHUTDOWN_FAST,
00302    SHUTDOWN_NORMAL,
00303    SHUTDOWN_NICE,
00304    SHUTDOWN_REALLY_NICE
00305 } shutdown_nice_t;


Function Documentation

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

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

00980 {
00981    struct ast_atexit *ae;
00982 
00983    AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
00984       if (ae->func == func) {
00985          AST_LIST_REMOVE_CURRENT(list);
00986          ast_free(ae);
00987          break;
00988       }
00989    }
00990    AST_LIST_TRAVERSE_SAFE_END;
00991 }

static void __quit_handler ( int  num  )  [static]

Definition at line 1878 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

01879 {
01880    int a = 0;
01881    sig_flags.need_quit = 1;
01882    if (sig_alert_pipe[1] != -1) {
01883       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01884          fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
01885       }
01886    }
01887    /* There is no need to restore the signal handler here, since the app
01888     * is going to exit */
01889 }

static void __remote_quit_handler ( int  num  )  [static]

Definition at line 1891 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

01892 {
01893    sig_flags.need_quit = 1;
01894 }

static void _child_handler ( int  sig  )  [static]

Definition at line 1606 of file asterisk.c.

References errno, and status.

01607 {
01608    /* Must not ever ast_log or ast_verbose within signal handler */
01609    int n, status, save_errno = errno;
01610 
01611    /*
01612     * Reap all dead children -- not just one
01613     */
01614    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01615       ;
01616    if (n == 0 && option_debug)
01617       printf("Huh?  Child handler, but nobody there?\n");
01618    errno = save_errno;
01619 }

static void _hup_handler ( int  num  )  [static]

Definition at line 1585 of file asterisk.c.

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

01586 {
01587    int a = 0, save_errno = errno;
01588    if (option_verbose > 1)
01589       printf("Received HUP signal -- Reloading configs\n");
01590    if (restartnow)
01591       execvp(_argv[0], _argv);
01592    sig_flags.need_reload = 1;
01593    if (sig_alert_pipe[1] != -1) {
01594       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01595          fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
01596       }
01597    }
01598    errno = save_errno;
01599 }

static void _null_sig_handler ( int  sig  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 1042 of file asterisk.c.

01043 {
01044 }

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

01576 {
01577    return;
01578 }

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

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

Referenced by extension_match_core().

00725 {
00726    int l = sizeof(struct profile_data);
00727    int n = 10; /* default entries */
00728 
00729    if (prof_data == NULL) {
00730       prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
00731       if (prof_data == NULL)
00732          return -1;
00733       prof_data->entries = 0;
00734       prof_data->max_size = n;
00735    }
00736    if (prof_data->entries >= prof_data->max_size) {
00737       void *p;
00738       n = prof_data->max_size + 20;
00739       p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
00740       if (p == NULL)
00741          return -1;
00742       prof_data = p;
00743       prof_data->max_size = n;
00744    }
00745    n = prof_data->entries++;
00746    prof_data->e[n].name = ast_strdup(name);
00747    prof_data->e[n].value = 0;
00748    prof_data->e[n].events = 0;
00749    prof_data->e[n].mark = 0;
00750    prof_data->e[n].scale = scale;
00751    return n;
00752 }

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1938 of file asterisk.c.

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

01939 {
01940    while (*s) {
01941       if (*s > 32)
01942          return 0;
01943       s++;
01944    }
01945    return 1;
01946 }

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

Definition at line 2608 of file asterisk.c.

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

Referenced by cli_complete().

02609 {
02610    int i, idx, limit, count;
02611    int screenwidth = 0;
02612    int numoutput = 0, numoutputline = 0;
02613 
02614    screenwidth = ast_get_termcols(STDOUT_FILENO);
02615 
02616    /* find out how many entries can be put on one line, with two spaces between strings */
02617    limit = screenwidth / (max + 2);
02618    if (limit == 0)
02619       limit = 1;
02620 
02621    /* how many lines of output */
02622    count = len / limit;
02623    if (count * limit < len)
02624       count++;
02625 
02626    idx = 1;
02627 
02628    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
02629 
02630    for (; count > 0; count--) {
02631       numoutputline = 0;
02632       for (i = 0; i < limit && matches[idx]; i++, idx++) {
02633 
02634          /* Don't print dupes */
02635          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
02636             i--;
02637             ast_free(matches[idx]);
02638             matches[idx] = NULL;
02639             continue;
02640          }
02641 
02642          numoutput++;
02643          numoutputline++;
02644          fprintf(stdout, "%-*s  ", max, matches[idx]);
02645          ast_free(matches[idx]);
02646          matches[idx] = NULL;
02647       }
02648       if (numoutputline > 0)
02649          fprintf(stdout, "\n");
02650    }
02651 
02652    return numoutput;
02653 }

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

Definition at line 371 of file asterisk.c.

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

Referenced by handle_verbose().

00372 {
00373    struct file_version *find;
00374    size_t len = strlen(partial);
00375    int count = 0;
00376    char *res = NULL;
00377 
00378    AST_RWLIST_RDLOCK(&file_versions);
00379    AST_RWLIST_TRAVERSE(&file_versions, find, list) {
00380       if (!strncasecmp(find->file, partial, len) && ++count > n) {
00381          res = ast_strdup(find->file);
00382          break;
00383       }
00384    }
00385    AST_RWLIST_UNLOCK(&file_versions);
00386    return res;
00387 }

void ast_console_puts ( const char *  string  ) 

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

Definition at line 1236 of file asterisk.c.

References ast_network_puts().

01237 {
01238    fputs(string, stdout);
01239    fflush(stdout);
01240    ast_network_puts(string);
01241 }

void ast_console_puts_mutable ( const char *  string,
int  level 
)

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

Version:
1.6.1 added level parameter

Definition at line 1213 of file asterisk.c.

References ast_network_puts_mutable().

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

01214 {
01215    fputs(string, stdout);
01216    fflush(stdout);
01217    ast_network_puts_mutable(string, level);
01218 }

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

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

Referenced by handle_logger_set_level().

01151 {
01152    int x;
01153 
01154    if (level >= NUMLOGLEVELS) {
01155       level = NUMLOGLEVELS - 1;
01156    }
01157 
01158    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01159       if (fd == consoles[x].fd) {
01160          /*
01161           * Since the logging occurs when levels are false, set to
01162           * flipped iinput because this function accepts 0 as off and 1 as on
01163           */
01164          consoles[x].levels[level] = state ? 0 : 1;
01165          return;
01166       }
01167    }
01168 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1173 of file asterisk.c.

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

Referenced by handle_logger_mute().

01174 {
01175    int x;
01176    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01177       if (fd == consoles[x].fd) {
01178          if (consoles[x].mute) {
01179             consoles[x].mute = 0;
01180             if (!silent)
01181                ast_cli(fd, "Console is not muted anymore.\n");
01182          } else {
01183             consoles[x].mute = 1;
01184             if (!silent)
01185                ast_cli(fd, "Console is muted.\n");
01186          }
01187          return;
01188       }
01189    }
01190    ast_cli(fd, "Couldn't find remote console.\n");
01191 }

static int ast_el_add_history ( char *  buf  )  [static]

Definition at line 2818 of file asterisk.c.

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

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

02819 {
02820    HistEvent ev;
02821 
02822    if (el_hist == NULL || el == NULL)
02823       ast_el_initialize();
02824    if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1))
02825       return 0;
02826    return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf))));
02827 }

static int ast_el_initialize ( void   )  [static]

Definition at line 2781 of file asterisk.c.

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

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

02782 {
02783    HistEvent ev;
02784    char *editor = getenv("AST_EDITOR");
02785 
02786    if (el != NULL)
02787       el_end(el);
02788    if (el_hist != NULL)
02789       history_end(el_hist);
02790 
02791    el = el_init("asterisk", stdin, stdout, stderr);
02792    el_set(el, EL_PROMPT, cli_prompt);
02793 
02794    el_set(el, EL_EDITMODE, 1);
02795    el_set(el, EL_EDITOR, editor ? editor : "emacs");
02796    el_hist = history_init();
02797    if (!el || !el_hist)
02798       return -1;
02799 
02800    /* setup history with 100 entries */
02801    history(el_hist, &ev, H_SETSIZE, 100);
02802 
02803    el_set(el, EL_HIST, history, el_hist);
02804 
02805    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02806    /* Bind <tab> to command completion */
02807    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02808    /* Bind ? to command completion */
02809    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02810    /* Bind ^D to redisplay */
02811    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02812 
02813    return 0;
02814 }

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

Definition at line 2310 of file asterisk.c.

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

Referenced by ast_remotecontrol(), and main().

02311 {
02312    int num_read = 0;
02313    int lastpos = 0;
02314    struct pollfd fds[2];
02315    int res;
02316    int max;
02317 #define EL_BUF_SIZE 512
02318    char buf[EL_BUF_SIZE];
02319 
02320    for (;;) {
02321       max = 1;
02322       fds[0].fd = ast_consock;
02323       fds[0].events = POLLIN;
02324       if (!ast_opt_exec) {
02325          fds[1].fd = STDIN_FILENO;
02326          fds[1].events = POLLIN;
02327          max++;
02328       }
02329       res = ast_poll(fds, max, -1);
02330       if (res < 0) {
02331          if (sig_flags.need_quit || sig_flags.need_quit_handler)
02332             break;
02333          if (errno == EINTR)
02334             continue;
02335          fprintf(stderr, "poll failed: %s\n", strerror(errno));
02336          break;
02337       }
02338 
02339       if (!ast_opt_exec && fds[1].revents) {
02340          num_read = read(STDIN_FILENO, cp, 1);
02341          if (num_read < 1) {
02342             break;
02343          } else
02344             return (num_read);
02345       }
02346       if (fds[0].revents) {
02347          char *tmp;
02348          res = read(ast_consock, buf, sizeof(buf) - 1);
02349          /* if the remote side disappears exit */
02350          if (res < 1) {
02351             fprintf(stderr, "\nDisconnected from Asterisk server\n");
02352             if (!ast_opt_reconnect) {
02353                quit_handler(0, SHUTDOWN_FAST, 0);
02354             } else {
02355                int tries;
02356                int reconnects_per_second = 20;
02357                fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
02358                for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
02359                   if (ast_tryconnect()) {
02360                      fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
02361                      printf("%s", term_quit());
02362                      WELCOME_MESSAGE;
02363                      if (!ast_opt_mute)
02364                         fdsend(ast_consock, "logger mute silent");
02365                      else
02366                         printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02367                      break;
02368                   } else
02369                      usleep(1000000 / reconnects_per_second);
02370                }
02371                if (tries >= 30 * reconnects_per_second) {
02372                   fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
02373                   quit_handler(0, SHUTDOWN_FAST, 0);
02374                }
02375             }
02376             continue;
02377          }
02378 
02379          buf[res] = '\0';
02380 
02381          /* Strip preamble from asynchronous events, too */
02382          for (tmp = buf; *tmp; tmp++) {
02383             if (*tmp == 127) {
02384                memmove(tmp, tmp + 1, strlen(tmp));
02385                tmp--;
02386                res--;
02387             }
02388          }
02389 
02390          /* Write over the CLI prompt */
02391          if (!ast_opt_exec && !lastpos) {
02392             if (write(STDOUT_FILENO, "\r", 5) < 0) {
02393             }
02394          }
02395          if (write(STDOUT_FILENO, buf, res) < 0) {
02396          }
02397          if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
02398             *cp = CC_REFRESH;
02399             return(1);
02400          } else
02401             lastpos = 1;
02402       }
02403    }
02404 
02405    *cp = '\0';
02406    return (0);
02407 }

static int ast_el_read_history ( char *  filename  )  [static]

Definition at line 2839 of file asterisk.c.

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

Referenced by ast_remotecontrol(), and main().

02840 {
02841    char buf[MAX_HISTORY_COMMAND_LENGTH];
02842    FILE *f;
02843    int ret = -1;
02844 
02845    if (el_hist == NULL || el == NULL)
02846       ast_el_initialize();
02847 
02848    if ((f = fopen(filename, "r")) == NULL)
02849       return ret;
02850 
02851    while (!feof(f)) {
02852       if (!fgets(buf, sizeof(buf), f))
02853          break;
02854       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02855          continue;
02856       if (ast_all_zeros(buf))
02857          continue;
02858       if ((ret = ast_el_add_history(buf)) == -1)
02859          break;
02860    }
02861    fclose(f);
02862 
02863    return ret;
02864 }

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

Definition at line 2598 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02599 {
02600    char *s1, *s2;
02601 
02602    s1 = ((char **)i1)[0];
02603    s2 = ((char **)i2)[0];
02604 
02605    return strcasecmp(s1, s2);
02606 }

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

Definition at line 2550 of file asterisk.c.

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

Referenced by cli_complete().

02551 {
02552    char *retstr;
02553    char **match_list = NULL;
02554    char **new_list;
02555    size_t match_list_len = 1;
02556    int matches = 0;
02557 
02558    while ((retstr = strsep(&buf, " "))) {
02559       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
02560          break;
02561       }
02562       if (matches + 1 >= match_list_len) {
02563          match_list_len <<= 1;
02564          new_list = ast_realloc(match_list, match_list_len * sizeof(char *));
02565          if (!new_list) {
02566             destroy_match_list(match_list, matches);
02567             return NULL;
02568          }
02569          match_list = new_list;
02570       }
02571 
02572       retstr = ast_strdup(retstr);
02573       if (!retstr) {
02574          destroy_match_list(match_list, matches);
02575          return NULL;
02576       }
02577       match_list[matches++] = retstr;
02578    }
02579 
02580    if (!match_list) {
02581       return NULL;
02582    }
02583 
02584    if (matches >= match_list_len) {
02585       new_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *));
02586       if (!new_list) {
02587          destroy_match_list(match_list, matches);
02588          return NULL;
02589       }
02590       match_list = new_list;
02591    }
02592 
02593    match_list[matches] = NULL;
02594 
02595    return match_list;
02596 }

static int ast_el_write_history ( char *  filename  )  [static]

Definition at line 2829 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by really_quit().

02830 {
02831    HistEvent ev;
02832 
02833    if (el_hist == NULL || el == NULL)
02834       ast_el_initialize();
02835 
02836    return (history(el_hist, &ev, H_SAVE, filename));
02837 }

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

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

Referenced by manager_modulecheck().

00391 {
00392    struct file_version *iterator;
00393 
00394    AST_RWLIST_WRLOCK(&file_versions);
00395    AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
00396       if (!strcasecmp(iterator->file, file))
00397          break;
00398    }
00399    AST_RWLIST_UNLOCK(&file_versions);
00400    if (iterator)
00401       return iterator->version;
00402    return NULL;
00403 }

static int ast_makesocket ( void   )  [static]

Definition at line 1474 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, and network_verboser().

Referenced by main().

01475 {
01476    struct sockaddr_un sunaddr;
01477    int res;
01478    int x;
01479    uid_t uid = -1;
01480    gid_t gid = -1;
01481 
01482    for (x = 0; x < AST_MAX_CONNECTS; x++)
01483       consoles[x].fd = -1;
01484    unlink(ast_config_AST_SOCKET);
01485    ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
01486    if (ast_socket < 0) {
01487       ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
01488       return -1;
01489    }
01490    memset(&sunaddr, 0, sizeof(sunaddr));
01491    sunaddr.sun_family = AF_LOCAL;
01492    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01493    res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01494    if (res) {
01495       ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01496       close(ast_socket);
01497       ast_socket = -1;
01498       return -1;
01499    }
01500    res = listen(ast_socket, 2);
01501    if (res < 0) {
01502       ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01503       close(ast_socket);
01504       ast_socket = -1;
01505       return -1;
01506    }
01507    if (ast_register_verbose(network_verboser)) {
01508       ast_log(LOG_WARNING, "Unable to register network verboser?\n");
01509    }
01510 
01511    if (ast_pthread_create_background(&lthread, NULL, listener, NULL)) {
01512       ast_log(LOG_WARNING, "Unable to create listener thread.\n");
01513       close(ast_socket);
01514       return -1;
01515    }
01516 
01517    if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
01518       struct passwd *pw;
01519       if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
01520          ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
01521       else
01522          uid = pw->pw_uid;
01523    }
01524 
01525    if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
01526       struct group *grp;
01527       if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
01528          ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
01529       else
01530          gid = grp->gr_gid;
01531    }
01532 
01533    if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
01534       ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01535 
01536    if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
01537       unsigned int p1;
01538       mode_t p;
01539       sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
01540       p = p1;
01541       if ((chmod(ast_config_AST_SOCKET, p)) < 0)
01542          ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01543    }
01544 
01545    return 0;
01546 }

int64_t ast_mark ( int  i,
int  startstop 
)

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

00790 {
00791    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00792       return 0;
00793    if (startstop == 1)
00794       prof_data->e[i].mark = rdtsc();
00795    else {
00796       prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
00797       if (prof_data->e[i].scale > 1)
00798          prof_data->e[i].mark /= prof_data->e[i].scale;
00799       prof_data->e[i].value += prof_data->e[i].mark;
00800       prof_data->e[i].events++;
00801    }
00802    return prof_data->e[i].mark;
00803 }

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

write the string to all attached console clients

Definition at line 1223 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

01224 {
01225    int x;
01226    for (x = 0; x < AST_MAX_CONNECTS; x++) {
01227       if (consoles[x].fd > -1)
01228          fdprint(consoles[x].p[1], string);
01229    }
01230 }

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

log the string to all attached console clients

Definition at line 1196 of file asterisk.c.

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

Referenced by ast_console_puts_mutable(), and network_verboser().

01197 {
01198    int x;
01199    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01200       if (consoles[x].mute)
01201          continue;
01202       if (consoles[x].fd > -1) {
01203          if (!consoles[x].levels[level])
01204             fdprint(consoles[x].p[1], string);
01205       }
01206    }
01207 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 754 of file asterisk.c.

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

00755 {
00756    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00757       return 0;
00758    if (prof_data->e[i].scale > 1)
00759       delta /= prof_data->e[i].scale;
00760    prof_data->e[i].value += delta;
00761    prof_data->e[i].events++;
00762    return prof_data->e[i].value;
00763 }

static void ast_readconfig ( void   )  [static]

Definition at line 3056 of file asterisk.c.

References _cfg_paths::agi_dir, agimaskvarend, agivar_count, AST_CACHE_DIR_LEN, AST_COMPAT_APP_SET, AST_COMPAT_DELIM_PBX_REALTIME, AST_COMPAT_DELIM_RES_AGI, ast_config_AST_CONFIG_FILE, ast_config_AST_CTL, ast_config_AST_CTL_GROUP, ast_config_AST_CTL_OWNER, ast_config_AST_CTL_PERMISSIONS, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_eid_default, ast_language_is_prefix, AST_LIST_EMPTY, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, AST_LOCK_TYPE_FLOCK, AST_LOCK_TYPE_LOCKFILE, ast_log(), 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_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_lock_type(), ast_str_to_eid(), ast_strip(), 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, DEFAULT_AGI_DIR, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILE, DEFAULT_DATA_DIR, DEFAULT_DB, DEFAULT_KEY_DIR, DEFAULT_LOG_DIR, DEFAULT_MODULE_DIR, DEFAULT_PID, DEFAULT_RUN_DIR, DEFAULT_SOCKET, DEFAULT_SPOOL_DIR, DEFAULT_VAR_DIR, defaultlanguage, hostname, _cfg_paths::key_dir, ast_atexit::list, live_dangerously, _cfg_paths::log_dir, LOG_ERROR, LOG_WARNING, malloc, MAX_LANGUAGE, MAXHOSTNAMELEN, _cfg_paths::module_dir, _cfg_paths::monitor_dir, ast_variable::name, ast_variable::next, pbx_live_dangerously(), _cfg_paths::pid_path, readmaskvarend, readvar_count, _cfg_paths::run_dir, _cfg_paths::run_group, _cfg_paths::run_user, set_ulimit(), setmaskvarend, setvar_count, _cfg_paths::socket_path, _cfg_paths::spool_dir, _cfg_paths::system_name, ast_variable::value, _cfg_paths::var_dir, ast_variable_list::variable, VERBOSE_PREFIX_1, and version.

Referenced by main().

03057 {
03058    struct ast_config *cfg;
03059    struct ast_variable *v;
03060    char *config = DEFAULT_CONFIG_FILE;
03061    char hostname[MAXHOSTNAMELEN] = "";
03062    struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME };
03063    struct {
03064       unsigned int dbdir:1;
03065       unsigned int keydir:1;
03066    } found = { 0, 0 };
03067    /* Default to true for backward compatibility */
03068    int live_dangerously = 1;
03069    char *tab = NULL;
03070    struct ast_variable_list *cur;
03071 
03072    if (ast_opt_override_config) {
03073       cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
03074       if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03075          fprintf(stderr, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
03076       }
03077    } else {
03078       cfg = ast_config_load2(config, "" /* core, can't reload */, config_flags);
03079    }
03080 
03081    /* init with buildtime config */
03082    ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir));
03083    ast_copy_string(cfg_paths.spool_dir, DEFAULT_SPOOL_DIR, sizeof(cfg_paths.spool_dir));
03084    ast_copy_string(cfg_paths.module_dir, DEFAULT_MODULE_DIR, sizeof(cfg_paths.module_dir));
03085    snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", cfg_paths.spool_dir);
03086    ast_copy_string(cfg_paths.var_dir, DEFAULT_VAR_DIR, sizeof(cfg_paths.var_dir));
03087    ast_copy_string(cfg_paths.data_dir, DEFAULT_DATA_DIR, sizeof(cfg_paths.data_dir));
03088    ast_copy_string(cfg_paths.log_dir, DEFAULT_LOG_DIR, sizeof(cfg_paths.log_dir));
03089    ast_copy_string(cfg_paths.agi_dir, DEFAULT_AGI_DIR, sizeof(cfg_paths.agi_dir));
03090    ast_copy_string(cfg_paths.db_path, DEFAULT_DB, sizeof(cfg_paths.db_path));
03091    ast_copy_string(cfg_paths.key_dir, DEFAULT_KEY_DIR, sizeof(cfg_paths.key_dir));
03092    ast_copy_string(cfg_paths.pid_path, DEFAULT_PID, sizeof(cfg_paths.pid_path));
03093    ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path));
03094    ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir));
03095 
03096    ast_set_default_eid(&ast_eid_default);
03097 
03098    /* no asterisk.conf? no problem, use buildtime config! */
03099    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03100       return;
03101    }
03102 
03103    for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
03104       if (!strcasecmp(v->name, "astctlpermissions"))
03105          ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
03106       else if (!strcasecmp(v->name, "astctlowner"))
03107          ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
03108       else if (!strcasecmp(v->name, "astctlgroup"))
03109          ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
03110       else if (!strcasecmp(v->name, "astctl"))
03111          ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
03112    }
03113 
03114    for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
03115       if (!strcasecmp(v->name, "astetcdir")) {
03116          ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir));
03117       } else if (!strcasecmp(v->name, "astspooldir")) {
03118          ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir));
03119          snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value);
03120       } else if (!strcasecmp(v->name, "astvarlibdir")) {
03121          ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir));
03122          if (!found.dbdir)
03123             snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
03124       } else if (!strcasecmp(v->name, "astdbdir")) {
03125          snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
03126          found.dbdir = 1;
03127       } else if (!strcasecmp(v->name, "astdatadir")) {
03128          ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir));
03129          if (!found.keydir)
03130             snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
03131       } else if (!strcasecmp(v->name, "astkeydir")) {
03132          snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
03133          found.keydir = 1;
03134       } else if (!strcasecmp(v->name, "astlogdir")) {
03135          ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir));
03136       } else if (!strcasecmp(v->name, "astagidir")) {
03137          ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir));
03138       } else if (!strcasecmp(v->name, "astrundir")) {
03139          snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid");
03140          snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", v->value, ast_config_AST_CTL);
03141          ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir));
03142       } else if (!strcasecmp(v->name, "astmoddir")) {
03143          ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir));
03144       }
03145    }
03146 
03147    for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
03148       /* verbose level (-v at startup) */
03149       if (!strcasecmp(v->name, "verbose")) {
03150          option_verbose = atoi(v->value);
03151       /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
03152       } else if (!strcasecmp(v->name, "timestamp")) {
03153          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
03154       /* whether or not to support #exec in config files */
03155       } else if (!strcasecmp(v->name, "execincludes")) {
03156          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
03157       /* debug level (-d at startup) */
03158       } else if (!strcasecmp(v->name, "debug")) {
03159          option_debug = 0;
03160          if (sscanf(v->value, "%30d", &option_debug) != 1) {
03161             option_debug = ast_true(v->value);
03162          }
03163 #if HAVE_WORKING_FORK
03164       /* Disable forking (-f at startup) */
03165       } else if (!strcasecmp(v->name, "nofork")) {
03166          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
03167       /* Always fork, even if verbose or debug are enabled (-F at startup) */
03168       } else if (!strcasecmp(v->name, "alwaysfork")) {
03169          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
03170 #endif
03171       /* Run quietly (-q at startup ) */
03172       } else if (!strcasecmp(v->name, "quiet")) {
03173          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
03174       /* Run as console (-c at startup, implies nofork) */
03175       } else if (!strcasecmp(v->name, "console")) {
03176          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
03177       /* Run with high priority if the O/S permits (-p at startup) */
03178       } else if (!strcasecmp(v->name, "highpriority")) {
03179          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
03180       /* Initialize RSA auth keys (IAX2) (-i at startup) */
03181       } else if (!strcasecmp(v->name, "initcrypto")) {
03182          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
03183       /* Disable ANSI colors for console (-c at startup) */
03184       } else if (!strcasecmp(v->name, "nocolor")) {
03185          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
03186       /* Disable some usage warnings for picky people :p */
03187       } else if (!strcasecmp(v->name, "dontwarn")) {
03188          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
03189       /* Dump core in case of crash (-g) */
03190       } else if (!strcasecmp(v->name, "dumpcore")) {
03191          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
03192       /* Cache recorded sound files to another directory during recording */
03193       } else if (!strcasecmp(v->name, "cache_record_files")) {
03194          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
03195       /* Specify cache directory */
03196       }  else if (!strcasecmp(v->name, "record_cache_dir")) {
03197          ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
03198       /* Build transcode paths via SLINEAR, instead of directly */
03199       } else if (!strcasecmp(v->name, "transcode_via_sln")) {
03200          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
03201       /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
03202       } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
03203          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
03204       /* Enable internal timing */
03205       } else if (!strcasecmp(v->name, "internal_timing")) {
03206          if (!ast_opt_remote) {
03207             fprintf(stderr,
03208                "NOTICE: The internal_timing option is no longer needed.\n"
03209                "  It will always be enabled if you have a timing module loaded.\n");
03210          }
03211       } else if (!strcasecmp(v->name, "maxcalls")) {
03212          if ((sscanf(v->value, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
03213             option_maxcalls = 0;
03214          }
03215       } else if (!strcasecmp(v->name, "maxload")) {
03216          double test[1];
03217 
03218          if (getloadavg(test, 1) == -1) {
03219             ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
03220             option_maxload = 0.0;
03221          } else if ((sscanf(v->value, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
03222             option_maxload = 0.0;
03223          }
03224       /* Set the maximum amount of open files */
03225       } else if (!strcasecmp(v->name, "maxfiles")) {
03226          option_maxfiles = atoi(v->value);
03227          set_ulimit(option_maxfiles);
03228       /* What user to run as */
03229       } else if (!strcasecmp(v->name, "runuser")) {
03230          ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user));
03231       /* What group to run as */
03232       } else if (!strcasecmp(v->name, "rungroup")) {
03233          ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group));
03234       } else if (!strcasecmp(v->name, "systemname")) {
03235          ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name));
03236       } else if (!strcasecmp(v->name, "autosystemname")) {
03237          if (ast_true(v->value)) {
03238             if (!gethostname(hostname, sizeof(hostname) - 1))
03239                ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name));
03240             else {
03241                if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){
03242                   ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name));
03243                }
03244                ast_log(LOG_ERROR, "Cannot obtain hostname for this system.  Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME);
03245             }
03246          }
03247       } else if (!strcasecmp(v->name, "languageprefix")) {
03248          ast_language_is_prefix = ast_true(v->value);
03249       } else if (!strcasecmp(v->name, "defaultlanguage")) {
03250          ast_copy_string(defaultlanguage, v->value, MAX_LANGUAGE);
03251       } else if (!strcasecmp(v->name, "lockmode")) {
03252          if (!strcasecmp(v->value, "lockfile")) {
03253             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03254          } else if (!strcasecmp(v->value, "flock")) {
03255             ast_set_lock_type(AST_LOCK_TYPE_FLOCK);
03256          } else {
03257             ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, "
03258                "defaulting to 'lockfile'\n", v->value);
03259             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03260          }
03261 #if defined(HAVE_SYSINFO)
03262       } else if (!strcasecmp(v->name, "minmemfree")) {
03263          /* specify the minimum amount of free memory to retain.  Asterisk should stop accepting new calls
03264           * if the amount of free memory falls below this watermark */
03265          if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
03266             option_minmemfree = 0;
03267          }
03268 #endif
03269       } else if (!strcasecmp(v->name, "entityid")) {
03270          struct ast_eid tmp_eid;
03271          if (!ast_str_to_eid(&tmp_eid, v->value)) {
03272             ast_verbose("Successfully set global EID to '%s'\n", v->value);
03273             ast_eid_default = tmp_eid;
03274          } else
03275             ast_verbose("Invalid Entity ID '%s' provided\n", v->value);
03276       } else if (!strcasecmp(v->name, "lightbackground")) {
03277          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND);
03278       } else if (!strcasecmp(v->name, "forceblackbackground")) {
03279          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03280       } else if (!strcasecmp(v->name, "hideconnect")) {
03281          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT);
03282       } else if (!strcasecmp(v->name, "lockconfdir")) {
03283          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LOCK_CONFIG_DIR);
03284       } else if (!strcasecmp(v->name, "live_dangerously")) {
03285          live_dangerously = ast_true(v->value);
03286       } else if (!strcasecmp(v->name, "setmaskvar")) {
03287          /* Only read at asterisk boot */
03288          if (!ast_opt_remote) {
03289             ast_copy_string(setmaskvar, v->value, sizeof(setmaskvar));
03290          /* Load list with values */
03291             while ((tab = strsep(&v->value, ","))) {
03292                cur = (struct ast_variable_list *) malloc(sizeof(struct ast_variable_list));
03293                memset(cur, 0, sizeof(struct ast_variable_list));
03294                if (!cur) {
03295                   ast_verbose( VERBOSE_PREFIX_1 "MALLOC FAILED - Can't create a list for 'setmaskvar'\n");
03296                   break;
03297                }
03298                ast_copy_string(cur->variable, ast_strip(tab), sizeof(cur->variable));
03299                if (strlen(cur->variable) > 0) {
03300                   AST_LIST_INSERT_TAIL(&setmaskvars, cur, list);
03301                   setvar_count++;
03302                }
03303             }
03304             if (AST_LIST_EMPTY(&setmaskvars)) {
03305                ast_verbose( VERBOSE_PREFIX_1 "No variables configured for setmaskvar\n");
03306             } else {
03307                ast_verbose( VERBOSE_PREFIX_1 "Using %i variables for setmaskvar: ", setvar_count);
03308                AST_LIST_TRAVERSE(&setmaskvars, cur, list) {
03309                   ast_verbose("%s ", cur->variable);
03310                }
03311                ast_verbose("\n");
03312             }
03313          }
03314       } else if (!strcasecmp(v->name, "setmaskvarini")) {
03315          setmaskvarini = atoi(v->value);
03316       } else if (!strcasecmp(v->name, "setmaskvarend")) {
03317          setmaskvarend = atoi(v->value);
03318       } else if (!strcasecmp(v->name, "readmaskvar")) {
03319          /* Only read at asterisk boot */
03320          if (!ast_opt_remote) {
03321             ast_copy_string(readmaskvar, v->value, sizeof(readmaskvar));
03322          /* Load list with values */
03323             while ((tab = strsep(&v->value, ","))) {
03324                cur = (struct ast_variable_list *) malloc(sizeof(struct ast_variable_list));
03325                memset(cur, 0, sizeof(struct ast_variable_list));
03326                if (!cur) {
03327                   ast_verbose( VERBOSE_PREFIX_1 "MALLOC FAILED - Can't create a list for 'readmaskvar'\n");
03328                   break;
03329                }
03330                ast_copy_string(cur->variable, ast_strip(tab), sizeof(cur->variable));
03331                if (strlen(cur->variable) > 0) {
03332                   AST_LIST_INSERT_TAIL(&readmaskvars, cur, list);
03333                   readvar_count++;
03334                }
03335             }
03336             if (AST_LIST_EMPTY(&readmaskvars)) {
03337                ast_verbose( VERBOSE_PREFIX_1 "No variables configured for readmaskvar\n");
03338             } else {
03339                ast_verbose( VERBOSE_PREFIX_1 "Using %i variables for readmaskvar: ", readvar_count);
03340                AST_LIST_TRAVERSE(&readmaskvars, cur, list) {
03341                   ast_verbose("%s ", cur->variable);
03342                }
03343                ast_verbose("\n");
03344             }
03345          }
03346       } else if (!strcasecmp(v->name, "readmaskvarini")) {
03347          readmaskvarini = atoi(v->value);
03348       } else if (!strcasecmp(v->name, "readmaskvarend")) {
03349          readmaskvarend = atoi(v->value);
03350       } else if (!strcasecmp(v->name, "agimaskvar")) {
03351          /* Only read at asterisk boot */
03352          if (!ast_opt_remote) {
03353             ast_copy_string(agimaskvar, v->value, sizeof(agimaskvar));
03354          /* Load list with values */
03355             while ((tab = strsep(&v->value, ","))) {
03356                cur = (struct ast_variable_list *) malloc(sizeof(struct ast_variable_list));
03357                memset(cur, 0, sizeof(struct ast_variable_list));
03358                if (!cur) {
03359                   ast_verbose( VERBOSE_PREFIX_1 "MALLOC FAILED - Can't create a list for 'agimaskvar'\n");
03360                   break;
03361                }
03362                ast_copy_string(cur->variable, ast_strip(tab), sizeof(cur->variable));
03363                if (strlen(cur->variable) > 0) {
03364                   AST_LIST_INSERT_TAIL(&agimaskvars, cur, list);
03365                   agivar_count++;
03366                }
03367             }
03368             if (AST_LIST_EMPTY(&agimaskvars)) {
03369                ast_verbose( VERBOSE_PREFIX_1 "No variables configured for agimaskvar\n");
03370             } else {
03371                ast_verbose( VERBOSE_PREFIX_1 "Using %i variables for agimaskvar: ", agivar_count);
03372                AST_LIST_TRAVERSE(&agimaskvars, cur, list) {
03373                   ast_verbose("%s ", cur->variable);
03374                }
03375                ast_verbose("\n");
03376             }
03377          }
03378       } else if (!strcasecmp(v->name, "agimaskvarini")) {
03379          agimaskvarini = atoi(v->value);
03380       } else if (!strcasecmp(v->name, "agimaskvarend")) {
03381          agimaskvarend = atoi(v->value);
03382       }
03383 
03384    }
03385    if (!ast_opt_remote) {
03386       pbx_live_dangerously(live_dangerously);
03387    }
03388    for (v = ast_variable_browse(cfg, "compat"); v; v = v->next) {
03389       float version;
03390       if (sscanf(v->value, "%30f", &version) != 1) {
03391          fprintf(stderr, "Compatibility version for option '%s' is not a number: '%s'\n", v->name, v->value);
03392          continue;
03393       }
03394       if (!strcasecmp(v->name, "app_set")) {
03395          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_APP_SET);
03396       } else if (!strcasecmp(v->name, "res_agi")) {
03397          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_RES_AGI);
03398       } else if (!strcasecmp(v->name, "pbx_realtime")) {
03399          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_PBX_REALTIME);
03400       }
03401    }
03402    ast_config_destroy(cfg);
03403 }

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

Register a function to be executed before Asterisk gracefully exits.

Since:
1.8.29 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 1017 of file asterisk.c.

References ast_atexit::func, and register_atexit().

Referenced by ast_autoservice_init().

01018 {
01019    return register_atexit(func, 1);
01020 }

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

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

00333 {
00334    struct file_version *new;
00335    char *work;
00336    size_t version_length;
00337 
00338    work = ast_strdupa(version);
00339    work = ast_strip(ast_strip_quoted(work, "$", "$"));
00340    version_length = strlen(work) + 1;
00341 
00342    if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
00343       return;
00344 
00345    new->file = file;
00346    new->version = (char *) new + sizeof(*new);
00347    memcpy(new->version, work, version_length);
00348    AST_RWLIST_WRLOCK(&file_versions);
00349    AST_RWLIST_INSERT_HEAD(&file_versions, new, list);
00350    AST_RWLIST_UNLOCK(&file_versions);
00351 }

void ast_register_thread ( char *  name  ) 

Definition at line 415 of file asterisk.c.

References ast_assert, ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and multi_thread_safe.

Referenced by dummy_start().

00416 {
00417    struct thread_list_t *new = ast_calloc(1, sizeof(*new));
00418 
00419    if (!new)
00420       return;
00421 
00422    ast_assert(multi_thread_safe);
00423    new->id = pthread_self();
00424    new->name = name; /* steal the allocated memory for the thread name */
00425    AST_RWLIST_WRLOCK(&thread_list);
00426    AST_RWLIST_INSERT_HEAD(&thread_list, new, list);
00427    AST_RWLIST_UNLOCK(&thread_list);
00428 }

static void ast_remotecontrol ( char *  data  )  [static]

Definition at line 2866 of file asterisk.c.

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

Referenced by main().

02867 {
02868    char buf[80];
02869    int res;
02870    char filename[80] = "";
02871    char *hostname;
02872    char *cpid;
02873    char *version;
02874    int pid;
02875    char *stringp = NULL;
02876 
02877    char *ebuf;
02878    int num = 0;
02879 
02880    memset(&sig_flags, 0, sizeof(sig_flags));
02881    signal(SIGINT, __remote_quit_handler);
02882    signal(SIGTERM, __remote_quit_handler);
02883    signal(SIGHUP, __remote_quit_handler);
02884 
02885    if (read(ast_consock, buf, sizeof(buf)) < 0) {
02886       ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02887       return;
02888    }
02889    if (data) {
02890       char prefix[] = "cli quit after ";
02891       char *tmp = ast_alloca(strlen(data) + strlen(prefix) + 1);
02892       sprintf(tmp, "%s%s", prefix, data);
02893       if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
02894          ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
02895          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02896             return;
02897          }
02898       }
02899    }
02900    stringp = buf;
02901    hostname = strsep(&stringp, "/");
02902    cpid = strsep(&stringp, "/");
02903    version = strsep(&stringp, "\n");
02904    if (!version)
02905       version = "<Version Unknown>";
02906    stringp = hostname;
02907    strsep(&stringp, ".");
02908    if (cpid)
02909       pid = atoi(cpid);
02910    else
02911       pid = -1;
02912    if (!data) {
02913       char tmp[80];
02914       snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
02915       fdsend(ast_consock, tmp);
02916       snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
02917       fdsend(ast_consock, tmp);
02918       if (!ast_opt_mute)
02919          fdsend(ast_consock, "logger mute silent");
02920       else
02921          printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02922    }
02923 
02924    if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
02925       struct pollfd fds;
02926       fds.fd = ast_consock;
02927       fds.events = POLLIN;
02928       fds.revents = 0;
02929       while (ast_poll(&fds, 1, 60000) > 0) {
02930          char buffer[512] = "", *curline = buffer, *nextline;
02931          int not_written = 1;
02932 
02933          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02934             break;
02935          }
02936 
02937          if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
02938             break;
02939          }
02940 
02941          do {
02942             if ((nextline = strchr(curline, '\n'))) {
02943                nextline++;
02944             } else {
02945                nextline = strchr(curline, '\0');
02946             }
02947 
02948             /* Skip verbose lines */
02949             if (*curline != 127) {
02950                not_written = 0;
02951                if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
02952                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
02953                }
02954             }
02955             curline = nextline;
02956          } while (!ast_strlen_zero(curline));
02957 
02958          /* No non-verbose output in 60 seconds. */
02959          if (not_written) {
02960             break;
02961          }
02962       }
02963       return;
02964    }
02965 
02966    ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
02967    remotehostname = hostname;
02968    if (getenv("HOME"))
02969       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
02970    if (el_hist == NULL || el == NULL)
02971       ast_el_initialize();
02972 
02973    el_set(el, EL_GETCFN, ast_el_read_char);
02974 
02975    if (!ast_strlen_zero(filename))
02976       ast_el_read_history(filename);
02977 
02978    for (;;) {
02979       ebuf = (char *)el_gets(el, &num);
02980 
02981       if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02982          break;
02983       }
02984 
02985       if (!ebuf && write(1, "", 1) < 0)
02986          break;
02987 
02988       if (!ast_strlen_zero(ebuf)) {
02989          if (ebuf[strlen(ebuf)-1] == '\n')
02990             ebuf[strlen(ebuf)-1] = '\0';
02991          if (!remoteconsolehandler(ebuf)) {
02992             /* Strip preamble from output */
02993             char *temp;
02994             for (temp = ebuf; *temp; temp++) {
02995                if (*temp == 127) {
02996                   memmove(temp, temp + 1, strlen(temp));
02997                   temp--;
02998                }
02999             }
03000             res = write(ast_consock, ebuf, strlen(ebuf) + 1);
03001             if (res < 1) {
03002                ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
03003                break;
03004             }
03005          }
03006       }
03007    }
03008    printf("\nDisconnected from Asterisk server\n");
03009 }

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

01062 {
01063    unsigned int level;
01064 
01065    ast_mutex_lock(&safe_system_lock);
01066    level = safe_system_level++;
01067 
01068    /* only replace the handler if it has not already been done */
01069    if (level == 0) {
01070       sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
01071    }
01072 
01073    ast_mutex_unlock(&safe_system_lock);
01074 }

static void ast_run_atexits ( int  run_cleanups  )  [static]

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

00966 {
00967    struct ast_atexit *ae;
00968 
00969    AST_LIST_LOCK(&atexits);
00970    while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
00971       if (ae->func && (!ae->is_cleanup || run_cleanups)) {
00972          ae->func();
00973       }
00974       ast_free(ae);
00975    }
00976    AST_LIST_UNLOCK(&atexits);
00977 }

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

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

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

01092 {
01093    pid_t pid;
01094    int res;
01095    struct rusage rusage;
01096    int status;
01097 
01098 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
01099    ast_replace_sigchld();
01100 
01101 #ifdef HAVE_WORKING_FORK
01102    pid = fork();
01103 #else
01104    pid = vfork();
01105 #endif
01106 
01107    if (pid == 0) {
01108 #ifdef HAVE_CAP
01109       cap_t cap = cap_from_text("cap_net_admin-eip");
01110 
01111       if (cap_set_proc(cap)) {
01112          /* Careful with order! Logging cannot happen after we close FDs */
01113          ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
01114       }
01115       cap_free(cap);
01116 #endif
01117 #ifdef HAVE_WORKING_FORK
01118       if (ast_opt_high_priority)
01119          ast_set_priority(0);
01120       /* Close file descriptors and launch system command */
01121       ast_close_fds_above_n(STDERR_FILENO);
01122 #endif
01123       execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
01124       _exit(1);
01125    } else if (pid > 0) {
01126       for (;;) {
01127          res = wait4(pid, &status, 0, &rusage);
01128          if (res > -1) {
01129             res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
01130             break;
01131          } else if (errno != EINTR)
01132             break;
01133       }
01134    } else {
01135       ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
01136       res = -1;
01137    }
01138 
01139    ast_unreplace_sigchld();
01140 #else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */
01141    res = -1;
01142 #endif
01143 
01144    return res;
01145 }

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

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

01665 {
01666    struct sched_param sched;
01667    memset(&sched, 0, sizeof(sched));
01668 #ifdef __linux__
01669    if (pri) {
01670       sched.sched_priority = 10;
01671       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01672          ast_log(LOG_WARNING, "Unable to set high priority\n");
01673          return -1;
01674       } else
01675          if (option_verbose)
01676             ast_verbose("Set to realtime thread\n");
01677    } else {
01678       sched.sched_priority = 0;
01679       /* According to the manpage, these parameters can never fail. */
01680       sched_setscheduler(0, SCHED_OTHER, &sched);
01681    }
01682 #else
01683    if (pri) {
01684       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01685          ast_log(LOG_WARNING, "Unable to set high priority\n");
01686          return -1;
01687       } else
01688          if (option_verbose)
01689             ast_verbose("Set to high priority\n");
01690    } else {
01691       /* According to the manpage, these parameters can never fail. */
01692       setpriority(PRIO_PROCESS, 0, 0);
01693    }
01694 #endif
01695    return 0;
01696 }

static int ast_tryconnect ( void   )  [static]

Definition at line 1548 of file asterisk.c.

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

Referenced by ast_el_read_char(), and main().

01549 {
01550    struct sockaddr_un sunaddr;
01551    int res;
01552    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01553    if (ast_consock < 0) {
01554       fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
01555       return 0;
01556    }
01557    memset(&sunaddr, 0, sizeof(sunaddr));
01558    sunaddr.sun_family = AF_LOCAL;
01559    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01560    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01561    if (res) {
01562       close(ast_consock);
01563       ast_consock = -1;
01564       return 0;
01565    } else
01566       return 1;
01567 }

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

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

Referenced by do_reload(), and unload_module().

01023 {
01024    AST_LIST_LOCK(&atexits);
01025    __ast_unregister_atexit(func);
01026    AST_LIST_UNLOCK(&atexits);
01027 }

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

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

00354 {
00355    struct file_version *find;
00356 
00357    AST_RWLIST_WRLOCK(&file_versions);
00358    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
00359       if (!strcasecmp(find->file, file)) {
00360          AST_RWLIST_REMOVE_CURRENT(list);
00361          break;
00362       }
00363    }
00364    AST_RWLIST_TRAVERSE_SAFE_END;
00365    AST_RWLIST_UNLOCK(&file_versions);
00366 
00367    if (find)
00368       ast_free(find);
00369 }

void ast_unregister_thread ( void *  id  ) 

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

00431 {
00432    struct thread_list_t *x;
00433 
00434    AST_RWLIST_WRLOCK(&thread_list);
00435    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
00436       if ((void *) x->id == id) {
00437          AST_RWLIST_REMOVE_CURRENT(list);
00438          break;
00439       }
00440    }
00441    AST_RWLIST_TRAVERSE_SAFE_END;
00442    AST_RWLIST_UNLOCK(&thread_list);
00443    if (x) {
00444       ast_free(x->name);
00445       ast_free(x);
00446    }
00447 }

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

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

Referenced by ast_safe_fork_cleanup(), and ast_safe_system().

01077 {
01078    unsigned int level;
01079 
01080    ast_mutex_lock(&safe_system_lock);
01081    level = --safe_system_level;
01082 
01083    /* only restore the handler if we are the last one */
01084    if (level == 0) {
01085       sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
01086    }
01087 
01088    ast_mutex_unlock(&safe_system_lock);
01089 }

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

Definition at line 1710 of file asterisk.c.

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

Referenced by quit_handler().

01711 {
01712    /* Check if someone else isn't already doing this. */
01713    ast_mutex_lock(&safe_system_lock);
01714    if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
01715       /* Already in progress and other request was less nice. */
01716       ast_mutex_unlock(&safe_system_lock);
01717       ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
01718       return 0;
01719    }
01720    shuttingdown = niceness;
01721    ast_mutex_unlock(&safe_system_lock);
01722 
01723    /* Try to get as many CDRs as possible submitted to the backend engines
01724     * (if in batch mode). really_quit happens to call it again when running
01725     * the atexit handlers, otherwise this would be a bit early. */
01726    ast_cdr_engine_term();
01727 
01728    if (niceness == SHUTDOWN_NORMAL) {
01729       time_t s, e;
01730       /* Begin shutdown routine, hanging up active channels */
01731       ast_begin_shutdown(1);
01732       if (option_verbose && ast_opt_console) {
01733          ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
01734       }
01735       time(&s);
01736       for (;;) {
01737          time(&e);
01738          /* Wait up to 15 seconds for all channels to go away */
01739          if ((e - s) > 15 || !ast_undestroyed_channels() || shuttingdown != niceness) {
01740             break;
01741          }
01742          /* Sleep 1/10 of a second */
01743          usleep(100000);
01744       }
01745    } else if (niceness >= SHUTDOWN_NICE) {
01746       if (niceness != SHUTDOWN_REALLY_NICE) {
01747          ast_begin_shutdown(0);
01748       }
01749       if (option_verbose && ast_opt_console) {
01750          ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
01751       }
01752       for (;;) {
01753          if (!ast_undestroyed_channels() || shuttingdown != niceness) {
01754             break;
01755          }
01756          sleep(1);
01757       }
01758    }
01759 
01760    /* Re-acquire lock and check if someone changed the niceness, in which
01761     * case someone else has taken over the shutdown. */
01762    ast_mutex_lock(&safe_system_lock);
01763    if (shuttingdown != niceness) {
01764       if (shuttingdown == NOT_SHUTTING_DOWN && option_verbose && ast_opt_console) {
01765          ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
01766       }
01767       ast_mutex_unlock(&safe_system_lock);
01768       return 0;
01769    }
01770    shuttingdown = SHUTTING_DOWN;
01771    ast_mutex_unlock(&safe_system_lock);
01772 
01773    return 1;
01774 }

static void canary_exit ( void   )  [static]

Definition at line 3460 of file asterisk.c.

References canary_pid.

Referenced by main().

03461 {
03462    if (canary_pid > 0)
03463       kill(canary_pid, SIGKILL);
03464 }

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

Definition at line 3431 of file asterisk.c.

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

Referenced by main().

03432 {
03433    struct stat canary_stat;
03434    struct timeval now;
03435 
03436    /* Give the canary time to sing */
03437    sleep(120);
03438 
03439    for (;;) {
03440       now = ast_tvnow();
03441       if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
03442          ast_log(LOG_WARNING,
03443             "The canary is no more.  He has ceased to be!  "
03444             "He's expired and gone to meet his maker!  "
03445             "He's a stiff!  Bereft of life, he rests in peace.  "
03446             "His metabolic processes are now history!  He's off the twig!  "
03447             "He's kicked the bucket.  He's shuffled off his mortal coil, "
03448             "run down the curtain, and joined the bleeding choir invisible!!  "
03449             "THIS is an EX-CANARY.  (Reducing priority)\n");
03450          ast_set_priority(0);
03451          pthread_exit(NULL);
03452       }
03453 
03454       /* Check the canary once a minute */
03455       sleep(60);
03456    }
03457 }

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

Definition at line 2656 of file asterisk.c.

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

Referenced by ast_el_initialize().

02657 {
02658    int len = 0;
02659    char *ptr;
02660    int nummatches = 0;
02661    char **matches;
02662    int retval = CC_ERROR;
02663    char buf[2048], savechr;
02664    int res;
02665 
02666    LineInfo *lf = (LineInfo *)el_line(editline);
02667 
02668    savechr = *(char *)lf->cursor;
02669    *(char *)lf->cursor = '\0';
02670    ptr = (char *)lf->cursor;
02671    if (ptr) {
02672       while (ptr > lf->buffer) {
02673          if (isspace(*ptr)) {
02674             ptr++;
02675             break;
02676          }
02677          ptr--;
02678       }
02679    }
02680 
02681    len = lf->cursor - ptr;
02682 
02683    if (ast_opt_remote) {
02684       snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);
02685       fdsend(ast_consock, buf);
02686       if ((res = read(ast_consock, buf, sizeof(buf) - 1)) < 0) {
02687          return (char*)(CC_ERROR);
02688       }
02689       buf[res] = '\0';
02690       nummatches = atoi(buf);
02691 
02692       if (nummatches > 0) {
02693          char *mbuf;
02694          char *new_mbuf;
02695          int mlen = 0, maxmbuf = 2048;
02696 
02697          /* Start with a 2048 byte buffer */
02698          if (!(mbuf = ast_malloc(maxmbuf))) {
02699             lf->cursor[0] = savechr;
02700             return (char *)(CC_ERROR);
02701          }
02702          snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);
02703          fdsend(ast_consock, buf);
02704          res = 0;
02705          mbuf[0] = '\0';
02706          while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
02707             if (mlen + 1024 > maxmbuf) {
02708                /* Every step increment buffer 1024 bytes */
02709                maxmbuf += 1024;
02710                new_mbuf = ast_realloc(mbuf, maxmbuf);
02711                if (!new_mbuf) {
02712                   ast_free(mbuf);
02713                   lf->cursor[0] = savechr;
02714                   return (char *)(CC_ERROR);
02715                }
02716                mbuf = new_mbuf;
02717             }
02718             /* Only read 1024 bytes at a time */
02719             res = read(ast_consock, mbuf + mlen, 1024);
02720             if (res > 0)
02721                mlen += res;
02722          }
02723          mbuf[mlen] = '\0';
02724 
02725          matches = ast_el_strtoarr(mbuf);
02726          ast_free(mbuf);
02727       } else
02728          matches = (char **) NULL;
02729    } else {
02730       char **p, *oldbuf=NULL;
02731       nummatches = 0;
02732       matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
02733       for (p = matches; p && *p; p++) {
02734          if (!oldbuf || strcmp(*p,oldbuf))
02735             nummatches++;
02736          oldbuf = *p;
02737       }
02738    }
02739 
02740    if (matches) {
02741       int i;
02742       int matches_num, maxlen, match_len;
02743 
02744       if (matches[0][0] != '\0') {
02745          el_deletestr(editline, (int) len);
02746          el_insertstr(editline, matches[0]);
02747          retval = CC_REFRESH;
02748       }
02749 
02750       if (nummatches == 1) {
02751          /* Found an exact match */
02752          el_insertstr(editline, " ");
02753          retval = CC_REFRESH;
02754       } else {
02755          /* Must be more than one match */
02756          for (i = 1, maxlen = 0; matches[i]; i++) {
02757             match_len = strlen(matches[i]);
02758             if (match_len > maxlen)
02759                maxlen = match_len;
02760          }
02761          matches_num = i - 1;
02762          if (matches_num >1) {
02763             fprintf(stdout, "\n");
02764             ast_cli_display_match_list(matches, nummatches, maxlen);
02765             retval = CC_REDISPLAY;
02766          } else {
02767             el_insertstr(editline," ");
02768             retval = CC_REFRESH;
02769          }
02770       }
02771       for (i = 0; matches[i]; i++)
02772          ast_free(matches[i]);
02773       ast_free(matches);
02774    }
02775 
02776    lf->cursor[0] = savechr;
02777 
02778    return (char *)(long)retval;
02779 }

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

Definition at line 2411 of file asterisk.c.

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

Referenced by ast_el_initialize().

02412 {
02413    char tmp[100];
02414    char *pfmt;
02415    int color_used = 0;
02416    static int cli_prompt_changes = 0;
02417    char term_code[20];
02418    struct passwd *pw;
02419    struct group *gr;
02420 
02421    if (prompt == NULL) {
02422       prompt = ast_str_create(100);
02423    } else if (!cli_prompt_changes) {
02424       return ast_str_buffer(prompt);
02425    } else {
02426       ast_str_reset(prompt);
02427    }
02428 
02429    if ((pfmt = getenv("ASTERISK_PROMPT"))) {
02430       char *t = pfmt;
02431       struct timeval ts = ast_tvnow();
02432       while (*t != '\0') {
02433          if (*t == '%') {
02434             char hostname[MAXHOSTNAMELEN] = "";
02435             int i, which;
02436             struct ast_tm tm = { 0, };
02437             int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
02438 
02439             t++;
02440             switch (*t) {
02441             case 'C': /* color */
02442                t++;
02443                if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
02444                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)));
02445                   t += i - 1;
02446                } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
02447                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code)));
02448                   t += i - 1;
02449                }
02450 
02451                /* If the color has been reset correctly, then there's no need to reset it later */
02452                color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
02453                break;
02454             case 'd': /* date */
02455                if (ast_localtime(&ts, &tm, NULL)) {
02456                   ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
02457                   ast_str_append(&prompt, 0, "%s", tmp);
02458                   cli_prompt_changes++;
02459                }
02460                break;
02461             case 'g': /* group */
02462                if ((gr = getgrgid(getgid()))) {
02463                   ast_str_append(&prompt, 0, "%s", gr->gr_name);
02464                }
02465                break;
02466             case 'h': /* hostname */
02467                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02468                   ast_str_append(&prompt, 0, "%s", hostname);
02469                } else {
02470                   ast_str_append(&prompt, 0, "%s", "localhost");
02471                }
02472                break;
02473             case 'H': /* short hostname */
02474                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02475                   char *dotptr;
02476                   if ((dotptr = strchr(hostname, '.'))) {
02477                      *dotptr = '\0';
02478                   }
02479                   ast_str_append(&prompt, 0, "%s", hostname);
02480                } else {
02481                   ast_str_append(&prompt, 0, "%s", "localhost");
02482                }
02483                break;
02484 #ifdef HAVE_GETLOADAVG
02485             case 'l': /* load avg */
02486                t++;
02487                if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
02488                   double list[3];
02489                   getloadavg(list, 3);
02490                   ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
02491                   cli_prompt_changes++;
02492                }
02493                break;
02494 #endif
02495             case 's': /* Asterisk system name (from asterisk.conf) */
02496                ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
02497                break;
02498             case 't': /* time */
02499                if (ast_localtime(&ts, &tm, NULL)) {
02500                   ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
02501                   ast_str_append(&prompt, 0, "%s", tmp);
02502                   cli_prompt_changes++;
02503                }
02504                break;
02505             case 'u': /* username */
02506                if ((pw = getpwuid(getuid()))) {
02507                   ast_str_append(&prompt, 0, "%s", pw->pw_name);
02508                }
02509                break;
02510             case '#': /* process console or remote? */
02511                ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
02512                break;
02513             case '%': /* literal % */
02514                ast_str_append(&prompt, 0, "%c", '%');
02515                break;
02516             case '\0': /* % is last character - prevent bug */
02517                t--;
02518                break;
02519             }
02520          } else {
02521             ast_str_append(&prompt, 0, "%c", *t);
02522          }
02523          t++;
02524       }
02525       if (color_used) {
02526          /* Force colors back to normal at end */
02527          ast_str_append(&prompt, 0, "%s", term_color_code(term_code, 0, 0, sizeof(term_code)));
02528       }
02529    } else if (remotehostname) {
02530       ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname);
02531    } else {
02532       ast_str_set(&prompt, 0, "%s", ASTERISK_PROMPT);
02533    }
02534 
02535    return ast_str_buffer(prompt);
02536 }

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

Definition at line 1913 of file asterisk.c.

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

Referenced by print_intro_message().

01914 {
01915    char tmp[80];
01916    const char *c = NULL;
01917 
01918    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01919        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01920        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01921        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
01922       fputs(tmp, stdout);
01923       fputs(c, stdout);
01924    } else {
01925       if (*s == 127) {
01926          s++;
01927       }
01928       fputs(s, stdout);
01929    }
01930 
01931    fflush(stdout);
01932 
01933    /* Wake up a poll()ing console */
01934    if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
01935       pthread_kill(consolethread, SIGURG);
01936 }

static void consolehandler ( char *  s  )  [static]

Definition at line 1948 of file asterisk.c.

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

Referenced by main().

01949 {
01950    printf("%s", term_end());
01951    fflush(stdout);
01952 
01953    /* Called when readline data is available */
01954    if (!ast_all_zeros(s))
01955       ast_el_add_history(s);
01956    /* The real handler for bang */
01957    if (s[0] == '!') {
01958       if (s[1])
01959          ast_safe_system(s+1);
01960       else
01961          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01962    } else
01963       ast_cli_command(STDOUT_FILENO, s);
01964 }

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

Definition at line 2538 of file asterisk.c.

References ast_free.

Referenced by ast_el_strtoarr().

02539 {
02540    if (match_list) {
02541       int idx;
02542 
02543       for (idx = 0; idx < matches; ++idx) {
02544          ast_free(match_list[idx]);
02545       }
02546       ast_free(match_list);
02547    }
02548 }

static void env_init ( void   )  [static]

Definition at line 3494 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, and ast_get_version().

Referenced by main().

03495 {
03496    setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
03497    setenv("AST_BUILD_HOST", ast_build_hostname, 1);
03498    setenv("AST_BUILD_DATE", ast_build_date, 1);
03499    setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
03500    setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
03501    setenv("AST_BUILD_OS", ast_build_os, 1);
03502    setenv("AST_BUILD_USER", ast_build_user, 1);
03503    setenv("AST_VERSION", ast_get_version(), 1);
03504 }

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

Definition at line 1036 of file asterisk.c.

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

01037 {
01038    return write(fd, s, strlen(s));
01039 }

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

Definition at line 1030 of file asterisk.c.

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

01031 {
01032    return write(fd, s, strlen(s) + 1);
01033 }

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

Definition at line 1896 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01897 {
01898    const char *c;
01899 
01900    /* Check for verboser preamble */
01901    if (*s == 127) {
01902       s++;
01903    }
01904 
01905    if (!strncmp(s, cmp, strlen(cmp))) {
01906       c = s + strlen(cmp);
01907       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01908       return c;
01909    }
01910    return NULL;
01911 }

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

Definition at line 2144 of file asterisk.c.

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

02145 {
02146    int aborting_shutdown = 0;
02147 
02148    switch (cmd) {
02149    case CLI_INIT:
02150       e->command = "core abort shutdown";
02151       e->usage =
02152          "Usage: core abort shutdown\n"
02153          "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
02154          "       call operations.\n";
02155       return NULL;
02156    case CLI_GENERATE:
02157       return NULL;
02158    }
02159 
02160    if (a->argc != e->args)
02161       return CLI_SHOWUSAGE;
02162 
02163    ast_mutex_lock(&safe_system_lock);
02164    if (shuttingdown >= SHUTDOWN_FAST) {
02165       aborting_shutdown = 1;
02166       shuttingdown = NOT_SHUTTING_DOWN;
02167    }
02168    ast_mutex_unlock(&safe_system_lock);
02169 
02170    if (aborting_shutdown) {
02171       ast_cancel_shutdown();
02172    }
02173    return CLI_SUCCESS;
02174 }

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

Definition at line 2176 of file asterisk.c.

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

02177 {
02178    switch (cmd) {
02179    case CLI_INIT:
02180       e->command = "!";
02181       e->usage =
02182          "Usage: !<command>\n"
02183          "       Executes a given shell command\n";
02184       return NULL;
02185    case CLI_GENERATE:
02186       return NULL;
02187    }
02188 
02189    return CLI_SUCCESS;
02190 }

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

Definition at line 853 of file asterisk.c.

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

00854 {
00855    int i, min, max;
00856    const char *search = NULL;
00857    switch (cmd) {
00858    case CLI_INIT:
00859       e->command = "core clear profile";
00860       e->usage = "Usage: core clear profile\n"
00861             "       clear profile information";
00862       return NULL;
00863    case CLI_GENERATE:
00864       return NULL;
00865    }
00866 
00867    if (prof_data == NULL)
00868       return 0;
00869 
00870    DEFINE_PROFILE_MIN_MAX_VALUES;
00871    for (i= min; i < max; i++) {
00872       if (!search || strstr(prof_data->e[i].name, search)) {
00873          prof_data->e[i].value = 0;
00874          prof_data->e[i].events = 0;
00875       }
00876    }
00877    return CLI_SUCCESS;
00878 }

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

Definition at line 2104 of file asterisk.c.

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

02105 {
02106    switch (cmd) {
02107    case CLI_INIT:
02108       e->command = "core restart gracefully";
02109       e->usage =
02110          "Usage: core restart gracefully\n"
02111          "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
02112          "       restart when all active calls have ended.\n";
02113       return NULL;
02114    case CLI_GENERATE:
02115       return NULL;
02116    }
02117 
02118    if (a->argc != e->args)
02119       return CLI_SHOWUSAGE;
02120    quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
02121    return CLI_SUCCESS;
02122 }

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

Definition at line 2084 of file asterisk.c.

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

02085 {
02086    switch (cmd) {
02087    case CLI_INIT:
02088       e->command = "core restart now";
02089       e->usage =
02090          "Usage: core restart now\n"
02091          "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
02092          "       restart.\n";
02093       return NULL;
02094    case CLI_GENERATE:
02095       return NULL;
02096    }
02097 
02098    if (a->argc != e->args)
02099       return CLI_SHOWUSAGE;
02100    quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
02101    return CLI_SUCCESS;
02102 }

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

Definition at line 2124 of file asterisk.c.

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

02125 {
02126    switch (cmd) {
02127    case CLI_INIT:
02128       e->command = "core restart when convenient";
02129       e->usage =
02130          "Usage: core restart when convenient\n"
02131          "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
02132       return NULL;
02133    case CLI_GENERATE:
02134       return NULL;
02135    }
02136 
02137    if (a->argc != e->args)
02138       return CLI_SHOWUSAGE;
02139    ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
02140    quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
02141    return CLI_SUCCESS;
02142 }

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

Definition at line 818 of file asterisk.c.

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

00819 {
00820    int i, min, max;
00821    const char *search = NULL;
00822    switch (cmd) {
00823    case CLI_INIT:
00824       e->command = "core show profile";
00825       e->usage = "Usage: core show profile\n"
00826             "       show profile information";
00827       return NULL;
00828    case CLI_GENERATE:
00829       return NULL;
00830    }
00831 
00832    if (prof_data == NULL)
00833       return 0;
00834 
00835    DEFINE_PROFILE_MIN_MAX_VALUES;
00836    ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
00837       prof_data->entries, prof_data->max_size);
00838    ast_cli(a->fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
00839          "Value", "Average", "Name");
00840    for (i = min; i < max; i++) {
00841       struct profile_entry *entry = &prof_data->e[i];
00842       if (!search || strstr(entry->name, search))
00843           ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
00844          i,
00845          (long)entry->scale,
00846          (long)entry->events, (long long)entry->value,
00847          (long long)(entry->events ? entry->value / entry->events : entry->value),
00848          entry->name);
00849    }
00850    return CLI_SUCCESS;
00851 }

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

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

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

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

Give an overview of system statistics.

Definition at line 607 of file asterisk.c.

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

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

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

Definition at line 535 of file asterisk.c.

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

00536 {
00537    int count = 0;
00538    struct thread_list_t *cur;
00539    switch (cmd) {
00540    case CLI_INIT:
00541       e->command = "core show threads";
00542       e->usage =
00543          "Usage: core show threads\n"
00544          "       List threads currently active in the system.\n";
00545       return NULL;
00546    case CLI_GENERATE:
00547       return NULL;
00548    }
00549 
00550    AST_RWLIST_RDLOCK(&thread_list);
00551    AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
00552       ast_cli(a->fd, "%p %s\n", (void *)cur->id, cur->name);
00553       count++;
00554    }
00555         AST_RWLIST_UNLOCK(&thread_list);
00556    ast_cli(a->fd, "%d threads listed.\n", count);
00557    return CLI_SUCCESS;
00558 }

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

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

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

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

Definition at line 2044 of file asterisk.c.

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

02045 {
02046    switch (cmd) {
02047    case CLI_INIT:
02048       e->command = "core stop gracefully";
02049       e->usage =
02050          "Usage: core stop gracefully\n"
02051          "       Causes Asterisk to not accept new calls, and exit when all\n"
02052          "       active calls have terminated normally.\n";
02053       return NULL;
02054    case CLI_GENERATE:
02055       return NULL;
02056    }
02057 
02058    if (a->argc != e->args)
02059       return CLI_SHOWUSAGE;
02060    quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
02061    return CLI_SUCCESS;
02062 }

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

Definition at line 2025 of file asterisk.c.

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

02026 {
02027    switch (cmd) {
02028    case CLI_INIT:
02029       e->command = "core stop now";
02030       e->usage =
02031          "Usage: core stop now\n"
02032          "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
02033       return NULL;
02034    case CLI_GENERATE:
02035       return NULL;
02036    }
02037 
02038    if (a->argc != e->args)
02039       return CLI_SHOWUSAGE;
02040    quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
02041    return CLI_SUCCESS;
02042 }

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

Definition at line 2064 of file asterisk.c.

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

02065 {
02066    switch (cmd) {
02067    case CLI_INIT:
02068       e->command = "core stop when convenient";
02069       e->usage =
02070          "Usage: core stop when convenient\n"
02071          "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
02072       return NULL;
02073    case CLI_GENERATE:
02074       return NULL;
02075    }
02076 
02077    if (a->argc != e->args)
02078       return CLI_SHOWUSAGE;
02079    ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
02080    quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
02081    return CLI_SUCCESS;
02082 }

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

Definition at line 1994 of file asterisk.c.

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

01995 {
01996    switch (cmd) {
01997    case CLI_INIT:
01998       e->command = "core show version";
01999       e->usage =
02000          "Usage: core show version\n"
02001          "       Shows Asterisk version information.\n";
02002       return NULL;
02003    case CLI_GENERATE:
02004       return NULL;
02005    }
02006 
02007    if (a->argc != 3)
02008       return CLI_SHOWUSAGE;
02009    ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
02010       ast_get_version(), ast_build_user, ast_build_hostname,
02011       ast_build_machine, ast_build_os, ast_build_date);
02012    return CLI_SUCCESS;
02013 }

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

Definition at line 1397 of file asterisk.c.

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

Referenced by ast_makesocket().

01398 {
01399    struct sockaddr_un sunaddr;
01400    int s;
01401    socklen_t len;
01402    int x;
01403    int flags;
01404    struct pollfd fds[1];
01405    for (;;) {
01406       if (ast_socket < 0)
01407          return NULL;
01408       fds[0].fd = ast_socket;
01409       fds[0].events = POLLIN;
01410       s = ast_poll(fds, 1, -1);
01411       pthread_testcancel();
01412       if (s < 0) {
01413          if (errno != EINTR)
01414             ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
01415          continue;
01416       }
01417       len = sizeof(sunaddr);
01418       s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
01419       if (s < 0) {
01420          if (errno != EINTR)
01421             ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
01422       } else {
01423 #if !defined(SO_PASSCRED)
01424          {
01425 #else
01426          int sckopt = 1;
01427          /* turn on socket credentials passing. */
01428          if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
01429             ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
01430          } else {
01431 #endif
01432             for (x = 0; x < AST_MAX_CONNECTS; x++) {
01433                if (consoles[x].fd >= 0) {
01434                   continue;
01435                }
01436                if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
01437                   ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
01438                   consoles[x].fd = -1;
01439                   fdprint(s, "Server failed to create pipe\n");
01440                   close(s);
01441                   break;
01442                }
01443                flags = fcntl(consoles[x].p[1], F_GETFL);
01444                fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
01445                consoles[x].fd = s;
01446                consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
01447                /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
01448                   to know if the user didn't send the credentials. */
01449                consoles[x].uid = -2;
01450                consoles[x].gid = -2;
01451                if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
01452                   ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
01453                   close(consoles[x].p[0]);
01454                   close(consoles[x].p[1]);
01455                   consoles[x].fd = -1;
01456                   fdprint(s, "Server failed to spawn thread\n");
01457                   close(s);
01458                }
01459                break;
01460             }
01461             if (x >= AST_MAX_CONNECTS) {
01462                fdprint(s, "No more connections allowed\n");
01463                ast_log(LOG_WARNING, "No more connections allowed\n");
01464                close(s);
01465             } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
01466                ast_verb(3, "Remote UNIX connection\n");
01467             }
01468          }
01469       }
01470    }
01471    return NULL;
01472 }

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

< Result from the module load subsystem

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

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

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

static void main_atexit ( void   )  [static]

Definition at line 3523 of file asterisk.c.

References ARRAY_LEN, and ast_cli_unregister_multiple().

Referenced by main().

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

Definition at line 3405 of file asterisk.c.

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

Referenced by main().

03406 {
03407    for (;;) {
03408       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
03409       int a;
03410       ast_poll(&p, 1, -1);
03411       if (sig_flags.need_reload) {
03412          sig_flags.need_reload = 0;
03413          ast_module_reload(NULL);
03414       }
03415       if (sig_flags.need_quit) {
03416          sig_flags.need_quit = 0;
03417          if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
03418             sig_flags.need_quit_handler = 1;
03419             pthread_kill(consolethread, SIGURG);
03420          } else {
03421             quit_handler(0, SHUTDOWN_NORMAL, 0);
03422          }
03423       }
03424       if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
03425       }
03426    }
03427 
03428    return NULL;
03429 }

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

Definition at line 1309 of file asterisk.c.

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

Referenced by listener().

01310 {
01311    struct console *con = vconsole;
01312    char hostname[MAXHOSTNAMELEN] = "";
01313    char inbuf[512];
01314    char outbuf[512];
01315    const char * const end_buf = inbuf + sizeof(inbuf);
01316    char *start_read = inbuf;
01317    int res;
01318    struct pollfd fds[2];
01319 
01320    if (gethostname(hostname, sizeof(hostname)-1))
01321       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
01322    snprintf(outbuf, sizeof(outbuf), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
01323    fdprint(con->fd, outbuf);
01324    for (;;) {
01325       fds[0].fd = con->fd;
01326       fds[0].events = POLLIN;
01327       fds[0].revents = 0;
01328       fds[1].fd = con->p[0];
01329       fds[1].events = POLLIN;
01330       fds[1].revents = 0;
01331 
01332       res = ast_poll(fds, 2, -1);
01333       if (res < 0) {
01334          if (errno != EINTR)
01335             ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
01336          continue;
01337       }
01338       if (fds[0].revents) {
01339          int cmds_read, bytes_read;
01340          if ((bytes_read = read_credentials(con->fd, start_read, end_buf - start_read, con)) < 1) {
01341             break;
01342          }
01343          /* XXX This will only work if it is the first command, and I'm not sure fixing it is worth the effort. */
01344          if (strncmp(inbuf, "cli quit after ", 15) == 0) {
01345             ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read - 15, inbuf + 15);
01346             break;
01347          }
01348          /* ast_cli_command_multiple_full will only process individual commands terminated by a
01349           * NULL and not trailing partial commands. */
01350          if (!(cmds_read = ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read + start_read - inbuf, inbuf))) {
01351             /* No commands were read. We either have a short read on the first command
01352              * with space left, or a command that is too long */
01353             if (start_read + bytes_read < end_buf) {
01354                start_read += bytes_read;
01355             } else {
01356                ast_log(LOG_ERROR, "Command too long! Skipping\n");
01357                start_read = inbuf;
01358             }
01359             continue;
01360          }
01361          if (start_read[bytes_read - 1] == '\0') {
01362             /* The read ended on a command boundary, start reading again at the head of inbuf */
01363             start_read = inbuf;
01364             continue;
01365          }
01366          /* If we get this far, we have left over characters that have not been processed.
01367           * Advance to the character after the last command read by ast_cli_command_multiple_full.
01368           * We are guaranteed to have at least cmds_read NULLs */
01369          while (cmds_read-- && (start_read = strchr(start_read, '\0'))) {
01370             start_read++;
01371          }
01372          memmove(inbuf, start_read, end_buf - start_read);
01373          start_read = end_buf - start_read + inbuf;
01374       }
01375       if (fds[1].revents) {
01376          res = read_credentials(con->p[0], outbuf, sizeof(outbuf), con);
01377          if (res < 1) {
01378             ast_log(LOG_ERROR, "read returned %d\n", res);
01379             break;
01380          }
01381          res = write(con->fd, outbuf, res);
01382          if (res < 1)
01383             break;
01384       }
01385    }
01386    if (!ast_opt_hide_connect) {
01387       ast_verb(3, "Remote UNIX connection disconnected\n");
01388    }
01389    close(con->fd);
01390    close(con->p[0]);
01391    close(con->p[1]);
01392    con->fd = -1;
01393 
01394    return NULL;
01395 }

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

Definition at line 1243 of file asterisk.c.

References __LOG_VERBOSE, and ast_network_puts_mutable().

Referenced by ast_makesocket().

01244 {
01245    ast_network_puts_mutable(s, __LOG_VERBOSE);
01246 }

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

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

03507 {
03508    if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
03509       if (ast_register_verbose(console_verboser)) {
03510          fprintf(stderr, "Unable to register console verboser?\n");
03511          return;
03512       }
03513       WELCOME_MESSAGE;
03514       if (runuser) {
03515          ast_verbose("Running as user '%s'\n", runuser);
03516       }
03517       if (rungroup) {
03518          ast_verbose("Running under group '%s'\n", rungroup);
03519       }
03520    }
03521 }

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

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

01702 {
01703    if (can_safely_quit(niceness, restart)) {
01704       really_quit(num, niceness, restart);
01705       /* No one gets here. */
01706    }
01707    /* It wasn't our time. */
01708 }

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 783 of file asterisk.c.

Referenced by ast_mark().

00784 {
00785    return 0;
00786 }

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

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

Referenced by netconsole().

01261 {
01262 #if defined(SO_PEERCRED)
01263 #ifdef HAVE_STRUCT_SOCKPEERCRED_UID
01264 #define HAVE_STRUCT_UCRED_UID
01265    struct sockpeercred cred;
01266 #else
01267    struct ucred cred;
01268 #endif
01269    socklen_t len = sizeof(cred);
01270 #endif
01271 #if defined(HAVE_GETPEEREID)
01272    uid_t uid;
01273    gid_t gid;
01274 #else
01275    int uid, gid;
01276 #endif
01277    int result;
01278 
01279    result = read(fd, buffer, size);
01280    if (result < 0) {
01281       return result;
01282    }
01283 
01284 #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
01285    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
01286       return result;
01287    }
01288 #if defined(HAVE_STRUCT_UCRED_UID)
01289    uid = cred.uid;
01290    gid = cred.gid;
01291 #else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
01292    uid = cred.cr_uid;
01293    gid = cred.cr_gid;
01294 #endif /* defined(HAVE_STRUCT_UCRED_UID) */
01295 
01296 #elif defined(HAVE_GETPEEREID)
01297    if (getpeereid(fd, &uid, &gid)) {
01298       return result;
01299    }
01300 #else
01301    return result;
01302 #endif
01303    con->uid = uid;
01304    con->gid = gid;
01305 
01306    return result;
01307 }

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

Called when exiting is certain.

Definition at line 1777 of file asterisk.c.

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

Referenced by quit_handler().

01778 {
01779    int active_channels;
01780    int run_cleanups = niceness >= SHUTDOWN_NICE;
01781 
01782    if (run_cleanups) {
01783       ast_module_shutdown();
01784    }
01785 
01786    if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
01787       char filename[80] = "";
01788       if (getenv("HOME")) {
01789          snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
01790       }
01791       if (!ast_strlen_zero(filename)) {
01792          ast_el_write_history(filename);
01793       }
01794       if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
01795          /* Only end if we are the consolethread, otherwise there's a race with that thread. */
01796          if (el != NULL) {
01797             el_end(el);
01798          }
01799          if (el_hist != NULL) {
01800             history_end(el_hist);
01801          }
01802       } else if (mon_sig_flags == pthread_self()) {
01803          if (consolethread != AST_PTHREADT_NULL) {
01804             pthread_kill(consolethread, SIGURG);
01805          }
01806       }
01807    }
01808    active_channels = ast_active_channels();
01809    /* The manager event for shutdown must happen prior to ast_run_atexits, as
01810     * the manager interface will dispose of its sessions as part of its
01811     * shutdown.
01812     */
01813    manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\n"
01814          "Restart: %s\r\n",
01815          active_channels ? "Uncleanly" : "Cleanly",
01816          restart ? "True" : "False");
01817    if (option_verbose && ast_opt_console) {
01818       ast_verbose("Asterisk %s ending (%d).\n",
01819          active_channels ? "uncleanly" : "cleanly", num);
01820    }
01821 
01822    if (option_verbose)
01823       ast_verbose("Executing last minute cleanups\n");
01824    ast_run_atexits(run_cleanups);
01825 
01826    ast_debug(1, "Asterisk ending (%d).\n", num);
01827    if (ast_socket > -1) {
01828       pthread_cancel(lthread);
01829       close(ast_socket);
01830       ast_socket = -1;
01831       unlink(ast_config_AST_SOCKET);
01832       pthread_kill(lthread, SIGURG);
01833       pthread_join(lthread, NULL);
01834    }
01835    if (ast_consock > -1)
01836       close(ast_consock);
01837    if (!ast_opt_remote)
01838       unlink(ast_config_AST_PID);
01839    if (sig_alert_pipe[0])
01840       close(sig_alert_pipe[0]);
01841    if (sig_alert_pipe[1])
01842       close(sig_alert_pipe[1]);
01843    printf("%s", term_quit());
01844    if (restart) {
01845       int i;
01846       if (option_verbose || ast_opt_console)
01847          ast_verbose("Preparing for Asterisk restart...\n");
01848       /* Mark all FD's for closing on exec */
01849       for (i = 3; i < 32768; i++) {
01850          fcntl(i, F_SETFD, FD_CLOEXEC);
01851       }
01852       if (option_verbose || ast_opt_console)
01853          ast_verbose("Asterisk is now restarting...\n");
01854       restartnow = 1;
01855 
01856       /* close logger */
01857       close_logger();
01858       clean_time_zones();
01859 
01860       /* If there is a consolethread running send it a SIGHUP
01861          so it can execvp, otherwise we can do it ourselves */
01862       if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
01863          pthread_kill(consolethread, SIGHUP);
01864          /* Give the signal handler some time to complete */
01865          sleep(2);
01866       } else
01867          execvp(_argv[0], _argv);
01868 
01869    } else {
01870       /* close logger */
01871       close_logger();
01872       clean_time_zones();
01873    }
01874 
01875    exit(0);
01876 }

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

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

00994 {
00995    struct ast_atexit *ae;
00996 
00997    ae = ast_calloc(1, sizeof(*ae));
00998    if (!ae) {
00999       return -1;
01000    }
01001    ae->func = func;
01002    ae->is_cleanup = is_cleanup;
01003 
01004    AST_LIST_LOCK(&atexits);
01005    __ast_unregister_atexit(func);
01006    AST_LIST_INSERT_HEAD(&atexits, ae, list);
01007    AST_LIST_UNLOCK(&atexits);
01008 
01009    return 0;
01010 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1966 of file asterisk.c.

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

Referenced by ast_remotecontrol().

01967 {
01968    int ret = 0;
01969 
01970    /* Called when readline data is available */
01971    if (!ast_all_zeros(s))
01972       ast_el_add_history(s);
01973    /* The real handler for bang */
01974    if (s[0] == '!') {
01975       if (s[1])
01976          ast_safe_system(s+1);
01977       else
01978          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01979       ret = 1;
01980    }
01981    while (isspace(*s)) {
01982       s++;
01983    }
01984 
01985    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
01986        (s[4] == '\0' || isspace(s[4]))) {
01987       quit_handler(0, SHUTDOWN_FAST, 0);
01988       ret = 1;
01989    }
01990 
01991    return ret;
01992 }

static void run_startup_commands ( void   )  [static]

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

03467 {
03468    int fd;
03469    struct ast_config *cfg;
03470    struct ast_flags cfg_flags = { 0 };
03471    struct ast_variable *v;
03472 
03473    if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
03474       return;
03475    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03476       return;
03477    }
03478 
03479    fd = open("/dev/null", O_RDWR);
03480    if (fd < 0) {
03481       ast_config_destroy(cfg);
03482       return;
03483    }
03484 
03485    for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
03486       if (ast_true(v->value))
03487          ast_cli_command(fd, v->name);
03488    }
03489 
03490    close(fd);
03491    ast_config_destroy(cfg);
03492 }

static void set_icon ( char *  text  )  [static]

Definition at line 1656 of file asterisk.c.

Referenced by main().

01657 {
01658    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01659       fprintf(stdout, "\033]1;%s\007", text);
01660 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1650 of file asterisk.c.

Referenced by main().

01651 {
01652    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01653       fprintf(stdout, "\033]2;%s\007", text);
01654 }

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1627 of file asterisk.c.

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

Referenced by ast_readconfig().

01628 {
01629    struct rlimit l = {0, 0};
01630 
01631    if (value <= 0) {
01632       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01633       return;
01634    }
01635 
01636    l.rlim_cur = value;
01637    l.rlim_max = value;
01638 
01639    if (setrlimit(RLIMIT_NOFILE, &l)) {
01640       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01641       return;
01642    }
01643 
01644    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01645 
01646    return;
01647 }

static int show_cli_help ( void   )  [static]

Definition at line 3017 of file asterisk.c.

References ast_get_version().

Referenced by main().

03018 {
03019    printf("Asterisk %s, Copyright (C) 1999 - 2013, Digium, Inc. and others.\n", ast_get_version());
03020    printf("Usage: asterisk [OPTIONS]\n");
03021    printf("Valid Options:\n");
03022    printf("   -V              Display version number and exit\n");
03023    printf("   -C <configfile> Use an alternate configuration file\n");
03024    printf("   -G <group>      Run as a group other than the caller\n");
03025    printf("   -U <user>       Run as a user other than the caller\n");
03026    printf("   -c              Provide console CLI\n");
03027    printf("   -d              Enable extra debugging\n");
03028 #if HAVE_WORKING_FORK
03029    printf("   -f              Do not fork\n");
03030    printf("   -F              Always fork\n");
03031 #endif
03032    printf("   -g              Dump core in case of a crash\n");
03033    printf("   -h              This help screen\n");
03034    printf("   -i              Initialize crypto keys at startup\n");
03035    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
03036    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
03037    printf("   -m              Mute debugging and console output on the console\n");
03038    printf("   -n              Disable console colorization\n");
03039    printf("   -p              Run as pseudo-realtime thread\n");
03040    printf("   -q              Quiet mode (suppress output)\n");
03041    printf("   -r              Connect to Asterisk on this machine\n");
03042    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
03043    printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
03044    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
03045    printf("                   belong after they are done\n");
03046    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
03047    printf("                   of output to the CLI\n");
03048    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
03049    printf("   -x <cmd>        Execute command <cmd> (implies -r)\n");
03050    printf("   -X              Execute includes by default (allows #exec in asterisk.conf)\n");
03051    printf("   -W              Adjust terminal colors to compensate for a light background\n");
03052    printf("\n");
03053    return 0;
03054 }

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

Definition at line 2253 of file asterisk.c.

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

02254 {
02255    switch (cmd) {
02256    case CLI_INIT:
02257       e->command = "core show license";
02258       e->usage =
02259          "Usage: core show license\n"
02260          "       Shows the license(s) for this copy of Asterisk.\n";
02261       return NULL;
02262    case CLI_GENERATE:
02263       return NULL;
02264    }
02265 
02266    ast_cli(a->fd, "%s", license_lines);
02267 
02268    return CLI_SUCCESS;
02269 }

static int show_version ( void   )  [static]

Definition at line 3011 of file asterisk.c.

References ast_get_version().

Referenced by main().

03012 {
03013    printf("Asterisk %s\n", ast_get_version());
03014    return 0;
03015 }

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

Definition at line 2216 of file asterisk.c.

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

02217 {
02218    switch (cmd) {
02219    case CLI_INIT:
02220       e->command = "core show warranty";
02221       e->usage =
02222          "Usage: core show warranty\n"
02223          "       Shows the warranty (if any) for this copy of Asterisk.\n";
02224       return NULL;
02225    case CLI_GENERATE:
02226       return NULL;
02227    }
02228 
02229    ast_cli(a->fd, "%s", warranty_lines);
02230 
02231    return CLI_SUCCESS;
02232 }


Variable Documentation

char* _argv[256] [static]

Definition at line 296 of file asterisk.c.

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

char agimaskvar[PATH_MAX] = ""

Definition at line 201 of file asterisk.c.

Referenced by pbx_extension_helper().

int agimaskvarend = 0

Definition at line 202 of file asterisk.c.

Referenced by ast_readconfig(), handle_verbose(), pbx_extension_helper(), and run_agi().

int agimaskvarini = 0

Definition at line 202 of file asterisk.c.

Referenced by handle_verbose(), pbx_extension_helper(), and run_agi().

int agivar_count = 0 [static]

Definition at line 230 of file asterisk.c.

Referenced by ast_readconfig().

const char* ast_config_AST_AGI_DIR = cfg_paths.agi_dir

Definition at line 278 of file asterisk.c.

Referenced by handle_show_settings(), and launch_script().

const char* ast_config_AST_CONFIG_DIR = cfg_paths.config_dir

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

Referenced by ast_readconfig().

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

Definition at line 291 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

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

Definition at line 290 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static]

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

Definition at line 282 of file asterisk.c.

Referenced by dbinit(), and handle_show_settings().

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

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

const char* ast_config_AST_RUN_DIR = cfg_paths.run_dir

Definition at line 280 of file asterisk.c.

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

const char* ast_config_AST_RUN_GROUP = cfg_paths.run_group

Definition at line 286 of file asterisk.c.

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

const char* ast_config_AST_RUN_USER = cfg_paths.run_user

Definition at line 285 of file asterisk.c.

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

const char* ast_config_AST_SOCKET = cfg_paths.socket_path

Definition at line 284 of file asterisk.c.

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

const char* ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir
const char* ast_config_AST_SYSTEM_NAME = cfg_paths.system_name
const char* ast_config_AST_VAR_DIR = cfg_paths.var_dir

Definition at line 275 of file asterisk.c.

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

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

Definition at line 205 of file asterisk.c.

Global EID.

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

Definition at line 192 of file asterisk.c.

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

unsigned int ast_FD_SETSIZE

Definition at line 86 of file poll.c.

struct timeval ast_lastreloadtime
pid_t ast_mainpid

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

struct timeval ast_startuptime
char canary_filename[128] [static]

Definition at line 311 of file asterisk.c.

Referenced by canary_thread(), and main().

int canary_pid = 0 [static]

Definition at line 310 of file asterisk.c.

Referenced by canary_exit(), and main().

struct _cfg_paths cfg_paths [static]

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

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 2292 of file asterisk.c.

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

struct console consoles[AST_MAX_CONNECTS]
pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 308 of file asterisk.c.

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

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 241 of file asterisk.c.

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

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

struct sigaction ignore_sig_handler [static]
Initial value:
 {
   .sa_handler = SIG_IGN,
}

Definition at line 1051 of file asterisk.c.

Referenced by main().

const char license_lines[] [static]

Definition at line 2234 of file asterisk.c.

pthread_t lthread [static]

Definition at line 1248 of file asterisk.c.

Referenced by ast_makesocket(), and really_quit().

pthread_t mon_sig_flags [static]

Definition at line 309 of file asterisk.c.

Referenced by main(), and really_quit().

int multi_thread_safe [static]

Definition at line 312 of file asterisk.c.

Referenced by ast_register_thread(), and main().

unsigned int need_quit

Definition at line 319 of file asterisk.c.

unsigned int need_quit_handler

Definition at line 320 of file asterisk.c.

unsigned int need_reload

Definition at line 318 of file asterisk.c.

struct sigaction null_sig_handler [static]
Initial value:
 {
   .sa_handler = _null_sig_handler,
   .sa_flags = SA_RESTART,
}

Definition at line 1046 of file asterisk.c.

Referenced by ast_replace_sigchld().

struct profile_data* prof_data [static]
struct ast_str* prompt = NULL [static]

Definition at line 2409 of file asterisk.c.

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

char randompool[256] [static]

Definition at line 314 of file asterisk.c.

Referenced by main().

char readmaskvar[PATH_MAX] = ""

Definition at line 199 of file asterisk.c.

int readmaskvarend = 0

Definition at line 200 of file asterisk.c.

Referenced by AST_LIST_HEAD(), and ast_readconfig().

int readmaskvarini = 0

Definition at line 200 of file asterisk.c.

Referenced by AST_LIST_HEAD().

int readvar_count = 0 [static]

Definition at line 228 of file asterisk.c.

Referenced by ast_readconfig().

char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR

Definition at line 195 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 237 of file asterisk.c.

Referenced by ast_remotecontrol(), and cli_prompt().

int restartnow [static]

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

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

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

Definition at line 1059 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

char setmaskvar[PATH_MAX] = ""

Definition at line 197 of file asterisk.c.

Referenced by pbx_extension_helper().

int setmaskvarend = 0

Definition at line 198 of file asterisk.c.

Referenced by ast_readconfig(), and pbx_extension_helper().

int setmaskvarini = 0

Definition at line 198 of file asterisk.c.

Referenced by pbx_extension_helper().

int setvar_count = 0 [static]

Definition at line 226 of file asterisk.c.

Referenced by ast_readconfig().

shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN [static]

Definition at line 306 of file asterisk.c.

Referenced by can_safely_quit(), and handle_abort_shutdown().

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

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

const char warranty_lines[] [static]

Definition at line 2191 of file asterisk.c.


Generated on 7 Sep 2017 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1