Fri Aug 17 00:17:25 2018

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

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 2259 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

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

Referenced by ast_el_add_history(), and ast_el_read_history().

#define NUM_MSGS   64

Definition at line 159 of file asterisk.c.

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 162 of file asterisk.c.

Referenced by ast_el_read_char(), and print_intro_message().


Enumeration Type Documentation

Enumerator:
NOT_SHUTTING_DOWN 
SHUTTING_DOWN 
SHUTDOWN_FAST 
SHUTDOWN_NORMAL 
SHUTDOWN_NICE 
SHUTDOWN_REALLY_NICE 

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

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

static void __quit_handler ( int  num  )  [static]

Definition at line 1864 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

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

static void __remote_quit_handler ( int  num  )  [static]

Definition at line 1877 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

01878 {
01879    sig_flags.need_quit = 1;
01880 }

static void _child_handler ( int  sig  )  [static]

Definition at line 1592 of file asterisk.c.

References errno, and status.

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

static void _hup_handler ( int  num  )  [static]

Definition at line 1571 of file asterisk.c.

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

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

static void _null_sig_handler ( int  sig  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 1028 of file asterisk.c.

01029 {
01030 }

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

01562 {
01563    return;
01564 }

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

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

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1924 of file asterisk.c.

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

01925 {
01926    while (*s) {
01927       if (*s > 32)
01928          return 0;
01929       s++;
01930    }
01931    return 1;
01932 }

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

Definition at line 2594 of file asterisk.c.

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

Referenced by cli_complete().

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

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

References ast_network_puts().

01223 {
01224    fputs(string, stdout);
01225    fflush(stdout);
01226    ast_network_puts(string);
01227 }

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

References ast_network_puts_mutable().

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

01200 {
01201    fputs(string, stdout);
01202    fflush(stdout);
01203    ast_network_puts_mutable(string, level);
01204 }

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

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

Referenced by handle_logger_set_level().

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

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1159 of file asterisk.c.

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

Referenced by handle_logger_mute().

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

static int ast_el_add_history ( char *  buf  )  [static]

Definition at line 2804 of file asterisk.c.

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

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

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

static int ast_el_initialize ( void   )  [static]

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

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

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

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

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

static int ast_el_read_history ( char *  filename  )  [static]

Definition at line 2825 of file asterisk.c.

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

Referenced by ast_remotecontrol(), and main().

02826 {
02827    char buf[MAX_HISTORY_COMMAND_LENGTH];
02828    FILE *f;
02829    int ret = -1;
02830 
02831    if (el_hist == NULL || el == NULL)
02832       ast_el_initialize();
02833 
02834    if ((f = fopen(filename, "r")) == NULL)
02835       return ret;
02836 
02837    while (!feof(f)) {
02838       if (!fgets(buf, sizeof(buf), f))
02839          break;
02840       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02841          continue;
02842       if (ast_all_zeros(buf))
02843          continue;
02844       if ((ret = ast_el_add_history(buf)) == -1)
02845          break;
02846    }
02847    fclose(f);
02848 
02849    return ret;
02850 }

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

Definition at line 2584 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02585 {
02586    char *s1, *s2;
02587 
02588    s1 = ((char **)i1)[0];
02589    s2 = ((char **)i2)[0];
02590 
02591    return strcasecmp(s1, s2);
02592 }

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

Definition at line 2536 of file asterisk.c.

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

Referenced by cli_complete().

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

static int ast_el_write_history ( char *  filename  )  [static]

Definition at line 2815 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by really_quit().

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

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

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

int64_t ast_mark ( int  i,
int  startstop 
)

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

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

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

write the string to all attached console clients

Definition at line 1209 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

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

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

log the string to all attached console clients

Definition at line 1182 of file asterisk.c.

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

Referenced by ast_console_puts_mutable(), and network_verboser().

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

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 740 of file asterisk.c.

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

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

static void ast_readconfig ( void   )  [static]

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

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

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

References ast_atexit::func, and register_atexit().

Referenced by ast_autoservice_init().

01004 {
01005    return register_atexit(func, 1);
01006 }

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

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

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

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

static void ast_run_atexits ( int  run_cleanups  )  [static]

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

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

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

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

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

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

static int ast_tryconnect ( void   )  [static]

Definition at line 1534 of file asterisk.c.

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

Referenced by ast_el_read_char(), and main().

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

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

01009 {
01010    AST_LIST_LOCK(&atexits);
01011    __ast_unregister_atexit(func);
01012    AST_LIST_UNLOCK(&atexits);
01013 }

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

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

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

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

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

static void canary_exit ( void   )  [static]

Definition at line 3347 of file asterisk.c.

References canary_pid.

Referenced by main().

03348 {
03349    if (canary_pid > 0)
03350       kill(canary_pid, SIGKILL);
03351 }

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

Definition at line 3318 of file asterisk.c.

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

Referenced by main().

03319 {
03320    struct stat canary_stat;
03321    struct timeval now;
03322 
03323    /* Give the canary time to sing */
03324    sleep(120);
03325 
03326    for (;;) {
03327       now = ast_tvnow();
03328       if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
03329          ast_log(LOG_WARNING,
03330             "The canary is no more.  He has ceased to be!  "
03331             "He's expired and gone to meet his maker!  "
03332             "He's a stiff!  Bereft of life, he rests in peace.  "
03333             "His metabolic processes are now history!  He's off the twig!  "
03334             "He's kicked the bucket.  He's shuffled off his mortal coil, "
03335             "run down the curtain, and joined the bleeding choir invisible!!  "
03336             "THIS is an EX-CANARY.  (Reducing priority)\n");
03337          ast_set_priority(0);
03338          pthread_exit(NULL);
03339       }
03340 
03341       /* Check the canary once a minute */
03342       sleep(60);
03343    }
03344 }

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

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

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

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

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

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

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

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

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

static void consolehandler ( char *  s  )  [static]

Definition at line 1934 of file asterisk.c.

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

Referenced by main().

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

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

Definition at line 2524 of file asterisk.c.

References ast_free.

Referenced by ast_el_strtoarr().

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

static void env_init ( void   )  [static]

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

03382 {
03383    setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
03384    setenv("AST_BUILD_HOST", ast_build_hostname, 1);
03385    setenv("AST_BUILD_DATE", ast_build_date, 1);
03386    setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
03387    setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
03388    setenv("AST_BUILD_OS", ast_build_os, 1);
03389    setenv("AST_BUILD_USER", ast_build_user, 1);
03390    setenv("AST_VERSION", ast_get_version(), 1);
03391 }

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

Definition at line 1022 of file asterisk.c.

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

01023 {
01024    return write(fd, s, strlen(s));
01025 }

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

Definition at line 1016 of file asterisk.c.

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

01017 {
01018    return write(fd, s, strlen(s) + 1);
01019 }

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

Definition at line 1882 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

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

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

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

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

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

Definition at line 2162 of file asterisk.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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    struct rlimit rlim;
00491    if (!getrlimit(RLIMIT_NOFILE, &rlim))
00492    ast_cli(a->fd, "  Current file desc. limits:   current: %i max: %i\n", rlim.rlim_cur, rlim.rlim_max);
00493 
00494    ast_cli(a->fd, "\n* Subsystems\n");
00495    ast_cli(a->fd, "  -------------\n");
00496    ast_cli(a->fd, "  Manager (AMI):               %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
00497    ast_cli(a->fd, "  Web Manager (AMI/HTTP):      %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled");
00498    ast_cli(a->fd, "  Call data records:           %s\n", check_cdr_enabled() ? "Enabled" : "Disabled");
00499    ast_cli(a->fd, "  Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
00500 
00501    /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues  */
00502 
00503    ast_cli(a->fd, "\n* Directories\n");
00504    ast_cli(a->fd, "  -------------\n");
00505    ast_cli(a->fd, "  Configuration file:          %s\n", ast_config_AST_CONFIG_FILE);
00506    ast_cli(a->fd, "  Configuration directory:     %s\n", ast_config_AST_CONFIG_DIR);
00507    ast_cli(a->fd, "  Module directory:            %s\n", ast_config_AST_MODULE_DIR);
00508    ast_cli(a->fd, "  Spool directory:             %s\n", ast_config_AST_SPOOL_DIR);
00509    ast_cli(a->fd, "  Log directory:               %s\n", ast_config_AST_LOG_DIR);
00510    ast_cli(a->fd, "  Run/Sockets directory:       %s\n", ast_config_AST_RUN_DIR);
00511    ast_cli(a->fd, "  PID file:                    %s\n", ast_config_AST_PID);
00512    ast_cli(a->fd, "  VarLib directory:            %s\n", ast_config_AST_VAR_DIR);
00513    ast_cli(a->fd, "  Data directory:              %s\n", ast_config_AST_DATA_DIR);
00514    ast_cli(a->fd, "  ASTDB:                       %s\n", ast_config_AST_DB);
00515    ast_cli(a->fd, "  IAX2 Keys directory:         %s\n", ast_config_AST_KEY_DIR);
00516    ast_cli(a->fd, "  AGI Scripts directory:       %s\n", ast_config_AST_AGI_DIR);
00517    ast_cli(a->fd, "\n\n");
00518    return CLI_SUCCESS;
00519 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

static void main_atexit ( void   )  [static]

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

03293 {
03294    for (;;) {
03295       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
03296       int a;
03297       ast_poll(&p, 1, -1);
03298       if (sig_flags.need_reload) {
03299          sig_flags.need_reload = 0;
03300          ast_module_reload(NULL);
03301       }
03302       if (sig_flags.need_quit) {
03303          sig_flags.need_quit = 0;
03304          if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
03305             sig_flags.need_quit_handler = 1;
03306             pthread_kill(consolethread, SIGURG);
03307          } else {
03308             quit_handler(0, SHUTDOWN_NORMAL, 0);
03309          }
03310       }
03311       if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
03312       }
03313    }
03314 
03315    return NULL;
03316 }

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

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

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

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

Definition at line 1229 of file asterisk.c.

References __LOG_VERBOSE, and ast_network_puts_mutable().

Referenced by ast_makesocket().

01230 {
01231    ast_network_puts_mutable(s, __LOG_VERBOSE);
01232 }

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

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

03394 {
03395    if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
03396       if (ast_register_verbose(console_verboser)) {
03397          fprintf(stderr, "Unable to register console verboser?\n");
03398          return;
03399       }
03400       WELCOME_MESSAGE;
03401       if (runuser) {
03402          ast_verbose("Running as user '%s'\n", runuser);
03403       }
03404       if (rungroup) {
03405          ast_verbose("Running under group '%s'\n", rungroup);
03406       }
03407    }
03408 }

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

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

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

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 769 of file asterisk.c.

Referenced by ast_mark().

00770 {
00771    return 0;
00772 }

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

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

Referenced by netconsole().

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

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

Called when exiting is certain.

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

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

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

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

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

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1952 of file asterisk.c.

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

Referenced by ast_remotecontrol().

01953 {
01954    int ret = 0;
01955 
01956    /* Called when readline data is available */
01957    if (!ast_all_zeros(s))
01958       ast_el_add_history(s);
01959    /* The real handler for bang */
01960    if (s[0] == '!') {
01961       if (s[1])
01962          ast_safe_system(s+1);
01963       else
01964          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01965       ret = 1;
01966    }
01967    while (isspace(*s)) {
01968       s++;
01969    }
01970 
01971    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
01972        (s[4] == '\0' || isspace(s[4]))) {
01973       quit_handler(0, SHUTDOWN_FAST, 0);
01974       ret = 1;
01975    }
01976 
01977    return ret;
01978 }

static void run_startup_commands ( void   )  [static]

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

03354 {
03355    int fd;
03356    struct ast_config *cfg;
03357    struct ast_flags cfg_flags = { 0 };
03358    struct ast_variable *v;
03359 
03360    if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
03361       return;
03362    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03363       return;
03364    }
03365 
03366    fd = open("/dev/null", O_RDWR);
03367    if (fd < 0) {
03368       ast_config_destroy(cfg);
03369       return;
03370    }
03371 
03372    for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
03373       if (ast_true(v->value))
03374          ast_cli_command(fd, v->name);
03375    }
03376 
03377    close(fd);
03378    ast_config_destroy(cfg);
03379 }

static void set_icon ( char *  text  )  [static]

Definition at line 1642 of file asterisk.c.

Referenced by main().

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

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1636 of file asterisk.c.

Referenced by main().

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

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1613 of file asterisk.c.

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

Referenced by ast_readconfig().

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

static int show_cli_help ( void   )  [static]

Definition at line 3003 of file asterisk.c.

References ast_get_version().

Referenced by main().

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

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

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

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

static int show_version ( void   )  [static]

Definition at line 2997 of file asterisk.c.

References ast_get_version().

Referenced by main().

02998 {
02999    printf("Asterisk %s\n", ast_get_version());
03000    return 0;
03001 }

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

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

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


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

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 2278 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 2269 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 1587 of file asterisk.c.

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

Definition at line 1037 of file asterisk.c.

Referenced by main().

const char license_lines[] [static]

Definition at line 2220 of file asterisk.c.

pthread_t lthread [static]

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

Referenced by ast_replace_sigchld().

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

Definition at line 2395 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 1044 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 1045 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 1566 of file asterisk.c.

const char warranty_lines[] [static]

Definition at line 2177 of file asterisk.c.


Generated on 17 Aug 2018 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1