Wed Oct 28 13:31:45 2009

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 <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 "../defaults.h"

Include dependency graph for asterisk.c:

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 __fini_atexits (void)
static void __fini_file_versions (void)
static void __fini_thread_list (void)
static void __init_atexits (void)
static void __init_file_versions (void)
static void __init_thread_list (void)
static void __quit_handler (int num)
static void __remote_quit_handler (int num)
int ast_add_profile (const char *name, uint64_t scale)
 allocates a counter with a given name and scale.
static int ast_all_zeros (char *s)
static int ast_cli_display_match_list (char **matches, int len, int max)
char * ast_complete_source_filename (const char *partial, int n)
void ast_console_puts (const char *string)
void ast_console_puts_mutable (const char *string, int level)
 log the string to the console, and all attached console clients
void ast_console_toggle_loglevel (int fd, int level, int state)
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 void child_handler (int sig)
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 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_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 hup_handler (int num)
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 null_sig_handler (int sig)
 NULL handler so we can collect the child exit status.
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)
static void urg_handler (int num)
 Urgent handler.

Variables

static char * _argv [256]
struct ast_flags ast_compat = { 0 }
const char * ast_config_AST_AGI_DIR = cfg_paths.agi_dir
const char * ast_config_AST_CONFIG_DIR = cfg_paths.config_dir
const char * ast_config_AST_CONFIG_FILE = cfg_paths.config_file
static char ast_config_AST_CTL [PATH_MAX] = "asterisk.ctl"
static char ast_config_AST_CTL_GROUP [PATH_MAX] = "\0"
static char ast_config_AST_CTL_OWNER [PATH_MAX] = "\0"
static char ast_config_AST_CTL_PERMISSIONS [PATH_MAX]
const char * ast_config_AST_DATA_DIR = cfg_paths.data_dir
const char * ast_config_AST_DB = cfg_paths.db_path
const char * ast_config_AST_KEY_DIR = cfg_paths.key_dir
const char * ast_config_AST_LOG_DIR = cfg_paths.log_dir
const char * ast_config_AST_MODULE_DIR = cfg_paths.module_dir
const char * ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir
const char * ast_config_AST_PID = cfg_paths.pid_path
const char * ast_config_AST_RUN_DIR = cfg_paths.run_dir
const char * ast_config_AST_RUN_GROUP = cfg_paths.run_group
const char * ast_config_AST_RUN_USER = cfg_paths.run_user
const char * ast_config_AST_SOCKET = cfg_paths.socket_path
const char * ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir
const char * ast_config_AST_SYSTEM_NAME = cfg_paths.system_name
const char * ast_config_AST_VAR_DIR = cfg_paths.var_dir
static int ast_consock = -1
struct ast_eid ast_eid_default
 Global EID.
struct timeval ast_lastreloadtime
pid_t ast_mainpid
struct ast_flags ast_options = { AST_DEFAULT_OPTIONS }
static int ast_socket = -1
struct timeval ast_startuptime
static char canary_filename [128]
static int canary_pid = 0
static int canary_pipe = -1
static struct _cfg_paths cfg_paths
static struct ast_cli_entry cli_asterisk []
struct console consoles [AST_MAX_CONNECTS]
static pthread_t consolethread = AST_PTHREADT_NULL
char defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE
static EditLine * el
static History * el_hist
static const char license_lines []
static pthread_t lthread
int option_debug
int option_maxcalls
int option_maxfiles
double option_maxload
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 = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static void * 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 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 145 of file asterisk.c.

#define AST_MAX_CONNECTS   128

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 2035 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 2037 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

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

Referenced by ast_el_add_history(), and ast_el_read_history().

#define NUM_MSGS   64

Definition at line 150 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

Definition at line 146 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 153 of file asterisk.c.

Referenced by ast_el_read_char(), and main().


Function Documentation

static void __fini_atexits ( void   )  [static]

Definition at line 206 of file asterisk.c.

00223 {

static void __fini_file_versions ( void   )  [static]

Definition at line 293 of file asterisk.c.

00296 {

static void __fini_thread_list ( void   )  [static]

Definition at line 377 of file asterisk.c.

00380 { 

static void __init_atexits ( void   )  [static]

Definition at line 206 of file asterisk.c.

00223 {

static void __init_file_versions ( void   )  [static]

Definition at line 293 of file asterisk.c.

00296 {

static void __init_thread_list ( void   )  [static]

Definition at line 377 of file asterisk.c.

00380 { 

static void __quit_handler ( int  num  )  [static]

Definition at line 1657 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

01658 {
01659    int a = 0;
01660    sig_flags.need_quit = 1;
01661    if (sig_alert_pipe[1] != -1) {
01662       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01663          fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
01664       }
01665    }
01666    /* There is no need to restore the signal handler here, since the app
01667     * is going to exit */
01668 }

static void __remote_quit_handler ( int  num  )  [static]

Definition at line 1670 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

01671 {
01672    sig_flags.need_quit = 1;
01673 }

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

allocates a counter with a given name and scale.

support for event profiling

Returns:
Returns the identifier of the counter.

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

00673 {
00674    int l = sizeof(struct profile_data);
00675    int n = 10; /* default entries */
00676 
00677    if (prof_data == NULL) {
00678       prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
00679       if (prof_data == NULL)
00680          return -1;
00681       prof_data->entries = 0;
00682       prof_data->max_size = n;
00683    }
00684    if (prof_data->entries >= prof_data->max_size) {
00685       void *p;
00686       n = prof_data->max_size + 20;
00687       p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
00688       if (p == NULL)
00689          return -1;
00690       prof_data = p;
00691       prof_data->max_size = n;
00692    }
00693    n = prof_data->entries++;
00694    prof_data->e[n].name = ast_strdup(name);
00695    prof_data->e[n].value = 0;
00696    prof_data->e[n].events = 0;
00697    prof_data->e[n].mark = 0;
00698    prof_data->e[n].scale = scale;
00699    return n;
00700 }

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1717 of file asterisk.c.

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

01718 {
01719    while (*s) {
01720       if (*s > 32)
01721          return 0;
01722       s++;  
01723    }
01724    return 1;
01725 }

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

Definition at line 2343 of file asterisk.c.

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

Referenced by cli_complete().

02344 {
02345    int i, idx, limit, count;
02346    int screenwidth = 0;
02347    int numoutput = 0, numoutputline = 0;
02348 
02349    screenwidth = ast_get_termcols(STDOUT_FILENO);
02350 
02351    /* find out how many entries can be put on one line, with two spaces between strings */
02352    limit = screenwidth / (max + 2);
02353    if (limit == 0)
02354       limit = 1;
02355 
02356    /* how many lines of output */
02357    count = len / limit;
02358    if (count * limit < len)
02359       count++;
02360 
02361    idx = 1;
02362 
02363    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
02364 
02365    for (; count > 0; count--) {
02366       numoutputline = 0;
02367       for (i = 0; i < limit && matches[idx]; i++, idx++) {
02368 
02369          /* Don't print dupes */
02370          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
02371             i--;
02372             ast_free(matches[idx]);
02373             matches[idx] = NULL;
02374             continue;
02375          }
02376 
02377          numoutput++;
02378          numoutputline++;
02379          fprintf(stdout, "%-*s  ", max, matches[idx]);
02380          ast_free(matches[idx]);
02381          matches[idx] = NULL;
02382       }
02383       if (numoutputline > 0)
02384          fprintf(stdout, "\n");
02385    }
02386 
02387    return numoutput;
02388 }

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

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

00335 {
00336    struct file_version *find;
00337    size_t len = strlen(partial);
00338    int count = 0;
00339    char *res = NULL;
00340 
00341    AST_RWLIST_RDLOCK(&file_versions);
00342    AST_RWLIST_TRAVERSE(&file_versions, find, list) {
00343       if (!strncasecmp(find->file, partial, len) && ++count > n) {
00344          res = ast_strdup(find->file);
00345          break;
00346       }
00347    }
00348    AST_RWLIST_UNLOCK(&file_versions);
00349    return res;
00350 }

void ast_console_puts ( const char *  string  ) 

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

Definition at line 1132 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

01133 {
01134    fputs(string, stdout);
01135    fflush(stdout);
01136    ast_network_puts(string);
01137 }

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

References ast_network_puts_mutable().

Referenced by logger_print_normal().

01110 {
01111    fputs(string, stdout);
01112    fflush(stdout);
01113    ast_network_puts_mutable(string, level);
01114 }

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

Since:
1.6.1

Definition at line 1056 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and console::levels.

Referenced by handle_logger_set_level().

01057 {
01058    int x;
01059    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01060       if (fd == consoles[x].fd) {
01061          consoles[x].levels[level] = state;
01062          return;
01063       }
01064    }
01065 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1070 of file asterisk.c.

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

Referenced by handle_logger_mute().

01070                                                  {
01071    int x;
01072    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01073       if (fd == consoles[x].fd) {
01074          if (consoles[x].mute) {
01075             consoles[x].mute = 0;
01076             if (!silent)
01077                ast_cli(fd, "Console is not muted anymore.\n");
01078          } else {
01079             consoles[x].mute = 1;
01080             if (!silent)
01081                ast_cli(fd, "Console is muted.\n");
01082          }
01083          return;
01084       }
01085    }
01086    ast_cli(fd, "Couldn't find remote console.\n");
01087 }

static int ast_el_add_history ( char *  buf  )  [static]

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

02547 {
02548    HistEvent ev;
02549 
02550    if (el_hist == NULL || el == NULL)
02551       ast_el_initialize();
02552    if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1))
02553       return 0;
02554    return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf))));
02555 }

static int ast_el_initialize ( void   )  [static]

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

02510 {
02511    HistEvent ev;
02512    char *editor = getenv("AST_EDITOR");
02513 
02514    if (el != NULL)
02515       el_end(el);
02516    if (el_hist != NULL)
02517       history_end(el_hist);
02518 
02519    el = el_init("asterisk", stdin, stdout, stderr);
02520    el_set(el, EL_PROMPT, cli_prompt);
02521 
02522    el_set(el, EL_EDITMODE, 1);      
02523    el_set(el, EL_EDITOR, editor ? editor : "emacs");     
02524    el_hist = history_init();
02525    if (!el || !el_hist)
02526       return -1;
02527 
02528    /* setup history with 100 entries */
02529    history(el_hist, &ev, H_SETSIZE, 100);
02530 
02531    el_set(el, EL_HIST, history, el_hist);
02532 
02533    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02534    /* Bind <tab> to command completion */
02535    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02536    /* Bind ? to command completion */
02537    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02538    /* Bind ^D to redisplay */
02539    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02540 
02541    return 0;
02542 }

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

Definition at line 2063 of file asterisk.c.

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

Referenced by ast_remotecontrol().

02064 {
02065    int num_read = 0;
02066    int lastpos = 0;
02067    struct pollfd fds[2];
02068    int res;
02069    int max;
02070 #define EL_BUF_SIZE 512
02071    char buf[EL_BUF_SIZE];
02072 
02073    for (;;) {
02074       max = 1;
02075       fds[0].fd = ast_consock;
02076       fds[0].events = POLLIN;
02077       if (!ast_opt_exec) {
02078          fds[1].fd = STDIN_FILENO;
02079          fds[1].events = POLLIN;
02080          max++;
02081       }
02082       res = ast_poll(fds, max, -1);
02083       if (res < 0) {
02084          if (sig_flags.need_quit)
02085             break;
02086          if (errno == EINTR)
02087             continue;
02088          ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
02089          break;
02090       }
02091 
02092       if (!ast_opt_exec && fds[1].revents) {
02093          num_read = read(STDIN_FILENO, cp, 1);
02094          if (num_read < 1) {
02095             break;
02096          } else 
02097             return (num_read);
02098       }
02099       if (fds[0].revents) {
02100          char *tmp;
02101          res = read(ast_consock, buf, sizeof(buf) - 1);
02102          /* if the remote side disappears exit */
02103          if (res < 1) {
02104             fprintf(stderr, "\nDisconnected from Asterisk server\n");
02105             if (!ast_opt_reconnect) {
02106                quit_handler(0, 0, 0, 0);
02107             } else {
02108                int tries;
02109                int reconnects_per_second = 20;
02110                fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
02111                for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
02112                   if (ast_tryconnect()) {
02113                      fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
02114                      printf("%s", term_quit());
02115                      WELCOME_MESSAGE;
02116                      if (!ast_opt_mute)
02117                         fdsend(ast_consock, "logger mute silent");
02118                      else 
02119                         printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02120                      break;
02121                   } else
02122                      usleep(1000000 / reconnects_per_second);
02123                }
02124                if (tries >= 30 * reconnects_per_second) {
02125                   fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
02126                   quit_handler(0, 0, 0, 0);
02127                }
02128             }
02129          }
02130 
02131          buf[res] = '\0';
02132 
02133          /* Strip preamble from asynchronous events, too */
02134          for (tmp = buf; *tmp; tmp++) {
02135             if (*tmp == 127) {
02136                memmove(tmp, tmp + 1, strlen(tmp));
02137                tmp--;
02138                res--;
02139             }
02140          }
02141 
02142          /* Write over the CLI prompt */
02143          if (!ast_opt_exec && !lastpos) {
02144             if (write(STDOUT_FILENO, "\r", 1) < 0) {
02145             }
02146          }
02147          if (write(STDOUT_FILENO, buf, res) < 0) {
02148          }
02149          if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
02150             *cp = CC_REFRESH;
02151             return(1);
02152          } else
02153             lastpos = 1;
02154       }
02155    }
02156 
02157    *cp = '\0';
02158    return (0);
02159 }

static int ast_el_read_history ( char *  filename  )  [static]

Definition at line 2567 of file asterisk.c.

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

Referenced by ast_remotecontrol(), and main().

02568 {
02569    char buf[MAX_HISTORY_COMMAND_LENGTH];
02570    FILE *f;
02571    int ret = -1;
02572 
02573    if (el_hist == NULL || el == NULL)
02574       ast_el_initialize();
02575 
02576    if ((f = fopen(filename, "r")) == NULL)
02577       return ret;
02578 
02579    while (!feof(f)) {
02580       if (!fgets(buf, sizeof(buf), f))
02581          break;
02582       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02583          continue;
02584       if (ast_all_zeros(buf))
02585          continue;
02586       if ((ret = ast_el_add_history(buf)) == -1)
02587          break;
02588    }
02589    fclose(f);
02590 
02591    return ret;
02592 }

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

Definition at line 2333 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02334 {
02335    char *s1, *s2;
02336 
02337    s1 = ((char **)i1)[0];
02338    s2 = ((char **)i2)[0];
02339 
02340    return strcasecmp(s1, s2);
02341 }

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

Definition at line 2290 of file asterisk.c.

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

Referenced by cli_complete().

02291 {
02292    char **match_list = NULL, **match_list_tmp, *retstr;
02293    size_t match_list_len;
02294    int matches = 0;
02295 
02296    match_list_len = 1;
02297    while ( (retstr = strsep(&buf, " ")) != NULL) {
02298 
02299       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
02300          break;
02301       if (matches + 1 >= match_list_len) {
02302          match_list_len <<= 1;
02303          if ((match_list_tmp = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
02304             match_list = match_list_tmp;
02305          } else {
02306             if (match_list)
02307                ast_free(match_list);
02308             return (char **) NULL;
02309          }
02310       }
02311 
02312       match_list[matches++] = ast_strdup(retstr);
02313    }
02314 
02315    if (!match_list)
02316       return (char **) NULL;
02317 
02318    if (matches >= match_list_len) {
02319       if ((match_list_tmp = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
02320          match_list = match_list_tmp;
02321       } else {
02322          if (match_list)
02323             ast_free(match_list);
02324          return (char **) NULL;
02325       }
02326    }
02327 
02328    match_list[matches] = (char *) NULL;
02329 
02330    return match_list;
02331 }

static int ast_el_write_history ( char *  filename  )  [static]

Definition at line 2557 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by quit_handler().

02558 {
02559    HistEvent ev;
02560 
02561    if (el_hist == NULL || el == NULL)
02562       ast_el_initialize();
02563 
02564    return (history(el_hist, &ev, H_SAVE, filename));
02565 }

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

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

static int ast_makesocket ( void   )  [static]

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

01332 {
01333    struct sockaddr_un sunaddr;
01334    int res;
01335    int x;
01336    uid_t uid = -1;
01337    gid_t gid = -1;
01338 
01339    for (x = 0; x < AST_MAX_CONNECTS; x++) 
01340       consoles[x].fd = -1;
01341    unlink(ast_config_AST_SOCKET);
01342    ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
01343    if (ast_socket < 0) {
01344       ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
01345       return -1;
01346    }     
01347    memset(&sunaddr, 0, sizeof(sunaddr));
01348    sunaddr.sun_family = AF_LOCAL;
01349    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01350    res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01351    if (res) {
01352       ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01353       close(ast_socket);
01354       ast_socket = -1;
01355       return -1;
01356    }
01357    res = listen(ast_socket, 2);
01358    if (res < 0) {
01359       ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01360       close(ast_socket);
01361       ast_socket = -1;
01362       return -1;
01363    }
01364    if (ast_register_verbose(network_verboser)) {
01365       ast_log(LOG_WARNING, "Unable to register network verboser?\n");
01366    }
01367 
01368    ast_pthread_create_background(&lthread, NULL, listener, NULL);
01369 
01370    if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
01371       struct passwd *pw;
01372       if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
01373          ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
01374       else
01375          uid = pw->pw_uid;
01376    }
01377       
01378    if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
01379       struct group *grp;
01380       if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
01381          ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
01382       else
01383          gid = grp->gr_gid;
01384    }
01385 
01386    if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
01387       ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01388 
01389    if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
01390       int p1;
01391       mode_t p;
01392       sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
01393       p = p1;
01394       if ((chmod(ast_config_AST_SOCKET, p)) < 0)
01395          ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01396    }
01397 
01398    return 0;
01399 }

int64_t ast_mark ( int  i,
int  startstop 
)

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

00738 {
00739    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00740       return 0;
00741    if (startstop == 1)
00742       prof_data->e[i].mark = rdtsc();
00743    else {
00744       prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
00745       if (prof_data->e[i].scale > 1)
00746          prof_data->e[i].mark /= prof_data->e[i].scale;
00747       prof_data->e[i].value += prof_data->e[i].mark;
00748       prof_data->e[i].events++;
00749    }
00750    return prof_data->e[i].mark;
00751 }

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

write the string to all attached console clients

Definition at line 1119 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

01120 {
01121    int x;
01122    for (x = 0; x < AST_MAX_CONNECTS; x++) {
01123       if (consoles[x].fd > -1) 
01124          fdprint(consoles[x].p[1], string);
01125    }
01126 }

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

log the string to all attached console clients

Definition at line 1092 of file asterisk.c.

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

Referenced by ast_console_puts_mutable(), and network_verboser().

01093 {
01094    int x;
01095    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01096       if (consoles[x].mute)
01097          continue;
01098       if (consoles[x].fd > -1) {
01099          if (!consoles[x].levels[level]) 
01100             fdprint(consoles[x].p[1], string);
01101       }
01102    }
01103 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 702 of file asterisk.c.

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

00703 {
00704    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00705       return 0;
00706    if (prof_data->e[i].scale > 1)
00707       delta /= prof_data->e[i].scale;
00708    prof_data->e[i].value += delta;
00709    prof_data->e[i].events++;
00710    return prof_data->e[i].value;
00711 }

static void ast_readconfig ( void   )  [static]

Definition at line 2783 of file asterisk.c.

References _cfg_paths::agi_dir, AST_CACHE_DIR_LEN, AST_COMPAT_APP_SET, AST_COMPAT_DELIM_PBX_REALTIME, AST_COMPAT_DELIM_RES_AGI, ast_config_AST_CONFIG_FILE, ast_config_AST_CTL, ast_config_AST_CTL_GROUP, ast_config_AST_CTL_OWNER, ast_config_AST_CTL_PERMISSIONS, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_eid_default, ast_language_is_prefix, AST_LOCK_TYPE_FLOCK, AST_LOCK_TYPE_LOCKFILE, ast_log(), AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DONT_WARN, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND, AST_OPT_FLAG_HIDE_CONSOLE_CONNECT, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_LIGHT_BACKGROUND, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_TIMESTAMP, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_opt_override_config, ast_set2_flag, ast_set_default_eid(), ast_set_lock_type(), ast_str_to_eid(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_verbose, cfg_paths, config, _cfg_paths::config_dir, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, _cfg_paths::data_dir, _cfg_paths::db_path, getloadavg(), hostname, _cfg_paths::key_dir, _cfg_paths::log_dir, LOG_ERROR, 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::run_group, _cfg_paths::run_user, set_ulimit(), _cfg_paths::socket_path, _cfg_paths::spool_dir, _cfg_paths::system_name, ast_variable::value, _cfg_paths::var_dir, and version.

Referenced by main().

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

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

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

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

00914 {
00915    struct ast_atexit *ae;
00916 
00917    if (!(ae = ast_calloc(1, sizeof(*ae))))
00918       return -1;
00919 
00920    ae->func = func;
00921 
00922    ast_unregister_atexit(func);  
00923 
00924    AST_RWLIST_WRLOCK(&atexits);
00925    AST_RWLIST_INSERT_HEAD(&atexits, ae, list);
00926    AST_RWLIST_UNLOCK(&atexits);
00927 
00928    return 0;
00929 }

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

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

00296 {
00297    struct file_version *new;
00298    char *work;
00299    size_t version_length;
00300 
00301    work = ast_strdupa(version);
00302    work = ast_strip(ast_strip_quoted(work, "$", "$"));
00303    version_length = strlen(work) + 1;
00304    
00305    if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
00306       return;
00307 
00308    new->file = file;
00309    new->version = (char *) new + sizeof(*new);
00310    memcpy(new->version, work, version_length);
00311    AST_RWLIST_WRLOCK(&file_versions);
00312    AST_RWLIST_INSERT_HEAD(&file_versions, new, list);
00313    AST_RWLIST_UNLOCK(&file_versions);
00314 }

void ast_register_thread ( char *  name  ) 

Definition at line 379 of file asterisk.c.

References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

Referenced by dummy_start().

00380 { 
00381    struct thread_list_t *new = ast_calloc(1, sizeof(*new));
00382 
00383    if (!new)
00384       return;
00385    new->id = pthread_self();
00386    new->name = name; /* steal the allocated memory for the thread name */
00387    AST_RWLIST_WRLOCK(&thread_list);
00388    AST_RWLIST_INSERT_HEAD(&thread_list, new, list);
00389    AST_RWLIST_UNLOCK(&thread_list);
00390 }

static void ast_remotecontrol ( char *  data  )  [static]

Definition at line 2594 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, buf, el, el_hist, errno, fdsend(), hostname, LOG_ERROR, LOG_WARNING, num, prefix, remoteconsolehandler(), remotehostname, sig_flags, strsep(), and version.

Referenced by main().

02595 {
02596    char buf[80];
02597    int res;
02598    char filename[80] = "";
02599    char *hostname;
02600    char *cpid;
02601    char *version;
02602    int pid;
02603    char *stringp = NULL;
02604 
02605    char *ebuf;
02606    int num = 0;
02607 
02608    memset(&sig_flags, 0, sizeof(sig_flags));
02609    signal(SIGINT, __remote_quit_handler);
02610    signal(SIGTERM, __remote_quit_handler);
02611    signal(SIGHUP, __remote_quit_handler);
02612 
02613    if (read(ast_consock, buf, sizeof(buf)) < 0) {
02614       ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02615       return;
02616    }
02617    if (data) {
02618       char prefix[] = "cli quit after ";
02619       char *tmp = alloca(strlen(data) + strlen(prefix) + 1);
02620       sprintf(tmp, "%s%s", prefix, data);
02621       if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
02622          ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
02623          if (sig_flags.need_quit == 1) {
02624             return;
02625          }
02626       }
02627    }
02628    stringp = buf;
02629    hostname = strsep(&stringp, "/");
02630    cpid = strsep(&stringp, "/");
02631    version = strsep(&stringp, "\n");
02632    if (!version)
02633       version = "<Version Unknown>";
02634    stringp = hostname;
02635    strsep(&stringp, ".");
02636    if (cpid)
02637       pid = atoi(cpid);
02638    else
02639       pid = -1;
02640    if (!data) {
02641       char tmp[80];
02642       snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
02643       fdsend(ast_consock, tmp);
02644       snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
02645       fdsend(ast_consock, tmp);
02646       if (!ast_opt_mute)
02647          fdsend(ast_consock, "logger mute silent");
02648       else 
02649          printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02650    }
02651 
02652    if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
02653       struct pollfd fds;
02654       fds.fd = ast_consock;
02655       fds.events = POLLIN;
02656       fds.revents = 0;
02657       while (ast_poll(&fds, 1, 500) > 0) {
02658          char buffer[512] = "", *curline = buffer, *nextline;
02659          int not_written = 1;
02660 
02661          if (sig_flags.need_quit == 1) {
02662             break;
02663          }
02664 
02665          if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
02666             break;
02667          }
02668 
02669          do {
02670             if ((nextline = strchr(curline, '\n'))) {
02671                nextline++;
02672             } else {
02673                nextline = strchr(curline, '\0');
02674             }
02675 
02676             /* Skip verbose lines */
02677             if (*curline != 127) {
02678                not_written = 0;
02679                if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
02680                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
02681                }
02682             }
02683             curline = nextline;
02684          } while (!ast_strlen_zero(curline));
02685 
02686          /* No non-verbose output in 500ms */
02687          if (not_written) {
02688             break;
02689          }
02690       }
02691       return;
02692    }
02693 
02694    ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
02695    remotehostname = hostname;
02696    if (getenv("HOME")) 
02697       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
02698    if (el_hist == NULL || el == NULL)
02699       ast_el_initialize();
02700 
02701    el_set(el, EL_GETCFN, ast_el_read_char);
02702 
02703    if (!ast_strlen_zero(filename))
02704       ast_el_read_history(filename);
02705 
02706    for (;;) {
02707       ebuf = (char *)el_gets(el, &num);
02708 
02709       if (sig_flags.need_quit == 1) {
02710          break;
02711       }
02712 
02713       if (!ebuf && write(1, "", 1) < 0)
02714          break;
02715 
02716       if (!ast_strlen_zero(ebuf)) {
02717          if (ebuf[strlen(ebuf)-1] == '\n')
02718             ebuf[strlen(ebuf)-1] = '\0';
02719          if (!remoteconsolehandler(ebuf)) {
02720             /* Strip preamble from output */
02721             char *temp;
02722             for (temp = ebuf; *temp; temp++) {
02723                if (*temp == 127) {
02724                   memmove(temp, temp + 1, strlen(temp));
02725                   temp--;
02726                }
02727             }
02728             res = write(ast_consock, ebuf, strlen(ebuf) + 1);
02729             if (res < 1) {
02730                ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
02731                break;
02732             }
02733          }
02734       }
02735    }
02736    printf("\nDisconnected from Asterisk server\n");
02737 }

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

References ast_mutex_lock(), ast_mutex_unlock(), null_sig_handler(), safe_system_level, safe_system_lock, and safe_system_prev_handler.

Referenced by ast_safe_fork(), and ast_safe_system().

00973 {
00974    unsigned int level;
00975 
00976    ast_mutex_lock(&safe_system_lock);
00977    level = safe_system_level++;
00978 
00979    /* only replace the handler if it has not already been done */
00980    if (level == 0)
00981       safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
00982 
00983    ast_mutex_unlock(&safe_system_lock);
00984 }

static void ast_run_atexits ( void   )  [static]

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

01538 {
01539    struct ast_atexit *ae;
01540    AST_RWLIST_RDLOCK(&atexits);
01541    AST_RWLIST_TRAVERSE(&atexits, ae, list) {
01542       if (ae->func) 
01543          ae->func();
01544    }
01545    AST_RWLIST_UNLOCK(&atexits);
01546 }

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 1000 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(), filestream_destructor(), mixmonitor_thread(), notify_message(), process_text_line(), remoteconsolehandler(), rotate_file(), run_externnotify(), sendmail(), sendpage(), system_exec_helper(), and vm_change_password_shell().

01001 {
01002    pid_t pid;
01003    int res;
01004    struct rusage rusage;
01005    int status;
01006 
01007 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
01008    ast_replace_sigchld();
01009 
01010 #ifdef HAVE_WORKING_FORK
01011    pid = fork();
01012 #else
01013    pid = vfork();
01014 #endif   
01015 
01016    if (pid == 0) {
01017 #ifdef HAVE_CAP
01018       cap_t cap = cap_from_text("cap_net_admin-eip");
01019 
01020       if (cap_set_proc(cap)) {
01021          /* Careful with order! Logging cannot happen after we close FDs */
01022          ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
01023       }
01024       cap_free(cap);
01025 #endif
01026 #ifdef HAVE_WORKING_FORK
01027       if (ast_opt_high_priority)
01028          ast_set_priority(0);
01029       /* Close file descriptors and launch system command */
01030       ast_close_fds_above_n(STDERR_FILENO);
01031 #endif
01032       execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
01033       _exit(1);
01034    } else if (pid > 0) {
01035       for (;;) {
01036          res = wait4(pid, &status, 0, &rusage);
01037          if (res > -1) {
01038             res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
01039             break;
01040          } else if (errno != EINTR) 
01041             break;
01042       }
01043    } else {
01044       ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
01045       res = -1;
01046    }
01047 
01048    ast_unreplace_sigchld();
01049 #else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */
01050    res = -1;
01051 #endif
01052 
01053    return res;
01054 }

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

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

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

01504 {
01505    struct sched_param sched;
01506    memset(&sched, 0, sizeof(sched));
01507 #ifdef __linux__
01508    if (pri) {  
01509       sched.sched_priority = 10;
01510       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01511          ast_log(LOG_WARNING, "Unable to set high priority\n");
01512          return -1;
01513       } else
01514          if (option_verbose)
01515             ast_verbose("Set to realtime thread\n");
01516    } else {
01517       sched.sched_priority = 0;
01518       /* According to the manpage, these parameters can never fail. */
01519       sched_setscheduler(0, SCHED_OTHER, &sched);
01520    }
01521 #else
01522    if (pri) {
01523       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01524          ast_log(LOG_WARNING, "Unable to set high priority\n");
01525          return -1;
01526       } else
01527          if (option_verbose)
01528             ast_verbose("Set to high priority\n");
01529    } else {
01530       /* According to the manpage, these parameters can never fail. */
01531       setpriority(PRIO_PROCESS, 0, 0);
01532    }
01533 #endif
01534    return 0;
01535 }

static int ast_tryconnect ( void   )  [static]

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

01402 {
01403    struct sockaddr_un sunaddr;
01404    int res;
01405    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01406    if (ast_consock < 0) {
01407       ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
01408       return 0;
01409    }
01410    memset(&sunaddr, 0, sizeof(sunaddr));
01411    sunaddr.sun_family = AF_LOCAL;
01412    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01413    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01414    if (res) {
01415       close(ast_consock);
01416       ast_consock = -1;
01417       return 0;
01418    } else
01419       return 1;
01420 }

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

00932 {
00933    struct ast_atexit *ae = NULL;
00934 
00935    AST_RWLIST_WRLOCK(&atexits);
00936    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
00937       if (ae->func == func) {
00938          AST_RWLIST_REMOVE_CURRENT(list);
00939          break;
00940       }
00941    }
00942    AST_RWLIST_TRAVERSE_SAFE_END;
00943    AST_RWLIST_UNLOCK(&atexits);
00944 
00945    free(ae);
00946 }

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

00317 {
00318    struct file_version *find;
00319 
00320    AST_RWLIST_WRLOCK(&file_versions);
00321    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
00322       if (!strcasecmp(find->file, file)) {
00323          AST_RWLIST_REMOVE_CURRENT(list);
00324          break;
00325       }
00326    }
00327    AST_RWLIST_TRAVERSE_SAFE_END;
00328    AST_RWLIST_UNLOCK(&file_versions);
00329 
00330    if (find)
00331       ast_free(find);
00332 }

void ast_unregister_thread ( void *  id  ) 

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

00393 {
00394    struct thread_list_t *x;
00395 
00396    AST_RWLIST_WRLOCK(&thread_list);
00397    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
00398       if ((void *) x->id == id) {
00399          AST_RWLIST_REMOVE_CURRENT(list);
00400          break;
00401       }
00402    }
00403    AST_RWLIST_TRAVERSE_SAFE_END;
00404    AST_RWLIST_UNLOCK(&thread_list);
00405    if (x) {
00406       ast_free(x->name);
00407       ast_free(x);
00408    }
00409 }

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

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

Referenced by ast_safe_fork_cleanup(), and ast_safe_system().

00987 {
00988    unsigned int level;
00989 
00990    ast_mutex_lock(&safe_system_lock);
00991    level = --safe_system_level;
00992 
00993    /* only restore the handler if we are the last one */
00994    if (level == 0)
00995       signal(SIGCHLD, safe_system_prev_handler);
00996 
00997    ast_mutex_unlock(&safe_system_lock);
00998 }

static void canary_exit ( void   )  [static]

Definition at line 3060 of file asterisk.c.

References canary_pid.

Referenced by main().

03061 {
03062    if (canary_pid > 0)
03063       kill(canary_pid, SIGKILL);
03064 }

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

Definition at line 3037 of file asterisk.c.

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

Referenced by main().

03038 {
03039    struct stat canary_stat;
03040    struct timeval now;
03041 
03042    /* Give the canary time to sing */
03043    sleep(120);
03044 
03045    for (;;) {
03046       stat(canary_filename, &canary_stat);
03047       now = ast_tvnow();
03048       if (now.tv_sec > canary_stat.st_mtime + 60) {
03049          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");
03050          ast_set_priority(0);
03051          pthread_exit(NULL);
03052       }
03053 
03054       /* Check the canary once a minute */
03055       sleep(60);
03056    }
03057 }

static void child_handler ( int  sig  )  [static]

Definition at line 1450 of file asterisk.c.

References status.

Referenced by main().

01451 {
01452    /* Must not ever ast_log or ast_verbose within signal handler */
01453    int n, status;
01454 
01455    /*
01456     * Reap all dead children -- not just one
01457     */
01458    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01459       ;
01460    if (n == 0 && option_debug)   
01461       printf("Huh?  Child handler, but nobody there?\n");
01462    signal(sig, child_handler);
01463 }

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

Definition at line 2391 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, buf, and fdsend().

Referenced by ast_el_initialize().

02392 {
02393    int len = 0;
02394    char *ptr;
02395    int nummatches = 0;
02396    char **matches;
02397    int retval = CC_ERROR;
02398    char buf[2048], savechr;
02399    int res;
02400 
02401    LineInfo *lf = (LineInfo *)el_line(editline);
02402 
02403    savechr = *(char *)lf->cursor;
02404    *(char *)lf->cursor = '\0';
02405    ptr = (char *)lf->cursor;
02406    if (ptr) {
02407       while (ptr > lf->buffer) {
02408          if (isspace(*ptr)) {
02409             ptr++;
02410             break;
02411          }
02412          ptr--;
02413       }
02414    }
02415 
02416    len = lf->cursor - ptr;
02417 
02418    if (ast_opt_remote) {
02419       snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 
02420       fdsend(ast_consock, buf);
02421       res = read(ast_consock, buf, sizeof(buf) - 1);
02422       buf[res] = '\0';
02423       nummatches = atoi(buf);
02424 
02425       if (nummatches > 0) {
02426          char *mbuf;
02427          int mlen = 0, maxmbuf = 2048;
02428          /* Start with a 2048 byte buffer */       
02429          if (!(mbuf = ast_malloc(maxmbuf))) {
02430             lf->cursor[0] = savechr;
02431             return (char *)(CC_ERROR);
02432          }
02433          snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 
02434          fdsend(ast_consock, buf);
02435          res = 0;
02436          mbuf[0] = '\0';
02437          while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
02438             if (mlen + 1024 > maxmbuf) {
02439                /* Every step increment buffer 1024 bytes */
02440                maxmbuf += 1024;              
02441                if (!(mbuf = ast_realloc(mbuf, maxmbuf))) {
02442                   lf->cursor[0] = savechr;
02443                   return (char *)(CC_ERROR);
02444                }
02445             }
02446             /* Only read 1024 bytes at a time */
02447             res = read(ast_consock, mbuf + mlen, 1024);
02448             if (res > 0)
02449                mlen += res;
02450          }
02451          mbuf[mlen] = '\0';
02452 
02453          matches = ast_el_strtoarr(mbuf);
02454          ast_free(mbuf);
02455       } else
02456          matches = (char **) NULL;
02457    } else {
02458       char **p, *oldbuf=NULL;
02459       nummatches = 0;
02460       matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
02461       for (p = matches; p && *p; p++) {
02462          if (!oldbuf || strcmp(*p,oldbuf))
02463             nummatches++;
02464          oldbuf = *p;
02465       }
02466    }
02467 
02468    if (matches) {
02469       int i;
02470       int matches_num, maxlen, match_len;
02471 
02472       if (matches[0][0] != '\0') {
02473          el_deletestr(editline, (int) len);
02474          el_insertstr(editline, matches[0]);
02475          retval = CC_REFRESH;
02476       }
02477 
02478       if (nummatches == 1) {
02479          /* Found an exact match */
02480          el_insertstr(editline, " ");
02481          retval = CC_REFRESH;
02482       } else {
02483          /* Must be more than one match */
02484          for (i = 1, maxlen = 0; matches[i]; i++) {
02485             match_len = strlen(matches[i]);
02486             if (match_len > maxlen)
02487                maxlen = match_len;
02488          }
02489          matches_num = i - 1;
02490          if (matches_num >1) {
02491             fprintf(stdout, "\n");
02492             ast_cli_display_match_list(matches, nummatches, maxlen);
02493             retval = CC_REDISPLAY;
02494          } else { 
02495             el_insertstr(editline," ");
02496             retval = CC_REFRESH;
02497          }
02498       }
02499       for (i = 0; matches[i]; i++)
02500          ast_free(matches[i]);
02501       ast_free(matches);
02502    }
02503 
02504    lf->cursor[0] = savechr;
02505 
02506    return (char *)(long)retval;
02507 }

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

Definition at line 2163 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, remotehostname, and term_color_code().

Referenced by ast_el_initialize().

02164 {
02165    char tmp[100];
02166    char *pfmt;
02167    int color_used = 0;
02168    static int cli_prompt_changes = 0;
02169    char term_code[20];
02170    struct passwd *pw;
02171    struct group *gr;
02172 
02173    if (prompt == NULL) {
02174       prompt = ast_str_create(100);
02175    } else if (!cli_prompt_changes) {
02176       return ast_str_buffer(prompt);
02177    } else {
02178       ast_str_reset(prompt);
02179    }
02180 
02181    if ((pfmt = getenv("ASTERISK_PROMPT"))) {
02182       char *t = pfmt;
02183       struct timeval ts = ast_tvnow();
02184       while (*t != '\0') {
02185          if (*t == '%') {
02186             char hostname[MAXHOSTNAMELEN] = "";
02187             int i, which;
02188             struct ast_tm tm = { 0, };
02189             int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
02190 
02191             t++;
02192             switch (*t) {
02193             case 'C': /* color */
02194                t++;
02195                if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
02196                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)));
02197                   t += i - 1;
02198                } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
02199                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code)));
02200                   t += i - 1;
02201                }
02202 
02203                /* If the color has been reset correctly, then there's no need to reset it later */
02204                color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
02205                break;
02206             case 'd': /* date */
02207                if (ast_localtime(&ts, &tm, NULL)) {
02208                   ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
02209                   ast_str_append(&prompt, 0, "%s", tmp);
02210                   cli_prompt_changes++;
02211                }
02212                break;
02213             case 'g': /* group */
02214                if ((gr = getgrgid(getgid()))) {
02215                   ast_str_append(&prompt, 0, "%s", gr->gr_name);
02216                }
02217                break;
02218             case 'h': /* hostname */
02219                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02220                   ast_str_append(&prompt, 0, "%s", hostname);
02221                } else {
02222                   ast_str_append(&prompt, 0, "%s", "localhost");
02223                }
02224                break;
02225             case 'H': /* short hostname */
02226                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02227                   char *dotptr;
02228                   if ((dotptr = strchr(hostname, '.'))) {
02229                      *dotptr = '\0';
02230                   }
02231                   ast_str_append(&prompt, 0, "%s", hostname);
02232                } else {
02233                   ast_str_append(&prompt, 0, "%s", "localhost");
02234                }
02235                break;
02236 #ifdef HAVE_GETLOADAVG
02237             case 'l': /* load avg */
02238                t++;
02239                if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
02240                   double list[3];
02241                   getloadavg(list, 3);
02242                   ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
02243                   cli_prompt_changes++;
02244                }
02245                break;
02246 #endif
02247             case 's': /* Asterisk system name (from asterisk.conf) */
02248                ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
02249                break;
02250             case 't': /* time */
02251                if (ast_localtime(&ts, &tm, NULL)) {
02252                   ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
02253                   ast_str_append(&prompt, 0, "%s", tmp);
02254                   cli_prompt_changes++;
02255                }
02256                break;
02257             case 'u': /* username */
02258                if ((pw = getpwuid(getuid()))) {
02259                   ast_str_append(&prompt, 0, "%s", pw->pw_name);
02260                }
02261                break;
02262             case '#': /* process console or remote? */
02263                ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
02264                break;
02265             case '%': /* literal % */
02266                ast_str_append(&prompt, 0, "%c", '%');
02267                break;
02268             case '\0': /* % is last character - prevent bug */
02269                t--;
02270                break;
02271             }
02272          } else {
02273             ast_str_append(&prompt, 0, "%c", *t);
02274          }
02275          t++;
02276       }
02277       if (color_used) {
02278          /* Force colors back to normal at end */
02279          ast_str_append(&prompt, 0, "%s", term_color_code(term_code, 0, 0, sizeof(term_code)));
02280       }
02281    } else if (remotehostname) {
02282       ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname);
02283    } else {
02284       ast_str_set(&prompt, 0, "%s", ASTERISK_PROMPT);
02285    }
02286 
02287    return ast_str_buffer(prompt);   
02288 }

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

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

01693 {
01694    char tmp[80];
01695    const char *c = NULL;
01696 
01697    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01698        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01699        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01700        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
01701       fputs(tmp, stdout);
01702       fputs(c, stdout);
01703    } else {
01704       if (*s == 127) {
01705          s++;
01706       }
01707       fputs(s, stdout);
01708    }
01709 
01710    fflush(stdout);
01711    
01712    /* Wake up a poll()ing console */
01713    if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
01714       pthread_kill(consolethread, SIGURG);
01715 }

static void consolehandler ( char *  s  )  [static]

Definition at line 1727 of file asterisk.c.

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

Referenced by main().

01728 {
01729    printf("%s", term_end());
01730    fflush(stdout);
01731 
01732    /* Called when readline data is available */
01733    if (!ast_all_zeros(s))
01734       ast_el_add_history(s);
01735    /* The real handler for bang */
01736    if (s[0] == '!') {
01737       if (s[1])
01738          ast_safe_system(s+1);
01739       else
01740          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01741    } else 
01742       ast_cli_command(STDOUT_FILENO, s);
01743 }

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

Definition at line 955 of file asterisk.c.

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

00956 {
00957    return write(fd, s, strlen(s));
00958 }

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

Definition at line 949 of file asterisk.c.

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

00950 {
00951    return write(fd, s, strlen(s) + 1);
00952 }

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

Definition at line 1675 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01676 {
01677    const char *c;
01678 
01679    /* Check for verboser preamble */
01680    if (*s == 127) {
01681       s++;
01682    }
01683 
01684    if (!strncmp(s, cmp, strlen(cmp))) {
01685       c = s + strlen(cmp);
01686       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01687       return c;
01688    }
01689    return NULL;
01690 }

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

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

01920 {
01921    switch (cmd) {
01922    case CLI_INIT:
01923       e->command = "core abort shutdown";
01924       e->usage = 
01925          "Usage: core abort shutdown\n"
01926          "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
01927          "       call operations.\n";
01928       return NULL;
01929    case CLI_GENERATE:
01930       return NULL;
01931    }
01932 
01933    if (a->argc != e->args)
01934       return CLI_SHOWUSAGE;
01935    ast_cancel_shutdown();
01936    shuttingdown = 0;
01937    return CLI_SUCCESS;
01938 }

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

Definition at line 1940 of file asterisk.c.

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

01941 {
01942    switch (cmd) {
01943    case CLI_INIT:
01944       e->command = "!";
01945       e->usage = 
01946          "Usage: !<command>\n"
01947          "       Executes a given shell command\n";
01948       return NULL;
01949    case CLI_GENERATE:
01950       return NULL;
01951    }
01952 
01953    return CLI_SUCCESS;
01954 }

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

Definition at line 801 of file asterisk.c.

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

00802 {
00803    int i, min, max;
00804    const char *search = NULL;
00805    switch (cmd) {
00806    case CLI_INIT:
00807       e->command = "core clear profile";
00808       e->usage = "Usage: core clear profile\n"
00809             "       clear profile information";
00810       return NULL;
00811    case CLI_GENERATE:
00812       return NULL;
00813    }
00814 
00815    if (prof_data == NULL)
00816       return 0;
00817 
00818    DEFINE_PROFILE_MIN_MAX_VALUES;
00819    for (i= min; i < max; i++) {
00820       if (!search || strstr(prof_data->e[i].name, search)) {
00821          prof_data->e[i].value = 0;
00822          prof_data->e[i].events = 0;
00823       }
00824    }
00825    return CLI_SUCCESS;
00826 }

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

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

01880 {
01881    switch (cmd) {
01882    case CLI_INIT:
01883       e->command = "core restart gracefully";
01884       e->usage = 
01885          "Usage: core restart gracefully\n"
01886          "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
01887          "       restart when all active calls have ended.\n";
01888       return NULL;
01889    case CLI_GENERATE:
01890       return NULL;
01891    }
01892 
01893    if (a->argc != e->args)
01894       return CLI_SHOWUSAGE;
01895    quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
01896    return CLI_SUCCESS;
01897 }

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

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

01860 {
01861    switch (cmd) {
01862    case CLI_INIT:
01863       e->command = "core restart now";
01864       e->usage = 
01865          "Usage: core restart now\n"
01866          "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
01867          "       restart.\n";
01868       return NULL;
01869    case CLI_GENERATE:
01870       return NULL;
01871    }
01872 
01873    if (a->argc != e->args)
01874       return CLI_SHOWUSAGE;
01875    quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */);
01876    return CLI_SUCCESS;
01877 }

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

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

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

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

Definition at line 766 of file asterisk.c.

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

00767 {
00768    int i, min, max;
00769    const char *search = NULL;
00770    switch (cmd) {
00771    case CLI_INIT:
00772       e->command = "core show profile";
00773       e->usage = "Usage: core show profile\n"
00774             "       show profile information";
00775       return NULL;
00776    case CLI_GENERATE:
00777       return NULL;
00778    }
00779 
00780    if (prof_data == NULL)
00781       return 0;
00782 
00783    DEFINE_PROFILE_MIN_MAX_VALUES;
00784    ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
00785       prof_data->entries, prof_data->max_size);
00786    ast_cli(a->fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
00787          "Value", "Average", "Name");
00788    for (i = min; i < max; i++) {
00789       struct profile_entry *entry = &prof_data->e[i];
00790       if (!search || strstr(entry->name, search))
00791           ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
00792          i,
00793          (long)entry->scale,
00794          (long)entry->events, (long long)entry->value,
00795          (long long)(entry->events ? entry->value / entry->events : entry->value),
00796          entry->name);
00797    }
00798    return CLI_SUCCESS;
00799 }

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

References ast_active_channels(), ast_build_date, ast_build_kernel, ast_build_machine, ast_build_os, ast_build_user, ast_cli(), ast_config_AST_CONFIG_DIR, ast_config_AST_CONFIG_FILE, ast_config_AST_LOG_DIR, ast_config_AST_MODULE_DIR, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SPOOL_DIR, ast_config_AST_SYSTEM_NAME, 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_INTERNAL_TIMING, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_realtime_enabled(), ast_startuptime, ast_strftime(), ast_test_flag, buf, 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.

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

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

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

00488 {
00489    int count = 0;
00490    struct thread_list_t *cur;
00491    switch (cmd) {
00492    case CLI_INIT:
00493       e->command = "core show threads";
00494       e->usage = 
00495          "Usage: core show threads\n"
00496          "       List threads currently active in the system.\n";
00497       return NULL;
00498    case CLI_GENERATE:
00499       return NULL;
00500    }
00501 
00502    AST_RWLIST_RDLOCK(&thread_list);
00503    AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
00504       ast_cli(a->fd, "%p %s\n", (void *)cur->id, cur->name);
00505       count++;
00506    }
00507         AST_RWLIST_UNLOCK(&thread_list);
00508    ast_cli(a->fd, "%d threads listed.\n", count);
00509    return CLI_SUCCESS;
00510 }

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

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

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

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

01820 {
01821    switch (cmd) {
01822    case CLI_INIT:
01823       e->command = "core stop gracefully";
01824       e->usage = 
01825          "Usage: core stop gracefully\n"
01826          "       Causes Asterisk to not accept new calls, and exit when all\n"
01827          "       active calls have terminated normally.\n";
01828       return NULL;
01829    case CLI_GENERATE:
01830       return NULL;
01831    }
01832 
01833    if (a->argc != e->args)
01834       return CLI_SHOWUSAGE;
01835    quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
01836    return CLI_SUCCESS;
01837 }

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

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

01801 {
01802    switch (cmd) {
01803    case CLI_INIT:
01804       e->command = "core stop now";
01805       e->usage = 
01806          "Usage: core stop now\n"
01807          "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
01808       return NULL;
01809    case CLI_GENERATE:
01810       return NULL;
01811    }
01812 
01813    if (a->argc != e->args)
01814       return CLI_SHOWUSAGE;
01815    quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */);
01816    return CLI_SUCCESS;
01817 }

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

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

01840 {
01841    switch (cmd) {
01842    case CLI_INIT:
01843       e->command = "core stop when convenient";
01844       e->usage = 
01845          "Usage: core stop when convenient\n"
01846          "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
01847       return NULL;
01848    case CLI_GENERATE:
01849       return NULL;
01850    }
01851 
01852    if (a->argc != e->args)
01853       return CLI_SHOWUSAGE;
01854    ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
01855    quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
01856    return CLI_SUCCESS;
01857 }

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

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

01770 {
01771    switch (cmd) {
01772    case CLI_INIT:
01773       e->command = "core show version";
01774       e->usage = 
01775          "Usage: core show version\n"
01776          "       Shows Asterisk version information.\n";
01777       return NULL;
01778    case CLI_GENERATE:
01779       return NULL;
01780    }
01781 
01782    if (a->argc != 3)
01783       return CLI_SHOWUSAGE;
01784    ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
01785       ast_get_version(), ast_build_user, ast_build_hostname,
01786       ast_build_machine, ast_build_os, ast_build_date);
01787    return CLI_SUCCESS;
01788 }

static void hup_handler ( int  num  )  [static]

Definition at line 1434 of file asterisk.c.

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

Referenced by main().

01435 {
01436    int a = 0;
01437    if (option_verbose > 1) 
01438       printf("Received HUP signal -- Reloading configs\n");
01439    if (restartnow)
01440       execvp(_argv[0], _argv);
01441    sig_flags.need_reload = 1;
01442    if (sig_alert_pipe[1] != -1) {
01443       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01444          fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
01445       }
01446    }
01447    signal(num, hup_handler);
01448 }

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

Definition at line 1254 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, LOG_ERROR, LOG_WARNING, console::mute, netconsole(), s, and console::uid.

Referenced by ast_makesocket().

01255 {
01256    struct sockaddr_un sunaddr;
01257    int s;
01258    socklen_t len;
01259    int x;
01260    int flags;
01261    struct pollfd fds[1];
01262    for (;;) {
01263       if (ast_socket < 0)
01264          return NULL;
01265       fds[0].fd = ast_socket;
01266       fds[0].events = POLLIN;
01267       s = ast_poll(fds, 1, -1);
01268       pthread_testcancel();
01269       if (s < 0) {
01270          if (errno != EINTR)
01271             ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
01272          continue;
01273       }
01274       len = sizeof(sunaddr);
01275       s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
01276       if (s < 0) {
01277          if (errno != EINTR)
01278             ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
01279       } else {
01280 #if !defined(SO_PASSCRED)
01281          {
01282 #else
01283          int sckopt = 1;
01284          /* turn on socket credentials passing. */
01285          if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
01286             ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
01287          } else {
01288 #endif
01289             for (x = 0; x < AST_MAX_CONNECTS; x++) {
01290                if (consoles[x].fd >= 0) {
01291                   continue;
01292                }
01293                if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
01294                   ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
01295                   consoles[x].fd = -1;
01296                   fdprint(s, "Server failed to create pipe\n");
01297                   close(s);
01298                   break;
01299                }
01300                flags = fcntl(consoles[x].p[1], F_GETFL);
01301                fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
01302                consoles[x].fd = s;
01303                consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
01304                /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
01305                   to know if the user didn't send the credentials. */
01306                consoles[x].uid = -2;
01307                consoles[x].gid = -2;
01308                if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
01309                   ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
01310                   close(consoles[x].p[0]);
01311                   close(consoles[x].p[1]);
01312                   consoles[x].fd = -1;
01313                   fdprint(s, "Server failed to spawn thread\n");
01314                   close(s);
01315                }
01316                break;
01317             }
01318             if (x >= AST_MAX_CONNECTS) {
01319                fdprint(s, "No more connections allowed\n");
01320                ast_log(LOG_WARNING, "No more connections allowed\n");
01321                close(s);
01322             } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
01323                ast_verb(3, "Remote UNIX connection\n");
01324             }
01325          }
01326       }
01327    }
01328    return NULL;
01329 }

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

Definition at line 3094 of file asterisk.c.

References __ast_mm_init(), __quit_handler(), _argv, ARRAY_LEN, ast_alaw_init(), ast_autoservice_init(), ast_builtins_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_device_state_engine_init(), ast_dsp_init(), ast_el_initialize(), ast_el_read_history(), ast_enum_init(), ast_event_init(), ast_fd_init(), 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_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_process_pending_reloads(), ast_pthread_create_detached, ast_readconfig(), ast_register_verbose(), ast_remotecontrol(), 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_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(), buf, callerid_init(), canary_exit(), canary_filename, canary_pid, canary_pipe, canary_thread(), cfg_paths, child_handler(), COLOR_BLACK, COLOR_BRWHITE, _cfg_paths::config_file, console_verboser(), consolehandler(), consolethread, dir, dnsmgr_init(), dnsmgr_start_refresh(), el, el_hist, errno, f, hostname, hup_handler(), init_framer(), init_logger(), init_manager(), load_modules(), load_pbx(), LOG_ERROR, LOG_WARNING, MAXHOSTNAMELEN, monitor_sig_flags(), num, 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(), urg_handler(), and WELCOME_MESSAGE.

03095 {
03096    int c;
03097    char filename[80] = "";
03098    char hostname[MAXHOSTNAMELEN] = "";
03099    char tmp[80];
03100    char * xarg = NULL;
03101    int x;
03102    FILE *f;
03103    sigset_t sigs;
03104    int num;
03105    int isroot = 1;
03106    char *buf;
03107    const char *runuser = NULL, *rungroup = NULL;
03108    char *remotesock = NULL;
03109 
03110    /* Remember original args for restart */
03111    if (argc > ARRAY_LEN(_argv) - 1) {
03112       fprintf(stderr, "Truncating argument size to %d\n", (int)ARRAY_LEN(_argv) - 1);
03113       argc = ARRAY_LEN(_argv) - 1;
03114    }
03115    for (x = 0; x < argc; x++)
03116       _argv[x] = argv[x];
03117    _argv[x] = NULL;
03118 
03119    if (geteuid() != 0)
03120       isroot = 0;
03121 
03122    /* if the progname is rasterisk consider it a remote console */
03123    if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
03124       ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03125    }
03126    if (gethostname(hostname, sizeof(hostname)-1))
03127       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
03128    ast_mainpid = getpid();
03129    ast_ulaw_init();
03130    ast_alaw_init();
03131    callerid_init();
03132    ast_builtins_init();
03133    ast_utils_init();
03134    tdd_init();
03135    ast_tps_init();
03136    ast_fd_init();
03137 
03138    if (getenv("HOME")) 
03139       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
03140    /* Check for options */
03141    while ((c = getopt(argc, argv, "mtThfFdvVqprRgciInx:U:G:C:L:M:e:s:WB")) != -1) {
03142       switch (c) {
03143 #if defined(HAVE_SYSINFO)
03144       case 'e':
03145          if ((sscanf(&optarg[1], "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
03146             option_minmemfree = 0;
03147          }
03148          break;
03149 #endif
03150 #if HAVE_WORKING_FORK
03151       case 'F':
03152          ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
03153          break;
03154       case 'f':
03155          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03156          break;
03157 #endif
03158       case 'd':
03159          option_debug++;
03160          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03161          break;
03162       case 'c':
03163          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
03164          break;
03165       case 'n':
03166          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
03167          break;
03168       case 'r':
03169          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
03170          break;
03171       case 'R':
03172          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
03173          break;
03174       case 'p':
03175          ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
03176          break;
03177       case 'v':
03178          option_verbose++;
03179          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
03180          break;
03181       case 'm':
03182          ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
03183          break;
03184       case 'M':
03185          if ((sscanf(optarg, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0))
03186             option_maxcalls = 0;
03187          break;
03188       case 'L':
03189          if ((sscanf(optarg, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0))
03190             option_maxload = 0.0;
03191          break;
03192       case 'q':
03193          ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
03194          break;
03195       case 't':
03196          ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
03197          break;
03198       case 'T':
03199          ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
03200          break;
03201       case 'x':
03202          ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC);
03203          xarg = ast_strdupa(optarg);
03204          break;
03205       case 'C':
03206          ast_copy_string(cfg_paths.config_file, optarg, sizeof(cfg_paths.config_file));
03207          ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
03208          break;
03209       case 'I':
03210          ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING);
03211          break;
03212       case 'i':
03213          ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
03214          break;
03215       case 'g':
03216          ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
03217          break;
03218       case 'h':
03219          show_cli_help();
03220          exit(0);
03221       case 'V':
03222          show_version();
03223          exit(0);
03224       case 'U':
03225          runuser = ast_strdupa(optarg);
03226          break;
03227       case 'G':
03228          rungroup = ast_strdupa(optarg);
03229          break;
03230       case 's':
03231          remotesock = ast_strdupa(optarg);
03232          break;
03233       case 'W': /* White background */
03234          ast_set_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
03235          ast_clear_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03236          break;
03237       case 'B': /* Force black background */
03238          ast_set_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
03239          ast_clear_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
03240          break;
03241       case '?':
03242          exit(1);
03243       }
03244    }
03245 
03246    if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
03247       if (ast_register_verbose(console_verboser)) {
03248          ast_log(LOG_WARNING, "Unable to register console verboser?\n");
03249       }
03250       WELCOME_MESSAGE;
03251    }
03252 
03253    if (ast_opt_console && !option_verbose) 
03254       ast_verbose("[ Booting...\n");
03255 
03256    /* For remote connections, change the name of the remote connection.
03257     * We do this for the benefit of init scripts (which need to know if/when
03258     * the main asterisk process has died yet). */
03259    if (ast_opt_remote) {
03260       strcpy(argv[0], "rasterisk");
03261       for (x = 1; x < argc; x++) {
03262          argv[x] = argv[0] + 10;
03263       }
03264    }
03265 
03266    if (ast_opt_console && !option_verbose) {
03267       ast_verbose("[ Reading Master Configuration ]\n");
03268    }
03269 
03270    ast_readconfig();
03271 
03272    if (ast_opt_remote && remotesock != NULL)
03273       ast_copy_string((char *) cfg_paths.socket_path, remotesock, sizeof(cfg_paths.socket_path));
03274 
03275    if (!ast_language_is_prefix && !ast_opt_remote)
03276       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");
03277 
03278    if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
03279       ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
03280       ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
03281    }
03282 
03283    if (ast_opt_dump_core) {
03284       struct rlimit l;
03285       memset(&l, 0, sizeof(l));
03286       l.rlim_cur = RLIM_INFINITY;
03287       l.rlim_max = RLIM_INFINITY;
03288       if (setrlimit(RLIMIT_CORE, &l)) {
03289          ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
03290       }
03291    }
03292 
03293    if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
03294       rungroup = ast_config_AST_RUN_GROUP;
03295    if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
03296       runuser = ast_config_AST_RUN_USER;
03297 
03298    /* Must install this signal handler up here to ensure that if the canary
03299     * fails to execute that it doesn't kill the Asterisk process.
03300     */
03301    signal(SIGCHLD, child_handler);
03302 
03303 #ifndef __CYGWIN__
03304 
03305    if (isroot) {
03306       ast_set_priority(ast_opt_high_priority);
03307    }
03308 
03309    if (isroot && rungroup) {
03310       struct group *gr;
03311       gr = getgrnam(rungroup);
03312       if (!gr) {
03313          ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
03314          exit(1);
03315       }
03316       if (setgid(gr->gr_gid)) {
03317          ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
03318          exit(1);
03319       }
03320       if (setgroups(0, NULL)) {
03321          ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
03322          exit(1);
03323       }
03324       if (option_verbose)
03325          ast_verbose("Running as group '%s'\n", rungroup);
03326    }
03327 
03328    if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
03329 #ifdef HAVE_CAP
03330       int has_cap = 1;
03331 #endif /* HAVE_CAP */
03332       struct passwd *pw;
03333       pw = getpwnam(runuser);
03334       if (!pw) {
03335          ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
03336          exit(1);
03337       }
03338 #ifdef HAVE_CAP
03339       if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
03340          ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
03341          has_cap = 0;
03342       }
03343 #endif /* HAVE_CAP */
03344       if (!isroot && pw->pw_uid != geteuid()) {
03345          ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
03346          exit(1);
03347       }
03348       if (!rungroup) {
03349          if (setgid(pw->pw_gid)) {
03350             ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
03351             exit(1);
03352          }
03353          if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
03354             ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser);
03355             exit(1);
03356          }
03357       }
03358       if (setuid(pw->pw_uid)) {
03359          ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
03360          exit(1);
03361       }
03362       if (option_verbose)
03363          ast_verbose("Running as user '%s'\n", runuser);
03364 #ifdef HAVE_CAP
03365       if (has_cap) {
03366          cap_t cap;
03367 
03368          cap = cap_from_text("cap_net_admin=eip");
03369 
03370          if (cap_set_proc(cap))
03371             ast_log(LOG_WARNING, "Unable to install capabilities.\n");
03372 
03373          if (cap_free(cap))
03374             ast_log(LOG_WARNING, "Unable to drop capabilities.\n");
03375       }
03376 #endif /* HAVE_CAP */
03377    }
03378 
03379 #endif /* __CYGWIN__ */
03380 
03381 #ifdef linux
03382    if (geteuid() && ast_opt_dump_core) {
03383       if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
03384          ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
03385       }
03386    }
03387 #endif
03388 
03389    {
03390 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
03391 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
03392 #define eaccess euidaccess
03393 #endif
03394       char dir[PATH_MAX];
03395       if (!getcwd(dir, sizeof(dir)) || eaccess(dir, R_OK | X_OK | F_OK)) {
03396          ast_log(LOG_ERROR, "Unable to access the running directory (%s).  Changing to '/' for compatibility.\n", strerror(errno));
03397          /* If we cannot access the CWD, then we couldn't dump core anyway,
03398           * so chdir("/") won't break anything. */
03399          if (chdir("/")) {
03400             /* chdir(/) should never fail, so this ends up being a no-op */
03401             ast_log(LOG_ERROR, "chdir(\"/\") failed?!! %s\n", strerror(errno));
03402          }
03403       } else
03404 #endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */
03405       if (!ast_opt_no_fork && !ast_opt_dump_core) {
03406          /* Backgrounding, but no cores, so chdir won't break anything. */
03407          if (chdir("/")) {
03408             ast_log(LOG_ERROR, "Unable to chdir(\"/\") ?!! %s\n", strerror(errno));
03409          }
03410       }
03411    }
03412 
03413    ast_term_init();
03414    printf("%s", term_end());
03415    fflush(stdout);
03416 
03417    if (ast_opt_console && !option_verbose) 
03418       ast_verbose("[ Initializing Custom Configuration Options ]\n");
03419    /* custom config setup */
03420    register_config_cli();
03421    read_config_maps();
03422    
03423    if (ast_opt_console) {
03424       if (el_hist == NULL || el == NULL)
03425          ast_el_initialize();
03426 
03427       if (!ast_strlen_zero(filename))
03428          ast_el_read_history(filename);
03429    }
03430 
03431    if (ast_tryconnect()) {
03432       /* One is already running */
03433       if (ast_opt_remote) {
03434          if (ast_opt_exec) {
03435             ast_remotecontrol(xarg);
03436             quit_handler(0, 0, 0, 0);
03437             exit(0);
03438          }
03439          printf("%s", term_quit());
03440          ast_remotecontrol(NULL);
03441          quit_handler(0, 0, 0, 0);
03442          exit(0);
03443       } else {
03444          ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
03445          printf("%s", term_quit());
03446          exit(1);
03447       }
03448    } else if (ast_opt_remote || ast_opt_exec) {
03449       ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
03450       printf("%s", term_quit());
03451       exit(1);
03452    }
03453    /* Blindly write pid file since we couldn't connect */
03454    unlink(ast_config_AST_PID);
03455    f = fopen(ast_config_AST_PID, "w");
03456    if (f) {
03457       fprintf(f, "%ld\n", (long)getpid());
03458       fclose(f);
03459    } else
03460       ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
03461 
03462 #if HAVE_WORKING_FORK
03463    if (ast_opt_always_fork || !ast_opt_no_fork) {
03464 #ifndef HAVE_SBIN_LAUNCHD
03465       if (daemon(1, 0) < 0) {
03466          ast_log(LOG_ERROR, "daemon() failed: %s\n", strerror(errno));
03467       }
03468       ast_mainpid = getpid();
03469       /* Blindly re-write pid file since we are forking */
03470       unlink(ast_config_AST_PID);
03471       f = fopen(ast_config_AST_PID, "w");
03472       if (f) {
03473          fprintf(f, "%ld\n", (long)ast_mainpid);
03474          fclose(f);
03475       } else
03476          ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
03477 #else
03478       ast_log(LOG_WARNING, "Mac OS X detected.  Use '/sbin/launchd -d' to launch with the nofork option.\n");
03479 #endif
03480    }
03481 #endif
03482 
03483    /* Spawning of astcanary must happen AFTER the call to daemon(3) */
03484    if (isroot && ast_opt_high_priority) {
03485       int cpipe[2];
03486 
03487       /* PIPE signal ensures that astcanary dies when Asterisk dies */
03488       if (pipe(cpipe)) {
03489          fprintf(stderr, "Unable to open pipe for canary process: %s\n", strerror(errno));
03490          exit(1);
03491       }
03492       canary_pipe = cpipe[0];
03493 
03494       snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
03495 
03496       /* Don't let the canary child kill Asterisk, if it dies immediately */
03497       signal(SIGPIPE, SIG_IGN);
03498 
03499       canary_pid = fork();
03500       if (canary_pid == 0) {
03501          char canary_binary[128], *lastslash;
03502 
03503          /* Reset signal handler */
03504          signal(SIGCHLD, SIG_DFL);
03505          signal(SIGPIPE, SIG_DFL);
03506 
03507          dup2(cpipe[1], 0);
03508          close(cpipe[1]);
03509          ast_close_fds_above_n(0);
03510          ast_set_priority(0);
03511 
03512          execlp("astcanary", "astcanary", canary_filename, (char *)NULL);
03513 
03514          /* If not found, try the same path as used to execute asterisk */
03515          ast_copy_string(canary_binary, argv[0], sizeof(canary_binary));
03516          if ((lastslash = strrchr(canary_binary, '/'))) {
03517             ast_copy_string(lastslash + 1, "astcanary", sizeof(canary_binary) + canary_binary - (lastslash + 1));
03518             execl(canary_binary, "astcanary", canary_filename, (char *)NULL);
03519          }
03520 
03521          /* Should never happen */
03522          _exit(1);
03523       } else if (canary_pid > 0) {
03524          pthread_t dont_care;
03525          close(cpipe[1]);
03526          ast_pthread_create_detached(&dont_care, NULL, canary_thread, NULL);
03527       }
03528 
03529       /* Kill the canary when we exit */
03530       atexit(canary_exit);
03531    }
03532 
03533    if (ast_event_init()) {
03534       printf("%s", term_quit());
03535       exit(1);
03536    }
03537 
03538    ast_makesocket();
03539    sigemptyset(&sigs);
03540    sigaddset(&sigs, SIGHUP);
03541    sigaddset(&sigs, SIGTERM);
03542    sigaddset(&sigs, SIGINT);
03543    sigaddset(&sigs, SIGPIPE);
03544    sigaddset(&sigs, SIGWINCH);
03545    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
03546    signal(SIGURG, urg_handler);
03547    signal(SIGINT, __quit_handler);
03548    signal(SIGTERM, __quit_handler);
03549    signal(SIGHUP, hup_handler);
03550    signal(SIGPIPE, SIG_IGN);
03551 
03552    /* ensure that the random number generators are seeded with a different value every time
03553       Asterisk is started
03554    */
03555    srand((unsigned int) getpid() + (unsigned int) time(NULL));
03556    initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
03557 
03558    if (init_logger()) {    /* Start logging subsystem */
03559       printf("%s", term_quit());
03560       exit(1);
03561    }
03562 
03563    threadstorage_init();
03564 
03565    astobj2_init();
03566 
03567    ast_autoservice_init();
03568 
03569    if (ast_timing_init()) {
03570       printf("%s", term_quit());
03571       exit(1);
03572    }
03573 
03574    if (ast_ssl_init()) {
03575       printf("%s", term_quit());
03576       exit(1);
03577    }
03578 
03579 #ifdef AST_XML_DOCS
03580    /* Load XML documentation. */
03581    ast_xmldoc_load_documentation();
03582 #endif
03583 
03584    if (load_modules(1)) {     /* Load modules, pre-load only */
03585       printf("%s", term_quit());
03586       exit(1);
03587    }
03588 
03589    if (dnsmgr_init()) {    /* Initialize the DNS manager */
03590       printf("%s", term_quit());
03591       exit(1);
03592    }
03593 
03594    ast_http_init();     /* Start the HTTP server, if needed */
03595 
03596    ast_channels_init();
03597 
03598    if (init_manager()) {
03599       printf("%s", term_quit());
03600       exit(1);
03601    }
03602 
03603    if (ast_cdr_engine_init()) {
03604       printf("%s", term_quit());
03605       exit(1);
03606    }
03607 
03608    if (ast_cel_engine_init()) {
03609       printf("%s", term_quit());
03610       exit(1);
03611    }
03612 
03613    if (ast_device_state_engine_init()) {
03614       printf("%s", term_quit());
03615       exit(1);
03616    }
03617 
03618    ast_dsp_init();
03619    ast_udptl_init();
03620 
03621    if (ast_image_init()) {
03622       printf("%s", term_quit());
03623       exit(1);
03624    }
03625 
03626    if (ast_file_init()) {
03627       printf("%s", term_quit());
03628       exit(1);
03629    }
03630 
03631    if (load_pbx()) {
03632       printf("%s", term_quit());
03633       exit(1);
03634    }
03635 
03636    if (ast_indications_init()) {
03637       printf("%s", term_quit());
03638       exit(1);
03639    }
03640 
03641    ast_features_init();
03642 
03643    if (init_framer()) {
03644       printf("%s", term_quit());
03645       exit(1);
03646    }
03647 
03648    if (astdb_init()) {
03649       printf("%s", term_quit());
03650       exit(1);
03651    }
03652 
03653    if (ast_enum_init()) {
03654       printf("%s", term_quit());
03655       exit(1);
03656    }
03657 
03658    if (load_modules(0)) {
03659       printf("%s", term_quit());
03660       exit(1);
03661    }
03662 
03663    /* loads the cli_permissoins.conf file needed to implement cli restrictions. */
03664    ast_cli_perms_init(0);
03665 
03666    ast_stun_init();
03667 
03668    dnsmgr_start_refresh();
03669 
03670    /* We might have the option of showing a console, but for now just
03671       do nothing... */
03672    if (ast_opt_console && !option_verbose)
03673       ast_verbose(" ]\n");
03674    if (option_verbose || ast_opt_console)
03675       ast_verbose("%s", term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
03676    if (ast_opt_no_fork)
03677       consolethread = pthread_self();
03678 
03679    if (pipe(sig_alert_pipe))
03680       sig_alert_pipe[0] = sig_alert_pipe[1] = -1;
03681 
03682    ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
03683 
03684    ast_process_pending_reloads();
03685 
03686    pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
03687 
03688 #ifdef __AST_DEBUG_MALLOC
03689    __ast_mm_init();
03690 #endif   
03691 
03692    ast_lastreloadtime = ast_startuptime = ast_tvnow();
03693    ast_cli_register_multiple(cli_asterisk, ARRAY_LEN(cli_asterisk));
03694 
03695    run_startup_commands();
03696 
03697    if (ast_opt_console) {
03698       /* Console stuff now... */
03699       /* Register our quit function */
03700       char title[256];
03701       pthread_t dont_care;
03702 
03703       ast_pthread_create_detached(&dont_care, NULL, monitor_sig_flags, NULL);
03704 
03705       set_icon("Asterisk");
03706       snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
03707       set_title(title);
03708 
03709       for (;;) {
03710          buf = (char *) el_gets(el, &num);
03711 
03712          if (!buf && write(1, "", 1) < 0)
03713             goto lostterm;
03714 
03715          if (buf) {
03716             if (buf[strlen(buf)-1] == '\n')
03717                buf[strlen(buf)-1] = '\0';
03718 
03719             consolehandler((char *)buf);
03720          } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
03721                strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) {
03722             /* Whoa, stdout disappeared from under us... Make /dev/null's */
03723             int fd;
03724             fd = open("/dev/null", O_RDWR);
03725             if (fd > -1) {
03726                dup2(fd, STDOUT_FILENO);
03727                dup2(fd, STDIN_FILENO);
03728             } else
03729                ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
03730             break;
03731          }
03732       }
03733    }
03734 
03735    monitor_sig_flags(NULL);
03736 
03737 lostterm:
03738    return 0;
03739 }

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

Definition at line 3016 of file asterisk.c.

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

Referenced by main().

03017 {
03018    for (;;) {
03019       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
03020       int a;
03021       ast_poll(&p, 1, -1);
03022       if (sig_flags.need_reload) {
03023          sig_flags.need_reload = 0;
03024          ast_module_reload(NULL);
03025       }
03026       if (sig_flags.need_quit) {
03027          sig_flags.need_quit = 0;
03028          quit_handler(0, 0, 1, 0);
03029       }
03030       if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
03031       }
03032    }
03033 
03034    return NULL;
03035 }

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

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

01195 {
01196    struct console *con = vconsole;
01197    char hostname[MAXHOSTNAMELEN] = "";
01198    char tmp[512];
01199    int res;
01200    struct pollfd fds[2];
01201    
01202    if (gethostname(hostname, sizeof(hostname)-1))
01203       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
01204    snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
01205    fdprint(con->fd, tmp);
01206    for (;;) {
01207       fds[0].fd = con->fd;
01208       fds[0].events = POLLIN;
01209       fds[0].revents = 0;
01210       fds[1].fd = con->p[0];
01211       fds[1].events = POLLIN;
01212       fds[1].revents = 0;
01213 
01214       res = ast_poll(fds, 2, -1);
01215       if (res < 0) {
01216          if (errno != EINTR)
01217             ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
01218          continue;
01219       }
01220       if (fds[0].revents) {
01221          res = read_credentials(con->fd, tmp, sizeof(tmp) - 1, con);
01222          if (res < 1) {
01223             break;
01224          }
01225          tmp[res] = 0;
01226          if (strncmp(tmp, "cli quit after ", 15) == 0) {
01227             ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res - 15, tmp + 15);
01228             break;
01229          }
01230          ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res, tmp);
01231       }
01232       if (fds[1].revents) {
01233          res = read_credentials(con->p[0], tmp, sizeof(tmp), con);
01234          if (res < 1) {
01235             ast_log(LOG_ERROR, "read returned %d\n", res);
01236             break;
01237          }
01238          res = write(con->fd, tmp, res);
01239          if (res < 1)
01240             break;
01241       }
01242    }
01243    if (!ast_opt_hide_connect) {
01244       ast_verb(3, "Remote UNIX connection disconnected\n");
01245    }
01246    close(con->fd);
01247    close(con->p[0]);
01248    close(con->p[1]);
01249    con->fd = -1;
01250    
01251    return NULL;
01252 }

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

Definition at line 1139 of file asterisk.c.

References __LOG_VERBOSE, and ast_network_puts_mutable().

Referenced by ast_makesocket().

01140 {
01141    ast_network_puts_mutable(s, __LOG_VERBOSE);
01142 }

static void null_sig_handler ( int  sig  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 961 of file asterisk.c.

Referenced by ast_replace_sigchld().

00962 {
00963 
00964 }

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

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

01549 {
01550    char filename[80] = "";
01551    time_t s,e;
01552    int x;
01553    /* Try to get as many CDRs as possible submitted to the backend engines (if in batch mode) */
01554    ast_cdr_engine_term();
01555    if (safeshutdown) {
01556       shuttingdown = 1;
01557       if (!niceness) {
01558          /* Begin shutdown routine, hanging up active channels */
01559          ast_begin_shutdown(1);
01560          if (option_verbose && ast_opt_console)
01561             ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
01562          time(&s);
01563          for (;;) {
01564             time(&e);
01565             /* Wait up to 15 seconds for all channels to go away */
01566             if ((e - s) > 15)
01567                break;
01568             if (!ast_active_channels())
01569                break;
01570             if (!shuttingdown)
01571                break;
01572             /* Sleep 1/10 of a second */
01573             usleep(100000);
01574          }
01575       } else {
01576          if (niceness < 2)
01577             ast_begin_shutdown(0);
01578          if (option_verbose && ast_opt_console)
01579             ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
01580          for (;;) {
01581             if (!ast_active_channels())
01582                break;
01583             if (!shuttingdown)
01584                break;
01585             sleep(1);
01586          }
01587       }
01588 
01589       if (!shuttingdown) {
01590          if (option_verbose && ast_opt_console)
01591             ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
01592          return;
01593       }
01594 
01595       if (niceness)
01596          ast_module_shutdown();
01597    }
01598    if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
01599       if (getenv("HOME")) 
01600          snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
01601       if (!ast_strlen_zero(filename))
01602          ast_el_write_history(filename);
01603       if (el != NULL)
01604          el_end(el);
01605       if (el_hist != NULL)
01606          history_end(el_hist);
01607    }
01608    if (option_verbose)
01609       ast_verbose("Executing last minute cleanups\n");
01610    ast_run_atexits();
01611    /* Called on exit */
01612    if (option_verbose && ast_opt_console)
01613       ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
01614    ast_debug(1, "Asterisk ending (%d).\n", num);
01615    manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
01616    if (ast_socket > -1) {
01617       pthread_cancel(lthread);
01618       close(ast_socket);
01619       ast_socket = -1;
01620       unlink(ast_config_AST_SOCKET);
01621    }
01622    if (ast_consock > -1)
01623       close(ast_consock);
01624    if (!ast_opt_remote)
01625       unlink(ast_config_AST_PID);
01626    printf("%s", term_quit());
01627    if (restart) {
01628       if (option_verbose || ast_opt_console)
01629          ast_verbose("Preparing for Asterisk restart...\n");
01630       /* Mark all FD's for closing on exec */
01631       for (x=3; x < 32768; x++) {
01632          fcntl(x, F_SETFD, FD_CLOEXEC);
01633       }
01634       if (option_verbose || ast_opt_console)
01635          ast_verbose("Asterisk is now restarting...\n");
01636       restartnow = 1;
01637 
01638       /* close logger */
01639       close_logger();
01640 
01641       /* If there is a consolethread running send it a SIGHUP 
01642          so it can execvp, otherwise we can do it ourselves */
01643       if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
01644          pthread_kill(consolethread, SIGHUP);
01645          /* Give the signal handler some time to complete */
01646          sleep(2);
01647       } else
01648          execvp(_argv[0], _argv);
01649    
01650    } else {
01651       /* close logger */
01652       close_logger();
01653    }
01654    exit(0);
01655 }

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 731 of file asterisk.c.

Referenced by ast_mark().

00732 {
00733    return 0;
00734 }

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

References console::gid, and console::uid.

Referenced by netconsole().

01157 {
01158 #if defined(SO_PEERCRED)
01159    struct ucred cred;
01160    socklen_t len = sizeof(cred);
01161 #endif
01162 #if defined(HAVE_GETPEEREID)
01163    uid_t uid;
01164    gid_t gid;
01165 #else
01166    int uid, gid;
01167 #endif
01168    int result;
01169 
01170    result = read(fd, buffer, size);
01171    if (result < 0) {
01172       return result;
01173    }
01174 
01175 #if defined(SO_PEERCRED)
01176    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
01177       return result;
01178    }
01179    uid = cred.uid;
01180    gid = cred.gid;
01181 #elif defined(HAVE_GETPEEREID)
01182    if (getpeereid(fd, &uid, &gid)) {
01183       return result;
01184    }
01185 #else
01186    return result;
01187 #endif
01188    con->uid = uid;
01189    con->gid = gid;
01190 
01191    return result;
01192 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1745 of file asterisk.c.

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

Referenced by ast_remotecontrol().

01746 {
01747    int ret = 0;
01748 
01749    /* Called when readline data is available */
01750    if (!ast_all_zeros(s))
01751       ast_el_add_history(s);
01752    /* The real handler for bang */
01753    if (s[0] == '!') {
01754       if (s[1])
01755          ast_safe_system(s+1);
01756       else
01757          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01758       ret = 1;
01759    }
01760    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
01761        (s[4] == '\0' || isspace(s[4]))) {
01762       quit_handler(0, 0, 0, 0);
01763       ret = 1;
01764    }
01765 
01766    return ret;
01767 }

static void run_startup_commands ( void   )  [static]

Definition at line 3066 of file asterisk.c.

References ast_cli_command, ast_config_destroy(), ast_config_load2(), ast_true(), ast_variable_browse(), CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by main().

03067 {
03068    int fd;
03069    struct ast_config *cfg;
03070    struct ast_flags cfg_flags = { 0 };
03071    struct ast_variable *v;
03072 
03073    if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
03074       return;
03075    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03076       return;
03077    }
03078 
03079    fd = open("/dev/null", O_RDWR);
03080    if (fd < 0) {
03081       ast_config_destroy(cfg);
03082       return;
03083    }
03084 
03085    for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
03086       if (ast_true(v->value))
03087          ast_cli_command(fd, v->name);
03088    }
03089 
03090    close(fd);
03091    ast_config_destroy(cfg);
03092 }

static void set_icon ( char *  text  )  [static]

Definition at line 1495 of file asterisk.c.

Referenced by main().

01496 {
01497    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01498       fprintf(stdout, "\033]1;%s\007", text);
01499 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1489 of file asterisk.c.

Referenced by main().

01490 {
01491    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01492       fprintf(stdout, "\033]2;%s\007", text);
01493 }

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1466 of file asterisk.c.

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

Referenced by ast_readconfig().

01467 {
01468    struct rlimit l = {0, 0};
01469    
01470    if (value <= 0) {
01471       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01472       return;
01473    }
01474    
01475    l.rlim_cur = value;
01476    l.rlim_max = value;
01477    
01478    if (setrlimit(RLIMIT_NOFILE, &l)) {
01479       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01480       return;
01481    }
01482    
01483    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01484    
01485    return;
01486 }

static int show_cli_help ( void   )  [static]

Definition at line 2745 of file asterisk.c.

References ast_get_version().

Referenced by main().

02745                                {
02746    printf("Asterisk %s, Copyright (C) 1999 - 2009, Digium, Inc. and others.\n", ast_get_version());
02747    printf("Usage: asterisk [OPTIONS]\n");
02748    printf("Valid Options:\n");
02749    printf("   -V              Display version number and exit\n");
02750    printf("   -C <configfile> Use an alternate configuration file\n");
02751    printf("   -G <group>      Run as a group other than the caller\n");
02752    printf("   -U <user>       Run as a user other than the caller\n");
02753    printf("   -c              Provide console CLI\n");
02754    printf("   -d              Enable extra debugging\n");
02755 #if HAVE_WORKING_FORK
02756    printf("   -f              Do not fork\n");
02757    printf("   -F              Always fork\n");
02758 #endif
02759    printf("   -g              Dump core in case of a crash\n");
02760    printf("   -h              This help screen\n");
02761    printf("   -i              Initialize crypto keys at startup\n");
02762    printf("   -I              Enable internal timing if DAHDI timer is available\n");
02763    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
02764    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
02765    printf("   -m              Mute debugging and console output on the console\n");
02766    printf("   -n              Disable console colorization\n");
02767    printf("   -p              Run as pseudo-realtime thread\n");
02768    printf("   -q              Quiet mode (suppress output)\n");
02769    printf("   -r              Connect to Asterisk on this machine\n");
02770    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
02771    printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
02772    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
02773    printf("                   belong after they are done\n");
02774    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
02775    printf("                   of output to the CLI\n");
02776    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
02777    printf("   -x <cmd>        Execute command <cmd> (only valid with -r)\n");
02778    printf("   -W              Adjust terminal colors to compensate for a light background\n");
02779    printf("\n");
02780    return 0;
02781 }

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

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

02018 {
02019    switch (cmd) {
02020    case CLI_INIT:
02021       e->command = "core show license";
02022       e->usage = 
02023          "Usage: core show license\n"
02024          "       Shows the license(s) for this copy of Asterisk.\n";
02025       return NULL;
02026    case CLI_GENERATE:
02027       return NULL;
02028    }
02029 
02030    ast_cli(a->fd, "%s", license_lines);
02031 
02032    return CLI_SUCCESS;
02033 }

static int show_version ( void   )  [static]

Definition at line 2739 of file asterisk.c.

References ast_get_version().

Referenced by main().

02740 {
02741    printf("Asterisk %s\n", ast_get_version());
02742    return 0;
02743 }

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

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

01981 {
01982    switch (cmd) {
01983    case CLI_INIT:
01984       e->command = "core show warranty";
01985       e->usage = 
01986          "Usage: core show warranty\n"
01987          "       Shows the warranty (if any) for this copy of Asterisk.\n";
01988       return NULL;
01989    case CLI_GENERATE:
01990       return NULL;
01991    }
01992 
01993    ast_cli(a->fd, "%s", warranty_lines);
01994 
01995    return CLI_SUCCESS;
01996 }

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

Referenced by main().

01429 {
01430    signal(num, urg_handler);
01431    return;
01432 }


Variable Documentation

char* _argv[256] [static]

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

Referenced by launch_script().

const char* ast_config_AST_CONFIG_DIR = cfg_paths.config_dir

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

Referenced by ast_readconfig().

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

Definition at line 267 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

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

Definition at line 266 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static]

Definition at line 265 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

const char* ast_config_AST_DATA_DIR = cfg_paths.data_dir

const char* ast_config_AST_DB = cfg_paths.db_path

Definition at line 258 of file asterisk.c.

Referenced by dbinit().

const char* ast_config_AST_KEY_DIR = cfg_paths.key_dir

Definition at line 255 of file asterisk.c.

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

const char* ast_config_AST_LOG_DIR = cfg_paths.log_dir

const char* ast_config_AST_MODULE_DIR = cfg_paths.module_dir

const char* ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir

const char* ast_config_AST_PID = cfg_paths.pid_path

Definition at line 259 of file asterisk.c.

Referenced by main(), and quit_handler().

const char* ast_config_AST_RUN_DIR = cfg_paths.run_dir

Definition at line 256 of file asterisk.c.

Referenced by launch_script(), and main().

const char* ast_config_AST_RUN_GROUP = cfg_paths.run_group

Definition at line 262 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 261 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 260 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

const char* ast_config_AST_SYSTEM_NAME = cfg_paths.system_name

const char* ast_config_AST_VAR_DIR = cfg_paths.var_dir

Definition at line 251 of file asterisk.c.

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

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

Definition at line 189 of file asterisk.c.

Global EID.

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

Definition at line 183 of file asterisk.c.

Referenced by ast_event_cb(), ast_event_new(), ast_readconfig(), ast_str_retrieve_variable(), evt_event_deliver_cb(), handle_show_settings(), and set_config().

struct timeval ast_lastreloadtime

pid_t ast_mainpid

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

struct timeval ast_startuptime

char canary_filename[128] [static]

Definition at line 275 of file asterisk.c.

Referenced by canary_thread(), and main().

int canary_pid = 0 [static]

Definition at line 274 of file asterisk.c.

Referenced by canary_exit(), and main().

int canary_pipe = -1 [static]

Definition at line 276 of file asterisk.c.

Referenced by main().

struct _cfg_paths cfg_paths [static]

Definition at line 244 of file asterisk.c.

Referenced by ast_readconfig(), and main().

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 2039 of file asterisk.c.

struct console consoles[AST_MAX_CONNECTS]

pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 273 of file asterisk.c.

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

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 217 of file asterisk.c.

Referenced by __ast_channel_alloc_ap(), and handle_show_settings().

EditLine* el [static]

History* el_hist [static]

const char license_lines[] [static]

Definition at line 1998 of file asterisk.c.

pthread_t lthread [static]

Definition at line 1144 of file asterisk.c.

Referenced by ast_makesocket(), and quit_handler().

unsigned int need_quit

Definition at line 283 of file asterisk.c.

unsigned int need_reload

Definition at line 282 of file asterisk.c.

struct profile_data* prof_data [static]

struct ast_str* prompt = NULL [static]

Definition at line 2161 of file asterisk.c.

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

char randompool[256] [static]

Definition at line 278 of file asterisk.c.

Referenced by main().

char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR

Definition at line 186 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 213 of file asterisk.c.

Referenced by ast_remotecontrol(), and cli_prompt().

int restartnow [static]

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

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

ast_mutex_t safe_system_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 966 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

void* safe_system_prev_handler [static]

Definition at line 970 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

int shuttingdown [static]

Definition at line 271 of file asterisk.c.

Referenced by handle_abort_shutdown(), and quit_handler().

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

Definition at line 280 of file asterisk.c.

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

struct { ... } sig_flags [static]

const char warranty_lines[] [static]

Definition at line 1955 of file asterisk.c.


Generated on Wed Oct 28 13:31:46 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6