Fri Apr 15 20:38:47 2016

Asterisk developer's documentation


asterisk.c File Reference

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

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

Go to the source code of this file.

Data Structures

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

Defines

#define 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]
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 record_cache_dir [AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR
static char * remotehostname
static int restartnow
static unsigned int safe_system_level = 0
 Keep track of how many threads are currently trying to wait*() on a child process.
static ast_mutex_t safe_system_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static struct sigaction safe_system_prev_handler
static shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN
static int sig_alert_pipe [2] = { -1, -1 }
struct {
   unsigned int   need_quit:1
   unsigned int   need_quit_handler:1
   unsigned int   need_reload:1
sig_flags
static struct sigaction urg_handler
static const char warranty_lines []

Detailed Description

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

Definition in file asterisk.c.


Define Documentation

#define AST_MAX_CONNECTS   128
#define ASTERISK_PROMPT   "*CLI> "

Definition at line 2254 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 2256 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

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

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

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


Function Documentation

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

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

00963 {
00964    struct ast_atexit *ae;
00965 
00966    AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
00967       if (ae->func == func) {
00968          AST_LIST_REMOVE_CURRENT(list);
00969          ast_free(ae);
00970          break;
00971       }
00972    }
00973    AST_LIST_TRAVERSE_SAFE_END;
00974 }

static void __quit_handler ( int  num  )  [static]

Definition at line 1861 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

01862 {
01863    int a = 0;
01864    sig_flags.need_quit = 1;
01865    if (sig_alert_pipe[1] != -1) {
01866       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01867          fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
01868       }
01869    }
01870    /* There is no need to restore the signal handler here, since the app
01871     * is going to exit */
01872 }

static void __remote_quit_handler ( int  num  )  [static]

Definition at line 1874 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

01875 {
01876    sig_flags.need_quit = 1;
01877 }

static void _child_handler ( int  sig  )  [static]

Definition at line 1589 of file asterisk.c.

References errno, and status.

01590 {
01591    /* Must not ever ast_log or ast_verbose within signal handler */
01592    int n, status, save_errno = errno;
01593 
01594    /*
01595     * Reap all dead children -- not just one
01596     */
01597    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01598       ;
01599    if (n == 0 && option_debug)
01600       printf("Huh?  Child handler, but nobody there?\n");
01601    errno = save_errno;
01602 }

static void _hup_handler ( int  num  )  [static]

Definition at line 1568 of file asterisk.c.

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

01569 {
01570    int a = 0, save_errno = errno;
01571    if (option_verbose > 1)
01572       printf("Received HUP signal -- Reloading configs\n");
01573    if (restartnow)
01574       execvp(_argv[0], _argv);
01575    sig_flags.need_reload = 1;
01576    if (sig_alert_pipe[1] != -1) {
01577       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01578          fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
01579       }
01580    }
01581    errno = save_errno;
01582 }

static void _null_sig_handler ( int  sig  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 1025 of file asterisk.c.

01026 {
01027 }

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

01559 {
01560    return;
01561 }

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

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

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1921 of file asterisk.c.

Referenced by consolehandler(), and remoteconsolehandler().

01922 {
01923    while (*s) {
01924       if (*s > 32)
01925          return 0;
01926       s++;
01927    }
01928    return 1;
01929 }

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

Definition at line 2591 of file asterisk.c.

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

Referenced by cli_complete().

02592 {
02593    int i, idx, limit, count;
02594    int screenwidth = 0;
02595    int numoutput = 0, numoutputline = 0;
02596 
02597    screenwidth = ast_get_termcols(STDOUT_FILENO);
02598 
02599    /* find out how many entries can be put on one line, with two spaces between strings */
02600    limit = screenwidth / (max + 2);
02601    if (limit == 0)
02602       limit = 1;
02603 
02604    /* how many lines of output */
02605    count = len / limit;
02606    if (count * limit < len)
02607       count++;
02608 
02609    idx = 1;
02610 
02611    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
02612 
02613    for (; count > 0; count--) {
02614       numoutputline = 0;
02615       for (i = 0; i < limit && matches[idx]; i++, idx++) {
02616 
02617          /* Don't print dupes */
02618          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
02619             i--;
02620             ast_free(matches[idx]);
02621             matches[idx] = NULL;
02622             continue;
02623          }
02624 
02625          numoutput++;
02626          numoutputline++;
02627          fprintf(stdout, "%-*s  ", max, matches[idx]);
02628          ast_free(matches[idx]);
02629          matches[idx] = NULL;
02630       }
02631       if (numoutputline > 0)
02632          fprintf(stdout, "\n");
02633    }
02634 
02635    return numoutput;
02636 }

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

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

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

void ast_console_puts ( const char *  string  ) 

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

Definition at line 1219 of file asterisk.c.

References ast_network_puts().

01220 {
01221    fputs(string, stdout);
01222    fflush(stdout);
01223    ast_network_puts(string);
01224 }

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

References ast_network_puts_mutable().

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

01197 {
01198    fputs(string, stdout);
01199    fflush(stdout);
01200    ast_network_puts_mutable(string, level);
01201 }

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

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

Referenced by handle_logger_set_level().

01134 {
01135    int x;
01136 
01137    if (level >= NUMLOGLEVELS) {
01138       level = NUMLOGLEVELS - 1;
01139    }
01140 
01141    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01142       if (fd == consoles[x].fd) {
01143          /*
01144           * Since the logging occurs when levels are false, set to
01145           * flipped iinput because this function accepts 0 as off and 1 as on
01146           */
01147          consoles[x].levels[level] = state ? 0 : 1;
01148          return;
01149       }
01150    }
01151 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1156 of file asterisk.c.

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

Referenced by handle_logger_mute().

01157 {
01158    int x;
01159    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01160       if (fd == consoles[x].fd) {
01161          if (consoles[x].mute) {
01162             consoles[x].mute = 0;
01163             if (!silent)
01164                ast_cli(fd, "Console is not muted anymore.\n");
01165          } else {
01166             consoles[x].mute = 1;
01167             if (!silent)
01168                ast_cli(fd, "Console is muted.\n");
01169          }
01170          return;
01171       }
01172    }
01173    ast_cli(fd, "Couldn't find remote console.\n");
01174 }

static int ast_el_add_history ( char *  buf  )  [static]

Definition at line 2801 of file asterisk.c.

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

Referenced by consolehandler(), and remoteconsolehandler().

02802 {
02803    HistEvent ev;
02804 
02805    if (el_hist == NULL || el == NULL)
02806       ast_el_initialize();
02807    if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1))
02808       return 0;
02809    return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf))));
02810 }

static int ast_el_initialize ( void   )  [static]

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

02765 {
02766    HistEvent ev;
02767    char *editor = getenv("AST_EDITOR");
02768 
02769    if (el != NULL)
02770       el_end(el);
02771    if (el_hist != NULL)
02772       history_end(el_hist);
02773 
02774    el = el_init("asterisk", stdin, stdout, stderr);
02775    el_set(el, EL_PROMPT, cli_prompt);
02776 
02777    el_set(el, EL_EDITMODE, 1);
02778    el_set(el, EL_EDITOR, editor ? editor : "emacs");
02779    el_hist = history_init();
02780    if (!el || !el_hist)
02781       return -1;
02782 
02783    /* setup history with 100 entries */
02784    history(el_hist, &ev, H_SETSIZE, 100);
02785 
02786    el_set(el, EL_HIST, history, el_hist);
02787 
02788    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02789    /* Bind <tab> to command completion */
02790    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02791    /* Bind ? to command completion */
02792    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02793    /* Bind ^D to redisplay */
02794    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02795 
02796    return 0;
02797 }

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

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

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

static int ast_el_read_history ( char *  filename  )  [static]

Definition at line 2822 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by ast_remotecontrol(), and main().

02823 {
02824    HistEvent ev;
02825 
02826    if (el_hist == NULL || el == NULL)
02827       ast_el_initialize();
02828 
02829    return (history(el_hist, &ev, H_LOAD, filename));
02830 }

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

Definition at line 2581 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02582 {
02583    char *s1, *s2;
02584 
02585    s1 = ((char **)i1)[0];
02586    s2 = ((char **)i2)[0];
02587 
02588    return strcasecmp(s1, s2);
02589 }

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

Definition at line 2533 of file asterisk.c.

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

Referenced by cli_complete().

02534 {
02535    char *retstr;
02536    char **match_list = NULL;
02537    char **new_list;
02538    size_t match_list_len = 1;
02539    int matches = 0;
02540 
02541    while ((retstr = strsep(&buf, " "))) {
02542       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
02543          break;
02544       }
02545       if (matches + 1 >= match_list_len) {
02546          match_list_len <<= 1;
02547          new_list = ast_realloc(match_list, match_list_len * sizeof(char *));
02548          if (!new_list) {
02549             destroy_match_list(match_list, matches);
02550             return NULL;
02551          }
02552          match_list = new_list;
02553       }
02554 
02555       retstr = ast_strdup(retstr);
02556       if (!retstr) {
02557          destroy_match_list(match_list, matches);
02558          return NULL;
02559       }
02560       match_list[matches++] = retstr;
02561    }
02562 
02563    if (!match_list) {
02564       return NULL;
02565    }
02566 
02567    if (matches >= match_list_len) {
02568       new_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *));
02569       if (!new_list) {
02570          destroy_match_list(match_list, matches);
02571          return NULL;
02572       }
02573       match_list = new_list;
02574    }
02575 
02576    match_list[matches] = NULL;
02577 
02578    return match_list;
02579 }

static int ast_el_write_history ( char *  filename  )  [static]

Definition at line 2812 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by really_quit().

02813 {
02814    HistEvent ev;
02815 
02816    if (el_hist == NULL || el == NULL)
02817       ast_el_initialize();
02818 
02819    return (history(el_hist, &ev, H_SAVE, filename));
02820 }

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

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

static int ast_makesocket ( void   )  [static]

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

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

int64_t ast_mark ( int  i,
int  startstop 
)

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

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

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

write the string to all attached console clients

Definition at line 1206 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

01207 {
01208    int x;
01209    for (x = 0; x < AST_MAX_CONNECTS; x++) {
01210       if (consoles[x].fd > -1)
01211          fdprint(consoles[x].p[1], string);
01212    }
01213 }

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

log the string to all attached console clients

Definition at line 1179 of file asterisk.c.

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

Referenced by ast_console_puts_mutable(), and network_verboser().

01180 {
01181    int x;
01182    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01183       if (consoles[x].mute)
01184          continue;
01185       if (consoles[x].fd > -1) {
01186          if (!consoles[x].levels[level])
01187             fdprint(consoles[x].p[1], string);
01188       }
01189    }
01190 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 737 of file asterisk.c.

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

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

static void ast_readconfig ( void   )  [static]

Definition at line 3022 of file asterisk.c.

References _cfg_paths::agi_dir, 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_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_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, live_dangerously, _cfg_paths::log_dir, LOG_ERROR, LOG_WARNING, MAX_LANGUAGE, MAXHOSTNAMELEN, _cfg_paths::module_dir, _cfg_paths::monitor_dir, ast_variable::name, ast_variable::next, pbx_live_dangerously(), _cfg_paths::pid_path, _cfg_paths::run_dir, _cfg_paths::run_group, _cfg_paths::run_user, set_ulimit(), _cfg_paths::socket_path, _cfg_paths::spool_dir, _cfg_paths::system_name, ast_variable::value, _cfg_paths::var_dir, and version.

Referenced by main().

03023 {
03024    struct ast_config *cfg;
03025    struct ast_variable *v;
03026    char *config = DEFAULT_CONFIG_FILE;
03027    char hostname[MAXHOSTNAMELEN] = "";
03028    struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME };
03029    struct {
03030       unsigned int dbdir:1;
03031       unsigned int keydir:1;
03032    } found = { 0, 0 };
03033    /* Default to true for backward compatibility */
03034    int live_dangerously = 1;
03035 
03036    if (ast_opt_override_config) {
03037       cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
03038       if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03039          fprintf(stderr, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
03040       }
03041    } else {
03042       cfg = ast_config_load2(config, "" /* core, can't reload */, config_flags);
03043    }
03044 
03045    /* init with buildtime config */
03046    ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir));
03047    ast_copy_string(cfg_paths.spool_dir, DEFAULT_SPOOL_DIR, sizeof(cfg_paths.spool_dir));
03048    ast_copy_string(cfg_paths.module_dir, DEFAULT_MODULE_DIR, sizeof(cfg_paths.module_dir));
03049    snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", cfg_paths.spool_dir);
03050    ast_copy_string(cfg_paths.var_dir, DEFAULT_VAR_DIR, sizeof(cfg_paths.var_dir));
03051    ast_copy_string(cfg_paths.data_dir, DEFAULT_DATA_DIR, sizeof(cfg_paths.data_dir));
03052    ast_copy_string(cfg_paths.log_dir, DEFAULT_LOG_DIR, sizeof(cfg_paths.log_dir));
03053    ast_copy_string(cfg_paths.agi_dir, DEFAULT_AGI_DIR, sizeof(cfg_paths.agi_dir));
03054    ast_copy_string(cfg_paths.db_path, DEFAULT_DB, sizeof(cfg_paths.db_path));
03055    ast_copy_string(cfg_paths.key_dir, DEFAULT_KEY_DIR, sizeof(cfg_paths.key_dir));
03056    ast_copy_string(cfg_paths.pid_path, DEFAULT_PID, sizeof(cfg_paths.pid_path));
03057    ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path));
03058    ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir));
03059 
03060    ast_set_default_eid(&ast_eid_default);
03061 
03062    /* no asterisk.conf? no problem, use buildtime config! */
03063    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03064       return;
03065    }
03066 
03067    for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
03068       if (!strcasecmp(v->name, "astctlpermissions"))
03069          ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
03070       else if (!strcasecmp(v->name, "astctlowner"))
03071          ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
03072       else if (!strcasecmp(v->name, "astctlgroup"))
03073          ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
03074       else if (!strcasecmp(v->name, "astctl"))
03075          ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
03076    }
03077 
03078    for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
03079       if (!strcasecmp(v->name, "astetcdir")) {
03080          ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir));
03081       } else if (!strcasecmp(v->name, "astspooldir")) {
03082          ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir));
03083          snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value);
03084       } else if (!strcasecmp(v->name, "astvarlibdir")) {
03085          ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir));
03086          if (!found.dbdir)
03087             snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
03088       } else if (!strcasecmp(v->name, "astdbdir")) {
03089          snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
03090          found.dbdir = 1;
03091       } else if (!strcasecmp(v->name, "astdatadir")) {
03092          ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir));
03093          if (!found.keydir)
03094             snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
03095       } else if (!strcasecmp(v->name, "astkeydir")) {
03096          snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
03097          found.keydir = 1;
03098       } else if (!strcasecmp(v->name, "astlogdir")) {
03099          ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir));
03100       } else if (!strcasecmp(v->name, "astagidir")) {
03101          ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir));
03102       } else if (!strcasecmp(v->name, "astrundir")) {
03103          snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid");
03104          snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", v->value, ast_config_AST_CTL);
03105          ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir));
03106       } else if (!strcasecmp(v->name, "astmoddir")) {
03107          ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir));
03108       }
03109    }
03110 
03111    for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
03112       /* verbose level (-v at startup) */
03113       if (!strcasecmp(v->name, "verbose")) {
03114          option_verbose = atoi(v->value);
03115       /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
03116       } else if (!strcasecmp(v->name, "timestamp")) {
03117          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
03118       /* whether or not to support #exec in config files */
03119       } else if (!strcasecmp(v->name, "execincludes")) {
03120          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
03121       /* debug level (-d at startup) */
03122       } else if (!strcasecmp(v->name, "debug")) {
03123          option_debug = 0;
03124          if (sscanf(v->value, "%30d", &option_debug) != 1) {
03125             option_debug = ast_true(v->value);
03126          }
03127 #if HAVE_WORKING_FORK
03128       /* Disable forking (-f at startup) */
03129       } else if (!strcasecmp(v->name, "nofork")) {
03130          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
03131       /* Always fork, even if verbose or debug are enabled (-F at startup) */
03132       } else if (!strcasecmp(v->name, "alwaysfork")) {
03133          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
03134 #endif
03135       /* Run quietly (-q at startup ) */
03136       } else if (!strcasecmp(v->name, "quiet")) {
03137          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
03138       /* Run as console (-c at startup, implies nofork) */
03139       } else if (!strcasecmp(v->name, "console")) {
03140          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
03141       /* Run with high priority if the O/S permits (-p at startup) */
03142       } else if (!strcasecmp(v->name, "highpriority")) {
03143          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
03144       /* Initialize RSA auth keys (IAX2) (-i at startup) */
03145       } else if (!strcasecmp(v->name, "initcrypto")) {
03146          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
03147       /* Disable ANSI colors for console (-c at startup) */
03148       } else if (!strcasecmp(v->name, "nocolor")) {
03149          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
03150       /* Disable some usage warnings for picky people :p */
03151       } else if (!strcasecmp(v->name, "dontwarn")) {
03152          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
03153       /* Dump core in case of crash (-g) */
03154       } else if (!strcasecmp(v->name, "dumpcore")) {
03155          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
03156       /* Cache recorded sound files to another directory during recording */
03157       } else if (!strcasecmp(v->name, "cache_record_files")) {
03158          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
03159       /* Specify cache directory */
03160       }  else if (!strcasecmp(v->name, "record_cache_dir")) {
03161          ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
03162       /* Build transcode paths via SLINEAR, instead of directly */
03163       } else if (!strcasecmp(v->name, "transcode_via_sln")) {
03164          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
03165       /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
03166       } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
03167          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
03168       /* Enable internal timing */
03169       } else if (!strcasecmp(v->name, "internal_timing")) {
03170          if (!ast_opt_remote) {
03171             fprintf(stderr,
03172                "NOTICE: The internal_timing option is no longer needed.\n"
03173                "  It will always be enabled if you have a timing module loaded.\n");
03174          }
03175       } else if (!strcasecmp(v->name, "maxcalls")) {
03176          if ((sscanf(v->value, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
03177             option_maxcalls = 0;
03178          }
03179       } else if (!strcasecmp(v->name, "maxload")) {
03180          double test[1];
03181 
03182          if (getloadavg(test, 1) == -1) {
03183             ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
03184             option_maxload = 0.0;
03185          } else if ((sscanf(v->value, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
03186             option_maxload = 0.0;
03187          }
03188       /* Set the maximum amount of open files */
03189       } else if (!strcasecmp(v->name, "maxfiles")) {
03190          option_maxfiles = atoi(v->value);
03191          set_ulimit(option_maxfiles);
03192       /* What user to run as */
03193       } else if (!strcasecmp(v->name, "runuser")) {
03194          ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user));
03195       /* What group to run as */
03196       } else if (!strcasecmp(v->name, "rungroup")) {
03197          ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group));
03198       } else if (!strcasecmp(v->name, "systemname")) {
03199          ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name));
03200       } else if (!strcasecmp(v->name, "autosystemname")) {
03201          if (ast_true(v->value)) {
03202             if (!gethostname(hostname, sizeof(hostname) - 1))
03203                ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name));
03204             else {
03205                if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){
03206                   ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name));
03207                }
03208                ast_log(LOG_ERROR, "Cannot obtain hostname for this system.  Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME);
03209             }
03210          }
03211       } else if (!strcasecmp(v->name, "languageprefix")) {
03212          ast_language_is_prefix = ast_true(v->value);
03213       } else if (!strcasecmp(v->name, "defaultlanguage")) {
03214          ast_copy_string(defaultlanguage, v->value, MAX_LANGUAGE);
03215       } else if (!strcasecmp(v->name, "lockmode")) {
03216          if (!strcasecmp(v->value, "lockfile")) {
03217             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03218          } else if (!strcasecmp(v->value, "flock")) {
03219             ast_set_lock_type(AST_LOCK_TYPE_FLOCK);
03220          } else {
03221             ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, "
03222                "defaulting to 'lockfile'\n", v->value);
03223             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03224          }
03225 #if defined(HAVE_SYSINFO)
03226       } else if (!strcasecmp(v->name, "minmemfree")) {
03227          /* specify the minimum amount of free memory to retain.  Asterisk should stop accepting new calls
03228           * if the amount of free memory falls below this watermark */
03229          if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
03230             option_minmemfree = 0;
03231          }
03232 #endif
03233       } else if (!strcasecmp(v->name, "entityid")) {
03234          struct ast_eid tmp_eid;
03235          if (!ast_str_to_eid(&tmp_eid, v->value)) {
03236             ast_verbose("Successfully set global EID to '%s'\n", v->value);
03237             ast_eid_default = tmp_eid;
03238          } else
03239             ast_verbose("Invalid Entity ID '%s' provided\n", v->value);
03240       } else if (!strcasecmp(v->name, "lightbackground")) {
03241          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND);
03242       } else if (!strcasecmp(v->name, "forceblackbackground")) {
03243          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03244       } else if (!strcasecmp(v->name, "hideconnect")) {
03245          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT);
03246       } else if (!strcasecmp(v->name, "lockconfdir")) {
03247          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LOCK_CONFIG_DIR);
03248       } else if (!strcasecmp(v->name, "live_dangerously")) {
03249          live_dangerously = ast_true(v->value);
03250       }
03251    }
03252    if (!ast_opt_remote) {
03253       pbx_live_dangerously(live_dangerously);
03254    }
03255    for (v = ast_variable_browse(cfg, "compat"); v; v = v->next) {
03256       float version;
03257       if (sscanf(v->value, "%30f", &version) != 1) {
03258          fprintf(stderr, "Compatibility version for option '%s' is not a number: '%s'\n", v->name, v->value);
03259          continue;
03260       }
03261       if (!strcasecmp(v->name, "app_set")) {
03262          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_APP_SET);
03263       } else if (!strcasecmp(v->name, "res_agi")) {
03264          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_RES_AGI);
03265       } else if (!strcasecmp(v->name, "pbx_realtime")) {
03266          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_PBX_REALTIME);
03267       }
03268    }
03269    ast_config_destroy(cfg);
03270 }

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

References ast_atexit::func, and register_atexit().

Referenced by ast_autoservice_init().

01001 {
01002    return register_atexit(func, 1);
01003 }

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

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

void ast_register_thread ( char *  name  ) 

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

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

static void ast_remotecontrol ( char *  data  )  [static]

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

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

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

01045 {
01046    unsigned int level;
01047 
01048    ast_mutex_lock(&safe_system_lock);
01049    level = safe_system_level++;
01050 
01051    /* only replace the handler if it has not already been done */
01052    if (level == 0) {
01053       sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
01054    }
01055 
01056    ast_mutex_unlock(&safe_system_lock);
01057 }

static void ast_run_atexits ( int  run_cleanups  )  [static]

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

00949 {
00950    struct ast_atexit *ae;
00951 
00952    AST_LIST_LOCK(&atexits);
00953    while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
00954       if (ae->func && (!ae->is_cleanup || run_cleanups)) {
00955          ae->func();
00956       }
00957       ast_free(ae);
00958    }
00959    AST_LIST_UNLOCK(&atexits);
00960 }

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

01075 {
01076    pid_t pid;
01077    int res;
01078    struct rusage rusage;
01079    int status;
01080 
01081 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
01082    ast_replace_sigchld();
01083 
01084 #ifdef HAVE_WORKING_FORK
01085    pid = fork();
01086 #else
01087    pid = vfork();
01088 #endif
01089 
01090    if (pid == 0) {
01091 #ifdef HAVE_CAP
01092       cap_t cap = cap_from_text("cap_net_admin-eip");
01093 
01094       if (cap_set_proc(cap)) {
01095          /* Careful with order! Logging cannot happen after we close FDs */
01096          ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
01097       }
01098       cap_free(cap);
01099 #endif
01100 #ifdef HAVE_WORKING_FORK
01101       if (ast_opt_high_priority)
01102          ast_set_priority(0);
01103       /* Close file descriptors and launch system command */
01104       ast_close_fds_above_n(STDERR_FILENO);
01105 #endif
01106       execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
01107       _exit(1);
01108    } else if (pid > 0) {
01109       for (;;) {
01110          res = wait4(pid, &status, 0, &rusage);
01111          if (res > -1) {
01112             res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
01113             break;
01114          } else if (errno != EINTR)
01115             break;
01116       }
01117    } else {
01118       ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
01119       res = -1;
01120    }
01121 
01122    ast_unreplace_sigchld();
01123 #else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */
01124    res = -1;
01125 #endif
01126 
01127    return res;
01128 }

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

01648 {
01649    struct sched_param sched;
01650    memset(&sched, 0, sizeof(sched));
01651 #ifdef __linux__
01652    if (pri) {
01653       sched.sched_priority = 10;
01654       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01655          ast_log(LOG_WARNING, "Unable to set high priority\n");
01656          return -1;
01657       } else
01658          if (option_verbose)
01659             ast_verbose("Set to realtime thread\n");
01660    } else {
01661       sched.sched_priority = 0;
01662       /* According to the manpage, these parameters can never fail. */
01663       sched_setscheduler(0, SCHED_OTHER, &sched);
01664    }
01665 #else
01666    if (pri) {
01667       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01668          ast_log(LOG_WARNING, "Unable to set high priority\n");
01669          return -1;
01670       } else
01671          if (option_verbose)
01672             ast_verbose("Set to high priority\n");
01673    } else {
01674       /* According to the manpage, these parameters can never fail. */
01675       setpriority(PRIO_PROCESS, 0, 0);
01676    }
01677 #endif
01678    return 0;
01679 }

static int ast_tryconnect ( void   )  [static]

Definition at line 1531 of file asterisk.c.

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

Referenced by ast_el_read_char(), and main().

01532 {
01533    struct sockaddr_un sunaddr;
01534    int res;
01535    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01536    if (ast_consock < 0) {
01537       fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
01538       return 0;
01539    }
01540    memset(&sunaddr, 0, sizeof(sunaddr));
01541    sunaddr.sun_family = AF_LOCAL;
01542    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01543    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01544    if (res) {
01545       close(ast_consock);
01546       ast_consock = -1;
01547       return 0;
01548    } else
01549       return 1;
01550 }

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

01006 {
01007    AST_LIST_LOCK(&atexits);
01008    __ast_unregister_atexit(func);
01009    AST_LIST_UNLOCK(&atexits);
01010 }

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

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

void ast_unregister_thread ( void *  id  ) 

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

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

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

01060 {
01061    unsigned int level;
01062 
01063    ast_mutex_lock(&safe_system_lock);
01064    level = --safe_system_level;
01065 
01066    /* only restore the handler if we are the last one */
01067    if (level == 0) {
01068       sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
01069    }
01070 
01071    ast_mutex_unlock(&safe_system_lock);
01072 }

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

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

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

static void canary_exit ( void   )  [static]

Definition at line 3327 of file asterisk.c.

References canary_pid.

Referenced by main().

03328 {
03329    if (canary_pid > 0)
03330       kill(canary_pid, SIGKILL);
03331 }

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

Definition at line 3298 of file asterisk.c.

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

Referenced by main().

03299 {
03300    struct stat canary_stat;
03301    struct timeval now;
03302 
03303    /* Give the canary time to sing */
03304    sleep(120);
03305 
03306    for (;;) {
03307       now = ast_tvnow();
03308       if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
03309          ast_log(LOG_WARNING,
03310             "The canary is no more.  He has ceased to be!  "
03311             "He's expired and gone to meet his maker!  "
03312             "He's a stiff!  Bereft of life, he rests in peace.  "
03313             "His metabolic processes are now history!  He's off the twig!  "
03314             "He's kicked the bucket.  He's shuffled off his mortal coil, "
03315             "run down the curtain, and joined the bleeding choir invisible!!  "
03316             "THIS is an EX-CANARY.  (Reducing priority)\n");
03317          ast_set_priority(0);
03318          pthread_exit(NULL);
03319       }
03320 
03321       /* Check the canary once a minute */
03322       sleep(60);
03323    }
03324 }

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

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

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

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

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

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

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

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

01897 {
01898    char tmp[80];
01899    const char *c = NULL;
01900 
01901    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01902        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01903        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01904        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
01905       fputs(tmp, stdout);
01906       fputs(c, stdout);
01907    } else {
01908       if (*s == 127) {
01909          s++;
01910       }
01911       fputs(s, stdout);
01912    }
01913 
01914    fflush(stdout);
01915 
01916    /* Wake up a poll()ing console */
01917    if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
01918       pthread_kill(consolethread, SIGURG);
01919 }

static void consolehandler ( char *  s  )  [static]

Definition at line 1931 of file asterisk.c.

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

Referenced by main().

01932 {
01933    printf("%s", term_end());
01934    fflush(stdout);
01935 
01936    /* Called when readline data is available */
01937    if (!ast_all_zeros(s))
01938       ast_el_add_history(s);
01939    /* The real handler for bang */
01940    if (s[0] == '!') {
01941       if (s[1])
01942          ast_safe_system(s+1);
01943       else
01944          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01945    } else
01946       ast_cli_command(STDOUT_FILENO, s);
01947 }

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

Definition at line 2521 of file asterisk.c.

References ast_free.

Referenced by ast_el_strtoarr().

02522 {
02523    if (match_list) {
02524       int idx;
02525 
02526       for (idx = 0; idx < matches; ++idx) {
02527          ast_free(match_list[idx]);
02528       }
02529       ast_free(match_list);
02530    }
02531 }

static void env_init ( void   )  [static]

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

03362 {
03363    setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
03364    setenv("AST_BUILD_HOST", ast_build_hostname, 1);
03365    setenv("AST_BUILD_DATE", ast_build_date, 1);
03366    setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
03367    setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
03368    setenv("AST_BUILD_OS", ast_build_os, 1);
03369    setenv("AST_BUILD_USER", ast_build_user, 1);
03370    setenv("AST_VERSION", ast_get_version(), 1);
03371 }

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

Definition at line 1019 of file asterisk.c.

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

01020 {
01021    return write(fd, s, strlen(s));
01022 }

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

Definition at line 1013 of file asterisk.c.

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

01014 {
01015    return write(fd, s, strlen(s) + 1);
01016 }

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

Definition at line 1879 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01880 {
01881    const char *c;
01882 
01883    /* Check for verboser preamble */
01884    if (*s == 127) {
01885       s++;
01886    }
01887 
01888    if (!strncmp(s, cmp, strlen(cmp))) {
01889       c = s + strlen(cmp);
01890       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01891       return c;
01892    }
01893    return NULL;
01894 }

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

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

02128 {
02129    int aborting_shutdown = 0;
02130 
02131    switch (cmd) {
02132    case CLI_INIT:
02133       e->command = "core abort shutdown";
02134       e->usage =
02135          "Usage: core abort shutdown\n"
02136          "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
02137          "       call operations.\n";
02138       return NULL;
02139    case CLI_GENERATE:
02140       return NULL;
02141    }
02142 
02143    if (a->argc != e->args)
02144       return CLI_SHOWUSAGE;
02145 
02146    ast_mutex_lock(&safe_system_lock);
02147    if (shuttingdown >= SHUTDOWN_FAST) {
02148       aborting_shutdown = 1;
02149       shuttingdown = NOT_SHUTTING_DOWN;
02150    }
02151    ast_mutex_unlock(&safe_system_lock);
02152 
02153    if (aborting_shutdown) {
02154       ast_cancel_shutdown();
02155    }
02156    return CLI_SUCCESS;
02157 }

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

Definition at line 2159 of file asterisk.c.

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

02160 {
02161    switch (cmd) {
02162    case CLI_INIT:
02163       e->command = "!";
02164       e->usage =
02165          "Usage: !<command>\n"
02166          "       Executes a given shell command\n";
02167       return NULL;
02168    case CLI_GENERATE:
02169       return NULL;
02170    }
02171 
02172    return CLI_SUCCESS;
02173 }

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

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

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

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

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

02088 {
02089    switch (cmd) {
02090    case CLI_INIT:
02091       e->command = "core restart gracefully";
02092       e->usage =
02093          "Usage: core restart gracefully\n"
02094          "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
02095          "       restart when all active calls have ended.\n";
02096       return NULL;
02097    case CLI_GENERATE:
02098       return NULL;
02099    }
02100 
02101    if (a->argc != e->args)
02102       return CLI_SHOWUSAGE;
02103    quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
02104    return CLI_SUCCESS;
02105 }

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

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

02068 {
02069    switch (cmd) {
02070    case CLI_INIT:
02071       e->command = "core restart now";
02072       e->usage =
02073          "Usage: core restart now\n"
02074          "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
02075          "       restart.\n";
02076       return NULL;
02077    case CLI_GENERATE:
02078       return NULL;
02079    }
02080 
02081    if (a->argc != e->args)
02082       return CLI_SHOWUSAGE;
02083    quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
02084    return CLI_SUCCESS;
02085 }

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

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

02108 {
02109    switch (cmd) {
02110    case CLI_INIT:
02111       e->command = "core restart when convenient";
02112       e->usage =
02113          "Usage: core restart when convenient\n"
02114          "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
02115       return NULL;
02116    case CLI_GENERATE:
02117       return NULL;
02118    }
02119 
02120    if (a->argc != e->args)
02121       return CLI_SHOWUSAGE;
02122    ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
02123    quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
02124    return CLI_SUCCESS;
02125 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

02028 {
02029    switch (cmd) {
02030    case CLI_INIT:
02031       e->command = "core stop gracefully";
02032       e->usage =
02033          "Usage: core stop gracefully\n"
02034          "       Causes Asterisk to not accept new calls, and exit when all\n"
02035          "       active calls have terminated normally.\n";
02036       return NULL;
02037    case CLI_GENERATE:
02038       return NULL;
02039    }
02040 
02041    if (a->argc != e->args)
02042       return CLI_SHOWUSAGE;
02043    quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
02044    return CLI_SUCCESS;
02045 }

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

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

02009 {
02010    switch (cmd) {
02011    case CLI_INIT:
02012       e->command = "core stop now";
02013       e->usage =
02014          "Usage: core stop now\n"
02015          "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
02016       return NULL;
02017    case CLI_GENERATE:
02018       return NULL;
02019    }
02020 
02021    if (a->argc != e->args)
02022       return CLI_SHOWUSAGE;
02023    quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
02024    return CLI_SUCCESS;
02025 }

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

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

02048 {
02049    switch (cmd) {
02050    case CLI_INIT:
02051       e->command = "core stop when convenient";
02052       e->usage =
02053          "Usage: core stop when convenient\n"
02054          "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
02055       return NULL;
02056    case CLI_GENERATE:
02057       return NULL;
02058    }
02059 
02060    if (a->argc != e->args)
02061       return CLI_SHOWUSAGE;
02062    ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
02063    quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
02064    return CLI_SUCCESS;
02065 }

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

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

01978 {
01979    switch (cmd) {
01980    case CLI_INIT:
01981       e->command = "core show version";
01982       e->usage =
01983          "Usage: core show version\n"
01984          "       Shows Asterisk version information.\n";
01985       return NULL;
01986    case CLI_GENERATE:
01987       return NULL;
01988    }
01989 
01990    if (a->argc != 3)
01991       return CLI_SHOWUSAGE;
01992    ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
01993       ast_get_version(), ast_build_user, ast_build_hostname,
01994       ast_build_machine, ast_build_os, ast_build_date);
01995    return CLI_SUCCESS;
01996 }

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

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

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

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

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

static void main_atexit ( void   )  [static]

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

03273 {
03274    for (;;) {
03275       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
03276       int a;
03277       ast_poll(&p, 1, -1);
03278       if (sig_flags.need_reload) {
03279          sig_flags.need_reload = 0;
03280          ast_module_reload(NULL);
03281       }
03282       if (sig_flags.need_quit) {
03283          sig_flags.need_quit = 0;
03284          if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
03285             sig_flags.need_quit_handler = 1;
03286             pthread_kill(consolethread, SIGURG);
03287          } else {
03288             quit_handler(0, SHUTDOWN_NORMAL, 0);
03289          }
03290       }
03291       if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
03292       }
03293    }
03294 
03295    return NULL;
03296 }

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

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

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

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

Definition at line 1226 of file asterisk.c.

References __LOG_VERBOSE, and ast_network_puts_mutable().

Referenced by ast_makesocket().

01227 {
01228    ast_network_puts_mutable(s, __LOG_VERBOSE);
01229 }

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

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

03374 {
03375    if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
03376       if (ast_register_verbose(console_verboser)) {
03377          fprintf(stderr, "Unable to register console verboser?\n");
03378          return;
03379       }
03380       WELCOME_MESSAGE;
03381       if (runuser) {
03382          ast_verbose("Running as user '%s'\n", runuser);
03383       }
03384       if (rungroup) {
03385          ast_verbose("Running under group '%s'\n", rungroup);
03386       }
03387    }
03388 }

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

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

01685 {
01686    if (can_safely_quit(niceness, restart)) {
01687       really_quit(num, niceness, restart);
01688       /* No one gets here. */
01689    }
01690    /* It wasn't our time. */
01691 }

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 766 of file asterisk.c.

Referenced by ast_mark().

00767 {
00768    return 0;
00769 }

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

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

Referenced by netconsole().

01244 {
01245 #if defined(SO_PEERCRED)
01246 #ifdef HAVE_STRUCT_SOCKPEERCRED_UID
01247 #define HAVE_STRUCT_UCRED_UID
01248    struct sockpeercred cred;
01249 #else
01250    struct ucred cred;
01251 #endif
01252    socklen_t len = sizeof(cred);
01253 #endif
01254 #if defined(HAVE_GETPEEREID)
01255    uid_t uid;
01256    gid_t gid;
01257 #else
01258    int uid, gid;
01259 #endif
01260    int result;
01261 
01262    result = read(fd, buffer, size);
01263    if (result < 0) {
01264       return result;
01265    }
01266 
01267 #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
01268    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
01269       return result;
01270    }
01271 #if defined(HAVE_STRUCT_UCRED_UID)
01272    uid = cred.uid;
01273    gid = cred.gid;
01274 #else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
01275    uid = cred.cr_uid;
01276    gid = cred.cr_gid;
01277 #endif /* defined(HAVE_STRUCT_UCRED_UID) */
01278 
01279 #elif defined(HAVE_GETPEEREID)
01280    if (getpeereid(fd, &uid, &gid)) {
01281       return result;
01282    }
01283 #else
01284    return result;
01285 #endif
01286    con->uid = uid;
01287    con->gid = gid;
01288 
01289    return result;
01290 }

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

Called when exiting is certain.

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

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

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

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

00977 {
00978    struct ast_atexit *ae;
00979 
00980    ae = ast_calloc(1, sizeof(*ae));
00981    if (!ae) {
00982       return -1;
00983    }
00984    ae->func = func;
00985    ae->is_cleanup = is_cleanup;
00986 
00987    AST_LIST_LOCK(&atexits);
00988    __ast_unregister_atexit(func);
00989    AST_LIST_INSERT_HEAD(&atexits, ae, list);
00990    AST_LIST_UNLOCK(&atexits);
00991 
00992    return 0;
00993 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1949 of file asterisk.c.

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

Referenced by ast_remotecontrol().

01950 {
01951    int ret = 0;
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       ret = 1;
01963    }
01964    while (isspace(*s)) {
01965       s++;
01966    }
01967 
01968    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
01969        (s[4] == '\0' || isspace(s[4]))) {
01970       quit_handler(0, SHUTDOWN_FAST, 0);
01971       ret = 1;
01972    }
01973 
01974    return ret;
01975 }

static void run_startup_commands ( void   )  [static]

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

03334 {
03335    int fd;
03336    struct ast_config *cfg;
03337    struct ast_flags cfg_flags = { 0 };
03338    struct ast_variable *v;
03339 
03340    if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
03341       return;
03342    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03343       return;
03344    }
03345 
03346    fd = open("/dev/null", O_RDWR);
03347    if (fd < 0) {
03348       ast_config_destroy(cfg);
03349       return;
03350    }
03351 
03352    for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
03353       if (ast_true(v->value))
03354          ast_cli_command(fd, v->name);
03355    }
03356 
03357    close(fd);
03358    ast_config_destroy(cfg);
03359 }

static void set_icon ( char *  text  )  [static]

Definition at line 1639 of file asterisk.c.

Referenced by main().

01640 {
01641    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01642       fprintf(stdout, "\033]1;%s\007", text);
01643 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1633 of file asterisk.c.

Referenced by main().

01634 {
01635    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01636       fprintf(stdout, "\033]2;%s\007", text);
01637 }

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1610 of file asterisk.c.

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

Referenced by ast_readconfig().

01611 {
01612    struct rlimit l = {0, 0};
01613 
01614    if (value <= 0) {
01615       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01616       return;
01617    }
01618 
01619    l.rlim_cur = value;
01620    l.rlim_max = value;
01621 
01622    if (setrlimit(RLIMIT_NOFILE, &l)) {
01623       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01624       return;
01625    }
01626 
01627    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01628 
01629    return;
01630 }

static int show_cli_help ( void   )  [static]

Definition at line 2983 of file asterisk.c.

References ast_get_version().

Referenced by main().

02984 {
02985    printf("Asterisk %s, Copyright (C) 1999 - 2013, Digium, Inc. and others.\n", ast_get_version());
02986    printf("Usage: asterisk [OPTIONS]\n");
02987    printf("Valid Options:\n");
02988    printf("   -V              Display version number and exit\n");
02989    printf("   -C <configfile> Use an alternate configuration file\n");
02990    printf("   -G <group>      Run as a group other than the caller\n");
02991    printf("   -U <user>       Run as a user other than the caller\n");
02992    printf("   -c              Provide console CLI\n");
02993    printf("   -d              Enable extra debugging\n");
02994 #if HAVE_WORKING_FORK
02995    printf("   -f              Do not fork\n");
02996    printf("   -F              Always fork\n");
02997 #endif
02998    printf("   -g              Dump core in case of a crash\n");
02999    printf("   -h              This help screen\n");
03000    printf("   -i              Initialize crypto keys at startup\n");
03001    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
03002    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
03003    printf("   -m              Mute debugging and console output on the console\n");
03004    printf("   -n              Disable console colorization\n");
03005    printf("   -p              Run as pseudo-realtime thread\n");
03006    printf("   -q              Quiet mode (suppress output)\n");
03007    printf("   -r              Connect to Asterisk on this machine\n");
03008    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
03009    printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
03010    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
03011    printf("                   belong after they are done\n");
03012    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
03013    printf("                   of output to the CLI\n");
03014    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
03015    printf("   -x <cmd>        Execute command <cmd> (implies -r)\n");
03016    printf("   -X              Execute includes by default (allows #exec in asterisk.conf)\n");
03017    printf("   -W              Adjust terminal colors to compensate for a light background\n");
03018    printf("\n");
03019    return 0;
03020 }

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

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

02237 {
02238    switch (cmd) {
02239    case CLI_INIT:
02240       e->command = "core show license";
02241       e->usage =
02242          "Usage: core show license\n"
02243          "       Shows the license(s) for this copy of Asterisk.\n";
02244       return NULL;
02245    case CLI_GENERATE:
02246       return NULL;
02247    }
02248 
02249    ast_cli(a->fd, "%s", license_lines);
02250 
02251    return CLI_SUCCESS;
02252 }

static int show_version ( void   )  [static]

Definition at line 2977 of file asterisk.c.

References ast_get_version().

Referenced by main().

02978 {
02979    printf("Asterisk %s\n", ast_get_version());
02980    return 0;
02981 }

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

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

02200 {
02201    switch (cmd) {
02202    case CLI_INIT:
02203       e->command = "core show warranty";
02204       e->usage =
02205          "Usage: core show warranty\n"
02206          "       Shows the warranty (if any) for this copy of Asterisk.\n";
02207       return NULL;
02208    case CLI_GENERATE:
02209       return NULL;
02210    }
02211 
02212    ast_cli(a->fd, "%s", warranty_lines);
02213 
02214    return CLI_SUCCESS;
02215 }


Variable Documentation

char* _argv[256] [static]

Definition at line 282 of file asterisk.c.

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

const char* ast_config_AST_AGI_DIR = cfg_paths.agi_dir

Definition at line 264 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 257 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 278 of file asterisk.c.

Referenced by ast_readconfig().

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

Definition at line 277 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

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

Definition at line 276 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static]

Definition at line 275 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 268 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 269 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 266 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 272 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 271 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 270 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 261 of file asterisk.c.

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

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

Definition at line 198 of file asterisk.c.

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

Referenced by safe_append(), and scan_service().

int ast_socket = -1 [static]

UNIX Socket for allowing remote control

Definition at line 197 of file asterisk.c.

struct timeval ast_startuptime
char canary_filename[128] [static]

Definition at line 297 of file asterisk.c.

Referenced by canary_thread(), and main().

int canary_pid = 0 [static]

Definition at line 296 of file asterisk.c.

Referenced by canary_exit(), and main().

struct _cfg_paths cfg_paths [static]

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

struct ast_cli_entry cli_asterisk[] [static]

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

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

Definition at line 294 of file asterisk.c.

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

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

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

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

Definition at line 1034 of file asterisk.c.

Referenced by main().

const char license_lines[] [static]

Definition at line 2217 of file asterisk.c.

pthread_t lthread [static]

Definition at line 1231 of file asterisk.c.

Referenced by ast_makesocket(), and really_quit().

pthread_t mon_sig_flags [static]

Definition at line 295 of file asterisk.c.

Referenced by main(), and really_quit().

int multi_thread_safe [static]

Definition at line 298 of file asterisk.c.

Referenced by ast_register_thread(), and main().

unsigned int need_quit

Definition at line 305 of file asterisk.c.

unsigned int need_quit_handler

Definition at line 306 of file asterisk.c.

unsigned int need_reload

Definition at line 304 of file asterisk.c.

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

Definition at line 1029 of file asterisk.c.

Referenced by ast_replace_sigchld().

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

Definition at line 2392 of file asterisk.c.

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

char randompool[256] [static]

Definition at line 300 of file asterisk.c.

Referenced by main().

char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR

Definition at line 195 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 223 of file asterisk.c.

Referenced by ast_remotecontrol(), and cli_prompt().

int restartnow [static]

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

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN [static]

Definition at line 292 of file asterisk.c.

Referenced by can_safely_quit(), and handle_abort_shutdown().

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

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

const char warranty_lines[] [static]

Definition at line 2174 of file asterisk.c.


Generated on 15 Apr 2016 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1