Fri Feb 10 06:34:56 2012

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/translate.h"
#include "asterisk/features.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/image.h"
#include "asterisk/tdd.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/cdr.h"
#include "asterisk/cel.h"
#include "asterisk/pbx.h"
#include "asterisk/enum.h"
#include "asterisk/http.h"
#include "asterisk/udptl.h"
#include "asterisk/app.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/io.h"
#include "editline/histedit.h"
#include "asterisk/config.h"
#include "asterisk/ast_version.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"
#include "asterisk/module.h"
#include "asterisk/dsp.h"
#include "asterisk/buildinfo.h"
#include "asterisk/xmldoc.h"
#include "asterisk/poll-compat.h"
#include "asterisk/ccss.h"
#include "asterisk/test.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/format.h"
#include "asterisk/aoc.h"
#include "../defaults.h"

Go to the source code of this file.

Data Structures

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

Defines

#define AF_LOCAL   AF_UNIX
#define AST_MAX_CONNECTS   128
#define ASTERISK_PROMPT   "*CLI> "
#define ASTERISK_PROMPT2   "%s*CLI> "
#define DEFINE_PROFILE_MIN_MAX_VALUES
#define EL_BUF_SIZE   512
#define FORMAT   "%-25.25s %-40.40s\n"
#define MAX_HISTORY_COMMAND_LENGTH   256
#define NUM_MSGS   64
#define PF_LOCAL   PF_UNIX
#define WELCOME_MESSAGE
 Welcome message when starting a CLI interface.

Enumerations

enum  shutdown_nice_t {
  NOT_SHUTTING_DOWN = -2, SHUTTING_DOWN = -1, SHUTDOWN_FAST, SHUTDOWN_NORMAL,
  SHUTDOWN_NICE, SHUTDOWN_REALLY_NICE
}

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)
static void _child_handler (int sig)
static void _hup_handler (int num)
static void _null_sig_handler (int sig)
 NULL handler so we can collect the child exit status.
static void _urg_handler (int num)
 Urgent handler.
int ast_add_profile (const char *name, uint64_t scale)
 allocates a counter with a given name and scale.
static int ast_all_zeros (char *s)
static int ast_cli_display_match_list (char **matches, int len, int max)
char * ast_complete_source_filename (const char *partial, int n)
void ast_console_puts (const char *string)
void ast_console_puts_mutable (const char *string, int level)
 log the string to the console, and all attached console clients
void ast_console_toggle_loglevel (int fd, int level, int state)
 enable or disable a logging level to a specified console
void ast_console_toggle_mute (int fd, int silent)
 mute or unmute a console from logging
static int ast_el_add_history (char *)
static int ast_el_initialize (void)
static int ast_el_read_char (EditLine *editline, char *cp)
static int ast_el_read_history (char *)
static int ast_el_sort_compare (const void *i1, const void *i2)
static char ** ast_el_strtoarr (char *buf)
static int ast_el_write_history (char *)
const char * ast_file_version_find (const char *file)
 Find version for given module name.
static int ast_makesocket (void)
int64_t ast_mark (int i, int startstop)
static void ast_network_puts (const char *string)
 write the string to all attached console clients
static void ast_network_puts_mutable (const char *string, int level)
 log the string to all attached console clients
int64_t ast_profile (int i, int64_t delta)
static void ast_readconfig (void)
int ast_register_atexit (void(*func)(void))
 Register a function to be executed before Asterisk exits.
void ast_register_file_version (const char *file, const char *version)
 Register the version of a source code file with the core.
void ast_register_thread (char *name)
static void ast_remotecontrol (char *data)
void ast_replace_sigchld (void)
 Replace the SIGCHLD handler.
static void ast_run_atexits (void)
int ast_safe_system (const char *s)
 Safely spawn an external program while closing file descriptors.
int ast_set_priority (int pri)
 We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy activity on it, this is a good thing.
static int ast_tryconnect (void)
void ast_unregister_atexit (void(*func)(void))
 Unregister a function registered with ast_register_atexit().
void ast_unregister_file_version (const char *file)
 Unregister a source code file from the core.
void ast_unregister_thread (void *id)
void ast_unreplace_sigchld (void)
 Restore the SIGCHLD handler.
static int can_safely_quit (shutdown_nice_t niceness, int restart)
static void canary_exit (void)
static void * canary_thread (void *unused)
static char * cli_complete (EditLine *editline, int ch)
static char * cli_prompt (EditLine *editline)
static void console_verboser (const char *s)
static void consolehandler (char *s)
static void env_init (void)
static int fdprint (int fd, const char *s)
static int fdsend (int fd, const char *s)
static const char * fix_header (char *outbuf, int maxout, const char *s, char *cmp)
static char * handle_abort_shutdown (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_bang (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_clear_profile (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_restart_gracefully (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_restart_now (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_restart_when_convenient (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_show_profile (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Give an overview of core settings.
static char * handle_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_show_version_files (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to list module versions.
static char * handle_stop_gracefully (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_stop_now (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_stop_when_convenient (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_version (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void * listener (void *unused)
int main (int argc, char *argv[])
static void * monitor_sig_flags (void *unused)
static void * netconsole (void *vconsole)
static void network_verboser (const char *s)
static void quit_handler (int num, shutdown_nice_t niceness, int restart)
static __inline uint64_t rdtsc (void)
static int read_credentials (int fd, char *buffer, size_t size, struct console *con)
 read() function supporting the reception of user credentials.
static void really_quit (int num, shutdown_nice_t niceness, int restart)
static int remoteconsolehandler (char *s)
static void run_startup_commands (void)
static void set_icon (char *text)
static void set_title (char *text)
 Set an X-term or screen title.
static void set_ulimit (int value)
 Set maximum open files.
static int show_cli_help (void)
static char * show_license (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int show_version (void)
static char * show_warranty (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Variables

static char * _argv [256]
struct ast_flags ast_compat = { 0 }
const char * ast_config_AST_AGI_DIR = cfg_paths.agi_dir
const char * ast_config_AST_CONFIG_DIR = cfg_paths.config_dir
const char * ast_config_AST_CONFIG_FILE = cfg_paths.config_file
static char ast_config_AST_CTL [PATH_MAX] = "asterisk.ctl"
static char ast_config_AST_CTL_GROUP [PATH_MAX] = "\0"
static char ast_config_AST_CTL_OWNER [PATH_MAX] = "\0"
static char ast_config_AST_CTL_PERMISSIONS [PATH_MAX]
const char * ast_config_AST_DATA_DIR = cfg_paths.data_dir
const char * ast_config_AST_DB = cfg_paths.db_path
const char * ast_config_AST_KEY_DIR = cfg_paths.key_dir
const char * ast_config_AST_LOG_DIR = cfg_paths.log_dir
const char * ast_config_AST_MODULE_DIR = cfg_paths.module_dir
const char * ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir
const char * ast_config_AST_PID = cfg_paths.pid_path
const char * ast_config_AST_RUN_DIR = cfg_paths.run_dir
const char * ast_config_AST_RUN_GROUP = cfg_paths.run_group
const char * ast_config_AST_RUN_USER = cfg_paths.run_user
const char * ast_config_AST_SBIN_DIR = cfg_paths.sbin_dir
const char * ast_config_AST_SOCKET = cfg_paths.socket_path
const char * ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir
const char * ast_config_AST_SYSTEM_NAME = cfg_paths.system_name
const char * ast_config_AST_VAR_DIR = cfg_paths.var_dir
static int ast_consock = -1
struct ast_eid ast_eid_default
 Global EID.
unsigned int ast_FD_SETSIZE
struct timeval ast_lastreloadtime
pid_t ast_mainpid
struct ast_flags ast_options = { AST_DEFAULT_OPTIONS }
static int ast_socket = -1
struct timeval ast_startuptime
static char canary_filename [128]
static int canary_pid = 0
static struct _cfg_paths cfg_paths
static struct sigaction child_handler
static struct ast_cli_entry cli_asterisk []
struct console consoles [AST_MAX_CONNECTS]
static pthread_t consolethread = AST_PTHREADT_NULL
char defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE
static EditLine * el
static History * el_hist
static struct sigaction hup_handler
static struct sigaction ignore_sig_handler
static const char license_lines []
static pthread_t lthread
static pthread_t mon_sig_flags
static struct sigaction null_sig_handler
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 = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static struct sigaction safe_system_prev_handler
static shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN
static int sig_alert_pipe [2] = { -1, -1 }
struct {
   unsigned int   need_quit:1
   unsigned int   need_quit_handler:1
   unsigned int   need_reload:1
sig_flags
static struct sigaction urg_handler
static const char warranty_lines []


Detailed Description

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

Definition in file asterisk.c.


Define Documentation

#define AF_LOCAL   AF_UNIX

Definition at line 153 of file asterisk.c.

#define AST_MAX_CONNECTS   128

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 2173 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 2175 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

Definition at line 788 of file asterisk.c.

Referenced by handle_clear_profile(), and handle_show_profile().

#define EL_BUF_SIZE   512

Referenced by ast_el_read_char().

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

#define MAX_HISTORY_COMMAND_LENGTH   256

Definition at line 2701 of file asterisk.c.

Referenced by ast_el_add_history(), and ast_el_read_history().

#define NUM_MSGS   64

Definition at line 158 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

Definition at line 154 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 161 of file asterisk.c.

Referenced by ast_el_read_char(), and main().


Enumeration Type Documentation

Enumerator:
NOT_SHUTTING_DOWN 
SHUTTING_DOWN 
SHUTDOWN_FAST 
SHUTDOWN_NORMAL 
SHUTDOWN_NICE 
SHUTDOWN_REALLY_NICE 

Definition at line 283 of file asterisk.c.

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


Function Documentation

static void __fini_atexits ( void   )  [static]

Definition at line 214 of file asterisk.c.

00231 {

static void __fini_file_versions ( void   )  [static]

Definition at line 315 of file asterisk.c.

00318 {

static void __fini_thread_list ( void   )  [static]

Definition at line 399 of file asterisk.c.

00402 { 

static void __init_atexits ( void   )  [static]

Definition at line 214 of file asterisk.c.

00231 {

static void __init_file_versions ( void   )  [static]

Definition at line 315 of file asterisk.c.

00318 {

static void __init_thread_list ( void   )  [static]

Definition at line 399 of file asterisk.c.

00402 { 

static void __quit_handler ( int  num  )  [static]

Definition at line 1783 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

01784 {
01785    int a = 0;
01786    sig_flags.need_quit = 1;
01787    if (sig_alert_pipe[1] != -1) {
01788       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01789          fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
01790       }
01791    }
01792    /* There is no need to restore the signal handler here, since the app
01793     * is going to exit */
01794 }

static void __remote_quit_handler ( int  num  )  [static]

Definition at line 1796 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

01797 {
01798    sig_flags.need_quit = 1;
01799 }

static void _child_handler ( int  sig  )  [static]

Definition at line 1523 of file asterisk.c.

References errno, and status.

01524 {
01525    /* Must not ever ast_log or ast_verbose within signal handler */
01526    int n, status, save_errno = errno;
01527 
01528    /*
01529     * Reap all dead children -- not just one
01530     */
01531    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01532       ;
01533    if (n == 0 && option_debug)   
01534       printf("Huh?  Child handler, but nobody there?\n");
01535    errno = save_errno;
01536 }

static void _hup_handler ( int  num  )  [static]

Definition at line 1502 of file asterisk.c.

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

01503 {
01504    int a = 0, save_errno = errno;
01505    if (option_verbose > 1) 
01506       printf("Received HUP signal -- Reloading configs\n");
01507    if (restartnow)
01508       execvp(_argv[0], _argv);
01509    sig_flags.need_reload = 1;
01510    if (sig_alert_pipe[1] != -1) {
01511       if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
01512          fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
01513       }
01514    }
01515    errno = save_errno;
01516 }

static void _null_sig_handler ( int  sig  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 996 of file asterisk.c.

00997 {
00998 }

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

01493 {
01494    return;
01495 }

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

allocates a counter with a given name and scale.

support for event profiling

Returns:
Returns the identifier of the counter.

Definition at line 707 of file asterisk.c.

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

Referenced by extension_match_core().

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

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1844 of file asterisk.c.

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

01845 {
01846    while (*s) {
01847       if (*s > 32)
01848          return 0;
01849       s++;  
01850    }
01851    return 1;
01852 }

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

Definition at line 2482 of file asterisk.c.

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

Referenced by cli_complete().

02483 {
02484    int i, idx, limit, count;
02485    int screenwidth = 0;
02486    int numoutput = 0, numoutputline = 0;
02487 
02488    screenwidth = ast_get_termcols(STDOUT_FILENO);
02489 
02490    /* find out how many entries can be put on one line, with two spaces between strings */
02491    limit = screenwidth / (max + 2);
02492    if (limit == 0)
02493       limit = 1;
02494 
02495    /* how many lines of output */
02496    count = len / limit;
02497    if (count * limit < len)
02498       count++;
02499 
02500    idx = 1;
02501 
02502    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
02503 
02504    for (; count > 0; count--) {
02505       numoutputline = 0;
02506       for (i = 0; i < limit && matches[idx]; i++, idx++) {
02507 
02508          /* Don't print dupes */
02509          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
02510             i--;
02511             ast_free(matches[idx]);
02512             matches[idx] = NULL;
02513             continue;
02514          }
02515 
02516          numoutput++;
02517          numoutputline++;
02518          fprintf(stdout, "%-*s  ", max, matches[idx]);
02519          ast_free(matches[idx]);
02520          matches[idx] = NULL;
02521       }
02522       if (numoutputline > 0)
02523          fprintf(stdout, "\n");
02524    }
02525 
02526    return numoutput;
02527 }

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

Definition at line 356 of file asterisk.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, file_version::file, len(), and ast_atexit::list.

Referenced by handle_verbose().

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

void ast_console_puts ( const char *  string  ) 

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

Definition at line 1185 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

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

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

References ast_network_puts_mutable().

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

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

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

enable or disable a logging level to a specified console

enables or disables logging of a specified level to the console fd specifies the index of the console receiving the level change level specifies the index of the logging level being toggled state indicates whether logging will be on or off (0 for off, 1 for on)

Definition at line 1104 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and console::levels.

Referenced by handle_logger_set_level().

01105 {
01106    int x;
01107    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01108       if (fd == consoles[x].fd) {
01109          /*
01110           * Since the logging occurs when levels are false, set to
01111           * flipped iinput because this function accepts 0 as off and 1 as on
01112           */
01113          consoles[x].levels[level] = state ? 0 : 1;
01114          return;
01115       }
01116    }
01117 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1122 of file asterisk.c.

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

Referenced by handle_logger_mute().

01123 {
01124    int x;
01125    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01126       if (fd == consoles[x].fd) {
01127          if (consoles[x].mute) {
01128             consoles[x].mute = 0;
01129             if (!silent)
01130                ast_cli(fd, "Console is not muted anymore.\n");
01131          } else {
01132             consoles[x].mute = 1;
01133             if (!silent)
01134                ast_cli(fd, "Console is muted.\n");
01135          }
01136          return;
01137       }
01138    }
01139    ast_cli(fd, "Couldn't find remote console.\n");
01140 }

static int ast_el_add_history ( char *  buf  )  [static]

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

02704 {
02705    HistEvent ev;
02706 
02707    if (el_hist == NULL || el == NULL)
02708       ast_el_initialize();
02709    if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1))
02710       return 0;
02711    return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf))));
02712 }

static int ast_el_initialize ( void   )  [static]

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

02649 {
02650    HistEvent ev;
02651    char *editor, *editrc = getenv("EDITRC");
02652 
02653    if (!(editor = getenv("AST_EDITMODE"))) {
02654       if (!(editor = getenv("AST_EDITOR"))) {
02655          editor = "emacs";
02656       }
02657    }
02658 
02659    if (el != NULL)
02660       el_end(el);
02661    if (el_hist != NULL)
02662       history_end(el_hist);
02663 
02664    el = el_init("asterisk", stdin, stdout, stderr);
02665    el_set(el, EL_PROMPT, cli_prompt);
02666 
02667    el_set(el, EL_EDITMODE, 1);      
02668    el_set(el, EL_EDITOR, editor);
02669    el_hist = history_init();
02670    if (!el || !el_hist)
02671       return -1;
02672 
02673    /* setup history with 100 entries */
02674    history(el_hist, &ev, H_SETSIZE, 100);
02675 
02676    el_set(el, EL_HIST, history, el_hist);
02677 
02678    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02679    /* Bind <tab> to command completion */
02680    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02681    /* Bind ? to command completion */
02682    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02683    /* Bind ^D to redisplay */
02684    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02685    /* Bind Delete to delete char left */
02686    el_set(el, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
02687    /* Bind Home and End to move to line start and end */
02688    el_set(el, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
02689    el_set(el, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
02690    /* Bind C-left and C-right to move by word (not all terminals) */
02691    el_set(el, EL_BIND, "\\eOC", "vi-next-word", NULL);
02692    el_set(el, EL_BIND, "\\eOD", "vi-prev-word", NULL);
02693 
02694    if (editrc) {
02695       el_source(el, editrc);
02696    }
02697 
02698    return 0;
02699 }

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

Definition at line 2201 of file asterisk.c.

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

Referenced by ast_remotecontrol(), and main().

02202 {
02203    int num_read = 0;
02204    int lastpos = 0;
02205    struct pollfd fds[2];
02206    int res;
02207    int max;
02208 #define EL_BUF_SIZE 512
02209    char buf[EL_BUF_SIZE];
02210 
02211    for (;;) {
02212       max = 1;
02213       fds[0].fd = ast_consock;
02214       fds[0].events = POLLIN;
02215       if (!ast_opt_exec) {
02216          fds[1].fd = STDIN_FILENO;
02217          fds[1].events = POLLIN;
02218          max++;
02219       }
02220       res = ast_poll(fds, max, -1);
02221       if (res < 0) {
02222          if (sig_flags.need_quit || sig_flags.need_quit_handler)
02223             break;
02224          if (errno == EINTR)
02225             continue;
02226          ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
02227          break;
02228       }
02229 
02230       if (!ast_opt_exec && fds[1].revents) {
02231          num_read = read(STDIN_FILENO, cp, 1);
02232          if (num_read < 1) {
02233             break;
02234          } else {
02235             return (num_read);
02236          }
02237       }
02238       if (fds[0].revents) {
02239          char *tmp;
02240          res = read(ast_consock, buf, sizeof(buf) - 1);
02241          /* if the remote side disappears exit */
02242          if (res < 1) {
02243             fprintf(stderr, "\nDisconnected from Asterisk server\n");
02244             if (!ast_opt_reconnect) {
02245                quit_handler(0, SHUTDOWN_FAST, 0);
02246             } else {
02247                int tries;
02248                int reconnects_per_second = 20;
02249                fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
02250                for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
02251                   if (ast_tryconnect()) {
02252                      fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
02253                      printf("%s", term_quit());
02254                      WELCOME_MESSAGE;
02255                      if (!ast_opt_mute)
02256                         fdsend(ast_consock, "logger mute silent");
02257                      else 
02258                         printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02259                      break;
02260                   } else
02261                      usleep(1000000 / reconnects_per_second);
02262                }
02263                if (tries >= 30 * reconnects_per_second) {
02264                   fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
02265                   quit_handler(0, SHUTDOWN_FAST, 0);
02266                }
02267             }
02268          }
02269 
02270          buf[res] = '\0';
02271 
02272          /* Strip preamble from asynchronous events, too */
02273          for (tmp = buf; *tmp; tmp++) {
02274             if (*tmp == 127) {
02275                memmove(tmp, tmp + 1, strlen(tmp));
02276                tmp--;
02277                res--;
02278             }
02279          }
02280 
02281          /* Write over the CLI prompt */
02282          if (!ast_opt_exec && !lastpos) {
02283             if (write(STDOUT_FILENO, "\r", 5) < 0) {
02284             }
02285          }
02286          if (write(STDOUT_FILENO, buf, res) < 0) {
02287          }
02288          if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
02289             *cp = CC_REFRESH;
02290             return(1);
02291          } else
02292             lastpos = 1;
02293       }
02294    }
02295 
02296    *cp = '\0';
02297    return (0);
02298 }

static int ast_el_read_history ( char *  filename  )  [static]

Definition at line 2724 of file asterisk.c.

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

Referenced by ast_remotecontrol(), and main().

02725 {
02726    char buf[MAX_HISTORY_COMMAND_LENGTH];
02727    FILE *f;
02728    int ret = -1;
02729 
02730    if (el_hist == NULL || el == NULL)
02731       ast_el_initialize();
02732 
02733    if ((f = fopen(filename, "r")) == NULL)
02734       return ret;
02735 
02736    while (!feof(f)) {
02737       if (!fgets(buf, sizeof(buf), f))
02738          break;
02739       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02740          continue;
02741       if (ast_all_zeros(buf))
02742          continue;
02743       if ((ret = ast_el_add_history(buf)) == -1)
02744          break;
02745    }
02746    fclose(f);
02747 
02748    return ret;
02749 }

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

Definition at line 2472 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02473 {
02474    char *s1, *s2;
02475 
02476    s1 = ((char **)i1)[0];
02477    s2 = ((char **)i2)[0];
02478 
02479    return strcasecmp(s1, s2);
02480 }

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

Definition at line 2429 of file asterisk.c.

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

Referenced by cli_complete().

02430 {
02431    char **match_list = NULL, **match_list_tmp, *retstr;
02432    size_t match_list_len;
02433    int matches = 0;
02434 
02435    match_list_len = 1;
02436    while ( (retstr = strsep(&buf, " ")) != NULL) {
02437 
02438       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
02439          break;
02440       if (matches + 1 >= match_list_len) {
02441          match_list_len <<= 1;
02442          if ((match_list_tmp = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
02443             match_list = match_list_tmp;
02444          } else {
02445             if (match_list)
02446                ast_free(match_list);
02447             return (char **) NULL;
02448          }
02449       }
02450 
02451       match_list[matches++] = ast_strdup(retstr);
02452    }
02453 
02454    if (!match_list)
02455       return (char **) NULL;
02456 
02457    if (matches >= match_list_len) {
02458       if ((match_list_tmp = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
02459          match_list = match_list_tmp;
02460       } else {
02461          if (match_list)
02462             ast_free(match_list);
02463          return (char **) NULL;
02464       }
02465    }
02466 
02467    match_list[matches] = (char *) NULL;
02468 
02469    return match_list;
02470 }

static int ast_el_write_history ( char *  filename  )  [static]

Definition at line 2714 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by really_quit().

02715 {
02716    HistEvent ev;
02717 
02718    if (el_hist == NULL || el == NULL)
02719       ast_el_initialize();
02720 
02721    return (history(el_hist, &ev, H_SAVE, filename));
02722 }

const char* ast_file_version_find ( const char *  file  ) 

Find version for given module name.

Parameters:
file Module name (i.e. chan_sip.so)
Returns:
version string or NULL if the module is not found

Definition at line 375 of file asterisk.c.

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

Referenced by manager_modulecheck().

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

static int ast_makesocket ( void   )  [static]

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

01396 {
01397    struct sockaddr_un sunaddr;
01398    int res;
01399    int x;
01400    uid_t uid = -1;
01401    gid_t gid = -1;
01402 
01403    for (x = 0; x < AST_MAX_CONNECTS; x++) 
01404       consoles[x].fd = -1;
01405    unlink(ast_config_AST_SOCKET);
01406    ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
01407    if (ast_socket < 0) {
01408       ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
01409       return -1;
01410    }     
01411    memset(&sunaddr, 0, sizeof(sunaddr));
01412    sunaddr.sun_family = AF_LOCAL;
01413    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01414    res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01415    if (res) {
01416       ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01417       close(ast_socket);
01418       ast_socket = -1;
01419       return -1;
01420    }
01421    res = listen(ast_socket, 2);
01422    if (res < 0) {
01423       ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01424       close(ast_socket);
01425       ast_socket = -1;
01426       return -1;
01427    }
01428    if (ast_register_verbose(network_verboser)) {
01429       ast_log(LOG_WARNING, "Unable to register network verboser?\n");
01430    }
01431 
01432    ast_pthread_create_background(&lthread, NULL, listener, NULL);
01433 
01434    if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
01435       struct passwd *pw;
01436       if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
01437          ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
01438       else
01439          uid = pw->pw_uid;
01440    }
01441       
01442    if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
01443       struct group *grp;
01444       if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
01445          ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
01446       else
01447          gid = grp->gr_gid;
01448    }
01449 
01450    if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
01451       ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01452 
01453    if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
01454       int p1;
01455       mode_t p;
01456       sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
01457       p = p1;
01458       if ((chmod(ast_config_AST_SOCKET, p)) < 0)
01459          ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01460    }
01461 
01462    return 0;
01463 }

int64_t ast_mark ( int  i,
int  startstop 
)

Definition at line 772 of file asterisk.c.

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

Referenced by __ast_pthread_mutex_lock(), and extension_match_core().

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

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

write the string to all attached console clients

Definition at line 1172 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

01173 {
01174    int x;
01175    for (x = 0; x < AST_MAX_CONNECTS; x++) {
01176       if (consoles[x].fd > -1) 
01177          fdprint(consoles[x].p[1], string);
01178    }
01179 }

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

log the string to all attached console clients

Definition at line 1145 of file asterisk.c.

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

Referenced by ast_console_puts_mutable(), and network_verboser().

01146 {
01147    int x;
01148    for (x = 0;x < AST_MAX_CONNECTS; x++) {
01149       if (consoles[x].mute)
01150          continue;
01151       if (consoles[x].fd > -1) {
01152          if (!consoles[x].levels[level]) 
01153             fdprint(consoles[x].p[1], string);
01154       }
01155    }
01156 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 737 of file asterisk.c.

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

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

static void ast_readconfig ( void   )  [static]

Definition at line 2942 of file asterisk.c.

References _cfg_paths::agi_dir, AST_CACHE_DIR_LEN, AST_COMPAT_APP_SET, AST_COMPAT_DELIM_PBX_REALTIME, AST_COMPAT_DELIM_RES_AGI, ast_config_AST_CONFIG_FILE, ast_config_AST_CTL, ast_config_AST_CTL_GROUP, ast_config_AST_CTL_OWNER, ast_config_AST_CTL_PERMISSIONS, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_eid_default, ast_language_is_prefix, AST_LOCK_TYPE_FLOCK, AST_LOCK_TYPE_LOCKFILE, ast_log(), AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DONT_WARN, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND, AST_OPT_FLAG_HIDE_CONSOLE_CONNECT, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_LIGHT_BACKGROUND, AST_OPT_FLAG_LOCK_CONFIG_DIR, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_TIMESTAMP, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_opt_override_config, ast_set2_flag, ast_set_default_eid(), ast_set_lock_type(), ast_str_to_eid(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_verbose, cfg_paths, config, _cfg_paths::config_dir, CONFIG_FLAG_NOREALTIME, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, _cfg_paths::data_dir, _cfg_paths::db_path, defaultlanguage, getloadavg(), hostname, _cfg_paths::key_dir, _cfg_paths::log_dir, LOG_ERROR, LOG_WARNING, MAX_LANGUAGE, MAXHOSTNAMELEN, _cfg_paths::module_dir, _cfg_paths::monitor_dir, ast_variable::name, ast_variable::next, _cfg_paths::pid_path, _cfg_paths::run_dir, _cfg_paths::run_group, _cfg_paths::run_user, _cfg_paths::sbin_dir, 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().

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

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 948 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(), astdb_init(), do_reload(), load_module(), and main().

00949 {
00950    struct ast_atexit *ae;
00951 
00952    if (!(ae = ast_calloc(1, sizeof(*ae))))
00953       return -1;
00954 
00955    ae->func = func;
00956 
00957    ast_unregister_atexit(func);  
00958 
00959    AST_RWLIST_WRLOCK(&atexits);
00960    AST_RWLIST_INSERT_HEAD(&atexits, ae, list);
00961    AST_RWLIST_UNLOCK(&atexits);
00962 
00963    return 0;
00964 }

void ast_register_file_version ( const char *  file,
const char *  version 
)

Register the version of a source code file with the core.

Parameters:
file the source file name
version the version string (typically a SVN revision keyword string)
Returns:
nothing
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to register a file with the core.

Definition at line 317 of file asterisk.c.

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

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

void ast_register_thread ( char *  name  ) 

Definition at line 401 of file asterisk.c.

References ast_calloc, ast_get_tid(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

Referenced by dummy_start().

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

static void ast_remotecontrol ( char *  data  )  [static]

Definition at line 2751 of file asterisk.c.

References __remote_quit_handler(), ast_el_initialize(), ast_el_read_char(), ast_el_read_history(), ast_log(), ast_opt_exec, ast_opt_mute, ast_poll, ast_strlen_zero(), ast_verbose, el, el_hist, errno, fdsend(), hostname, LOG_ERROR, LOG_WARNING, prefix, remoteconsolehandler(), remotehostname, sig_flags, strsep(), and version.

Referenced by main().

02752 {
02753    char buf[80];
02754    int res;
02755    char filename[80] = "";
02756    char *hostname;
02757    char *cpid;
02758    char *version;
02759    int pid;
02760    char *stringp = NULL;
02761 
02762    char *ebuf;
02763    int num = 0;
02764 
02765    memset(&sig_flags, 0, sizeof(sig_flags));
02766    signal(SIGINT, __remote_quit_handler);
02767    signal(SIGTERM, __remote_quit_handler);
02768    signal(SIGHUP, __remote_quit_handler);
02769 
02770    if (read(ast_consock, buf, sizeof(buf)) < 0) {
02771       ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02772       return;
02773    }
02774    if (data) {
02775       char prefix[] = "cli quit after ";
02776       char *tmp = alloca(strlen(data) + strlen(prefix) + 1);
02777       sprintf(tmp, "%s%s", prefix, data);
02778       if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
02779          ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
02780          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02781             return;
02782          }
02783       }
02784    }
02785    stringp = buf;
02786    hostname = strsep(&stringp, "/");
02787    cpid = strsep(&stringp, "/");
02788    version = strsep(&stringp, "\n");
02789    if (!version)
02790       version = "<Version Unknown>";
02791    stringp = hostname;
02792    strsep(&stringp, ".");
02793    if (cpid)
02794       pid = atoi(cpid);
02795    else
02796       pid = -1;
02797    if (!data) {
02798       char tmp[80];
02799       snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
02800       fdsend(ast_consock, tmp);
02801       snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
02802       fdsend(ast_consock, tmp);
02803       if (!ast_opt_mute)
02804          fdsend(ast_consock, "logger mute silent");
02805       else 
02806          printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02807    }
02808 
02809    if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
02810       struct pollfd fds;
02811       fds.fd = ast_consock;
02812       fds.events = POLLIN;
02813       fds.revents = 0;
02814       while (ast_poll(&fds, 1, 60000) > 0) {
02815          char buffer[512] = "", *curline = buffer, *nextline;
02816          int not_written = 1;
02817 
02818          if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02819             break;
02820          }
02821 
02822          if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
02823             break;
02824          }
02825 
02826          do {
02827             if ((nextline = strchr(curline, '\n'))) {
02828                nextline++;
02829             } else {
02830                nextline = strchr(curline, '\0');
02831             }
02832 
02833             /* Skip verbose lines */
02834             if (*curline != 127) {
02835                not_written = 0;
02836                if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
02837                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
02838                }
02839             }
02840             curline = nextline;
02841          } while (!ast_strlen_zero(curline));
02842 
02843          /* No non-verbose output in 60 seconds. */
02844          if (not_written) {
02845             break;
02846          }
02847       }
02848       return;
02849    }
02850 
02851    ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
02852    remotehostname = hostname;
02853    if (getenv("HOME")) 
02854       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
02855    if (el_hist == NULL || el == NULL)
02856       ast_el_initialize();
02857 
02858    el_set(el, EL_GETCFN, ast_el_read_char);
02859 
02860    if (!ast_strlen_zero(filename))
02861       ast_el_read_history(filename);
02862 
02863    for (;;) {
02864       ebuf = (char *)el_gets(el, &num);
02865 
02866       if (sig_flags.need_quit || sig_flags.need_quit_handler) {
02867          break;
02868       }
02869 
02870       if (!ebuf && write(1, "", 1) < 0)
02871          break;
02872 
02873       if (!ast_strlen_zero(ebuf)) {
02874          if (ebuf[strlen(ebuf)-1] == '\n')
02875             ebuf[strlen(ebuf)-1] = '\0';
02876          if (!remoteconsolehandler(ebuf)) {
02877             /* Strip preamble from output */
02878             char *temp;
02879             for (temp = ebuf; *temp; temp++) {
02880                if (*temp == 127) {
02881                   memmove(temp, temp + 1, strlen(temp));
02882                   temp--;
02883                }
02884             }
02885             res = write(ast_consock, ebuf, strlen(ebuf) + 1);
02886             if (res < 1) {
02887                ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
02888                break;
02889             }
02890          }
02891       }
02892    }
02893    printf("\nDisconnected from Asterisk server\n");
02894 }

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

01016 {
01017    unsigned int level;
01018 
01019    ast_mutex_lock(&safe_system_lock);
01020    level = safe_system_level++;
01021 
01022    /* only replace the handler if it has not already been done */
01023    if (level == 0) {
01024       sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
01025    }
01026 
01027    ast_mutex_unlock(&safe_system_lock);
01028 }

static void ast_run_atexits ( void   )  [static]

Definition at line 1615 of file asterisk.c.

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

Referenced by really_quit().

01616 {
01617    struct ast_atexit *ae;
01618    AST_RWLIST_RDLOCK(&atexits);
01619    AST_RWLIST_TRAVERSE(&atexits, ae, list) {
01620       if (ae->func) 
01621          ae->func();
01622    }
01623    AST_RWLIST_UNLOCK(&atexits);
01624 }

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

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

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

01582 {
01583    struct sched_param sched;
01584    memset(&sched, 0, sizeof(sched));
01585 #ifdef __linux__
01586    if (pri) {  
01587       sched.sched_priority = 10;
01588       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01589          ast_log(LOG_WARNING, "Unable to set high priority\n");
01590          return -1;
01591       } else
01592          if (option_verbose)
01593             ast_verbose("Set to realtime thread\n");
01594    } else {
01595       sched.sched_priority = 0;
01596       /* According to the manpage, these parameters can never fail. */
01597       sched_setscheduler(0, SCHED_OTHER, &sched);
01598    }
01599 #else
01600    if (pri) {
01601       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01602          ast_log(LOG_WARNING, "Unable to set high priority\n");
01603          return -1;
01604       } else
01605          if (option_verbose)
01606             ast_verbose("Set to high priority\n");
01607    } else {
01608       /* According to the manpage, these parameters can never fail. */
01609       setpriority(PRIO_PROCESS, 0, 0);
01610    }
01611 #endif
01612    return 0;
01613 }

static int ast_tryconnect ( void   )  [static]

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

01466 {
01467    struct sockaddr_un sunaddr;
01468    int res;
01469    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01470    if (ast_consock < 0) {
01471       ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
01472       return 0;
01473    }
01474    memset(&sunaddr, 0, sizeof(sunaddr));
01475    sunaddr.sun_family = AF_LOCAL;
01476    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01477    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01478    if (res) {
01479       close(ast_consock);
01480       ast_consock = -1;
01481       return 0;
01482    } else
01483       return 1;
01484 }

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

00967 {
00968    struct ast_atexit *ae = NULL;
00969 
00970    AST_RWLIST_WRLOCK(&atexits);
00971    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
00972       if (ae->func == func) {
00973          AST_RWLIST_REMOVE_CURRENT(list);
00974          break;
00975       }
00976    }
00977    AST_RWLIST_TRAVERSE_SAFE_END;
00978    AST_RWLIST_UNLOCK(&atexits);
00979 
00980    free(ae);
00981 }

void ast_unregister_file_version ( const char *  file  ) 

Unregister a source code file from the core.

Parameters:
file the source file name
Returns:
nothing
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to automatically unregister the file when the module is unloaded.

Definition at line 338 of file asterisk.c.

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

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

void ast_unregister_thread ( void *  id  ) 

Definition at line 415 of file asterisk.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, thread_list_t::id, ast_atexit::list, and thread_list_t::name.

Referenced by dummy_start().

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

void ast_unreplace_sigchld ( void   ) 

Restore the SIGCHLD handler.

This function is called after a call to ast_replace_sigchld. It restores the SIGCHLD handler that cleans up any zombie processes.

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

01031 {
01032    unsigned int level;
01033 
01034    ast_mutex_lock(&safe_system_lock);
01035    level = --safe_system_level;
01036 
01037    /* only restore the handler if we are the last one */
01038    if (level == 0) {
01039       sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
01040    }
01041 
01042    ast_mutex_unlock(&safe_system_lock);
01043 }

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

Definition at line 1638 of file asterisk.c.

References ast_active_channels(), ast_begin_shutdown(), ast_cdr_engine_term(), ast_mutex_lock, ast_mutex_unlock, ast_opt_console, ast_verbose, NOT_SHUTTING_DOWN, safe_system_lock, SHUTDOWN_NICE, SHUTDOWN_NORMAL, SHUTDOWN_REALLY_NICE, SHUTTING_DOWN, and shuttingdown.

Referenced by quit_handler().

01639 {
01640    /* Check if someone else isn't already doing this. */
01641    ast_mutex_lock(&safe_system_lock);
01642    if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
01643       /* Already in progress and other request was less nice. */
01644       ast_mutex_unlock(&safe_system_lock);
01645       ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
01646       return 0;
01647    }
01648    shuttingdown = niceness;
01649    ast_mutex_unlock(&safe_system_lock);
01650 
01651    /* Try to get as many CDRs as possible submitted to the backend engines
01652     * (if in batch mode). really_quit happens to call it again when running
01653     * the atexit handlers, otherwise this would be a bit early. */
01654    ast_cdr_engine_term();
01655 
01656    if (niceness == SHUTDOWN_NORMAL) {
01657       time_t s, e;
01658       /* Begin shutdown routine, hanging up active channels */
01659       ast_begin_shutdown(1);
01660       if (option_verbose && ast_opt_console) {
01661          ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
01662       }
01663       time(&s);
01664       for (;;) {
01665          time(&e);
01666          /* Wait up to 15 seconds for all channels to go away */
01667          if ((e - s) > 15 || !ast_active_channels() || shuttingdown != niceness) {
01668             break;
01669          }
01670          /* Sleep 1/10 of a second */
01671          usleep(100000);
01672       }
01673    } else if (niceness >= SHUTDOWN_NICE) {
01674       if (niceness != SHUTDOWN_REALLY_NICE) {
01675          ast_begin_shutdown(0);
01676       }
01677       if (option_verbose && ast_opt_console) {
01678          ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
01679       }
01680       for (;;) {
01681          if (!ast_active_channels() || shuttingdown != niceness) {
01682             break;
01683          }
01684          sleep(1);
01685       }
01686    }
01687 
01688    /* Re-acquire lock and check if someone changed the niceness, in which
01689     * case someone else has taken over the shutdown. */
01690    ast_mutex_lock(&safe_system_lock);
01691    if (shuttingdown != niceness) {
01692       if (shuttingdown == NOT_SHUTTING_DOWN && option_verbose && ast_opt_console) {
01693          ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
01694       }
01695       ast_mutex_unlock(&safe_system_lock);
01696       return 0;
01697    }
01698    shuttingdown = SHUTTING_DOWN;
01699    ast_mutex_unlock(&safe_system_lock);
01700 
01701    return 1;
01702 }

static void canary_exit ( void   )  [static]

Definition at line 3238 of file asterisk.c.

References canary_pid.

Referenced by main().

03239 {
03240    if (canary_pid > 0)
03241       kill(canary_pid, SIGKILL);
03242 }

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

Definition at line 3208 of file asterisk.c.

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

Referenced by main().

03209 {
03210    struct stat canary_stat;
03211    struct timeval now;
03212 
03213    /* Give the canary time to sing */
03214    sleep(120);
03215 
03216    for (;;) {
03217       stat(canary_filename, &canary_stat);
03218       now = ast_tvnow();
03219       if (now.tv_sec > canary_stat.st_mtime + 60) {
03220          ast_log(LOG_WARNING,
03221             "The canary is no more.  He has ceased to be!  "
03222             "He's expired and gone to meet his maker!  "
03223             "He's a stiff!  Bereft of life, he rests in peace.  "
03224             "His metabolic processes are now history!  He's off the twig!  "
03225             "He's kicked the bucket.  He's shuffled off his mortal coil, "
03226             "run down the curtain, and joined the bleeding choir invisible!!  "
03227             "THIS is an EX-CANARY.  (Reducing priority)\n");
03228          ast_set_priority(0);
03229          pthread_exit(NULL);
03230       }
03231 
03232       /* Check the canary once a minute */
03233       sleep(60);
03234    }
03235 }

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

Definition at line 2530 of file asterisk.c.

References AST_CLI_COMPLETE_EOF, ast_cli_completion_matches(), ast_cli_display_match_list(), ast_el_strtoarr(), ast_free, ast_malloc, ast_opt_remote, ast_realloc, and fdsend().

Referenced by ast_el_initialize().

02531 {
02532    int len = 0;
02533    char *ptr;
02534    int nummatches = 0;
02535    char **matches;
02536    int retval = CC_ERROR;
02537    char buf[2048], savechr;
02538    int res;
02539 
02540    LineInfo *lf = (LineInfo *)el_line(editline);
02541 
02542    savechr = *(char *)lf->cursor;
02543    *(char *)lf->cursor = '\0';
02544    ptr = (char *)lf->cursor;
02545    if (ptr) {
02546       while (ptr > lf->buffer) {
02547          if (isspace(*ptr)) {
02548             ptr++;
02549             break;
02550          }
02551          ptr--;
02552       }
02553    }
02554 
02555    len = lf->cursor - ptr;
02556 
02557    if (ast_opt_remote) {
02558       snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 
02559       fdsend(ast_consock, buf);
02560       res = read(ast_consock, buf, sizeof(buf) - 1);
02561       buf[res] = '\0';
02562       nummatches = atoi(buf);
02563 
02564       if (nummatches > 0) {
02565          char *mbuf;
02566          int mlen = 0, maxmbuf = 2048;
02567          /* Start with a 2048 byte buffer */       
02568          if (!(mbuf = ast_malloc(maxmbuf))) {
02569             lf->cursor[0] = savechr;
02570             return (char *)(CC_ERROR);
02571          }
02572          snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 
02573          fdsend(ast_consock, buf);
02574          res = 0;
02575          mbuf[0] = '\0';
02576          while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
02577             if (mlen + 1024 > maxmbuf) {
02578                /* Every step increment buffer 1024 bytes */
02579                maxmbuf += 1024;              
02580                if (!(mbuf = ast_realloc(mbuf, maxmbuf))) {
02581                   lf->cursor[0] = savechr;
02582                   return (char *)(CC_ERROR);
02583                }
02584             }
02585             /* Only read 1024 bytes at a time */
02586             res = read(ast_consock, mbuf + mlen, 1024);
02587             if (res > 0)
02588                mlen += res;
02589          }
02590          mbuf[mlen] = '\0';
02591 
02592          matches = ast_el_strtoarr(mbuf);
02593          ast_free(mbuf);
02594       } else
02595          matches = (char **) NULL;
02596    } else {
02597       char **p, *oldbuf=NULL;
02598       nummatches = 0;
02599       matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
02600       for (p = matches; p && *p; p++) {
02601          if (!oldbuf || strcmp(*p,oldbuf))
02602             nummatches++;
02603          oldbuf = *p;
02604       }
02605    }
02606 
02607    if (matches) {
02608       int i;
02609       int matches_num, maxlen, match_len;
02610 
02611       if (matches[0][0] != '\0') {
02612          el_deletestr(editline, (int) len);
02613          el_insertstr(editline, matches[0]);
02614          retval = CC_REFRESH;
02615       }
02616 
02617       if (nummatches == 1) {
02618          /* Found an exact match */
02619          el_insertstr(editline, " ");
02620          retval = CC_REFRESH;
02621       } else {
02622          /* Must be more than one match */
02623          for (i = 1, maxlen = 0; matches[i]; i++) {
02624             match_len = strlen(matches[i]);
02625             if (match_len > maxlen)
02626                maxlen = match_len;
02627          }
02628          matches_num = i - 1;
02629          if (matches_num >1) {
02630             fprintf(stdout, "\n");
02631             ast_cli_display_match_list(matches, nummatches, maxlen);
02632             retval = CC_REDISPLAY;
02633          } else { 
02634             el_insertstr(editline," ");
02635             retval = CC_REFRESH;
02636          }
02637       }
02638       for (i = 0; matches[i]; i++)
02639          ast_free(matches[i]);
02640       ast_free(matches);
02641    }
02642 
02643    lf->cursor[0] = savechr;
02644 
02645    return (char *)(long)retval;
02646 }

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

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

02303 {
02304    char tmp[100];
02305    char *pfmt;
02306    int color_used = 0;
02307    static int cli_prompt_changes = 0;
02308    char term_code[20];
02309    struct passwd *pw;
02310    struct group *gr;
02311 
02312    if (prompt == NULL) {
02313       prompt = ast_str_create(100);
02314    } else if (!cli_prompt_changes) {
02315       return ast_str_buffer(prompt);
02316    } else {
02317       ast_str_reset(prompt);
02318    }
02319 
02320    if ((pfmt = getenv("ASTERISK_PROMPT"))) {
02321       char *t = pfmt;
02322       struct timeval ts = ast_tvnow();
02323       while (*t != '\0') {
02324          if (*t == '%') {
02325             char hostname[MAXHOSTNAMELEN] = "";
02326             int i, which;
02327             struct ast_tm tm = { 0, };
02328             int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
02329 
02330             t++;
02331             switch (*t) {
02332             case 'C': /* color */
02333                t++;
02334                if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
02335                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)));
02336                   t += i - 1;
02337                } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
02338                   ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code)));
02339                   t += i - 1;
02340                }
02341 
02342                /* If the color has been reset correctly, then there's no need to reset it later */
02343                color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
02344                break;
02345             case 'd': /* date */
02346                if (ast_localtime(&ts, &tm, NULL)) {
02347                   ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
02348                   ast_str_append(&prompt, 0, "%s", tmp);
02349                   cli_prompt_changes++;
02350                }
02351                break;
02352             case 'g': /* group */
02353                if ((gr = getgrgid(getgid()))) {
02354                   ast_str_append(&prompt, 0, "%s", gr->gr_name);
02355                }
02356                break;
02357             case 'h': /* hostname */
02358                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02359                   ast_str_append(&prompt, 0, "%s", hostname);
02360                } else {
02361                   ast_str_append(&prompt, 0, "%s", "localhost");
02362                }
02363                break;
02364             case 'H': /* short hostname */
02365                if (!gethostname(hostname, sizeof(hostname) - 1)) {
02366                   char *dotptr;
02367                   if ((dotptr = strchr(hostname, '.'))) {
02368                      *dotptr = '\0';
02369                   }
02370                   ast_str_append(&prompt, 0, "%s", hostname);
02371                } else {
02372                   ast_str_append(&prompt, 0, "%s", "localhost");
02373                }
02374                break;
02375 #ifdef HAVE_GETLOADAVG
02376             case 'l': /* load avg */
02377                t++;
02378                if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
02379                   double list[3];
02380                   getloadavg(list, 3);
02381                   ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
02382                   cli_prompt_changes++;
02383                }
02384                break;
02385 #endif
02386             case 's': /* Asterisk system name (from asterisk.conf) */
02387                ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
02388                break;
02389             case 't': /* time */
02390                if (ast_localtime(&ts, &tm, NULL)) {
02391                   ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
02392                   ast_str_append(&prompt, 0, "%s", tmp);
02393                   cli_prompt_changes++;
02394                }
02395                break;
02396             case 'u': /* username */
02397                if ((pw = getpwuid(getuid()))) {
02398                   ast_str_append(&prompt, 0, "%s", pw->pw_name);
02399                }
02400                break;
02401             case '#': /* process console or remote? */
02402                ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
02403                break;
02404             case '%': /* literal % */
02405                ast_str_append(&prompt, 0, "%c", '%');
02406                break;
02407             case '\0': /* % is last character - prevent bug */
02408                t--;
02409                break;
02410             }
02411          } else {
02412             ast_str_append(&prompt, 0, "%c", *t);
02413          }
02414          t++;
02415       }
02416       if (color_used) {
02417          /* Force colors back to normal at end */
02418          ast_str_append(&prompt, 0, "%s", term_color_code(term_code, 0, 0, sizeof(term_code)));
02419       }
02420    } else if (remotehostname) {
02421       ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname);
02422    } else {
02423       ast_str_set(&prompt, 0, "%s", ASTERISK_PROMPT);
02424    }
02425 
02426    return ast_str_buffer(prompt);   
02427 }

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

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

01819 {
01820    char tmp[80];
01821    const char *c = NULL;
01822 
01823    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01824        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01825        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01826        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
01827       fputs(tmp, stdout);
01828       fputs(c, stdout);
01829    } else {
01830       if (*s == 127) {
01831          s++;
01832       }
01833       fputs(s, stdout);
01834    }
01835 
01836    fflush(stdout);
01837    
01838    /* Wake up a poll()ing console */
01839    if (ast_opt_console && consolethread != AST_PTHREADT_NULL) {
01840       pthread_kill(consolethread, SIGURG);
01841    }
01842 }

static void consolehandler ( char *  s  )  [static]

Definition at line 1854 of file asterisk.c.

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

Referenced by main().

01855 {
01856    printf("%s", term_end());
01857    fflush(stdout);
01858 
01859    /* Called when readline data is available */
01860    if (!ast_all_zeros(s))
01861       ast_el_add_history(s);
01862    /* The real handler for bang */
01863    if (s[0] == '!') {
01864       if (s[1])
01865          ast_safe_system(s+1);
01866       else
01867          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01868    } else 
01869       ast_cli_command(STDOUT_FILENO, s);
01870 }

static void env_init ( void   )  [static]

Definition at line 3272 of file asterisk.c.

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

Referenced by main().

03273 {
03274    setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
03275    setenv("AST_BUILD_HOST", ast_build_hostname, 1);
03276    setenv("AST_BUILD_DATE", ast_build_date, 1);
03277    setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
03278    setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
03279    setenv("AST_BUILD_OS", ast_build_os, 1);
03280    setenv("AST_BUILD_USER", ast_build_user, 1);
03281    setenv("AST_VERSION", ast_get_version(), 1);
03282 }

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

Definition at line 990 of file asterisk.c.

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

00991 {
00992    return write(fd, s, strlen(s));
00993 }

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

Definition at line 984 of file asterisk.c.

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

00985 {
00986    return write(fd, s, strlen(s) + 1);
00987 }

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

Definition at line 1801 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01802 {
01803    const char *c;
01804 
01805    /* Check for verboser preamble */
01806    if (*s == 127) {
01807       s++;
01808    }
01809 
01810    if (!strncmp(s, cmp, strlen(cmp))) {
01811       c = s + strlen(cmp);
01812       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01813       return c;
01814    }
01815    return NULL;
01816 }

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

Definition at line 2046 of file asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cancel_shutdown(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NOT_SHUTTING_DOWN, safe_system_lock, SHUTDOWN_FAST, shuttingdown, and ast_cli_entry::usage.

02047 {
02048    int aborting_shutdown = 0;
02049 
02050    switch (cmd) {
02051    case CLI_INIT:
02052       e->command = "core abort shutdown";
02053       e->usage = 
02054          "Usage: core abort shutdown\n"
02055          "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
02056          "       call operations.\n";
02057       return NULL;
02058    case CLI_GENERATE:
02059       return NULL;
02060    }
02061 
02062    if (a->argc != e->args)
02063       return CLI_SHOWUSAGE;
02064 
02065    ast_mutex_lock(&safe_system_lock);
02066    if (shuttingdown >= SHUTDOWN_FAST) {
02067       aborting_shutdown = 1;
02068       shuttingdown = NOT_SHUTTING_DOWN;
02069    }
02070    ast_mutex_unlock(&safe_system_lock);
02071 
02072    if (aborting_shutdown) {
02073       ast_cancel_shutdown();
02074    }
02075    return CLI_SUCCESS;
02076 }

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

Definition at line 2078 of file asterisk.c.

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

02079 {
02080    switch (cmd) {
02081    case CLI_INIT:
02082       e->command = "!";
02083       e->usage = 
02084          "Usage: !<command>\n"
02085          "       Executes a given shell command\n";
02086       return NULL;
02087    case CLI_GENERATE:
02088       return NULL;
02089    }
02090 
02091    return CLI_SUCCESS;
02092 }

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

Definition at line 836 of file asterisk.c.

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

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

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

Definition at line 2006 of file asterisk.c.

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

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

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

Definition at line 1986 of file asterisk.c.

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

01987 {
01988    switch (cmd) {
01989    case CLI_INIT:
01990       e->command = "core restart now";
01991       e->usage = 
01992          "Usage: core restart now\n"
01993          "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
01994          "       restart.\n";
01995       return NULL;
01996    case CLI_GENERATE:
01997       return NULL;
01998    }
01999 
02000    if (a->argc != e->args)
02001       return CLI_SHOWUSAGE;
02002    quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
02003    return CLI_SUCCESS;
02004 }

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

Definition at line 2026 of file asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, quit_handler(), SHUTDOWN_REALLY_NICE, and ast_cli_entry::usage.

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

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

Definition at line 801 of file asterisk.c.

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

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

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

Give an overview of core settings.

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

Definition at line 435 of file asterisk.c.

References ast_active_channels(), ast_build_date, ast_build_kernel, ast_build_machine, ast_build_os, ast_build_user, ast_cli(), ast_config_AST_AGI_DIR, ast_config_AST_CONFIG_DIR, ast_config_AST_CONFIG_FILE, ast_config_AST_DATA_DIR, ast_config_AST_DB, ast_config_AST_KEY_DIR, ast_config_AST_LOG_DIR, ast_config_AST_MODULE_DIR, ast_config_AST_PID, ast_config_AST_RUN_DIR, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SPOOL_DIR, ast_config_AST_SYSTEM_NAME, ast_config_AST_VAR_DIR, ast_eid_default, ast_eid_to_str(), ast_get_version(), ast_language_is_prefix, ast_lastreloadtime, ast_localtime(), AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_GENERIC_PLC, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_realtime_enabled(), ast_startuptime, ast_strftime(), ast_test_flag, check_cdr_enabled(), check_manager_enabled(), check_webmanager_enabled(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, defaultlanguage, ast_cli_args::fd, S_OR, and ast_cli_entry::usage.

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

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

Definition at line 518 of file asterisk.c.

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

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

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

CLI command to list module versions.

Definition at line 865 of file asterisk.c.

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

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

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

Definition at line 1946 of file asterisk.c.

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

01947 {
01948    switch (cmd) {
01949    case CLI_INIT:
01950       e->command = "core stop gracefully";
01951       e->usage = 
01952          "Usage: core stop gracefully\n"
01953          "       Causes Asterisk to not accept new calls, and exit when all\n"
01954          "       active calls have terminated normally.\n";
01955       return NULL;
01956    case CLI_GENERATE:
01957       return NULL;
01958    }
01959 
01960    if (a->argc != e->args)
01961       return CLI_SHOWUSAGE;
01962    quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
01963    return CLI_SUCCESS;
01964 }

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

Definition at line 1927 of file asterisk.c.

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

01928 {
01929    switch (cmd) {
01930    case CLI_INIT:
01931       e->command = "core stop now";
01932       e->usage = 
01933          "Usage: core stop now\n"
01934          "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
01935       return NULL;
01936    case CLI_GENERATE:
01937       return NULL;
01938    }
01939 
01940    if (a->argc != e->args)
01941       return CLI_SHOWUSAGE;
01942    quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
01943    return CLI_SUCCESS;
01944 }

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

Definition at line 1966 of file asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, quit_handler(), SHUTDOWN_REALLY_NICE, and ast_cli_entry::usage.

01967 {
01968    switch (cmd) {
01969    case CLI_INIT:
01970       e->command = "core stop when convenient";
01971       e->usage = 
01972          "Usage: core stop when convenient\n"
01973          "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
01974       return NULL;
01975    case CLI_GENERATE:
01976       return NULL;
01977    }
01978 
01979    if (a->argc != e->args)
01980       return CLI_SHOWUSAGE;
01981    ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
01982    quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
01983    return CLI_SUCCESS;
01984 }

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

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

01897 {
01898    switch (cmd) {
01899    case CLI_INIT:
01900       e->command = "core show version";
01901       e->usage = 
01902          "Usage: core show version\n"
01903          "       Shows Asterisk version information.\n";
01904       return NULL;
01905    case CLI_GENERATE:
01906       return NULL;
01907    }
01908 
01909    if (a->argc != 3)
01910       return CLI_SHOWUSAGE;
01911    ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
01912       ast_get_version(), ast_build_user, ast_build_hostname,
01913       ast_build_machine, ast_build_os, ast_build_date);
01914    return CLI_SUCCESS;
01915 }

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

Definition at line 1318 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(), and console::uid.

Referenced by ast_makesocket().

01319 {
01320    struct sockaddr_un sunaddr;
01321    int s;
01322    socklen_t len;
01323    int x;
01324    int flags;
01325    struct pollfd fds[1];
01326    for (;;) {
01327       if (ast_socket < 0)
01328          return NULL;
01329       fds[0].fd = ast_socket;
01330       fds[0].events = POLLIN;
01331       s = ast_poll(fds, 1, -1);
01332       pthread_testcancel();
01333       if (s < 0) {
01334          if (errno != EINTR)
01335             ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
01336          continue;
01337       }
01338       len = sizeof(sunaddr);
01339       s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
01340       if (s < 0) {
01341          if (errno != EINTR)
01342             ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
01343       } else {
01344 #if !defined(SO_PASSCRED)
01345          {
01346 #else
01347          int sckopt = 1;
01348          /* turn on socket credentials passing. */
01349          if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
01350             ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
01351          } else {
01352 #endif
01353             for (x = 0; x < AST_MAX_CONNECTS; x++) {
01354                if (consoles[x].fd >= 0) {
01355                   continue;
01356                }
01357                if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
01358                   ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
01359                   consoles[x].fd = -1;
01360                   fdprint(s, "Server failed to create pipe\n");
01361                   close(s);
01362                   break;
01363                }
01364                flags = fcntl(consoles[x].p[1], F_GETFL);
01365                fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
01366                consoles[x].fd = s;
01367                consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
01368                /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
01369                   to know if the user didn't send the credentials. */
01370                consoles[x].uid = -2;
01371                consoles[x].gid = -2;
01372                if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
01373                   ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
01374                   close(consoles[x].p[0]);
01375                   close(consoles[x].p[1]);
01376                   consoles[x].fd = -1;
01377                   fdprint(s, "Server failed to spawn thread\n");
01378                   close(s);
01379                }
01380                break;
01381             }
01382             if (x >= AST_MAX_CONNECTS) {
01383                fdprint(s, "No more connections allowed\n");
01384                ast_log(LOG_WARNING, "No more connections allowed\n");
01385                close(s);
01386             } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
01387                ast_verb(3, "Remote UNIX connection\n");
01388             }
01389          }
01390       }
01391    }
01392    return NULL;
01393 }

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

< Result from the module load subsystem

Note:
Please keep the ordering here to alphabetical, capital letters first. This will make it easier in the future to select unused option flags for new features.

Definition at line 3284 of file asterisk.c.

References __ast_mm_init(), __quit_handler(), _argv, ARRAY_LEN, ast_alaw_init(), ast_aoc_cli_init(), ast_autoservice_init(), ast_builtins_init(), ast_cc_init(), ast_cdr_engine_init(), ast_cel_engine_init(), ast_channels_init(), ast_clear_flag, ast_cli_perms_init(), ast_cli_register_multiple(), ast_close_fds_above_n(), ast_config_AST_PID, ast_config_AST_RUN_DIR, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SBIN_DIR, ast_config_AST_SOCKET, ast_copy_string(), ast_data_init(), ast_device_state_engine_init(), ast_dsp_init(), ast_el_initialize(), ast_el_read_char(), ast_el_read_history(), ast_enum_init(), ast_event_init(), ast_fd_init(), ast_FD_SETSIZE, ast_FDMAX, ast_features_init(), ast_file_init(), ast_format_attr_init(), ast_format_list_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_language_is_prefix, ast_lastreloadtime, ast_log(), ast_makesocket(), ast_msg_init(), ast_opt_always_fork, ast_opt_console, ast_opt_dump_core, ast_opt_exec, AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC, AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND, AST_OPT_FLAG_FULLY_BOOTED, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_LIGHT_BACKGROUND, AST_OPT_FLAG_MUTE, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_OVERRIDE_CONFIG, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_RECONNECT, AST_OPT_FLAG_REMOTE, AST_OPT_FLAG_TIMESTAMP, ast_opt_high_priority, ast_opt_no_fork, ast_opt_remote, ast_pbx_init(), ast_process_pending_reloads(), ast_pthread_create_detached, ast_readconfig(), ast_register_atexit(), ast_register_verbose(), ast_remotecontrol(), ast_rtp_engine_init(), ast_select(), ast_set_flag, ast_set_priority(), ast_ssl_init(), ast_startuptime, ast_strdupa, ast_strlen_zero(), ast_stun_init(), ast_term_init(), ast_test_flag, ast_test_init(), ast_timing_init(), ast_tps_init(), ast_translate_init(), ast_tryconnect(), ast_tvnow(), ast_udptl_init(), ast_ulaw_init(), ast_utils_init(), ast_verbose, ast_xmldoc_load_documentation(), astdb_init(), astobj2_init(), callerid_init(), canary_exit(), canary_filename, canary_pid, canary_thread(), cfg_paths, COLOR_BLACK, COLOR_BRWHITE, _cfg_paths::config_file, console_verboser(), consolehandler(), consolethread, dnsmgr_init(), dnsmgr_start_refresh(), el, el_hist, env_init(), errno, EVENT_FLAG_SYSTEM, f, FD_SET, FD_ZERO, hostname, ignore_sig_handler, init_framer(), init_logger(), init_manager(), load_modules(), load_pbx(), LOG_ERROR, LOG_WARNING, manager_event, MAXHOSTNAMELEN, mon_sig_flags, monitor_sig_flags(), quit_handler(), randompool, read_config_maps(), register_config_cli(), run_startup_commands(), set_icon(), set_title(), show_cli_help(), show_version(), SHUTDOWN_FAST, sig_alert_pipe, sig_flags, _cfg_paths::socket_path, tdd_init(), term_color(), term_end(), term_quit(), threadstorage_init(), and WELCOME_MESSAGE.

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

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

Definition at line 3182 of file asterisk.c.

References ast_module_reload(), ast_poll, AST_PTHREADT_NULL, consolethread, quit_handler(), SHUTDOWN_NORMAL, sig_alert_pipe, and sig_flags.

Referenced by main().

03183 {
03184    for (;;) {
03185       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
03186       int a;
03187       ast_poll(&p, 1, -1);
03188       if (sig_flags.need_reload) {
03189          sig_flags.need_reload = 0;
03190          ast_module_reload(NULL);
03191       }
03192       if (sig_flags.need_quit) {
03193          sig_flags.need_quit = 0;
03194          if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
03195             sig_flags.need_quit_handler = 1;
03196             pthread_kill(consolethread, SIGURG);
03197          } else {
03198             quit_handler(0, SHUTDOWN_NORMAL, 0);
03199          }
03200       }
03201       if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
03202       }
03203    }
03204 
03205    return NULL;
03206 }

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

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

01259 {
01260    struct console *con = vconsole;
01261    char hostname[MAXHOSTNAMELEN] = "";
01262    char tmp[512];
01263    int res;
01264    struct pollfd fds[2];
01265    
01266    if (gethostname(hostname, sizeof(hostname)-1))
01267       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
01268    snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
01269    fdprint(con->fd, tmp);
01270    for (;;) {
01271       fds[0].fd = con->fd;
01272       fds[0].events = POLLIN;
01273       fds[0].revents = 0;
01274       fds[1].fd = con->p[0];
01275       fds[1].events = POLLIN;
01276       fds[1].revents = 0;
01277 
01278       res = ast_poll(fds, 2, -1);
01279       if (res < 0) {
01280          if (errno != EINTR)
01281             ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
01282          continue;
01283       }
01284       if (fds[0].revents) {
01285          res = read_credentials(con->fd, tmp, sizeof(tmp) - 1, con);
01286          if (res < 1) {
01287             break;
01288          }
01289          tmp[res] = 0;
01290          if (strncmp(tmp, "cli quit after ", 15) == 0) {
01291             ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res - 15, tmp + 15);
01292             break;
01293          }
01294          ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res, tmp);
01295       }
01296       if (fds[1].revents) {
01297          res = read_credentials(con->p[0], tmp, sizeof(tmp), con);
01298          if (res < 1) {
01299             ast_log(LOG_ERROR, "read returned %d\n", res);
01300             break;
01301          }
01302          res = write(con->fd, tmp, res);
01303          if (res < 1)
01304             break;
01305       }
01306    }
01307    if (!ast_opt_hide_connect) {
01308       ast_verb(3, "Remote UNIX connection disconnected\n");
01309    }
01310    close(con->fd);
01311    close(con->p[0]);
01312    close(con->p[1]);
01313    con->fd = -1;
01314    
01315    return NULL;
01316 }

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

Definition at line 1192 of file asterisk.c.

References __LOG_VERBOSE, and ast_network_puts_mutable().

Referenced by ast_makesocket().

01193 {
01194    ast_network_puts_mutable(s, __LOG_VERBOSE);
01195 }

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

Definition at line 1629 of file asterisk.c.

References can_safely_quit(), and really_quit().

Referenced by ast_el_read_char(), handle_restart_gracefully(), handle_restart_now(), handle_restart_when_convenient(), handle_stop_gracefully(), handle_stop_now(), handle_stop_when_convenient(), main(), monitor_sig_flags(), and remoteconsolehandler().

01630 {
01631    if (can_safely_quit(niceness, restart)) {
01632       really_quit(num, niceness, restart);
01633       /* No one gets here. */
01634    }
01635    /* It wasn't our time. */
01636 }

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 766 of file asterisk.c.

Referenced by ast_mark().

00767 {
00768    return 0;
00769 }

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

read() function supporting the reception of user credentials.

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

Definition at line 1209 of file asterisk.c.

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

Referenced by netconsole().

01210 {
01211 #if defined(SO_PEERCRED)
01212 #ifdef HAVE_STRUCT_SOCKPEERCRED_UID
01213 #define HAVE_STRUCT_UCRED_UID
01214    struct sockpeercred cred;
01215 #else
01216    struct ucred cred;
01217 #endif
01218    socklen_t len = sizeof(cred);
01219 #endif
01220 #if defined(HAVE_GETPEEREID)
01221    uid_t uid;
01222    gid_t gid;
01223 #else
01224    int uid, gid;
01225 #endif
01226    int result;
01227 
01228    result = read(fd, buffer, size);
01229    if (result < 0) {
01230       return result;
01231    }
01232 
01233 #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
01234    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
01235       return result;
01236    }
01237 #if defined(HAVE_STRUCT_UCRED_UID)
01238    uid = cred.uid;
01239    gid = cred.gid;
01240 #else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
01241    uid = cred.cr_uid;
01242    gid = cred.cr_gid;
01243 #endif /* defined(HAVE_STRUCT_UCRED_UID) */
01244 
01245 #elif defined(HAVE_GETPEEREID)
01246    if (getpeereid(fd, &uid, &gid)) {
01247       return result;
01248    }
01249 #else
01250    return result;
01251 #endif
01252    con->uid = uid;
01253    con->gid = gid;
01254 
01255    return result;
01256 }

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

Definition at line 1704 of file asterisk.c.

References _argv, ast_active_channels(), ast_config_AST_PID, ast_config_AST_SOCKET, ast_debug, ast_el_write_history(), ast_module_shutdown(), ast_opt_console, ast_opt_exec, ast_opt_remote, AST_PTHREADT_NULL, ast_run_atexits(), ast_strlen_zero(), ast_verbose, close_logger(), consolethread, el, el_hist, EVENT_FLAG_SYSTEM, lthread, manager_event, mon_sig_flags, restartnow, SHUTDOWN_NICE, and term_quit().

Referenced by quit_handler().

01705 {
01706    if (niceness >= SHUTDOWN_NICE) {
01707       ast_module_shutdown();
01708    }
01709 
01710    if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
01711       char filename[80] = "";
01712       if (getenv("HOME")) {
01713          snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
01714       }
01715       if (!ast_strlen_zero(filename)) {
01716          ast_el_write_history(filename);
01717       }
01718       if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
01719          /* Only end if we are the consolethread, otherwise there's a race with that thread. */
01720          if (el != NULL) {
01721             el_end(el);
01722          }
01723          if (el_hist != NULL) {
01724             history_end(el_hist);
01725          }
01726       } else if (mon_sig_flags == pthread_self()) {
01727          if (consolethread != AST_PTHREADT_NULL) {
01728             pthread_kill(consolethread, SIGURG);
01729          }
01730       }
01731    }
01732    if (option_verbose)
01733       ast_verbose("Executing last minute cleanups\n");
01734    ast_run_atexits();
01735    /* Called on exit */
01736    if (option_verbose && ast_opt_console)
01737       ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
01738    ast_debug(1, "Asterisk ending (%d).\n", num);
01739    manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
01740    if (ast_socket > -1) {
01741       pthread_cancel(lthread);
01742       close(ast_socket);
01743       ast_socket = -1;
01744       unlink(ast_config_AST_SOCKET);
01745    }
01746    if (ast_consock > -1)
01747       close(ast_consock);
01748    if (!ast_opt_remote)
01749       unlink(ast_config_AST_PID);
01750    printf("%s", term_quit());
01751    if (restart) {
01752       int i;
01753       if (option_verbose || ast_opt_console)
01754          ast_verbose("Preparing for Asterisk restart...\n");
01755       /* Mark all FD's for closing on exec */
01756       for (i = 3; i < 32768; i++) {
01757          fcntl(i, F_SETFD, FD_CLOEXEC);
01758       }
01759       if (option_verbose || ast_opt_console)
01760          ast_verbose("Asterisk is now restarting...\n");
01761       restartnow = 1;
01762 
01763       /* close logger */
01764       close_logger();
01765 
01766       /* If there is a consolethread running send it a SIGHUP 
01767          so it can execvp, otherwise we can do it ourselves */
01768       if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
01769          pthread_kill(consolethread, SIGHUP);
01770          /* Give the signal handler some time to complete */
01771          sleep(2);
01772       } else
01773          execvp(_argv[0], _argv);
01774    
01775    } else {
01776       /* close logger */
01777       close_logger();
01778    }
01779 
01780    exit(0);
01781 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1872 of file asterisk.c.

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

Referenced by ast_remotecontrol().

01873 {
01874    int ret = 0;
01875 
01876    /* Called when readline data is available */
01877    if (!ast_all_zeros(s))
01878       ast_el_add_history(s);
01879    /* The real handler for bang */
01880    if (s[0] == '!') {
01881       if (s[1])
01882          ast_safe_system(s+1);
01883       else
01884          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01885       ret = 1;
01886    }
01887    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
01888        (s[4] == '\0' || isspace(s[4]))) {
01889       quit_handler(0, SHUTDOWN_FAST, 0);
01890       ret = 1;
01891    }
01892 
01893    return ret;
01894 }

static void run_startup_commands ( void   )  [static]

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

03245 {
03246    int fd;
03247    struct ast_config *cfg;
03248    struct ast_flags cfg_flags = { 0 };
03249    struct ast_variable *v;
03250 
03251    if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
03252       return;
03253    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
03254       return;
03255    }
03256 
03257    fd = open("/dev/null", O_RDWR);
03258    if (fd < 0) {
03259       ast_config_destroy(cfg);
03260       return;
03261    }
03262 
03263    for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
03264       if (ast_true(v->value))
03265          ast_cli_command(fd, v->name);
03266    }
03267 
03268    close(fd);
03269    ast_config_destroy(cfg);
03270 }

static void set_icon ( char *  text  )  [static]

Definition at line 1573 of file asterisk.c.

Referenced by main().

01574 {
01575    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01576       fprintf(stdout, "\033]1;%s\007", text);
01577 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1567 of file asterisk.c.

Referenced by main().

01568 {
01569    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01570       fprintf(stdout, "\033]2;%s\007", text);
01571 }

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1544 of file asterisk.c.

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

Referenced by ast_readconfig().

01545 {
01546    struct rlimit l = {0, 0};
01547    
01548    if (value <= 0) {
01549       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01550       return;
01551    }
01552    
01553    l.rlim_cur = value;
01554    l.rlim_max = value;
01555    
01556    if (setrlimit(RLIMIT_NOFILE, &l)) {
01557       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01558       return;
01559    }
01560    
01561    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01562    
01563    return;
01564 }

static int show_cli_help ( void   )  [static]

Definition at line 2902 of file asterisk.c.

References ast_get_version().

Referenced by main().

02903 {
02904    printf("Asterisk %s, Copyright (C) 1999 - 2012, Digium, Inc. and others.\n", ast_get_version());
02905    printf("Usage: asterisk [OPTIONS]\n");
02906    printf("Valid Options:\n");
02907    printf("   -V              Display version number and exit\n");
02908    printf("   -C <configfile> Use an alternate configuration file\n");
02909    printf("   -G <group>      Run as a group other than the caller\n");
02910    printf("   -U <user>       Run as a user other than the caller\n");
02911    printf("   -c              Provide console CLI\n");
02912    printf("   -d              Enable extra debugging\n");
02913 #if HAVE_WORKING_FORK
02914    printf("   -f              Do not fork\n");
02915    printf("   -F              Always fork\n");
02916 #endif
02917    printf("   -g              Dump core in case of a crash\n");
02918    printf("   -h              This help screen\n");
02919    printf("   -i              Initialize crypto keys at startup\n");
02920    printf("   -I              Enable internal timing if DAHDI timer is available\n");
02921    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
02922    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
02923    printf("   -m              Mute debugging and console output on the console\n");
02924    printf("   -n              Disable console colorization\n");
02925    printf("   -p              Run as pseudo-realtime thread\n");
02926    printf("   -q              Quiet mode (suppress output)\n");
02927    printf("   -r              Connect to Asterisk on this machine\n");
02928    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
02929    printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
02930    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
02931    printf("                   belong after they are done\n");
02932    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
02933    printf("                   of output to the CLI\n");
02934    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
02935    printf("   -x <cmd>        Execute command <cmd> (implies -r)\n");
02936    printf("   -X              Execute includes by default (allows #exec in asterisk.conf)\n");
02937    printf("   -W              Adjust terminal colors to compensate for a light background\n");
02938    printf("\n");
02939    return 0;
02940 }

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

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

02156 {
02157    switch (cmd) {
02158    case CLI_INIT:
02159       e->command = "core show license";
02160       e->usage = 
02161          "Usage: core show license\n"
02162          "       Shows the license(s) for this copy of Asterisk.\n";
02163       return NULL;
02164    case CLI_GENERATE:
02165       return NULL;
02166    }
02167 
02168    ast_cli(a->fd, "%s", license_lines);
02169 
02170    return CLI_SUCCESS;
02171 }

static int show_version ( void   )  [static]

Definition at line 2896 of file asterisk.c.

References ast_get_version().

Referenced by main().

02897 {
02898    printf("Asterisk %s\n", ast_get_version());
02899    return 0;
02900 }

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

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

02119 {
02120    switch (cmd) {
02121    case CLI_INIT:
02122       e->command = "core show warranty";
02123       e->usage = 
02124          "Usage: core show warranty\n"
02125          "       Shows the warranty (if any) for this copy of Asterisk.\n";
02126       return NULL;
02127    case CLI_GENERATE:
02128       return NULL;
02129    }
02130 
02131    ast_cli(a->fd, "%s", warranty_lines);
02132 
02133    return CLI_SUCCESS;
02134 }


Variable Documentation

char* _argv[256] [static]

Definition at line 282 of file asterisk.c.

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

const char* ast_config_AST_AGI_DIR = cfg_paths.agi_dir

Definition at line 263 of file asterisk.c.

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

const char* ast_config_AST_CONFIG_DIR = cfg_paths.config_dir

Definition at line 256 of file asterisk.c.

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

char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl" [static]

Definition at line 278 of file asterisk.c.

Referenced by ast_readconfig().

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

Definition at line 277 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

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

Definition at line 276 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static]

Definition at line 275 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

const char* ast_config_AST_DATA_DIR = cfg_paths.data_dir

const char* ast_config_AST_DB = cfg_paths.db_path

const char* ast_config_AST_KEY_DIR = cfg_paths.key_dir

const char* ast_config_AST_LOG_DIR = cfg_paths.log_dir

const char* ast_config_AST_MODULE_DIR = cfg_paths.module_dir

const char* ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir

const char* ast_config_AST_PID = cfg_paths.pid_path

Definition at line 269 of file asterisk.c.

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

const char* ast_config_AST_RUN_DIR = cfg_paths.run_dir

Definition at line 265 of file asterisk.c.

Referenced by ast_str_retrieve_variable(), handle_show_settings(), launch_script(), and main().

const char* ast_config_AST_RUN_GROUP = cfg_paths.run_group

Definition at line 272 of file asterisk.c.

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

const char* ast_config_AST_RUN_USER = cfg_paths.run_user

Definition at line 271 of file asterisk.c.

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

const char* ast_config_AST_SBIN_DIR = cfg_paths.sbin_dir

Definition at line 266 of file asterisk.c.

Referenced by convert_bdb_to_sqlite3(), and main().

const char* ast_config_AST_SOCKET = cfg_paths.socket_path

Definition at line 270 of file asterisk.c.

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

const char* ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir

const char* ast_config_AST_SYSTEM_NAME = cfg_paths.system_name

const char* ast_config_AST_VAR_DIR = cfg_paths.var_dir

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

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

Referenced by aji_devstate_cb(), aji_handle_pubsub_event(), aji_mwi_cb(), aji_publish_device_state(), aji_publish_mwi(), ast_event_append_eid(), ast_event_cb(), ast_readconfig(), ast_str_retrieve_variable(), cpg_confchg_cb(), cpg_deliver_cb(), handle_show_settings(), and set_config().

unsigned int ast_FD_SETSIZE

Definition at line 86 of file poll.c.

struct timeval ast_lastreloadtime

pid_t ast_mainpid

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

struct timeval ast_startuptime

char canary_filename[128] [static]

Definition at line 297 of file asterisk.c.

Referenced by canary_thread(), and main().

int canary_pid = 0 [static]

Definition at line 296 of file asterisk.c.

Referenced by canary_exit(), and main().

struct _cfg_paths cfg_paths [static]

Definition at line 253 of file asterisk.c.

Referenced by ast_readconfig(), and main().

struct sigaction child_handler [static]

Initial value:

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

Definition at line 1538 of file asterisk.c.

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 2177 of file asterisk.c.

struct console consoles[AST_MAX_CONNECTS]

pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 294 of file asterisk.c.

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

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 225 of file asterisk.c.

Referenced by __ast_channel_alloc_ap(), ast_readconfig(), and handle_show_settings().

EditLine* el [static]

History* el_hist [static]

struct sigaction hup_handler [static]

Initial value:

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

Definition at line 1518 of file asterisk.c.

struct sigaction ignore_sig_handler [static]

Initial value:

 {
   .sa_handler = SIG_IGN,
}

Definition at line 1005 of file asterisk.c.

Referenced by main().

const char license_lines[] [static]

Definition at line 2136 of file asterisk.c.

pthread_t lthread [static]

Definition at line 1197 of file asterisk.c.

Referenced by ast_makesocket(), and really_quit().

pthread_t mon_sig_flags [static]

Definition at line 295 of file asterisk.c.

Referenced by main(), and really_quit().

unsigned int need_quit

Definition at line 304 of file asterisk.c.

unsigned int need_quit_handler

Definition at line 305 of file asterisk.c.

unsigned int need_reload

Definition at line 303 of file asterisk.c.

struct sigaction null_sig_handler [static]

Initial value:

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

Definition at line 1000 of file asterisk.c.

Referenced by ast_replace_sigchld().

struct profile_data* prof_data [static]

struct ast_str* prompt = NULL [static]

Definition at line 2300 of file asterisk.c.

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

char randompool[256] [static]

Definition at line 299 of file asterisk.c.

Referenced by main().

char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR

Definition at line 194 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 221 of file asterisk.c.

Referenced by ast_remotecontrol(), and cli_prompt().

int restartnow [static]

Definition at line 293 of file asterisk.c.

Referenced by _hup_handler(), and really_quit().

unsigned int safe_system_level = 0 [static]

Keep track of how many threads are currently trying to wait*() on a child process.

Definition at line 1012 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

ast_mutex_t safe_system_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static]

struct sigaction safe_system_prev_handler [static]

Definition at line 1013 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN [static]

Definition at line 292 of file asterisk.c.

Referenced by can_safely_quit(), and handle_abort_shutdown().

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

Definition at line 301 of file asterisk.c.

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

struct { ... } sig_flags [static]

struct sigaction urg_handler [static]

Initial value:

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

Definition at line 1497 of file asterisk.c.

const char warranty_lines[] [static]

Definition at line 2093 of file asterisk.c.


Generated on Fri Feb 10 06:34:56 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6