Wed Apr 6 11:29:53 2011

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 AF_LOCAL   AF_UNIX
#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 PF_LOCAL   PF_UNIX
#define WELCOME_MESSAGE
 Welcome message when starting a CLI interface.

Functions

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)
 support for event profiling
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)
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 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 * monitor_sig_flags (void *unused)
static void * netconsole (void *vconsole)
static void network_verboser (const char *s)
static void quit_handler (int num, int niceness, int safeshutdown, 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 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]
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
ast_eid ast_eid_default
 Global EID.
unsigned int ast_FD_SETSIZE
timeval ast_lastreloadtime
pid_t ast_mainpid
ast_flags ast_options = { AST_DEFAULT_OPTIONS }
static int ast_socket = -1
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 []
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 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 = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP }
static struct sigaction safe_system_prev_handler
static int shuttingdown
static int sig_alert_pipe [2] = { -1, -1 }
struct {
   unsigned int   need_quit:1
   unsigned int   need_reload:1
sig_flags
static struct sigaction urg_handler
static const char warranty_lines []


Detailed Description

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

Definition in file asterisk.c.


Define Documentation

#define AF_LOCAL   AF_UNIX

Definition at line 150 of file asterisk.c.

#define AST_MAX_CONNECTS   128

Definition at line 154 of file asterisk.c.

Referenced by ast_console_toggle_loglevel(), ast_console_toggle_mute(), ast_makesocket(), ast_network_puts(), ast_network_puts_mutable(), and listener().

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 2091 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 2093 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

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

Referenced by ast_el_add_history(), and ast_el_read_history().

#define NUM_MSGS   64

Definition at line 155 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

Definition at line 151 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 158 of file asterisk.c.

Referenced by ast_el_read_char(), and main().


Function Documentation

static void __quit_handler ( int  num  )  [static]

Definition at line 1713 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

01714 {
01715    int a = 0;
01716    sig_flags.need_quit = 1;
01717    if (sig_alert_pipe[1] != -1) {
01718       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01719          fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
01720       }
01721    }
01722    /* There is no need to restore the signal handler here, since the app
01723     * is going to exit */
01724 }

static void __remote_quit_handler ( int  num  )  [static]

Definition at line 1726 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

01727 {
01728    sig_flags.need_quit = 1;
01729 }

static void _child_handler ( int  sig  )  [static]

Definition at line 1494 of file asterisk.c.

References status.

01495 {
01496    /* Must not ever ast_log or ast_verbose within signal handler */
01497    int n, status;
01498 
01499    /*
01500     * Reap all dead children -- not just one
01501     */
01502    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01503       ;
01504    if (n == 0 && option_debug)   
01505       printf("Huh?  Child handler, but nobody there?\n");
01506 }

static void _hup_handler ( int  num  )  [static]

Definition at line 1474 of file asterisk.c.

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

01475 {
01476    int a = 0;
01477    if (option_verbose > 1) 
01478       printf("Received HUP signal -- Reloading configs\n");
01479    if (restartnow)
01480       execvp(_argv[0], _argv);
01481    sig_flags.need_reload = 1;
01482    if (sig_alert_pipe[1] != -1) {
01483       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01484          fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
01485       }
01486    }
01487 }

static void _null_sig_handler ( int  sig  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 980 of file asterisk.c.

00981 {
00982 
00983 }

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

01465 {
01466    return;
01467 }

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

support for event profiling

Returns:
Returns the identifier of the counter.

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

00692 {
00693    int l = sizeof(struct profile_data);
00694    int n = 10; /* default entries */
00695 
00696    if (prof_data == NULL) {
00697       prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
00698       if (prof_data == NULL)
00699          return -1;
00700       prof_data->entries = 0;
00701       prof_data->max_size = n;
00702    }
00703    if (prof_data->entries >= prof_data->max_size) {
00704       void *p;
00705       n = prof_data->max_size + 20;
00706       p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
00707       if (p == NULL)
00708          return -1;
00709       prof_data = p;
00710       prof_data->max_size = n;
00711    }
00712    n = prof_data->entries++;
00713    prof_data->e[n].name = ast_strdup(name);
00714    prof_data->e[n].value = 0;
00715    prof_data->e[n].events = 0;
00716    prof_data->e[n].mark = 0;
00717    prof_data->e[n].scale = scale;
00718    return n;
00719 }

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1773 of file asterisk.c.

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

01774 {
01775    while (*s) {
01776       if (*s > 32)
01777          return 0;
01778       s++;  
01779    }
01780    return 1;
01781 }

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

Definition at line 2399 of file asterisk.c.

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

Referenced by cli_complete().

02400 {
02401    int i, idx, limit, count;
02402    int screenwidth = 0;
02403    int numoutput = 0, numoutputline = 0;
02404 
02405    screenwidth = ast_get_termcols(STDOUT_FILENO);
02406 
02407    /* find out how many entries can be put on one line, with two spaces between strings */
02408    limit = screenwidth / (max + 2);
02409    if (limit == 0)
02410       limit = 1;
02411 
02412    /* how many lines of output */
02413    count = len / limit;
02414    if (count * limit < len)
02415       count++;
02416 
02417    idx = 1;
02418 
02419    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
02420 
02421    for (; count > 0; count--) {
02422       numoutputline = 0;
02423       for (i = 0; i < limit && matches[idx]; i++, idx++) {
02424 
02425          /* Don't print dupes */
02426          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
02427             i--;
02428             ast_free(matches[idx]);
02429             matches[idx] = NULL;
02430             continue;
02431          }
02432 
02433          numoutput++;
02434          numoutputline++;
02435          fprintf(stdout, "%-*s  ", max, matches[idx]);
02436          ast_free(matches[idx]);
02437          matches[idx] = NULL;
02438       }
02439       if (numoutputline > 0)
02440          fprintf(stdout, "\n");
02441    }
02442 
02443    return numoutput;
02444 }

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

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

00342 {
00343    struct file_version *find;
00344    size_t len = strlen(partial);
00345    int count = 0;
00346    char *res = NULL;
00347 
00348    AST_RWLIST_RDLOCK(&file_versions);
00349    AST_RWLIST_TRAVERSE(&file_versions, find, list) {
00350       if (!strncasecmp(find->file, partial, len) && ++count > n) {
00351          res = ast_strdup(find->file);
00352          break;
00353       }
00354    }
00355    AST_RWLIST_UNLOCK(&file_versions);
00356    return res;
00357 }

void ast_console_puts ( const char *  string  ) 

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

Definition at line 1162 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

01163 {
01164    fputs(string, stdout);
01165    fflush(stdout);
01166    ast_network_puts(string);
01167 }

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

References ast_network_puts_mutable().

Referenced by logger_print_normal().

01140 {
01141    fputs(string, stdout);
01142    fflush(stdout);
01143    ast_network_puts_mutable(string, level);
01144 }

void ast_console_toggle_loglevel ( int  fd,
int  level,
int  state 
)

Since:
1.6.1

Definition at line 1086 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and levels.

Referenced by handle_logger_set_level().

01087 {
01088    int x;
01089    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01090       if (fd == consoles[x].fd) {
01091          consoles[x].levels[level] = state;
01092          return;
01093       }
01094    }
01095 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1100 of file asterisk.c.

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

Referenced by handle_logger_mute().

01100                                                  {
01101    int x;
01102    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01103       if (fd == consoles[x].fd) {
01104          if (consoles[x].mute) {
01105             consoles[x].mute = 0;
01106             if (!silent)
01107                ast_cli(fd, "Console is not muted anymore.\n");
01108          } else {
01109             consoles[x].mute = 1;
01110             if (!silent)
01111                ast_cli(fd, "Console is muted.\n");
01112          }
01113          return;
01114       }
01115    }
01116    ast_cli(fd, "Couldn't find remote console.\n");
01117 }

static int ast_el_add_history ( char *   )  [static]

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

02603 {
02604    HistEvent ev;
02605 
02606    if (el_hist == NULL || el == NULL)
02607       ast_el_initialize();
02608    if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1))
02609       return 0;
02610    return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf))));
02611 }

static int ast_el_initialize ( void   )  [static]

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

02566 {
02567    HistEvent ev;
02568    char *editor = getenv("AST_EDITOR");
02569 
02570    if (el != NULL)
02571       el_end(el);
02572    if (el_hist != NULL)
02573       history_end(el_hist);
02574 
02575    el = el_init("asterisk", stdin, stdout, stderr);
02576    el_set(el, EL_PROMPT, cli_prompt);
02577 
02578    el_set(el, EL_EDITMODE, 1);      
02579    el_set(el, EL_EDITOR, editor ? editor : "emacs");     
02580    el_hist = history_init();
02581    if (!el || !el_hist)
02582       return -1;
02583 
02584    /* setup history with 100 entries */
02585    history(el_hist, &ev, H_SETSIZE, 100);
02586 
02587    el_set(el, EL_HIST, history, el_hist);
02588 
02589    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02590    /* Bind <tab> to command completion */
02591    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02592    /* Bind ? to command completion */
02593    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02594    /* Bind ^D to redisplay */
02595    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02596 
02597    return 0;
02598 }

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

Definition at line 2119 of file asterisk.c.

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

Referenced by ast_remotecontrol().

02120 {
02121    int num_read = 0;
02122    int lastpos = 0;
02123    struct pollfd fds[2];
02124    int res;
02125    int max;
02126 #define EL_BUF_SIZE 512
02127    char buf[EL_BUF_SIZE];
02128 
02129    for (;;) {
02130       max = 1;
02131       fds[0].fd = ast_consock;
02132       fds[0].events = POLLIN;
02133       if (!ast_opt_exec) {
02134          fds[1].fd = STDIN_FILENO;
02135          fds[1].events = POLLIN;
02136          max++;
02137       }
02138       res = ast_poll(fds, max, -1);
02139       if (res < 0) {
02140          if (sig_flags.need_quit)
02141             break;
02142          if (errno == EINTR)
02143             continue;
02144          ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
02145          break;
02146       }
02147 
02148       if (!ast_opt_exec && fds[1].revents) {
02149          num_read = read(STDIN_FILENO, cp, 1);
02150          if (num_read < 1) {
02151             break;
02152          } else 
02153             return (num_read);
02154       }
02155       if (fds[0].revents) {
02156          char *tmp;
02157          res = read(ast_consock, buf, sizeof(buf) - 1);
02158          /* if the remote side disappears exit */
02159          if (res < 1) {
02160             fprintf(stderr, "\nDisconnected from Asterisk server\n");
02161             if (!ast_opt_reconnect) {
02162                quit_handler(0, 0, 0, 0);
02163             } else {
02164                int tries;
02165                int reconnects_per_second = 20;
02166                fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
02167                for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
02168                   if (ast_tryconnect()) {
02169                      fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
02170                      printf("%s", term_quit());
02171                      WELCOME_MESSAGE;
02172                      if (!ast_opt_mute)
02173                         fdsend(ast_consock, "logger mute silent");
02174                      else 
02175                         printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02176                      break;
02177                   } else
02178                      usleep(1000000 / reconnects_per_second);
02179                }
02180                if (tries >= 30 * reconnects_per_second) {
02181                   fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
02182                   quit_handler(0, 0, 0, 0);
02183                }
02184             }
02185          }
02186 
02187          buf[res] = '\0';
02188 
02189          /* Strip preamble from asynchronous events, too */
02190          for (tmp = buf; *tmp; tmp++) {
02191             if (*tmp == 127) {
02192                memmove(tmp, tmp + 1, strlen(tmp));
02193                tmp--;
02194                res--;
02195             }
02196          }
02197 
02198          /* Write over the CLI prompt */
02199          if (!ast_opt_exec && !lastpos) {
02200             if (write(STDOUT_FILENO, "\r", 5) < 0) {
02201             }
02202          }
02203          if (write(STDOUT_FILENO, buf, res) < 0) {
02204          }
02205          if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
02206             *cp = CC_REFRESH;
02207             return(1);
02208          } else
02209             lastpos = 1;
02210       }
02211    }
02212 
02213    *cp = '\0';
02214    return (0);
02215 }

static int ast_el_read_history ( char *   )  [static]

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

02624 {
02625    char buf[MAX_HISTORY_COMMAND_LENGTH];
02626    FILE *f;
02627    int ret = -1;
02628 
02629    if (el_hist == NULL || el == NULL)
02630       ast_el_initialize();
02631 
02632    if ((f = fopen(filename, "r")) == NULL)
02633       return ret;
02634 
02635    while (!feof(f)) {
02636       if (!fgets(buf, sizeof(buf), f))
02637          break;
02638       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02639          continue;
02640       if (ast_all_zeros(buf))
02641          continue;
02642       if ((ret = ast_el_add_history(buf)) == -1)
02643          break;
02644    }
02645    fclose(f);
02646 
02647    return ret;
02648 }

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

Definition at line 2389 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02390 {
02391    char *s1, *s2;
02392 
02393    s1 = ((char **)i1)[0];
02394    s2 = ((char **)i2)[0];
02395 
02396    return strcasecmp(s1, s2);
02397 }

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

Definition at line 2346 of file asterisk.c.

References AST_CLI_COMPLETE_EOF, ast_free, ast_realloc, ast_strdup, and strsep().

Referenced by cli_complete().

02347 {
02348    char **match_list = NULL, **match_list_tmp, *retstr;
02349    size_t match_list_len;
02350    int matches = 0;
02351 
02352    match_list_len = 1;
02353    while ( (retstr = strsep(&buf, " ")) != NULL) {
02354 
02355       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
02356          break;
02357       if (matches + 1 >= match_list_len) {
02358          match_list_len <<= 1;
02359          if ((match_list_tmp = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
02360             match_list = match_list_tmp;
02361          } else {
02362             if (match_list)
02363                ast_free(match_list);
02364             return (char **) NULL;
02365          }
02366       }
02367 
02368       match_list[matches++] = ast_strdup(retstr);
02369    }
02370 
02371    if (!match_list)
02372       return (char **) NULL;
02373 
02374    if (matches >= match_list_len) {
02375       if ((match_list_tmp = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
02376          match_list = match_list_tmp;
02377       } else {
02378          if (match_list)
02379             ast_free(match_list);
02380          return (char **) NULL;
02381       }
02382    }
02383 
02384    match_list[matches] = (char *) NULL;
02385 
02386    return match_list;
02387 }

static int ast_el_write_history ( char *   )  [static]

Definition at line 2613 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by quit_handler().

02614 {
02615    HistEvent ev;
02616 
02617    if (el_hist == NULL || el == NULL)
02618       ast_el_initialize();
02619 
02620    return (history(el_hist, &ev, H_SAVE, filename));
02621 }

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

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

Referenced by manager_modulecheck().

00361 {
00362    struct file_version *iterator;
00363 
00364    AST_RWLIST_WRLOCK(&file_versions);
00365    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, iterator, list) {
00366       if (!strcasecmp(iterator->file, file))
00367          break;
00368    }
00369    AST_RWLIST_TRAVERSE_SAFE_END;
00370    AST_RWLIST_UNLOCK(&file_versions);
00371    if (iterator)
00372       return iterator->version;
00373    return NULL;
00374 }      

static int ast_makesocket ( void   )  [static]

Definition at line 1367 of file asterisk.c.

References AF_LOCAL, ast_config_AST_CTL_GROUP, ast_config_AST_CTL_OWNER, ast_config_AST_CTL_PERMISSIONS, ast_config_AST_SOCKET, ast_copy_string(), ast_log(), AST_MAX_CONNECTS, ast_pthread_create_background, ast_register_verbose(), ast_strlen_zero(), consoles, errno, listener(), LOG_WARNING, lthread, network_verboser(), and PF_LOCAL.

Referenced by main().

01368 {
01369    struct sockaddr_un sunaddr;
01370    int res;
01371    int x;
01372    uid_t uid = -1;
01373    gid_t gid = -1;
01374 
01375    for (x = 0; x < AST_MAX_CONNECTS; x++) 
01376       consoles[x].fd = -1;
01377    unlink(ast_config_AST_SOCKET);
01378    ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
01379    if (ast_socket < 0) {
01380       ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
01381       return -1;
01382    }     
01383    memset(&sunaddr, 0, sizeof(sunaddr));
01384    sunaddr.sun_family = AF_LOCAL;
01385    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01386    res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01387    if (res) {
01388       ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01389       close(ast_socket);
01390       ast_socket = -1;
01391       return -1;
01392    }
01393    res = listen(ast_socket, 2);
01394    if (res < 0) {
01395       ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01396       close(ast_socket);
01397       ast_socket = -1;
01398       return -1;
01399    }
01400    if (ast_register_verbose(network_verboser)) {
01401       ast_log(LOG_WARNING, "Unable to register network verboser?\n");
01402    }
01403 
01404    ast_pthread_create_background(&lthread, NULL, listener, NULL);
01405 
01406    if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
01407       struct passwd *pw;
01408       if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
01409          ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
01410       else
01411          uid = pw->pw_uid;
01412    }
01413       
01414    if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
01415       struct group *grp;
01416       if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
01417          ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
01418       else
01419          gid = grp->gr_gid;
01420    }
01421 
01422    if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
01423       ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01424 
01425    if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
01426       int p1;
01427       mode_t p;
01428       sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
01429       p = p1;
01430       if ((chmod(ast_config_AST_SOCKET, p)) < 0)
01431          ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01432    }
01433 
01434    return 0;
01435 }

int64_t ast_mark ( int  i,
int  startstop 
)

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

00757 {
00758    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00759       return 0;
00760    if (startstop == 1)
00761       prof_data->e[i].mark = rdtsc();
00762    else {
00763       prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
00764       if (prof_data->e[i].scale > 1)
00765          prof_data->e[i].mark /= prof_data->e[i].scale;
00766       prof_data->e[i].value += prof_data->e[i].mark;
00767       prof_data->e[i].events++;
00768    }
00769    return prof_data->e[i].mark;
00770 }

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

write the string to all attached console clients

Definition at line 1149 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

01150 {
01151    int x;
01152    for (x = 0; x < AST_MAX_CONNECTS; x++) {
01153       if (consoles[x].fd > -1) 
01154          fdprint(consoles[x].p[1], string);
01155    }
01156 }

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

log the string to all attached console clients

Definition at line 1122 of file asterisk.c.

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

Referenced by ast_console_puts_mutable(), and network_verboser().

01123 {
01124    int x;
01125    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01126       if (consoles[x].mute)
01127          continue;
01128       if (consoles[x].fd > -1) {
01129          if (!consoles[x].levels[level]) 
01130             fdprint(consoles[x].p[1], string);
01131       }
01132    }
01133 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 721 of file asterisk.c.

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

00722 {
00723    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00724       return 0;
00725    if (prof_data->e[i].scale > 1)
00726       delta /= prof_data->e[i].scale;
00727    prof_data->e[i].value += delta;
00728    prof_data->e[i].events++;
00729    return prof_data->e[i].value;
00730 }

static void ast_readconfig ( void   )  [static]

Definition at line 2840 of file asterisk.c.

References _cfg_paths::agi_dir, 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_load2(), ast_copy_string(), ast_eid_default, ast_log(), ast_opt_override_config, ast_set_default_eid(), ast_variable_browse(), cfg_paths, config, _cfg_paths::config_dir, CONFIG_FLAG_NOREALTIME, config_flags, 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, hostname, _cfg_paths::key_dir, _cfg_paths::log_dir, LOG_WARNING, 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::socket_path, _cfg_paths::spool_dir, ast_variable::value, and _cfg_paths::var_dir.

Referenced by main().

02841 {
02842    struct ast_config *cfg;
02843    struct ast_variable *v;
02844    char *config = DEFAULT_CONFIG_FILE;
02845    char hostname[MAXHOSTNAMELEN] = "";
02846    struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME };
02847    struct {
02848       unsigned int dbdir:1;
02849       unsigned int keydir:1;
02850    } found = { 0, 0 };
02851 
02852    if (ast_opt_override_config) {
02853       cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
02854       if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
02855          ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
02856    } else 
02857       cfg = ast_config_load2(config, "" /* core, can't reload */, config_flags);
02858 
02859    /* init with buildtime config */
02860    ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir));
02861    ast_copy_string(cfg_paths.spool_dir, DEFAULT_SPOOL_DIR, sizeof(cfg_paths.spool_dir));
02862    ast_copy_string(cfg_paths.module_dir, DEFAULT_MODULE_DIR, sizeof(cfg_paths.module_dir));
02863    snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", cfg_paths.spool_dir);
02864    ast_copy_string(cfg_paths.var_dir, DEFAULT_VAR_DIR, sizeof(cfg_paths.var_dir));
02865    ast_copy_string(cfg_paths.data_dir, DEFAULT_DATA_DIR, sizeof(cfg_paths.data_dir));
02866    ast_copy_string(cfg_paths.log_dir, DEFAULT_LOG_DIR, sizeof(cfg_paths.log_dir));
02867    ast_copy_string(cfg_paths.agi_dir, DEFAULT_AGI_DIR, sizeof(cfg_paths.agi_dir));
02868    ast_copy_string(cfg_paths.db_path, DEFAULT_DB, sizeof(cfg_paths.db_path));
02869    ast_copy_string(cfg_paths.key_dir, DEFAULT_KEY_DIR, sizeof(cfg_paths.key_dir));
02870    ast_copy_string(cfg_paths.pid_path, DEFAULT_PID, sizeof(cfg_paths.pid_path));
02871    ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path));
02872    ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir));
02873 
02874    ast_set_default_eid(&ast_eid_default);
02875 
02876    /* no asterisk.conf? no problem, use buildtime config! */
02877    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
02878       return;
02879    }
02880 
02881    for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
02882       if (!strcasecmp(v->name, "astctlpermissions"))
02883          ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
02884       else if (!strcasecmp(v->name, "astctlowner"))
02885          ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
02886       else if (!strcasecmp(v->name, "astctlgroup"))
02887          ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
02888       else if (!strcasecmp(v->name, "astctl"))
02889          ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
02890    }
02891 
02892    for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
02893       if (!strcasecmp(v->name, "astetcdir")) {
02894          ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir));
02895       } else if (!strcasecmp(v->name, "astspooldir")) {
02896          ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir));
02897          snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value);
02898       } else if (!strcasecmp(v->name, "astvarlibdir")) {
02899          ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir));
02900          if (!found.dbdir)
02901             snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
02902       } else if (!strcasecmp(v->name, "astdbdir")) {
02903          snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
02904          found.dbdir = 1;
02905       } else if (!strcasecmp(v->name, "astdatadir")) {
02906          ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir));
02907          if (!found.keydir)
02908             snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
02909       } else if (!strcasecmp(v->name, "astkeydir")) {
02910          snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
02911          found.keydir = 1;
02912       } else if (!strcasecmp(v->name, "astlogdir")) {
02913          ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir));
02914       } else if (!strcasecmp(v->name, "astagidir")) {
02915          ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir));
02916       } else if (!strcasecmp(v->name, "astrundir")) {
02917          snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid");
02918          snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", v->value, ast_config_AST_CTL);
02919          ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir));
02920       } else if (!strcasecmp(v->name, "astmoddir")) {
02921          ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir));
02922       }
02923    }
02924 
02925    for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
02926       /* verbose level (-v at startup) */
02927       if (!strcasecmp(v->name, "verbose")) {
02928          option_verbose = atoi(v->value);
02929       /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
02930       } else if (!strcasecmp(v->name, "timestamp")) {
02931          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
02932       /* whether or not to support #exec in config files */
02933       } else if (!strcasecmp(v->name, "execincludes")) {
02934          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
02935       /* debug level (-d at startup) */
02936       } else if (!strcasecmp(v->name, "debug")) {
02937          option_debug = 0;
02938          if (sscanf(v->value, "%30d", &option_debug) != 1) {
02939             option_debug = ast_true(v->value);
02940          }
02941 #if HAVE_WORKING_FORK
02942       /* Disable forking (-f at startup) */
02943       } else if (!strcasecmp(v->name, "nofork")) {
02944          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
02945       /* Always fork, even if verbose or debug are enabled (-F at startup) */
02946       } else if (!strcasecmp(v->name, "alwaysfork")) {
02947          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
02948 #endif
02949       /* Run quietly (-q at startup ) */
02950       } else if (!strcasecmp(v->name, "quiet")) {
02951          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
02952       /* Run as console (-c at startup, implies nofork) */
02953       } else if (!strcasecmp(v->name, "console")) {
02954          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
02955       /* Run with high priority if the O/S permits (-p at startup) */
02956       } else if (!strcasecmp(v->name, "highpriority")) {
02957          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
02958       /* Initialize RSA auth keys (IAX2) (-i at startup) */
02959       } else if (!strcasecmp(v->name, "initcrypto")) {
02960          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
02961       /* Disable ANSI colors for console (-c at startup) */
02962       } else if (!strcasecmp(v->name, "nocolor")) {
02963          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
02964       /* Disable some usage warnings for picky people :p */
02965       } else if (!strcasecmp(v->name, "dontwarn")) {
02966          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
02967       /* Dump core in case of crash (-g) */
02968       } else if (!strcasecmp(v->name, "dumpcore")) {
02969          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
02970       /* Cache recorded sound files to another directory during recording */
02971       } else if (!strcasecmp(v->name, "cache_record_files")) {
02972          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
02973       /* Specify cache directory */
02974       }  else if (!strcasecmp(v->name, "record_cache_dir")) {
02975          ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
02976       /* Build transcode paths via SLINEAR, instead of directly */
02977       } else if (!strcasecmp(v->name, "transcode_via_sln")) {
02978          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
02979       /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
02980       } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
02981          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
02982       /* Enable internal timing */
02983       } else if (!strcasecmp(v->name, "internal_timing")) {
02984          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING);
02985       } else if (!strcasecmp(v->name, "maxcalls")) {
02986          if ((sscanf(v->value, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
02987             option_maxcalls = 0;
02988          }
02989       } else if (!strcasecmp(v->name, "maxload")) {
02990          double test[1];
02991 
02992          if (getloadavg(test, 1) == -1) {
02993             ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
02994             option_maxload = 0.0;
02995          } else if ((sscanf(v->value, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
02996             option_maxload = 0.0;
02997          }
02998       /* Set the maximum amount of open files */
02999       } else if (!strcasecmp(v->name, "maxfiles")) {
03000          option_maxfiles = atoi(v->value);
03001          set_ulimit(option_maxfiles);
03002       /* What user to run as */
03003       } else if (!strcasecmp(v->name, "runuser")) {
03004          ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user));
03005       /* What group to run as */
03006       } else if (!strcasecmp(v->name, "rungroup")) {
03007          ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group));
03008       } else if (!strcasecmp(v->name, "systemname")) {
03009          ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name));
03010       } else if (!strcasecmp(v->name, "autosystemname")) {
03011          if (ast_true(v->value)) {
03012             if (!gethostname(hostname, sizeof(hostname) - 1))
03013                ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name));
03014             else {
03015                if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){
03016                   ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name));
03017                }
03018                ast_log(LOG_ERROR, "Cannot obtain hostname for this system.  Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME);
03019             }
03020          }
03021       } else if (!strcasecmp(v->name, "languageprefix")) {
03022          ast_language_is_prefix = ast_true(v->value);
03023       } else if (!strcasecmp(v->name, "lockmode")) {
03024          if (!strcasecmp(v->value, "lockfile")) {
03025             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03026          } else if (!strcasecmp(v->value, "flock")) {
03027             ast_set_lock_type(AST_LOCK_TYPE_FLOCK);
03028          } else {
03029             ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, "
03030                "defaulting to 'lockfile'\n", v->value);
03031             ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
03032          }
03033 #if defined(HAVE_SYSINFO)
03034       } else if (!strcasecmp(v->name, "minmemfree")) {
03035          /* specify the minimum amount of free memory to retain.  Asterisk should stop accepting new calls
03036           * if the amount of free memory falls below this watermark */
03037          if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
03038             option_minmemfree = 0;
03039          }
03040 #endif
03041       } else if (!strcasecmp(v->name, "entityid")) {
03042          struct ast_eid tmp_eid;
03043          if (!ast_str_to_eid(&tmp_eid, v->value)) {
03044             ast_verbose("Successfully set global EID to '%s'\n", v->value);
03045             ast_eid_default = tmp_eid;
03046          } else
03047             ast_verbose("Invalid Entity ID '%s' provided\n", v->value);
03048       } else if (!strcasecmp(v->name, "lightbackground")) {
03049          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND);
03050       } else if (!strcasecmp(v->name, "forceblackbackground")) {
03051          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03052       } else if (!strcasecmp(v->name, "hideconnect")) {
03053          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT);
03054       } else if (!strcasecmp(v->name, "lockconfdir")) {
03055          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LOCK_CONFIG_DIR);
03056       }
03057    }
03058    for (v = ast_variable_browse(cfg, "compat"); v; v = v->next) {
03059       float version;
03060       if (sscanf(v->value, "%30f", &version) != 1) {
03061          ast_log(LOG_WARNING, "Compatibility version for option '%s' is not a number: '%s'\n", v->name, v->value);
03062          continue;
03063       }
03064       if (!strcasecmp(v->name, "app_set")) {
03065          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_APP_SET);
03066       } else if (!strcasecmp(v->name, "res_agi")) {
03067          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_RES_AGI);
03068       } else if (!strcasecmp(v->name, "pbx_realtime")) {
03069          ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_PBX_REALTIME);
03070       }
03071    }
03072    ast_config_destroy(cfg);
03073 }

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

References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_unregister_atexit(), and ast_atexit::list.

Referenced by ast_cel_engine_init(), do_reload(), load_module(), and main().

00933 {
00934    struct ast_atexit *ae;
00935 
00936    if (!(ae = ast_calloc(1, sizeof(*ae))))
00937       return -1;
00938 
00939    ae->func = func;
00940 
00941    ast_unregister_atexit(func);  
00942 
00943    AST_RWLIST_WRLOCK(&atexits);
00944    AST_RWLIST_INSERT_HEAD(&atexits, ae, list);
00945    AST_RWLIST_UNLOCK(&atexits);
00946 
00947    return 0;
00948 }

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

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

00303 {
00304    struct file_version *new;
00305    char *work;
00306    size_t version_length;
00307 
00308    work = ast_strdupa(version);
00309    work = ast_strip(ast_strip_quoted(work, "$", "$"));
00310    version_length = strlen(work) + 1;
00311    
00312    if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
00313       return;
00314 
00315    new->file = file;
00316    new->version = (char *) new + sizeof(*new);
00317    memcpy(new->version, work, version_length);
00318    AST_RWLIST_WRLOCK(&file_versions);
00319    AST_RWLIST_INSERT_HEAD(&file_versions, new, list);
00320    AST_RWLIST_UNLOCK(&file_versions);
00321 }

void ast_register_thread ( char *  name  ) 

Definition at line 386 of file asterisk.c.

References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_atexit::list.

Referenced by dummy_start().

00387 { 
00388    struct thread_list_t *new = ast_calloc(1, sizeof(*new));
00389 
00390    if (!new)
00391       return;
00392    new->id = pthread_self();
00393    new->name = name; /* steal the allocated memory for the thread name */
00394    AST_RWLIST_WRLOCK(&thread_list);
00395    AST_RWLIST_INSERT_HEAD(&thread_list, new, list);
00396    AST_RWLIST_UNLOCK(&thread_list);
00397 }

static void ast_remotecontrol ( char *  data  )  [static]

Definition at line 2650 of file asterisk.c.

References __remote_quit_handler(), 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, strsep(), and version.

Referenced by main().

02651 {
02652    char buf[80];
02653    int res;
02654    char filename[80] = "";
02655    char *hostname;
02656    char *cpid;
02657    char *version;
02658    int pid;
02659    char *stringp = NULL;
02660 
02661    char *ebuf;
02662    int num = 0;
02663 
02664    memset(&sig_flags, 0, sizeof(sig_flags));
02665    signal(SIGINT, __remote_quit_handler);
02666    signal(SIGTERM, __remote_quit_handler);
02667    signal(SIGHUP, __remote_quit_handler);
02668 
02669    if (read(ast_consock, buf, sizeof(buf)) < 0) {
02670       ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02671       return;
02672    }
02673    if (data) {
02674       char prefix[] = "cli quit after ";
02675       char *tmp = alloca(strlen(data) + strlen(prefix) + 1);
02676       sprintf(tmp, "%s%s", prefix, data);
02677       if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
02678          ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
02679          if (sig_flags.need_quit == 1) {
02680             return;
02681          }
02682       }
02683    }
02684    stringp = buf;
02685    hostname = strsep(&stringp, "/");
02686    cpid = strsep(&stringp, "/");
02687    version = strsep(&stringp, "\n");
02688    if (!version)
02689       version = "<Version Unknown>";
02690    stringp = hostname;
02691    strsep(&stringp, ".");
02692    if (cpid)
02693       pid = atoi(cpid);
02694    else
02695       pid = -1;
02696    if (!data) {
02697       char tmp[80];
02698       snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
02699       fdsend(ast_consock, tmp);
02700       snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
02701       fdsend(ast_consock, tmp);
02702       if (!ast_opt_mute)
02703          fdsend(ast_consock, "logger mute silent");
02704       else 
02705          printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02706    }
02707 
02708    if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
02709       struct pollfd fds;
02710       fds.fd = ast_consock;
02711       fds.events = POLLIN;
02712       fds.revents = 0;
02713       while (ast_poll(&fds, 1, 60000) > 0) {
02714          char buffer[512] = "", *curline = buffer, *nextline;
02715          int not_written = 1;
02716 
02717          if (sig_flags.need_quit == 1) {
02718             break;
02719          }
02720 
02721          if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
02722             break;
02723          }
02724 
02725          do {
02726             if ((nextline = strchr(curline, '\n'))) {
02727                nextline++;
02728             } else {
02729                nextline = strchr(curline, '\0');
02730             }
02731 
02732             /* Skip verbose lines */
02733             if (*curline != 127) {
02734                not_written = 0;
02735                if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
02736                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
02737                }
02738             }
02739             curline = nextline;
02740          } while (!ast_strlen_zero(curline));
02741 
02742          /* No non-verbose output in 60 seconds. */
02743          if (not_written) {
02744             break;
02745          }
02746       }
02747       return;
02748    }
02749 
02750    ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
02751    remotehostname = hostname;
02752    if (getenv("HOME")) 
02753       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
02754    if (el_hist == NULL || el == NULL)
02755       ast_el_initialize();
02756 
02757    el_set(el, EL_GETCFN, ast_el_read_char);
02758 
02759    if (!ast_strlen_zero(filename))
02760       ast_el_read_history(filename);
02761 
02762    for (;;) {
02763       ebuf = (char *)el_gets(el, &num);
02764 
02765       if (sig_flags.need_quit == 1) {
02766          break;
02767       }
02768 
02769       if (!ebuf && write(1, "", 1) < 0)
02770          break;
02771 
02772       if (!ast_strlen_zero(ebuf)) {
02773          if (ebuf[strlen(ebuf)-1] == '\n')
02774             ebuf[strlen(ebuf)-1] = '\0';
02775          if (!remoteconsolehandler(ebuf)) {
02776             /* Strip preamble from output */
02777             char *temp;
02778             for (temp = ebuf; *temp; temp++) {
02779                if (*temp == 127) {
02780                   memmove(temp, temp + 1, strlen(temp));
02781                   temp--;
02782                }
02783             }
02784             res = write(ast_consock, ebuf, strlen(ebuf) + 1);
02785             if (res < 1) {
02786                ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
02787                break;
02788             }
02789          }
02790       }
02791    }
02792    printf("\nDisconnected from Asterisk server\n");
02793 }

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

References ast_mutex_lock, ast_mutex_unlock, safe_system_level, and safe_system_lock.

Referenced by ast_safe_fork(), and ast_safe_system().

01001 {
01002    unsigned int level;
01003 
01004    ast_mutex_lock(&safe_system_lock);
01005    level = safe_system_level++;
01006 
01007    /* only replace the handler if it has not already been done */
01008    if (level == 0) {
01009       sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
01010    }
01011 
01012    ast_mutex_unlock(&safe_system_lock);
01013 }

static void ast_run_atexits ( void   )  [static]

Definition at line 1585 of file asterisk.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_atexit::func, and ast_atexit::list.

Referenced by quit_handler().

01586 {
01587    struct ast_atexit *ae;
01588    AST_RWLIST_RDLOCK(&atexits);
01589    AST_RWLIST_TRAVERSE(&atexits, ae, list) {
01590       if (ae->func) 
01591          ae->func();
01592    }
01593    AST_RWLIST_UNLOCK(&atexits);
01594 }

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

01031 {
01032    pid_t pid;
01033    int res;
01034    struct rusage rusage;
01035    int status;
01036 
01037 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
01038    ast_replace_sigchld();
01039 
01040 #ifdef HAVE_WORKING_FORK
01041    pid = fork();
01042 #else
01043    pid = vfork();
01044 #endif   
01045 
01046    if (pid == 0) {
01047 #ifdef HAVE_CAP
01048       cap_t cap = cap_from_text("cap_net_admin-eip");
01049 
01050       if (cap_set_proc(cap)) {
01051          /* Careful with order! Logging cannot happen after we close FDs */
01052          ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
01053       }
01054       cap_free(cap);
01055 #endif
01056 #ifdef HAVE_WORKING_FORK
01057       if (ast_opt_high_priority)
01058          ast_set_priority(0);
01059       /* Close file descriptors and launch system command */
01060       ast_close_fds_above_n(STDERR_FILENO);
01061 #endif
01062       execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
01063       _exit(1);
01064    } else if (pid > 0) {
01065       for (;;) {
01066          res = wait4(pid, &status, 0, &rusage);
01067          if (res > -1) {
01068             res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
01069             break;
01070          } else if (errno != EINTR) 
01071             break;
01072       }
01073    } else {
01074       ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
01075       res = -1;
01076    }
01077 
01078    ast_unreplace_sigchld();
01079 #else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */
01080    res = -1;
01081 #endif
01082 
01083    return res;
01084 }

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

References ast_log(), ast_verbose, LOG_WARNING, sched_setscheduler, and setpriority.

Referenced by ast_safe_system(), canary_thread(), icesencode(), launch_script(), main(), mp3play(), NBScatplay(), send_waveform_to_fd(), spawn_mp3(), and spawn_ras().

01552 {
01553    struct sched_param sched;
01554    memset(&sched, 0, sizeof(sched));
01555 #ifdef __linux__
01556    if (pri) {  
01557       sched.sched_priority = 10;
01558       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01559          ast_log(LOG_WARNING, "Unable to set high priority\n");
01560          return -1;
01561       } else
01562          if (option_verbose)
01563             ast_verbose("Set to realtime thread\n");
01564    } else {
01565       sched.sched_priority = 0;
01566       /* According to the manpage, these parameters can never fail. */
01567       sched_setscheduler(0, SCHED_OTHER, &sched);
01568    }
01569 #else
01570    if (pri) {
01571       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01572          ast_log(LOG_WARNING, "Unable to set high priority\n");
01573          return -1;
01574       } else
01575          if (option_verbose)
01576             ast_verbose("Set to high priority\n");
01577    } else {
01578       /* According to the manpage, these parameters can never fail. */
01579       setpriority(PRIO_PROCESS, 0, 0);
01580    }
01581 #endif
01582    return 0;
01583 }

static int ast_tryconnect ( void   )  [static]

Definition at line 1437 of file asterisk.c.

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

Referenced by ast_el_read_char(), and main().

01438 {
01439    struct sockaddr_un sunaddr;
01440    int res;
01441    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01442    if (ast_consock < 0) {
01443       ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
01444       return 0;
01445    }
01446    memset(&sunaddr, 0, sizeof(sunaddr));
01447    sunaddr.sun_family = AF_LOCAL;
01448    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01449    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01450    if (res) {
01451       close(ast_consock);
01452       ast_consock = -1;
01453       return 0;
01454    } else
01455       return 1;
01456 }

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

References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free, ast_atexit::func, and ast_atexit::list.

Referenced by ast_register_atexit(), do_reload(), and unload_module().

00951 {
00952    struct ast_atexit *ae = NULL;
00953 
00954    AST_RWLIST_WRLOCK(&atexits);
00955    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
00956       if (ae->func == func) {
00957          AST_RWLIST_REMOVE_CURRENT(list);
00958          break;
00959       }
00960    }
00961    AST_RWLIST_TRAVERSE_SAFE_END;
00962    AST_RWLIST_UNLOCK(&atexits);
00963 
00964    free(ae);
00965 }

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

00324 {
00325    struct file_version *find;
00326 
00327    AST_RWLIST_WRLOCK(&file_versions);
00328    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
00329       if (!strcasecmp(find->file, file)) {
00330          AST_RWLIST_REMOVE_CURRENT(list);
00331          break;
00332       }
00333    }
00334    AST_RWLIST_TRAVERSE_SAFE_END;
00335    AST_RWLIST_UNLOCK(&file_versions);
00336 
00337    if (find)
00338       ast_free(find);
00339 }

void ast_unregister_thread ( void *  id  ) 

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

00400 {
00401    struct thread_list_t *x;
00402 
00403    AST_RWLIST_WRLOCK(&thread_list);
00404    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
00405       if ((void *) x->id == id) {
00406          AST_RWLIST_REMOVE_CURRENT(list);
00407          break;
00408       }
00409    }
00410    AST_RWLIST_TRAVERSE_SAFE_END;
00411    AST_RWLIST_UNLOCK(&thread_list);
00412    if (x) {
00413       ast_free(x->name);
00414       ast_free(x);
00415    }
00416 }

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

References ast_mutex_lock, ast_mutex_unlock, safe_system_level, and safe_system_lock.

Referenced by ast_safe_fork_cleanup(), and ast_safe_system().

01016 {
01017    unsigned int level;
01018 
01019    ast_mutex_lock(&safe_system_lock);
01020    level = --safe_system_level;
01021 
01022    /* only restore the handler if we are the last one */
01023    if (level == 0) {
01024       sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
01025    }
01026 
01027    ast_mutex_unlock(&safe_system_lock);
01028 }

static void canary_exit ( void   )  [static]

Definition at line 3119 of file asterisk.c.

References canary_pid.

Referenced by main().

03120 {
03121    if (canary_pid > 0)
03122       kill(canary_pid, SIGKILL);
03123 }

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

Definition at line 3096 of file asterisk.c.

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

Referenced by main().

03097 {
03098    struct stat canary_stat;
03099    struct timeval now;
03100 
03101    /* Give the canary time to sing */
03102    sleep(120);
03103 
03104    for (;;) {
03105       stat(canary_filename, &canary_stat);
03106       now = ast_tvnow();
03107       if (now.tv_sec > canary_stat.st_mtime + 60) {
03108          ast_log(LOG_WARNING, "The canary is no more.  He has ceased to be!  He's expired and gone to meet his maker!  He's a stiff!  Bereft of life, he rests in peace.  His metabolic processes are now history!  He's off the twig!  He's kicked the bucket.  He's shuffled off his mortal coil, run down the curtain, and joined the bleeding choir invisible!!  THIS is an EX-CANARY.  (Reducing priority)\n");
03109          ast_set_priority(0);
03110          pthread_exit(NULL);
03111       }
03112 
03113       /* Check the canary once a minute */
03114       sleep(60);
03115    }
03116 }

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

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

02448 {
02449    int len = 0;
02450    char *ptr;
02451    int nummatches = 0;
02452    char **matches;
02453    int retval = CC_ERROR;
02454    char buf[2048], savechr;
02455    int res;
02456 
02457    LineInfo *lf = (LineInfo *)el_line(editline);
02458 
02459    savechr = *(char *)lf->cursor;
02460    *(char *)lf->cursor = '\0';
02461    ptr = (char *)lf->cursor;
02462    if (ptr) {
02463       while (ptr > lf->buffer) {
02464          if (isspace(*ptr)) {
02465             ptr++;
02466             break;
02467          }
02468          ptr--;
02469       }
02470    }
02471 
02472    len = lf->cursor - ptr;
02473 
02474    if (ast_opt_remote) {
02475       snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 
02476       fdsend(ast_consock, buf);
02477       res = read(ast_consock, buf, sizeof(buf) - 1);
02478       buf[res] = '\0';
02479       nummatches = atoi(buf);
02480 
02481       if (nummatches > 0) {
02482          char *mbuf;
02483          int mlen = 0, maxmbuf = 2048;
02484          /* Start with a 2048 byte buffer */       
02485          if (!(mbuf = ast_malloc(maxmbuf))) {
02486             lf->cursor[0] = savechr;
02487             return (char *)(CC_ERROR);
02488          }
02489          snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 
02490          fdsend(ast_consock, buf);
02491          res = 0;
02492          mbuf[0] = '\0';
02493          while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
02494             if (mlen + 1024 > maxmbuf) {
02495                /* Every step increment buffer 1024 bytes */
02496                maxmbuf += 1024;              
02497                if (!(mbuf = ast_realloc(mbuf, maxmbuf))) {
02498                   lf->cursor[0] = savechr;
02499                   return (char *)(CC_ERROR);
02500                }
02501             }
02502             /* Only read 1024 bytes at a time */
02503             res = read(ast_consock, mbuf + mlen, 1024);
02504             if (res > 0)
02505                mlen += res;
02506          }
02507          mbuf[mlen] = '\0';
02508 
02509          matches = ast_el_strtoarr(mbuf);
02510          ast_free(mbuf);
02511       } else
02512          matches = (char **) NULL;
02513    } else {
02514       char **p, *oldbuf=NULL;
02515       nummatches = 0;
02516       matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
02517       for (p = matches; p && *p; p++) {
02518          if (!oldbuf || strcmp(*p,oldbuf))
02519             nummatches++;
02520          oldbuf = *p;
02521       }
02522    }
02523 
02524    if (matches) {
02525       int i;
02526       int matches_num, maxlen, match_len;
02527 
02528       if (matches[0][0] != '\0') {
02529          el_deletestr(editline, (int) len);
02530          el_insertstr(editline, matches[0]);
02531          retval = CC_REFRESH;
02532       }
02533 
02534       if (nummatches == 1) {
02535          /* Found an exact match */
02536          el_insertstr(editline, " ");
02537          retval = CC_REFRESH;
02538       } else {
02539          /* Must be more than one match */
02540          for (i = 1, maxlen = 0; matches[i]; i++) {
02541             match_len = strlen(matches[i]);
02542             if (match_len > maxlen)
02543                maxlen = match_len;
02544          }
02545          matches_num = i - 1;
02546          if (matches_num >1) {
02547             fprintf(stdout, "\n");
02548             ast_cli_display_match_list(matches, nummatches, maxlen);
02549             retval = CC_REDISPLAY;
02550          } else { 
02551             el_insertstr(editline," ");
02552             retval = CC_REFRESH;
02553          }
02554       }
02555       for (i = 0; matches[i]; i++)
02556          ast_free(matches[i]);
02557       ast_free(matches);
02558    }
02559 
02560    lf->cursor[0] = savechr;
02561 
02562    return (char *)(long)retval;
02563 }

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

Definition at line 2219 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, getloadavg(), hostname, ast_atexit::list, MAXHOSTNAMELEN, prompt, remotehostname, and term_color_code().

Referenced by ast_el_initialize().

02220 {
02221    char tmp[100];
02222    char *pfmt;
02223    int color_used = 0;
02224    static int cli_prompt_changes = 0;
02225    char term_code[20];
02226    struct passwd *pw;
02227    struct group *gr;
02228 
02229    if (prompt == NULL) {
02230       prompt = ast_str_create(100);
02231    } else if (!cli_prompt_changes) {
02232       return ast_str_buffer(prompt);
02233    } else {
02234       ast_str_reset(prompt);
02235    }
02236 
02237    if ((pfmt = getenv("ASTERISK_PROMPT"))) {
02238       char *t = pfmt;
02239       struct timeval ts = ast_tvnow();
02240       while (*t != '\0') {
02241          if (*t == '%') {
02242             char hostname[MAXHOSTNAMELEN] = "";
02243             int i, which;
02244             struct ast_tm tm = { 0, };
02245             int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
02246 
02247             t++;
02248             switch (*t) {
02249             case 'C': /* color */
02250                t++;
02251                if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
02252                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)));
02253                   t += i - 1;
02254                } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
02255                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code)));
02256                   t += i - 1;
02257                }
02258 
02259                /* If the color has been reset correctly, then there's no need to reset it later */
02260                color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
02261                break;
02262             case 'd': /* date */
02263                if (ast_localtime(&ts, &tm, NULL)) {
02264                   ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
02265                   ast_str_append(&prompt, 0, "%s", tmp);
02266                   cli_prompt_changes++;
02267                }
02268                break;
02269             case 'g': /* group */
02270                if ((gr = getgrgid(getgid()))) {
02271                   ast_str_append(&prompt, 0, "%s", gr->gr_name);
02272                }
02273                break;
02274             case 'h': /* hostname */
02275                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02276                   ast_str_append(&prompt, 0, "%s", hostname);
02277                } else {
02278                   ast_str_append(&prompt, 0, "%s", "localhost");
02279                }
02280                break;
02281             case 'H': /* short hostname */
02282                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02283                   char *dotptr;
02284                   if ((dotptr = strchr(hostname, '.'))) {
02285                      *dotptr = '\0';
02286                   }
02287                   ast_str_append(&prompt, 0, "%s", hostname);
02288                } else {
02289                   ast_str_append(&prompt, 0, "%s", "localhost");
02290                }
02291                break;
02292 #ifdef HAVE_GETLOADAVG
02293             case 'l': /* load avg */
02294                t++;
02295                if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
02296                   double list[3];
02297                   getloadavg(list, 3);
02298                   ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
02299                   cli_prompt_changes++;
02300                }
02301                break;
02302 #endif
02303             case 's': /* Asterisk system name (from asterisk.conf) */
02304                ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
02305                break;
02306             case 't': /* time */
02307                if (ast_localtime(&ts, &tm, NULL)) {
02308                   ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
02309                   ast_str_append(&prompt, 0, "%s", tmp);
02310                   cli_prompt_changes++;
02311                }
02312                break;
02313             case 'u': /* username */
02314                if ((pw = getpwuid(getuid()))) {
02315                   ast_str_append(&prompt, 0, "%s", pw->pw_name);
02316                }
02317                break;
02318             case '#': /* process console or remote? */
02319                ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
02320                break;
02321             case '%': /* literal % */
02322                ast_str_append(&prompt, 0, "%c", '%');
02323                break;
02324             case '\0': /* % is last character - prevent bug */
02325                t--;
02326                break;
02327             }
02328          } else {
02329             ast_str_append(&prompt, 0, "%c", *t);
02330          }
02331          t++;
02332       }
02333       if (color_used) {
02334          /* Force colors back to normal at end */
02335          ast_str_append(&prompt, 0, "%s", term_color_code(term_code, 0, 0, sizeof(term_code)));
02336       }
02337    } else if (remotehostname) {
02338       ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname);
02339    } else {
02340       ast_str_set(&prompt, 0, "%s", ASTERISK_PROMPT);
02341    }
02342 
02343    return ast_str_buffer(prompt);   
02344 }

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

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

01749 {
01750    char tmp[80];
01751    const char *c = NULL;
01752 
01753    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01754        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01755        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01756        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
01757       fputs(tmp, stdout);
01758       fputs(c, stdout);
01759    } else {
01760       if (*s == 127) {
01761          s++;
01762       }
01763       fputs(s, stdout);
01764    }
01765 
01766    fflush(stdout);
01767    
01768    /* Wake up a poll()ing console */
01769    if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
01770       pthread_kill(consolethread, SIGURG);
01771 }

static void consolehandler ( char *  s  )  [static]

Definition at line 1783 of file asterisk.c.

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

Referenced by main().

01784 {
01785    printf("%s", term_end());
01786    fflush(stdout);
01787 
01788    /* Called when readline data is available */
01789    if (!ast_all_zeros(s))
01790       ast_el_add_history(s);
01791    /* The real handler for bang */
01792    if (s[0] == '!') {
01793       if (s[1])
01794          ast_safe_system(s+1);
01795       else
01796          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01797    } else 
01798       ast_cli_command(STDOUT_FILENO, s);
01799 }

static void env_init ( void   )  [static]

Definition at line 3153 of file asterisk.c.

References ast_build_date, ast_build_hostname, ast_build_kernel, ast_build_machine, ast_build_os, ast_build_user, ast_config_AST_SYSTEM_NAME, ast_get_version(), and setenv().

Referenced by main().

03154 {
03155    setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
03156    setenv("AST_BUILD_HOST", ast_build_hostname, 1);
03157    setenv("AST_BUILD_DATE", ast_build_date, 1);
03158    setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
03159    setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
03160    setenv("AST_BUILD_OS", ast_build_os, 1);
03161    setenv("AST_BUILD_USER", ast_build_user, 1);
03162    setenv("AST_VERSION", ast_get_version(), 1);
03163 }

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

Definition at line 974 of file asterisk.c.

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

00975 {
00976    return write(fd, s, strlen(s));
00977 }

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

Definition at line 968 of file asterisk.c.

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

00969 {
00970    return write(fd, s, strlen(s) + 1);
00971 }

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

Definition at line 1731 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01732 {
01733    const char *c;
01734 
01735    /* Check for verboser preamble */
01736    if (*s == 127) {
01737       s++;
01738    }
01739 
01740    if (!strncmp(s, cmp, strlen(cmp))) {
01741       c = s + strlen(cmp);
01742       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01743       return c;
01744    }
01745    return NULL;
01746 }

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

Definition at line 1975 of file asterisk.c.

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

01976 {
01977    switch (cmd) {
01978    case CLI_INIT:
01979       e->command = "core abort shutdown";
01980       e->usage = 
01981          "Usage: core abort shutdown\n"
01982          "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
01983          "       call operations.\n";
01984       return NULL;
01985    case CLI_GENERATE:
01986       return NULL;
01987    }
01988 
01989    if (a->argc != e->args)
01990       return CLI_SHOWUSAGE;
01991    ast_cancel_shutdown();
01992    shuttingdown = 0;
01993    return CLI_SUCCESS;
01994 }

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

Definition at line 1996 of file asterisk.c.

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

01997 {
01998    switch (cmd) {
01999    case CLI_INIT:
02000       e->command = "!";
02001       e->usage = 
02002          "Usage: !<command>\n"
02003          "       Executes a given shell command\n";
02004       return NULL;
02005    case CLI_GENERATE:
02006       return NULL;
02007    }
02008 
02009    return CLI_SUCCESS;
02010 }

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

Definition at line 820 of file asterisk.c.

References CLI_GENERATE, CLI_INIT, DEFINE_PROFILE_MIN_MAX_VALUES, profile_data::e, profile_entry::events, profile_entry::name, prof_data, and profile_entry::value.

00821 {
00822    int i, min, max;
00823    const char *search = NULL;
00824    switch (cmd) {
00825    case CLI_INIT:
00826       e->command = "core clear profile";
00827       e->usage = "Usage: core clear profile\n"
00828             "       clear profile information";
00829       return NULL;
00830    case CLI_GENERATE:
00831       return NULL;
00832    }
00833 
00834    if (prof_data == NULL)
00835       return 0;
00836 
00837    DEFINE_PROFILE_MIN_MAX_VALUES;
00838    for (i= min; i < max; i++) {
00839       if (!search || strstr(prof_data->e[i].name, search)) {
00840          prof_data->e[i].value = 0;
00841          prof_data->e[i].events = 0;
00842       }
00843    }
00844    return CLI_SUCCESS;
00845 }

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

Definition at line 1935 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(), and ast_cli_entry::usage.

01936 {
01937    switch (cmd) {
01938    case CLI_INIT:
01939       e->command = "core restart gracefully";
01940       e->usage = 
01941          "Usage: core restart gracefully\n"
01942          "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
01943          "       restart when all active calls have ended.\n";
01944       return NULL;
01945    case CLI_GENERATE:
01946       return NULL;
01947    }
01948 
01949    if (a->argc != e->args)
01950       return CLI_SHOWUSAGE;
01951    quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
01952    return CLI_SUCCESS;
01953 }

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

Definition at line 1915 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(), and ast_cli_entry::usage.

01916 {
01917    switch (cmd) {
01918    case CLI_INIT:
01919       e->command = "core restart now";
01920       e->usage = 
01921          "Usage: core restart now\n"
01922          "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
01923          "       restart.\n";
01924       return NULL;
01925    case CLI_GENERATE:
01926       return NULL;
01927    }
01928 
01929    if (a->argc != e->args)
01930       return CLI_SHOWUSAGE;
01931    quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */);
01932    return CLI_SUCCESS;
01933 }

static char* handle_restart_when_convenient ( 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_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, quit_handler(), and ast_cli_entry::usage.

01956 {
01957    switch (cmd) {
01958    case CLI_INIT:
01959       e->command = "core restart when convenient";
01960       e->usage = 
01961          "Usage: core restart when convenient\n"
01962          "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
01963       return NULL;
01964    case CLI_GENERATE:
01965       return NULL;
01966    }
01967 
01968    if (a->argc != e->args)
01969       return CLI_SHOWUSAGE;
01970    ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
01971    quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */);
01972    return CLI_SUCCESS;
01973 }

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

Definition at line 785 of file asterisk.c.

References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, DEFINE_PROFILE_MIN_MAX_VALUES, profile_data::e, profile_data::entries, ast_cli_args::fd, profile_data::max_size, and prof_data.

00786 {
00787    int i, min, max;
00788    const char *search = NULL;
00789    switch (cmd) {
00790    case CLI_INIT:
00791       e->command = "core show profile";
00792       e->usage = "Usage: core show profile\n"
00793             "       show profile information";
00794       return NULL;
00795    case CLI_GENERATE:
00796       return NULL;
00797    }
00798 
00799    if (prof_data == NULL)
00800       return 0;
00801 
00802    DEFINE_PROFILE_MIN_MAX_VALUES;
00803    ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
00804       prof_data->entries, prof_data->max_size);
00805    ast_cli(a->fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
00806          "Value", "Average", "Name");
00807    for (i = min; i < max; i++) {
00808       struct profile_entry *entry = &prof_data->e[i];
00809       if (!search || strstr(entry->name, search))
00810           ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
00811          i,
00812          (long)entry->scale,
00813          (long)entry->events, (long long)entry->value,
00814          (long long)(entry->events ? entry->value / entry->events : entry->value),
00815          entry->name);
00816    }
00817    return CLI_SUCCESS;
00818 }

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 419 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_options, 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.

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

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

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

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

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

00503 {
00504    int count = 0;
00505    struct thread_list_t *cur;
00506    switch (cmd) {
00507    case CLI_INIT:
00508       e->command = "core show threads";
00509       e->usage = 
00510          "Usage: core show threads\n"
00511          "       List threads currently active in the system.\n";
00512       return NULL;
00513    case CLI_GENERATE:
00514       return NULL;
00515    }
00516 
00517    AST_RWLIST_RDLOCK(&thread_list);
00518    AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
00519       ast_cli(a->fd, "%p %s\n", (void *)cur->id, cur->name);
00520       count++;
00521    }
00522         AST_RWLIST_UNLOCK(&thread_list);
00523    ast_cli(a->fd, "%d threads listed.\n", count);
00524    return CLI_SUCCESS;
00525 }

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

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

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

Definition at line 1875 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(), and ast_cli_entry::usage.

01876 {
01877    switch (cmd) {
01878    case CLI_INIT:
01879       e->command = "core stop gracefully";
01880       e->usage = 
01881          "Usage: core stop gracefully\n"
01882          "       Causes Asterisk to not accept new calls, and exit when all\n"
01883          "       active calls have terminated normally.\n";
01884       return NULL;
01885    case CLI_GENERATE:
01886       return NULL;
01887    }
01888 
01889    if (a->argc != e->args)
01890       return CLI_SHOWUSAGE;
01891    quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
01892    return CLI_SUCCESS;
01893 }

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

Definition at line 1856 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(), and ast_cli_entry::usage.

01857 {
01858    switch (cmd) {
01859    case CLI_INIT:
01860       e->command = "core stop now";
01861       e->usage = 
01862          "Usage: core stop now\n"
01863          "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
01864       return NULL;
01865    case CLI_GENERATE:
01866       return NULL;
01867    }
01868 
01869    if (a->argc != e->args)
01870       return CLI_SHOWUSAGE;
01871    quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */);
01872    return CLI_SUCCESS;
01873 }

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

Definition at line 1895 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(), and ast_cli_entry::usage.

01896 {
01897    switch (cmd) {
01898    case CLI_INIT:
01899       e->command = "core stop when convenient";
01900       e->usage = 
01901          "Usage: core stop when convenient\n"
01902          "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
01903       return NULL;
01904    case CLI_GENERATE:
01905       return NULL;
01906    }
01907 
01908    if (a->argc != e->args)
01909       return CLI_SHOWUSAGE;
01910    ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
01911    quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
01912    return CLI_SUCCESS;
01913 }

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

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

01826 {
01827    switch (cmd) {
01828    case CLI_INIT:
01829       e->command = "core show version";
01830       e->usage = 
01831          "Usage: core show version\n"
01832          "       Shows Asterisk version information.\n";
01833       return NULL;
01834    case CLI_GENERATE:
01835       return NULL;
01836    }
01837 
01838    if (a->argc != 3)
01839       return CLI_SHOWUSAGE;
01840    ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
01841       ast_get_version(), ast_build_user, ast_build_hostname,
01842       ast_build_machine, ast_build_os, ast_build_date);
01843    return CLI_SUCCESS;
01844 }

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

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

01291 {
01292    struct sockaddr_un sunaddr;
01293    int s;
01294    socklen_t len;
01295    int x;
01296    int flags;
01297    struct pollfd fds[1];
01298    for (;;) {
01299       if (ast_socket < 0)
01300          return NULL;
01301       fds[0].fd = ast_socket;
01302       fds[0].events = POLLIN;
01303       s = ast_poll(fds, 1, -1);
01304       pthread_testcancel();
01305       if (s < 0) {
01306          if (errno != EINTR)
01307             ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
01308          continue;
01309       }
01310       len = sizeof(sunaddr);
01311       s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
01312       if (s < 0) {
01313          if (errno != EINTR)
01314             ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
01315       } else {
01316 #if !defined(SO_PASSCRED)
01317          {
01318 #else
01319          int sckopt = 1;
01320          /* turn on socket credentials passing. */
01321          if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
01322             ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
01323          } else {
01324 #endif
01325             for (x = 0; x < AST_MAX_CONNECTS; x++) {
01326                if (consoles[x].fd >= 0) {
01327                   continue;
01328                }
01329                if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
01330                   ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
01331                   consoles[x].fd = -1;
01332                   fdprint(s, "Server failed to create pipe\n");
01333                   close(s);
01334                   break;
01335                }
01336                flags = fcntl(consoles[x].p[1], F_GETFL);
01337                fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
01338                consoles[x].fd = s;
01339                consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
01340                /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
01341                   to know if the user didn't send the credentials. */
01342                consoles[x].uid = -2;
01343                consoles[x].gid = -2;
01344                if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
01345                   ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
01346                   close(consoles[x].p[0]);
01347                   close(consoles[x].p[1]);
01348                   consoles[x].fd = -1;
01349                   fdprint(s, "Server failed to spawn thread\n");
01350                   close(s);
01351                }
01352                break;
01353             }
01354             if (x >= AST_MAX_CONNECTS) {
01355                fdprint(s, "No more connections allowed\n");
01356                ast_log(LOG_WARNING, "No more connections allowed\n");
01357                close(s);
01358             } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
01359                ast_verb(3, "Remote UNIX connection\n");
01360             }
01361          }
01362       }
01363    }
01364    return NULL;
01365 }

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

Definition at line 3165 of file asterisk.c.

References __ast_mm_init(), __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_history(), ast_enum_init(), ast_event_init(), ast_fd_init(), ast_FD_SETSIZE, 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_options, ast_pbx_init(), ast_process_pending_reloads(), ast_pthread_create_detached, ast_readconfig(), ast_register_atexit(), ast_register_verbose(), 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, cli_asterisk, COLOR_BLACK, COLOR_BRWHITE, _cfg_paths::config_file, console_verboser(), consolehandler(), consolethread, dnsmgr_init(), dnsmgr_start_refresh(), el, el_hist, env_init(), errno, EVENT_FLAG_SYSTEM, f, FD_SET, FD_ZERO, init_framer(), init_logger(), init_manager(), load_modules(), load_pbx(), LOG_ERROR, LOG_WARNING, manager_event, MAXHOSTNAMELEN, mon_sig_flags, monitor_sig_flags(), quit_handler(), randompool, read_config_maps(), register_config_cli(), run_startup_commands(), set_icon(), set_title(), show_cli_help(), show_version(), sig_alert_pipe, _cfg_paths::socket_path, tdd_init(), term_color(), term_end(), term_quit(), threadstorage_init(), and WELCOME_MESSAGE.

03166 {
03167    int c;
03168    char filename[80] = "";
03169    char hostname[MAXHOSTNAMELEN] = "";
03170    char tmp[80];
03171    char * xarg = NULL;
03172    int x;
03173    FILE *f;
03174    sigset_t sigs;
03175    int num;
03176    int isroot = 1, rundir_exists = 0;
03177    char *buf;
03178    const char *runuser = NULL, *rungroup = NULL;
03179    char *remotesock = NULL;
03180    int moduleresult;         /*!< Result from the module load subsystem */
03181    struct rlimit l;
03182 
03183    /* Remember original args for restart */
03184    if (argc > ARRAY_LEN(_argv) - 1) {
03185       fprintf(stderr, "Truncating argument size to %d\n", (int)ARRAY_LEN(_argv) - 1);
03186       argc = ARRAY_LEN(_argv) - 1;
03187    }
03188    for (x = 0; x < argc; x++)
03189       _argv[x] = argv[x];
03190    _argv[x] = NULL;
03191 
03192    if (geteuid() != 0)
03193       isroot = 0;
03194 
03195    /* if the progname is rasterisk consider it a remote console */
03196    if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
03197       ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03198    }
03199    if (gethostname(hostname, sizeof(hostname)-1))
03200       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
03201    ast_mainpid = getpid();
03202    ast_ulaw_init();
03203    ast_alaw_init();
03204    callerid_init();
03205    ast_builtins_init();
03206    ast_utils_init();
03207    tdd_init();
03208    ast_tps_init();
03209    ast_fd_init();
03210    ast_pbx_init();
03211 
03212    if (getenv("HOME")) 
03213       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
03214    /* Check for options */
03215    while ((c = getopt(argc, argv, "BC:cde:FfG:ghIiL:M:mnpqRrs:TtU:VvWXx:")) != -1) {
03216       /*!\note Please keep the ordering here to alphabetical, capital letters
03217        * first.  This will make it easier in the future to select unused
03218        * option flags for new features. */
03219       switch (c) {
03220       case 'B': /* Force black background */
03221          ast_set_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03222          ast_clear_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
03223          break;
03224       case 'X':
03225          ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES);
03226          break;
03227       case 'C':
03228          ast_copy_string(cfg_paths.config_file, optarg, sizeof(cfg_paths.config_file));
03229          ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
03230          break;
03231       case 'c':
03232          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
03233          break;
03234       case 'd':
03235          option_debug++;
03236          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03237          break;
03238 #if defined(HAVE_SYSINFO)
03239       case 'e':
03240          if ((sscanf(&optarg[1], "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
03241             option_minmemfree = 0;
03242          }
03243          break;
03244 #endif
03245 #if HAVE_WORKING_FORK
03246       case 'F':
03247          ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
03248          break;
03249       case 'f':
03250          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03251          break;
03252 #endif
03253       case 'G':
03254          rungroup = ast_strdupa(optarg);
03255          break;
03256       case 'g':
03257          ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
03258          break;
03259       case 'h':
03260          show_cli_help();
03261          exit(0);
03262       case 'I':
03263          ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING);
03264          break;
03265       case 'i':
03266          ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
03267          break;
03268       case 'L':
03269          if ((sscanf(optarg, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
03270             option_maxload = 0.0;
03271          }
03272          break;
03273       case 'M':
03274          if ((sscanf(optarg, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
03275             option_maxcalls = 0;
03276          }
03277          break;
03278       case 'm':
03279          ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
03280          break;
03281       case 'n':
03282          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
03283          break;
03284       case 'p':
03285          ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
03286          break;
03287       case 'q':
03288          ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
03289          break;
03290       case 'R':
03291          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
03292          break;
03293       case 'r':
03294          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03295          break;
03296       case 's':
03297          remotesock = ast_strdupa(optarg);
03298          break;
03299       case 'T':
03300          ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
03301          break;
03302       case 't':
03303          ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
03304          break;
03305       case 'U':
03306          runuser = ast_strdupa(optarg);
03307          break;
03308       case 'V':
03309          show_version();
03310          exit(0);
03311       case 'v':
03312          option_verbose++;
03313          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03314          break;
03315       case 'W': /* White background */
03316          ast_set_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
03317          ast_clear_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03318          break;
03319       case 'x':
03320          ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC);
03321          xarg = ast_strdupa(optarg);
03322          break;
03323       case '?':
03324          exit(1);
03325       }
03326    }
03327 
03328    if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
03329       if (ast_register_verbose(console_verboser)) {
03330          ast_log(LOG_WARNING, "Unable to register console verboser?\n");
03331       }
03332       WELCOME_MESSAGE;
03333    }
03334 
03335    if (ast_opt_console && !option_verbose) 
03336       ast_verbose("[ Booting...\n");
03337 
03338    /* For remote connections, change the name of the remote connection.
03339     * We do this for the benefit of init scripts (which need to know if/when
03340     * the main asterisk process has died yet). */
03341    if (ast_opt_remote) {
03342       strcpy(argv[0], "rasterisk");
03343       for (x = 1; x < argc; x++) {
03344          argv[x] = argv[0] + 10;
03345       }
03346    }
03347 
03348    if (ast_opt_console && !option_verbose) {
03349       ast_verbose("[ Reading Master Configuration ]\n");
03350    }
03351 
03352    ast_readconfig();
03353    env_init();
03354 
03355    if (ast_opt_remote && remotesock != NULL)
03356       ast_copy_string((char *) cfg_paths.socket_path, remotesock, sizeof(cfg_paths.socket_path));
03357 
03358    if (!ast_language_is_prefix && !ast_opt_remote)
03359       ast_log(LOG_WARNING, "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");
03360 
03361    if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
03362       ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
03363       ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
03364    }
03365 
03366    if (ast_opt_dump_core) {
03367       memset(&l, 0, sizeof(l));
03368       l.rlim_cur = RLIM_INFINITY;
03369       l.rlim_max = RLIM_INFINITY;
03370       if (setrlimit(RLIMIT_CORE, &l)) {
03371          ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
03372       }
03373    }
03374 
03375    if (getrlimit(RLIMIT_NOFILE, &l)) {
03376       ast_log(LOG_WARNING, "Unable to check file descriptor limit: %s\n", strerror(errno));
03377    }
03378 
03379 #if !defined(CONFIGURE_RAN_AS_ROOT)
03380    /* Check if select(2) will run with more file descriptors */
03381    do {
03382       int fd, fd2;
03383       ast_fdset readers;
03384       struct timeval tv = { 0, };
03385 
03386       if (l.rlim_cur <= FD_SETSIZE) {
03387          /* The limit of select()able FDs is irrelevant, because we'll never
03388           * open one that high. */
03389          break;
03390       }
03391 
03392       if (!(fd = open("/dev/null", O_RDONLY))) {
03393          ast_log(LOG_ERROR, "Cannot open a file descriptor at boot? %s\n", strerror(errno));
03394          break; /* XXX Should we exit() here? XXX */
03395       }
03396 
03397       fd2 = (l.rlim_cur > sizeof(readers) * 8 ? sizeof(readers) * 8 : l.rlim_cur) - 1;
03398       if (dup2(fd, fd2) < 0) {
03399          ast_log(LOG_WARNING, "Cannot open maximum file descriptor %d at boot? %s\n", fd2, strerror(errno));
03400          break;
03401       }
03402 
03403       FD_ZERO(&readers);
03404       FD_SET(fd2, &readers);
03405       if (ast_select(fd2 + 1, &readers, NULL, NULL, &tv) < 0) {
03406          ast_log(LOG_WARNING, "Maximum select()able file descriptor is %d\n", FD_SETSIZE);
03407       }
03408    } while (0);
03409 #elif defined(HAVE_VARIABLE_FDSET)
03410    ast_FD_SETSIZE = l.rlim_cur;
03411 #endif /* !defined(CONFIGURE_RAN_AS_ROOT) */
03412 
03413    if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
03414       rungroup = ast_config_AST_RUN_GROUP;
03415    if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
03416       runuser = ast_config_AST_RUN_USER;
03417 
03418    /* Must install this signal handler up here to ensure that if the canary
03419     * fails to execute that it doesn't kill the Asterisk process.
03420     */
03421    sigaction(SIGCHLD, &child_handler, NULL);
03422 
03423    /* It's common on some platforms to clear /var/run at boot.  Create the
03424     * socket file directory before we drop privileges. */
03425    if (mkdir(ast_config_AST_RUN_DIR, 0755)) {
03426       if (errno == EEXIST) {
03427          rundir_exists = 1;
03428       } else {
03429          ast_log(LOG_WARNING, "Unable to create socket file directory.  Remote consoles will not be able to connect! (%s)\n", strerror(x));
03430       }
03431    }
03432 
03433 #ifndef __CYGWIN__
03434 
03435    if (isroot) {
03436       ast_set_priority(ast_opt_high_priority);
03437    }
03438 
03439    if (isroot && rungroup) {
03440       struct group *gr;
03441       gr = getgrnam(rungroup);
03442       if (!gr) {
03443          ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
03444          exit(1);
03445       }
03446       if (!rundir_exists && chown(ast_config_AST_RUN_DIR, -1, gr->gr_gid)) {
03447          ast_log(LOG_WARNING, "Unable to chgrp run directory to %d (%s)\n", (int) gr->gr_gid, rungroup);
03448       }
03449       if (setgid(gr->gr_gid)) {
03450          ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
03451          exit(1);
03452       }
03453       if (setgroups(0, NULL)) {
03454          ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
03455          exit(1);
03456       }
03457       if (option_verbose)
03458          ast_verbose("Running as group '%s'\n", rungroup);
03459    }
03460 
03461    if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
03462 #ifdef HAVE_CAP
03463       int has_cap = 1;
03464 #endif /* HAVE_CAP */
03465       struct passwd *pw;
03466       pw = getpwnam(runuser);
03467       if (!pw) {
03468          ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
03469          exit(1);
03470       }
03471       if (chown(ast_config_AST_RUN_DIR, pw->pw_uid, -1)) {
03472          ast_log(LOG_WARNING, "Unable to chown run directory to %d (%s)\n", (int) pw->pw_uid, runuser);
03473       }
03474 #ifdef HAVE_CAP
03475       if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
03476          ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
03477          has_cap = 0;
03478       }
03479 #endif /* HAVE_CAP */
03480       if (!isroot && pw->pw_uid != geteuid()) {
03481          ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
03482          exit(1);
03483       }
03484       if (!rungroup) {
03485          if (setgid(pw->pw_gid)) {
03486             ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
03487             exit(1);
03488          }
03489          if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
03490             ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser);
03491             exit(1);
03492          }
03493       }
03494       if (setuid(pw->pw_uid)) {
03495          ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
03496          exit(1);
03497       }
03498       if (option_verbose)
03499          ast_verbose("Running as user '%s'\n", runuser);
03500 #ifdef HAVE_CAP
03501       if (has_cap) {
03502          cap_t cap;
03503 
03504          cap = cap_from_text("cap_net_admin=eip");
03505 
03506          if (cap_set_proc(cap))
03507             ast_log(LOG_WARNING, "Unable to install capabilities.\n");
03508 
03509          if (cap_free(cap))
03510             ast_log(LOG_WARNING, "Unable to drop capabilities.\n");
03511       }
03512 #endif /* HAVE_CAP */
03513    }
03514 
03515 #endif /* __CYGWIN__ */
03516 
03517 #ifdef linux
03518    if (geteuid() && ast_opt_dump_core) {
03519       if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
03520          ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
03521       }
03522    }
03523 #endif
03524 
03525    {
03526 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
03527 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
03528 #define eaccess euidaccess
03529 #endif
03530       char dir[PATH_MAX];
03531       if (!getcwd(dir, sizeof(dir)) || eaccess(dir, R_OK | X_OK | F_OK)) {
03532          ast_log(LOG_ERROR, "Unable to access the running directory (%s).  Changing to '/' for compatibility.\n", strerror(errno));
03533          /* If we cannot access the CWD, then we couldn't dump core anyway,
03534           * so chdir("/") won't break anything. */
03535          if (chdir("/")) {
03536             /* chdir(/) should never fail, so this ends up being a no-op */
03537             ast_log(LOG_ERROR, "chdir(\"/\") failed?!! %s\n", strerror(errno));
03538          }
03539       } else
03540 #endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */
03541       if (!ast_opt_no_fork && !ast_opt_dump_core) {
03542          /* Backgrounding, but no cores, so chdir won't break anything. */
03543          if (chdir("/")) {
03544             ast_log(LOG_ERROR, "Unable to chdir(\"/\") ?!! %s\n", strerror(errno));
03545          }
03546       }
03547    }
03548 
03549    ast_term_init();
03550    printf("%s", term_end());
03551    fflush(stdout);
03552 
03553    if (ast_opt_console && !option_verbose) 
03554       ast_verbose("[ Initializing Custom Configuration Options ]\n");
03555    /* custom config setup */
03556    register_config_cli();
03557    read_config_maps();
03558    
03559    if (ast_opt_console) {
03560       if (el_hist == NULL || el == NULL)
03561          ast_el_initialize();
03562 
03563       if (!ast_strlen_zero(filename))
03564          ast_el_read_history(filename);
03565    }
03566 
03567    if (ast_tryconnect()) {
03568       /* One is already running */
03569       if (ast_opt_remote) {
03570          if (ast_opt_exec) {
03571             ast_remotecontrol(xarg);
03572             quit_handler(0, 0, 0, 0);
03573             exit(0);
03574          }
03575          printf("%s", term_quit());
03576          ast_remotecontrol(NULL);
03577          quit_handler(0, 0, 0, 0);
03578          exit(0);
03579       } else {
03580          ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
03581          printf("%s", term_quit());
03582          exit(1);
03583       }
03584    } else if (ast_opt_remote || ast_opt_exec) {
03585       ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
03586       printf("%s", term_quit());
03587       exit(1);
03588    }
03589    /* Blindly write pid file since we couldn't connect */
03590    unlink(ast_config_AST_PID);
03591    f = fopen(ast_config_AST_PID, "w");
03592    if (f) {
03593       fprintf(f, "%ld\n", (long)getpid());
03594       fclose(f);
03595    } else
03596       ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
03597 
03598 #if HAVE_WORKING_FORK
03599    if (ast_opt_always_fork || !ast_opt_no_fork) {
03600 #ifndef HAVE_SBIN_LAUNCHD
03601       if (daemon(1, 0) < 0) {
03602          ast_log(LOG_ERROR, "daemon() failed: %s\n", strerror(errno));
03603       }
03604       ast_mainpid = getpid();
03605       /* Blindly re-write pid file since we are forking */
03606       unlink(ast_config_AST_PID);
03607       f = fopen(ast_config_AST_PID, "w");
03608       if (f) {
03609          fprintf(f, "%ld\n", (long)ast_mainpid);
03610          fclose(f);
03611       } else
03612          ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
03613 #else
03614       ast_log(LOG_WARNING, "Mac OS X detected.  Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
03615 #endif
03616    }
03617 #endif
03618 
03619    /* Spawning of astcanary must happen AFTER the call to daemon(3) */
03620    if (isroot && ast_opt_high_priority) {
03621       snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
03622 
03623       /* Don't let the canary child kill Asterisk, if it dies immediately */
03624       sigaction(SIGPIPE, &ignore_sig_handler, NULL);
03625 
03626       canary_pid = fork();
03627       if (canary_pid == 0) {
03628          char canary_binary[128], *lastslash, ppid[12];
03629 
03630          /* Reset signal handler */
03631          signal(SIGCHLD, SIG_DFL);
03632          signal(SIGPIPE, SIG_DFL);
03633 
03634          ast_close_fds_above_n(0);
03635          ast_set_priority(0);
03636          snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid);
03637 
03638          execlp("astcanary", "astcanary", canary_filename, ppid, (char *)NULL);
03639 
03640          /* If not found, try the same path as used to execute asterisk */
03641          ast_copy_string(canary_binary, argv[0], sizeof(canary_binary));
03642          if ((lastslash = strrchr(canary_binary, '/'))) {
03643             ast_copy_string(lastslash + 1, "astcanary", sizeof(canary_binary) + canary_binary - (lastslash + 1));
03644             execl(canary_binary, "astcanary", canary_filename, (char *)NULL);
03645          }
03646 
03647          /* Should never happen */
03648          _exit(1);
03649       } else if (canary_pid > 0) {
03650          pthread_t dont_care;
03651          ast_pthread_create_detached(&dont_care, NULL, canary_thread, NULL);
03652       }
03653 
03654       /* Kill the canary when we exit */
03655       ast_register_atexit(canary_exit);
03656    }
03657 
03658    if (ast_event_init()) {
03659       printf("%s", term_quit());
03660       exit(1);
03661    }
03662 
03663 #ifdef TEST_FRAMEWORK
03664    if (ast_test_init()) {
03665       printf("%s", term_quit());
03666       exit(1);
03667    }
03668 #endif
03669 
03670    ast_aoc_cli_init();
03671 
03672    ast_makesocket();
03673    sigemptyset(&sigs);
03674    sigaddset(&sigs, SIGHUP);
03675    sigaddset(&sigs, SIGTERM);
03676    sigaddset(&sigs, SIGINT);
03677    sigaddset(&sigs, SIGPIPE);
03678    sigaddset(&sigs, SIGWINCH);
03679    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
03680    sigaction(SIGURG, &urg_handler, NULL);
03681    signal(SIGINT, __quit_handler);
03682    signal(SIGTERM, __quit_handler);
03683    sigaction(SIGHUP, &hup_handler, NULL);
03684    sigaction(SIGPIPE, &ignore_sig_handler, NULL);
03685 
03686    /* ensure that the random number generators are seeded with a different value every time
03687       Asterisk is started
03688    */
03689    srand((unsigned int) getpid() + (unsigned int) time(NULL));
03690    initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
03691 
03692    if (init_logger()) {    /* Start logging subsystem */
03693       printf("%s", term_quit());
03694       exit(1);
03695    }
03696 
03697    threadstorage_init();
03698 
03699    astobj2_init();
03700 
03701    ast_autoservice_init();
03702 
03703    if (ast_timing_init()) {
03704       printf("%s", term_quit());
03705       exit(1);
03706    }
03707 
03708    if (ast_ssl_init()) {
03709       printf("%s", term_quit());
03710       exit(1);
03711    }
03712 
03713 #ifdef AST_XML_DOCS
03714    /* Load XML documentation. */
03715    ast_xmldoc_load_documentation();
03716 #endif
03717 
03718    /* initialize the data retrieval API */
03719    if (ast_data_init()) {
03720       printf ("%s", term_quit());
03721       exit(1);
03722    }
03723 
03724    ast_channels_init();
03725 
03726    if ((moduleresult = load_modules(1))) {      /* Load modules, pre-load only */
03727       printf("%s", term_quit());
03728       exit(moduleresult == -2 ? 2 : 1);
03729    }
03730 
03731    if (dnsmgr_init()) {    /* Initialize the DNS manager */
03732       printf("%s", term_quit());
03733       exit(1);
03734    }
03735 
03736    ast_http_init();     /* Start the HTTP server, if needed */
03737 
03738    if (init_manager()) {
03739       printf("%s", term_quit());
03740       exit(1);
03741    }
03742 
03743    if (ast_cdr_engine_init()) {
03744       printf("%s", term_quit());
03745       exit(1);
03746    }
03747 
03748    if (ast_cel_engine_init()) {
03749       printf("%s", term_quit());
03750       exit(1);
03751    }
03752 
03753    if (ast_device_state_engine_init()) {
03754       printf("%s", term_quit());
03755       exit(1);
03756    }
03757 
03758    ast_dsp_init();
03759    ast_udptl_init();
03760 
03761    if (ast_image_init()) {
03762       printf("%s", term_quit());
03763       exit(1);
03764    }
03765 
03766    if (ast_file_init()) {
03767       printf("%s", term_quit());
03768       exit(1);
03769    }
03770 
03771    if (load_pbx()) {
03772       printf("%s", term_quit());
03773       exit(1);
03774    }
03775 
03776    if (ast_indications_init()) {
03777       printf("%s", term_quit());
03778       exit(1);
03779    }
03780 
03781    ast_features_init();
03782 
03783    if (init_framer()) {
03784       printf("%s", term_quit());
03785       exit(1);
03786    }
03787 
03788    if (astdb_init()) {
03789       printf("%s", term_quit());
03790       exit(1);
03791    }
03792 
03793    if (ast_enum_init()) {
03794       printf("%s", term_quit());
03795       exit(1);
03796    }
03797 
03798    if (ast_cc_init()) {
03799       printf("%s", term_quit());
03800       exit(1);
03801    }
03802 
03803    if ((moduleresult = load_modules(0))) {      /* Load modules */
03804       printf("%s", term_quit());
03805       exit(moduleresult == -2 ? 2 : 1);
03806    }
03807 
03808    /* loads the cli_permissoins.conf file needed to implement cli restrictions. */
03809    ast_cli_perms_init(0);
03810 
03811    ast_stun_init();
03812 
03813    dnsmgr_start_refresh();
03814 
03815    /* We might have the option of showing a console, but for now just
03816       do nothing... */
03817    if (ast_opt_console && !option_verbose)
03818       ast_verbose(" ]\n");
03819    if (option_verbose || ast_opt_console)
03820       ast_verbose("%s", term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
03821    if (ast_opt_no_fork)
03822       consolethread = pthread_self();
03823 
03824    if (pipe(sig_alert_pipe))
03825       sig_alert_pipe[0] = sig_alert_pipe[1] = -1;
03826 
03827    ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
03828    manager_event(EVENT_FLAG_SYSTEM, "FullyBooted", "Status: Fully Booted\r\n");
03829 
03830    ast_process_pending_reloads();
03831 
03832    pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
03833 
03834 #ifdef __AST_DEBUG_MALLOC
03835    __ast_mm_init();
03836 #endif   
03837 
03838    ast_lastreloadtime = ast_startuptime = ast_tvnow();
03839    ast_cli_register_multiple(cli_asterisk, ARRAY_LEN(cli_asterisk));
03840 
03841    run_startup_commands();
03842 
03843    if (ast_opt_console) {
03844       /* Console stuff now... */
03845       /* Register our quit function */
03846       char title[256];
03847 
03848       ast_pthread_create_detached(&mon_sig_flags, NULL, monitor_sig_flags, NULL);
03849 
03850       set_icon("Asterisk");
03851       snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
03852       set_title(title);
03853 
03854       for (;;) {
03855          buf = (char *) el_gets(el, &num);
03856 
03857          if (!buf && write(1, "", 1) < 0)
03858             goto lostterm;
03859 
03860          if (buf) {
03861             if (buf[strlen(buf)-1] == '\n')
03862                buf[strlen(buf)-1] = '\0';
03863 
03864             consolehandler((char *)buf);
03865          } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
03866                strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) {
03867             /* Whoa, stdout disappeared from under us... Make /dev/null's */
03868             int fd;
03869             fd = open("/dev/null", O_RDWR);
03870             if (fd > -1) {
03871                dup2(fd, STDOUT_FILENO);
03872                dup2(fd, STDIN_FILENO);
03873             } else
03874                ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
03875             break;
03876          }
03877       }
03878    }
03879 
03880    monitor_sig_flags(NULL);
03881 
03882 lostterm:
03883    return 0;
03884 }

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

Definition at line 3075 of file asterisk.c.

References ast_module_reload(), ast_poll, quit_handler(), sig_alert_pipe, and sig_flags.

Referenced by main().

03076 {
03077    for (;;) {
03078       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
03079       int a;
03080       ast_poll(&p, 1, -1);
03081       if (sig_flags.need_reload) {
03082          sig_flags.need_reload = 0;
03083          ast_module_reload(NULL);
03084       }
03085       if (sig_flags.need_quit) {
03086          sig_flags.need_quit = 0;
03087          quit_handler(0, 0, 1, 0);
03088       }
03089       if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
03090       }
03091    }
03092 
03093    return NULL;
03094 }

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

Definition at line 1230 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, LOG_ERROR, LOG_WARNING, MAXHOSTNAMELEN, console::p, read_credentials(), and console::uid.

Referenced by listener().

01231 {
01232    struct console *con = vconsole;
01233    char hostname[MAXHOSTNAMELEN] = "";
01234    char tmp[512];
01235    int res;
01236    struct pollfd fds[2];
01237    
01238    if (gethostname(hostname, sizeof(hostname)-1))
01239       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
01240    snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
01241    fdprint(con->fd, tmp);
01242    for (;;) {
01243       fds[0].fd = con->fd;
01244       fds[0].events = POLLIN;
01245       fds[0].revents = 0;
01246       fds[1].fd = con->p[0];
01247       fds[1].events = POLLIN;
01248       fds[1].revents = 0;
01249 
01250       res = ast_poll(fds, 2, -1);
01251       if (res < 0) {
01252          if (errno != EINTR)
01253             ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
01254          continue;
01255       }
01256       if (fds[0].revents) {
01257          res = read_credentials(con->fd, tmp, sizeof(tmp) - 1, con);
01258          if (res < 1) {
01259             break;
01260          }
01261          tmp[res] = 0;
01262          if (strncmp(tmp, "cli quit after ", 15) == 0) {
01263             ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res - 15, tmp + 15);
01264             break;
01265          }
01266          ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res, tmp);
01267       }
01268       if (fds[1].revents) {
01269          res = read_credentials(con->p[0], tmp, sizeof(tmp), con);
01270          if (res < 1) {
01271             ast_log(LOG_ERROR, "read returned %d\n", res);
01272             break;
01273          }
01274          res = write(con->fd, tmp, res);
01275          if (res < 1)
01276             break;
01277       }
01278    }
01279    if (!ast_opt_hide_connect) {
01280       ast_verb(3, "Remote UNIX connection disconnected\n");
01281    }
01282    close(con->fd);
01283    close(con->p[0]);
01284    close(con->p[1]);
01285    con->fd = -1;
01286    
01287    return NULL;
01288 }

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

Definition at line 1169 of file asterisk.c.

References __LOG_VERBOSE, and ast_network_puts_mutable().

Referenced by ast_makesocket().

01170 {
01171    ast_network_puts_mutable(s, __LOG_VERBOSE);
01172 }

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

Definition at line 1596 of file asterisk.c.

References _argv, ast_active_channels(), ast_begin_shutdown(), ast_cdr_engine_term(), 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, close_logger(), consolethread, el, el_hist, EVENT_FLAG_SYSTEM, lthread, manager_event, mon_sig_flags, restartnow, shuttingdown, and term_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().

01597 {
01598    char filename[80] = "";
01599    time_t s,e;
01600    int x;
01601    /* Try to get as many CDRs as possible submitted to the backend engines (if in batch mode) */
01602    ast_cdr_engine_term();
01603    if (safeshutdown) {
01604       shuttingdown = 1;
01605       if (!niceness) {
01606          /* Begin shutdown routine, hanging up active channels */
01607          ast_begin_shutdown(1);
01608          if (option_verbose && ast_opt_console)
01609             ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
01610          time(&s);
01611          for (;;) {
01612             time(&e);
01613             /* Wait up to 15 seconds for all channels to go away */
01614             if ((e - s) > 15)
01615                break;
01616             if (!ast_active_channels())
01617                break;
01618             if (!shuttingdown)
01619                break;
01620             /* Sleep 1/10 of a second */
01621             usleep(100000);
01622          }
01623       } else {
01624          if (niceness < 2)
01625             ast_begin_shutdown(0);
01626          if (option_verbose && ast_opt_console)
01627             ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
01628          for (;;) {
01629             if (!ast_active_channels())
01630                break;
01631             if (!shuttingdown)
01632                break;
01633             sleep(1);
01634          }
01635       }
01636 
01637       if (!shuttingdown) {
01638          if (option_verbose && ast_opt_console)
01639             ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
01640          return;
01641       }
01642 
01643       if (niceness)
01644          ast_module_shutdown();
01645    }
01646    if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
01647       pthread_t thisthread = pthread_self();
01648       if (getenv("HOME")) {
01649          snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
01650       }
01651       if (!ast_strlen_zero(filename)) {
01652          ast_el_write_history(filename);
01653       }
01654       if (consolethread == AST_PTHREADT_NULL || consolethread == thisthread || mon_sig_flags == thisthread) {
01655          /* Only end if we are the consolethread or signal handler, otherwise there's a race with that thread. */
01656          if (el != NULL) {
01657             el_end(el);
01658          }
01659          if (el_hist != NULL) {
01660             history_end(el_hist);
01661          }
01662       }
01663    }
01664    if (option_verbose)
01665       ast_verbose("Executing last minute cleanups\n");
01666    ast_run_atexits();
01667    /* Called on exit */
01668    if (option_verbose && ast_opt_console)
01669       ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
01670    ast_debug(1, "Asterisk ending (%d).\n", num);
01671    manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
01672    if (ast_socket > -1) {
01673       pthread_cancel(lthread);
01674       close(ast_socket);
01675       ast_socket = -1;
01676       unlink(ast_config_AST_SOCKET);
01677    }
01678    if (ast_consock > -1)
01679       close(ast_consock);
01680    if (!ast_opt_remote)
01681       unlink(ast_config_AST_PID);
01682    printf("%s", term_quit());
01683    if (restart) {
01684       if (option_verbose || ast_opt_console)
01685          ast_verbose("Preparing for Asterisk restart...\n");
01686       /* Mark all FD's for closing on exec */
01687       for (x=3; x < 32768; x++) {
01688          fcntl(x, F_SETFD, FD_CLOEXEC);
01689       }
01690       if (option_verbose || ast_opt_console)
01691          ast_verbose("Asterisk is now restarting...\n");
01692       restartnow = 1;
01693 
01694       /* close logger */
01695       close_logger();
01696 
01697       /* If there is a consolethread running send it a SIGHUP 
01698          so it can execvp, otherwise we can do it ourselves */
01699       if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
01700          pthread_kill(consolethread, SIGHUP);
01701          /* Give the signal handler some time to complete */
01702          sleep(2);
01703       } else
01704          execvp(_argv[0], _argv);
01705    
01706    } else {
01707       /* close logger */
01708       close_logger();
01709    }
01710    exit(0);
01711 }

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 750 of file asterisk.c.

Referenced by ast_mark().

00751 {
00752    return 0;
00753 }

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

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

Referenced by netconsole().

01187 {
01188 #if defined(SO_PEERCRED)
01189    struct ucred cred;
01190    socklen_t len = sizeof(cred);
01191 #endif
01192 #if defined(HAVE_GETPEEREID)
01193    uid_t uid;
01194    gid_t gid;
01195 #else
01196    int uid, gid;
01197 #endif
01198    int result;
01199 
01200    result = read(fd, buffer, size);
01201    if (result < 0) {
01202       return result;
01203    }
01204 
01205 #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
01206    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
01207       return result;
01208    }
01209 #if defined(HAVE_STRUCT_UCRED_UID)
01210    uid = cred.uid;
01211    gid = cred.gid;
01212 #else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
01213    uid = cred.cr_uid;
01214    gid = cred.cr_gid;
01215 #endif /* defined(HAVE_STRUCT_UCRED_UID) */
01216 
01217 #elif defined(HAVE_GETPEEREID)
01218    if (getpeereid(fd, &uid, &gid)) {
01219       return result;
01220    }
01221 #else
01222    return result;
01223 #endif
01224    con->uid = uid;
01225    con->gid = gid;
01226 
01227    return result;
01228 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1801 of file asterisk.c.

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

Referenced by ast_remotecontrol().

01802 {
01803    int ret = 0;
01804 
01805    /* Called when readline data is available */
01806    if (!ast_all_zeros(s))
01807       ast_el_add_history(s);
01808    /* The real handler for bang */
01809    if (s[0] == '!') {
01810       if (s[1])
01811          ast_safe_system(s+1);
01812       else
01813          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01814       ret = 1;
01815    }
01816    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
01817        (s[4] == '\0' || isspace(s[4]))) {
01818       quit_handler(0, 0, 0, 0);
01819       ret = 1;
01820    }
01821 
01822    return ret;
01823 }

static void run_startup_commands ( void   )  [static]

Definition at line 3125 of file asterisk.c.

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

03126 {
03127    int fd;
03128    struct ast_config *cfg;
03129    struct ast_flags cfg_flags = { 0 };
03130    struct ast_variable *v;
03131 
03132    if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
03133       return;
03134    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03135       return;
03136    }
03137 
03138    fd = open("/dev/null", O_RDWR);
03139    if (fd < 0) {
03140       ast_config_destroy(cfg);
03141       return;
03142    }
03143 
03144    for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
03145       if (ast_true(v->value))
03146          ast_cli_command(fd, v->name);
03147    }
03148 
03149    close(fd);
03150    ast_config_destroy(cfg);
03151 }

static void set_icon ( char *  text  )  [static]

Definition at line 1543 of file asterisk.c.

Referenced by main().

01544 {
01545    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01546       fprintf(stdout, "\033]1;%s\007", text);
01547 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1537 of file asterisk.c.

Referenced by main().

01538 {
01539    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01540       fprintf(stdout, "\033]2;%s\007", text);
01541 }

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1514 of file asterisk.c.

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

01515 {
01516    struct rlimit l = {0, 0};
01517    
01518    if (value <= 0) {
01519       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01520       return;
01521    }
01522    
01523    l.rlim_cur = value;
01524    l.rlim_max = value;
01525    
01526    if (setrlimit(RLIMIT_NOFILE, &l)) {
01527       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01528       return;
01529    }
01530    
01531    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01532    
01533    return;
01534 }

static int show_cli_help ( void   )  [static]

Definition at line 2801 of file asterisk.c.

References ast_get_version().

Referenced by main().

02801                                {
02802    printf("Asterisk %s, Copyright (C) 1999 - 2010, Digium, Inc. and others.\n", ast_get_version());
02803    printf("Usage: asterisk [OPTIONS]\n");
02804    printf("Valid Options:\n");
02805    printf("   -V              Display version number and exit\n");
02806    printf("   -C <configfile> Use an alternate configuration file\n");
02807    printf("   -G <group>      Run as a group other than the caller\n");
02808    printf("   -U <user>       Run as a user other than the caller\n");
02809    printf("   -c              Provide console CLI\n");
02810    printf("   -d              Enable extra debugging\n");
02811 #if HAVE_WORKING_FORK
02812    printf("   -f              Do not fork\n");
02813    printf("   -F              Always fork\n");
02814 #endif
02815    printf("   -g              Dump core in case of a crash\n");
02816    printf("   -h              This help screen\n");
02817    printf("   -i              Initialize crypto keys at startup\n");
02818    printf("   -I              Enable internal timing if DAHDI timer is available\n");
02819    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
02820    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
02821    printf("   -m              Mute debugging and console output on the console\n");
02822    printf("   -n              Disable console colorization\n");
02823    printf("   -p              Run as pseudo-realtime thread\n");
02824    printf("   -q              Quiet mode (suppress output)\n");
02825    printf("   -r              Connect to Asterisk on this machine\n");
02826    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
02827    printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
02828    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
02829    printf("                   belong after they are done\n");
02830    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
02831    printf("                   of output to the CLI\n");
02832    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
02833    printf("   -x <cmd>        Execute command <cmd> (only valid with -r)\n");
02834    printf("   -X              Execute includes by default (allows #exec in asterisk.conf)\n");
02835    printf("   -W              Adjust terminal colors to compensate for a light background\n");
02836    printf("\n");
02837    return 0;
02838 }

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

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

02074 {
02075    switch (cmd) {
02076    case CLI_INIT:
02077       e->command = "core show license";
02078       e->usage = 
02079          "Usage: core show license\n"
02080          "       Shows the license(s) for this copy of Asterisk.\n";
02081       return NULL;
02082    case CLI_GENERATE:
02083       return NULL;
02084    }
02085 
02086    ast_cli(a->fd, "%s", license_lines);
02087 
02088    return CLI_SUCCESS;
02089 }

static int show_version ( void   )  [static]

Definition at line 2795 of file asterisk.c.

References ast_get_version().

Referenced by main().

02796 {
02797    printf("Asterisk %s\n", ast_get_version());
02798    return 0;
02799 }

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

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

02037 {
02038    switch (cmd) {
02039    case CLI_INIT:
02040       e->command = "core show warranty";
02041       e->usage = 
02042          "Usage: core show warranty\n"
02043          "       Shows the warranty (if any) for this copy of Asterisk.\n";
02044       return NULL;
02045    case CLI_GENERATE:
02046       return NULL;
02047    }
02048 
02049    ast_cli(a->fd, "%s", warranty_lines);
02050 
02051    return CLI_SUCCESS;
02052 }


Variable Documentation

char* _argv[256] [static]

Definition at line 277 of file asterisk.c.

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

const char* ast_config_AST_AGI_DIR = cfg_paths.agi_dir

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

Referenced by action_createconfig(), ast_module_reload(), compile_script(), config_text_file_load(), handle_cli_dialplan_save(), handle_show_settings(), ices_exec(), launch_script(), lua_read_extensions_file(), message_template_parse_filebody(), pbx_load_module(), and set_fn().

const char* ast_config_AST_CONFIG_FILE = cfg_paths.config_file

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

Referenced by ast_readconfig().

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

Definition at line 272 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

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

Definition at line 271 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static]

Definition at line 270 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

const char* ast_config_AST_DATA_DIR = cfg_paths.data_dir

Definition at line 257 of file asterisk.c.

Referenced by ast_linear_stream(), build_filename(), handle_show_settings(), launch_script(), make_filename(), moh_scan_files(), phoneprov_callback(), pp_each_extension_helper(), reload_firmware(), setup_privacy_args(), and static_callback().

const char* ast_config_AST_DB = cfg_paths.db_path

Definition at line 263 of file asterisk.c.

Referenced by dbinit(), and handle_show_settings().

const char* ast_config_AST_KEY_DIR = cfg_paths.key_dir

Definition at line 260 of file asterisk.c.

Referenced by crypto_load(), handle_cli_keys_init(), handle_show_settings(), launch_script(), and osp_create_provider().

const char* ast_config_AST_LOG_DIR = cfg_paths.log_dir

Definition at line 258 of file asterisk.c.

Referenced by apply_general_options(), csv_log(), dahdi_r2_set_context(), handle_show_settings(), init_logger(), launch_script(), load_config(), load_module(), make_logchannel(), OpenHistory(), reload_logger(), testclient_exec(), testserver_exec(), write_history(), and writefile().

const char* ast_config_AST_MODULE_DIR = cfg_paths.module_dir

Definition at line 253 of file asterisk.c.

Referenced by complete_fn(), handle_show_settings(), launch_script(), and load_dynamic_module().

const char* ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir

Definition at line 255 of file asterisk.c.

Referenced by ast_monitor_change_fname(), ast_monitor_start(), chanspy_exec(), extenspy_exec(), launch_script(), and mixmonitor_exec().

const char* ast_config_AST_PID = cfg_paths.pid_path

Definition at line 264 of file asterisk.c.

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

const char* ast_config_AST_RUN_DIR = cfg_paths.run_dir

Definition at line 261 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 267 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 266 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 265 of file asterisk.c.

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

const char* ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir

Definition at line 254 of file asterisk.c.

Referenced by app_exec(), conf_run(), dictate_exec(), handle_show_settings(), launch_script(), load_module(), sms_nextoutgoing(), and sms_writefile().

const char* ast_config_AST_SYSTEM_NAME = cfg_paths.system_name

Definition at line 268 of file asterisk.c.

Referenced by __ast_channel_alloc_ap(), __init_manager(), action_coresettings(), ast_str_retrieve_variable(), cli_prompt(), env_init(), handle_show_settings(), and realtime_update_peer().

const char* ast_config_AST_VAR_DIR = cfg_paths.var_dir

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

struct ast_eid ast_eid_default

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 188 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

Definition at line 214 of file asterisk.c.

Referenced by action_corestatus(), ast_module_reload(), ast_var_Config(), handle_show_settings(), handle_showuptime(), and main().

pid_t ast_mainpid

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

struct timeval ast_startuptime

Definition at line 213 of file asterisk.c.

Referenced by action_corestatus(), ast_var_Config(), handle_show_settings(), handle_showcalls(), handle_showuptime(), and main().

char canary_filename[128] [static]

Definition at line 283 of file asterisk.c.

Referenced by canary_thread(), and main().

int canary_pid = 0 [static]

Definition at line 282 of file asterisk.c.

Referenced by canary_exit(), and main().

struct _cfg_paths cfg_paths [static]

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

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 2095 of file asterisk.c.

Referenced by main().

struct console consoles[AST_MAX_CONNECTS]

Definition at line 220 of file asterisk.c.

Referenced by ast_console_toggle_loglevel(), ast_console_toggle_mute(), ast_makesocket(), ast_network_puts(), ast_network_puts_mutable(), and listener().

pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 280 of file asterisk.c.

Referenced by console_verboser(), main(), and quit_handler().

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 222 of file asterisk.c.

Referenced by __ast_channel_alloc_ap(), and handle_show_settings().

EditLine* el [static]

Definition at line 217 of file asterisk.c.

Referenced by __ast_internal_context_destroy(), add_pri(), ast_add_extension2_lockopt(), ast_el_add_history(), ast_el_initialize(), ast_el_read_history(), ast_el_write_history(), ast_remotecontrol(), handle_cli_dialplan_save(), main(), quit_handler(), and show_dialplan_helper().

History* el_hist [static]

Definition at line 216 of file asterisk.c.

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

struct sigaction hup_handler [static]

Initial value:

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

Definition at line 1489 of file asterisk.c.

struct sigaction ignore_sig_handler [static]

Initial value:

 {
   .sa_handler = SIG_IGN,
}

Definition at line 990 of file asterisk.c.

const char license_lines[] [static]

Definition at line 2054 of file asterisk.c.

pthread_t lthread [static]

Definition at line 1174 of file asterisk.c.

Referenced by ast_makesocket(), and quit_handler().

pthread_t mon_sig_flags [static]

Definition at line 281 of file asterisk.c.

Referenced by main(), and quit_handler().

unsigned int need_quit

Definition at line 290 of file asterisk.c.

unsigned int need_reload

Definition at line 289 of file asterisk.c.

struct sigaction null_sig_handler [static]

Initial value:

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

Definition at line 985 of file asterisk.c.

struct profile_data* prof_data [static]

Definition at line 686 of file asterisk.c.

Referenced by ast_add_profile(), ast_mark(), ast_profile(), handle_clear_profile(), and handle_show_profile().

struct ast_str* prompt = NULL [static]

Definition at line 2217 of file asterisk.c.

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

char randompool[256] [static]

Definition at line 285 of file asterisk.c.

Referenced by main().

char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR

Definition at line 191 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 218 of file asterisk.c.

Referenced by ast_remotecontrol(), and cli_prompt().

int restartnow [static]

Definition at line 279 of file asterisk.c.

Referenced by _hup_handler(), and quit_handler().

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

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

ast_mutex_t safe_system_lock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static]

Definition at line 994 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

struct sigaction safe_system_prev_handler [static]

Definition at line 998 of file asterisk.c.

int shuttingdown [static]

Definition at line 278 of file asterisk.c.

Referenced by handle_abort_shutdown(), and quit_handler().

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

Definition at line 287 of file asterisk.c.

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

struct { ... } sig_flags [static]

Referenced by __quit_handler(), __remote_quit_handler(), _hup_handler(), ast_el_read_char(), ast_remotecontrol(), and monitor_sig_flags().

struct sigaction urg_handler [static]

Initial value:

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

Definition at line 1469 of file asterisk.c.

const char warranty_lines[] [static]

Definition at line 2011 of file asterisk.c.


Generated on Wed Apr 6 11:29:53 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7