Thu Apr 28 2011 16:56:55

Asterisk developer's documentation


asterisk.c File Reference

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

#include "asterisk.h"
#include "asterisk/_private.h"
#include <sys/time.h>
#include <fcntl.h>
#include <signal.h>
#include <sched.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <ctype.h>
#include <sys/resource.h>
#include <grp.h>
#include <pwd.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/paths.h"
#include "asterisk/network.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/features.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/image.h"
#include "asterisk/tdd.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/cdr.h"
#include "asterisk/pbx.h"
#include "asterisk/enum.h"
#include "asterisk/rtp.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/doxyref.h"
#include "../defaults.h"
Include dependency graph for asterisk.c:

Go to the source code of this file.

Data Structures

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

Defines

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

Functions

static void __fini_atexits (void)
static void __fini_file_versions (void)
static void __fini_thread_list (void)
static void __init_atexits (void)
static void __init_file_versions (void)
static void __init_thread_list (void)
static void __quit_handler (int num)
static void __remote_quit_handler (int num)
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)
void ast_console_toggle_mute (int fd, int silent)
 mute or unmute a console from logging
static int ast_el_add_history (char *)
static int ast_el_initialize (void)
static int ast_el_read_char (EditLine *editline, char *cp)
static int ast_el_read_history (char *)
static int ast_el_sort_compare (const void *i1, const void *i2)
static char ** ast_el_strtoarr (char *buf)
static int ast_el_write_history (char *)
const char * ast_file_version_find (const char *file)
 Find version for given module name.
static int ast_makesocket (void)
int64_t ast_mark (int i, int startstop)
static void ast_network_puts (const char *string)
 write the string to all attached console clients
static void ast_network_puts_mutable (const char *string, int level)
 log the string to all attached console clients
int64_t ast_profile (int i, int64_t delta)
static void ast_readconfig (void)
int ast_register_atexit (void(*func)(void))
 Register a function to be executed before Asterisk exits.
void ast_register_file_version (const char *file, const char *version)
 Register the version of a source code file with the core.
void ast_register_thread (char *name)
static void ast_remotecontrol (char *data)
void ast_replace_sigchld (void)
 Replace the SIGCHLD handler.
static void ast_run_atexits (void)
int ast_safe_system (const char *s)
 Safely spawn an external program while closing file descriptors.
int ast_set_priority (int pri)
 We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy activity on it, this is a good thing.
static int ast_tryconnect (void)
void ast_unregister_atexit (void(*func)(void))
 Unregister a function registered with ast_register_atexit().
void ast_unregister_file_version (const char *file)
 Unregister a source code file from the core.
void ast_unregister_thread (void *id)
void ast_unreplace_sigchld (void)
 Restore the SIGCHLD handler.
static void canary_exit (void)
static void * canary_thread (void *unused)
static char * cli_complete (EditLine *editline, int ch)
static char * cli_prompt (EditLine *editline)
static void console_verboser (const char *s)
static void consolehandler (char *s)
static 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, int niceness, int safeshutdown, int restart)
static __inline uint64_t rdtsc (void)
static int read_credentials (int fd, char *buffer, size_t size, struct console *con)
 read() function supporting the reception of user credentials.
static int remoteconsolehandler (char *s)
static void run_startup_commands (void)
static void set_icon (char *text)
static void set_title (char *text)
 Set an X-term or screen title.
static void set_ulimit (int value)
 Set maximum open files.
static int show_cli_help (void)
static char * show_license (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int show_version (void)
static char * show_warranty (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Variables

static char * _argv [256]
struct ast_flags ast_compat = { 7 }
const char * ast_config_AST_AGI_DIR = cfg_paths.agi_dir
const char * ast_config_AST_CONFIG_DIR = cfg_paths.config_dir
const char * ast_config_AST_CONFIG_FILE = cfg_paths.config_file
static char ast_config_AST_CTL [PATH_MAX] = "asterisk.ctl"
static char ast_config_AST_CTL_GROUP [PATH_MAX] = "\0"
static char ast_config_AST_CTL_OWNER [PATH_MAX] = "\0"
static char ast_config_AST_CTL_PERMISSIONS [PATH_MAX]
const char * ast_config_AST_DATA_DIR = cfg_paths.data_dir
const char * ast_config_AST_DB = cfg_paths.db_path
const char * ast_config_AST_KEY_DIR = cfg_paths.key_dir
const char * ast_config_AST_LOG_DIR = cfg_paths.log_dir
const char * ast_config_AST_MODULE_DIR = cfg_paths.module_dir
const char * ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir
const char * ast_config_AST_PID = cfg_paths.pid_path
const char * ast_config_AST_RUN_DIR = cfg_paths.run_dir
const char * ast_config_AST_RUN_GROUP = cfg_paths.run_group
const char * ast_config_AST_RUN_USER = cfg_paths.run_user
const char * ast_config_AST_SOCKET = cfg_paths.socket_path
const char * ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir
const char * ast_config_AST_SYSTEM_NAME = cfg_paths.system_name
const char * ast_config_AST_VAR_DIR = cfg_paths.var_dir
static int ast_consock = -1
struct ast_eid ast_eid_default
 Global EID.
unsigned int ast_FD_SETSIZE
struct timeval ast_lastreloadtime
pid_t ast_mainpid
struct ast_flags ast_options = { AST_DEFAULT_OPTIONS }
static int ast_socket = -1
struct timeval ast_startuptime
static struct atexits atexits
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 file_versions file_versions
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 = AST_MUTEX_INIT_VALUE
static struct sigaction safe_system_prev_handler
static int shuttingdown
static int sig_alert_pipe [2] = { -1, -1 }
struct {
   unsigned int   need_quit:1
   unsigned int   need_reload:1
sig_flags
static struct thread_list thread_list
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 147 of file asterisk.c.

Referenced by ast_makesocket(), ast_tryconnect(), and listener().

#define AST_MAX_CONNECTS   128
#define ASTERISK_PROMPT   "*CLI> "

Definition at line 2082 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 2084 of file asterisk.c.

Referenced by cli_prompt().

#define DEFINE_PROFILE_MIN_MAX_VALUES

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

Referenced by ast_el_add_history().

#define NUM_MSGS   64

Definition at line 152 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

Definition at line 148 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 155 of file asterisk.c.

Referenced by ast_el_read_char(), and main().


Function Documentation

static void __fini_atexits ( void  ) [static]

Definition at line 208 of file asterisk.c.

{
static void __fini_file_versions ( void  ) [static]

Definition at line 297 of file asterisk.c.

{
static void __fini_thread_list ( void  ) [static]

Definition at line 381 of file asterisk.c.

{ 
static void __init_atexits ( void  ) [static]

Definition at line 208 of file asterisk.c.

{
static void __init_file_versions ( void  ) [static]

Definition at line 297 of file asterisk.c.

{
static void __init_thread_list ( void  ) [static]

Definition at line 381 of file asterisk.c.

{ 
static void __quit_handler ( int  num) [static]

Definition at line 1704 of file asterisk.c.

References errno, sig_alert_pipe, and sig_flags.

Referenced by main().

{
   int a = 0;
   sig_flags.need_quit = 1;
   if (sig_alert_pipe[1] != -1) {
      if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
         fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
      }
   }
   /* There is no need to restore the signal handler here, since the app
    * is going to exit */
}
static void __remote_quit_handler ( int  num) [static]

Definition at line 1717 of file asterisk.c.

References sig_flags.

Referenced by ast_remotecontrol().

{
   sig_flags.need_quit = 1;
}
static void _child_handler ( int  sig) [static]

Definition at line 1485 of file asterisk.c.

References status.

{
   /* Must not ever ast_log or ast_verbose within signal handler */
   int n, status;

   /*
    * Reap all dead children -- not just one
    */
   for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
      ;
   if (n == 0 && option_debug)   
      printf("Huh?  Child handler, but nobody there?\n");
}
static void _hup_handler ( int  num) [static]

Definition at line 1465 of file asterisk.c.

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

{
   int a = 0;
   if (option_verbose > 1) 
      printf("Received HUP signal -- Reloading configs\n");
   if (restartnow)
      execvp(_argv[0], _argv);
   sig_flags.need_reload = 1;
   if (sig_alert_pipe[1] != -1) {
      if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
         fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
      }
   }
}
static void _null_sig_handler ( int  sig) [static]

NULL handler so we can collect the child exit status.

Definition at line 971 of file asterisk.c.

{

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

{
   return;
}
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 682 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().

{
   int l = sizeof(struct profile_data);
   int n = 10; /* default entries */

   if (prof_data == NULL) {
      prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
      if (prof_data == NULL)
         return -1;
      prof_data->entries = 0;
      prof_data->max_size = n;
   }
   if (prof_data->entries >= prof_data->max_size) {
      void *p;
      n = prof_data->max_size + 20;
      p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
      if (p == NULL)
         return -1;
      prof_data = p;
      prof_data->max_size = n;
   }
   n = prof_data->entries++;
   prof_data->e[n].name = ast_strdup(name);
   prof_data->e[n].value = 0;
   prof_data->e[n].events = 0;
   prof_data->e[n].mark = 0;
   prof_data->e[n].scale = scale;
   return n;
}
static int ast_all_zeros ( char *  s) [static]

Definition at line 1764 of file asterisk.c.

Referenced by consolehandler(), and remoteconsolehandler().

{
   while (*s) {
      if (*s > 32)
         return 0;
      s++;  
   }
   return 1;
}
static int ast_cli_display_match_list ( char **  matches,
int  len,
int  max 
) [static]

Definition at line 2390 of file asterisk.c.

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

Referenced by cli_complete().

{
   int i, idx, limit, count;
   int screenwidth = 0;
   int numoutput = 0, numoutputline = 0;

   screenwidth = ast_get_termcols(STDOUT_FILENO);

   /* find out how many entries can be put on one line, with two spaces between strings */
   limit = screenwidth / (max + 2);
   if (limit == 0)
      limit = 1;

   /* how many lines of output */
   count = len / limit;
   if (count * limit < len)
      count++;

   idx = 1;

   qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);

   for (; count > 0; count--) {
      numoutputline = 0;
      for (i = 0; i < limit && matches[idx]; i++, idx++) {

         /* Don't print dupes */
         if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
            i--;
            ast_free(matches[idx]);
            matches[idx] = NULL;
            continue;
         }

         numoutput++;
         numoutputline++;
         fprintf(stdout, "%-*s  ", max, matches[idx]);
         ast_free(matches[idx]);
         matches[idx] = NULL;
      }
      if (numoutputline > 0)
         fprintf(stdout, "\n");
   }

   return numoutput;
}
char* ast_complete_source_filename ( const char *  partial,
int  n 
)

Definition at line 338 of file asterisk.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, and len().

Referenced by handle_verbose().

{
   struct file_version *find;
   size_t len = strlen(partial);
   int count = 0;
   char *res = NULL;

   AST_RWLIST_RDLOCK(&file_versions);
   AST_RWLIST_TRAVERSE(&file_versions, find, list) {
      if (!strncasecmp(find->file, partial, len) && ++count > n) {
         res = ast_strdup(find->file);
         break;
      }
   }
   AST_RWLIST_UNLOCK(&file_versions);
   return res;
}
void ast_console_puts ( const char *  string)

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

Definition at line 1153 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

{
   fputs(string, stdout);
   fflush(stdout);
   ast_network_puts(string);
}
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 1130 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by logger_print_normal().

{
   fputs(string, stdout);
   fflush(stdout);
   ast_network_puts_mutable(string, level);
}
void ast_console_toggle_loglevel ( int  fd,
int  level,
int  state 
)
Since:
1.6.1

Definition at line 1077 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and console::levels.

Referenced by handle_logger_set_level().

{
   int x;
   for (x = 0;x < AST_MAX_CONNECTS; x++) {
      if (fd == consoles[x].fd) {
         consoles[x].levels[level] = state;
         return;
      }
   }
}
void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1091 of file asterisk.c.

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

Referenced by handle_logger_mute().

                                                 {
   int x;
   for (x = 0;x < AST_MAX_CONNECTS; x++) {
      if (fd == consoles[x].fd) {
         if (consoles[x].mute) {
            consoles[x].mute = 0;
            if (!silent)
               ast_cli(fd, "Console is not muted anymore.\n");
         } else {
            consoles[x].mute = 1;
            if (!silent)
               ast_cli(fd, "Console is muted.\n");
         }
         return;
      }
   }
   ast_cli(fd, "Couldn't find remote console.\n");
}
static int ast_el_add_history ( char *  buf) [static]

Definition at line 2593 of file asterisk.c.

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

Referenced by consolehandler(), and remoteconsolehandler().

{
   HistEvent ev;

   if (el_hist == NULL || el == NULL)
      ast_el_initialize();
   if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1))
      return 0;
   return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf))));
}
static int ast_el_initialize ( void  ) [static]

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

{
   HistEvent ev;
   char *editor = getenv("AST_EDITOR");

   if (el != NULL)
      el_end(el);
   if (el_hist != NULL)
      history_end(el_hist);

   el = el_init("asterisk", stdin, stdout, stderr);
   el_set(el, EL_PROMPT, cli_prompt);

   el_set(el, EL_EDITMODE, 1);      
   el_set(el, EL_EDITOR, editor ? editor : "emacs");     
   el_hist = history_init();
   if (!el || !el_hist)
      return -1;

   /* setup history with 100 entries */
   history(el_hist, &ev, H_SETSIZE, 100);

   el_set(el, EL_HIST, history, el_hist);

   el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
   /* Bind <tab> to command completion */
   el_set(el, EL_BIND, "^I", "ed-complete", NULL);
   /* Bind ? to command completion */
   el_set(el, EL_BIND, "?", "ed-complete", NULL);
   /* Bind ^D to redisplay */
   el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);

   return 0;
}
static int ast_el_read_char ( EditLine *  editline,
char *  cp 
) [static]

Definition at line 2110 of file asterisk.c.

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

Referenced by ast_remotecontrol().

{
   int num_read = 0;
   int lastpos = 0;
   struct pollfd fds[2];
   int res;
   int max;
#define EL_BUF_SIZE 512
   char buf[EL_BUF_SIZE];

   for (;;) {
      max = 1;
      fds[0].fd = ast_consock;
      fds[0].events = POLLIN;
      if (!ast_opt_exec) {
         fds[1].fd = STDIN_FILENO;
         fds[1].events = POLLIN;
         max++;
      }
      res = ast_poll(fds, max, -1);
      if (res < 0) {
         if (sig_flags.need_quit)
            break;
         if (errno == EINTR)
            continue;
         ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
         break;
      }

      if (!ast_opt_exec && fds[1].revents) {
         num_read = read(STDIN_FILENO, cp, 1);
         if (num_read < 1) {
            break;
         } else 
            return (num_read);
      }
      if (fds[0].revents) {
         char *tmp;
         res = read(ast_consock, buf, sizeof(buf) - 1);
         /* if the remote side disappears exit */
         if (res < 1) {
            fprintf(stderr, "\nDisconnected from Asterisk server\n");
            if (!ast_opt_reconnect) {
               quit_handler(0, 0, 0, 0);
            } else {
               int tries;
               int reconnects_per_second = 20;
               fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
               for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
                  if (ast_tryconnect()) {
                     fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
                     printf("%s", term_quit());
                     WELCOME_MESSAGE;
                     if (!ast_opt_mute)
                        fdsend(ast_consock, "logger mute silent");
                     else 
                        printf("log and verbose output currently muted ('logger mute' to unmute)\n");
                     break;
                  } else
                     usleep(1000000 / reconnects_per_second);
               }
               if (tries >= 30 * reconnects_per_second) {
                  fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
                  quit_handler(0, 0, 0, 0);
               }
            }
         }

         buf[res] = '\0';

         /* Strip preamble from asynchronous events, too */
         for (tmp = buf; *tmp; tmp++) {
            if (*tmp == 127) {
               memmove(tmp, tmp + 1, strlen(tmp));
               tmp--;
               res--;
            }
         }

         /* Write over the CLI prompt */
         if (!ast_opt_exec && !lastpos) {
            if (write(STDOUT_FILENO, "\r", 5) < 0) {
            }
         }
         if (write(STDOUT_FILENO, buf, res) < 0) {
         }
         if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
            *cp = CC_REFRESH;
            return(1);
         } else
            lastpos = 1;
      }
   }

   *cp = '\0';
   return (0);
}
static int ast_el_read_history ( char *  filename) [static]

Definition at line 2614 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by ast_remotecontrol(), and main().

{
   HistEvent ev;

   if (el_hist == NULL || el == NULL)
      ast_el_initialize();

   return (history(el_hist, &ev, H_LOAD, filename));
}
static int ast_el_sort_compare ( const void *  i1,
const void *  i2 
) [static]

Definition at line 2380 of file asterisk.c.

Referenced by ast_cli_display_match_list().

{
   char *s1, *s2;

   s1 = ((char **)i1)[0];
   s2 = ((char **)i2)[0];

   return strcasecmp(s1, s2);
}
static char** ast_el_strtoarr ( char *  buf) [static]

Definition at line 2337 of file asterisk.c.

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

Referenced by cli_complete().

{
   char **match_list = NULL, **match_list_tmp, *retstr;
   size_t match_list_len;
   int matches = 0;

   match_list_len = 1;
   while ( (retstr = strsep(&buf, " ")) != NULL) {

      if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
         break;
      if (matches + 1 >= match_list_len) {
         match_list_len <<= 1;
         if ((match_list_tmp = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
            match_list = match_list_tmp;
         } else {
            if (match_list)
               ast_free(match_list);
            return (char **) NULL;
         }
      }

      match_list[matches++] = ast_strdup(retstr);
   }

   if (!match_list)
      return (char **) NULL;

   if (matches >= match_list_len) {
      if ((match_list_tmp = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
         match_list = match_list_tmp;
      } else {
         if (match_list)
            ast_free(match_list);
         return (char **) NULL;
      }
   }

   match_list[matches] = (char *) NULL;

   return match_list;
}
static int ast_el_write_history ( char *  filename) [static]

Definition at line 2604 of file asterisk.c.

References ast_el_initialize(), el, and el_hist.

Referenced by quit_handler().

{
   HistEvent ev;

   if (el_hist == NULL || el == NULL)
      ast_el_initialize();

   return (history(el_hist, &ev, H_SAVE, filename));
}
const char* ast_file_version_find ( const char *  file)

Find version for given module name.

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

Definition at line 357 of file asterisk.c.

References AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

Referenced by manager_modulecheck().

{
   struct file_version *iterator;

   AST_RWLIST_WRLOCK(&file_versions);
   AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, iterator, list) {
      if (!strcasecmp(iterator->file, file))
         break;
   }
   AST_RWLIST_TRAVERSE_SAFE_END;
   AST_RWLIST_UNLOCK(&file_versions);
   if (iterator)
      return iterator->version;
   return NULL;
}      
static int ast_makesocket ( void  ) [static]

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

{
   struct sockaddr_un sunaddr;
   int res;
   int x;
   uid_t uid = -1;
   gid_t gid = -1;

   for (x = 0; x < AST_MAX_CONNECTS; x++) 
      consoles[x].fd = -1;
   unlink(ast_config_AST_SOCKET);
   ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
   if (ast_socket < 0) {
      ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
      return -1;
   }     
   memset(&sunaddr, 0, sizeof(sunaddr));
   sunaddr.sun_family = AF_LOCAL;
   ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
   res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
   if (res) {
      ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
      close(ast_socket);
      ast_socket = -1;
      return -1;
   }
   res = listen(ast_socket, 2);
   if (res < 0) {
      ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
      close(ast_socket);
      ast_socket = -1;
      return -1;
   }
   if (ast_register_verbose(network_verboser)) {
      ast_log(LOG_WARNING, "Unable to register network verboser?\n");
   }

   ast_pthread_create_background(&lthread, NULL, listener, NULL);

   if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
      struct passwd *pw;
      if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
         ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
      else
         uid = pw->pw_uid;
   }
      
   if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
      struct group *grp;
      if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
         ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
      else
         gid = grp->gr_gid;
   }

   if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
      ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));

   if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
      int p1;
      mode_t p;
      sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
      p = p1;
      if ((chmod(ast_config_AST_SOCKET, p)) < 0)
         ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
   }

   return 0;
}
int64_t ast_mark ( int  i,
int  startstop 
)

Definition at line 747 of file asterisk.c.

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

Referenced by extension_match_core().

{
   if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
      return 0;
   if (startstop == 1)
      prof_data->e[i].mark = rdtsc();
   else {
      prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
      if (prof_data->e[i].scale > 1)
         prof_data->e[i].mark /= prof_data->e[i].scale;
      prof_data->e[i].value += prof_data->e[i].mark;
      prof_data->e[i].events++;
   }
   return prof_data->e[i].mark;
}
static void ast_network_puts ( const char *  string) [static]

write the string to all attached console clients

Definition at line 1140 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

{
   int x;
   for (x = 0; x < AST_MAX_CONNECTS; x++) {
      if (consoles[x].fd > -1) 
         fdprint(consoles[x].p[1], string);
   }
}
static void ast_network_puts_mutable ( const char *  string,
int  level 
) [static]

log the string to all attached console clients

Definition at line 1113 of file asterisk.c.

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

Referenced by ast_console_puts_mutable(), and network_verboser().

{
   int x;
   for (x = 0;x < AST_MAX_CONNECTS; x++) {
      if (consoles[x].mute)
         continue;
      if (consoles[x].fd > -1) {
         if (!consoles[x].levels[level]) 
            fdprint(consoles[x].p[1], string);
      }
   }
}
int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 712 of file asterisk.c.

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

{
   if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
      return 0;
   if (prof_data->e[i].scale > 1)
      delta /= prof_data->e[i].scale;
   prof_data->e[i].value += delta;
   prof_data->e[i].events++;
   return prof_data->e[i].value;
}
static void ast_readconfig ( void  ) [static]

Definition at line 2813 of file asterisk.c.

References _cfg_paths::agi_dir, AST_CACHE_DIR_LEN, AST_COMPAT_APP_SET, AST_COMPAT_DELIM_PBX_REALTIME, AST_COMPAT_DELIM_RES_AGI, ast_config_AST_CONFIG_FILE, ast_config_AST_CTL, ast_config_AST_CTL_GROUP, ast_config_AST_CTL_OWNER, ast_config_AST_CTL_PERMISSIONS, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_eid_default, ast_language_is_prefix, AST_LOCK_TYPE_FLOCK, AST_LOCK_TYPE_LOCKFILE, ast_log(), AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DONT_WARN, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND, AST_OPT_FLAG_HIDE_CONSOLE_CONNECT, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_LIGHT_BACKGROUND, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_SEND_FULLYBOOTED, AST_OPT_FLAG_TIMESTAMP, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_opt_override_config, ast_set2_flag, ast_set_default_eid(), ast_set_lock_type(), ast_str_to_eid(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_verbose(), cfg_paths, config, _cfg_paths::config_dir, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, _cfg_paths::data_dir, _cfg_paths::db_path, DEFAULT_AGI_DIR, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILE, DEFAULT_DATA_DIR, DEFAULT_DB, DEFAULT_KEY_DIR, DEFAULT_LOG_DIR, DEFAULT_MODULE_DIR, DEFAULT_PID, DEFAULT_RUN_DIR, DEFAULT_SOCKET, DEFAULT_SPOOL_DIR, DEFAULT_VAR_DIR, getloadavg(), hostname, _cfg_paths::key_dir, _cfg_paths::log_dir, LOG_ERROR, LOG_WARNING, MAXHOSTNAMELEN, _cfg_paths::module_dir, _cfg_paths::monitor_dir, ast_variable::name, ast_variable::next, _cfg_paths::pid_path, _cfg_paths::run_dir, _cfg_paths::run_group, _cfg_paths::run_user, set_ulimit(), _cfg_paths::socket_path, _cfg_paths::spool_dir, _cfg_paths::system_name, ast_variable::value, _cfg_paths::var_dir, and version.

Referenced by main().

{
   struct ast_config *cfg;
   struct ast_variable *v;
   char *config = DEFAULT_CONFIG_FILE;
   char hostname[MAXHOSTNAMELEN] = "";
   struct ast_flags config_flags = { 0 };
   struct {
      unsigned int dbdir:1;
      unsigned int keydir:1;
   } found = { 0, 0 };

   if (ast_opt_override_config) {
      cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
      if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
         ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
   } else 
      cfg = ast_config_load2(config, "" /* core, can't reload */, config_flags);

   /* init with buildtime config */
   ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir));
   ast_copy_string(cfg_paths.spool_dir, DEFAULT_SPOOL_DIR, sizeof(cfg_paths.spool_dir));
   ast_copy_string(cfg_paths.module_dir, DEFAULT_MODULE_DIR, sizeof(cfg_paths.module_dir));
   snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", cfg_paths.spool_dir);
   ast_copy_string(cfg_paths.var_dir, DEFAULT_VAR_DIR, sizeof(cfg_paths.var_dir));
   ast_copy_string(cfg_paths.data_dir, DEFAULT_DATA_DIR, sizeof(cfg_paths.data_dir));
   ast_copy_string(cfg_paths.log_dir, DEFAULT_LOG_DIR, sizeof(cfg_paths.log_dir));
   ast_copy_string(cfg_paths.agi_dir, DEFAULT_AGI_DIR, sizeof(cfg_paths.agi_dir));
   ast_copy_string(cfg_paths.db_path, DEFAULT_DB, sizeof(cfg_paths.db_path));
   ast_copy_string(cfg_paths.key_dir, DEFAULT_KEY_DIR, sizeof(cfg_paths.key_dir));
   ast_copy_string(cfg_paths.pid_path, DEFAULT_PID, sizeof(cfg_paths.pid_path));
   ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path));
   ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir));

   ast_set_default_eid(&ast_eid_default);

   /* no asterisk.conf? no problem, use buildtime config! */
   if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
      return;
   }

   for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
      if (!strcasecmp(v->name, "astctlpermissions"))
         ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
      else if (!strcasecmp(v->name, "astctlowner"))
         ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
      else if (!strcasecmp(v->name, "astctlgroup"))
         ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
      else if (!strcasecmp(v->name, "astctl"))
         ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
   }

   for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
      if (!strcasecmp(v->name, "astetcdir")) {
         ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir));
      } else if (!strcasecmp(v->name, "astspooldir")) {
         ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir));
         snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value);
      } else if (!strcasecmp(v->name, "astvarlibdir")) {
         ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir));
         if (!found.dbdir)
            snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
      } else if (!strcasecmp(v->name, "astdbdir")) {
         snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
         found.dbdir = 1;
      } else if (!strcasecmp(v->name, "astdatadir")) {
         ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir));
         if (!found.keydir)
            snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
      } else if (!strcasecmp(v->name, "astkeydir")) {
         snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
         found.keydir = 1;
      } else if (!strcasecmp(v->name, "astlogdir")) {
         ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir));
      } else if (!strcasecmp(v->name, "astagidir")) {
         ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir));
      } else if (!strcasecmp(v->name, "astrundir")) {
         snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid");
         snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", v->value, ast_config_AST_CTL);
         ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir));
      } else if (!strcasecmp(v->name, "astmoddir")) {
         ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir));
      }
   }

   for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
      /* verbose level (-v at startup) */
      if (!strcasecmp(v->name, "verbose")) {
         option_verbose = atoi(v->value);
      /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
      } else if (!strcasecmp(v->name, "timestamp")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
      /* whether or not to support #exec in config files */
      } else if (!strcasecmp(v->name, "execincludes")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
      /* debug level (-d at startup) */
      } else if (!strcasecmp(v->name, "debug")) {
         option_debug = 0;
         if (sscanf(v->value, "%30d", &option_debug) != 1) {
            option_debug = ast_true(v->value);
         }
#if HAVE_WORKING_FORK
      /* Disable forking (-f at startup) */
      } else if (!strcasecmp(v->name, "nofork")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
      /* Always fork, even if verbose or debug are enabled (-F at startup) */
      } else if (!strcasecmp(v->name, "alwaysfork")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
#endif
      /* Run quietly (-q at startup ) */
      } else if (!strcasecmp(v->name, "quiet")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
      /* Run as console (-c at startup, implies nofork) */
      } else if (!strcasecmp(v->name, "console")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
      /* Run with high priority if the O/S permits (-p at startup) */
      } else if (!strcasecmp(v->name, "highpriority")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
      /* Initialize RSA auth keys (IAX2) (-i at startup) */
      } else if (!strcasecmp(v->name, "initcrypto")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
      /* Disable ANSI colors for console (-c at startup) */
      } else if (!strcasecmp(v->name, "nocolor")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
      /* Disable some usage warnings for picky people :p */
      } else if (!strcasecmp(v->name, "dontwarn")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
      /* Dump core in case of crash (-g) */
      } else if (!strcasecmp(v->name, "dumpcore")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
      /* Cache recorded sound files to another directory during recording */
      } else if (!strcasecmp(v->name, "cache_record_files")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
      /* Specify cache directory */
      }  else if (!strcasecmp(v->name, "record_cache_dir")) {
         ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
      /* Build transcode paths via SLINEAR, instead of directly */
      } else if (!strcasecmp(v->name, "transcode_via_sln")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
      /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
      } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
      /* Enable internal timing */
      } else if (!strcasecmp(v->name, "internal_timing")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING);
      } else if (!strcasecmp(v->name, "maxcalls")) {
         if ((sscanf(v->value, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
            option_maxcalls = 0;
         }
      } else if (!strcasecmp(v->name, "maxload")) {
         double test[1];

         if (getloadavg(test, 1) == -1) {
            ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
            option_maxload = 0.0;
         } else if ((sscanf(v->value, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
            option_maxload = 0.0;
         }
      /* Set the maximum amount of open files */
      } else if (!strcasecmp(v->name, "maxfiles")) {
         option_maxfiles = atoi(v->value);
         set_ulimit(option_maxfiles);
      /* What user to run as */
      } else if (!strcasecmp(v->name, "runuser")) {
         ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user));
      /* What group to run as */
      } else if (!strcasecmp(v->name, "rungroup")) {
         ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group));
      } else if (!strcasecmp(v->name, "systemname")) {
         ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name));
      } else if (!strcasecmp(v->name, "autosystemname")) {
         if (ast_true(v->value)) {
            if (!gethostname(hostname, sizeof(hostname) - 1))
               ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name));
            else {
               if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){
                  ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name));
               }
               ast_log(LOG_ERROR, "Cannot obtain hostname for this system.  Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME);
            }
         }
      } else if (!strcasecmp(v->name, "languageprefix")) {
         ast_language_is_prefix = ast_true(v->value);
      } else if (!strcasecmp(v->name, "lockmode")) {
         if (!strcasecmp(v->value, "lockfile")) {
            ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
         } else if (!strcasecmp(v->value, "flock")) {
            ast_set_lock_type(AST_LOCK_TYPE_FLOCK);
         } else {
            ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, "
               "defaulting to 'lockfile'\n", v->value);
            ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
         }
#if defined(HAVE_SYSINFO)
      } else if (!strcasecmp(v->name, "minmemfree")) {
         /* specify the minimum amount of free memory to retain.  Asterisk should stop accepting new calls
          * if the amount of free memory falls below this watermark */
         if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
            option_minmemfree = 0;
         }
#endif
      } else if (!strcasecmp(v->name, "entityid")) {
         struct ast_eid tmp_eid;
         if (!ast_str_to_eid(&tmp_eid, v->value)) {
            ast_verbose("Successfully set global EID to '%s'\n", v->value);
            ast_eid_default = tmp_eid;
         } else
            ast_verbose("Invalid Entity ID '%s' provided\n", v->value);
      } else if (!strcasecmp(v->name, "lightbackground")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND);
      } else if (!strcasecmp(v->name, "forceblackbackground")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
      } else if (!strcasecmp(v->name, "hideconnect")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT);
      } else if (!strcasecmp(v->name, "sendfullybooted")) {
         ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_SEND_FULLYBOOTED);
      }
   }
   for (v = ast_variable_browse(cfg, "compat"); v; v = v->next) {
      float version;
      if (sscanf(v->value, "%30f", &version) != 1) {
         ast_log(LOG_WARNING, "Compatibility version for option '%s' is not a number: '%s'\n", v->name, v->value);
         continue;
      }
      if (!strcasecmp(v->name, "app_set")) {
         ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_APP_SET);
      } else if (!strcasecmp(v->name, "res_agi")) {
         ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_RES_AGI);
      } else if (!strcasecmp(v->name, "pbx_realtime")) {
         ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_PBX_REALTIME);
      }
   }
   ast_config_destroy(cfg);
}
int ast_register_atexit ( void(*)(void)  func)

Register a function to be executed before Asterisk exits.

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

Definition at line 923 of file asterisk.c.

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

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

{
   struct ast_atexit *ae;

   if (!(ae = ast_calloc(1, sizeof(*ae))))
      return -1;

   ae->func = func;

   ast_unregister_atexit(func);  

   AST_RWLIST_WRLOCK(&atexits);
   AST_RWLIST_INSERT_HEAD(&atexits, ae, list);
   AST_RWLIST_UNLOCK(&atexits);

   return 0;
}
void ast_register_file_version ( const char *  file,
const char *  version 
)

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

Parameters:
filethe source file name
versionthe 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 299 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().

{
   struct file_version *new;
   char *work;
   size_t version_length;

   work = ast_strdupa(version);
   work = ast_strip(ast_strip_quoted(work, "$", "$"));
   version_length = strlen(work) + 1;
   
   if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
      return;

   new->file = file;
   new->version = (char *) new + sizeof(*new);
   memcpy(new->version, work, version_length);
   AST_RWLIST_WRLOCK(&file_versions);
   AST_RWLIST_INSERT_HEAD(&file_versions, new, list);
   AST_RWLIST_UNLOCK(&file_versions);
}
void ast_register_thread ( char *  name)

Definition at line 383 of file asterisk.c.

References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and name.

Referenced by dummy_start().

{ 
   struct thread_list_t *new = ast_calloc(1, sizeof(*new));

   if (!new)
      return;
   new->id = pthread_self();
   new->name = name; /* steal the allocated memory for the thread name */
   AST_RWLIST_WRLOCK(&thread_list);
   AST_RWLIST_INSERT_HEAD(&thread_list, new, list);
   AST_RWLIST_UNLOCK(&thread_list);
}
static void ast_remotecontrol ( char *  data) [static]

Definition at line 2624 of file asterisk.c.

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

Referenced by main().

{
   char buf[80];
   int res;
   char filename[80] = "";
   char *hostname;
   char *cpid;
   char *version;
   int pid;
   char *stringp = NULL;

   char *ebuf;
   int num = 0;

   memset(&sig_flags, 0, sizeof(sig_flags));
   signal(SIGINT, __remote_quit_handler);
   signal(SIGTERM, __remote_quit_handler);
   signal(SIGHUP, __remote_quit_handler);

   if (read(ast_consock, buf, sizeof(buf)) < 0) {
      ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
      return;
   }
   if (data) {
      char prefix[] = "cli quit after ";
      char *tmp = alloca(strlen(data) + strlen(prefix) + 1);
      sprintf(tmp, "%s%s", prefix, data);
      if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
         ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
         if (sig_flags.need_quit == 1) {
            return;
         }
      }
   }
   stringp = buf;
   hostname = strsep(&stringp, "/");
   cpid = strsep(&stringp, "/");
   version = strsep(&stringp, "\n");
   if (!version)
      version = "<Version Unknown>";
   stringp = hostname;
   strsep(&stringp, ".");
   if (cpid)
      pid = atoi(cpid);
   else
      pid = -1;
   if (!data) {
      char tmp[80];
      snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
      fdsend(ast_consock, tmp);
      snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
      fdsend(ast_consock, tmp);
      if (!ast_opt_mute)
         fdsend(ast_consock, "logger mute silent");
      else 
         printf("log and verbose output currently muted ('logger mute' to unmute)\n");
   }

   if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
      struct pollfd fds;
      fds.fd = ast_consock;
      fds.events = POLLIN;
      fds.revents = 0;
      while (ast_poll(&fds, 1, 60000) > 0) {
         char buffer[512] = "", *curline = buffer, *nextline;
         int not_written = 1;

         if (sig_flags.need_quit == 1) {
            break;
         }

         if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
            break;
         }

         do {
            if ((nextline = strchr(curline, '\n'))) {
               nextline++;
            } else {
               nextline = strchr(curline, '\0');
            }

            /* Skip verbose lines */
            if (*curline != 127) {
               not_written = 0;
               if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
                  ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
               }
            }
            curline = nextline;
         } while (!ast_strlen_zero(curline));

         /* No non-verbose output in 60s */
         if (not_written) {
            break;
         }
      }
      return;
   }

   ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
   remotehostname = hostname;
   if (getenv("HOME")) 
      snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
   if (el_hist == NULL || el == NULL)
      ast_el_initialize();

   el_set(el, EL_GETCFN, ast_el_read_char);

   if (!ast_strlen_zero(filename))
      ast_el_read_history(filename);

   for (;;) {
      ebuf = (char *)el_gets(el, &num);

      if (sig_flags.need_quit == 1) {
         break;
      }

      if (!ebuf && write(1, "", 1) < 0)
         break;

      if (!ast_strlen_zero(ebuf)) {
         if (ebuf[strlen(ebuf)-1] == '\n')
            ebuf[strlen(ebuf)-1] = '\0';
         if (!remoteconsolehandler(ebuf)) {
            /* Strip preamble from output */
            char *temp;
            for (temp = ebuf; *temp; temp++) {
               if (*temp == 127) {
                  memmove(temp, temp + 1, strlen(temp));
                  temp--;
               }
            }
            res = write(ast_consock, ebuf, strlen(ebuf) + 1);
            if (res < 1) {
               ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
               break;
            }
         }
      }
   }
   printf("\nDisconnected from Asterisk server\n");
}
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 991 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().

{
   unsigned int level;

   ast_mutex_lock(&safe_system_lock);
   level = safe_system_level++;

   /* only replace the handler if it has not already been done */
   if (level == 0) {
      sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
   }

   ast_mutex_unlock(&safe_system_lock);
}
static void ast_run_atexits ( void  ) [static]

Definition at line 1576 of file asterisk.c.

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

Referenced by quit_handler().

{
   struct ast_atexit *ae;
   AST_RWLIST_RDLOCK(&atexits);
   AST_RWLIST_TRAVERSE(&atexits, ae, list) {
      if (ae->func) 
         ae->func();
   }
   AST_RWLIST_UNLOCK(&atexits);
}
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 1021 of file asterisk.c.

References ast_close_fds_above_n(), ast_log(), ast_opt_high_priority, ast_replace_sigchld(), ast_set_priority(), ast_unreplace_sigchld(), errno, LOG_WARNING, status, WEXITSTATUS, and WIFEXITED.

Referenced by add_email_attachment(), alarmreceiver_exec(), ast_monitor_stop(), consolehandler(), filestream_destructor(), mixmonitor_thread(), notify_message(), process_text_line(), remoteconsolehandler(), rotate_file(), run_externnotify(), sendmail(), sendpage(), system_exec_helper(), and vm_change_password_shell().

{
   pid_t pid;
   int res;
   struct rusage rusage;
   int status;

#if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
   ast_replace_sigchld();

#ifdef HAVE_WORKING_FORK
   pid = fork();
#else
   pid = vfork();
#endif   

   if (pid == 0) {
#ifdef HAVE_CAP
      cap_t cap = cap_from_text("cap_net_admin-eip");

      if (cap_set_proc(cap)) {
         /* Careful with order! Logging cannot happen after we close FDs */
         ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
      }
      cap_free(cap);
#endif
#ifdef HAVE_WORKING_FORK
      if (ast_opt_high_priority)
         ast_set_priority(0);
      /* Close file descriptors and launch system command */
      ast_close_fds_above_n(STDERR_FILENO);
#endif
      execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
      _exit(1);
   } else if (pid > 0) {
      for (;;) {
         res = wait4(pid, &status, 0, &rusage);
         if (res > -1) {
            res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
            break;
         } else if (errno != EINTR) 
            break;
      }
   } else {
      ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
      res = -1;
   }

   ast_unreplace_sigchld();
#else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */
   res = -1;
#endif

   return res;
}
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 1542 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().

{
   struct sched_param sched;
   memset(&sched, 0, sizeof(sched));
#ifdef __linux__
   if (pri) {  
      sched.sched_priority = 10;
      if (sched_setscheduler(0, SCHED_RR, &sched)) {
         ast_log(LOG_WARNING, "Unable to set high priority\n");
         return -1;
      } else
         if (option_verbose)
            ast_verbose("Set to realtime thread\n");
   } else {
      sched.sched_priority = 0;
      /* According to the manpage, these parameters can never fail. */
      sched_setscheduler(0, SCHED_OTHER, &sched);
   }
#else
   if (pri) {
      if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
         ast_log(LOG_WARNING, "Unable to set high priority\n");
         return -1;
      } else
         if (option_verbose)
            ast_verbose("Set to high priority\n");
   } else {
      /* According to the manpage, these parameters can never fail. */
      setpriority(PRIO_PROCESS, 0, 0);
   }
#endif
   return 0;
}
static int ast_tryconnect ( void  ) [static]

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

{
   struct sockaddr_un sunaddr;
   int res;
   ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
   if (ast_consock < 0) {
      ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
      return 0;
   }
   memset(&sunaddr, 0, sizeof(sunaddr));
   sunaddr.sun_family = AF_LOCAL;
   ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
   res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
   if (res) {
      close(ast_consock);
      ast_consock = -1;
      return 0;
   } else
      return 1;
}
void ast_unregister_atexit ( void(*)(void)  func)

Unregister a function registered with ast_register_atexit().

Parameters:
funcThe callback function to unregister.

Definition at line 941 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, and ast_atexit::func.

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

void ast_unregister_file_version ( const char *  file)

Unregister a source code file from the core.

Parameters:
filethe 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 320 of file asterisk.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

{
   struct file_version *find;

   AST_RWLIST_WRLOCK(&file_versions);
   AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
      if (!strcasecmp(find->file, file)) {
         AST_RWLIST_REMOVE_CURRENT(list);
         break;
      }
   }
   AST_RWLIST_TRAVERSE_SAFE_END;
   AST_RWLIST_UNLOCK(&file_versions);

   if (find)
      ast_free(find);
}
void ast_unregister_thread ( void *  id)
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 1006 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().

{
   unsigned int level;

   ast_mutex_lock(&safe_system_lock);
   level = --safe_system_level;

   /* only restore the handler if we are the last one */
   if (level == 0) {
      sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
   }

   ast_mutex_unlock(&safe_system_lock);
}
static void canary_exit ( void  ) [static]

Definition at line 3092 of file asterisk.c.

References canary_pid.

Referenced by main().

{
   if (canary_pid > 0)
      kill(canary_pid, SIGKILL);
}
static void* canary_thread ( void *  unused) [static]

Definition at line 3069 of file asterisk.c.

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

Referenced by main().

{
   struct stat canary_stat;
   struct timeval now;

   /* Give the canary time to sing */
   sleep(120);

   for (;;) {
      stat(canary_filename, &canary_stat);
      now = ast_tvnow();
      if (now.tv_sec > canary_stat.st_mtime + 60) {
         ast_log(LOG_WARNING, "The canary is no more.  He has ceased to be!  He's expired and gone to meet his maker!  He's a stiff!  Bereft of life, he rests in peace.  His metabolic processes are now history!  He's off the twig!  He's kicked the bucket.  He's shuffled off his mortal coil, run down the curtain, and joined the bleeding choir invisible!!  THIS is an EX-CANARY.  (Reducing priority)\n");
         ast_set_priority(0);
         pthread_exit(NULL);
      }

      /* Check the canary once a minute */
      sleep(60);
   }
}
static char* cli_complete ( EditLine *  editline,
int  ch 
) [static]

Definition at line 2438 of file asterisk.c.

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

Referenced by ast_el_initialize().

{
   int len = 0;
   char *ptr;
   int nummatches = 0;
   char **matches;
   int retval = CC_ERROR;
   char buf[2048], savechr;
   int res;

   LineInfo *lf = (LineInfo *)el_line(editline);

   savechr = *(char *)lf->cursor;
   *(char *)lf->cursor = '\0';
   ptr = (char *)lf->cursor;
   if (ptr) {
      while (ptr > lf->buffer) {
         if (isspace(*ptr)) {
            ptr++;
            break;
         }
         ptr--;
      }
   }

   len = lf->cursor - ptr;

   if (ast_opt_remote) {
      snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 
      fdsend(ast_consock, buf);
      res = read(ast_consock, buf, sizeof(buf) - 1);
      buf[res] = '\0';
      nummatches = atoi(buf);

      if (nummatches > 0) {
         char *mbuf;
         int mlen = 0, maxmbuf = 2048;
         /* Start with a 2048 byte buffer */       
         if (!(mbuf = ast_malloc(maxmbuf))) {
            lf->cursor[0] = savechr;
            return (char *)(CC_ERROR);
         }
         snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 
         fdsend(ast_consock, buf);
         res = 0;
         mbuf[0] = '\0';
         while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
            if (mlen + 1024 > maxmbuf) {
               /* Every step increment buffer 1024 bytes */
               maxmbuf += 1024;              
               if (!(mbuf = ast_realloc(mbuf, maxmbuf))) {
                  lf->cursor[0] = savechr;
                  return (char *)(CC_ERROR);
               }
            }
            /* Only read 1024 bytes at a time */
            res = read(ast_consock, mbuf + mlen, 1024);
            if (res > 0)
               mlen += res;
         }
         mbuf[mlen] = '\0';

         matches = ast_el_strtoarr(mbuf);
         ast_free(mbuf);
      } else
         matches = (char **) NULL;
   } else {
      char **p, *oldbuf=NULL;
      nummatches = 0;
      matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
      for (p = matches; p && *p; p++) {
         if (!oldbuf || strcmp(*p,oldbuf))
            nummatches++;
         oldbuf = *p;
      }
   }

   if (matches) {
      int i;
      int matches_num, maxlen, match_len;

      if (matches[0][0] != '\0') {
         el_deletestr(editline, (int) len);
         el_insertstr(editline, matches[0]);
         retval = CC_REFRESH;
      }

      if (nummatches == 1) {
         /* Found an exact match */
         el_insertstr(editline, " ");
         retval = CC_REFRESH;
      } else {
         /* Must be more than one match */
         for (i = 1, maxlen = 0; matches[i]; i++) {
            match_len = strlen(matches[i]);
            if (match_len > maxlen)
               maxlen = match_len;
         }
         matches_num = i - 1;
         if (matches_num >1) {
            fprintf(stdout, "\n");
            ast_cli_display_match_list(matches, nummatches, maxlen);
            retval = CC_REDISPLAY;
         } else { 
            el_insertstr(editline," ");
            retval = CC_REFRESH;
         }
      }
      for (i = 0; matches[i]; i++)
         ast_free(matches[i]);
      ast_free(matches);
   }

   lf->cursor[0] = savechr;

   return (char *)(long)retval;
}
static char* cli_prompt ( EditLine *  editline) [static]

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

Referenced by ast_el_initialize().

{
   char tmp[100];
   char *pfmt;
   int color_used = 0;
   static int cli_prompt_changes = 0;
   char term_code[20];
   struct passwd *pw;
   struct group *gr;

   if (prompt == NULL) {
      prompt = ast_str_create(100);
   } else if (!cli_prompt_changes) {
      return ast_str_buffer(prompt);
   } else {
      ast_str_reset(prompt);
   }

   if ((pfmt = getenv("ASTERISK_PROMPT"))) {
      char *t = pfmt;
      struct timeval ts = ast_tvnow();
      while (*t != '\0') {
         if (*t == '%') {
            char hostname[MAXHOSTNAMELEN] = "";
            int i, which;
            struct ast_tm tm = { 0, };
            int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;

            t++;
            switch (*t) {
            case 'C': /* color */
               t++;
               if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
                  ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)));
                  t += i - 1;
               } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
                  ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code)));
                  t += i - 1;
               }

               /* If the color has been reset correctly, then there's no need to reset it later */
               color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
               break;
            case 'd': /* date */
               if (ast_localtime(&ts, &tm, NULL)) {
                  ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
                  ast_str_append(&prompt, 0, "%s", tmp);
                  cli_prompt_changes++;
               }
               break;
            case 'g': /* group */
               if ((gr = getgrgid(getgid()))) {
                  ast_str_append(&prompt, 0, "%s", gr->gr_name);
               }
               break;
            case 'h': /* hostname */
               if (!gethostname(hostname, sizeof(hostname) - 1)) {
                  ast_str_append(&prompt, 0, "%s", hostname);
               } else {
                  ast_str_append(&prompt, 0, "%s", "localhost");
               }
               break;
            case 'H': /* short hostname */
               if (!gethostname(hostname, sizeof(hostname) - 1)) {
                  char *dotptr;
                  if ((dotptr = strchr(hostname, '.'))) {
                     *dotptr = '\0';
                  }
                  ast_str_append(&prompt, 0, "%s", hostname);
               } else {
                  ast_str_append(&prompt, 0, "%s", "localhost");
               }
               break;
#ifdef HAVE_GETLOADAVG
            case 'l': /* load avg */
               t++;
               if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
                  double list[3];
                  getloadavg(list, 3);
                  ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
                  cli_prompt_changes++;
               }
               break;
#endif
            case 's': /* Asterisk system name (from asterisk.conf) */
               ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
               break;
            case 't': /* time */
               if (ast_localtime(&ts, &tm, NULL)) {
                  ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
                  ast_str_append(&prompt, 0, "%s", tmp);
                  cli_prompt_changes++;
               }
               break;
            case 'u': /* username */
               if ((pw = getpwuid(getuid()))) {
                  ast_str_append(&prompt, 0, "%s", pw->pw_name);
               }
               break;
            case '#': /* process console or remote? */
               ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
               break;
            case '%': /* literal % */
               ast_str_append(&prompt, 0, "%c", '%');
               break;
            case '\0': /* % is last character - prevent bug */
               t--;
               break;
            }
         } else {
            ast_str_append(&prompt, 0, "%c", *t);
         }
         t++;
      }
      if (color_used) {
         /* Force colors back to normal at end */
         ast_str_append(&prompt, 0, "%s", term_color_code(term_code, 0, 0, sizeof(term_code)));
      }
   } else if (remotehostname) {
      ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname);
   } else {
      ast_str_set(&prompt, 0, "%s", ASTERISK_PROMPT);
   }

   return ast_str_buffer(prompt);   
}
static void console_verboser ( const char *  s) [static]

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

{
   char tmp[80];
   const char *c = NULL;

   if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
       (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
       (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
       (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
      fputs(tmp, stdout);
      fputs(c, stdout);
   } else {
      if (*s == 127) {
         s++;
      }
      fputs(s, stdout);
   }

   fflush(stdout);
   
   /* Wake up a poll()ing console */
   if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
      pthread_kill(consolethread, SIGURG);
}
static void consolehandler ( char *  s) [static]

Definition at line 1774 of file asterisk.c.

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

Referenced by main().

{
   printf("%s", term_end());
   fflush(stdout);

   /* Called when readline data is available */
   if (!ast_all_zeros(s))
      ast_el_add_history(s);
   /* The real handler for bang */
   if (s[0] == '!') {
      if (s[1])
         ast_safe_system(s+1);
      else
         ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
   } else 
      ast_cli_command(STDOUT_FILENO, s);
}
static int fdprint ( int  fd,
const char *  s 
) [static]

Definition at line 965 of file asterisk.c.

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

{
   return write(fd, s, strlen(s));
}
static int fdsend ( int  fd,
const char *  s 
) [static]

Definition at line 959 of file asterisk.c.

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

{
   return write(fd, s, strlen(s) + 1);
}
static const char* fix_header ( char *  outbuf,
int  maxout,
const char *  s,
char *  cmp 
) [static]

Definition at line 1722 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

{
   const char *c;

   /* Check for verboser preamble */
   if (*s == 127) {
      s++;
   }

   if (!strncmp(s, cmp, strlen(cmp))) {
      c = s + strlen(cmp);
      term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
      return c;
   }
   return NULL;
}
static char* handle_abort_shutdown ( 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_cancel_shutdown(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, shuttingdown, and ast_cli_entry::usage.

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "core abort shutdown";
      e->usage = 
         "Usage: core abort shutdown\n"
         "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
         "       call operations.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc != e->args)
      return CLI_SHOWUSAGE;
   ast_cancel_shutdown();
   shuttingdown = 0;
   return CLI_SUCCESS;
}
static char* handle_bang ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1987 of file asterisk.c.

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

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "!";
      e->usage = 
         "Usage: !<command>\n"
         "       Executes a given shell command\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

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

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

{
   int i, min, max;
   char *search = NULL;
   switch (cmd) {
   case CLI_INIT:
      e->command = "core clear profile";
      e->usage = "Usage: core clear profile\n"
            "       clear profile information";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (prof_data == NULL)
      return 0;

   DEFINE_PROFILE_MIN_MAX_VALUES;
   for (i= min; i < max; i++) {
      if (!search || strstr(prof_data->e[i].name, search)) {
         prof_data->e[i].value = 0;
         prof_data->e[i].events = 0;
      }
   }
   return CLI_SUCCESS;
}
static char* handle_restart_gracefully ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1926 of file asterisk.c.

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

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "core restart gracefully";
      e->usage = 
         "Usage: core restart gracefully\n"
         "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
         "       restart when all active calls have ended.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc != e->args)
      return CLI_SHOWUSAGE;
   quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
   return CLI_SUCCESS;
}
static char* handle_restart_now ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1906 of file asterisk.c.

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

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "core restart now";
      e->usage = 
         "Usage: core restart now\n"
         "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
         "       restart.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc != e->args)
      return CLI_SHOWUSAGE;
   quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */);
   return CLI_SUCCESS;
}
static char* handle_restart_when_convenient ( 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, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, quit_handler(), and ast_cli_entry::usage.

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "core restart when convenient";
      e->usage = 
         "Usage: core restart when convenient\n"
         "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc != e->args)
      return CLI_SHOWUSAGE;
   ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
   quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */);
   return CLI_SUCCESS;
}
static char* handle_show_profile ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

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

{
   int i, min, max;
   char *search = NULL;
   switch (cmd) {
   case CLI_INIT:
      e->command = "core show profile";
      e->usage = "Usage: core show profile\n"
            "       show profile information";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (prof_data == NULL)
      return 0;

   DEFINE_PROFILE_MIN_MAX_VALUES;
   ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
      prof_data->entries, prof_data->max_size);
   ast_cli(a->fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
         "Value", "Average", "Name");
   for (i = min; i < max; i++) {
      struct profile_entry *entry = &prof_data->e[i];
      if (!search || strstr(entry->name, search))
          ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
         i,
         (long)entry->scale,
         (long)entry->events, (long long)entry->value,
         (long long)(entry->events ? entry->value / entry->events : entry->value),
         entry->name);
   }
   return CLI_SUCCESS;
}
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 416 of file asterisk.c.

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

{
   char buf[BUFSIZ];
   struct ast_tm tm;
   char eid_str[128];

   switch (cmd) {
   case CLI_INIT:
      e->command = "core show settings";
      e->usage = "Usage: core show settings\n"
            "       Show core misc settings";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);

   ast_cli(a->fd, "\nPBX Core settings\n");
   ast_cli(a->fd, "-----------------\n");
   ast_cli(a->fd, "  Version:                     %s\n", ast_get_version());
   ast_cli(a->fd, "  Build Options:               %s\n", S_OR(AST_BUILDOPTS, "(none)"));
   if (option_maxcalls)
      ast_cli(a->fd, "  Maximum calls:               %d (Current %d)\n", option_maxcalls, ast_active_channels());
   else
      ast_cli(a->fd, "  Maximum calls:               Not set\n");
   if (option_maxfiles)
      ast_cli(a->fd, "  Maximum open file handles:   %d\n", option_maxfiles); 
   else
      ast_cli(a->fd, "  Maximum open file handles:   Not set\n");
   ast_cli(a->fd, "  Verbosity:                   %d\n", option_verbose);
   ast_cli(a->fd, "  Debug level:                 %d\n", option_debug);
   ast_cli(a->fd, "  Maximum load average:        %lf\n", option_maxload);
#if defined(HAVE_SYSINFO)
   ast_cli(a->fd, "  Minimum free memory:         %ld MB\n", option_minmemfree);
#endif
   if (ast_localtime(&ast_startuptime, &tm, NULL)) {
      ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
      ast_cli(a->fd, "  Startup time:                %s\n", buf);
   }
   if (ast_localtime(&ast_lastreloadtime, &tm, NULL)) {
      ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
      ast_cli(a->fd, "  Last reload time:            %s\n", buf);
   }
   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);
   ast_cli(a->fd, "  System name:                 %s\n", ast_config_AST_SYSTEM_NAME);
   ast_cli(a->fd, "  Entity ID:                   %s\n", eid_str);
   ast_cli(a->fd, "  Default language:            %s\n", defaultlanguage);
   ast_cli(a->fd, "  Language prefix:             %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
   ast_cli(a->fd, "  User name and group:         %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
   ast_cli(a->fd, "  Executable includes:         %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
   ast_cli(a->fd, "  Transcode via SLIN:          %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
   ast_cli(a->fd, "  Internal timing:             %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled");
   ast_cli(a->fd, "  Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled");
   ast_cli(a->fd, "  Generic PLC:                 %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");

   ast_cli(a->fd, "\n* Subsystems\n");
   ast_cli(a->fd, "  -------------\n");
   ast_cli(a->fd, "  Manager (AMI):               %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
   ast_cli(a->fd, "  Web Manager (AMI/HTTP):      %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled");
   ast_cli(a->fd, "  Send Manager FullyBooted:    %s\n", ast_opt_send_fullybooted ? "Enabled" : "Disabled");
   ast_cli(a->fd, "  Call data records:           %s\n", check_cdr_enabled() ? "Enabled" : "Disabled");
   ast_cli(a->fd, "  Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");

   /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues  */

   ast_cli(a->fd, "\n* Directories\n");
   ast_cli(a->fd, "  -------------\n");
   ast_cli(a->fd, "  Configuration file:          %s\n", ast_config_AST_CONFIG_FILE);
   ast_cli(a->fd, "  Configuration directory:     %s\n", ast_config_AST_CONFIG_DIR);
   ast_cli(a->fd, "  Module directory:            %s\n", ast_config_AST_MODULE_DIR);
   ast_cli(a->fd, "  Spool directory:             %s\n", ast_config_AST_SPOOL_DIR);
   ast_cli(a->fd, "  Log directory:               %s\n", ast_config_AST_LOG_DIR);
   ast_cli(a->fd, "\n\n");
   return CLI_SUCCESS;
}
static char* handle_show_threads ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

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

{
   int count = 0;
   struct thread_list_t *cur;
   switch (cmd) {
   case CLI_INIT:
      e->command = "core show threads";
      e->usage = 
         "Usage: core show threads\n"
         "       List threads currently active in the system.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   AST_RWLIST_RDLOCK(&thread_list);
   AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
      ast_cli(a->fd, "%p %s\n", (void *)cur->id, cur->name);
      count++;
   }
        AST_RWLIST_UNLOCK(&thread_list);
   ast_cli(a->fd, "%d threads listed.\n", count);
   return CLI_SUCCESS;
}
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 840 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, FORMAT, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

{
#define FORMAT "%-25.25s %-40.40s\n"
   struct file_version *iterator;
   regex_t regexbuf;
   int havepattern = 0;
   int havename = 0;
   int count_files = 0;
   char *ret = NULL;
   int matchlen, which = 0;
   struct file_version *find;

   switch (cmd) {
   case CLI_INIT:
      e->command = "core show file version [like]";
      e->usage = 
         "Usage: core show file version [like <pattern>]\n"
         "       Lists the revision numbers of the files used to build this copy of Asterisk.\n"
         "       Optional regular expression pattern is used to filter the file list.\n";
      return NULL;
   case CLI_GENERATE:
      matchlen = strlen(a->word);
      if (a->pos != 3)
         return NULL;
      AST_RWLIST_RDLOCK(&file_versions);
      AST_RWLIST_TRAVERSE(&file_versions, find, list) {
         if (!strncasecmp(a->word, find->file, matchlen) && ++which > a->n) {
            ret = ast_strdup(find->file);
            break;
         }
      }
      AST_RWLIST_UNLOCK(&file_versions);
      return ret;
   }


   switch (a->argc) {
   case 6:
      if (!strcasecmp(a->argv[4], "like")) {
         if (regcomp(&regexbuf, a->argv[5], REG_EXTENDED | REG_NOSUB))
            return CLI_SHOWUSAGE;
         havepattern = 1;
      } else
         return CLI_SHOWUSAGE;
      break;
   case 5:
      havename = 1;
      break;
   case 4:
      break;
   default:
      return CLI_SHOWUSAGE;
   }

   ast_cli(a->fd, FORMAT, "File", "Revision");
   ast_cli(a->fd, FORMAT, "----", "--------");
   AST_RWLIST_RDLOCK(&file_versions);
   AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
      if (havename && strcasecmp(iterator->file, a->argv[4]))
         continue;

      if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
         continue;

      ast_cli(a->fd, FORMAT, iterator->file, iterator->version);
      count_files++;
      if (havename)
         break;
   }
   AST_RWLIST_UNLOCK(&file_versions);
   if (!havename) {
      ast_cli(a->fd, "%d files listed.\n", count_files);
   }

   if (havepattern)
      regfree(&regexbuf);

   return CLI_SUCCESS;
#undef FORMAT
}
static char* handle_stop_gracefully ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1866 of file asterisk.c.

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

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "core stop gracefully";
      e->usage = 
         "Usage: core stop gracefully\n"
         "       Causes Asterisk to not accept new calls, and exit when all\n"
         "       active calls have terminated normally.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc != e->args)
      return CLI_SHOWUSAGE;
   quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
   return CLI_SUCCESS;
}
static char* handle_stop_now ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1847 of file asterisk.c.

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

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "core stop now";
      e->usage = 
         "Usage: core stop now\n"
         "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc != e->args)
      return CLI_SHOWUSAGE;
   quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */);
   return CLI_SUCCESS;
}
static char* handle_stop_when_convenient ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1886 of file asterisk.c.

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

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "core stop when convenient";
      e->usage = 
         "Usage: core stop when convenient\n"
         "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc != e->args)
      return CLI_SHOWUSAGE;
   ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
   quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
   return CLI_SUCCESS;
}
static char* handle_version ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

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

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "core show version";
      e->usage = 
         "Usage: core show version\n"
         "       Shows Asterisk version information.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc != 3)
      return CLI_SHOWUSAGE;
   ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
      ast_get_version(), ast_build_user, ast_build_hostname,
      ast_build_machine, ast_build_os, ast_build_date);
   return CLI_SUCCESS;
}
static void* listener ( void *  unused) [static]

Definition at line 1281 of file asterisk.c.

References AF_LOCAL, ast_log(), AST_MAX_CONNECTS, ast_opt_hide_connect, ast_poll, ast_pthread_create_detached_background, ast_socket, ast_verb, consoles, errno, console::fd, fdprint(), console::gid, len(), LOG_ERROR, LOG_WARNING, console::mute, netconsole(), s, and console::uid.

Referenced by ast_makesocket().

{
   struct sockaddr_un sunaddr;
   int s;
   socklen_t len;
   int x;
   int flags;
   struct pollfd fds[1];
   for (;;) {
      if (ast_socket < 0)
         return NULL;
      fds[0].fd = ast_socket;
      fds[0].events = POLLIN;
      s = ast_poll(fds, 1, -1);
      pthread_testcancel();
      if (s < 0) {
         if (errno != EINTR)
            ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
         continue;
      }
      len = sizeof(sunaddr);
      s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
      if (s < 0) {
         if (errno != EINTR)
            ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
      } else {
#if !defined(SO_PASSCRED)
         {
#else
         int sckopt = 1;
         /* turn on socket credentials passing. */
         if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
            ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
         } else {
#endif
            for (x = 0; x < AST_MAX_CONNECTS; x++) {
               if (consoles[x].fd >= 0) {
                  continue;
               }
               if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
                  ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
                  consoles[x].fd = -1;
                  fdprint(s, "Server failed to create pipe\n");
                  close(s);
                  break;
               }
               flags = fcntl(consoles[x].p[1], F_GETFL);
               fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
               consoles[x].fd = s;
               consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
               /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
                  to know if the user didn't send the credentials. */
               consoles[x].uid = -2;
               consoles[x].gid = -2;
               if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
                  ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
                  close(consoles[x].p[0]);
                  close(consoles[x].p[1]);
                  consoles[x].fd = -1;
                  fdprint(s, "Server failed to spawn thread\n");
                  close(s);
               }
               break;
            }
            if (x >= AST_MAX_CONNECTS) {
               fdprint(s, "No more connections allowed\n");
               ast_log(LOG_WARNING, "No more connections allowed\n");
               close(s);
            } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
               ast_verb(3, "Remote UNIX connection\n");
            }
         }
      }
   }
   return NULL;
}
int main ( int  argc,
char *  argv[] 
)

Definition at line 3126 of file asterisk.c.

References __ast_mm_init(), __quit_handler(), _argv, ARRAY_LEN, ast_alaw_init(), ast_autoservice_init(), ast_builtins_init(), ast_cdr_engine_init(), ast_channels_init(), ast_clear_flag, ast_cli_perms_init(), ast_cli_register_multiple(), ast_close_fds_above_n(), ast_config_AST_PID, ast_config_AST_RUN_DIR, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SOCKET, ast_copy_string(), ast_device_state_engine_init(), ast_dsp_init(), ast_el_initialize(), ast_el_read_history(), ast_enum_init(), ast_event_init(), ast_fd_init(), ast_FD_SETSIZE, ast_features_init(), ast_file_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_language_is_prefix, ast_lastreloadtime, ast_log(), ast_makesocket(), ast_opt_always_fork, ast_opt_console, ast_opt_dump_core, ast_opt_exec, AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC, AST_OPT_FLAG_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_opt_send_fullybooted, ast_pbx_init(), ast_process_pending_reloads(), ast_pthread_create_detached, ast_readconfig(), ast_register_atexit(), ast_register_verbose(), ast_remotecontrol(), ast_rtp_init(), ast_select(), ast_set_flag, ast_set_priority(), ast_ssl_init(), ast_startuptime, ast_strdupa, ast_strlen_zero(), ast_term_init(), ast_test_flag, ast_test_init(), ast_timing_init(), ast_tps_init(), ast_tryconnect(), ast_tvnow(), ast_udptl_init(), ast_ulaw_init(), ast_utils_init(), ast_verbose(), ast_xmldoc_load_documentation(), astdb_init(), astobj2_init(), buf, callerid_init(), canary_exit(), canary_filename, canary_pid, canary_thread(), cfg_paths, COLOR_BLACK, COLOR_BRWHITE, _cfg_paths::config_file, console_verboser(), consolehandler(), consolethread, dir, dnsmgr_init(), dnsmgr_start_refresh(), el, el_hist, errno, EVENT_FLAG_SYSTEM, f, F_OK, 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(), num, quit_handler(), R_OK, randompool, read_config_maps(), register_config_cli(), run_startup_commands(), set_icon(), set_title(), show_cli_help(), show_version(), sig_alert_pipe, _cfg_paths::socket_path, tdd_init(), term_color(), term_end(), term_quit(), threadstorage_init(), and WELCOME_MESSAGE.

{
   int c;
   char filename[80] = "";
   char hostname[MAXHOSTNAMELEN] = "";
   char tmp[80];
   char * xarg = NULL;
   int x;
   FILE *f;
   sigset_t sigs;
   int num;
   int isroot = 1, rundir_exists = 0;
   char *buf;
   const char *runuser = NULL, *rungroup = NULL;
   char *remotesock = NULL;
   struct rlimit l;

   /* Remember original args for restart */
   if (argc > ARRAY_LEN(_argv) - 1) {
      fprintf(stderr, "Truncating argument size to %d\n", (int)ARRAY_LEN(_argv) - 1);
      argc = ARRAY_LEN(_argv) - 1;
   }
   for (x = 0; x < argc; x++)
      _argv[x] = argv[x];
   _argv[x] = NULL;

   if (geteuid() != 0)
      isroot = 0;

   /* if the progname is rasterisk consider it a remote console */
   if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
      ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
   }
   if (gethostname(hostname, sizeof(hostname)-1))
      ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
   ast_mainpid = getpid();
   ast_ulaw_init();
   ast_alaw_init();
   callerid_init();
   ast_builtins_init();
   ast_utils_init();
   tdd_init();
   ast_tps_init();
   ast_fd_init();
   ast_pbx_init();

   if (getenv("HOME")) 
      snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
   /* Check for options */
   while ((c = getopt(argc, argv, "mtThfFdvVqprRgciInx:U:G:C:L:M:e:s:WB")) != -1) {
      switch (c) {
#if defined(HAVE_SYSINFO)
      case 'e':
         if ((sscanf(&optarg[1], "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
            option_minmemfree = 0;
         }
         break;
#endif
#if HAVE_WORKING_FORK
      case 'F':
         ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
         break;
      case 'f':
         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
         break;
#endif
      case 'd':
         option_debug++;
         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
         break;
      case 'c':
         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
         break;
      case 'n':
         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
         break;
      case 'r':
         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
         break;
      case 'R':
         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
         break;
      case 'p':
         ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
         break;
      case 'v':
         option_verbose++;
         ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
         break;
      case 'm':
         ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
         break;
      case 'M':
         if ((sscanf(optarg, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0))
            option_maxcalls = 0;
         break;
      case 'L':
         if ((sscanf(optarg, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0))
            option_maxload = 0.0;
         break;
      case 'q':
         ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
         break;
      case 't':
         ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
         break;
      case 'T':
         ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
         break;
      case 'x':
         ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC | AST_OPT_FLAG_NO_COLOR);
         xarg = ast_strdupa(optarg);
         break;
      case 'C':
         ast_copy_string(cfg_paths.config_file, optarg, sizeof(cfg_paths.config_file));
         ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
         break;
      case 'I':
         ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING);
         break;
      case 'i':
         ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
         break;
      case 'g':
         ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
         break;
      case 'h':
         show_cli_help();
         exit(0);
      case 'V':
         show_version();
         exit(0);
      case 'U':
         runuser = ast_strdupa(optarg);
         break;
      case 'G':
         rungroup = ast_strdupa(optarg);
         break;
      case 's':
         remotesock = ast_strdupa(optarg);
         break;
      case 'W': /* White background */
         ast_set_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
         ast_clear_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
         break;
      case 'B': /* Force black background */
         ast_set_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
         ast_clear_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
         break;
      case '?':
         exit(1);
      }
   }

   if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
      if (ast_register_verbose(console_verboser)) {
         ast_log(LOG_WARNING, "Unable to register console verboser?\n");
      }
      WELCOME_MESSAGE;
   }

   if (ast_opt_console && !option_verbose) 
      ast_verbose("[ Booting...\n");

   /* For remote connections, change the name of the remote connection.
    * We do this for the benefit of init scripts (which need to know if/when
    * the main asterisk process has died yet). */
   if (ast_opt_remote) {
      strcpy(argv[0], "rasterisk");
      for (x = 1; x < argc; x++) {
         argv[x] = argv[0] + 10;
      }
   }

   if (ast_opt_console && !option_verbose) {
      ast_verbose("[ Reading Master Configuration ]\n");
   }

   ast_readconfig();

   if (ast_opt_remote && remotesock != NULL)
      ast_copy_string((char *) cfg_paths.socket_path, remotesock, sizeof(cfg_paths.socket_path));

   if (!ast_language_is_prefix && !ast_opt_remote)
      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");

   if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
      ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
      ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
   }

   if (ast_opt_dump_core) {
      memset(&l, 0, sizeof(l));
      l.rlim_cur = RLIM_INFINITY;
      l.rlim_max = RLIM_INFINITY;
      if (setrlimit(RLIMIT_CORE, &l)) {
         ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
      }
   }

   if (getrlimit(RLIMIT_NOFILE, &l)) {
      ast_log(LOG_WARNING, "Unable to check file descriptor limit: %s\n", strerror(errno));
   }

#if !defined(CONFIGURE_RAN_AS_ROOT)
   /* Check if select(2) will run with more file descriptors */
   do {
      int fd, fd2;
      ast_fdset readers;
      struct timeval tv = { 0, };

      if (l.rlim_cur <= FD_SETSIZE) {
         /* The limit of select()able FDs is irrelevant, because we'll never
          * open one that high. */
         break;
      }

      if (!(fd = open("/dev/null", O_RDONLY))) {
         ast_log(LOG_ERROR, "Cannot open a file descriptor at boot? %s\n", strerror(errno));
         break; /* XXX Should we exit() here? XXX */
      }

      fd2 = (l.rlim_cur > sizeof(readers) * 8 ? sizeof(readers) * 8 : l.rlim_cur) - 1;
      if (dup2(fd, fd2) < 0) {
         ast_log(LOG_WARNING, "Cannot open maximum file descriptor %d at boot? %s\n", fd2, strerror(errno));
         break;
      }

      FD_ZERO(&readers);
      FD_SET(fd2, &readers);
      if (ast_select(fd2 + 1, &readers, NULL, NULL, &tv) < 0) {
         ast_log(LOG_WARNING, "Maximum select()able file descriptor is %d\n", FD_SETSIZE);
      }
   } while (0);
#elif defined(HAVE_VARIABLE_FDSET)
   ast_FD_SETSIZE = l.rlim_cur;
#endif /* !defined(CONFIGURE_RAN_AS_ROOT) */

   if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
      rungroup = ast_config_AST_RUN_GROUP;
   if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
      runuser = ast_config_AST_RUN_USER;

   /* Must install this signal handler up here to ensure that if the canary
    * fails to execute that it doesn't kill the Asterisk process.
    */
   sigaction(SIGCHLD, &child_handler, NULL);

   /* It's common on some platforms to clear /var/run at boot.  Create the
    * socket file directory before we drop privileges. */
   if (mkdir(ast_config_AST_RUN_DIR, 0755)) {
      if (errno == EEXIST) {
         rundir_exists = 1;
      } else {
         ast_log(LOG_WARNING, "Unable to create socket file directory.  Remote consoles will not be able to connect! (%s)\n", strerror(x));
      }
   }

#ifndef __CYGWIN__

   if (isroot) {
      ast_set_priority(ast_opt_high_priority);
   }

   if (isroot && rungroup) {
      struct group *gr;
      gr = getgrnam(rungroup);
      if (!gr) {
         ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
         exit(1);
      }
      if (!rundir_exists && chown(ast_config_AST_RUN_DIR, -1, gr->gr_gid)) {
         ast_log(LOG_WARNING, "Unable to chgrp run directory to %d (%s)\n", (int) gr->gr_gid, rungroup);
      }
      if (setgid(gr->gr_gid)) {
         ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
         exit(1);
      }
      if (setgroups(0, NULL)) {
         ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
         exit(1);
      }
      if (option_verbose)
         ast_verbose("Running as group '%s'\n", rungroup);
   }

   if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
#ifdef HAVE_CAP
      int has_cap = 1;
#endif /* HAVE_CAP */
      struct passwd *pw;
      pw = getpwnam(runuser);
      if (!pw) {
         ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
         exit(1);
      }
      if (chown(ast_config_AST_RUN_DIR, pw->pw_uid, -1)) {
         ast_log(LOG_WARNING, "Unable to chown run directory to %d (%s)\n", (int) pw->pw_uid, runuser);
      }
#ifdef HAVE_CAP
      if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
         ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
         has_cap = 0;
      }
#endif /* HAVE_CAP */
      if (!isroot && pw->pw_uid != geteuid()) {
         ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
         exit(1);
      }
      if (!rungroup) {
         if (setgid(pw->pw_gid)) {
            ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
            exit(1);
         }
         if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
            ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser);
            exit(1);
         }
      }
      if (setuid(pw->pw_uid)) {
         ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
         exit(1);
      }
      if (option_verbose)
         ast_verbose("Running as user '%s'\n", runuser);
#ifdef HAVE_CAP
      if (has_cap) {
         cap_t cap;

         cap = cap_from_text("cap_net_admin=eip");

         if (cap_set_proc(cap))
            ast_log(LOG_WARNING, "Unable to install capabilities.\n");

         if (cap_free(cap))
            ast_log(LOG_WARNING, "Unable to drop capabilities.\n");
      }
#endif /* HAVE_CAP */
   }

#endif /* __CYGWIN__ */

#ifdef linux
   if (geteuid() && ast_opt_dump_core) {
      if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
         ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
      }
   }
#endif

   {
#if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
#if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
#define eaccess euidaccess
#endif
      char dir[PATH_MAX];
      if (!getcwd(dir, sizeof(dir)) || eaccess(dir, R_OK | X_OK | F_OK)) {
         ast_log(LOG_ERROR, "Unable to access the running directory (%s).  Changing to '/' for compatibility.\n", strerror(errno));
         /* If we cannot access the CWD, then we couldn't dump core anyway,
          * so chdir("/") won't break anything. */
         if (chdir("/")) {
            /* chdir(/) should never fail, so this ends up being a no-op */
            ast_log(LOG_ERROR, "chdir(\"/\") failed?!! %s\n", strerror(errno));
         }
      } else
#endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */
      if (!ast_opt_no_fork && !ast_opt_dump_core) {
         /* Backgrounding, but no cores, so chdir won't break anything. */
         if (chdir("/")) {
            ast_log(LOG_ERROR, "Unable to chdir(\"/\") ?!! %s\n", strerror(errno));
         }
      }
   }

   ast_term_init();
   printf("%s", term_end());
   fflush(stdout);

   if (ast_opt_console && !option_verbose) 
      ast_verbose("[ Initializing Custom Configuration Options ]\n");
   /* custom config setup */
   register_config_cli();
   read_config_maps();
   
   if (ast_opt_console) {
      if (el_hist == NULL || el == NULL)
         ast_el_initialize();

      if (!ast_strlen_zero(filename))
         ast_el_read_history(filename);
   }

   if (ast_tryconnect()) {
      /* One is already running */
      if (ast_opt_remote) {
         if (ast_opt_exec) {
            ast_remotecontrol(xarg);
            quit_handler(0, 0, 0, 0);
            exit(0);
         }
         printf("%s", term_quit());
         ast_remotecontrol(NULL);
         quit_handler(0, 0, 0, 0);
         exit(0);
      } else {
         ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
         printf("%s", term_quit());
         exit(1);
      }
   } else if (ast_opt_remote || ast_opt_exec) {
      ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
      printf("%s", term_quit());
      exit(1);
   }
   /* Blindly write pid file since we couldn't connect */
   unlink(ast_config_AST_PID);
   f = fopen(ast_config_AST_PID, "w");
   if (f) {
      fprintf(f, "%ld\n", (long)getpid());
      fclose(f);
   } else
      ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));

#if HAVE_WORKING_FORK
   if (ast_opt_always_fork || !ast_opt_no_fork) {
#ifndef HAVE_SBIN_LAUNCHD
      if (daemon(1, 0) < 0) {
         ast_log(LOG_ERROR, "daemon() failed: %s\n", strerror(errno));
      }
      ast_mainpid = getpid();
      /* Blindly re-write pid file since we are forking */
      unlink(ast_config_AST_PID);
      f = fopen(ast_config_AST_PID, "w");
      if (f) {
         fprintf(f, "%ld\n", (long)ast_mainpid);
         fclose(f);
      } else
         ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
#else
      ast_log(LOG_WARNING, "Mac OS X detected.  Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
#endif
   }
#endif

   /* Spawning of astcanary must happen AFTER the call to daemon(3) */
   if (isroot && ast_opt_high_priority) {
      snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);

      /* Don't let the canary child kill Asterisk, if it dies immediately */
      sigaction(SIGPIPE, &ignore_sig_handler, NULL);

      canary_pid = fork();
      if (canary_pid == 0) {
         char canary_binary[128], *lastslash, ppid[12];

         /* Reset signal handler */
         signal(SIGCHLD, SIG_DFL);
         signal(SIGPIPE, SIG_DFL);

         ast_close_fds_above_n(0);
         ast_set_priority(0);
         snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid);

         execlp("astcanary", "astcanary", canary_filename, ppid, (char *)NULL);

         /* If not found, try the same path as used to execute asterisk */
         ast_copy_string(canary_binary, argv[0], sizeof(canary_binary));
         if ((lastslash = strrchr(canary_binary, '/'))) {
            ast_copy_string(lastslash + 1, "astcanary", sizeof(canary_binary) + canary_binary - (lastslash + 1));
            execl(canary_binary, "astcanary", canary_filename, (char *)NULL);
         }

         /* Should never happen */
         _exit(1);
      } else if (canary_pid > 0) {
         pthread_t dont_care;
         ast_pthread_create_detached(&dont_care, NULL, canary_thread, NULL);
      }

      /* Kill the canary when we exit */
      ast_register_atexit(canary_exit);
   }

   if (ast_event_init()) {
      printf("%s", term_quit());
      exit(1);
   }

#ifdef TEST_FRAMEWORK
   if (ast_test_init()) {
      printf("%s", term_quit());
      exit(1);
   }
#endif

   ast_makesocket();
   sigemptyset(&sigs);
   sigaddset(&sigs, SIGHUP);
   sigaddset(&sigs, SIGTERM);
   sigaddset(&sigs, SIGINT);
   sigaddset(&sigs, SIGPIPE);
   sigaddset(&sigs, SIGWINCH);
   pthread_sigmask(SIG_BLOCK, &sigs, NULL);
   sigaction(SIGURG, &urg_handler, NULL);
   signal(SIGINT, __quit_handler);
   signal(SIGTERM, __quit_handler);
   sigaction(SIGHUP, &hup_handler, NULL);
   sigaction(SIGPIPE, &ignore_sig_handler, NULL);

   /* ensure that the random number generators are seeded with a different value every time
      Asterisk is started
   */
   srand((unsigned int) getpid() + (unsigned int) time(NULL));
   initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));

   if (init_logger()) {    /* Start logging subsystem */
      printf("%s", term_quit());
      exit(1);
   }

   threadstorage_init();

   astobj2_init();

   ast_autoservice_init();

   if (ast_timing_init()) {
      printf("%s", term_quit());
      exit(1);
   }

   if (ast_ssl_init()) {
      printf("%s", term_quit());
      exit(1);
   }

#ifdef AST_XML_DOCS
   /* Load XML documentation. */
   ast_xmldoc_load_documentation();
#endif

   if (load_modules(1)) {     /* Load modules, pre-load only */
      printf("%s", term_quit());
      exit(1);
   }

   if (dnsmgr_init()) {    /* Initialize the DNS manager */
      printf("%s", term_quit());
      exit(1);
   }

   ast_http_init();     /* Start the HTTP server, if needed */

   ast_channels_init();

   if (init_manager()) {
      printf("%s", term_quit());
      exit(1);
   }

   if (ast_cdr_engine_init()) {
      printf("%s", term_quit());
      exit(1);
   }

   if (ast_device_state_engine_init()) {
      printf("%s", term_quit());
      exit(1);
   }

   ast_rtp_init();
   ast_dsp_init();
   ast_udptl_init();

   if (ast_image_init()) {
      printf("%s", term_quit());
      exit(1);
   }

   if (ast_file_init()) {
      printf("%s", term_quit());
      exit(1);
   }

   if (load_pbx()) {
      printf("%s", term_quit());
      exit(1);
   }

   if (ast_indications_init()) {
      printf("%s", term_quit());
      exit(1);
   }

   ast_features_init();

   if (init_framer()) {
      printf("%s", term_quit());
      exit(1);
   }

   if (astdb_init()) {
      printf("%s", term_quit());
      exit(1);
   }

   if (ast_enum_init()) {
      printf("%s", term_quit());
      exit(1);
   }

   if (load_modules(0)) {
      printf("%s", term_quit());
      exit(1);
   }

   /* loads the cli_permissoins.conf file needed to implement cli restrictions. */
   ast_cli_perms_init(0);

   dnsmgr_start_refresh();

   /* We might have the option of showing a console, but for now just
      do nothing... */
   if (ast_opt_console && !option_verbose)
      ast_verbose(" ]\n");
   if (option_verbose || ast_opt_console)
      ast_verbose("%s", term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
   if (ast_opt_no_fork)
      consolethread = pthread_self();

   if (pipe(sig_alert_pipe))
      sig_alert_pipe[0] = sig_alert_pipe[1] = -1;

   ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
   if (ast_opt_send_fullybooted) {
      manager_event(EVENT_FLAG_SYSTEM, "FullyBooted", "Status: Fully Booted\r\n");
   }

   ast_process_pending_reloads();

   pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);

#ifdef __AST_DEBUG_MALLOC
   __ast_mm_init();
#endif   

   ast_lastreloadtime = ast_startuptime = ast_tvnow();
   ast_cli_register_multiple(cli_asterisk, ARRAY_LEN(cli_asterisk));

   run_startup_commands();

   if (ast_opt_console) {
      /* Console stuff now... */
      /* Register our quit function */
      char title[256];

      ast_pthread_create_detached(&mon_sig_flags, NULL, monitor_sig_flags, NULL);

      set_icon("Asterisk");
      snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
      set_title(title);

      for (;;) {
         buf = (char *) el_gets(el, &num);

         if (!buf && write(1, "", 1) < 0)
            goto lostterm;

         if (buf) {
            if (buf[strlen(buf)-1] == '\n')
               buf[strlen(buf)-1] = '\0';

            consolehandler((char *)buf);
         } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
               strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) {
            /* Whoa, stdout disappeared from under us... Make /dev/null's */
            int fd;
            fd = open("/dev/null", O_RDWR);
            if (fd > -1) {
               dup2(fd, STDOUT_FILENO);
               dup2(fd, STDIN_FILENO);
            } else
               ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
            break;
         }
      }
   }

   monitor_sig_flags(NULL);

lostterm:
   return 0;
}
static void* monitor_sig_flags ( void *  unused) [static]

Definition at line 3048 of file asterisk.c.

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

Referenced by main().

{
   for (;;) {
      struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
      int a;
      ast_poll(&p, 1, -1);
      if (sig_flags.need_reload) {
         sig_flags.need_reload = 0;
         ast_module_reload(NULL);
      }
      if (sig_flags.need_quit) {
         sig_flags.need_quit = 0;
         quit_handler(0, 0, 1, 0);
      }
      if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
      }
   }

   return NULL;
}
static void* netconsole ( void *  vconsole) [static]

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

{
   struct console *con = vconsole;
   char hostname[MAXHOSTNAMELEN] = "";
   char tmp[512];
   int res;
   struct pollfd fds[2];
   
   if (gethostname(hostname, sizeof(hostname)-1))
      ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
   snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
   fdprint(con->fd, tmp);
   for (;;) {
      fds[0].fd = con->fd;
      fds[0].events = POLLIN;
      fds[0].revents = 0;
      fds[1].fd = con->p[0];
      fds[1].events = POLLIN;
      fds[1].revents = 0;

      res = ast_poll(fds, 2, -1);
      if (res < 0) {
         if (errno != EINTR)
            ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
         continue;
      }
      if (fds[0].revents) {
         res = read_credentials(con->fd, tmp, sizeof(tmp) - 1, con);
         if (res < 1) {
            break;
         }
         tmp[res] = 0;
         if (strncmp(tmp, "cli quit after ", 15) == 0) {
            ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res - 15, tmp + 15);
            break;
         }
         ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res, tmp);
      }
      if (fds[1].revents) {
         res = read_credentials(con->p[0], tmp, sizeof(tmp), con);
         if (res < 1) {
            ast_log(LOG_ERROR, "read returned %d\n", res);
            break;
         }
         res = write(con->fd, tmp, res);
         if (res < 1)
            break;
      }
   }
   if (!ast_opt_hide_connect) {
      ast_verb(3, "Remote UNIX connection disconnected\n");
   }
   close(con->fd);
   close(con->p[0]);
   close(con->p[1]);
   con->fd = -1;
   
   return NULL;
}
static void network_verboser ( const char *  s) [static]

Definition at line 1160 of file asterisk.c.

References __LOG_VERBOSE, and ast_network_puts_mutable().

Referenced by ast_makesocket().

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

Definition at line 1587 of file asterisk.c.

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

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

{
   char filename[80] = "";
   time_t s,e;
   int x;
   /* Try to get as many CDRs as possible submitted to the backend engines (if in batch mode) */
   ast_cdr_engine_term();
   if (safeshutdown) {
      shuttingdown = 1;
      if (!niceness) {
         /* Begin shutdown routine, hanging up active channels */
         ast_begin_shutdown(1);
         if (option_verbose && ast_opt_console)
            ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
         time(&s);
         for (;;) {
            time(&e);
            /* Wait up to 15 seconds for all channels to go away */
            if ((e - s) > 15)
               break;
            if (!ast_active_channels())
               break;
            if (!shuttingdown)
               break;
            /* Sleep 1/10 of a second */
            usleep(100000);
         }
      } else {
         if (niceness < 2)
            ast_begin_shutdown(0);
         if (option_verbose && ast_opt_console)
            ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
         for (;;) {
            if (!ast_active_channels())
               break;
            if (!shuttingdown)
               break;
            sleep(1);
         }
      }

      if (!shuttingdown) {
         if (option_verbose && ast_opt_console)
            ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
         return;
      }

      if (niceness)
         ast_module_shutdown();
   }
   if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
      pthread_t thisthread = pthread_self();
      if (getenv("HOME")) {
         snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
      }
      if (!ast_strlen_zero(filename)) {
         ast_el_write_history(filename);
      }
      if (consolethread == AST_PTHREADT_NULL || consolethread == thisthread || mon_sig_flags == thisthread) {
         /* Only end if we are the consolethread or signal handler, otherwise there's a race with that thread. */
         if (el != NULL) {
            el_end(el);
         }
         if (el_hist != NULL) {
            history_end(el_hist);
         }
      }
   }
   if (option_verbose)
      ast_verbose("Executing last minute cleanups\n");
   ast_run_atexits();
   /* Called on exit */
   if (option_verbose && ast_opt_console)
      ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
   ast_debug(1, "Asterisk ending (%d).\n", num);
   manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
   if (ast_socket > -1) {
      pthread_cancel(lthread);
      close(ast_socket);
      ast_socket = -1;
      unlink(ast_config_AST_SOCKET);
   }
   if (ast_consock > -1)
      close(ast_consock);
   if (!ast_opt_remote)
      unlink(ast_config_AST_PID);
   printf("%s", term_quit());
   if (restart) {
      if (option_verbose || ast_opt_console)
         ast_verbose("Preparing for Asterisk restart...\n");
      /* Mark all FD's for closing on exec */
      for (x=3; x < 32768; x++) {
         fcntl(x, F_SETFD, FD_CLOEXEC);
      }
      if (option_verbose || ast_opt_console)
         ast_verbose("Asterisk is now restarting...\n");
      restartnow = 1;

      /* close logger */
      close_logger();

      /* If there is a consolethread running send it a SIGHUP 
         so it can execvp, otherwise we can do it ourselves */
      if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
         pthread_kill(consolethread, SIGHUP);
         /* Give the signal handler some time to complete */
         sleep(2);
      } else
         execvp(_argv[0], _argv);
   
   } else {
      /* close logger */
      close_logger();
   }
   exit(0);
}
static __inline uint64_t rdtsc ( void  ) [static]

Definition at line 741 of file asterisk.c.

Referenced by ast_mark().

{
   return 0;
}
static int read_credentials ( int  fd,
char *  buffer,
size_t  size,
struct console con 
) [static]

read() function supporting the reception of user credentials.

Parameters:
fdSocket file descriptor.
bufferReceive buffer.
size'buffer' size.
conConsole structure to set received credentials
Return values:
-1on error
thenumber of bytes received on success.

Definition at line 1177 of file asterisk.c.

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

Referenced by netconsole().

{
#if defined(SO_PEERCRED)
   struct ucred cred;
   socklen_t len = sizeof(cred);
#endif
#if defined(HAVE_GETPEEREID)
   uid_t uid;
   gid_t gid;
#else
   int uid, gid;
#endif
   int result;

   result = read(fd, buffer, size);
   if (result < 0) {
      return result;
   }

#if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
   if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
      return result;
   }
#if defined(HAVE_STRUCT_UCRED_UID)
   uid = cred.uid;
   gid = cred.gid;
#else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
   uid = cred.cr_uid;
   gid = cred.cr_gid;
#endif /* defined(HAVE_STRUCT_UCRED_UID) */

#elif defined(HAVE_GETPEEREID)
   if (getpeereid(fd, &uid, &gid)) {
      return result;
   }
#else
   return result;
#endif
   con->uid = uid;
   con->gid = gid;

   return result;
}
static int remoteconsolehandler ( char *  s) [static]

Definition at line 1792 of file asterisk.c.

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

Referenced by ast_remotecontrol().

{
   int ret = 0;

   /* Called when readline data is available */
   if (!ast_all_zeros(s))
      ast_el_add_history(s);
   /* The real handler for bang */
   if (s[0] == '!') {
      if (s[1])
         ast_safe_system(s+1);
      else
         ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
      ret = 1;
   }
   if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
       (s[4] == '\0' || isspace(s[4]))) {
      quit_handler(0, 0, 0, 0);
      ret = 1;
   }

   return ret;
}
static void run_startup_commands ( void  ) [static]

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

{
   int fd;
   struct ast_config *cfg;
   struct ast_flags cfg_flags = { 0 };
   struct ast_variable *v;

   if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
      return;
   if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
      return;
   }

   fd = open("/dev/null", O_RDWR);
   if (fd < 0) {
      ast_config_destroy(cfg);
      return;
   }

   for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
      if (ast_true(v->value))
         ast_cli_command(fd, v->name);
   }

   close(fd);
   ast_config_destroy(cfg);
}
static void set_icon ( char *  text) [static]

Definition at line 1534 of file asterisk.c.

Referenced by main().

{
   if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
      fprintf(stdout, "\033]1;%s\007", text);
}
static void set_title ( char *  text) [static]

Set an X-term or screen title.

Definition at line 1528 of file asterisk.c.

Referenced by main().

{
   if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
      fprintf(stdout, "\033]2;%s\007", text);
}
static void set_ulimit ( int  value) [static]

Set maximum open files.

Definition at line 1505 of file asterisk.c.

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

Referenced by ast_readconfig().

{
   struct rlimit l = {0, 0};
   
   if (value <= 0) {
      ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
      return;
   }
   
   l.rlim_cur = value;
   l.rlim_max = value;
   
   if (setrlimit(RLIMIT_NOFILE, &l)) {
      ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
      return;
   }
   
   ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
   
   return;
}
static int show_cli_help ( void  ) [static]

Definition at line 2775 of file asterisk.c.

References ast_get_version().

Referenced by main().

                               {
   printf("Asterisk %s, Copyright (C) 1999 - 2010, Digium, Inc. and others.\n", ast_get_version());
   printf("Usage: asterisk [OPTIONS]\n");
   printf("Valid Options:\n");
   printf("   -V              Display version number and exit\n");
   printf("   -C <configfile> Use an alternate configuration file\n");
   printf("   -G <group>      Run as a group other than the caller\n");
   printf("   -U <user>       Run as a user other than the caller\n");
   printf("   -c              Provide console CLI\n");
   printf("   -d              Enable extra debugging\n");
#if HAVE_WORKING_FORK
   printf("   -f              Do not fork\n");
   printf("   -F              Always fork\n");
#endif
   printf("   -g              Dump core in case of a crash\n");
   printf("   -h              This help screen\n");
   printf("   -i              Initialize crypto keys at startup\n");
   printf("   -I              Enable internal timing if DAHDI timer is available\n");
   printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
   printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
   printf("   -m              Mute debugging and console output on the console\n");
   printf("   -n              Disable console colorization\n");
   printf("   -p              Run as pseudo-realtime thread\n");
   printf("   -q              Quiet mode (suppress output)\n");
   printf("   -r              Connect to Asterisk on this machine\n");
   printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
   printf("   -s <socket>     Connect to Asterisk via socket <socket> (only valid with -r)\n");
   printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
   printf("                   belong after they are done\n");
   printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
   printf("                   of output to the CLI\n");
   printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
   printf("   -x <cmd>        Execute command <cmd> (only valid with -r)\n");
   printf("   -W              Adjust terminal colors to compensate for a light background\n");
   printf("\n");
   return 0;
}
static char* show_license ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

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

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "core show license";
      e->usage = 
         "Usage: core show license\n"
         "       Shows the license(s) for this copy of Asterisk.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   ast_cli(a->fd, "%s", license_lines);

   return CLI_SUCCESS;
}
static int show_version ( void  ) [static]

Definition at line 2769 of file asterisk.c.

References ast_get_version().

Referenced by main().

{
   printf("Asterisk %s\n", ast_get_version());
   return 0;
}
static char* show_warranty ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

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

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "core show warranty";
      e->usage = 
         "Usage: core show warranty\n"
         "       Shows the warranty (if any) for this copy of Asterisk.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   ast_cli(a->fd, "%s", warranty_lines);

   return CLI_SUCCESS;
}

Variable Documentation

char* _argv[256] [static]

Definition at line 274 of file asterisk.c.

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

const char* ast_config_AST_AGI_DIR = cfg_paths.agi_dir

Definition at line 256 of file asterisk.c.

Referenced by launch_script().

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

Definition at line 270 of file asterisk.c.

Referenced by ast_readconfig().

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

Definition at line 269 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

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

Definition at line 268 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static]

Definition at line 267 of file asterisk.c.

Referenced by ast_makesocket(), and ast_readconfig().

const char* ast_config_AST_DB = cfg_paths.db_path

Definition at line 260 of file asterisk.c.

Referenced by dbinit().

const char* ast_config_AST_KEY_DIR = cfg_paths.key_dir

Definition at line 257 of file asterisk.c.

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

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

Referenced by main(), and quit_handler().

const char* ast_config_AST_RUN_DIR = cfg_paths.run_dir

Definition at line 258 of file asterisk.c.

Referenced by launch_script(), and main().

const char* ast_config_AST_RUN_GROUP = cfg_paths.run_group

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

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

const char* ast_config_AST_SOCKET = cfg_paths.socket_path

Definition at line 262 of file asterisk.c.

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

const char* ast_config_AST_VAR_DIR = cfg_paths.var_dir

Definition at line 253 of file asterisk.c.

Referenced by ael2_semantic_check(), and launch_script().

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

Definition at line 191 of file asterisk.c.

Referenced by ast_el_read_char(), and ast_remotecontrol().

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

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

unsigned int ast_FD_SETSIZE

Definition at line 86 of file poll.c.

pid_t ast_mainpid

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

Referenced by listener().

struct atexits atexits [static]
char canary_filename[128] [static]

Definition at line 280 of file asterisk.c.

Referenced by canary_thread(), and main().

int canary_pid = 0 [static]

Definition at line 279 of file asterisk.c.

Referenced by canary_exit(), and main().

struct _cfg_paths cfg_paths [static]

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

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 2086 of file asterisk.c.

pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 277 of file asterisk.c.

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

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 219 of file asterisk.c.

Referenced by __ast_channel_alloc_ap(), and handle_show_settings().

struct file_versions file_versions [static]
struct sigaction hup_handler [static]
Initial value:
 {
   .sa_handler = _hup_handler,
   .sa_flags = SA_RESTART,
}

Definition at line 1480 of file asterisk.c.

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

Definition at line 981 of file asterisk.c.

Referenced by main().

const char license_lines[] [static]

Definition at line 2045 of file asterisk.c.

pthread_t lthread [static]

Definition at line 1165 of file asterisk.c.

Referenced by ast_makesocket(), and quit_handler().

pthread_t mon_sig_flags [static]

Definition at line 278 of file asterisk.c.

Referenced by main(), and quit_handler().

unsigned int need_quit

Definition at line 287 of file asterisk.c.

unsigned int need_reload

Definition at line 286 of file asterisk.c.

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

Definition at line 976 of file asterisk.c.

Referenced by ast_replace_sigchld().

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

Definition at line 2208 of file asterisk.c.

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

char randompool[256] [static]

Definition at line 282 of file asterisk.c.

Referenced by main().

char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR

Definition at line 188 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 215 of file asterisk.c.

Referenced by ast_remotecontrol(), and cli_prompt().

int restartnow [static]

Definition at line 276 of file asterisk.c.

Referenced by _hup_handler(), and quit_handler().

unsigned int safe_system_level = 0 [static]

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

Definition at line 988 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

ast_mutex_t safe_system_lock = AST_MUTEX_INIT_VALUE [static]

Definition at line 985 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

struct sigaction safe_system_prev_handler [static]

Definition at line 989 of file asterisk.c.

Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().

int shuttingdown [static]

Definition at line 275 of file asterisk.c.

Referenced by handle_abort_shutdown(), and quit_handler().

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

Definition at line 284 of file asterisk.c.

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

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

Definition at line 1460 of file asterisk.c.

const char warranty_lines[] [static]

Definition at line 2002 of file asterisk.c.