Tue Aug 20 16:34:47 2013

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.
void ast_register_file_version (const char *file, const char *version)
 Register the version of a source code file with the core.
void ast_register_thread (char *name)
static void ast_remotecontrol (char *data)
void ast_replace_sigchld (void)
 Replace the SIGCHLD handler.
static void ast_run_atexits (void)
int ast_safe_system (const char *s)
 Safely spawn an external program while closing file descriptors.
int ast_set_priority (int pri)
 We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy activity on it, this is a good thing.
static int ast_tryconnect (void)
void ast_unregister_atexit (void(*func)(void))
 Unregister a function registered with ast_register_atexit().
void ast_unregister_file_version (const char *file)
 Unregister a source code file from the core.
void ast_unregister_thread (void *id)
void ast_unreplace_sigchld (void)
 Restore the SIGCHLD handler.
static int can_safely_quit (shutdown_nice_t niceness, int restart)
static void canary_exit (void)
static void * canary_thread (void *unused)
static char * cli_complete (EditLine *editline, int ch)
static char * cli_prompt (EditLine *editline)
static void console_verboser (const char *s)
static void consolehandler (char *s)
static 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 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 2232 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 2234 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

Definition at line 788 of file asterisk.c.

Referenced by handle_clear_profile(), and handle_show_profile().

#define EL_BUF_SIZE   512

Referenced by ast_el_read_char().

#define FORMAT   "%-25.25s %-40.40s\n"
#define MAX_HISTORY_COMMAND_LENGTH   256

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

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


Function Documentation

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

Definition at line 962 of file asterisk.c.

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

Referenced by ast_register_atexit(), and ast_unregister_atexit().

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

static void __quit_handler ( int  num  )  [static]

Definition at line 1843 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

01844 {
01845    int a = 0;
01846    sig_flags.need_quit = 1;
01847    if (sig_alert_pipe[1] != -1) {
01848       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01849          fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
01850       }
01851    }
01852    /* There is no need to restore the signal handler here, since the app
01853     * is going to exit */
01854 }

static void __remote_quit_handler ( int  num  )  [static]

Definition at line 1856 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

01857 {
01858    sig_flags.need_quit = 1;
01859 }

static void _child_handler ( int  sig  )  [static]

Definition at line 1578 of file asterisk.c.

References errno, and status.

01579 {
01580    /* Must not ever ast_log or ast_verbose within signal handler */
01581    int n, status, save_errno = errno;
01582 
01583    /*
01584     * Reap all dead children -- not just one
01585     */
01586    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01587       ;
01588    if (n == 0 && option_debug)   
01589       printf("Huh?  Child handler, but nobody there?\n");
01590    errno = save_errno;
01591 }

static void _hup_handler ( int  num  )  [static]

Definition at line 1557 of file asterisk.c.

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

01558 {
01559    int a = 0, save_errno = errno;
01560    if (option_verbose > 1) 
01561       printf("Received HUP signal -- Reloading configs\n");
01562    if (restartnow)
01563       execvp(_argv[0], _argv);
01564    sig_flags.need_reload = 1;
01565    if (sig_alert_pipe[1] != -1) {
01566       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01567          fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
01568       }
01569    }
01570    errno = save_errno;
01571 }

static void _null_sig_handler ( int  sig  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 1014 of file asterisk.c.

01015 {
01016 }

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

01548 {
01549    return;
01550 }

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

allocates a counter with a given name and scale.

support for event profiling

Returns:
Returns the identifier of the counter.

Definition at line 707 of file asterisk.c.

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

Referenced by extension_match_core().

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

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1903 of file asterisk.c.

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

01904 {
01905    while (*s) {
01906       if (*s > 32)
01907          return 0;
01908       s++;  
01909    }
01910    return 1;
01911 }

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

Definition at line 2552 of file asterisk.c.

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

Referenced by cli_complete().

02553 {
02554    int i, idx, limit, count;
02555    int screenwidth = 0;
02556    int numoutput = 0, numoutputline = 0;
02557 
02558    screenwidth = ast_get_termcols(STDOUT_FILENO);
02559 
02560    /* find out how many entries can be put on one line, with two spaces between strings */
02561    limit = screenwidth / (max + 2);
02562    if (limit == 0)
02563       limit = 1;
02564 
02565    /* how many lines of output */
02566    count = len / limit;
02567    if (count * limit < len)
02568       count++;
02569 
02570    idx = 1;
02571 
02572    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
02573 
02574    for (; count > 0; count--) {
02575       numoutputline = 0;
02576       for (i = 0; i < limit && matches[idx]; i++, idx++) {
02577 
02578          /* Don't print dupes */
02579          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
02580             i--;
02581             ast_free(matches[idx]);
02582             matches[idx] = NULL;
02583             continue;
02584          }
02585 
02586          numoutput++;
02587          numoutputline++;
02588          fprintf(stdout, "%-*s  ", max, matches[idx]);
02589          ast_free(matches[idx]);
02590          matches[idx] = NULL;
02591       }
02592       if (numoutputline > 0)
02593          fprintf(stdout, "\n");
02594    }
02595 
02596    return numoutput;
02597 }

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

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

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

void ast_console_puts ( const char *  string  ) 

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

Definition at line 1208 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

01209 {
01210    fputs(string, stdout);
01211    fflush(stdout);
01212    ast_network_puts(string);
01213 }

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

References ast_network_puts_mutable().

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

01186 {
01187    fputs(string, stdout);
01188    fflush(stdout);
01189    ast_network_puts_mutable(string, level);
01190 }

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

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

Referenced by handle_logger_set_level().

01123 {
01124    int x;
01125 
01126    if (level >= NUMLOGLEVELS) {
01127       level = NUMLOGLEVELS - 1;
01128    }
01129 
01130    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01131       if (fd == consoles[x].fd) {
01132          /*
01133           * Since the logging occurs when levels are false, set to
01134           * flipped iinput because this function accepts 0 as off and 1 as on
01135           */
01136          consoles[x].levels[level] = state ? 0 : 1;
01137          return;
01138       }
01139    }
01140 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1145 of file asterisk.c.

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

Referenced by handle_logger_mute().

01146 {
01147    int x;
01148    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01149       if (fd == consoles[x].fd) {
01150          if (consoles[x].mute) {
01151             consoles[x].mute = 0;
01152             if (!silent)
01153                ast_cli(fd, "Console is not muted anymore.\n");
01154          } else {
01155             consoles[x].mute = 1;
01156             if (!silent)
01157                ast_cli(fd, "Console is muted.\n");
01158          }
01159          return;
01160       }
01161    }
01162    ast_cli(fd, "Couldn't find remote console.\n");
01163 }

static int ast_el_add_history ( char *  buf  )  [static]

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

02758 {
02759    HistEvent ev;
02760 
02761    if (el_hist == NULL || el == NULL)
02762       ast_el_initialize();
02763    if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1))
02764       return 0;
02765    return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf))));
02766 }

static int ast_el_initialize ( void   )  [static]

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

02721 {
02722    HistEvent ev;
02723    char *editor = getenv("AST_EDITOR");
02724 
02725    if (el != NULL)
02726       el_end(el);
02727    if (el_hist != NULL)
02728       history_end(el_hist);
02729 
02730    el = el_init("asterisk", stdin, stdout, stderr);
02731    el_set(el, EL_PROMPT, cli_prompt);
02732 
02733    el_set(el, EL_EDITMODE, 1);      
02734    el_set(el, EL_EDITOR, editor ? editor : "emacs");     
02735    el_hist = history_init();
02736    if (!el || !el_hist)
02737       return -1;
02738 
02739    /* setup history with 100 entries */
02740    history(el_hist, &ev, H_SETSIZE, 100);
02741 
02742    el_set(el, EL_HIST, history, el_hist);
02743 
02744    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02745    /* Bind <tab> to command completion */
02746    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02747    /* Bind ? to command completion */
02748    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02749    /* Bind ^D to redisplay */
02750    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02751 
02752    return 0;
02753 }

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

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

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

static int ast_el_read_history ( char *  filename  )  [static]

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

02779 {
02780    char buf[MAX_HISTORY_COMMAND_LENGTH];
02781    FILE *f;
02782    int ret = -1;
02783 
02784    if (el_hist == NULL || el == NULL)
02785       ast_el_initialize();
02786 
02787    if ((f = fopen(filename, "r")) == NULL)
02788       return ret;
02789 
02790    while (!feof(f)) {
02791       if (!fgets(buf, sizeof(buf), f))
02792          break;
02793       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02794          continue;
02795       if (ast_all_zeros(buf))
02796          continue;
02797       if ((ret = ast_el_add_history(buf)) == -1)
02798          break;
02799    }
02800    fclose(f);
02801 
02802    return ret;
02803 }

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

Definition at line 2542 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02543 {
02544    char *s1, *s2;
02545 
02546    s1 = ((char **)i1)[0];
02547    s2 = ((char **)i2)[0];
02548 
02549    return strcasecmp(s1, s2);
02550 }

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

Definition at line 2499 of file asterisk.c.

References AST_CLI_COMPLETE_EOF, ast_free, ast_realloc, and ast_strdup.

Referenced by cli_complete().

02500 {
02501    char **match_list = NULL, **match_list_tmp, *retstr;
02502    size_t match_list_len;
02503    int matches = 0;
02504 
02505    match_list_len = 1;
02506    while ( (retstr = strsep(&buf, " ")) != NULL) {
02507 
02508       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
02509          break;
02510       if (matches + 1 >= match_list_len) {
02511          match_list_len <<= 1;
02512          if ((match_list_tmp = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
02513             match_list = match_list_tmp;
02514          } else {
02515             if (match_list)
02516                ast_free(match_list);
02517             return (char **) NULL;
02518          }
02519       }
02520 
02521       match_list[matches++] = ast_strdup(retstr);
02522    }
02523 
02524    if (!match_list)
02525       return (char **) NULL;
02526 
02527    if (matches >= match_list_len) {
02528       if ((match_list_tmp = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
02529          match_list = match_list_tmp;
02530       } else {
02531          if (match_list)
02532             ast_free(match_list);
02533          return (char **) NULL;
02534       }
02535    }
02536 
02537    match_list[matches] = (char *) NULL;
02538 
02539    return match_list;
02540 }

static int ast_el_write_history ( char *  filename  )  [static]

Definition at line 2768 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by really_quit().

02769 {
02770    HistEvent ev;
02771 
02772    if (el_hist == NULL || el == NULL)
02773       ast_el_initialize();
02774 
02775    return (history(el_hist, &ev, H_SAVE, filename));
02776 }

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

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

static int ast_makesocket ( void   )  [static]

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

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

int64_t ast_mark ( int  i,
int  startstop 
)

Definition at line 772 of file asterisk.c.

References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, prof_data, rdtsc(), profile_entry::scale, and profile_entry::value.

Referenced by __ast_pthread_mutex_lock(), and extension_match_core().

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

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

write the string to all attached console clients

Definition at line 1195 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

01196 {
01197    int x;
01198    for (x = 0; x < AST_MAX_CONNECTS; x++) {
01199       if (consoles[x].fd > -1) 
01200          fdprint(consoles[x].p[1], string);
01201    }
01202 }

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

log the string to all attached console clients

Definition at line 1168 of file asterisk.c.

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

Referenced by ast_console_puts_mutable(), and network_verboser().

01169 {
01170    int x;
01171    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01172       if (consoles[x].mute)
01173          continue;
01174       if (consoles[x].fd > -1) {
01175          if (!consoles[x].levels[level]) 
01176             fdprint(consoles[x].p[1], string);
01177       }
01178    }
01179 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 737 of file asterisk.c.

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

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

static void ast_readconfig ( void   )  [static]

Definition at line 2996 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_INTERNAL_TIMING, AST_OPT_FLAG_LIGHT_BACKGROUND, AST_OPT_FLAG_LOCK_CONFIG_DIR, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_TIMESTAMP, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_opt_override_config, ast_set2_flag, ast_set_default_eid(), ast_set_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, _cfg_paths::log_dir, LOG_ERROR, LOG_WARNING, MAX_LANGUAGE, MAXHOSTNAMELEN, _cfg_paths::module_dir, _cfg_paths::monitor_dir, ast_variable::name, ast_variable::next, _cfg_paths::pid_path, _cfg_paths::run_dir, _cfg_paths::run_group, _cfg_paths::run_user, 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().

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

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

Register a function to be executed before Asterisk exits.

Parameters:
func The callback function to use.
Return values:
0 on success.
-1 on error.

Definition at line 976 of file asterisk.c.

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

Referenced by __ast_mm_init_phase_2(), __init_manager(), ast_aoc_cli_init(), ast_builtins_init(), ast_cc_init(), ast_cdr_engine_init(), ast_cel_engine_init(), ast_channels_init(), ast_data_init(), ast_event_init(), ast_features_init(), ast_file_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_pbx_init(), ast_stun_init(), ast_timing_init(), ast_tps_init(), ast_udptl_init(), astdb_init(), dnsmgr_init(), do_reload(), init_framer(), load_module(), load_pbx(), main(), and register_config_cli().

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

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

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

void ast_register_thread ( char *  name  ) 

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

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

static void ast_remotecontrol ( char *  data  )  [static]

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

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

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

01034 {
01035    unsigned int level;
01036 
01037    ast_mutex_lock(&safe_system_lock);
01038    level = safe_system_level++;
01039 
01040    /* only replace the handler if it has not already been done */
01041    if (level == 0) {
01042       sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
01043    }
01044 
01045    ast_mutex_unlock(&safe_system_lock);
01046 }

static void ast_run_atexits ( void   )  [static]

Definition at line 948 of file asterisk.c.

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

Referenced by really_quit().

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

int ast_safe_system ( const char *  s  ) 

Safely spawn an external program while closing file descriptors.

Note:
This replaces the system call in all Asterisk modules

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

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

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

01637 {
01638    struct sched_param sched;
01639    memset(&sched, 0, sizeof(sched));
01640 #ifdef __linux__
01641    if (pri) {  
01642       sched.sched_priority = 10;
01643       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01644          ast_log(LOG_WARNING, "Unable to set high priority\n");
01645          return -1;
01646       } else
01647          if (option_verbose)
01648             ast_verbose("Set to realtime thread\n");
01649    } else {
01650       sched.sched_priority = 0;
01651       /* According to the manpage, these parameters can never fail. */
01652       sched_setscheduler(0, SCHED_OTHER, &sched);
01653    }
01654 #else
01655    if (pri) {
01656       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01657          ast_log(LOG_WARNING, "Unable to set high priority\n");
01658          return -1;
01659       } else
01660          if (option_verbose)
01661             ast_verbose("Set to high priority\n");
01662    } else {
01663       /* According to the manpage, these parameters can never fail. */
01664       setpriority(PRIO_PROCESS, 0, 0);
01665    }
01666 #endif
01667    return 0;
01668 }

static int ast_tryconnect ( void   )  [static]

Definition at line 1520 of file asterisk.c.

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

Referenced by ast_el_read_char(), and main().

01521 {
01522    struct sockaddr_un sunaddr;
01523    int res;
01524    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01525    if (ast_consock < 0) {
01526       fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
01527       return 0;
01528    }
01529    memset(&sunaddr, 0, sizeof(sunaddr));
01530    sunaddr.sun_family = AF_LOCAL;
01531    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01532    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01533    if (res) {
01534       close(ast_consock);
01535       ast_consock = -1;
01536       return 0;
01537    } else
01538       return 1;
01539 }

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

00995 {
00996    AST_LIST_LOCK(&atexits);
00997    __ast_unregister_atexit(func);
00998    AST_LIST_UNLOCK(&atexits);
00999 }

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

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

void ast_unregister_thread ( void *  id  ) 

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

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

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

01049 {
01050    unsigned int level;
01051 
01052    ast_mutex_lock(&safe_system_lock);
01053    level = --safe_system_level;
01054 
01055    /* only restore the handler if we are the last one */
01056    if (level == 0) {
01057       sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
01058    }
01059 
01060    ast_mutex_unlock(&safe_system_lock);
01061 }

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

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

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

static void canary_exit ( void   )  [static]

Definition at line 3290 of file asterisk.c.

References canary_pid.

Referenced by main().

03291 {
03292    if (canary_pid > 0)
03293       kill(canary_pid, SIGKILL);
03294 }

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

Definition at line 3261 of file asterisk.c.

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

Referenced by main().

03262 {
03263    struct stat canary_stat;
03264    struct timeval now;
03265 
03266    /* Give the canary time to sing */
03267    sleep(120);
03268 
03269    for (;;) {
03270       now = ast_tvnow();
03271       if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
03272          ast_log(LOG_WARNING,
03273             "The canary is no more.  He has ceased to be!  "
03274             "He's expired and gone to meet his maker!  "
03275             "He's a stiff!  Bereft of life, he rests in peace.  "
03276             "His metabolic processes are now history!  He's off the twig!  "
03277             "He's kicked the bucket.  He's shuffled off his mortal coil, "
03278             "run down the curtain, and joined the bleeding choir invisible!!  "
03279             "THIS is an EX-CANARY.  (Reducing priority)\n");
03280          ast_set_priority(0);
03281          pthread_exit(NULL);
03282       }
03283 
03284       /* Check the canary once a minute */
03285       sleep(60);
03286    }
03287 }

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

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

02601 {
02602    int len = 0;
02603    char *ptr;
02604    int nummatches = 0;
02605    char **matches;
02606    int retval = CC_ERROR;
02607    char buf[2048], savechr;
02608    int res;
02609 
02610    LineInfo *lf = (LineInfo *)el_line(editline);
02611 
02612    savechr = *(char *)lf->cursor;
02613    *(char *)lf->cursor = '\0';
02614    ptr = (char *)lf->cursor;
02615    if (ptr) {
02616       while (ptr > lf->buffer) {
02617          if (isspace(*ptr)) {
02618             ptr++;
02619             break;
02620          }
02621          ptr--;
02622       }
02623    }
02624 
02625    len = lf->cursor - ptr;
02626 
02627    if (ast_opt_remote) {
02628       snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 
02629       fdsend(ast_consock, buf);
02630       if ((res = read(ast_consock, buf, sizeof(buf) - 1)) < 0) {
02631          return (char*)(CC_ERROR);
02632       }
02633       buf[res] = '\0';
02634       nummatches = atoi(buf);
02635 
02636       if (nummatches > 0) {
02637          char *mbuf;
02638          int mlen = 0, maxmbuf = 2048;
02639          /* Start with a 2048 byte buffer */       
02640          if (!(mbuf = ast_malloc(maxmbuf))) {
02641             lf->cursor[0] = savechr;
02642             return (char *)(CC_ERROR);
02643          }
02644          snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 
02645          fdsend(ast_consock, buf);
02646          res = 0;
02647          mbuf[0] = '\0';
02648          while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
02649             if (mlen + 1024 > maxmbuf) {
02650                /* Every step increment buffer 1024 bytes */
02651                maxmbuf += 1024;              
02652                if (!(mbuf = ast_realloc(mbuf, maxmbuf))) {
02653                   lf->cursor[0] = savechr;
02654                   return (char *)(CC_ERROR);
02655                }
02656             }
02657             /* Only read 1024 bytes at a time */
02658             res = read(ast_consock, mbuf + mlen, 1024);
02659             if (res > 0)
02660                mlen += res;
02661          }
02662          mbuf[mlen] = '\0';
02663 
02664          matches = ast_el_strtoarr(mbuf);
02665          ast_free(mbuf);
02666       } else
02667          matches = (char **) NULL;
02668    } else {
02669       char **p, *oldbuf=NULL;
02670       nummatches = 0;
02671       matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
02672       for (p = matches; p && *p; p++) {
02673          if (!oldbuf || strcmp(*p,oldbuf))
02674             nummatches++;
02675          oldbuf = *p;
02676       }
02677    }
02678 
02679    if (matches) {
02680       int i;
02681       int matches_num, maxlen, match_len;
02682 
02683       if (matches[0][0] != '\0') {
02684          el_deletestr(editline, (int) len);
02685          el_insertstr(editline, matches[0]);
02686          retval = CC_REFRESH;
02687       }
02688 
02689       if (nummatches == 1) {
02690          /* Found an exact match */
02691          el_insertstr(editline, " ");
02692          retval = CC_REFRESH;
02693       } else {
02694          /* Must be more than one match */
02695          for (i = 1, maxlen = 0; matches[i]; i++) {
02696             match_len = strlen(matches[i]);
02697             if (match_len > maxlen)
02698                maxlen = match_len;
02699          }
02700          matches_num = i - 1;
02701          if (matches_num >1) {
02702             fprintf(stdout, "\n");
02703             ast_cli_display_match_list(matches, nummatches, maxlen);
02704             retval = CC_REDISPLAY;
02705          } else { 
02706             el_insertstr(editline," ");
02707             retval = CC_REFRESH;
02708          }
02709       }
02710       for (i = 0; matches[i]; i++)
02711          ast_free(matches[i]);
02712       ast_free(matches);
02713    }
02714 
02715    lf->cursor[0] = savechr;
02716 
02717    return (char *)(long)retval;
02718 }

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

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

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

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

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

01879 {
01880    char tmp[80];
01881    const char *c = NULL;
01882 
01883    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01884        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01885        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01886        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
01887       fputs(tmp, stdout);
01888       fputs(c, stdout);
01889    } else {
01890       if (*s == 127) {
01891          s++;
01892       }
01893       fputs(s, stdout);
01894    }
01895 
01896    fflush(stdout);
01897    
01898    /* Wake up a poll()ing console */
01899    if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
01900       pthread_kill(consolethread, SIGURG);
01901 }

static void consolehandler ( char *  s  )  [static]

Definition at line 1913 of file asterisk.c.

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

Referenced by main().

01914 {
01915    printf("%s", term_end());
01916    fflush(stdout);
01917 
01918    /* Called when readline data is available */
01919    if (!ast_all_zeros(s))
01920       ast_el_add_history(s);
01921    /* The real handler for bang */
01922    if (s[0] == '!') {
01923       if (s[1])
01924          ast_safe_system(s+1);
01925       else
01926          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01927    } else 
01928       ast_cli_command(STDOUT_FILENO, s);
01929 }

static void env_init ( void   )  [static]

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

03325 {
03326    setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
03327    setenv("AST_BUILD_HOST", ast_build_hostname, 1);
03328    setenv("AST_BUILD_DATE", ast_build_date, 1);
03329    setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
03330    setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
03331    setenv("AST_BUILD_OS", ast_build_os, 1);
03332    setenv("AST_BUILD_USER", ast_build_user, 1);
03333    setenv("AST_VERSION", ast_get_version(), 1);
03334 }

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

Definition at line 1008 of file asterisk.c.

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

01009 {
01010    return write(fd, s, strlen(s));
01011 }

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

Definition at line 1002 of file asterisk.c.

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

01003 {
01004    return write(fd, s, strlen(s) + 1);
01005 }

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

Definition at line 1861 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01862 {
01863    const char *c;
01864 
01865    /* Check for verboser preamble */
01866    if (*s == 127) {
01867       s++;
01868    }
01869 
01870    if (!strncmp(s, cmp, strlen(cmp))) {
01871       c = s + strlen(cmp);
01872       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01873       return c;
01874    }
01875    return NULL;
01876 }

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

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

02106 {
02107    int aborting_shutdown = 0;
02108 
02109    switch (cmd) {
02110    case CLI_INIT:
02111       e->command = "core abort shutdown";
02112       e->usage = 
02113          "Usage: core abort shutdown\n"
02114          "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
02115          "       call operations.\n";
02116       return NULL;
02117    case CLI_GENERATE:
02118       return NULL;
02119    }
02120 
02121    if (a->argc != e->args)
02122       return CLI_SHOWUSAGE;
02123 
02124    ast_mutex_lock(&safe_system_lock);
02125    if (shuttingdown >= SHUTDOWN_FAST) {
02126       aborting_shutdown = 1;
02127       shuttingdown = NOT_SHUTTING_DOWN;
02128    }
02129    ast_mutex_unlock(&safe_system_lock);
02130 
02131    if (aborting_shutdown) {
02132       ast_cancel_shutdown();
02133    }
02134    return CLI_SUCCESS;
02135 }

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

Definition at line 2137 of file asterisk.c.

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

02138 {
02139    switch (cmd) {
02140    case CLI_INIT:
02141       e->command = "!";
02142       e->usage = 
02143          "Usage: !<command>\n"
02144          "       Executes a given shell command\n";
02145       return NULL;
02146    case CLI_GENERATE:
02147       return NULL;
02148    }
02149 
02150    return CLI_SUCCESS;
02151 }

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

Definition at line 836 of file asterisk.c.

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

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

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

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

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

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

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

02046 {
02047    switch (cmd) {
02048    case CLI_INIT:
02049       e->command = "core restart now";
02050       e->usage = 
02051          "Usage: core restart now\n"
02052          "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
02053          "       restart.\n";
02054       return NULL;
02055    case CLI_GENERATE:
02056       return NULL;
02057    }
02058 
02059    if (a->argc != e->args)
02060       return CLI_SHOWUSAGE;
02061    quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
02062    return CLI_SUCCESS;
02063 }

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

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

02086 {
02087    switch (cmd) {
02088    case CLI_INIT:
02089       e->command = "core restart when convenient";
02090       e->usage = 
02091          "Usage: core restart when convenient\n"
02092          "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
02093       return NULL;
02094    case CLI_GENERATE:
02095       return NULL;
02096    }
02097 
02098    if (a->argc != e->args)
02099       return CLI_SHOWUSAGE;
02100    ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
02101    quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
02102    return CLI_SUCCESS;
02103 }

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

Definition at line 801 of file asterisk.c.

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

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

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

Give an overview of core settings.

Todo:
we could check musiconhold, voicemail, smdi, adsi, queues

Definition at line 435 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_INTERNAL_TIMING, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_realtime_enabled(), ast_startuptime, ast_strftime(), ast_test_flag, check_cdr_enabled(), check_manager_enabled(), check_webmanager_enabled(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, defaultlanguage, ast_cli_args::fd, S_OR, and ast_cli_entry::usage.

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

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

Give an overview of system statistics.

Definition at line 590 of file asterisk.c.

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

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

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

Definition at line 518 of file asterisk.c.

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

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

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

CLI command to list module versions.

Definition at line 865 of file asterisk.c.

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

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

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

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

02006 {
02007    switch (cmd) {
02008    case CLI_INIT:
02009       e->command = "core stop gracefully";
02010       e->usage = 
02011          "Usage: core stop gracefully\n"
02012          "       Causes Asterisk to not accept new calls, and exit when all\n"
02013          "       active calls have terminated normally.\n";
02014       return NULL;
02015    case CLI_GENERATE:
02016       return NULL;
02017    }
02018 
02019    if (a->argc != e->args)
02020       return CLI_SHOWUSAGE;
02021    quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
02022    return CLI_SUCCESS;
02023 }

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

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

01987 {
01988    switch (cmd) {
01989    case CLI_INIT:
01990       e->command = "core stop now";
01991       e->usage = 
01992          "Usage: core stop now\n"
01993          "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
01994       return NULL;
01995    case CLI_GENERATE:
01996       return NULL;
01997    }
01998 
01999    if (a->argc != e->args)
02000       return CLI_SHOWUSAGE;
02001    quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
02002    return CLI_SUCCESS;
02003 }

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

Definition at line 2025 of file asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, 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.

02026 {
02027    switch (cmd) {
02028    case CLI_INIT:
02029       e->command = "core stop when convenient";
02030       e->usage = 
02031          "Usage: core stop when convenient\n"
02032          "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
02033       return NULL;
02034    case CLI_GENERATE:
02035       return NULL;
02036    }
02037 
02038    if (a->argc != e->args)
02039       return CLI_SHOWUSAGE;
02040    ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
02041    quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
02042    return CLI_SUCCESS;
02043 }

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

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

01956 {
01957    switch (cmd) {
01958    case CLI_INIT:
01959       e->command = "core show version";
01960       e->usage = 
01961          "Usage: core show version\n"
01962          "       Shows Asterisk version information.\n";
01963       return NULL;
01964    case CLI_GENERATE:
01965       return NULL;
01966    }
01967 
01968    if (a->argc != 3)
01969       return CLI_SHOWUSAGE;
01970    ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
01971       ast_get_version(), ast_build_user, ast_build_hostname,
01972       ast_build_machine, ast_build_os, ast_build_date);
01973    return CLI_SUCCESS;
01974 }

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

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

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

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 3358 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_INTERNAL_TIMING, AST_OPT_FLAG_LIGHT_BACKGROUND, AST_OPT_FLAG_MUTE, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_OVERRIDE_CONFIG, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_RECONNECT, AST_OPT_FLAG_REMOTE, AST_OPT_FLAG_TIMESTAMP, ast_opt_high_priority, ast_opt_no_fork, ast_opt_remote, ast_pbx_init(), ast_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().

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

static void main_atexit ( void   )  [static]

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

03236 {
03237    for (;;) {
03238       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
03239       int a;
03240       ast_poll(&p, 1, -1);
03241       if (sig_flags.need_reload) {
03242          sig_flags.need_reload = 0;
03243          ast_module_reload(NULL);
03244       }
03245       if (sig_flags.need_quit) {
03246          sig_flags.need_quit = 0;
03247          if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
03248             sig_flags.need_quit_handler = 1;
03249             pthread_kill(consolethread, SIGURG);
03250          } else {
03251             quit_handler(0, SHUTDOWN_NORMAL, 0);
03252          }
03253       }
03254       if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
03255       }
03256    }
03257 
03258    return NULL;
03259 }

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

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

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

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

Definition at line 1215 of file asterisk.c.

References __LOG_VERBOSE, and ast_network_puts_mutable().

Referenced by ast_makesocket().

01216 {
01217    ast_network_puts_mutable(s, __LOG_VERBOSE);
01218 }

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

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

03337 {
03338    if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
03339       if (ast_register_verbose(console_verboser)) {
03340          fprintf(stderr, "Unable to register console verboser?\n");
03341          return;
03342       }
03343       WELCOME_MESSAGE;
03344       if (runuser) {
03345          ast_verbose("Running as user '%s'\n", runuser);
03346       }
03347       if (rungroup) {
03348          ast_verbose("Running under group '%s'\n", rungroup);
03349       }
03350    }
03351 }

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

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

01674 {
01675    if (can_safely_quit(niceness, restart)) {
01676       really_quit(num, niceness, restart);
01677       /* No one gets here. */
01678    }
01679    /* It wasn't our time. */
01680 }

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 766 of file asterisk.c.

Referenced by ast_mark().

00767 {
00768    return 0;
00769 }

static int read_credentials ( int  fd,
char *  buffer,
size_t  size,
struct console con 
) [static]

read() function supporting the reception of user credentials.

Parameters:
fd Socket file descriptor.
buffer Receive buffer.
size 'buffer' size.
con Console structure to set received credentials
Return values:
-1 on error
the number of bytes received on success.

Definition at line 1232 of file asterisk.c.

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

Referenced by netconsole().

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

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

Called when exiting is certain.

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

Referenced by quit_handler().

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

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1931 of file asterisk.c.

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

Referenced by ast_remotecontrol().

01932 {
01933    int ret = 0;
01934 
01935    /* Called when readline data is available */
01936    if (!ast_all_zeros(s))
01937       ast_el_add_history(s);
01938    /* The real handler for bang */
01939    if (s[0] == '!') {
01940       if (s[1])
01941          ast_safe_system(s+1);
01942       else
01943          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01944       ret = 1;
01945    }
01946    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
01947        (s[4] == '\0' || isspace(s[4]))) {
01948       quit_handler(0, SHUTDOWN_FAST, 0);
01949       ret = 1;
01950    }
01951 
01952    return ret;
01953 }

static void run_startup_commands ( void   )  [static]

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

03297 {
03298    int fd;
03299    struct ast_config *cfg;
03300    struct ast_flags cfg_flags = { 0 };
03301    struct ast_variable *v;
03302 
03303    if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
03304       return;
03305    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03306       return;
03307    }
03308 
03309    fd = open("/dev/null", O_RDWR);
03310    if (fd < 0) {
03311       ast_config_destroy(cfg);
03312       return;
03313    }
03314 
03315    for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
03316       if (ast_true(v->value))
03317          ast_cli_command(fd, v->name);
03318    }
03319 
03320    close(fd);
03321    ast_config_destroy(cfg);
03322 }

static void set_icon ( char *  text  )  [static]

Definition at line 1628 of file asterisk.c.

Referenced by main().

01629 {
01630    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01631       fprintf(stdout, "\033]1;%s\007", text);
01632 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1622 of file asterisk.c.

Referenced by main().

01623 {
01624    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01625       fprintf(stdout, "\033]2;%s\007", text);
01626 }

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1599 of file asterisk.c.

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

Referenced by ast_readconfig().

01600 {
01601    struct rlimit l = {0, 0};
01602    
01603    if (value <= 0) {
01604       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01605       return;
01606    }
01607    
01608    l.rlim_cur = value;
01609    l.rlim_max = value;
01610    
01611    if (setrlimit(RLIMIT_NOFILE, &l)) {
01612       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01613       return;
01614    }
01615    
01616    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01617    
01618    return;
01619 }

static int show_cli_help ( void   )  [static]

Definition at line 2956 of file asterisk.c.

References ast_get_version().

Referenced by main().

02957 {
02958    printf("Asterisk %s, Copyright (C) 1999 - 2012, Digium, Inc. and others.\n", ast_get_version());
02959    printf("Usage: asterisk [OPTIONS]\n");
02960    printf("Valid Options:\n");
02961    printf("   -V              Display version number and exit\n");
02962    printf("   -C <configfile> Use an alternate configuration file\n");
02963    printf("   -G <group>      Run as a group other than the caller\n");
02964    printf("   -U <user>       Run as a user other than the caller\n");
02965    printf("   -c              Provide console CLI\n");
02966    printf("   -d              Enable extra debugging\n");
02967 #if HAVE_WORKING_FORK
02968    printf("   -f              Do not fork\n");
02969    printf("   -F              Always fork\n");
02970 #endif
02971    printf("   -g              Dump core in case of a crash\n");
02972    printf("   -h              This help screen\n");
02973    printf("   -i              Initialize crypto keys at startup\n");
02974    printf("   -I              Enable internal timing if DAHDI timer is available\n");
02975    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
02976    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
02977    printf("   -m              Mute debugging and console output on the console\n");
02978    printf("   -n              Disable console colorization\n");
02979    printf("   -p              Run as pseudo-realtime thread\n");
02980    printf("   -q              Quiet mode (suppress output)\n");
02981    printf("   -r              Connect to Asterisk on this machine\n");
02982    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
02983    printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
02984    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
02985    printf("                   belong after they are done\n");
02986    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
02987    printf("                   of output to the CLI\n");
02988    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
02989    printf("   -x <cmd>        Execute command <cmd> (implies -r)\n");
02990    printf("   -X              Execute includes by default (allows #exec in asterisk.conf)\n");
02991    printf("   -W              Adjust terminal colors to compensate for a light background\n");
02992    printf("\n");
02993    return 0;
02994 }

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

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

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

static int show_version ( void   )  [static]

Definition at line 2950 of file asterisk.c.

References ast_get_version().

Referenced by main().

02951 {
02952    printf("Asterisk %s\n", ast_get_version());
02953    return 0;
02954 }

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

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

02178 {
02179    switch (cmd) {
02180    case CLI_INIT:
02181       e->command = "core show warranty";
02182       e->usage = 
02183          "Usage: core show warranty\n"
02184          "       Shows the warranty (if any) for this copy of Asterisk.\n";
02185       return NULL;
02186    case CLI_GENERATE:
02187       return NULL;
02188    }
02189 
02190    ast_cli(a->fd, "%s", warranty_lines);
02191 
02192    return CLI_SUCCESS;
02193 }


Variable Documentation

char* _argv[256] [static]

Definition at line 281 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 263 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 256 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 277 of file asterisk.c.

Referenced by ast_readconfig().

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

Definition at line 276 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

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

Definition at line 275 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static]

Definition at line 274 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 267 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 268 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 265 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 271 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 270 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 269 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 260 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 296 of file asterisk.c.

Referenced by canary_thread(), and main().

int canary_pid = 0 [static]

Definition at line 295 of file asterisk.c.

Referenced by canary_exit(), and main().

struct _cfg_paths cfg_paths [static]

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

struct ast_cli_entry cli_asterisk[] [static]

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

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

Definition at line 293 of file asterisk.c.

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

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

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

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

Definition at line 1023 of file asterisk.c.

Referenced by main().

const char license_lines[] [static]

Definition at line 2195 of file asterisk.c.

pthread_t lthread [static]

Definition at line 1220 of file asterisk.c.

Referenced by ast_makesocket(), and really_quit().

pthread_t mon_sig_flags [static]

Definition at line 294 of file asterisk.c.

Referenced by main(), and really_quit().

int multi_thread_safe [static]

Definition at line 297 of file asterisk.c.

Referenced by ast_register_thread(), and main().

unsigned int need_quit

Definition at line 304 of file asterisk.c.

unsigned int need_quit_handler

Definition at line 305 of file asterisk.c.

unsigned int need_reload

Definition at line 303 of file asterisk.c.

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

Definition at line 1018 of file asterisk.c.

Referenced by ast_replace_sigchld().

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

Definition at line 2370 of file asterisk.c.

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

char randompool[256] [static]

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

Referenced by ast_remotecontrol(), and cli_prompt().

int restartnow [static]

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

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN [static]

Definition at line 291 of file asterisk.c.

Referenced by can_safely_quit(), and handle_abort_shutdown().

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

Definition at line 301 of file asterisk.c.

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

struct { ... } sig_flags [static]
struct sigaction urg_handler [static]
Initial value:
 {
   .sa_handler = _urg_handler,
   .sa_flags = SA_RESTART,
}

Definition at line 1552 of file asterisk.c.

const char warranty_lines[] [static]

Definition at line 2152 of file asterisk.c.


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1