Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Data Structures | Macros | Enumerations | Functions | Variables
asterisk.c File Reference

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

#include "asterisk.h"
#include "asterisk/_private.h"
#include <sys/time.h>
#include <fcntl.h>
#include <signal.h>
#include <sched.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <ctype.h>
#include <sys/resource.h>
#include <grp.h>
#include <pwd.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <regex.h>
#include <histedit.h>
#include "asterisk/paths.h"
#include "asterisk/network.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/translate.h"
#include "asterisk/pickup.h"
#include "asterisk/acl.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/app.h"
#include "asterisk/mwi.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/ast_version.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"
#include "asterisk/presencestate.h"
#include "asterisk/module.h"
#include "asterisk/buildinfo.h"
#include "asterisk/xmldoc.h"
#include "asterisk/poll-compat.h"
#include "asterisk/test.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/format.h"
#include "asterisk/aoc.h"
#include "asterisk/uuid.h"
#include "asterisk/sorcery.h"
#include "asterisk/bucket.h"
#include "asterisk/stasis.h"
#include "asterisk/json.h"
#include "asterisk/stasis_endpoints.h"
#include "asterisk/stasis_system.h"
#include "asterisk/security_events.h"
#include "asterisk/endpoints.h"
#include "asterisk/codec.h"
#include "asterisk/format_cache.h"
#include "asterisk/media_cache.h"
#include "asterisk/astdb.h"
#include "asterisk/options.h"
#include "asterisk/utf8.h"
#include "../defaults.h"

Go to the source code of this file.

Data Structures

struct  ast_atexit
 
struct  atexits
 
struct  console
 
struct  console_state_data
 
struct  profile_data
 
struct  profile_entry
 
struct  thread_list
 
struct  thread_list_t
 

Macros

#define AF_LOCAL   AF_UNIX
 
#define AST_MAX_CONNECTS   128
 
#define ASTERISK_PROMPT   "*CLI> "
 
#define CHAR_T_LIBEDIT   wchar_t
 
#define CHAR_TO_LIBEDIT(c)   btowc(c)
 
#define CMD_MATCHESARRAY   "_COMMAND MATCHESARRAY \"%s\" \"%s\""
 
#define COPYRIGHT_TAG   "Copyright (C) 1999 - 2021, Sangoma Technologies Corporation and others."
 
#define DEFINE_PROFILE_MIN_MAX_VALUES
 
#define EL_BUF_SIZE   512
 
#define MAX_HISTORY_COMMAND_LENGTH   256
 
#define NUM_MSGS   64
 
#define PF_LOCAL   PF_UNIX
 
#define SHUTDOWN_TIMEOUT   15 /* Seconds */
 
#define WELCOME_MESSAGE
 Welcome message when starting a CLI interface. More...
 

Enumerations

enum  shutdown_nice_t {
  NOT_SHUTTING_DOWN , SHUTTING_DOWN_FINAL , SHUTTING_DOWN , SHUTDOWN_FAST ,
  SHUTDOWN_NORMAL , SHUTDOWN_NICE , SHUTDOWN_REALLY_NICE
}
 

Functions

static void __ast_unregister_atexit (void(*func)(void))
 
static void __init_console_state (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. More...
 
static void _urg_handler (int num)
 Urgent handler. More...
 
int ast_add_profile (const char *name, uint64_t scale)
 allocates a counter with a given name and scale. More...
 
static int ast_all_zeros (const char *s)
 
static void ast_begin_shutdown (void)
 
int ast_cancel_shutdown (void)
 Cancel an existing shutdown and return to normal operation. More...
 
static void ast_cli_display_match_list (struct ast_vector_string *matches, int max)
 
void ast_console_puts (const char *string)
 write the string to the root console, and all attached network console clients More...
 
void ast_console_puts_mutable (const char *string, int level)
 log the string to the root console, and all attached network console clients More...
 
void ast_console_puts_mutable_full (const char *message, int level, int sublevel)
 log the string to the console, and all attached console clients More...
 
void ast_console_toggle_loglevel (int fd, int level, int state)
 enable or disable a logging level to a specified console More...
 
void ast_console_toggle_mute (int fd, int silent)
 mute or unmute a console from logging More...
 
static int ast_el_add_history (const char *)
 
static int ast_el_initialize (void)
 
static int ast_el_read_char (EditLine *editline, CHAR_T_LIBEDIT *cp)
 
static void ast_el_read_default_histfile (void)
 
static int ast_el_read_history (const char *)
 
static struct ast_vector_stringast_el_strtoarr (char *buf)
 
static void ast_el_write_default_histfile (void)
 
static int ast_el_write_history (const char *)
 
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 More...
 
static void ast_network_puts_mutable (const char *string, int level, int sublevel)
 log the string to all attached network console clients More...
 
int ast_pbx_uuid_get (char *pbx_uuid, int length)
 Retrieve the PBX UUID. More...
 
int64_t ast_profile (int i, int64_t delta)
 
int ast_register_atexit (void(*func)(void))
 Register a function to be executed before Asterisk exits. More...
 
int ast_register_cleanup (void(*func)(void))
 Register a function to be executed before Asterisk gracefully exits. More...
 
void ast_register_thread (char *name)
 
static void ast_remotecontrol (char *data)
 
void ast_replace_sigchld (void)
 Replace the SIGCHLD handler. More...
 
static void ast_run_atexits (int run_cleanups)
 
int ast_safe_execvp (int dualfork, const char *file, char *const argv[])
 Safely spawn an external program while closing file descriptors. More...
 
int ast_safe_system (const char *s)
 Safely spawn an OS shell command while closing file descriptors. More...
 
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. More...
 
int ast_shutdown_final (void)
 
int ast_shutting_down (void)
 
static int ast_tryconnect (void)
 
void ast_unregister_atexit (void(*func)(void))
 Unregister a function registered with ast_register_atexit(). More...
 
void ast_unregister_thread (void *id)
 
void ast_unreplace_sigchld (void)
 Restore the SIGCHLD handler. More...
 
static void asterisk_daemon (int isroot, const char *runuser, const char *rungroup)
 
static int can_safely_quit (shutdown_nice_t niceness, int restart)
 
static void canary_exit (void)
 
static void * canary_thread (void *unused)
 
static void check_init (int init_result, const char *name)
 
static char * cli_complete (EditLine *editline, int ch)
 
static char * cli_prompt (EditLine *editline)
 
static int console_print (const char *s)
 
static int console_state_init (void *ptr)
 
static void consolehandler (const char *s)
 
static void env_init (void)
 
static int fdprint (int fd, const char *s)
 
static int fdsend (int fd, const char *s)
 
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. More...
 
static char * handle_show_sysinfo (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Give an overview of system statistics. More...
 
static char * handle_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
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 int has_priority (void)
 Check whether we were set to high(er) priority. More...
 
static void * listener (void *unused)
 
int main (int argc, char *argv[])
 
static void main_atexit (void)
 
static void * monitor_sig_flags (void *unused)
 
static void * netconsole (void *vconsole)
 
static int print_file (int fd, char *desc, const char *filename)
 Print the contents of a file. More...
 
static void print_intro_message (const char *runuser, const char *rungroup)
 
static void publish_fully_booted (void)
 
static void quit_handler (int num, shutdown_nice_t niceness, int restart)
 
static __inline uint64_t rdtsc (void)
 
static int read_credentials (int fd, char *buffer, size_t size, struct console *con)
 read() function supporting the reception of user credentials. More...
 
static void read_pjproject_startup_options (void)
 
static void really_quit (int num, shutdown_nice_t niceness, int restart)
 
static int register_atexit (void(*func)(void), int is_cleanup)
 
static int remoteconsolehandler (const char *s)
 
static void run_startup_commands (void)
 
static pid_t safe_exec_prep (int dualfork)
 fork and perform other preparations for spawning applications More...
 
static int safe_exec_wait (pid_t pid)
 wait for spawned application to complete and unreplace sigchld More...
 
static void send_rasterisk_connect_commands (void)
 
static void set_header (char *outbuf, int maxout, char level)
 
static void set_icon (char *text)
 
static int set_priority_all (int pri)
 Set priority on all known threads. More...
 
static void set_title (char *text)
 Set an X-term or screen title. More...
 
static int show_cli_help (void)
 
static char * show_license (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int show_version (void)
 
static char * show_warranty (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int wait_for_channels_to_die (shutdown_nice_t niceness, int seconds)
 

Variables

static char * _argv [256]
 
static int ast_consock = -1
 
struct timeval ast_lastreloadtime
 
pid_t ast_mainpid
 
static int ast_socket = -1
 
static int ast_socket_is_sd = 0
 
struct timeval ast_startuptime
 
static struct atexits atexits = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static char canary_filename [128]
 
static int canary_pid = 0
 
static struct sigaction child_handler
 
static struct ast_cli_entry cli_asterisk []
 
static struct ast_cli_entry cli_asterisk_shutdown []
 Shutdown Asterisk CLI commands. More...
 
static struct ast_threadstorage console_state = { .once = PTHREAD_ONCE_INIT , .key_init = __init_console_state , .custom_init = console_state_init , }
 
struct console consoles [AST_MAX_CONNECTS]
 
static pthread_t consolethread = AST_PTHREADT_NULL
 
static EditLine * el
 
static History * el_hist
 
static struct sigaction hup_handler
 
static struct sigaction ignore_sig_handler
 
static const char license_lines []
 
static pthread_t lthread
 
static pthread_t mon_sig_flags
 
static int multi_thread_safe
 
static struct sigaction null_sig_handler
 
static struct profile_dataprof_data
 
static struct ast_strprompt = NULL
 
static char randompool [256]
 
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. More...
 
static ast_mutex_t safe_system_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static struct sigaction safe_system_prev_handler
 
static int shutdown_pending
 
static shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN
 
static int sig_alert_pipe [2] = { -1, -1 }
 
struct {
   unsigned int   need_el_end:1
 
   unsigned int   need_quit:1
 
   unsigned int   need_quit_handler:1
 
   unsigned int   need_reload:1
 
sig_flags
 
static struct thread_list thread_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
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.

Macro Definition Documentation

◆ AF_LOCAL

#define AF_LOCAL   AF_UNIX

Definition at line 292 of file asterisk.c.

◆ AST_MAX_CONNECTS

#define AST_MAX_CONNECTS   128

Definition at line 296 of file asterisk.c.

◆ ASTERISK_PROMPT

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 2590 of file asterisk.c.

◆ CHAR_T_LIBEDIT

#define CHAR_T_LIBEDIT   wchar_t

Definition at line 2655 of file asterisk.c.

◆ CHAR_TO_LIBEDIT

#define CHAR_TO_LIBEDIT (   c)    btowc(c)

Definition at line 2656 of file asterisk.c.

◆ CMD_MATCHESARRAY

#define CMD_MATCHESARRAY   "_COMMAND MATCHESARRAY \"%s\" \"%s\""

◆ COPYRIGHT_TAG

#define COPYRIGHT_TAG   "Copyright (C) 1999 - 2021, Sangoma Technologies Corporation and others."

Displayed copyright tag

Definition at line 300 of file asterisk.c.

◆ DEFINE_PROFILE_MIN_MAX_VALUES

#define DEFINE_PROFILE_MIN_MAX_VALUES

Definition at line 892 of file asterisk.c.

◆ EL_BUF_SIZE

#define EL_BUF_SIZE   512

◆ MAX_HISTORY_COMMAND_LENGTH

#define MAX_HISTORY_COMMAND_LENGTH   256

Definition at line 3112 of file asterisk.c.

◆ NUM_MSGS

#define NUM_MSGS   64

Definition at line 297 of file asterisk.c.

◆ PF_LOCAL

#define PF_LOCAL   PF_UNIX

Definition at line 293 of file asterisk.c.

◆ SHUTDOWN_TIMEOUT

#define SHUTDOWN_TIMEOUT   15 /* Seconds */

Definition at line 1914 of file asterisk.c.

◆ WELCOME_MESSAGE

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 303 of file asterisk.c.

Enumeration Type Documentation

◆ shutdown_nice_t

Enumerator
NOT_SHUTTING_DOWN 

Normal operation

SHUTTING_DOWN_FINAL 

Committed to shutting down. Final phase

SHUTTING_DOWN 

Committed to shutting down. Initial phase

SHUTDOWN_FAST 

Valid values for quit_handler() niceness below. These shutdown/restart levels can be cancelled.

Remote console exit right now

SHUTDOWN_NORMAL 

core stop/restart now

SHUTDOWN_NICE 

core stop/restart gracefully

SHUTDOWN_REALLY_NICE 

core stop/restart when convenient

Definition at line 356 of file asterisk.c.

356  {
357  /*! Normal operation */
359  /*! Committed to shutting down. Final phase */
361  /*! Committed to shutting down. Initial phase */
363  /*!
364  * Valid values for quit_handler() niceness below.
365  * These shutdown/restart levels can be cancelled.
366  *
367  * Remote console exit right now
368  */
370  /*! core stop/restart now */
372  /*! core stop/restart gracefully */
374  /*! core stop/restart when convenient */
shutdown_nice_t
Definition: asterisk.c:356
@ SHUTDOWN_FAST
Definition: asterisk.c:369
@ SHUTDOWN_NORMAL
Definition: asterisk.c:371
@ SHUTDOWN_NICE
Definition: asterisk.c:373
@ SHUTDOWN_REALLY_NICE
Definition: asterisk.c:375
@ SHUTTING_DOWN
Definition: asterisk.c:362
@ SHUTTING_DOWN_FINAL
Definition: asterisk.c:360
@ NOT_SHUTTING_DOWN
Definition: asterisk.c:358

Function Documentation

◆ __ast_unregister_atexit()

static void __ast_unregister_atexit ( void(*)(void)  func)
static

Definition at line 1015 of file asterisk.c.

1016 {
1017  struct ast_atexit *ae;
1018 
1020  if (ae->func == func) {
1022  ast_free(ae);
1023  break;
1024  }
1025  }
1027 }
#define ast_free(a)
Definition: astmm.h:180
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
struct ast_atexit::@328 list
void(* func)(void)
Definition: asterisk.c:329

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

Referenced by ast_unregister_atexit(), and register_atexit().

◆ __init_console_state()

static void __init_console_state ( void  )
static

Definition at line 2196 of file asterisk.c.

2199 {

◆ __quit_handler()

static void __quit_handler ( int  num)
static

Definition at line 2136 of file asterisk.c.

2137 {
2138  sig_flags.need_quit = 1;
2140  fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
2141  }
2142  /* There is no need to restore the signal handler here, since the app
2143  * is going to exit */
2144 }
ssize_t ast_alertpipe_write(int alert_pipe[2])
Write an event to an alert pipe.
Definition: alertpipe.c:120
static int sig_alert_pipe[2]
Definition: asterisk.c:396
static struct @327 sig_flags
int errno

References ast_alertpipe_write(), errno, sig_alert_pipe, and sig_flags.

Referenced by asterisk_daemon().

◆ __remote_quit_handler()

static void __remote_quit_handler ( int  num)
static

Definition at line 2146 of file asterisk.c.

2147 {
2148  sig_flags.need_quit = 1;
2149 }

References sig_flags.

Referenced by ast_remotecontrol().

◆ _child_handler()

static void _child_handler ( int  sig)
static

Definition at line 1738 of file asterisk.c.

1739 {
1740  /* Must not ever ast_log or ast_verbose within signal handler */
1741  int n, status, save_errno = errno;
1742 
1743  /*
1744  * Reap all dead children -- not just one
1745  */
1746  for (n = 0; waitpid(-1, &status, WNOHANG) > 0; n++)
1747  ;
1748  if (n == 0 && option_debug)
1749  printf("Huh? Child handler, but nobody there?\n");
1750  errno = save_errno;
1751 }
jack_status_t status
Definition: app_jack.c:146
int option_debug
Definition: options.c:69

References errno, option_debug, and status.

◆ _hup_handler()

static void _hup_handler ( int  num)
static

Definition at line 1714 of file asterisk.c.

1715 {
1716  int save_errno = errno;
1717 
1718  if (restartnow) {
1719  if (el) {
1720  el_end(el);
1721  }
1722  execvp(_argv[0], _argv);
1723  }
1724 
1725  printf("Received HUP signal -- Reloading configs\n");
1726  sig_flags.need_reload = 1;
1728  fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
1729  }
1730  errno = save_errno;
1731 }
static EditLine * el
Definition: asterisk.c:340
static int restartnow
Definition: asterisk.c:383
static char * _argv[256]
Definition: asterisk.c:354

References _argv, ast_alertpipe_write(), el, errno, restartnow, sig_alert_pipe, and sig_flags.

◆ _null_sig_handler()

static void _null_sig_handler ( int  sig)
static

NULL handler so we can collect the child exit status.

Definition at line 1078 of file asterisk.c.

1079 {
1080 }

◆ _urg_handler()

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

1706 {
1707  return;
1708 }

◆ ast_add_profile()

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

797 {
798 #if !defined(LOW_MEMORY)
799  int l = sizeof(struct profile_data);
800  int n = 10; /* default entries */
801 
802  if (prof_data == NULL) {
803  prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
804  if (prof_data == NULL)
805  return -1;
806  prof_data->entries = 0;
807  prof_data->max_size = n;
808  }
809  if (prof_data->entries >= prof_data->max_size) {
810  void *p;
811  n = prof_data->max_size + 20;
812  p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
813  if (p == NULL)
814  return -1;
815  prof_data = p;
816  prof_data->max_size = n;
817  }
818  n = prof_data->entries++;
819  prof_data->e[n].name = ast_strdup(name);
820  prof_data->e[n].value = 0;
821  prof_data->e[n].events = 0;
822  prof_data->e[n].mark = 0;
823  prof_data->e[n].scale = scale;
824  return n;
825 #else /* if defined(LOW_MEMORY) */
826  return 0;
827 #endif
828 }
static struct profile_data * prof_data
Definition: asterisk.c:790
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:226
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static const char name[]
Definition: format_mp3.c:68
#define NULL
Definition: resample.c:96
int max_size
Definition: asterisk.c:786
struct profile_entry e[0]
Definition: asterisk.c:787
Definition: asterisk.c:776
int64_t events
Definition: asterisk.c:781
int64_t mark
Definition: asterisk.c:779
const char * name
Definition: asterisk.c:777
int64_t value
Definition: asterisk.c:780
uint64_t scale
Definition: asterisk.c:778

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

◆ ast_all_zeros()

static int ast_all_zeros ( const char *  s)
static

Definition at line 2269 of file asterisk.c.

2270 {
2271  while (*s) {
2272  if (*s > 32)
2273  return 0;
2274  s++;
2275  }
2276  return 1;
2277 }

Referenced by consolehandler(), and remoteconsolehandler().

◆ ast_begin_shutdown()

static void ast_begin_shutdown ( void  )
static

Definition at line 1893 of file asterisk.c.

1894 {
1897  shutdown_pending = 1;
1898  }
1900 }
static shutdown_nice_t shuttingdown
Definition: asterisk.c:378
static int shutdown_pending
Definition: asterisk.c:381
static ast_mutex_t safe_system_lock
Definition: asterisk.c:1091
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define ast_mutex_lock(a)
Definition: lock.h:187

References ast_mutex_lock, ast_mutex_unlock, NOT_SHUTTING_DOWN, safe_system_lock, shutdown_pending, and shuttingdown.

Referenced by can_safely_quit().

◆ ast_cancel_shutdown()

int ast_cancel_shutdown ( void  )

Cancel an existing shutdown and return to normal operation.

Note
Shutdown can be cancelled while the server is waiting for any existing channels to be destroyed before shutdown becomes irreversible.
Returns
non-zero if shutdown cancelled.

Definition at line 1875 of file asterisk.c.

1876 {
1877  int shutdown_aborted = 0;
1878 
1880  if (shuttingdown >= SHUTDOWN_FAST) {
1882  shutdown_pending = 0;
1883  shutdown_aborted = 1;
1884  }
1886  return shutdown_aborted;
1887 }

References ast_mutex_lock, ast_mutex_unlock, NOT_SHUTTING_DOWN, safe_system_lock, SHUTDOWN_FAST, shutdown_pending, and shuttingdown.

Referenced by handle_abort_shutdown().

◆ ast_cli_display_match_list()

static void ast_cli_display_match_list ( struct ast_vector_string matches,
int  max 
)
static

Definition at line 2923 of file asterisk.c.

2924 {
2925  int idx = 1;
2926  /* find out how many entries can be put on one line, with two spaces between strings */
2927  int limit = ast_get_termcols(STDOUT_FILENO) / (max + 2);
2928 
2929  if (limit == 0) {
2930  limit = 1;
2931  }
2932 
2933  for (;;) {
2934  int numoutputline;
2935 
2936  for (numoutputline = 0; numoutputline < limit && idx < AST_VECTOR_SIZE(matches); idx++) {
2937  numoutputline++;
2938  fprintf(stdout, "%-*s ", max, AST_VECTOR_GET(matches, idx));
2939  }
2940 
2941  if (!numoutputline) {
2942  break;
2943  }
2944 
2945  fprintf(stdout, "\n");
2946  }
2947 }
#define max(a, b)
Definition: f2c.h:198
int ast_get_termcols(int fd)
Columns of Terminal.
Definition: io.c:373
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680

References ast_get_termcols(), AST_VECTOR_GET, AST_VECTOR_SIZE, and max.

Referenced by cli_complete().

◆ ast_console_puts()

void ast_console_puts ( const char *  string)

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

Definition at line 1350 of file asterisk.c.

1351 {
1352  /* Send to the root console */
1353  fputs(string, stdout);
1354  fflush(stdout);
1355 
1356  /* Send to any network console clients */
1357  ast_network_puts(string);
1358 }
static void ast_network_puts(const char *string)
write the string to all attached console clients
Definition: asterisk.c:1334

References ast_network_puts().

◆ ast_console_puts_mutable()

void ast_console_puts_mutable ( const char *  string,
int  level 
)

log the string to the root console, and all attached network console clients

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

Definition at line 1310 of file asterisk.c.

1311 {
1312  ast_console_puts_mutable_full(string, level, 0);
1313 }
void ast_console_puts_mutable_full(const char *message, int level, int sublevel)
log the string to the console, and all attached console clients
Definition: asterisk.c:1317

References ast_console_puts_mutable_full().

Referenced by init_logger_chain(), and make_logchannel().

◆ ast_console_puts_mutable_full()

void ast_console_puts_mutable_full ( const char *  message,
int  level,
int  sublevel 
)

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

Since
14.0.0
Parameters
messageThe message to write to the console
sublevelIf the log level supports it, the sub-level of the message
levelThe log level of the message

Definition at line 1317 of file asterisk.c.

1318 {
1319  /* Send to the root console */
1321 
1322  /* Wake up a poll()ing console */
1324  pthread_kill(consolethread, SIGURG);
1325  }
1326 
1327  /* Send to any network console clients */
1328  ast_network_puts_mutable(message, level, sublevel);
1329 }
static void ast_network_puts_mutable(const char *string, int level, int sublevel)
log the string to all attached network console clients
Definition: asterisk.c:1291
static pthread_t consolethread
Definition: asterisk.c:384
static int console_print(const char *s)
Definition: asterisk.c:2198
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_opt_console
Definition: options.h:109

References ast_network_puts_mutable(), ast_opt_console, AST_PTHREADT_NULL, console_print(), and consolethread.

Referenced by ast_console_puts_mutable(), and logger_print_normal().

◆ ast_console_toggle_loglevel()

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

enable or disable a logging level to a specified console

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

Definition at line 1245 of file asterisk.c.

1246 {
1247  int x;
1248 
1249  if (level >= NUMLOGLEVELS) {
1250  level = NUMLOGLEVELS - 1;
1251  }
1252 
1253  for (x = 0;x < AST_MAX_CONNECTS; x++) {
1254  if (fd == consoles[x].fd) {
1255  /*
1256  * Since the logging occurs when levels are false, set to
1257  * flipped iinput because this function accepts 0 as off and 1 as on
1258  */
1259  consoles[x].levels[level] = state ? 0 : 1;
1260  return;
1261  }
1262  }
1263 }
#define AST_MAX_CONNECTS
Definition: asterisk.c:296
struct console consoles[AST_MAX_CONNECTS]
Definition: asterisk.c:343
#define NUMLOGLEVELS
int levels[NUMLOGLEVELS]
Definition: asterisk.c:323

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

Referenced by handle_logger_set_level().

◆ ast_console_toggle_mute()

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 1268 of file asterisk.c.

1269 {
1270  int x;
1271  for (x = 0;x < AST_MAX_CONNECTS; x++) {
1272  if (fd == consoles[x].fd) {
1273  if (consoles[x].mute) {
1274  consoles[x].mute = 0;
1275  if (!silent)
1276  ast_cli(fd, "Console is not muted anymore.\n");
1277  } else {
1278  consoles[x].mute = 1;
1279  if (!silent)
1280  ast_cli(fd, "Console is muted.\n");
1281  }
1282  return;
1283  }
1284  }
1285  ast_cli(fd, "Couldn't find remote console.\n");
1286 }
static int mute
Definition: chan_alsa.c:148
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int mute
Definition: asterisk.c:320

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

Referenced by handle_logger_mute().

◆ ast_el_add_history()

static int ast_el_add_history ( const char *  buf)
static

Definition at line 3114 of file asterisk.c.

3115 {
3116  HistEvent ev;
3117  char *stripped_buf;
3118 
3119  if (el_hist == NULL || el == NULL) {
3121  }
3122  if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1)) {
3123  return 0;
3124  }
3125 
3126  stripped_buf = ast_strip(ast_strdupa(buf));
3127 
3128  /* HISTCONTROL=ignoredups */
3129  if (!history(el_hist, &ev, H_FIRST) && strcmp(ev.str, stripped_buf) == 0) {
3130  return 0;
3131  }
3132 
3133  return history(el_hist, &ev, H_ENTER, stripped_buf);
3134 }
static int ast_el_initialize(void)
Definition: asterisk.c:3059
static History * el_hist
Definition: asterisk.c:339
#define MAX_HISTORY_COMMAND_LENGTH
Definition: asterisk.c:3112
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223

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

Referenced by consolehandler(), and remoteconsolehandler().

◆ ast_el_initialize()

static int ast_el_initialize ( void  )
static

Definition at line 3059 of file asterisk.c.

3060 {
3061  HistEvent ev;
3062  char *editor, *editrc = getenv("EDITRC");
3063 
3064  if (!(editor = getenv("AST_EDITMODE"))) {
3065  if (!(editor = getenv("AST_EDITOR"))) {
3066  editor = "emacs";
3067  }
3068  }
3069 
3070  if (el != NULL)
3071  el_end(el);
3072  if (el_hist != NULL)
3073  history_end(el_hist);
3074 
3075  el = el_init("asterisk", stdin, stdout, stderr);
3076  el_set(el, EL_PROMPT, cli_prompt);
3077 
3078  el_set(el, EL_EDITMODE, 1);
3079  el_set(el, EL_EDITOR, editor);
3080  el_hist = history_init();
3081  if (!el || !el_hist)
3082  return -1;
3083 
3084  /* setup history with 100 entries */
3085  history(el_hist, &ev, H_SETSIZE, 100);
3086 
3087  el_set(el, EL_HIST, history, el_hist);
3088 
3089  el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
3090  /* Bind <tab> to command completion */
3091  el_set(el, EL_BIND, "^I", "ed-complete", NULL);
3092  /* Bind ? to command completion */
3093  el_set(el, EL_BIND, "?", "ed-complete", NULL);
3094  /* Bind ^D to redisplay */
3095  el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
3096  /* Bind Delete to delete char left */
3097  el_set(el, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
3098  /* Bind Home and End to move to line start and end */
3099  el_set(el, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
3100  el_set(el, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
3101  /* Bind C-left and C-right to move by word (not all terminals) */
3102  el_set(el, EL_BIND, "\\eOC", "vi-next-word", NULL);
3103  el_set(el, EL_BIND, "\\eOD", "vi-prev-word", NULL);
3104 
3105  if (editrc) {
3106  el_source(el, editrc);
3107  }
3108 
3109  return 0;
3110 }
static char * cli_complete(EditLine *editline, int ch)
Definition: asterisk.c:2950
static char * cli_prompt(EditLine *editline)
Definition: asterisk.c:2763

References cli_complete(), cli_prompt(), el, el_hist, and NULL.

Referenced by ast_el_add_history(), ast_el_read_history(), ast_el_write_history(), ast_remotecontrol(), and asterisk_daemon().

◆ ast_el_read_char()

static int ast_el_read_char ( EditLine *  editline,
CHAR_T_LIBEDIT cp 
)
static

Definition at line 2662 of file asterisk.c.

2663 {
2664  int num_read = 0;
2665  int lastpos = 0;
2666  struct pollfd fds[2];
2667  int res;
2668  int max;
2669 #define EL_BUF_SIZE 512
2670  char buf[EL_BUF_SIZE];
2671 
2672  for (;;) {
2673  max = 1;
2674  fds[0].fd = ast_consock;
2675  fds[0].events = POLLIN;
2676  if (!ast_opt_exec) {
2677  fds[1].fd = STDIN_FILENO;
2678  fds[1].events = POLLIN;
2679  max++;
2680  }
2681  res = ast_poll(fds, max, -1);
2682  if (res < 0) {
2683  if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
2684  break;
2685  }
2686  if (errno == EINTR) {
2687  continue;
2688  }
2689  fprintf(stderr, "poll failed: %s\n", strerror(errno));
2690  break;
2691  }
2692 
2693  if (!ast_opt_exec && fds[1].revents) {
2694  char c = '\0';
2695 
2696  num_read = read(STDIN_FILENO, &c, 1);
2697  if (num_read < 1) {
2698  break;
2699  }
2700 
2701  *cp = CHAR_TO_LIBEDIT(c);
2702 
2703  return num_read;
2704  }
2705 
2706  if (fds[0].revents) {
2707  res = read(ast_consock, buf, sizeof(buf) - 1);
2708  /* if the remote side disappears exit */
2709  if (res < 1) {
2710  fprintf(stderr, "\nDisconnected from Asterisk server\n");
2711  if (!ast_opt_reconnect) {
2712  quit_handler(0, SHUTDOWN_FAST, 0);
2713  } else {
2714  int tries;
2715  int reconnects_per_second = 20;
2716 
2717  fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
2718  for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
2719  if (ast_tryconnect()) {
2720  fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
2721  printf("%s", term_quit());
2724  break;
2725  }
2726 
2727  usleep(1000000 / reconnects_per_second);
2728  }
2729  if (tries >= 30 * reconnects_per_second) {
2730  fprintf(stderr, "Failed to reconnect for 30 seconds. Quitting.\n");
2731  quit_handler(0, SHUTDOWN_FAST, 0);
2732  }
2733  }
2734  continue;
2735  }
2736 
2737  buf[res] = '\0';
2738 
2739  /* Write over the CLI prompt */
2740  if (!ast_opt_exec && !lastpos) {
2741  if (write(STDOUT_FILENO, "\r␛[0K", 5) < 0) {
2742  }
2743  }
2744 
2745  console_print(buf);
2746 
2747  if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (res >= 2 && buf[res-2] == '\n'))) {
2748  *cp = CHAR_TO_LIBEDIT(CC_REFRESH);
2749 
2750  return 1;
2751  }
2752  lastpos = 1;
2753  }
2754  }
2755 
2756  *cp = CHAR_TO_LIBEDIT('\0');
2757 
2758  return 0;
2759 }
#define WELCOME_MESSAGE
Welcome message when starting a CLI interface.
Definition: asterisk.c:303
static void send_rasterisk_connect_commands(void)
Definition: asterisk.c:2626
#define CHAR_TO_LIBEDIT(c)
Definition: asterisk.c:2656
static void quit_handler(int num, shutdown_nice_t niceness, int restart)
Definition: asterisk.c:1905
#define EL_BUF_SIZE
static int ast_tryconnect(void)
Definition: asterisk.c:1678
static int ast_consock
Definition: asterisk.c:314
#define ast_opt_exec
Definition: options.h:113
#define ast_opt_reconnect
Definition: options.h:123
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
const char * term_quit(void)
Definition: term.c:412
static struct test_val c

References ast_consock, ast_opt_exec, ast_opt_reconnect, ast_poll, ast_tryconnect(), buf, c, CHAR_TO_LIBEDIT, console_print(), EL_BUF_SIZE, errno, max, quit_handler(), send_rasterisk_connect_commands(), SHUTDOWN_FAST, sig_flags, term_quit(), and WELCOME_MESSAGE.

Referenced by ast_remotecontrol(), and asterisk_daemon().

◆ ast_el_read_default_histfile()

static void ast_el_read_default_histfile ( void  )
static

Definition at line 3157 of file asterisk.c.

3158 {
3159  char histfile[80] = "";
3160  const char *home = getenv("HOME");
3161 
3162  if (!ast_strlen_zero(home)) {
3163  snprintf(histfile, sizeof(histfile), "%s/.asterisk_history", home);
3164  ast_el_read_history(histfile);
3165  }
3166 }
static int ast_el_read_history(const char *)
Definition: asterisk.c:3146
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References ast_el_read_history(), and ast_strlen_zero().

Referenced by ast_remotecontrol(), and asterisk_daemon().

◆ ast_el_read_history()

static int ast_el_read_history ( const char *  filename)
static

Definition at line 3146 of file asterisk.c.

3147 {
3148  HistEvent ev;
3149 
3150  if (el_hist == NULL || el == NULL) {
3152  }
3153 
3154  return history(el_hist, &ev, H_LOAD, filename);
3155 }

References ast_el_initialize(), el, el_hist, and NULL.

Referenced by ast_el_read_default_histfile().

◆ ast_el_strtoarr()

static struct ast_vector_string* ast_el_strtoarr ( char *  buf)
static

Definition at line 2889 of file asterisk.c.

2890 {
2891  char *retstr;
2892  struct ast_vector_string *vec = ast_calloc(1, sizeof(*vec));
2893 
2894  if (!vec) {
2895  return NULL;
2896  }
2897 
2898  while ((retstr = strsep(&buf, " "))) {
2899  if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
2900  break;
2901  }
2902 
2903  retstr = ast_strdup(retstr);
2904  if (!retstr || AST_VECTOR_APPEND(vec, retstr)) {
2905  ast_free(retstr);
2906  goto vector_cleanup;
2907  }
2908  }
2909 
2910  if (!AST_VECTOR_SIZE(vec)) {
2911  goto vector_cleanup;
2912  }
2913 
2914  return vec;
2915 
2916 vector_cleanup:
2918  AST_VECTOR_PTR_FREE(vec);
2919 
2920  return NULL;
2921 }
#define AST_CLI_COMPLETE_EOF
Definition: cli.h:52
char * strsep(char **str, const char *delims)
String vector definitions.
Definition: vector.h:55
#define AST_VECTOR_PTR_FREE(vec)
Deallocates this vector pointer.
Definition: vector.h:189
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:862

References ast_calloc, AST_CLI_COMPLETE_EOF, ast_free, ast_strdup, AST_VECTOR_APPEND, AST_VECTOR_CALLBACK_VOID, AST_VECTOR_PTR_FREE, AST_VECTOR_SIZE, buf, NULL, and strsep().

Referenced by cli_complete().

◆ ast_el_write_default_histfile()

static void ast_el_write_default_histfile ( void  )
static

Definition at line 3168 of file asterisk.c.

3169 {
3170  char histfile[80] = "";
3171  const char *home = getenv("HOME");
3172 
3173  if (!ast_strlen_zero(home)) {
3174  snprintf(histfile, sizeof(histfile), "%s/.asterisk_history", home);
3175  ast_el_write_history(histfile);
3176  }
3177 }
static int ast_el_write_history(const char *)
Definition: asterisk.c:3136

References ast_el_write_history(), and ast_strlen_zero().

Referenced by really_quit().

◆ ast_el_write_history()

static int ast_el_write_history ( const char *  filename)
static

Definition at line 3136 of file asterisk.c.

3137 {
3138  HistEvent ev;
3139 
3140  if (el_hist == NULL || el == NULL)
3142 
3143  return (history(el_hist, &ev, H_SAVE, filename));
3144 }

References ast_el_initialize(), el, el_hist, and NULL.

Referenced by ast_el_write_default_histfile().

◆ ast_makesocket()

static int ast_makesocket ( void  )
static

Definition at line 1592 of file asterisk.c.

1593 {
1594  struct sockaddr_un sunaddr;
1595  int res;
1596  int x;
1597  uid_t uid = -1;
1598  gid_t gid = -1;
1599 
1600  for (x = 0; x < AST_MAX_CONNECTS; x++) {
1601  consoles[x].fd = -1;
1602  }
1603 
1604  if (ast_socket_is_sd) {
1606 
1607  goto start_lthread;
1608  }
1609 
1610  unlink(ast_config_AST_SOCKET);
1611  ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
1612  if (ast_socket < 0) {
1613  ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
1614  return -1;
1615  }
1616  memset(&sunaddr, 0, sizeof(sunaddr));
1617  sunaddr.sun_family = AF_LOCAL;
1618  ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
1619  res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
1620  if (res) {
1621  ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1622  close(ast_socket);
1623  ast_socket = -1;
1624  return -1;
1625  }
1626  res = listen(ast_socket, 2);
1627  if (res < 0) {
1628  ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1629  close(ast_socket);
1630  ast_socket = -1;
1631  return -1;
1632  }
1633 
1634 start_lthread:
1636  ast_log(LOG_WARNING, "Unable to create listener thread.\n");
1637  close(ast_socket);
1638  return -1;
1639  }
1640 
1641  if (ast_socket_is_sd) {
1642  /* owner/group/permissions are set by systemd, we might not even have access
1643  * to socket file so leave it alone */
1644  return 0;
1645  }
1646 
1648  struct passwd *pw;
1649  if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
1650  ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
1651  else
1652  uid = pw->pw_uid;
1653  }
1654 
1656  struct group *grp;
1657  if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
1658  ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
1659  else
1660  gid = grp->gr_gid;
1661  }
1662 
1663  if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
1664  ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1665 
1667  unsigned int p1;
1668  mode_t p;
1669  sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
1670  p = p1;
1671  if ((chmod(ast_config_AST_SOCKET, p)) < 0)
1672  ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1673  }
1674 
1675  return 0;
1676 }
static int ast_socket_is_sd
Definition: asterisk.c:313
static pthread_t lthread
Definition: asterisk.c:1360
#define PF_LOCAL
Definition: asterisk.c:293
static void * listener(void *unused)
Definition: asterisk.c:1512
static int ast_socket
Definition: asterisk.c:312
#define AF_LOCAL
Definition: asterisk.c:292
#define ast_log
Definition: astobj2.c:42
#define LOG_WARNING
int ast_sd_get_fd_un(int type, const char *path)
Find a listening AF_LOCAL file descriptor provided by socket activation.
Definition: io.c:454
const char * ast_config_AST_SOCKET
Definition: options.c:167
const char * ast_config_AST_CTL_PERMISSIONS
Definition: options.c:172
const char * ast_config_AST_CTL_GROUP
Definition: options.c:174
const char * ast_config_AST_CTL_OWNER
Definition: options.c:173
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:406
int fd
Definition: asterisk.c:317
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:587

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_sd_get_fd_un(), ast_socket, ast_socket_is_sd, ast_strlen_zero(), consoles, errno, console::fd, listener(), LOG_WARNING, lthread, NULL, and PF_LOCAL.

Referenced by asterisk_daemon().

◆ ast_mark()

int64_t ast_mark ( int  i,
int  startstop 
)

Definition at line 871 of file asterisk.c.

872 {
873 #if !defined(LOW_MEMORY)
874  if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
875  return 0;
876  if (startstop == 1)
877  prof_data->e[i].mark = rdtsc();
878  else {
879  prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
880  if (prof_data->e[i].scale > 1)
881  prof_data->e[i].mark /= prof_data->e[i].scale;
882  prof_data->e[i].value += prof_data->e[i].mark;
883  prof_data->e[i].events++;
884  }
885  return prof_data->e[i].mark;
886 #else /* if defined(LOW_MEMORY) */
887  return 0;
888 #endif
889 }
static __inline uint64_t rdtsc(void)
Definition: asterisk.c:864

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

◆ ast_network_puts()

static void ast_network_puts ( const char *  string)
static

write the string to all attached console clients

Definition at line 1334 of file asterisk.c.

1335 {
1336  int x;
1337 
1338  for (x = 0; x < AST_MAX_CONNECTS; ++x) {
1339  if (consoles[x].fd < 0) {
1340  continue;
1341  }
1342  fdprint(consoles[x].p[1], string);
1343  }
1344 }
static int fdprint(int fd, const char *s)
Definition: asterisk.c:1072

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

◆ ast_network_puts_mutable()

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

log the string to all attached network console clients

Definition at line 1291 of file asterisk.c.

1292 {
1293  int x;
1294 
1295  for (x = 0; x < AST_MAX_CONNECTS; ++x) {
1296  if (consoles[x].fd < 0
1297  || consoles[x].mute
1298  || consoles[x].levels[level]
1299  || (level == __LOG_VERBOSE && consoles[x].option_verbose < sublevel)) {
1300  continue;
1301  }
1302  fdprint(consoles[x].p[1], string);
1303  }
1304 }
int option_verbose
Definition: options.c:67
#define __LOG_VERBOSE
static char * levels[NUMLOGLEVELS]
Logging channels used in the Asterisk logging system.
Definition: logger.c:213

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

Referenced by ast_console_puts_mutable_full().

◆ ast_pbx_uuid_get()

int ast_pbx_uuid_get ( char *  pbx_uuid,
int  length 
)

Retrieve the PBX UUID.

Parameters
pbx_uuidA buffer of at least AST_UUID_STR_LEN (36 + 1) size to receive the UUID
lengthThe buffer length

Definition at line 970 of file asterisk.c.

971 {
972  return ast_db_get("pbx", "UUID", pbx_uuid, length);
973 }
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Definition: main/db.c:412

References ast_db_get().

Referenced by asterisk_daemon(), and handle_show_settings().

◆ ast_profile()

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 830 of file asterisk.c.

831 {
832 #if !defined(LOW_MEMORY)
833  if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
834  return 0;
835  if (prof_data->e[i].scale > 1)
836  delta /= prof_data->e[i].scale;
837  prof_data->e[i].value += delta;
838  prof_data->e[i].events++;
839  return prof_data->e[i].value;
840 #else /* if defined(LOW_MEMORY) */
841  return 0;
842 #endif
843 }

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

◆ ast_register_atexit()

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.
Note
This function should be rarely used in situations where something must be shutdown to avoid corruption, excessive data loss, or when external programs must be stopped. All other cleanup in the core should use ast_register_cleanup.

Definition at line 1048 of file asterisk.c.

1049 {
1050  return register_atexit(func, 0);
1051 }
static int register_atexit(void(*func)(void), int is_cleanup)
Definition: asterisk.c:1029

References ast_atexit::func, and register_atexit().

Referenced by asterisk_daemon().

◆ ast_register_cleanup()

int ast_register_cleanup ( void(*)(void)  func)

Register a function to be executed before Asterisk gracefully exits.

Since
11.9

If Asterisk is immediately shutdown (core stop now, or sending the TERM signal), the callback is not run. When the callbacks are run, they are run in sequence with ast_register_atexit() callbacks, in the reverse order of registration.

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

Definition at line 1053 of file asterisk.c.

1054 {
1055  return register_atexit(func, 1);
1056 }

References ast_atexit::func, and register_atexit().

Referenced by asterisk_daemon().

◆ ast_register_thread()

void ast_register_thread ( char *  name)

Definition at line 414 of file asterisk.c.

415 {
416  struct thread_list_t *new = ast_calloc(1, sizeof(*new));
417 
418  if (!new)
419  return;
420 
422  new->id = pthread_self();
423  new->lwp = ast_get_tid();
424  new->name = name; /* steal the allocated memory for the thread name */
426  AST_RWLIST_INSERT_HEAD(&thread_list, new, list);
428 }
static int multi_thread_safe
Definition: asterisk.c:388
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:718
#define ast_assert(a)
Definition: utils.h:734
int ast_get_tid(void)
Get current thread ID.
Definition: main/utils.c:2650

References ast_assert, ast_calloc, ast_get_tid(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, multi_thread_safe, and name.

Referenced by dummy_start().

◆ ast_remotecontrol()

static void ast_remotecontrol ( char *  data)
static

Definition at line 3179 of file asterisk.c.

3180 {
3181  char buf[256] = "";
3182  int res;
3183  char *hostname;
3184  char *cpid;
3185  char *version;
3186  int pid;
3187  char *stringp = NULL;
3188 
3189  char *ebuf;
3190  int num = 0;
3191 
3192  ast_term_init();
3193  printf("%s", term_end());
3194  fflush(stdout);
3195 
3196  memset(&sig_flags, 0, sizeof(sig_flags));
3197  signal(SIGINT, __remote_quit_handler);
3198  signal(SIGTERM, __remote_quit_handler);
3199  signal(SIGHUP, __remote_quit_handler);
3200 
3201  if (read(ast_consock, buf, sizeof(buf) - 1) < 0) {
3202  ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
3203  return;
3204  }
3205  if (data) {
3206  char prefix[] = "cli quit after ";
3207  char *tmp = ast_alloca(strlen(data) + strlen(prefix) + 1);
3208  sprintf(tmp, "%s%s", prefix, data);
3209  if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
3210  ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
3211  if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
3212  return;
3213  }
3214  }
3215  }
3216  stringp = buf;
3217  hostname = strsep(&stringp, "/");
3218  cpid = strsep(&stringp, "/");
3219  version = strsep(&stringp, "\n");
3220  if (!version)
3221  version = "<Version Unknown>";
3222  stringp = hostname;
3223  strsep(&stringp, ".");
3224  if (cpid)
3225  pid = atoi(cpid);
3226  else
3227  pid = -1;
3228  if (!data) {
3230  }
3231 
3232  if (ast_opt_exec && data) { /* hack to print output then exit if asterisk -rx is used */
3233  int linefull = 1, prev_linefull = 1, prev_line_verbose = 0;
3234  struct pollfd fds;
3235  fds.fd = ast_consock;
3236  fds.events = POLLIN;
3237  fds.revents = 0;
3238 
3239  while (ast_poll(&fds, 1, 60000) > 0) {
3240  char buffer[512] = "", *curline = buffer, *nextline;
3241  int not_written = 1;
3242 
3243  if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
3244  break;
3245  }
3246 
3247  if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
3248  break;
3249  }
3250 
3251  do {
3252  prev_linefull = linefull;
3253  if ((nextline = strchr(curline, '\n'))) {
3254  linefull = 1;
3255  nextline++;
3256  } else {
3257  linefull = 0;
3258  nextline = strchr(curline, '\0');
3259  }
3260 
3261  /* Skip verbose lines */
3262  /* Prev line full? | Line is verbose | Last line verbose? | Print
3263  * TRUE | TRUE* | TRUE | FALSE
3264  * TRUE | TRUE* | FALSE | FALSE
3265  * TRUE | FALSE* | TRUE | TRUE
3266  * TRUE | FALSE* | FALSE | TRUE
3267  * FALSE | TRUE | TRUE* | FALSE
3268  * FALSE | TRUE | FALSE* | TRUE
3269  * FALSE | FALSE | TRUE* | FALSE
3270  * FALSE | FALSE | FALSE* | TRUE
3271  */
3272  if ((!prev_linefull && !prev_line_verbose) || (prev_linefull && *curline > 0)) {
3273  prev_line_verbose = 0;
3274  not_written = 0;
3275  if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
3276  ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
3277  }
3278  } else {
3279  prev_line_verbose = 1;
3280  }
3281  curline = nextline;
3282  } while (!ast_strlen_zero(curline));
3283 
3284  /* No non-verbose output in 60 seconds. */
3285  if (not_written) {
3286  break;
3287  }
3288  }
3289  return;
3290  }
3291 
3292  ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
3294 
3296  if (el_hist == NULL || el == NULL)
3299 
3300  el_set(el, EL_GETCFN, ast_el_read_char);
3301 
3302  for (;;) {
3303  ebuf = (char *)el_gets(el, &num);
3304 
3305  if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
3306  break;
3307  }
3308 
3309  if (!ebuf && write(1, "", 1) < 0)
3310  break;
3311 
3312  if (!ast_strlen_zero(ebuf)) {
3313  if (ebuf[strlen(ebuf)-1] == '\n')
3314  ebuf[strlen(ebuf)-1] = '\0';
3315  if (!remoteconsolehandler(ebuf)) {
3316  res = write(ast_consock, ebuf, strlen(ebuf) + 1);
3317  if (res < 1) {
3318  ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
3319  break;
3320  }
3321  }
3322  }
3323  }
3324  printf("\nDisconnected from Asterisk server\n");
3325 }
int ast_term_init(void)
Definition: term.c:165
static char * remotehostname
Definition: asterisk.c:341
static void __remote_quit_handler(int num)
Definition: asterisk.c:2146
static int remoteconsolehandler(const char *s)
Definition: asterisk.c:2298
static int ast_el_read_char(EditLine *editline, CHAR_T_LIBEDIT *cp)
Definition: asterisk.c:2662
static void ast_el_read_default_histfile(void)
Definition: asterisk.c:3157
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
static int tmp()
Definition: bt_open.c:389
static char version[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:391
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2206
static char prefix[MAX_PREFIX]
Definition: http.c:144
void ast_init_logger_for_socket_console(void)
load logger.conf configuration for console socket connections
Definition: logger.c:700
#define LOG_ERROR
static char hostname[MAXHOSTNAMELEN]
Definition: logger.c:119
const char * term_end(void)
Definition: term.c:407

References __remote_quit_handler(), ast_alloca, ast_consock, ast_el_initialize(), ast_el_read_char(), ast_el_read_default_histfile(), ast_init_logger_for_socket_console(), ast_log, ast_opt_exec, ast_poll, ast_strlen_zero(), ast_term_init(), ast_verbose(), buf, el, el_hist, errno, hostname, LOG_ERROR, LOG_WARNING, NULL, prefix, remoteconsolehandler(), remotehostname, send_rasterisk_connect_commands(), sig_flags, strsep(), term_end(), tmp(), and version.

Referenced by main().

◆ ast_replace_sigchld()

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

1099 {
1100  unsigned int level;
1101 
1103  level = safe_system_level++;
1104 
1105  /* only replace the handler if it has not already been done */
1106  if (level == 0) {
1107  sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
1108  }
1109 
1111 }
static unsigned int safe_system_level
Keep track of how many threads are currently trying to wait*() on a child process.
Definition: asterisk.c:1095
static struct sigaction safe_system_prev_handler
Definition: asterisk.c:1096
static struct sigaction null_sig_handler
Definition: asterisk.c:1082

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

Referenced by safe_exec_prep().

◆ ast_run_atexits()

static void ast_run_atexits ( int  run_cleanups)
static

Definition at line 1001 of file asterisk.c.

1002 {
1003  struct ast_atexit *ae;
1004 
1006  while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
1007  if (ae->func && (!ae->is_cleanup || run_cleanups)) {
1008  ae->func();
1009  }
1010  ast_free(ae);
1011  }
1013 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
int is_cleanup
Definition: asterisk.c:330

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

Referenced by check_init(), and really_quit().

◆ ast_safe_execvp()

int ast_safe_execvp ( int  dualfork,
const char *  file,
char *const  argv[] 
)

Safely spawn an external program while closing file descriptors.

Note
This replaces the execvp call in all Asterisk modules
Parameters
dualforkNon-zero to simulate running the program in the background by forking twice. The option provides similar functionality to the '&' in the OS shell command "cmd &". The option allows Asterisk to run a reaper loop to watch the first fork which immediately exits after spaning the second fork. The actual program is run in the second fork.
fileexecvp(file, argv) file parameter
argvexecvp(file, argv) argv parameter

Definition at line 1216 of file asterisk.c.

1217 {
1218  pid_t pid = safe_exec_prep(dualfork);
1219 
1220  if (pid == 0) {
1221  execvp(file, argv);
1222  _exit(1);
1223  /* noreturn from _exit */
1224  }
1225 
1226  return safe_exec_wait(pid);
1227 }
static int safe_exec_wait(pid_t pid)
wait for spawned application to complete and unreplace sigchld
Definition: asterisk.c:1190
static pid_t safe_exec_prep(int dualfork)
fork and perform other preparations for spawning applications
Definition: asterisk.c:1129

References make_ari_stubs::file, safe_exec_prep(), and safe_exec_wait().

Referenced by run_externnotify().

◆ ast_safe_system()

int ast_safe_system ( const char *  s)

Safely spawn an OS shell command while closing file descriptors.

Note
This replaces the system call in all Asterisk modules
Parameters
s- OS shell command string to execute.
Warning
Command injection can happen using this call if the passed in string is created using untrusted data from an external source. It is best not to use untrusted data. However, the caller could filter out dangerous characters to avoid command injection.

Definition at line 1229 of file asterisk.c.

1230 {
1231  pid_t pid = safe_exec_prep(0);
1232 
1233  if (pid == 0) {
1234  execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
1235  _exit(1);
1236  /* noreturn from _exit */
1237  }
1238 
1239  return safe_exec_wait(pid);
1240 }

References NULL, safe_exec_prep(), and safe_exec_wait().

Referenced by consolehandler(), and remoteconsolehandler().

◆ ast_set_priority()

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.

Provided by asterisk.c

Definition at line 1835 of file asterisk.c.

1836 {
1837  struct sched_param sched;
1838  memset(&sched, 0, sizeof(sched));
1839 #ifdef __linux__
1840  if (pri) {
1841  sched.sched_priority = 10;
1842  if (sched_setscheduler(0, SCHED_RR, &sched)) {
1843  return -1;
1844  }
1845  } else {
1846  sched.sched_priority = 0;
1847  /* According to the manpage, these parameters can never fail. */
1848  sched_setscheduler(0, SCHED_OTHER, &sched);
1849  }
1850 #else
1851  if (pri) {
1852  if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
1853  ast_log(LOG_WARNING, "Unable to set high priority\n");
1854  return -1;
1855  } else
1856  ast_verb(1, "Set to high priority\n");
1857  } else {
1858  /* According to the manpage, these parameters can never fail. */
1859  setpriority(PRIO_PROCESS, 0, 0);
1860  }
1861 #endif
1862  return 0;
1863 }
#define sched_setscheduler
Definition: asterisk.h:51
#define setpriority
Definition: asterisk.h:50
#define ast_verb(level,...)
Definition: sched.c:76

References ast_log, ast_verb, LOG_WARNING, sched_setscheduler, and setpriority.

Referenced by app_exec(), asterisk_daemon(), main(), mp3play(), safe_exec_prep(), send_waveform_to_fd(), set_priority_all(), and spawn_mp3().

◆ ast_shutdown_final()

int ast_shutdown_final ( void  )
Returns
non-zero if the server is actively shutting down.
Since
13.3.0

The server is releasing resources and unloading modules. It won't be long now.

Definition at line 1865 of file asterisk.c.

1866 {
1868 }

References SHUTTING_DOWN_FINAL, and shuttingdown.

Referenced by httpd_process_request(), send_notify(), session_inv_on_media_update(), session_inv_on_redirected(), session_inv_on_rx_offer(), session_inv_on_state_changed(), and session_inv_on_tsx_state_changed().

◆ ast_shutting_down()

int ast_shutting_down ( void  )

The server is preventing new channel creation in preparation for shutdown and may actively be releasing resources. The shutdown process may be canceled by ast_cancel_shutdown() if it is not too late.

Note
The preparation to shutdown phase can be quite lengthy if we are gracefully shutting down. How long existing calls will last is not up to us.
Returns
non-zero if the server is preparing to or actively shutting down.

Definition at line 1870 of file asterisk.c.

1871 {
1872  return shutdown_pending;
1873 }

References shutdown_pending.

Referenced by __ast_channel_alloc_ap(), ast_cli_command_full(), ast_unregister_translator(), confbridge_exec(), handle_request_options(), options_on_rx_request(), and process_message().

◆ ast_tryconnect()

static int ast_tryconnect ( void  )
static

Definition at line 1678 of file asterisk.c.

1679 {
1680  struct sockaddr_un sunaddr;
1681  int res;
1682  ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
1683  if (ast_consock < 0) {
1684  fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
1685  return 0;
1686  }
1687  memset(&sunaddr, 0, sizeof(sunaddr));
1688  sunaddr.sun_family = AF_LOCAL;
1689  ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
1690  res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
1691  if (res) {
1692  close(ast_consock);
1693  ast_consock = -1;
1694  return 0;
1695  } else
1696  return 1;
1697 }

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

Referenced by ast_el_read_char(), and main().

◆ ast_unregister_atexit()

void ast_unregister_atexit ( void(*)(void)  func)

Unregister a function registered with ast_register_atexit().

Parameters
funcThe callback function to unregister.

Definition at line 1058 of file asterisk.c.

1059 {
1063 }
static void __ast_unregister_atexit(void(*func)(void))
Definition: asterisk.c:1015

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

Referenced by unload_module().

◆ ast_unregister_thread()

void ast_unregister_thread ( void *  id)

Definition at line 430 of file asterisk.c.

431 {
432  struct thread_list_t *x;
433 
436  if ((void *) x->id == id) {
438  break;
439  }
440  }
443  if (x) {
444  ast_free(x->name);
445  ast_free(x);
446  }
447 }
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617

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

Referenced by dummy_start().

◆ ast_unreplace_sigchld()

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

1114 {
1115  unsigned int level;
1116 
1118  level = --safe_system_level;
1119 
1120  /* only restore the handler if we are the last one */
1121  if (level == 0) {
1122  sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
1123  }
1124 
1126 }

References ast_mutex_lock, ast_mutex_unlock, NULL, safe_system_level, safe_system_lock, and safe_system_prev_handler.

Referenced by safe_exec_wait().

◆ asterisk_daemon()

static void asterisk_daemon ( int  isroot,
const char *  runuser,
const char *  rungroup 
)
static

Definition at line 4029 of file asterisk.c.

4030 {
4031  FILE *f;
4032  sigset_t sigs;
4033  int num;
4034  char *buf;
4035  char pbx_uuid[AST_UUID_STR_LEN];
4036 
4037  /* Set time as soon as possible */
4039 
4040  /* This needs to remain as high up in the initial start up as possible.
4041  * daemon causes a fork to occur, which has all sorts of unintended
4042  * consequences for things that interact with threads. This call *must*
4043  * occur before anything in Asterisk spawns or manipulates thread related
4044  * primitives. */
4045 #if HAVE_WORKING_FORK
4047 #ifndef HAVE_SBIN_LAUNCHD
4048  if (daemon(1, 0) < 0) {
4049  fprintf(stderr, "daemon() failed: %s\n", strerror(errno));
4050  } else {
4051  ast_mainpid = getpid();
4052  }
4053 #else
4054  fprintf(stderr, "Mac OS X detected. Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
4055 #endif
4056  }
4057 #endif
4058 
4059  /* At this point everything has been forked successfully,
4060  * we have determined that we aren't attempting to connect to
4061  * an Asterisk instance, and that there isn't one already running. */
4062  multi_thread_safe = 1;
4063 
4065 
4066  /* Check whether high prio was succesfully set by us or some
4067  * other incantation. */
4068  if (has_priority()) {
4070  } else {
4072  }
4073 
4074  /* Spawning of astcanary must happen AFTER the call to daemon(3) */
4075  if (ast_opt_high_priority) {
4076  snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
4077 
4078  /* Don't let the canary child kill Asterisk, if it dies immediately */
4079  sigaction(SIGPIPE, &ignore_sig_handler, NULL);
4080 
4081  canary_pid = fork();
4082  if (canary_pid == 0) {
4083  char canary_binary[PATH_MAX], ppid[12];
4084 
4085  /* Reset signal handler */
4086  signal(SIGCHLD, SIG_DFL);
4087  signal(SIGPIPE, SIG_DFL);
4088 
4090  ast_set_priority(0);
4091  snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid);
4092 
4093  /* Use the astcanary binary that we installed */
4094  snprintf(canary_binary, sizeof(canary_binary), "%s/astcanary", ast_config_AST_SBIN_DIR);
4095  execl(canary_binary, "astcanary", canary_filename, ppid, (char *)NULL);
4096 
4097  /* Should never happen */
4098  _exit(1);
4099  } else if (canary_pid > 0) {
4100  pthread_t dont_care;
4102  }
4103 
4104  /* Kill the canary when we exit */
4106  }
4107 
4108  /* Blindly write the PID file. */
4109  unlink(ast_config_AST_PID);
4110  f = fopen(ast_config_AST_PID, "w");
4111  if (f) {
4112  fprintf(f, "%ld\n", (long)ast_mainpid);
4113  fclose(f);
4114  } else {
4115  fprintf(stderr, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
4116  }
4117 
4118  /* Initialize the terminal. Since all processes have been forked,
4119  * we can now start using the standard log messages.
4120  */
4121  ast_term_init();
4122  printf("%s", term_end());
4123  fflush(stdout);
4124 
4125  print_intro_message(runuser, rungroup);
4126 
4128 
4129  check_init(astobj2_init(), "AO2");
4130  check_init(ast_named_locks_init(), "Named Locks");
4131 
4132  if (ast_opt_console) {
4133  if (el_hist == NULL || el == NULL)
4136  }
4137 
4138 #ifdef AST_XML_DOCS
4139  /* Load XML documentation. */
4141 #endif
4142 
4143  check_init(astdb_init(), "ASTdb");
4144 
4145  ast_uuid_init();
4146 
4147  if (ast_pbx_uuid_get(pbx_uuid, sizeof(pbx_uuid))) {
4148  ast_uuid_generate_str(pbx_uuid, sizeof(pbx_uuid));
4149  ast_db_put("pbx", "UUID", pbx_uuid);
4150  }
4151  ast_verb(0, "PBX UUID: %s\n", pbx_uuid);
4152 
4153  check_init(ast_json_init(), "libjansson");
4154  ast_ulaw_init();
4155  ast_alaw_init();
4156  ast_utf8_init();
4157  tdd_init();
4158  callerid_init();
4160 
4161  check_init(ast_utils_init(), "Utilities");
4162  check_init(ast_tps_init(), "Task Processor Core");
4163  check_init(ast_fd_init(), "File Descriptor Debugging");
4164  check_init(ast_pbx_init(), "ast_pbx_init");
4165  check_init(aco_init(), "Configuration Option Framework");
4166  check_init(stasis_init(), "Stasis");
4167 #ifdef TEST_FRAMEWORK
4168  check_init(ast_test_init(), "Test Framework");
4169 #endif
4170  check_init(ast_translate_init(), "Translator Core");
4171 
4172  ast_aoc_cli_init();
4173 
4174  check_init(ast_sorcery_init(), "Sorcery");
4175  check_init(ast_codec_init(), "Codecs");
4176  check_init(ast_format_init(), "Formats");
4177  check_init(ast_format_cache_init(), "Format Cache");
4178  check_init(ast_codec_builtin_init(), "Built-in Codecs");
4179  check_init(ast_bucket_init(), "Bucket API");
4180  check_init(ast_stasis_system_init(), "Stasis system-level information");
4181  check_init(ast_endpoint_stasis_init(), "Stasis Endpoint");
4182 
4183  ast_makesocket();
4184  /* GCC 4.9 gives a bogus "right-hand operand of comma expression has
4185  * no effect" warning */
4186  (void) sigemptyset(&sigs);
4187  (void) sigaddset(&sigs, SIGHUP);
4188  (void) sigaddset(&sigs, SIGTERM);
4189  (void) sigaddset(&sigs, SIGINT);
4190  (void) sigaddset(&sigs, SIGPIPE);
4191  (void) sigaddset(&sigs, SIGWINCH);
4192  pthread_sigmask(SIG_BLOCK, &sigs, NULL);
4193  sigaction(SIGURG, &urg_handler, NULL);
4194  signal(SIGINT, __quit_handler);
4195  signal(SIGTERM, __quit_handler);
4196  sigaction(SIGHUP, &hup_handler, NULL);
4197  sigaction(SIGPIPE, &ignore_sig_handler, NULL);
4198 
4199  /* ensure that the random number generators are seeded with a different value every time
4200  Asterisk is started
4201  */
4202  srand((unsigned int) getpid() + (unsigned int) time(NULL));
4203  initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
4204 
4206 
4207  check_init(init_logger(), "Logger");
4208  check_init(ast_rtp_engine_init(), "RTP Engine");
4209 
4211 
4212  check_init(ast_timing_init(), "Timing");
4213  check_init(ast_ssl_init(), "SSL");
4215  check_init(ast_pj_init(), "Embedded PJProject");
4216  check_init(app_init(), "App Core");
4217  check_init(mwi_init(), "MWI Core");
4218  check_init(devstate_init(), "Device State Core");
4219  check_init(ast_msg_init(), "Messaging API");
4220  check_init(ast_channels_init(), "Channel");
4221  check_init(ast_endpoint_init(), "Endpoints");
4222  check_init(ast_pickup_init(), "Call Pickup");
4223  check_init(ast_bridging_init(), "Bridging");
4224  check_init(ast_parking_stasis_init(), "Parking Core");
4225  check_init(ast_device_state_engine_init(), "Device State Engine");
4226  check_init(ast_presence_state_engine_init(), "Presence State Engine");
4227  check_init(dns_core_init(), "DNS Resolver Core");
4228  check_init(ast_dns_system_resolver_init(), "Default DNS resolver");
4229  check_init(ast_security_stasis_init(), "Security Stasis Topic and Events");
4230  check_init(ast_image_init(), "Image");
4231  check_init(ast_file_init(), "Generic File Format Support");
4232  check_init(load_pbx(), "load_pbx");
4233  check_init(load_pbx_builtins(), "Builtin PBX Applications");
4234  check_init(load_pbx_functions_cli(), "PBX Functions Support");
4235  check_init(load_pbx_variables(), "PBX Variables Support");
4236  check_init(load_pbx_switch(), "PBX Switch Support");
4237  check_init(load_pbx_app(), "PBX Application Support");
4238  check_init(load_pbx_hangup_handler(), "PBX Hangup Handler Support");
4239  check_init(ast_local_init(), "Local Proxy Channel Driver");
4240 
4241  /* We should avoid most config loads before this point as they can't use realtime. */
4242  check_init(load_modules(), "Module");
4243 
4244  /*
4245  * This has to load after the dynamic modules load, as items in the media
4246  * cache can't be constructed from items in the AstDB without their
4247  * bucket backends.
4248  */
4249  check_init(ast_media_cache_init(), "Media Cache");
4250 
4251  /* loads the cli_permissions.conf file needed to implement cli restrictions. */
4252  ast_cli_perms_init(0);
4253 
4254  ast_stun_init();
4255 
4257 
4258  if (ast_opt_no_fork) {
4259  consolethread = pthread_self();
4260  }
4261 
4263 
4265 
4268 
4269  pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
4270 
4272 
4276 
4278  ast_sd_notify("READY=1");
4279 
4280  ast_verb(0, COLORIZE_FMT "\n", COLORIZE(COLOR_BRGREEN, 0, "Asterisk Ready."));
4281 
4283 
4284  if (ast_opt_console) {
4285  /* Console stuff now... */
4286  /* Register our quit function */
4287  char title[256];
4288  char hostname[MAXHOSTNAMELEN] = "";
4289 
4290  if (gethostname(hostname, sizeof(hostname) - 1)) {
4291  ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
4292  }
4293 
4295 
4296  set_icon("Asterisk");
4297  snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
4298  set_title(title);
4299 
4300  el_set(el, EL_GETCFN, ast_el_read_char);
4301 
4302  for (;;) {
4303  if (sig_flags.need_el_end) {
4304  el_end(el);
4305 
4306  return;
4307  }
4308 
4309  if (sig_flags.need_quit || sig_flags.need_quit_handler) {
4310  quit_handler(0, SHUTDOWN_FAST, 0);
4311  break;
4312  }
4313  buf = (char *) el_gets(el, &num);
4314 
4315  if (!buf && write(1, "", 1) < 0)
4316  return; /* quit */
4317 
4318  if (buf) {
4319  if (buf[strlen(buf)-1] == '\n')
4320  buf[strlen(buf)-1] = '\0';
4321 
4323  }
4324  }
4325  }
4326 
4327  /* Stall until a quit signal is given */
4329 }
int load_pbx_variables(void)
void threadstorage_init(void)
Definition: threadstorage.c:35
void ast_process_pending_reloads(void)
Process reload requests received during startup.
Definition: loader.c:1407
int ast_bridging_init(void)
Initialize the bridging system.
Definition: bridge.c:5528
void dnsmgr_start_refresh(void)
Definition: dnsmgr.c:302
int ast_timing_init(void)
Definition: timing.c:289
int ast_device_state_engine_init(void)
Initialize the device state engine in separate thread.
Definition: devicestate.c:618
int load_modules(void)
Definition: loader.c:2338
void logger_queue_start(void)
Start the ast_queue_log() logger.
Definition: logger.c:1940
int aco_init(void)
int ast_test_init(void)
Definition: test.c:1222
void ast_stun_init(void)
Initialize the STUN system in Asterisk.
Definition: stun.c:576
int astdb_init(void)
Definition: main/db.c:1082
int ast_pj_init(void)
Definition: libasteriskpj.c:45
int load_pbx_functions_cli(void)
int ast_tps_init(void)
void load_astmm_phase_2(void)
Initialize malloc debug phase 2.
Definition: astmm.c:1529
int ast_msg_init(void)
int load_pbx_hangup_handler(void)
int ast_local_init(void)
Initialize the local proxy channel.
Definition: core_local.c:1134
int load_pbx_builtins(void)
int load_pbx_switch(void)
Definition: pbx_switch.c:125
int ast_rtp_engine_init(void)
initializes the rtp engine arrays
Definition: rtp_engine.c:3615
int ast_xmldoc_load_documentation(void)
Load XML documentation. Provided by xmldoc.c.
Definition: xmldoc.c:2881
int ast_named_locks_init(void)
Definition: named_locks.c:52
int ast_channels_init(void)
Definition: channel.c:8090
void load_astmm_phase_1(void)
Initialize malloc debug phase 1.
Definition: astmm.c:1525
void ast_builtins_init(void)
initialize the _full_cmd string in * each of the builtins.
Definition: main/cli.c:2243
void ast_autoservice_init(void)
Definition: autoservice.c:380
int init_logger(void)
Definition: logger.c:1956
int ast_endpoint_init(void)
Endpoint support initialization.
int dns_core_init(void)
Definition: dns_core.c:614
int load_pbx(void)
int astobj2_init(void)
Definition: astobj2.c:1169
int load_pbx_app(void)
Definition: pbx_app.c:511
int ast_dns_system_resolver_init(void)
Initializes the resolver.
int ast_ssl_init(void)
int ast_cli_perms_init(int reload)
Definition: main/cli.c:2115
int ast_file_init(void)
Definition: file.c:2024
int ast_parking_stasis_init(void)
initializes the rtp engine arrays
Definition: parking.c:53
void ast_alaw_init(void)
To init the alaw to slinear conversion stuff, this needs to be run.
Definition: alaw.c:152
int ast_alertpipe_init(int alert_pipe[2])
Initialize an alert pipe.
Definition: alertpipe.c:38
int ast_aoc_cli_init(void)
enable aoc cli options
Definition: aoc.c:2020
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: main/db.c:327
static void canary_exit(void)
Definition: asterisk.c:3460
static void check_init(int init_result, const char *name)
Definition: asterisk.c:4016
static void * canary_thread(void *unused)
Definition: asterisk.c:3431
static void publish_fully_booted(void)
Definition: asterisk.c:975
static void main_atexit(void)
Definition: asterisk.c:3523
static char randompool[256]
Definition: asterisk.c:390
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: asterisk.c:1053
static char canary_filename[128]
Definition: asterisk.c:387
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 ac...
Definition: asterisk.c:1835
static int has_priority(void)
Check whether we were set to high(er) priority.
Definition: asterisk.c:1772
static struct sigaction hup_handler
Definition: asterisk.c:1733
static pthread_t mon_sig_flags
Definition: asterisk.c:385
static void * monitor_sig_flags(void *unused)
Definition: asterisk.c:3406
int ast_pbx_uuid_get(char *pbx_uuid, int length)
Retrieve the PBX UUID.
Definition: asterisk.c:970
struct timeval ast_lastreloadtime
Definition: asterisk.c:337
static void consolehandler(const char *s)
Definition: asterisk.c:2280
static struct ast_cli_entry cli_asterisk_shutdown[]
Shutdown Asterisk CLI commands.
Definition: asterisk.c:2600
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:1048
static void set_title(char *text)
Set an X-term or screen title.
Definition: asterisk.c:1759
static int ast_makesocket(void)
Definition: asterisk.c:1592
static int canary_pid
Definition: asterisk.c:386
static struct ast_cli_entry cli_asterisk[]
Definition: asterisk.c:2609
static void run_startup_commands(void)
Definition: asterisk.c:3470
struct timeval ast_startuptime
Definition: asterisk.c:336
static void read_pjproject_startup_options(void)
Definition: asterisk.c:3372
pid_t ast_mainpid
Definition: asterisk.c:315
static void __quit_handler(int num)
Definition: asterisk.c:2136
static void set_icon(char *text)
Definition: asterisk.c:1765
static void print_intro_message(const char *runuser, const char *rungroup)
Definition: asterisk.c:3510
static struct sigaction ignore_sig_handler
Definition: asterisk.c:1087
static struct sigaction urg_handler
Definition: asterisk.c:1710
int ast_pbx_init(void)
int ast_fd_init(void)
Definition: astfd.c:370
#define PATH_MAX
Definition: asterisk.h:40
int ast_bucket_init(void)
Initialize bucket support.
Definition: bucket.c:954
void callerid_init(void)
CallerID Initialization.
Definition: callerid.c:115
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_codec_init(void)
Initialize codec support within the core.
Definition: codec.c:249
int ast_codec_builtin_init(void)
Initialize built-in codecs within the core.
int devstate_init(void)
Initialize the device state core.
Definition: devicestate.c:896
int ast_format_init(void)
Initialize media format support.
Definition: format.c:77
int ast_format_cache_init(void)
Initialize format cache support within the core.
Definition: format_cache.c:364
struct ast_flags ast_options
Definition: options.c:61
@ AST_OPT_FLAG_HIGH_PRIORITY
Definition: options.h:48
@ AST_OPT_FLAG_FULLY_BOOTED
Definition: options.h:58
int ast_image_init(void)
Initialize image stuff Initializes all the various image stuff. Basically just registers the cli stuf...
Definition: image.c:212
int app_init(void)
Initialize the application core.
Definition: main/app.c:3425
void ast_close_fds_above_n(int n)
Common routine for child processes, to close all fds prior to exec(2)
Definition: main/app.c:3262
int register_config_cli(void)
Exposed initialization method for core process.
Definition: main/config.c:4135
int ast_security_stasis_init(void)
initializes stasis topic/event types for ast_security_topic and ast_security_event_type
int ast_sd_notify(const char *state)
a wrapper for sd_notify(): notify systemd of any state changes.
Definition: io.c:392
int ast_json_init(void)
Initialize the JSON library.
Definition: json.c:705
int ast_media_cache_init(void)
Initialize the media cache.
Definition: media_cache.c:671
int mwi_init(void)
Initialize the mwi core.
Definition: mwi.c:507
#define MAXHOSTNAMELEN
Definition: network.h:69
#define ast_opt_high_priority
Definition: options.h:110
#define ast_opt_always_fork
Definition: options.h:126
#define ast_opt_no_fork
Definition: options.h:107
const char * ast_config_AST_PID
Definition: options.c:166
const char * ast_config_AST_RUN_DIR
Definition: options.c:162
const char * ast_config_AST_SBIN_DIR
Definition: options.c:163
int ast_pickup_init(void)
Initialize pickup.
Definition: pickup.c:400
int ast_presence_state_engine_init(void)
int ast_sorcery_init(void)
Initialize the sorcery API.
Definition: sorcery.c:387
int stasis_init(void)
Initialize the Stasis subsystem.
Definition: stasis.c:3063
int ast_endpoint_stasis_init(void)
Initialization function for endpoint stasis support.
int ast_stasis_system_init(void)
Initialize the stasis system topic and message types.
void tdd_init(void)
Definition: tdd.c:94
#define COLOR_BRGREEN
Definition: term.h:55
#define COLORIZE(fg, bg, str)
Definition: term.h:72
#define COLORIZE_FMT
Shortcut macros for coloring a set of text.
Definition: term.h:71
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:157
int ast_translate_init(void)
Initialize the translation matrix and index to format conversion table.
Definition: translate.c:1630
void ast_ulaw_init(void)
Set up mu-law conversion table.
Definition: ulaw.c:173
int ast_utf8_init(void)
Register UTF-8 tests.
Definition: utf8.c:375
#define ast_clear_flag(p, flag)
Definition: utils.h:77
int ast_utils_init(void)
Definition: main/utils.c:2515
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:583
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define ARRAY_LEN(a)
Definition: utils.h:661
#define AST_UUID_STR_LEN
Definition: uuid.h:27
void ast_uuid_init(void)
Initialize the UUID system.
Definition: uuid.c:192
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141

References __quit_handler(), aco_init(), app_init(), ARRAY_LEN, ast_alaw_init(), ast_alertpipe_init(), ast_aoc_cli_init(), ast_autoservice_init(), ast_bridging_init(), ast_bucket_init(), ast_builtins_init(), ast_channels_init(), ast_clear_flag, ast_cli_perms_init(), ast_cli_register_multiple, ast_close_fds_above_n(), ast_codec_builtin_init(), ast_codec_init(), ast_config_AST_PID, ast_config_AST_RUN_DIR, ast_config_AST_SBIN_DIR, ast_copy_string(), ast_db_put(), ast_device_state_engine_init(), ast_dns_system_resolver_init(), ast_el_initialize(), ast_el_read_char(), ast_el_read_default_histfile(), ast_endpoint_init(), ast_endpoint_stasis_init(), ast_fd_init(), ast_file_init(), ast_format_cache_init(), ast_format_init(), ast_image_init(), ast_json_init(), ast_lastreloadtime, ast_local_init(), ast_mainpid, ast_makesocket(), ast_media_cache_init(), ast_msg_init(), ast_named_locks_init(), ast_opt_always_fork, ast_opt_console, AST_OPT_FLAG_FULLY_BOOTED, AST_OPT_FLAG_HIGH_PRIORITY, ast_opt_high_priority, ast_opt_no_fork, ast_options, ast_parking_stasis_init(), ast_pbx_init(), ast_pbx_uuid_get(), ast_pickup_init(), ast_pj_init(), ast_presence_state_engine_init(), ast_process_pending_reloads(), ast_pthread_create_detached, ast_register_atexit(), ast_register_cleanup(), ast_rtp_engine_init(), ast_sd_notify(), ast_security_stasis_init(), ast_set_flag, ast_set_priority(), ast_sorcery_init(), ast_ssl_init(), ast_startuptime, ast_stasis_system_init(), ast_stun_init(), ast_term_init(), ast_test_init(), ast_timing_init(), ast_tps_init(), ast_translate_init(), ast_tvnow(), ast_ulaw_init(), ast_utf8_init(), ast_utils_init(), ast_uuid_generate_str(), ast_uuid_init(), AST_UUID_STR_LEN, ast_verb, ast_xmldoc_load_documentation(), astdb_init(), astobj2_init(), buf, callerid_init(), canary_exit(), canary_filename, canary_pid, canary_thread(), check_init(), cli_asterisk, cli_asterisk_shutdown, COLOR_BRGREEN, COLORIZE, COLORIZE_FMT, consolehandler(), consolethread, devstate_init(), dns_core_init(), dnsmgr_start_refresh(), el, el_hist, errno, has_priority(), hostname, hup_handler, ignore_sig_handler, init_logger(), load_astmm_phase_1(), load_astmm_phase_2(), load_modules(), load_pbx(), load_pbx_app(), load_pbx_builtins(), load_pbx_functions_cli(), load_pbx_hangup_handler(), load_pbx_switch(), load_pbx_variables(), logger_queue_start(), main_atexit(), MAXHOSTNAMELEN, mon_sig_flags, monitor_sig_flags(), multi_thread_safe, mwi_init(), NULL, PATH_MAX, print_intro_message(), publish_fully_booted(), quit_handler(), randompool, read_pjproject_startup_options(), register_config_cli(), run_startup_commands(), set_icon(), set_title(), SHUTDOWN_FAST, sig_alert_pipe, sig_flags, stasis_init(), tdd_init(), term_end(), threadstorage_init(), and urg_handler.

Referenced by main().

◆ can_safely_quit()

static int can_safely_quit ( shutdown_nice_t  niceness,
int  restart 
)
static

Definition at line 1957 of file asterisk.c.

1958 {
1959  int waited = 0;
1960 
1961  /* Check if someone else isn't already doing this. */
1963  if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
1964  /* Already in progress and other request was less nice. */
1966  ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
1967  return 0;
1968  }
1969  shuttingdown = niceness;
1971 
1972  /* Try to get as many CDRs as possible submitted to the backend engines
1973  * (if in batch mode). really_quit happens to call it again when running
1974  * the atexit handlers, otherwise this would be a bit early. */
1976 
1977  /*
1978  * Shutdown the message queue for the technology agnostic message channel.
1979  * This has to occur before we pause shutdown pending ast_undestroyed_channels.
1980  *
1981  * XXX This is not reversed on shutdown cancel.
1982  */
1983  ast_msg_shutdown();
1984 
1985  if (niceness == SHUTDOWN_NORMAL) {
1986  /* Begin shutdown routine, hanging up active channels */
1988  if (ast_opt_console) {
1989  ast_verb(0, "Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
1990  }
1992  waited |= wait_for_channels_to_die(niceness, SHUTDOWN_TIMEOUT);
1993  } else if (niceness >= SHUTDOWN_NICE) {
1994  if (niceness != SHUTDOWN_REALLY_NICE) {
1996  }
1997  if (ast_opt_console) {
1998  ast_verb(0, "Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
1999  }
2000  waited |= wait_for_channels_to_die(niceness, -1);
2001  }
2002 
2003  /* Re-acquire lock and check if someone changed the niceness, in which
2004  * case someone else has taken over the shutdown.
2005  */
2007  if (shuttingdown != niceness) {
2009  ast_verb(0, "Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
2010  }
2012  return 0;
2013  }
2014 
2015  if (niceness >= SHUTDOWN_REALLY_NICE) {
2018 
2019  /* No more Mr. Nice guy. We are committed to shutting down now. */
2023 
2025  }
2028 
2029  if (niceness >= SHUTDOWN_NORMAL && waited) {
2030  /*
2031  * We were not idle. Give things in progress a chance to
2032  * recognize the final shutdown phase.
2033  */
2034  sleep(1);
2035  }
2036  return 1;
2037 }
void ast_msg_shutdown(void)
static void ast_begin_shutdown(void)
Definition: asterisk.c:1893
#define SHUTDOWN_TIMEOUT
Definition: asterisk.c:1914
static int wait_for_channels_to_die(shutdown_nice_t niceness, int seconds)
Definition: asterisk.c:1927
void ast_cdr_engine_term(void)
Definition: cdr.c:4597
void ast_softhangup_all(void)
Soft hangup all active channels.
Definition: channel.c:493

References ast_begin_shutdown(), ast_cdr_engine_term(), ast_msg_shutdown(), ast_mutex_lock, ast_mutex_unlock, ast_opt_console, ast_softhangup_all(), ast_verb, ast_verbose(), NOT_SHUTTING_DOWN, safe_system_lock, SHUTDOWN_NICE, SHUTDOWN_NORMAL, SHUTDOWN_REALLY_NICE, SHUTDOWN_TIMEOUT, SHUTTING_DOWN, SHUTTING_DOWN_FINAL, shuttingdown, and wait_for_channels_to_die().

Referenced by quit_handler().

◆ canary_exit()

static void canary_exit ( void  )
static

Definition at line 3460 of file asterisk.c.

3461 {
3462  if (canary_pid > 0) {
3463  int status;
3464  kill(canary_pid, SIGKILL);
3465  waitpid(canary_pid, &status, 0);
3466  }
3467 }

References canary_pid, and status.

Referenced by asterisk_daemon().

◆ canary_thread()

static void* canary_thread ( void *  unused)
static

Definition at line 3431 of file asterisk.c.

3432 {
3433  struct stat canary_stat;
3434  struct timeval now;
3435 
3436  /* Give the canary time to sing */
3437  sleep(120);
3438 
3439  for (;;) {
3440  now = ast_tvnow();
3441  if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
3443  "The canary is no more. He has ceased to be! "
3444  "He's expired and gone to meet his maker! "
3445  "He's a stiff! Bereft of life, he rests in peace. "
3446  "His metabolic processes are now history! He's off the twig! "
3447  "He's kicked the bucket. He's shuffled off his mortal coil, "
3448  "run down the curtain, and joined the bleeding choir invisible!! "
3449  "THIS is an EX-CANARY. (Reducing priority)\n");
3450  set_priority_all(0);
3451  pthread_exit(NULL);
3452  }
3453 
3454  /* Check the canary once a minute */
3455  sleep(60);
3456  }
3457 }
static int set_priority_all(int pri)
Set priority on all known threads.
Definition: asterisk.c:1792

References ast_log, ast_tvnow(), canary_filename, LOG_WARNING, NULL, and set_priority_all().

Referenced by asterisk_daemon().

◆ check_init()

static void check_init ( int  init_result,
const char *  name 
)
inlinestatic

Definition at line 4016 of file asterisk.c.

4017 {
4018  if (init_result) {
4019  if (ast_is_logger_initialized()) {
4020  ast_log(LOG_ERROR, "%s initialization failed. ASTERISK EXITING!\n%s", name, term_quit());
4021  } else {
4022  fprintf(stderr, "%s initialization failed. ASTERISK EXITING!\n%s", name, term_quit());
4023  }
4024  ast_run_atexits(0);
4025  exit(init_result == -2 ? 2 : 1);
4026  }
4027 }
static void ast_run_atexits(int run_cleanups)
Definition: asterisk.c:1001
int ast_is_logger_initialized(void)
Test if logger is initialized.
Definition: logger.c:1929

References ast_is_logger_initialized(), ast_log, ast_run_atexits(), LOG_ERROR, name, and term_quit().

Referenced by asterisk_daemon().

◆ cli_complete()

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

Definition at line 2950 of file asterisk.c.

2951 {
2952  int len = 0;
2953  char *ptr;
2954  struct ast_vector_string *matches;
2955  int retval = CC_ERROR;
2956  char savechr;
2957  int res;
2958 
2959  LineInfo *lf = (LineInfo *)el_line(editline);
2960 
2961  savechr = *(char *)lf->cursor;
2962  *(char *)lf->cursor = '\0';
2963  ptr = (char *)lf->cursor;
2964  if (ptr) {
2965  while (ptr > lf->buffer) {
2966  if (isspace(*ptr)) {
2967  ptr++;
2968  break;
2969  }
2970  ptr--;
2971  }
2972  }
2973 
2974  len = lf->cursor - ptr;
2975 
2976  if (ast_opt_remote) {
2977 #define CMD_MATCHESARRAY "_COMMAND MATCHESARRAY \"%s\" \"%s\""
2978  char *mbuf;
2979  char *new_mbuf;
2980  int mlen = 0;
2981  int maxmbuf = ast_asprintf(&mbuf, CMD_MATCHESARRAY, lf->buffer, ptr);
2982 
2983  if (maxmbuf == -1) {
2984  *((char *) lf->cursor) = savechr;
2985 
2986  return (char *)(CC_ERROR);
2987  }
2988 
2989  fdsend(ast_consock, mbuf);
2990  res = 0;
2991  mlen = 0;
2992  mbuf[0] = '\0';
2993 
2994  while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
2995  if (mlen + 1024 > maxmbuf) {
2996  /* Expand buffer to the next 1024 byte increment plus a NULL terminator. */
2997  maxmbuf = mlen + 1024;
2998  new_mbuf = ast_realloc(mbuf, maxmbuf + 1);
2999  if (!new_mbuf) {
3000  ast_free(mbuf);
3001  *((char *) lf->cursor) = savechr;
3002 
3003  return (char *)(CC_ERROR);
3004  }
3005  mbuf = new_mbuf;
3006  }
3007  /* Only read 1024 bytes at a time */
3008  res = read(ast_consock, mbuf + mlen, 1024);
3009  if (res > 0) {
3010  mlen += res;
3011  mbuf[mlen] = '\0';
3012  }
3013  }
3014  mbuf[mlen] = '\0';
3015 
3016  matches = ast_el_strtoarr(mbuf);
3017  ast_free(mbuf);
3018  } else {
3019  matches = ast_cli_completion_vector((char *)lf->buffer, ptr);
3020  }
3021 
3022  if (matches) {
3023  int i;
3024  int maxlen, match_len;
3025  const char *best_match = AST_VECTOR_GET(matches, 0);
3026 
3027  if (!ast_strlen_zero(best_match)) {
3028  el_deletestr(editline, (int) len);
3029  el_insertstr(editline, best_match);
3030  retval = CC_REFRESH;
3031  }
3032 
3033  if (AST_VECTOR_SIZE(matches) == 2) {
3034  /* Found an exact match */
3035  el_insertstr(editline, " ");
3036  retval = CC_REFRESH;
3037  } else {
3038  /* Must be more than one match */
3039  for (i = 1, maxlen = 0; i < AST_VECTOR_SIZE(matches); i++) {
3040  match_len = strlen(AST_VECTOR_GET(matches, i));
3041  if (match_len > maxlen) {
3042  maxlen = match_len;
3043  }
3044  }
3045 
3046  fprintf(stdout, "\n");
3047  ast_cli_display_match_list(matches, maxlen);
3048  retval = CC_REDISPLAY;
3049  }
3051  AST_VECTOR_PTR_FREE(matches);
3052  }
3053 
3054  *((char *) lf->cursor) = savechr;
3055 
3056  return (char *)(long)retval;
3057 }
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
static void ast_cli_display_match_list(struct ast_vector_string *matches, int max)
Definition: asterisk.c:2923
#define CMD_MATCHESARRAY
static struct ast_vector_string * ast_el_strtoarr(char *buf)
Definition: asterisk.c:2889
static int fdsend(int fd, const char *s)
Definition: asterisk.c:1066
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
struct ast_vector_string * ast_cli_completion_vector(const char *text, const char *word)
Generates a vector of strings for CLI completion.
Definition: main/cli.c:2765
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static ENTRY retval
Definition: hsearch.c:50
#define ast_opt_remote
Definition: options.h:112

References ast_asprintf, AST_CLI_COMPLETE_EOF, ast_cli_completion_vector(), ast_cli_display_match_list(), ast_consock, ast_el_strtoarr(), ast_free, ast_opt_remote, ast_realloc, ast_strlen_zero(), AST_VECTOR_CALLBACK_VOID, AST_VECTOR_GET, AST_VECTOR_PTR_FREE, AST_VECTOR_SIZE, CMD_MATCHESARRAY, fdsend(), if(), len(), and retval.

Referenced by ast_el_initialize().

◆ cli_prompt()

static char* cli_prompt ( EditLine *  editline)
static

Definition at line 2763 of file asterisk.c.

2764 {
2765  char tmp[100];
2766  char *pfmt;
2767  int color_used = 0;
2768  static int cli_prompt_changes = 0;
2769  struct passwd *pw;
2770  struct group *gr;
2771 
2772  if (prompt == NULL) {
2773  prompt = ast_str_create(100);
2774  } else if (!cli_prompt_changes) {
2775  return ast_str_buffer(prompt);
2776  } else {
2778  }
2779 
2780  if ((pfmt = getenv("ASTERISK_PROMPT"))) {
2781  char *t = pfmt;
2782  struct timeval ts = ast_tvnow();
2783  while (*t != '\0') {
2784  if (*t == '%') {
2785  char hostname[MAXHOSTNAMELEN] = "";
2786  int i, which;
2787  struct ast_tm tm = { 0, };
2788  int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
2789 
2790  t++;
2791  switch (*t) {
2792  case 'C': /* color */
2793  t++;
2794  if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
2795  ast_term_color_code(&prompt, fgcolor, bgcolor);
2796  t += i - 1;
2797  } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
2798  ast_term_color_code(&prompt, fgcolor, 0);
2799  t += i - 1;
2800  }
2801 
2802  /* If the color has been reset correctly, then there's no need to reset it later */
2803  color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
2804  break;
2805  case 'd': /* date */
2806  if (ast_localtime(&ts, &tm, NULL)) {
2807  ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
2808  ast_str_append(&prompt, 0, "%s", tmp);
2809  cli_prompt_changes++;
2810  }
2811  break;
2812  case 'g': /* group */
2813  if ((gr = getgrgid(getgid()))) {
2814  ast_str_append(&prompt, 0, "%s", gr->gr_name);
2815  }
2816  break;
2817  case 'h': /* hostname */
2818  if (!gethostname(hostname, sizeof(hostname) - 1)) {
2819  ast_str_append(&prompt, 0, "%s", hostname);
2820  } else {
2821  ast_str_append(&prompt, 0, "%s", "localhost");
2822  }
2823  break;
2824  case 'H': /* short hostname */
2825  if (!gethostname(hostname, sizeof(hostname) - 1)) {
2826  char *dotptr;
2827  if ((dotptr = strchr(hostname, '.'))) {
2828  *dotptr = '\0';
2829  }
2830  ast_str_append(&prompt, 0, "%s", hostname);
2831  } else {
2832  ast_str_append(&prompt, 0, "%s", "localhost");
2833  }
2834  break;
2835 #ifdef HAVE_GETLOADAVG
2836  case 'l': /* load avg */
2837  t++;
2838  if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
2839  double list[3];
2840  getloadavg(list, 3);
2841  ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
2842  cli_prompt_changes++;
2843  }
2844  break;
2845 #endif
2846  case 's': /* Asterisk system name (from asterisk.conf) */
2848  break;
2849  case 't': /* time */
2850  if (ast_localtime(&ts, &tm, NULL)) {
2851  ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
2852  ast_str_append(&prompt, 0, "%s", tmp);
2853  cli_prompt_changes++;
2854  }
2855  break;
2856  case 'u': /* username */
2857  if ((pw = getpwuid(getuid()))) {
2858  ast_str_append(&prompt, 0, "%s", pw->pw_name);
2859  }
2860  break;
2861  case '#': /* process console or remote? */
2862  ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
2863  break;
2864  case '%': /* literal % */
2865  ast_str_append(&prompt, 0, "%c", '%');
2866  break;
2867  case '\0': /* % is last character - prevent bug */
2868  t--;
2869  break;
2870  }
2871  } else {
2872  ast_str_append(&prompt, 0, "%c", *t);
2873  }
2874  t++;
2875  }
2876  if (color_used) {
2877  /* Force colors back to normal at end */
2878  ast_term_color_code(&prompt, 0, 0);
2879  }
2880  } else {
2881  ast_str_set(&prompt, 0, "%s%s",
2883  ASTERISK_PROMPT);
2884  }
2885 
2886  return ast_str_buffer(prompt);
2887 }
static struct ast_str * prompt
Definition: asterisk.c:2761
#define ASTERISK_PROMPT
Definition: asterisk.c:2590
int getloadavg(double *list, int nelem)
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1117
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:739
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:674
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:640
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1091
int ast_term_color_code(struct ast_str **str, int fgcolor, int bgcolor)
Append a color sequence to an ast_str.
Definition: term.c:296
#define COLOR_WHITE
Definition: term.h:64
#define COLOR_BLACK
Definition: term.h:50

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_term_color_code(), ast_tvnow(), ASTERISK_PROMPT, COLOR_BLACK, COLOR_WHITE, getloadavg(), hostname, MAXHOSTNAMELEN, NULL, prompt, remotehostname, and tmp().

Referenced by ast_el_initialize().

◆ console_print()

static int console_print ( const char *  s)
static

Definition at line 2198 of file asterisk.c.

2199 {
2200  struct console_state_data *state =
2202 
2203  char prefix[80];
2204  const char *c;
2205  int num, res = 0;
2206  unsigned int newline;
2207 
2208  do {
2209  if (VERBOSE_HASMAGIC(s)) {
2210 
2211  /* always use the given line's level, otherwise
2212  we'll use the last line's level */
2213  state->verbose_line_level = VERBOSE_MAGIC2LEVEL(s);
2214 
2215  /* move past magic */
2216  s++;
2217 
2218  set_header(prefix, sizeof(prefix), state->verbose_line_level);
2219  } else {
2220  *prefix = '\0';
2221  }
2222  c = s;
2223 
2224  /* for a given line separate on verbose magic, newline, and eol */
2225  if ((s = strchr(c, '\n'))) {
2226  ++s;
2227  newline = 1;
2228  } else {
2229  s = strchr(c, '\0');
2230  newline = 0;
2231  }
2232 
2233  /* check if we should write this line after calculating begin/end
2234  so we process the case of a higher level line embedded within
2235  two lower level lines */
2236  if (state->verbose_line_level > option_verbose) {
2237  continue;
2238  }
2239 
2240  if (!ast_strlen_zero(prefix)) {
2241  fputs(prefix, stdout);
2242  }
2243 
2244  num = s - c;
2245  if (fwrite(c, sizeof(char), num, stdout) < num) {
2246  break;
2247  }
2248 
2249  if (!res) {
2250  /* if at least some info has been written
2251  we'll want to return true */
2252  res = 1;
2253  }
2254  } while (*s);
2255 
2256  if (newline) {
2257  /* if ending on a newline then reset last level to zero
2258  since what follows may be not be logging output */
2259  state->verbose_line_level = 0;
2260  }
2261 
2262  if (res) {
2263  fflush(stdout);
2264  }
2265 
2266  return res;
2267 }
static void set_header(char *outbuf, int maxout, char level)
Definition: asterisk.c:2151
static struct ast_threadstorage console_state
Definition: asterisk.c:2196
#define VERBOSE_MAGIC2LEVEL(x)
#define VERBOSE_HASMAGIC(x)
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.

References ast_strlen_zero(), ast_threadstorage_get(), c, console_state, option_verbose, prefix, set_header(), VERBOSE_HASMAGIC, and VERBOSE_MAGIC2LEVEL.

Referenced by ast_console_puts_mutable_full(), and ast_el_read_char().

◆ console_state_init()

static int console_state_init ( void *  ptr)
static

Definition at line 2189 of file asterisk.c.

2190 {
2191  struct console_state_data *state = ptr;
2192  state->verbose_line_level = 0;
2193  return 0;
2194 }

◆ consolehandler()

static void consolehandler ( const char *  s)
static

Definition at line 2280 of file asterisk.c.

2281 {
2282  printf("%s", term_end());
2283  fflush(stdout);
2284 
2285  /* Called when readline data is available */
2286  if (!ast_all_zeros(s))
2287  ast_el_add_history(s);
2288  /* The real handler for bang */
2289  if (s[0] == '!') {
2290  if (s[1])
2291  ast_safe_system(s+1);
2292  else
2293  ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
2294  } else
2295  ast_cli_command(STDOUT_FILENO, s);
2296 }
static int ast_el_add_history(const char *)
Definition: asterisk.c:3114
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: asterisk.c:1229
static int ast_all_zeros(const char *s)
Definition: asterisk.c:2269
ast_cli_command
calling arguments for new-style handlers.
Definition: cli.h:151

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

Referenced by asterisk_daemon().

◆ env_init()

static void env_init ( void  )
static

Definition at line 3498 of file asterisk.c.

3499 {
3500  setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
3501  setenv("AST_BUILD_HOST", ast_build_hostname, 1);
3502  setenv("AST_BUILD_DATE", ast_build_date, 1);
3503  setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
3504  setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
3505  setenv("AST_BUILD_OS", ast_build_os, 1);
3506  setenv("AST_BUILD_USER", ast_build_user, 1);
3507  setenv("AST_VERSION", ast_get_version(), 1);
3508 }
const char * ast_get_version(void)
Retrieve the Asterisk version string.
const char * ast_build_os
Definition: buildinfo.c:32
const char * ast_build_machine
Definition: buildinfo.c:31
const char * ast_build_hostname
Definition: buildinfo.c:29
const char * ast_build_user
Definition: buildinfo.c:34
const char * ast_build_date
Definition: buildinfo.c:33
const char * ast_build_kernel
Definition: buildinfo.c:30
int setenv(const char *name, const char *value, int overwrite)

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

Referenced by main().

◆ fdprint()

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

Definition at line 1072 of file asterisk.c.

1073 {
1074  return write(fd, s, strlen(s));
1075 }

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

◆ fdsend()

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

Definition at line 1066 of file asterisk.c.

1067 {
1068  return write(fd, s, strlen(s) + 1);
1069 }

Referenced by cli_complete(), and send_rasterisk_connect_commands().

◆ handle_abort_shutdown()

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

Definition at line 2472 of file asterisk.c.

2473 {
2474  switch (cmd) {
2475  case CLI_INIT:
2476  e->command = "core abort shutdown";
2477  e->usage =
2478  "Usage: core abort shutdown\n"
2479  " Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
2480  " call operations.\n";
2482  return NULL;
2483  case CLI_GENERATE:
2484  return NULL;
2485  }
2486 
2487  if (a->argc != e->args)
2488  return CLI_SHOWUSAGE;
2489 
2491 
2492  return CLI_SUCCESS;
2493 }
int ast_cancel_shutdown(void)
Cancel an existing shutdown and return to normal operation.
Definition: asterisk.c:1875
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_allow_at_shutdown(struct ast_cli_entry *e)
Allow a CLI command to be executed while Asterisk is shutting down.
Definition: main/cli.c:3060
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
int args
This gets set in ast_cli_register()
Definition: cli.h:185
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static struct test_val a

References a, ast_cli_entry::args, ast_cancel_shutdown(), ast_cli_allow_at_shutdown(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

◆ handle_bang()

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

Definition at line 2495 of file asterisk.c.

2496 {
2497  switch (cmd) {
2498  case CLI_INIT:
2499  e->command = "!";
2500  e->usage =
2501  "Usage: !<command>\n"
2502  " Executes a given shell command\n";
2503  return NULL;
2504  case CLI_GENERATE:
2505  return NULL;
2506  }
2507 
2508  return CLI_SUCCESS;
2509 }

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

◆ handle_clear_profile()

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

Definition at line 940 of file asterisk.c.

941 {
942  int i, min, max;
943  const char *search = NULL;
944  switch (cmd) {
945  case CLI_INIT:
946  e->command = "core clear profile";
947  e->usage = "Usage: core clear profile\n"
948  " clear profile information";
949  return NULL;
950  case CLI_GENERATE:
951  return NULL;
952  }
953 
954  if (prof_data == NULL)
955  return 0;
956 
958  for (i= min; i < max; i++) {
959  if (!search || strstr(prof_data->e[i].name, search)) {
960  prof_data->e[i].value = 0;
961  prof_data->e[i].events = 0;
962  }
963  }
964  return CLI_SUCCESS;
965 }
#define DEFINE_PROFILE_MIN_MAX_VALUES
Definition: asterisk.c:892
#define min(a, b)
Definition: f2c.h:197

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

◆ handle_restart_gracefully()

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

Definition at line 2430 of file asterisk.c.

2431 {
2432  switch (cmd) {
2433  case CLI_INIT:
2434  e->command = "core restart gracefully";
2435  e->usage =
2436  "Usage: core restart gracefully\n"
2437  " Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
2438  " restart when all active calls have ended.\n";
2440  return NULL;
2441  case CLI_GENERATE:
2442  return NULL;
2443  }
2444 
2445  if (a->argc != e->args)
2446  return CLI_SHOWUSAGE;
2447  quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
2448  return CLI_SUCCESS;
2449 }

References a, ast_cli_entry::args, ast_cli_allow_at_shutdown(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, quit_handler(), SHUTDOWN_NICE, and ast_cli_entry::usage.

◆ handle_restart_now()

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

Definition at line 2409 of file asterisk.c.

2410 {
2411  switch (cmd) {
2412  case CLI_INIT:
2413  e->command = "core restart now";
2414  e->usage =
2415  "Usage: core restart now\n"
2416  " Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
2417  " restart.\n";
2419  return NULL;
2420  case CLI_GENERATE:
2421  return NULL;
2422  }
2423 
2424  if (a->argc != e->args)
2425  return CLI_SHOWUSAGE;
2426  quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
2427  return CLI_SUCCESS;
2428 }

References a, ast_cli_entry::args, ast_cli_allow_at_shutdown(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, quit_handler(), SHUTDOWN_NORMAL, and ast_cli_entry::usage.

◆ handle_restart_when_convenient()

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

Definition at line 2451 of file asterisk.c.

2452 {
2453  switch (cmd) {
2454  case CLI_INIT:
2455  e->command = "core restart when convenient";
2456  e->usage =
2457  "Usage: core restart when convenient\n"
2458  " Causes Asterisk to perform a cold restart when all active calls have ended.\n";
2460  return NULL;
2461  case CLI_GENERATE:
2462  return NULL;
2463  }
2464 
2465  if (a->argc != e->args)
2466  return CLI_SHOWUSAGE;
2467  ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
2468  quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
2469  return CLI_SUCCESS;
2470 }

References a, ast_cli_entry::args, ast_cli(), ast_cli_allow_at_shutdown(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, quit_handler(), SHUTDOWN_REALLY_NICE, and ast_cli_entry::usage.

◆ handle_show_profile()

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

Definition at line 905 of file asterisk.c.

906 {
907  int i, min, max;
908  const char *search = NULL;
909  switch (cmd) {
910  case CLI_INIT:
911  e->command = "core show profile";
912  e->usage = "Usage: core show profile\n"
913  " show profile information";
914  return NULL;
915  case CLI_GENERATE:
916  return NULL;
917  }
918 
919  if (prof_data == NULL)
920  return 0;
921 
923  ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
925  ast_cli(a->fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events",
926  "Value", "Average", "Name");
927  for (i = min; i < max; i++) {
928  struct profile_entry *entry = &prof_data->e[i];
929  if (!search || strstr(entry->name, search))
930  ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n",
931  i,
932  (long)entry->scale,
933  (long)entry->events, (long long)entry->value,
934  (long long)(entry->events ? entry->value / entry->events : entry->value),
935  entry->name);
936  }
937  return CLI_SUCCESS;
938 }
Definition: search.h:40

References a, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, DEFINE_PROFILE_MIN_MAX_VALUES, profile_data::e, profile_data::entries, max, profile_data::max_size, min, NULL, and prof_data.

◆ handle_show_settings()

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

468 {
469  char buf[BUFSIZ];
470  struct ast_tm tm;
471  char eid_str[128];
472  struct rlimit limits;
473  char pbx_uuid[AST_UUID_STR_LEN];
474 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
475  char dir[PATH_MAX];
476 #endif
477 
478  switch (cmd) {
479  case CLI_INIT:
480  e->command = "core show settings";
481  e->usage = "Usage: core show settings\n"
482  " Show core misc settings";
483  return NULL;
484  case CLI_GENERATE:
485  return NULL;
486  }
487 
488  ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
489  ast_pbx_uuid_get(pbx_uuid, sizeof(pbx_uuid));
490 
491  ast_cli(a->fd, "\nPBX Core settings\n");
492  ast_cli(a->fd, "-----------------\n");
493  ast_cli(a->fd, " Version: %s\n", ast_get_version());
494  ast_cli(a->fd, " Build Options: %s\n", S_OR(ast_get_build_opts(), "(none)"));
496  ast_cli(a->fd, " Maximum calls: %d (Current %d)\n", ast_option_maxcalls, ast_active_channels());
497  else
498  ast_cli(a->fd, " Maximum calls: Not set\n");
499 
500  if (getrlimit(RLIMIT_NOFILE, &limits)) {
501  ast_cli(a->fd, " Maximum open file handles: Error because of %s\n", strerror(errno));
502  } else if (limits.rlim_cur == RLIM_INFINITY) {
503  ast_cli(a->fd, " Maximum open file handles: Unlimited\n");
504  } else if (limits.rlim_cur < ast_option_maxfiles) {
505  ast_cli(a->fd, " Maximum open file handles: %d (is) %d (requested)\n", (int) limits.rlim_cur, ast_option_maxfiles);
506  } else {
507  ast_cli(a->fd, " Maximum open file handles: %d\n", (int) limits.rlim_cur);
508  }
509 
510  ast_cli(a->fd, " Root console verbosity: %d\n", option_verbose);
511  ast_cli(a->fd, " Current console verbosity: %d\n", ast_verb_console_get());
512  ast_cli(a->fd, " Debug level: %d\n", option_debug);
513  ast_cli(a->fd, " Trace level: %d\n", option_trace);
514  ast_cli(a->fd, " Dump core on crash: %s\n", ast_opt_dump_core ? "Yes" : "No");
515  print_file(a->fd, " Core dump file: ", "/proc/sys/kernel/core_pattern");
516  ast_cli(a->fd, " Maximum load average: %lf\n", ast_option_maxload);
517 #if defined(HAVE_SYSINFO)
518  ast_cli(a->fd, " Minimum free memory: %ld MB\n", option_minmemfree);
519 #endif
520  if (ast_localtime(&ast_startuptime, &tm, NULL)) {
521  ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
522  ast_cli(a->fd, " Startup time: %s\n", buf);
523  }
524  if (ast_localtime(&ast_lastreloadtime, &tm, NULL)) {
525  ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
526  ast_cli(a->fd, " Last reload time: %s\n", buf);
527  }
528  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);
529  ast_cli(a->fd, " System name: %s\n", ast_config_AST_SYSTEM_NAME);
530  ast_cli(a->fd, " Entity ID: %s\n", eid_str);
531  ast_cli(a->fd, " PBX UUID: %s\n", pbx_uuid);
532  ast_cli(a->fd, " Default language: %s\n", ast_defaultlanguage);
533  ast_cli(a->fd, " Language prefix: %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
534  ast_cli(a->fd, " User name and group: %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
535 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
536 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
537 #define eaccess euidaccess
538 #endif
539  if (!getcwd(dir, sizeof(dir))) {
540  if (eaccess(dir, R_OK | X_OK | F_OK)) {
541  ast_cli(a->fd, " Running directory: %s\n", "Unable to access");
542  } else {
543  ast_cli(a->fd, " Running directory: %s (%s)\n", dir, "Unable to access");
544  }
545  } else {
546  ast_cli(a->fd, " Running directory: %s\n", dir);
547  }
548 #endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */
549  ast_cli(a->fd, " Executable includes: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
550  ast_cli(a->fd, " Transcode via SLIN: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
551  ast_cli(a->fd, " Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled");
552  ast_cli(a->fd, " Generic PLC: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");
553  ast_cli(a->fd, " Generic PLC on equal codecs: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC_ON_EQUAL_CODECS) ? "Enabled" : "Disabled");
554  ast_cli(a->fd, " Hide Msg Chan AMI events: %s\n", ast_opt_hide_messaging_ami_events ? "Enabled" : "Disabled");
555  ast_cli(a->fd, " Min DTMF duration:: %u\n", option_dtmfminduration);
556 #if !defined(LOW_MEMORY)
557  ast_cli(a->fd, " Cache media frames: %s\n", ast_opt_cache_media_frames ? "Enabled" : "Disabled");
558 #endif
559  ast_cli(a->fd, " RTP use dynamic payloads: %u\n", ast_option_rtpusedynamic);
560 
562  ast_cli(a->fd, " RTP dynamic payload types: %u,%u-%u\n",
566  ast_cli(a->fd, " RTP dynamic payload types: %u-%u,%u-%u\n",
569  } else {
570  ast_cli(a->fd, " RTP dynamic payload types: %u-%u\n",
572  }
573 
574  ast_cli(a->fd, "\n* Subsystems\n");
575  ast_cli(a->fd, " -------------\n");
576  ast_cli(a->fd, " Manager (AMI): %s\n", ast_manager_check_enabled() ? "Enabled" : "Disabled");
577  ast_cli(a->fd, " Web Manager (AMI/HTTP): %s\n", ast_webmanager_check_enabled() ? "Enabled" : "Disabled");
578  ast_cli(a->fd, " Call data records: %s\n", ast_cdr_is_enabled() ? "Enabled" : "Disabled");
579  ast_cli(a->fd, " Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
580 
581  /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues */
582 
583  ast_cli(a->fd, "\n* Directories\n");
584  ast_cli(a->fd, " -------------\n");
585  ast_cli(a->fd, " Configuration file: %s\n", ast_config_AST_CONFIG_FILE);
586  ast_cli(a->fd, " Configuration directory: %s\n", ast_config_AST_CONFIG_DIR);
587  ast_cli(a->fd, " Module directory: %s\n", ast_config_AST_MODULE_DIR);
588  ast_cli(a->fd, " Spool directory: %s\n", ast_config_AST_SPOOL_DIR);
589  ast_cli(a->fd, " Log directory: %s\n", ast_config_AST_LOG_DIR);
590  ast_cli(a->fd, " Run/Sockets directory: %s\n", ast_config_AST_RUN_DIR);
591  ast_cli(a->fd, " PID file: %s\n", ast_config_AST_PID);
592  ast_cli(a->fd, " VarLib directory: %s\n", ast_config_AST_VAR_DIR);
593  ast_cli(a->fd, " Data directory: %s\n", ast_config_AST_DATA_DIR);
594  ast_cli(a->fd, " ASTDB: %s\n", ast_config_AST_DB);
595  ast_cli(a->fd, " IAX2 Keys directory: %s\n", ast_config_AST_KEY_DIR);
596  ast_cli(a->fd, " AGI Scripts directory: %s\n", ast_config_AST_AGI_DIR);
597  ast_cli(a->fd, "\n\n");
598  return CLI_SUCCESS;
599 }
const char * ast_get_build_opts(void)
static int print_file(int fd, char *desc, const char *filename)
Print the contents of a file.
Definition: asterisk.c:450
int ast_cdr_is_enabled(void)
Return TRUE if CDR subsystem is enabled.
Definition: cdr.c:2883
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:499
int ast_manager_check_enabled(void)
Check if AMI is enabled.
Definition: manager.c:1956
int ast_webmanager_check_enabled(void)
Check if AMI/HTTP is enabled.
Definition: manager.c:1961
int ast_option_rtpusedynamic
Definition: options.c:88
int ast_option_maxfiles
Definition: options.c:81
int ast_option_maxcalls
Definition: options.c:79
double ast_option_maxload
Definition: options.c:77
unsigned int ast_option_rtpptdynamic
Definition: options.c:89
unsigned int option_dtmfminduration
Definition: options.c:83
long option_minmemfree
Definition: options.c:86
int option_trace
Definition: options.c:71
@ AST_OPT_FLAG_GENERIC_PLC
Definition: options.h:98
@ AST_OPT_FLAG_TRANSCODE_VIA_SLIN
Definition: options.h:60
@ AST_OPT_FLAG_EXEC_INCLUDES
Definition: options.h:40
@ AST_OPT_FLAG_TRANSMIT_SILENCE
Definition: options.h:74
@ AST_OPT_FLAG_GENERIC_PLC_ON_EQUAL_CODECS
Definition: options.h:100
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
Definition: main/config.c:3443
int ast_verb_console_get(void)
Get this thread's console verbosity level.
Definition: logger.c:2407
#define ast_opt_dump_core
Definition: options.h:119
int ast_language_is_prefix
The following variable controls the layout of localized sound files. If 0, use the historical layout ...
Definition: file.c:67
#define ast_opt_hide_messaging_ami_events
Definition: options.h:137
#define ast_opt_cache_media_frames
Definition: options.h:121
char ast_defaultlanguage[]
Definition: options.c:98
const char * ast_config_AST_KEY_DIR
Definition: options.c:161
const char * ast_config_AST_RUN_GROUP
Definition: options.c:169
const char * ast_config_AST_RUN_USER
Definition: options.c:168
const char * ast_config_AST_MODULE_DIR
Definition: options.c:153
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151
const char * ast_config_AST_SPOOL_DIR
Definition: options.c:154
const char * ast_config_AST_AGI_DIR
Definition: options.c:160
const char * ast_config_AST_VAR_DIR
Definition: options.c:157
const char * ast_config_AST_CONFIG_FILE
Definition: options.c:152
const char * ast_config_AST_LOG_DIR
Definition: options.c:159
const char * ast_config_AST_DB
Definition: options.c:165
#define AST_RTP_PT_LAST_REASSIGN
Definition: rtp_engine.h:95
#define AST_RTP_MAX_PT
Definition: rtp_engine.h:83
#define AST_RTP_PT_FIRST_DYNAMIC
Definition: rtp_engine.h:92
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
#define ast_test_flag(p, flag)
Definition: utils.h:63
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: main/utils.c:2735
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93

References a, ast_active_channels(), ast_build_date, ast_build_kernel, ast_build_machine, ast_build_os, ast_build_user, ast_cdr_is_enabled(), ast_cli(), ast_config_AST_AGI_DIR, ast_config_AST_CONFIG_DIR, ast_config_AST_CONFIG_FILE, ast_config_AST_DATA_DIR, ast_config_AST_DB, ast_config_AST_KEY_DIR, ast_config_AST_LOG_DIR, ast_config_AST_MODULE_DIR, ast_config_AST_PID, ast_config_AST_RUN_DIR, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SPOOL_DIR, ast_config_AST_SYSTEM_NAME, ast_config_AST_VAR_DIR, ast_defaultlanguage, ast_eid_default, ast_eid_to_str(), ast_get_build_opts(), ast_get_version(), ast_language_is_prefix, ast_lastreloadtime, ast_localtime(), ast_manager_check_enabled(), ast_opt_cache_media_frames, ast_opt_dump_core, AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_GENERIC_PLC, AST_OPT_FLAG_GENERIC_PLC_ON_EQUAL_CODECS, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_opt_hide_messaging_ami_events, ast_option_maxcalls, ast_option_maxfiles, ast_option_maxload, ast_option_rtpptdynamic, ast_option_rtpusedynamic, ast_options, ast_pbx_uuid_get(), ast_realtime_enabled(), AST_RTP_MAX_PT, AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_PT_LAST_REASSIGN, ast_startuptime, ast_strftime(), ast_test_flag, AST_UUID_STR_LEN, ast_verb_console_get(), ast_webmanager_check_enabled(), buf, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, errno, NULL, option_debug, option_dtmfminduration, option_minmemfree, option_trace, option_verbose, PATH_MAX, print_file(), S_OR, and ast_cli_entry::usage.

◆ handle_show_sysinfo()

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

Give an overview of system statistics.

Definition at line 667 of file asterisk.c.

668 {
669  uint64_t physmem, freeram;
670 #if defined(HAVE_SYSINFO) || defined(HAVE_SWAPCTL)
671  int totalswap = 0;
672  uint64_t freeswap = 0;
673 #endif
674  int nprocs = 0;
675  long uptime = 0;
676 #if defined(HAVE_SYSINFO)
677  struct sysinfo sys_info;
678 #elif defined(HAVE_SYSCTL)
679  static int pageshift;
680  struct vmtotal vmtotal;
681  struct timeval boottime;
682  time_t now;
683  int mib[2], pagesize;
684 #if defined(HAVE_SWAPCTL)
685  int usedswap = 0;
686 #endif
687  size_t len;
688 #endif
689 
690  switch (cmd) {
691  case CLI_INIT:
692  e->command = "core show sysinfo";
693  e->usage =
694  "Usage: core show sysinfo\n"
695  " List current system information.\n";
696  return NULL;
697  case CLI_GENERATE:
698  return NULL;
699  }
700 
701 #if defined(HAVE_SYSINFO)
702  sysinfo(&sys_info);
703  uptime = sys_info.uptime / 3600;
704  physmem = sys_info.totalram * sys_info.mem_unit;
705  freeram = (sys_info.freeram * sys_info.mem_unit) / 1024;
706  totalswap = (sys_info.totalswap * sys_info.mem_unit) / 1024;
707  freeswap = (sys_info.freeswap * sys_info.mem_unit) / 1024;
708  nprocs = sys_info.procs;
709 #elif defined(HAVE_SYSCTL)
710  /* calculate the uptime by looking at boottime */
711  time(&now);
712  mib[0] = CTL_KERN;
713  mib[1] = KERN_BOOTTIME;
714  len = sizeof(boottime);
715  if (sysctl(mib, 2, &boottime, &len, NULL, 0) != -1) {
716  uptime = now - boottime.tv_sec;
717  }
718  uptime = uptime/3600;
719  /* grab total physical memory */
720  mib[0] = CTL_HW;
721 #if defined(HW_PHYSMEM64)
722  mib[1] = HW_PHYSMEM64;
723 #else
724  mib[1] = HW_PHYSMEM;
725 #endif
726  len = sizeof(physmem);
727  sysctl(mib, 2, &physmem, &len, NULL, 0);
728 
729  pagesize = getpagesize();
730  pageshift = 0;
731  while (pagesize > 1) {
732  pageshift++;
733  pagesize >>= 1;
734  }
735 
736  /* we only need the amount of log(2)1024 for our conversion */
737  pageshift -= 10;
738 
739  /* grab vm totals */
740  mib[0] = CTL_VM;
741  mib[1] = VM_METER;
742  len = sizeof(vmtotal);
743  sysctl(mib, 2, &vmtotal, &len, NULL, 0);
744  freeram = (vmtotal.t_free << pageshift);
745  /* generate swap usage and totals */
746 #if defined(HAVE_SWAPCTL)
747  swapmode(&usedswap, &totalswap);
748  freeswap = (totalswap - usedswap);
749 #endif
750  /* grab number of processes */
751 #if defined(__OpenBSD__)
752  mib[0] = CTL_KERN;
753  mib[1] = KERN_NPROCS;
754  len = sizeof(nprocs);
755  sysctl(mib, 2, &nprocs, &len, NULL, 0);
756 #endif
757 #endif
758 
759  ast_cli(a->fd, "\nSystem Statistics\n");
760  ast_cli(a->fd, "-----------------\n");
761  ast_cli(a->fd, " System Uptime: %ld hours\n", uptime);
762  ast_cli(a->fd, " Total RAM: %" PRIu64 " KiB\n", physmem / 1024);
763  ast_cli(a->fd, " Free RAM: %" PRIu64 " KiB\n", freeram);
764 #if defined(HAVE_SYSINFO)
765  ast_cli(a->fd, " Buffer RAM: %" PRIu64 " KiB\n", ((uint64_t) sys_info.bufferram * sys_info.mem_unit) / 1024);
766 #endif
767 #if defined(HAVE_SYSINFO) || defined(HAVE_SWAPCTL)
768  ast_cli(a->fd, " Total Swap Space: %d KiB\n", totalswap);
769  ast_cli(a->fd, " Free Swap Space: %" PRIu64 " KiB\n\n", freeswap);
770 #endif
771  ast_cli(a->fd, " Number of Processes: %d \n\n", nprocs);
772  return CLI_SUCCESS;
773 }

References a, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, len(), NULL, and ast_cli_entry::usage.

◆ handle_show_threads()

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

Definition at line 601 of file asterisk.c.

602 {
603  int count = 0;
604  struct thread_list_t *cur;
605  switch (cmd) {
606  case CLI_INIT:
607  e->command = "core show threads";
608  e->usage =
609  "Usage: core show threads\n"
610  " List threads currently active in the system.\n";
611  return NULL;
612  case CLI_GENERATE:
613  return NULL;
614  }
615 
617  AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
618  ast_cli(a->fd, "%p %d %s\n", (void *)cur->id, cur->lwp, cur->name);
619  count++;
620  }
622  ast_cli(a->fd, "%d threads listed.\n", count);
623  return CLI_SUCCESS;
624 }
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494

References a, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

◆ handle_stop_gracefully()

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

Definition at line 2367 of file asterisk.c.

2368 {
2369  switch (cmd) {
2370  case CLI_INIT:
2371  e->command = "core stop gracefully";
2372  e->usage =
2373  "Usage: core stop gracefully\n"
2374  " Causes Asterisk to not accept new calls, and exit when all\n"
2375  " active calls have terminated normally.\n";
2377  return NULL;
2378  case CLI_GENERATE:
2379  return NULL;
2380  }
2381 
2382  if (a->argc != e->args)
2383  return CLI_SHOWUSAGE;
2384  quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
2385  return CLI_SUCCESS;
2386 }

References a, ast_cli_entry::args, ast_cli_allow_at_shutdown(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, quit_handler(), SHUTDOWN_NICE, and ast_cli_entry::usage.

◆ handle_stop_now()

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

Definition at line 2347 of file asterisk.c.

2348 {
2349  switch (cmd) {
2350  case CLI_INIT:
2351  e->command = "core stop now";
2352  e->usage =
2353  "Usage: core stop now\n"
2354  " Shuts down a running Asterisk immediately, hanging up all active calls .\n";
2356  return NULL;
2357  case CLI_GENERATE:
2358  return NULL;
2359  }
2360 
2361  if (a->argc != e->args)
2362  return CLI_SHOWUSAGE;
2363  quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
2364  return CLI_SUCCESS;
2365 }

References a, ast_cli_entry::args, ast_cli_allow_at_shutdown(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, quit_handler(), SHUTDOWN_NORMAL, and ast_cli_entry::usage.

◆ handle_stop_when_convenient()

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

Definition at line 2388 of file asterisk.c.

2389 {
2390  switch (cmd) {
2391  case CLI_INIT:
2392  e->command = "core stop when convenient";
2393  e->usage =
2394  "Usage: core stop when convenient\n"
2395  " Causes Asterisk to perform a shutdown when all active calls have ended.\n";
2397  return NULL;
2398  case CLI_GENERATE:
2399  return NULL;
2400  }
2401 
2402  if (a->argc != e->args)
2403  return CLI_SHOWUSAGE;
2404  ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
2405  quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
2406  return CLI_SUCCESS;
2407 }

References a, ast_cli_entry::args, ast_cli(), ast_cli_allow_at_shutdown(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, quit_handler(), SHUTDOWN_REALLY_NICE, and ast_cli_entry::usage.

◆ handle_version()

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

Definition at line 2326 of file asterisk.c.

2327 {
2328  switch (cmd) {
2329  case CLI_INIT:
2330  e->command = "core show version";
2331  e->usage =
2332  "Usage: core show version\n"
2333  " Shows Asterisk version information.\n";
2334  return NULL;
2335  case CLI_GENERATE:
2336  return NULL;
2337  }
2338 
2339  if (a->argc != 3)
2340  return CLI_SHOWUSAGE;
2341  ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
2344  return CLI_SUCCESS;
2345 }

References a, 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, NULL, and ast_cli_entry::usage.

◆ has_priority()

static int has_priority ( void  )
static

Check whether we were set to high(er) priority.

Definition at line 1772 of file asterisk.c.

1773 {
1774  /* Neither of these calls should fail with these arguments. */
1775 #ifdef __linux__
1776  /* For SCHED_OTHER, SCHED_BATCH and SCHED_IDLE, this will return
1777  * 0. For the realtime priorities SCHED_RR and SCHED_FIFO, it
1778  * will return something >= 1. */
1779  return sched_getscheduler(0);
1780 #else
1781  /* getpriority() can return a value in -20..19 (or even -INF..20)
1782  * where negative numbers are high priority. We don't bother
1783  * checking errno. If the query fails and it returns -1, we'll
1784  * assume that we're running at high prio; a safe assumption
1785  * that will enable the resource starvation monitor (canary)
1786  * just in case. */
1787  return (getpriority(PRIO_PROCESS, 0) < 0);
1788 #endif
1789 }

Referenced by ast_ari_validate_dialplan_cep(), and asterisk_daemon().

◆ listener()

static void* listener ( void *  unused)
static

Definition at line 1512 of file asterisk.c.

1513 {
1514  struct sockaddr_un sunaddr;
1515  int s;
1516  socklen_t len;
1517  int x;
1518  int poll_result;
1519  struct pollfd fds[1];
1520 
1521  for (;;) {
1522  if (ast_socket < 0) {
1523  return NULL;
1524  }
1525  fds[0].fd = ast_socket;
1526  fds[0].events = POLLIN;
1527  poll_result = ast_poll(fds, 1, -1);
1528  pthread_testcancel();
1529  if (poll_result < 0) {
1530  if (errno != EINTR) {
1531  ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
1532  }
1533  continue;
1534  }
1535  len = sizeof(sunaddr);
1536  s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
1537  if (s < 0) {
1538  if (errno != EINTR)
1539  ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
1540  } else {
1541 #if defined(SO_PASSCRED)
1542  int sckopt = 1;
1543  /* turn on socket credentials passing. */
1544  if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
1545  ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
1546  close(s);
1547  } else
1548 #endif
1549  {
1550  for (x = 0; x < AST_MAX_CONNECTS; x++) {
1551  if (consoles[x].fd >= 0) {
1552  continue;
1553  }
1554  if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
1555  ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
1556  fdprint(s, "Server failed to create pipe\n");
1557  close(s);
1558  break;
1559  }
1560  ast_fd_set_flags(consoles[x].p[1], O_NONBLOCK);
1561  consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
1562  /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
1563  to know if the user didn't send the credentials. */
1564  consoles[x].uid = -2;
1565  consoles[x].gid = -2;
1566  /* Server default of remote console verbosity level is OFF. */
1567  consoles[x].option_verbose = 0;
1568  consoles[x].fd = s;
1570  consoles[x].fd = -1;
1571  ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
1572  close(consoles[x].p[0]);
1573  close(consoles[x].p[1]);
1574  fdprint(s, "Server failed to spawn thread\n");
1575  close(s);
1576  }
1577  break;
1578  }
1579  if (x >= AST_MAX_CONNECTS) {
1580  fdprint(s, "No more connections allowed\n");
1581  ast_log(LOG_WARNING, "No more connections allowed\n");
1582  close(s);
1583  } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
1584  ast_verb(3, "Remote UNIX connection\n");
1585  }
1586  }
1587  }
1588  }
1589  return NULL;
1590 }
static void * netconsole(void *vconsole)
Definition: asterisk.c:1422
#define ast_opt_hide_connect
Definition: options.h:132
int uid
Definition: asterisk.c:321
int gid
Definition: asterisk.c:322
int option_verbose
Definition: asterisk.c:325
#define ast_fd_set_flags(fd, flags)
Set flags on the given file descriptor.
Definition: utils.h:1034
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:592

References AF_LOCAL, ast_fd_set_flags, 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(), NULL, console::option_verbose, and console::uid.

Referenced by __allocate_taskprocessor(), ast_makesocket(), ast_taskprocessor_create_with_listener(), ast_taskprocessor_get(), ast_taskprocessor_listener_alloc(), ast_taskprocessor_listener_get_tps(), ast_taskprocessor_listener_get_user_data(), AST_TEST_DEFINE(), ast_threadpool_create(), ast_threadpool_listener_alloc(), ast_threadpool_listener_get_user_data(), ast_threadpool_serializer_group(), default_listener_pvt_dtor(), default_listener_start(), default_task_pushed(), default_tps_processing_function(), listener_check(), listener_shutdown(), serializer_shutdown(), serializer_task_pushed(), taskprocessor_listener_dtor(), test_emptied(), test_state_changed(), test_task_pushed(), threadpool_tps_emptied(), and threadpool_tps_task_pushed().

◆ main()

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

Check for options

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

Definition at line 3528 of file asterisk.c.

3529 {
3530  int c;
3531  int x;
3532  int isroot = 1, rundir_exists = 0;
3533  RAII_VAR(char *, runuser, NULL, ast_free);
3534  RAII_VAR(char *, rungroup, NULL, ast_free);
3535  RAII_VAR(char *, xarg, NULL, ast_free);
3536  struct rlimit l;
3537  static const char *getopt_settings = "BC:cde:FfG:ghIiL:M:mnpqRrs:TtU:VvWXx:";
3538 
3539  /* Remember original args for restart */
3540  if (argc > ARRAY_LEN(_argv) - 1) {
3541  fprintf(stderr, "Truncating argument size to %d\n", (int)ARRAY_LEN(_argv) - 1);
3542  argc = ARRAY_LEN(_argv) - 1;
3543  }
3544  for (x = 0; x < argc; x++)
3545  _argv[x] = argv[x];
3546  _argv[x] = NULL;
3547 
3548  if (geteuid() != 0)
3549  isroot = 0;
3550 
3551  /* if the progname is rasterisk consider it a remote console */
3552  if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
3554  }
3555  ast_mainpid = getpid();
3556 
3557  /* Process command-line options that effect asterisk.conf load. */
3558  while ((c = getopt(argc, argv, getopt_settings)) != -1) {
3559  switch (c) {
3560  case 'X':
3562  break;
3563  case 'C':
3564  set_asterisk_conf_path(optarg);
3565  break;
3566  case 'd':
3567  option_debug++;
3568  break;
3569  case 'h':
3570  show_cli_help();
3571  exit(0);
3572  case 'R':
3573  case 'r':
3574  case 'x':
3575  /* ast_opt_remote is checked during config load. This is only part of what
3576  * these options do, see the second loop for the rest of the actions. */
3578  break;
3579  case 'V':
3580  show_version();
3581  exit(0);
3582  case 'v':
3583  option_verbose++;
3584  break;
3585  case '?':
3586  exit(1);
3587  }
3588  }
3589 
3590  /* Initialize env so it is available if #exec is used in asterisk.conf. */
3591  env_init();
3592 
3594 
3595  /* Update env to include any systemname that was set. */
3596  env_init();
3597 
3598  /*! \brief Check for options
3599  *
3600  * \todo Document these options
3601  */
3602  optind = 1;
3603  while ((c = getopt(argc, argv, getopt_settings)) != -1) {
3604  /*!\note Please keep the ordering here to alphabetical, capital letters
3605  * first. This will make it easier in the future to select unused
3606  * option flags for new features. */
3607  switch (c) {
3608  case 'B': /* Force black background */
3611  break;
3612  case 'X':
3613  /* The command-line -X option enables #exec for asterisk.conf only. */
3614  break;
3615  case 'C':
3616  /* already processed. */
3617  break;
3618  case 'c':
3620  break;
3621  case 'd':
3622  /* already processed. */
3623  break;
3624 #if defined(HAVE_SYSINFO)
3625  case 'e':
3626  if ((sscanf(&optarg[1], "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
3627  option_minmemfree = 0;
3628  }
3629  break;
3630 #endif
3631 #if HAVE_WORKING_FORK
3632  case 'F':
3634  break;
3635  case 'f':
3637  break;
3638 #endif
3639  case 'G':
3640  rungroup = ast_strdup(optarg);
3641  break;
3642  case 'g':
3644  break;
3645  case 'h':
3646  /* already processed. */
3647  break;
3648  case 'I':
3649  fprintf(stderr,
3650  "NOTICE: The -I option is no longer needed.\n"
3651  " It will always be enabled if you have a timing module loaded.\n");
3652  break;
3653  case 'i':
3655  break;
3656  case 'L':
3657  if ((sscanf(optarg, "%30lf", &ast_option_maxload) != 1) || (ast_option_maxload < 0.0)) {
3658  ast_option_maxload = 0.0;
3659  }
3660  break;
3661  case 'M':
3662  if ((sscanf(optarg, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) {
3663  ast_option_maxcalls = 0;
3664  }
3665  break;
3666  case 'm':
3668  break;
3669  case 'n':
3671  break;
3672  case 'p':
3674  break;
3675  case 'q':
3677  break;
3678  case 'R':
3680  break;
3681  case 'r':
3683  break;
3684  case 's':
3685  if (ast_opt_remote) {
3686  set_socket_path(optarg);
3687  }
3688  break;
3689  case 'T':
3691  break;
3692  case 't':
3694  break;
3695  case 'U':
3696  runuser = ast_strdup(optarg);
3697  break;
3698  case 'V':
3699  case 'v':
3700  /* already processed. */
3701  break;
3702  case 'W': /* White background */
3705  break;
3706  case 'x':
3707  /* -r is implied by -x so set the flags -r sets as well. */
3709 
3711  xarg = ast_strdup(optarg);
3712  break;
3713  case '?':
3714  /* already processed. */
3715  break;
3716  }
3717  }
3718 
3719  if (ast_opt_remote) {
3720  int didwarn = 0;
3721  optind = 1;
3722 
3723  /* Not all options can be used with remote console. Warn if they're used. */
3724  while ((c = getopt(argc, argv, getopt_settings)) != -1) {
3725  switch (c) {
3726  /* okay to run with remote console */
3727  case 'B': /* force black background */
3728  case 'd': /* debug */
3729  case 'h': /* help */
3730  case 'I': /* obsolete timing option: warning already thrown if used */
3731  case 'L': /* max load */
3732  case 'M': /* max calls */
3733  case 'R': /* reconnect */
3734  case 'r': /* remote */
3735  case 's': /* set socket path */
3736  case 'V': /* version */
3737  case 'v': /* verbose */
3738  case 'W': /* white background */
3739  case 'x': /* remote execute */
3740  case '?': /* ? */
3741  break;
3742  /* can only be run when Asterisk is starting */
3743  case 'X': /* enables #exec for asterisk.conf only. */
3744  case 'C': /* set config path */
3745  case 'c': /* foreground console */
3746  case 'e': /* minimum memory free */
3747  case 'F': /* always fork */
3748  case 'f': /* no fork */
3749  case 'G': /* run group */
3750  case 'g': /* dump core */
3751  case 'i': /* init keys */
3752  case 'm': /* mute */
3753  case 'n': /* no color */
3754  case 'p': /* high priority */
3755  case 'q': /* quiet */
3756  case 'T': /* timestamp */
3757  case 't': /* cache record files */
3758  case 'U': /* run user */
3759  fprintf(stderr, "'%c' option is not compatible with remote console mode and has no effect.\n", c);
3760  didwarn = 1;
3761  }
3762  }
3763  if (didwarn) {
3764  fprintf(stderr, "\n"); /* if any warnings print out, make them stand out */
3765  }
3766  }
3767 
3768  /* For remote connections, change the name of the remote connection.
3769  * We do this for the benefit of init scripts (which need to know if/when
3770  * the main asterisk process has died yet). */
3771  if (ast_opt_remote) {
3772  strcpy(argv[0], "rasterisk");
3773  for (x = 1; x < argc; x++) {
3774  argv[x] = argv[0] + 10;
3775  }
3776  }
3777 
3779  fprintf(stderr, "The 'languageprefix' option in asterisk.conf is deprecated; in a future release it will be removed, and your sound files will need to be organized in the 'new style' language layout.\n");
3780  }
3781 
3783  fprintf(stderr, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
3785  }
3786 
3787  if (ast_opt_dump_core) {
3788  memset(&l, 0, sizeof(l));
3789  l.rlim_cur = RLIM_INFINITY;
3790  l.rlim_max = RLIM_INFINITY;
3791  if (setrlimit(RLIMIT_CORE, &l)) {
3792  fprintf(stderr, "Unable to disable core size resource limit: %s\n", strerror(errno));
3793  }
3794  }
3795 
3796  if (getrlimit(RLIMIT_NOFILE, &l)) {
3797  fprintf(stderr, "Unable to check file descriptor limit: %s\n", strerror(errno));
3798  }
3799 
3800 #if !defined(CONFIGURE_RAN_AS_ROOT)
3801  /* Check if select(2) will run with more file descriptors */
3802  do {
3803  int fd, fd2;
3804  ast_fdset readers;
3805  struct timeval tv = { 0, };
3806 
3807  if (l.rlim_cur <= FD_SETSIZE) {
3808  /* The limit of select()able FDs is irrelevant, because we'll never
3809  * open one that high. */
3810  break;
3811  }
3812 
3813  if (!(fd = open("/dev/null", O_RDONLY))) {
3814  fprintf(stderr, "Cannot open a file descriptor at boot? %s\n", strerror(errno));
3815  break; /* XXX Should we exit() here? XXX */
3816  }
3817 
3818  fd2 = ((l.rlim_cur > sizeof(readers) * 8) ? sizeof(readers) * 8 : l.rlim_cur) - 1;
3819  if (dup2(fd, fd2) < 0) {
3820  fprintf(stderr, "Cannot open maximum file descriptor %d at boot? %s\n", fd2, strerror(errno));
3821  close(fd);
3822  break;
3823  }
3824 
3825  FD_ZERO(&readers);
3826  FD_SET(fd2, &readers);
3827  if (ast_select(fd2 + 1, &readers, NULL, NULL, &tv) < 0) {
3828  fprintf(stderr, "Maximum select()able file descriptor is %d\n", FD_SETSIZE);
3829  }
3830  ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
3831  close(fd);
3832  close(fd2);
3833  } while (0);
3834 #elif defined(HAVE_VARIABLE_FDSET)
3835  ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
3836 #endif /* !defined(CONFIGURE_RAN_AS_ROOT) */
3837 
3838  if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
3840  if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
3842 
3843  /* Must install this signal handler up here to ensure that if the canary
3844  * fails to execute that it doesn't kill the Asterisk process.
3845  */
3846  sigaction(SIGCHLD, &child_handler, NULL);
3847 
3848  /* It's common on some platforms to clear /var/run at boot. Create the
3849  * socket file directory before we drop privileges. */
3850  if (mkdir(ast_config_AST_RUN_DIR, 0755)) {
3851  if (errno == EEXIST) {
3852  rundir_exists = 1;
3853  } else {
3854  fprintf(stderr, "Unable to create socket file directory. Remote consoles will not be able to connect! (%s)\n", strerror(x));
3855  }
3856  }
3857 
3858 #ifndef __CYGWIN__
3859 
3860  if (isroot) {
3862  }
3863 
3864  if (isroot && rungroup) {
3865  struct group *gr;
3866  gr = getgrnam(rungroup);
3867  if (!gr) {
3868  fprintf(stderr, "No such group '%s'!\n", rungroup);
3869  exit(1);
3870  }
3871  if (!rundir_exists && chown(ast_config_AST_RUN_DIR, -1, gr->gr_gid)) {
3872  fprintf(stderr, "Unable to chgrp run directory to %d (%s)\n", (int) gr->gr_gid, rungroup);
3873  }
3874  if (setgid(gr->gr_gid)) {
3875  fprintf(stderr, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
3876  exit(1);
3877  }
3878  if (setgroups(0, NULL)) {
3879  fprintf(stderr, "Unable to drop unneeded groups\n");
3880  exit(1);
3881  }
3882  }
3883 
3884  if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
3885 #ifdef HAVE_CAP
3886  int has_cap = 1;
3887 #endif /* HAVE_CAP */
3888  struct passwd *pw;
3889  pw = getpwnam(runuser);
3890  if (!pw) {
3891  fprintf(stderr, "No such user '%s'!\n", runuser);
3892  exit(1);
3893  }
3894  if (chown(ast_config_AST_RUN_DIR, pw->pw_uid, -1)) {
3895  fprintf(stderr, "Unable to chown run directory to %d (%s)\n", (int) pw->pw_uid, runuser);
3896  }
3897 #ifdef HAVE_CAP
3898  if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
3899  ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
3900  has_cap = 0;
3901  }
3902 #endif /* HAVE_CAP */
3903  if (!isroot && pw->pw_uid != geteuid()) {
3904  fprintf(stderr, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
3905  exit(1);
3906  }
3907  if (!rungroup) {
3908  if (setgid(pw->pw_gid)) {
3909  fprintf(stderr, "Unable to setgid to %d!\n", (int)pw->pw_gid);
3910  exit(1);
3911  }
3912  if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
3913  fprintf(stderr, "Unable to init groups for '%s'\n", runuser);
3914  exit(1);
3915  }
3916  }
3917  if (setuid(pw->pw_uid)) {
3918  fprintf(stderr, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
3919  exit(1);
3920  }
3921 #ifdef HAVE_CAP
3922  if (has_cap) {
3923  cap_t cap;
3924 
3925  cap = cap_from_text("cap_net_admin=eip");
3926 
3927  if (cap_set_proc(cap)) {
3928  fprintf(stderr, "Unable to install capabilities.\n");
3929  }
3930  if (cap_free(cap)) {
3931  fprintf(stderr, "Unable to drop capabilities.\n");
3932  }
3933  }
3934 #endif /* HAVE_CAP */
3935  }
3936 
3937 #endif /* __CYGWIN__ */
3938 
3939 #ifdef linux
3940  if (geteuid() && ast_opt_dump_core) {
3941  if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
3942  fprintf(stderr, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
3943  }
3944  }
3945 #endif
3946 
3947  {
3948 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
3949  char dir[PATH_MAX];
3950  if (!getcwd(dir, sizeof(dir)) || eaccess(dir, R_OK | X_OK | F_OK)) {
3951  fprintf(stderr, "Unable to access the running directory (%s). Changing to '/' for compatibility.\n", strerror(errno));
3952  /* If we cannot access the CWD, then we couldn't dump core anyway,
3953  * so chdir("/") won't break anything. */
3954  if (chdir("/")) {
3955  /* chdir(/) should never fail, so this ends up being a no-op */
3956  fprintf(stderr, "chdir(\"/\") failed?!! %s\n", strerror(errno));
3957  }
3958  } else
3959 #endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */
3961  /* Backgrounding, but no cores, so chdir won't break anything. */
3962  if (chdir("/")) {
3963  fprintf(stderr, "Unable to chdir(\"/\") ?!! %s\n", strerror(errno));
3964  }
3965  }
3966  }
3967 
3968  /* Initial value of the maximum active system verbosity level. */
3970 
3971  if (ast_sd_get_fd_un(SOCK_STREAM, ast_config_AST_SOCKET) > 0) {
3972  ast_socket_is_sd = 1;
3973  }
3974 
3975  /* DO NOT perform check for existing daemon if systemd has CLI socket activation */
3976  if (!ast_socket_is_sd && ast_tryconnect()) {
3977  /* One is already running */
3978  if (ast_opt_remote) {
3979  multi_thread_safe = 1;
3980  if (ast_opt_exec) {
3981  ast_remotecontrol(xarg);
3982  quit_handler(0, SHUTDOWN_FAST, 0);
3983  exit(0);
3984  }
3985  ast_term_init();
3986  printf("%s", term_end());
3987  fflush(stdout);
3988 
3989  print_intro_message(runuser, rungroup);
3990  printf("%s", term_quit());
3992  quit_handler(0, SHUTDOWN_FAST, 0);
3993  exit(0);
3994  } else {
3995  fprintf(stderr, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
3996  printf("%s", term_quit());
3997  exit(1);
3998  }
3999  } else if (ast_opt_remote || ast_opt_exec) {
4000  fprintf(stderr, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
4001  printf("%s", term_quit());
4002  exit(1);
4003  }
4004 
4005 #ifdef HAVE_CAP
4006  child_cap = cap_from_text("cap_net_admin-eip");
4007 #endif
4008  /* Not a remote console? Start the daemon. */
4009  asterisk_daemon(isroot, runuser, rungroup);
4010 #ifdef HAS_CAP
4011  cap_free(child_cap);
4012 #endif
4013  return 0;
4014 }
void load_asterisk_conf(void)
Definition: options.c:210
void set_asterisk_conf_path(const char *path)
Definition: options.c:200
void set_socket_path(const char *path)
Definition: options.c:205
static int show_version(void)
Definition: asterisk.c:3327
static struct sigaction child_handler
Definition: asterisk.c:1753
static void asterisk_daemon(int isroot, const char *runuser, const char *rungroup)
Definition: asterisk.c:4029
static void ast_remotecontrol(char *data)
Definition: asterisk.c:3179
static int show_cli_help(void)
Definition: asterisk.c:3333
static void env_init(void)
Definition: asterisk.c:3498
int ast_verb_sys_level
Definition: options.c:64
@ AST_OPT_FLAG_NO_COLOR
Definition: options.h:56
@ AST_OPT_FLAG_NO_FORK
Definition: options.h:42
@ AST_OPT_FLAG_ALWAYS_FORK
Definition: options.h:80
@ AST_OPT_FLAG_QUIET
Definition: options.h:44
@ AST_OPT_FLAG_MUTE
Definition: options.h:82
@ AST_OPT_FLAG_TIMESTAMP
Definition: options.h:68
@ AST_OPT_FLAG_EXEC
Definition: options.h:54
@ AST_OPT_FLAG_CACHE_RECORD_FILES
Definition: options.h:66
@ AST_OPT_FLAG_INIT_KEYS
Definition: options.h:50
@ AST_OPT_FLAG_CONSOLE
Definition: options.h:46
@ AST_OPT_FLAG_FORCE_BLACK_BACKGROUND
Definition: options.h:92
@ AST_OPT_FLAG_LIGHT_BACKGROUND
Definition: options.h:88
@ AST_OPT_FLAG_REMOTE
Definition: options.h:52
@ AST_OPT_FLAG_DUMP_CORE
Definition: options.h:64
@ AST_OPT_FLAG_RECONNECT
Definition: options.h:72
#define FD_SET(fd, fds)
Definition: select.h:58
#define ast_FDMAX
Definition: select.h:41
unsigned int ast_FD_SETSIZE
Definition: poll.c:86
static int ast_select(int nfds, ast_fdset *rfds, ast_fdset *wfds, ast_fdset *efds, struct timeval *tvp)
Waits for activity on a group of channels.
Definition: select.h:79
#define FD_ZERO(a)
Definition: select.h:49
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:936

References _argv, ARRAY_LEN, ast_clear_flag, ast_config_AST_RUN_DIR, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SOCKET, ast_FD_SETSIZE, ast_FDMAX, ast_free, ast_language_is_prefix, ast_log, ast_mainpid, ast_opt_always_fork, ast_opt_console, ast_opt_dump_core, ast_opt_exec, AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC, AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_LIGHT_BACKGROUND, AST_OPT_FLAG_MUTE, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, 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_option_maxcalls, ast_option_maxload, ast_options, ast_remotecontrol(), ast_sd_get_fd_un(), ast_select(), ast_set_flag, ast_set_priority(), ast_socket_is_sd, ast_strdup, ast_strlen_zero(), ast_term_init(), ast_test_flag, ast_tryconnect(), ast_verb_sys_level, asterisk_daemon(), c, child_handler, env_init(), errno, FD_SET, FD_ZERO, load_asterisk_conf(), LOG_WARNING, multi_thread_safe, NULL, option_debug, option_minmemfree, option_verbose, PATH_MAX, print_intro_message(), quit_handler(), RAII_VAR, set_asterisk_conf_path(), set_socket_path(), show_cli_help(), show_version(), SHUTDOWN_FAST, term_end(), and term_quit().

◆ main_atexit()

static void main_atexit ( void  )
static

Definition at line 3523 of file asterisk.c.

3524 {
3526 }
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30

References ARRAY_LEN, ast_cli_unregister_multiple(), and cli_asterisk.

Referenced by asterisk_daemon().

◆ monitor_sig_flags()

static void* monitor_sig_flags ( void *  unused)
static

Definition at line 3406 of file asterisk.c.

3407 {
3408  for (;;) {
3409  struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
3410 
3411  ast_poll(&p, 1, -1);
3412  if (sig_flags.need_reload) {
3413  sig_flags.need_reload = 0;
3415  }
3416  if (sig_flags.need_quit) {
3417  sig_flags.need_quit = 0;
3418  if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
3419  sig_flags.need_quit_handler = 1;
3420  pthread_kill(consolethread, SIGURG);
3421  } else {
3423  }
3424  }
3426  }
3427 
3428  return NULL;
3429 }
ast_alert_status_t ast_alertpipe_read(int alert_pipe[2])
Read an event from an alert pipe.
Definition: alertpipe.c:102
enum ast_module_reload_result ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:1562

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

Referenced by asterisk_daemon().

◆ netconsole()

static void* netconsole ( void *  vconsole)
static

Definition at line 1422 of file asterisk.c.

1423 {
1424  struct console *con = vconsole;
1425  char hostname[MAXHOSTNAMELEN] = "";
1426  char inbuf[512];
1427  char outbuf[512];
1428  const char * const end_buf = inbuf + sizeof(inbuf);
1429  char *start_read = inbuf;
1430  int res;
1431  struct pollfd fds[2];
1432 
1433  if (gethostname(hostname, sizeof(hostname)-1))
1434  ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
1435  snprintf(outbuf, sizeof(outbuf), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
1436  fdprint(con->fd, outbuf);
1438  for (;;) {
1439  fds[0].fd = con->fd;
1440  fds[0].events = POLLIN;
1441  fds[0].revents = 0;
1442  fds[1].fd = con->p[0];
1443  fds[1].events = POLLIN;
1444  fds[1].revents = 0;
1445 
1446  res = ast_poll(fds, 2, -1);
1447  if (res < 0) {
1448  if (errno != EINTR)
1449  ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
1450  continue;
1451  }
1452  if (fds[0].revents) {
1453  int cmds_read, bytes_read;
1454  if ((bytes_read = read_credentials(con->fd, start_read, end_buf - start_read, con)) < 1) {
1455  break;
1456  }
1457  /* XXX This will only work if it is the first command, and I'm not sure fixing it is worth the effort. */
1458  if (strncmp(inbuf, "cli quit after ", 15) == 0) {
1459  ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read - 15, inbuf + 15);
1460  break;
1461  }
1462  /* ast_cli_command_multiple_full will only process individual commands terminated by a
1463  * NULL and not trailing partial commands. */
1464  if (!(cmds_read = ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read + start_read - inbuf, inbuf))) {
1465  /* No commands were read. We either have a short read on the first command
1466  * with space left, or a command that is too long */
1467  if (start_read + bytes_read < end_buf) {
1468  start_read += bytes_read;
1469  } else {
1470  ast_log(LOG_ERROR, "Command too long! Skipping\n");
1471  start_read = inbuf;
1472  }
1473  continue;
1474  }
1475  if (start_read[bytes_read - 1] == '\0') {
1476  /* The read ended on a command boundary, start reading again at the head of inbuf */
1477  start_read = inbuf;
1478  continue;
1479  }
1480  /* If we get this far, we have left over characters that have not been processed.
1481  * Advance to the character after the last command read by ast_cli_command_multiple_full.
1482  * We are guaranteed to have at least cmds_read NULLs */
1483  while (cmds_read-- && (start_read = strchr(start_read, '\0'))) {
1484  start_read++;
1485  }
1486  memmove(inbuf, start_read, end_buf - start_read);
1487  start_read = end_buf - start_read + inbuf;
1488  }
1489  if (fds[1].revents) {
1490  res = read_credentials(con->p[0], outbuf, sizeof(outbuf), con);
1491  if (res < 1) {
1492  ast_log(LOG_ERROR, "read returned %d\n", res);
1493  break;
1494  }
1495  res = write(con->fd, outbuf, res);
1496  if (res < 1)
1497  break;
1498  }
1499  }
1501  if (!ast_opt_hide_connect) {
1502  ast_verb(3, "Remote UNIX connection disconnected\n");
1503  }
1504  close(con->fd);
1505  close(con->p[0]);
1506  close(con->p[1]);
1507  con->fd = -1;
1508 
1509  return NULL;
1510 }