Asterisk - The Open Source Telephony Project GIT-master-91e368c
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 - 2022, 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 process_histfile (int(*readwrite)(const char *filename))
 
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 2592 of file asterisk.c.

◆ CHAR_T_LIBEDIT

#define CHAR_T_LIBEDIT   wchar_t

Definition at line 2657 of file asterisk.c.

◆ CHAR_TO_LIBEDIT

#define CHAR_TO_LIBEDIT (   c)    btowc(c)

Definition at line 2658 of file asterisk.c.

◆ CMD_MATCHESARRAY

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

◆ COPYRIGHT_TAG

#define COPYRIGHT_TAG   "Copyright (C) 1999 - 2022, 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 894 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 3131 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 1916 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 1017 of file asterisk.c.

1018{
1019 struct ast_atexit *ae;
1020
1022 if (ae->func == func) {
1024 ast_free(ae);
1025 break;
1026 }
1027 }
1029}
#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
void(* func)(void)
Definition: asterisk.c:329
struct ast_atexit::@298 list

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

2201{

◆ __quit_handler()

static void __quit_handler ( int  num)
static

Definition at line 2138 of file asterisk.c.

2139{
2140 sig_flags.need_quit = 1;
2142 fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
2143 }
2144 /* There is no need to restore the signal handler here, since the app
2145 * is going to exit */
2146}
ssize_t ast_alertpipe_write(int alert_pipe[2])
Write an event to an alert pipe.
Definition: alertpipe.c:120
static struct @297 sig_flags
static int sig_alert_pipe[2]
Definition: asterisk.c:396
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 2148 of file asterisk.c.

2149{
2150 sig_flags.need_quit = 1;
2151}

References sig_flags.

Referenced by ast_remotecontrol().

◆ _child_handler()

static void _child_handler ( int  sig)
static

Definition at line 1740 of file asterisk.c.

1741{
1742 /* Must not ever ast_log or ast_verbose within signal handler */
1743 int n, status, save_errno = errno;
1744
1745 /*
1746 * Reap all dead children -- not just one
1747 */
1748 for (n = 0; waitpid(-1, &status, WNOHANG) > 0; n++)
1749 ;
1750 if (n == 0 && option_debug)
1751 printf("Huh? Child handler, but nobody there?\n");
1752 errno = save_errno;
1753}
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 1716 of file asterisk.c.

1717{
1718 int save_errno = errno;
1719
1720 if (restartnow) {
1721 if (el) {
1722 el_end(el);
1723 }
1724 execvp(_argv[0], _argv);
1725 }
1726
1727 printf("Received HUP signal -- Reloading configs\n");
1728 sig_flags.need_reload = 1;
1730 fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
1731 }
1732 errno = save_errno;
1733}
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 1080 of file asterisk.c.

1081{
1082}

◆ _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 1707 of file asterisk.c.

1708{
1709 return;
1710}

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

799{
800#if !defined(LOW_MEMORY)
801 int l = sizeof(struct profile_data);
802 int n = 10; /* default entries */
803
804 if (prof_data == NULL) {
805 prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
806 if (prof_data == NULL)
807 return -1;
808 prof_data->entries = 0;
809 prof_data->max_size = n;
810 }
812 void *p;
813 n = prof_data->max_size + 20;
814 p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
815 if (p == NULL)
816 return -1;
817 prof_data = p;
818 prof_data->max_size = n;
819 }
820 n = prof_data->entries++;
822 prof_data->e[n].value = 0;
823 prof_data->e[n].events = 0;
824 prof_data->e[n].mark = 0;
825 prof_data->e[n].scale = scale;
826 return n;
827#else /* if defined(LOW_MEMORY) */
828 return 0;
829#endif
830}
static struct profile_data * prof_data
Definition: asterisk.c:792
#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:788
struct profile_entry e[0]
Definition: asterisk.c:789
Definition: asterisk.c:778
int64_t events
Definition: asterisk.c:783
int64_t mark
Definition: asterisk.c:781
const char * name
Definition: asterisk.c:779
int64_t value
Definition: asterisk.c:782
uint64_t scale
Definition: asterisk.c:780

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

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

Referenced by consolehandler(), and remoteconsolehandler().

◆ ast_begin_shutdown()

static void ast_begin_shutdown ( void  )
static

Definition at line 1895 of file asterisk.c.

1896{
1899 shutdown_pending = 1;
1900 }
1902}
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:1093
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189

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

1878{
1879 int shutdown_aborted = 0;
1880
1882 if (shuttingdown >= SHUTDOWN_FAST) {
1884 shutdown_pending = 0;
1885 shutdown_aborted = 1;
1886 }
1888 return shutdown_aborted;
1889}

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

2926{
2927 int idx = 1;
2928 /* find out how many entries can be put on one line, with two spaces between strings */
2929 int limit = ast_get_termcols(STDOUT_FILENO) / (max + 2);
2930
2931 if (limit == 0) {
2932 limit = 1;
2933 }
2934
2935 for (;;) {
2936 int numoutputline;
2937
2938 for (numoutputline = 0; numoutputline < limit && idx < AST_VECTOR_SIZE(matches); idx++) {
2939 numoutputline++;
2940 fprintf(stdout, "%-*s ", max, AST_VECTOR_GET(matches, idx));
2941 }
2942
2943 if (!numoutputline) {
2944 break;
2945 }
2946
2947 fprintf(stdout, "\n");
2948 }
2949}
#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 1352 of file asterisk.c.

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

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

1313{
1314 ast_console_puts_mutable_full(string, level, 0);
1315}
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:1319

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

1320{
1321 /* Send to the root console */
1323
1324 /* Wake up a poll()ing console */
1326 pthread_kill(consolethread, SIGURG);
1327 }
1328
1329 /* Send to any network console clients */
1330 ast_network_puts_mutable(message, level, sublevel);
1331}
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:1293
static pthread_t consolethread
Definition: asterisk.c:384
static int console_print(const char *s)
Definition: asterisk.c:2200
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_opt_console
Definition: options.h:111

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

1248{
1249 int x;
1250
1251 if (level >= NUMLOGLEVELS) {
1252 level = NUMLOGLEVELS - 1;
1253 }
1254
1255 for (x = 0;x < AST_MAX_CONNECTS; x++) {
1256 if (fd == consoles[x].fd) {
1257 /*
1258 * Since the logging occurs when levels are false, set to
1259 * flipped iinput because this function accepts 0 as off and 1 as on
1260 */
1261 consoles[x].levels[level] = state ? 0 : 1;
1262 return;
1263 }
1264 }
1265}
#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 1270 of file asterisk.c.

1271{
1272 int x;
1273 for (x = 0;x < AST_MAX_CONNECTS; x++) {
1274 if (fd == consoles[x].fd) {
1275 if (consoles[x].mute) {
1276 consoles[x].mute = 0;
1277 if (!silent)
1278 ast_cli(fd, "Console is not muted anymore.\n");
1279 } else {
1280 consoles[x].mute = 1;
1281 if (!silent)
1282 ast_cli(fd, "Console is muted.\n");
1283 }
1284 return;
1285 }
1286 }
1287 ast_cli(fd, "Couldn't find remote console.\n");
1288}
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, 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 3133 of file asterisk.c.

3134{
3135 HistEvent ev;
3136 char *stripped_buf;
3137
3138 if (el_hist == NULL || el == NULL) {
3140 }
3141 if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1)) {
3142 return 0;
3143 }
3144
3145 stripped_buf = ast_strip(ast_strdupa(buf));
3146
3147 /* HISTCONTROL=ignoredups */
3148 if (!history(el_hist, &ev, H_FIRST) && strcmp(ev.str, stripped_buf) == 0) {
3149 return 0;
3150 }
3151
3152 return history(el_hist, &ev, H_ENTER, stripped_buf);
3153}
static int ast_el_initialize(void)
Definition: asterisk.c:3078
static History * el_hist
Definition: asterisk.c:339
#define MAX_HISTORY_COMMAND_LENGTH
Definition: asterisk.c:3131
#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 3078 of file asterisk.c.

3079{
3080 HistEvent ev;
3081 char *editor, *editrc = getenv("EDITRC");
3082
3083 if (!(editor = getenv("AST_EDITMODE"))) {
3084 if (!(editor = getenv("AST_EDITOR"))) {
3085 editor = "emacs";
3086 }
3087 }
3088
3089 if (el != NULL)
3090 el_end(el);
3091 if (el_hist != NULL)
3092 history_end(el_hist);
3093
3094 el = el_init("asterisk", stdin, stdout, stderr);
3095 el_set(el, EL_PROMPT, cli_prompt);
3096
3097 el_set(el, EL_EDITMODE, 1);
3098 el_set(el, EL_EDITOR, editor);
3099 el_hist = history_init();
3100 if (!el || !el_hist)
3101 return -1;
3102
3103 /* setup history with 100 entries */
3104 history(el_hist, &ev, H_SETSIZE, 100);
3105
3106 el_set(el, EL_HIST, history, el_hist);
3107
3108 el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
3109 /* Bind <tab> to command completion */
3110 el_set(el, EL_BIND, "^I", "ed-complete", NULL);
3111 /* Bind ? to command completion */
3112 el_set(el, EL_BIND, "?", "ed-complete", NULL);
3113 /* Bind ^D to redisplay */
3114 el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
3115 /* Bind Delete to delete char left */
3116 el_set(el, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
3117 /* Bind Home and End to move to line start and end */
3118 el_set(el, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
3119 el_set(el, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
3120 /* Bind C-left and C-right to move by word (not all terminals) */
3121 el_set(el, EL_BIND, "\\eOC", "vi-next-word", NULL);
3122 el_set(el, EL_BIND, "\\eOD", "vi-prev-word", NULL);
3123
3124 if (editrc) {
3125 el_source(el, editrc);
3126 }
3127
3128 return 0;
3129}
static char * cli_complete(EditLine *editline, int ch)
Definition: asterisk.c:2952
static char * cli_prompt(EditLine *editline)
Definition: asterisk.c:2765

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

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

3204{
3206}
static int ast_el_read_history(const char *)
Definition: asterisk.c:3165
static void process_histfile(int(*readwrite)(const char *filename))
Definition: asterisk.c:3176

References ast_el_read_history(), and process_histfile().

Referenced by ast_remotecontrol(), and asterisk_daemon().

◆ ast_el_read_history()

static int ast_el_read_history ( const char *  filename)
static

Definition at line 3165 of file asterisk.c.

3166{
3167 HistEvent ev;
3168
3169 if (el_hist == NULL || el == NULL) {
3171 }
3172
3173 return history(el_hist, &ev, H_LOAD, filename);
3174}

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

2892{
2893 char *retstr;
2894 struct ast_vector_string *vec = ast_calloc(1, sizeof(*vec));
2895
2896 if (!vec) {
2897 return NULL;
2898 }
2899
2900 while ((retstr = strsep(&buf, " "))) {
2901 if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
2902 break;
2903 }
2904
2905 retstr = ast_strdup(retstr);
2906 if (!retstr || AST_VECTOR_APPEND(vec, retstr)) {
2907 ast_free(retstr);
2908 goto vector_cleanup;
2909 }
2910 }
2911
2912 if (!AST_VECTOR_SIZE(vec)) {
2913 goto vector_cleanup;
2914 }
2915
2916 return vec;
2917
2918vector_cleanup:
2921
2922 return NULL;
2923}
#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 3208 of file asterisk.c.

3209{
3211}
static int ast_el_write_history(const char *)
Definition: asterisk.c:3155

References ast_el_write_history(), and process_histfile().

Referenced by really_quit().

◆ ast_el_write_history()

static int ast_el_write_history ( const char *  filename)
static

Definition at line 3155 of file asterisk.c.

3156{
3157 HistEvent ev;
3158
3159 if (el_hist == NULL || el == NULL)
3161
3162 return (history(el_hist, &ev, H_SAVE, filename));
3163}

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

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

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

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

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

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

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

1294{
1295 int x;
1296
1297 for (x = 0; x < AST_MAX_CONNECTS; ++x) {
1298 if (consoles[x].fd < 0
1299 || consoles[x].mute
1300 || consoles[x].levels[level]
1301 || (level == __LOG_VERBOSE && consoles[x].option_verbose < sublevel)) {
1302 continue;
1303 }
1304 fdprint(consoles[x].p[1], string);
1305 }
1306}
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, 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 972 of file asterisk.c.

973{
974 return ast_db_get("pbx", "UUID", pbx_uuid, length);
975}
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:424

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

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

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

1051{
1052 return register_atexit(func, 0);
1053}
static int register_atexit(void(*func)(void), int is_cleanup)
Definition: asterisk.c:1031

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

1056{
1057 return register_atexit(func, 1);
1058}

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 */
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:739
int ast_get_tid(void)
Get current thread ID.
Definition: utils.c:2750

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

3214{
3215 char buf[256] = "";
3216 int res;
3217 char *hostname;
3218 char *cpid;
3219 char *version;
3220 int pid;
3221 char *stringp = NULL;
3222
3223 char *ebuf;
3224 int num = 0;
3225
3226 ast_term_init();
3227 printf("%s", term_end());
3228 fflush(stdout);
3229
3230 memset(&sig_flags, 0, sizeof(sig_flags));
3231 signal(SIGINT, __remote_quit_handler);
3232 signal(SIGTERM, __remote_quit_handler);
3233 signal(SIGHUP, __remote_quit_handler);
3234
3235 if (read(ast_consock, buf, sizeof(buf) - 1) < 0) {
3236 ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
3237 return;
3238 }
3239 if (data) {
3240 char prefix[] = "cli quit after ";
3241 char *tmp = ast_alloca(strlen(data) + strlen(prefix) + 1);
3242 sprintf(tmp, "%s%s", prefix, data);
3243 if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
3244 ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
3245 if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
3246 return;
3247 }
3248 }
3249 }
3250 stringp = buf;
3251 hostname = strsep(&stringp, "/");
3252 cpid = strsep(&stringp, "/");
3253 version = strsep(&stringp, "\n");
3254 if (!version)
3255 version = "<Version Unknown>";
3256 stringp = hostname;
3257 strsep(&stringp, ".");
3258 if (cpid)
3259 pid = atoi(cpid);
3260 else
3261 pid = -1;
3262 if (!data) {
3264 }
3265
3266 if (ast_opt_exec && data) { /* hack to print output then exit if asterisk -rx is used */
3267 int linefull = 1, prev_linefull = 1, prev_line_verbose = 0;
3268 struct pollfd fds;
3269 fds.fd = ast_consock;
3270 fds.events = POLLIN;
3271 fds.revents = 0;
3272
3273 while (ast_poll(&fds, 1, 60000) > 0) {
3274 char buffer[512] = "", *curline = buffer, *nextline;
3275 int not_written = 1;
3276
3277 if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
3278 break;
3279 }
3280
3281 if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
3282 break;
3283 }
3284
3285 do {
3286 prev_linefull = linefull;
3287 if ((nextline = strchr(curline, '\n'))) {
3288 linefull = 1;
3289 nextline++;
3290 } else {
3291 linefull = 0;
3292 nextline = strchr(curline, '\0');
3293 }
3294
3295 /* Skip verbose lines */
3296 /* Prev line full? | Line is verbose | Last line verbose? | Print
3297 * TRUE | TRUE* | TRUE | FALSE
3298 * TRUE | TRUE* | FALSE | FALSE
3299 * TRUE | FALSE* | TRUE | TRUE
3300 * TRUE | FALSE* | FALSE | TRUE
3301 * FALSE | TRUE | TRUE* | FALSE
3302 * FALSE | TRUE | FALSE* | TRUE
3303 * FALSE | FALSE | TRUE* | FALSE
3304 * FALSE | FALSE | FALSE* | TRUE
3305 */
3306 if ((!prev_linefull && !prev_line_verbose) || (prev_linefull && *curline > 0)) {
3307 prev_line_verbose = 0;
3308 not_written = 0;
3309 if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
3310 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
3311 }
3312 } else {
3313 prev_line_verbose = 1;
3314 }
3315 curline = nextline;
3316 } while (!ast_strlen_zero(curline));
3317
3318 /* No non-verbose output in 60 seconds. */
3319 if (not_written) {
3320 break;
3321 }
3322 }
3323 return;
3324 }
3325
3326 ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
3328
3330 if (el_hist == NULL || el == NULL)
3333
3334 el_set(el, EL_GETCFN, ast_el_read_char);
3335
3336 for (;;) {
3337 ebuf = (char *)el_gets(el, &num);
3338
3339 if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
3340 break;
3341 }
3342
3343 if (!ebuf && write(1, "", 1) < 0)
3344 break;
3345
3346 if (!ast_strlen_zero(ebuf)) {
3347 if (ebuf[strlen(ebuf)-1] == '\n')
3348 ebuf[strlen(ebuf)-1] = '\0';
3349 if (!remoteconsolehandler(ebuf)) {
3350 res = write(ast_consock, ebuf, strlen(ebuf) + 1);
3351 if (res < 1) {
3352 ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
3353 break;
3354 }
3355 }
3356 }
3357 }
3358 printf("\nDisconnected from Asterisk server\n");
3359}
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:2148
static int remoteconsolehandler(const char *s)
Definition: asterisk.c:2300
static int ast_el_read_char(EditLine *editline, CHAR_T_LIBEDIT *cp)
Definition: asterisk.c:2664
static void ast_el_read_default_histfile(void)
Definition: asterisk.c:3203
#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 1100 of file asterisk.c.

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

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

1004{
1005 struct ast_atexit *ae;
1006
1008 while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
1009 if (ae->func && (!ae->is_cleanup || run_cleanups)) {
1010 ae->func();
1011 }
1012 ast_free(ae);
1013 }
1015}
#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 1218 of file asterisk.c.

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

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

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

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

1838{
1839 struct sched_param sched;
1840 memset(&sched, 0, sizeof(sched));
1841#ifdef __linux__
1842 if (pri) {
1843 sched.sched_priority = 10;
1844 if (sched_setscheduler(0, SCHED_RR, &sched)) {
1845 return -1;
1846 }
1847 } else {
1848 sched.sched_priority = 0;
1849 /* According to the manpage, these parameters can never fail. */
1850 sched_setscheduler(0, SCHED_OTHER, &sched);
1851 }
1852#else
1853 if (pri) {
1854 if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
1855 ast_log(LOG_WARNING, "Unable to set high priority\n");
1856 return -1;
1857 } else
1858 ast_verb(1, "Set to high priority\n");
1859 } else {
1860 /* According to the manpage, these parameters can never fail. */
1861 setpriority(PRIO_PROCESS, 0, 0);
1862 }
1863#endif
1864 return 0;
1865}
#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(), launch_script(), 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 1867 of file asterisk.c.

1868{
1870}

References SHUTTING_DOWN_FINAL, and shuttingdown.

Referenced by httpd_process_request(), load_resource(), 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 1872 of file asterisk.c.

1873{
1874 return shutdown_pending;
1875}

References shutdown_pending.

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

◆ ast_tryconnect()

static int ast_tryconnect ( void  )
static

Definition at line 1680 of file asterisk.c.

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

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

1061{
1065}
static void __ast_unregister_atexit(void(*func)(void))
Definition: asterisk.c:1017

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

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

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

4066{
4067 FILE *f;
4068 sigset_t sigs;
4069 int num;
4070 char *buf;
4071 char pbx_uuid[AST_UUID_STR_LEN];
4072
4073 /* Set time as soon as possible */
4075
4076 /* This needs to remain as high up in the initial start up as possible.
4077 * daemon causes a fork to occur, which has all sorts of unintended
4078 * consequences for things that interact with threads. This call *must*
4079 * occur before anything in Asterisk spawns or manipulates thread related
4080 * primitives. */
4081#if HAVE_WORKING_FORK
4083#ifndef HAVE_SBIN_LAUNCHD
4084 if (daemon(1, 0) < 0) {
4085 fprintf(stderr, "daemon() failed: %s\n", strerror(errno));
4086 } else {
4087 ast_mainpid = getpid();
4088 }
4089#else
4090 fprintf(stderr, "Mac OS X detected. Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
4091#endif
4092 }
4093#endif
4094
4095 /* At this point everything has been forked successfully,
4096 * we have determined that we aren't attempting to connect to
4097 * an Asterisk instance, and that there isn't one already running. */
4099
4101
4102 /* Check whether high prio was successfully set by us or some
4103 * other incantation. */
4104 if (has_priority()) {
4106 } else {
4108 }
4109
4110 /* Spawning of astcanary must happen AFTER the call to daemon(3) */
4112 snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
4113
4114 /* Don't let the canary child kill Asterisk, if it dies immediately */
4115 sigaction(SIGPIPE, &ignore_sig_handler, NULL);
4116
4117 canary_pid = fork();
4118 if (canary_pid == 0) {
4119 char canary_binary[PATH_MAX], ppid[12];
4120
4121 /* Reset signal handler */
4122 signal(SIGCHLD, SIG_DFL);
4123 signal(SIGPIPE, SIG_DFL);
4124
4127 snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid);
4128
4129 /* Use the astcanary binary that we installed */
4130 snprintf(canary_binary, sizeof(canary_binary), "%s/astcanary", ast_config_AST_SBIN_DIR);
4131 execl(canary_binary, "astcanary", canary_filename, ppid, (char *)NULL);
4132
4133 /* Should never happen */
4134 _exit(1);
4135 } else if (canary_pid > 0) {
4136 pthread_t dont_care;
4138 }
4139
4140 /* Kill the canary when we exit */
4142 }
4143
4144 /* Blindly write the PID file. */
4145 unlink(ast_config_AST_PID);
4146 f = fopen(ast_config_AST_PID, "w");
4147 if (f) {
4148 fprintf(f, "%ld\n", (long)ast_mainpid);
4149 fclose(f);
4150 } else {
4151 fprintf(stderr, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
4152 }
4153
4154 /* Initialize the terminal. Since all processes have been forked,
4155 * we can now start using the standard log messages.
4156 */
4157 ast_term_init();
4158 printf("%s", term_end());
4159 fflush(stdout);
4160
4161 print_intro_message(runuser, rungroup);
4162
4164
4165 check_init(astobj2_init(), "AO2");
4166 check_init(ast_named_locks_init(), "Named Locks");
4167
4168 if (ast_opt_console) {
4169 if (el_hist == NULL || el == NULL)
4172 }
4173
4174#ifdef AST_XML_DOCS
4175 /* Load XML documentation. */
4177#endif
4178
4179 check_init(astdb_init(), "ASTdb");
4180
4181 ast_uuid_init();
4182
4183 if (ast_pbx_uuid_get(pbx_uuid, sizeof(pbx_uuid))) {
4184 ast_uuid_generate_str(pbx_uuid, sizeof(pbx_uuid));
4185 ast_db_put("pbx", "UUID", pbx_uuid);
4186 }
4187 ast_verb(0, "PBX UUID: %s\n", pbx_uuid);
4188
4189 check_init(ast_json_init(), "libjansson");
4190 ast_ulaw_init();
4191 ast_alaw_init();
4192 ast_utf8_init();
4193 tdd_init();
4194 callerid_init();
4196
4197 check_init(ast_utils_init(), "Utilities");
4198 check_init(ast_tps_init(), "Task Processor Core");
4199 check_init(ast_fd_init(), "File Descriptor Debugging");
4200 check_init(ast_pbx_init(), "ast_pbx_init");
4201 check_init(aco_init(), "Configuration Option Framework");
4202 check_init(stasis_init(), "Stasis");
4203#ifdef TEST_FRAMEWORK
4204 check_init(ast_test_init(), "Test Framework");
4205#endif
4206 check_init(ast_translate_init(), "Translator Core");
4207
4209
4210 check_init(ast_sorcery_init(), "Sorcery");
4211 check_init(ast_codec_init(), "Codecs");
4212 check_init(ast_format_init(), "Formats");
4213 check_init(ast_format_cache_init(), "Format Cache");
4214 check_init(ast_codec_builtin_init(), "Built-in Codecs");
4215 check_init(ast_bucket_init(), "Bucket API");
4216 check_init(ast_stasis_system_init(), "Stasis system-level information");
4217 check_init(ast_endpoint_stasis_init(), "Stasis Endpoint");
4218
4220 /* GCC 4.9 gives a bogus "right-hand operand of comma expression has
4221 * no effect" warning */
4222 (void) sigemptyset(&sigs);
4223 (void) sigaddset(&sigs, SIGHUP);
4224 (void) sigaddset(&sigs, SIGTERM);
4225 (void) sigaddset(&sigs, SIGINT);
4226 (void) sigaddset(&sigs, SIGPIPE);
4227 (void) sigaddset(&sigs, SIGWINCH);
4228 pthread_sigmask(SIG_BLOCK, &sigs, NULL);
4229 sigaction(SIGURG, &urg_handler, NULL);
4230 signal(SIGINT, __quit_handler);
4231 signal(SIGTERM, __quit_handler);
4232 sigaction(SIGHUP, &hup_handler, NULL);
4233 sigaction(SIGPIPE, &ignore_sig_handler, NULL);
4234
4235 /* ensure that the random number generators are seeded with a different value every time
4236 Asterisk is started
4237 */
4238 srand((unsigned int) getpid() + (unsigned int) time(NULL));
4239 initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
4240
4242
4243 check_init(init_logger(), "Logger");
4244 check_init(ast_rtp_engine_init(), "RTP Engine");
4245
4247
4248 check_init(ast_timing_init(), "Timing");
4249 check_init(ast_ssl_init(), "SSL");
4251 check_init(ast_pj_init(), "Embedded PJProject");
4252 check_init(app_init(), "App Core");
4253 check_init(mwi_init(), "MWI Core");
4254 check_init(devstate_init(), "Device State Core");
4255 check_init(ast_msg_init(), "Messaging API");
4256 check_init(ast_channels_init(), "Channel");
4257 check_init(ast_endpoint_init(), "Endpoints");
4258 check_init(ast_pickup_init(), "Call Pickup");
4259 check_init(ast_bridging_init(), "Bridging");
4260 check_init(ast_parking_stasis_init(), "Parking Core");
4261 check_init(ast_device_state_engine_init(), "Device State Engine");
4262 check_init(ast_presence_state_engine_init(), "Presence State Engine");
4263 check_init(dns_core_init(), "DNS Resolver Core");
4264 check_init(ast_dns_system_resolver_init(), "Default DNS resolver");
4265 check_init(ast_security_stasis_init(), "Security Stasis Topic and Events");
4266 check_init(ast_image_init(), "Image");
4267 check_init(ast_file_init(), "Generic File Format Support");
4268 check_init(load_pbx(), "load_pbx");
4269 check_init(load_pbx_builtins(), "Builtin PBX Applications");
4270 check_init(load_pbx_functions_cli(), "PBX Functions Support");
4271 check_init(load_pbx_variables(), "PBX Variables Support");
4272 check_init(load_pbx_switch(), "PBX Switch Support");
4273 check_init(load_pbx_app(), "PBX Application Support");
4274 check_init(load_pbx_hangup_handler(), "PBX Hangup Handler Support");
4275 check_init(ast_local_init(), "Local Proxy Channel Driver");
4276 check_init(ast_refer_init(), "Refer API");
4277
4278 /* We should avoid most config loads before this point as they can't use realtime. */
4279 check_init(load_modules(), "Module");
4280
4281 /*
4282 * This has to load after the dynamic modules load, as items in the media
4283 * cache can't be constructed from items in the AstDB without their
4284 * bucket backends.
4285 */
4286 check_init(ast_media_cache_init(), "Media Cache");
4287
4288 /* loads the cli_permissions.conf file needed to implement cli restrictions. */
4290 ast_cli_channels_init(); /* Not always safe to access CLI commands until startup is complete. */
4291
4292 ast_stun_init();
4293
4295
4296 if (ast_opt_no_fork) {
4297 consolethread = pthread_self();
4298 }
4299
4301
4303
4306
4307 pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
4308
4310
4314
4316 ast_sd_notify("READY=1");
4317
4318 ast_verb(0, COLORIZE_FMT "\n", COLORIZE(COLOR_BRGREEN, 0, "Asterisk Ready."));
4319
4321
4322 if (ast_opt_console) {
4323 /* Console stuff now... */
4324 /* Register our quit function */
4325 char title[256];
4326 char hostname[MAXHOSTNAMELEN] = "";
4327
4328 if (gethostname(hostname, sizeof(hostname) - 1)) {
4329 ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
4330 }
4331
4333
4334 set_icon("Asterisk");
4335 snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
4336 set_title(title);
4337
4338 el_set(el, EL_GETCFN, ast_el_read_char);
4339
4340 for (;;) {
4341 if (sig_flags.need_el_end) {
4342 el_end(el);
4343
4344 return;
4345 }
4346
4347 if (sig_flags.need_quit || sig_flags.need_quit_handler) {
4349 break;
4350 }
4351 buf = (char *) el_gets(el, &num);
4352
4353 if (!buf && write(1, "", 1) < 0)
4354 return; /* quit */
4355
4356 if (buf) {
4357 if (buf[strlen(buf)-1] == '\n')
4358 buf[strlen(buf)-1] = '\0';
4359
4361 }
4362 }
4363 }
4364
4365 /* Stall until a quit signal is given */
4367}
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:1412
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:2354
void ast_cli_channels_init(void)
Definition: main/cli.c:2242
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:1482
void ast_stun_init(void)
Initialize the STUN system in Asterisk.
Definition: stun.c:576
int astdb_init(void)
Definition: main/db.c:1193
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:3660
int ast_xmldoc_load_documentation(void)
Load XML documentation. Provided by xmldoc.c.
Definition: xmldoc.c:3047
int ast_named_locks_init(void)
Definition: named_locks.c:52
int ast_channels_init(void)
Definition: channel.c:8000
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:2235
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)
Definition: pbx.c:8421
int astobj2_init(void)
Definition: astobj2.c:1169
int load_pbx_app(void)
Definition: pbx_app.c:538
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:2102
int ast_file_init(void)
Definition: file.c:2050
int ast_refer_init(void)
Definition: refer.c:529
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:339
static void canary_exit(void)
Definition: asterisk.c:3494
static void check_init(int init_result, const char *name)
Definition: asterisk.c:4052
static void publish_fully_booted(void)
Definition: asterisk.c:977
static void main_atexit(void)
Definition: asterisk.c:3557
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:1055
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:1837
static int has_priority(void)
Check whether we were set to high(er) priority.
Definition: asterisk.c:1774
static struct sigaction hup_handler
Definition: asterisk.c:1735
static pthread_t mon_sig_flags
Definition: asterisk.c:385
int ast_pbx_uuid_get(char *pbx_uuid, int length)
Retrieve the PBX UUID.
Definition: asterisk.c:972
struct timeval ast_lastreloadtime
Definition: asterisk.c:337
static void * monitor_sig_flags(void *unused)
Definition: asterisk.c:3440
static void consolehandler(const char *s)
Definition: asterisk.c:2282
static struct ast_cli_entry cli_asterisk_shutdown[]
Shutdown Asterisk CLI commands.
Definition: asterisk.c:2602
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:1050
static void set_title(char *text)
Set an X-term or screen title.
Definition: asterisk.c:1761
static int ast_makesocket(void)
Definition: asterisk.c:1594
static int canary_pid
Definition: asterisk.c:386
static void * canary_thread(void *unused)
Definition: asterisk.c:3465
static struct ast_cli_entry cli_asterisk[]
Definition: asterisk.c:2611
static void run_startup_commands(void)
Definition: asterisk.c:3504
struct timeval ast_startuptime
Definition: asterisk.c:336
static void read_pjproject_startup_options(void)
Definition: asterisk.c:3406
pid_t ast_mainpid
Definition: asterisk.c:315
static void __quit_handler(int num)
Definition: asterisk.c:2138
static void set_icon(char *text)
Definition: asterisk.c:1767
static void print_intro_message(const char *runuser, const char *rungroup)
Definition: asterisk.c:3544
static struct sigaction ignore_sig_handler
Definition: asterisk.c:1089
static struct sigaction urg_handler
Definition: asterisk.c:1712
int ast_pbx_init(void)
Definition: pbx.c:8989
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:250
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:3355
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:3192
int register_config_cli(void)
Exposed initialization method for core process.
Definition: main/config.c:4147
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:716
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:112
#define ast_opt_always_fork
Definition: options.h:126
#define ast_opt_no_fork
Definition: options.h:109
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:399
int ast_presence_state_engine_init(void)
int ast_security_stasis_init(void)
initializes stasis topic/event types for ast_security_topic and ast_security_event_type
int ast_sorcery_init(void)
Initialize the sorcery API.
Definition: sorcery.c:387
int stasis_init(void)
Initialize the Stasis subsystem.
Definition: stasis.c:3061
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:159
int ast_translate_init(void)
Initialize the translation matrix and index to format conversion table.
Definition: translate.c:1658
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:919
#define ast_clear_flag(p, flag)
Definition: utils.h:77
int ast_utils_init(void)
Definition: utils.c:2615
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:588
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define ARRAY_LEN(a)
Definition: utils.h:666
#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_channels_init(), 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_refer_init(), 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 1959 of file asterisk.c.

1960{
1961 int waited = 0;
1962
1963 /* Check if someone else isn't already doing this. */
1965 if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
1966 /* Already in progress and other request was less nice. */
1968 ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
1969 return 0;
1970 }
1971 shuttingdown = niceness;
1973
1974 /* Try to get as many CDRs as possible submitted to the backend engines
1975 * (if in batch mode). really_quit happens to call it again when running
1976 * the atexit handlers, otherwise this would be a bit early. */
1978
1979 /*
1980 * Shutdown the message queue for the technology agnostic message channel.
1981 * This has to occur before we pause shutdown pending ast_undestroyed_channels.
1982 *
1983 * XXX This is not reversed on shutdown cancel.
1984 */
1986
1987 if (niceness == SHUTDOWN_NORMAL) {
1988 /* Begin shutdown routine, hanging up active channels */
1990 if (ast_opt_console) {
1991 ast_verb(0, "Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
1992 }
1994 waited |= wait_for_channels_to_die(niceness, SHUTDOWN_TIMEOUT);
1995 } else if (niceness >= SHUTDOWN_NICE) {
1996 if (niceness != SHUTDOWN_REALLY_NICE) {
1998 }
1999 if (ast_opt_console) {
2000 ast_verb(0, "Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
2001 }
2002 waited |= wait_for_channels_to_die(niceness, -1);
2003 }
2004
2005 /* Re-acquire lock and check if someone changed the niceness, in which
2006 * case someone else has taken over the shutdown.
2007 */
2009 if (shuttingdown != niceness) {
2011 ast_verb(0, "Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
2012 }
2014 return 0;
2015 }
2016
2017 if (niceness >= SHUTDOWN_REALLY_NICE) {
2020
2021 /* No more Mr. Nice guy. We are committed to shutting down now. */
2025
2027 }
2030
2031 if (niceness >= SHUTDOWN_NORMAL && waited) {
2032 /*
2033 * We were not idle. Give things in progress a chance to
2034 * recognize the final shutdown phase.
2035 */
2036 sleep(1);
2037 }
2038 return 1;
2039}
void ast_msg_shutdown(void)
static void ast_begin_shutdown(void)
Definition: asterisk.c:1895
#define SHUTDOWN_TIMEOUT
Definition: asterisk.c:1916
static int wait_for_channels_to_die(shutdown_nice_t niceness, int seconds)
Definition: asterisk.c:1929
void ast_cdr_engine_term(void)
Definition: cdr.c:4665
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 3494 of file asterisk.c.

3495{
3496 if (canary_pid > 0) {
3497 int status;
3498 kill(canary_pid, SIGKILL);
3499 waitpid(canary_pid, &status, 0);
3500 }
3501}

References canary_pid, and status.

Referenced by asterisk_daemon().

◆ canary_thread()

static void * canary_thread ( void *  unused)
static

Definition at line 3465 of file asterisk.c.

3466{
3467 struct stat canary_stat;
3468 struct timeval now;
3469
3470 /* Give the canary time to sing */
3471 sleep(120);
3472
3473 for (;;) {
3474 now = ast_tvnow();
3475 if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
3477 "The canary is no more. He has ceased to be! "
3478 "He's expired and gone to meet his maker! "
3479 "He's a stiff! Bereft of life, he rests in peace. "
3480 "His metabolic processes are now history! He's off the twig! "
3481 "He's kicked the bucket. He's shuffled off his mortal coil, "
3482 "run down the curtain, and joined the bleeding choir invisible!! "
3483 "THIS is an EX-CANARY. (Reducing priority)\n");
3485 pthread_exit(NULL);
3486 }
3487
3488 /* Check the canary once a minute */
3489 sleep(60);
3490 }
3491}
static int set_priority_all(int pri)
Set priority on all known threads.
Definition: asterisk.c:1794

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

4053{
4054 if (init_result) {
4056 ast_log(LOG_ERROR, "%s initialization failed. ASTERISK EXITING!\n%s", name, term_quit());
4057 } else {
4058 fprintf(stderr, "%s initialization failed. ASTERISK EXITING!\n%s", name, term_quit());
4059 }
4060 ast_run_atexits(0);
4061 exit(init_result == -2 ? 2 : 1);
4062 }
4063}
static void ast_run_atexits(int run_cleanups)
Definition: asterisk.c:1003
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 2952 of file asterisk.c.

2953{
2954 int len = 0;
2955 char *ptr;
2956 struct ast_vector_string *matches;
2957 int retval = CC_ERROR;
2958 char savechr;
2959 int res;
2960
2961 LineInfo *lf = (LineInfo *)el_line(editline);
2962
2963 savechr = *(char *)lf->cursor;
2964 *(char *)lf->cursor = '\0';
2965 ptr = (char *)lf->cursor;
2966 if (ptr) {
2967 while (ptr > lf->buffer) {
2968 if (isspace(*ptr)) {
2969 ptr++;
2970 break;
2971 }
2972 ptr--;
2973 }
2974 }
2975
2976 len = lf->cursor - ptr;
2977
2978 if (ast_opt_remote) {
2979#define CMD_MATCHESARRAY "_COMMAND MATCHESARRAY \"%s\" \"%s\""
2980 char *mbuf;
2981 char *new_mbuf;
2982 int mlen = 0;
2983 int maxmbuf = ast_asprintf(&mbuf, CMD_MATCHESARRAY, lf->buffer, ptr);
2984
2985 if (maxmbuf == -1) {
2986 *((char *) lf->cursor) = savechr;
2987
2988 return (char *)(CC_ERROR);
2989 }
2990
2991 fdsend(ast_consock, mbuf);
2992 res = 0;
2993 mlen = 0;
2994 mbuf[0] = '\0';
2995
2996 while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
2997 if (mlen + 1024 > maxmbuf) {
2998 /* Expand buffer to the next 1024 byte increment plus a NULL terminator. */
2999 maxmbuf = mlen + 1024;
3000 new_mbuf = ast_realloc(mbuf, maxmbuf + 1);
3001 if (!new_mbuf) {
3002 ast_free(mbuf);
3003 *((char *) lf->cursor) = savechr;
3004
3005 return (char *)(CC_ERROR);
3006 }
3007 mbuf = new_mbuf;
3008 }
3009 /* Only read 1024 bytes at a time */
3010 res = read(ast_consock, mbuf + mlen, 1024);
3011 if (res > 0) {
3012 if (!strncmp(mbuf, "Usage:", 6)) {
3013 /*
3014 * Abort on malformed tab completes
3015 * If help (tab complete) follows certain
3016 * special characters, the main Asterisk process
3017 * provides usage for the internal tab complete
3018 * helper command that the remote console processes
3019 * use.
3020 * If this happens, the AST_CLI_COMPLETE_EOF sentinel
3021 * value never gets sent. As a result, we'll just block
3022 * forever if we don't handle this case.
3023 * If we get command usage on a tab complete, then
3024 * we know this scenario just happened and we should
3025 * just silently ignore and do nothing.
3026 */
3027 break;
3028 }
3029 mlen += res;
3030 mbuf[mlen] = '\0';
3031 }
3032 }
3033 mbuf[mlen] = '\0';
3034
3035 matches = ast_el_strtoarr(mbuf);
3036 ast_free(mbuf);
3037 } else {
3038 matches = ast_cli_completion_vector((char *)lf->buffer, ptr);
3039 }
3040
3041 if (matches) {
3042 int i;
3043 int maxlen, match_len;
3044 const char *best_match = AST_VECTOR_GET(matches, 0);
3045
3046 if (!ast_strlen_zero(best_match)) {
3047 el_deletestr(editline, (int) len);
3048 el_insertstr(editline, best_match);
3049 retval = CC_REFRESH;
3050 }
3051
3052 if (AST_VECTOR_SIZE(matches) == 2) {
3053 /* Found an exact match */
3054 el_insertstr(editline, " ");
3055 retval = CC_REFRESH;
3056 } else {
3057 /* Must be more than one match */
3058 for (i = 1, maxlen = 0; i < AST_VECTOR_SIZE(matches); i++) {
3059 match_len = strlen(AST_VECTOR_GET(matches, i));
3060 if (match_len > maxlen) {
3061 maxlen = match_len;
3062 }
3063 }
3064
3065 fprintf(stdout, "\n");
3066 ast_cli_display_match_list(matches, maxlen);
3067 retval = CC_REDISPLAY;
3068 }
3070 AST_VECTOR_PTR_FREE(matches);
3071 }
3072
3073 *((char *) lf->cursor) = savechr;
3074
3075 return (char *)(long)retval;
3076}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
static void ast_cli_display_match_list(struct ast_vector_string *matches, int max)
Definition: asterisk.c:2925
#define CMD_MATCHESARRAY
static int fdsend(int fd, const char *s)
Definition: asterisk.c:1068
static struct ast_vector_string * ast_el_strtoarr(char *buf)
Definition: asterisk.c:2891
#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:2763
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:114

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

2766{
2767 char tmp[100];
2768 char *pfmt;
2769 int color_used = 0;
2770 static int cli_prompt_changes = 0;
2771 struct passwd *pw;
2772 struct group *gr;
2773
2774 if (prompt == NULL) {
2775 prompt = ast_str_create(100);
2776 } else if (!cli_prompt_changes) {
2777 return ast_str_buffer(prompt);
2778 } else {
2780 }
2781
2782 if ((pfmt = getenv("ASTERISK_PROMPT"))) {
2783 char *t = pfmt;
2784 struct timeval ts = ast_tvnow();
2785 while (*t != '\0') {
2786 if (*t == '%') {
2787 char hostname[MAXHOSTNAMELEN] = "";
2788 int i, which;
2789 struct ast_tm tm = { 0, };
2790 int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
2791
2792 t++;
2793 switch (*t) {
2794 case 'C': /* color */
2795 t++;
2796 if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
2797 ast_term_color_code(&prompt, fgcolor, bgcolor);
2798 t += i - 1;
2799 } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
2800 ast_term_color_code(&prompt, fgcolor, 0);
2801 t += i - 1;
2802 }
2803
2804 /* If the color has been reset correctly, then there's no need to reset it later */
2805 color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
2806 break;
2807 case 'd': /* date */
2808 if (ast_localtime(&ts, &tm, NULL)) {
2809 ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
2810 ast_str_append(&prompt, 0, "%s", tmp);
2811 cli_prompt_changes++;
2812 }
2813 break;
2814 case 'g': /* group */
2815 if ((gr = getgrgid(getgid()))) {
2816 ast_str_append(&prompt, 0, "%s", gr->gr_name);
2817 }
2818 break;
2819 case 'h': /* hostname */
2820 if (!gethostname(hostname, sizeof(hostname) - 1)) {
2821 ast_str_append(&prompt, 0, "%s", hostname);
2822 } else {
2823 ast_str_append(&prompt, 0, "%s", "localhost");
2824 }
2825 break;
2826 case 'H': /* short hostname */
2827 if (!gethostname(hostname, sizeof(hostname) - 1)) {
2828 char *dotptr;
2829 if ((dotptr = strchr(hostname, '.'))) {
2830 *dotptr = '\0';
2831 }
2832 ast_str_append(&prompt, 0, "%s", hostname);
2833 } else {
2834 ast_str_append(&prompt, 0, "%s", "localhost");
2835 }
2836 break;
2837#ifdef HAVE_GETLOADAVG
2838 case 'l': /* load avg */
2839 t++;
2840 if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
2841 double list[3];
2842 getloadavg(list, 3);
2843 ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
2844 cli_prompt_changes++;
2845 }
2846 break;
2847#endif
2848 case 's': /* Asterisk system name (from asterisk.conf) */
2850 break;
2851 case 't': /* time */
2852 if (ast_localtime(&ts, &tm, NULL)) {
2853 ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
2854 ast_str_append(&prompt, 0, "%s", tmp);
2855 cli_prompt_changes++;
2856 }
2857 break;
2858 case 'u': /* username */
2859 if ((pw = getpwuid(getuid()))) {
2860 ast_str_append(&prompt, 0, "%s", pw->pw_name);
2861 }
2862 break;
2863 case '#': /* process console or remote? */
2864 ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
2865 break;
2866 case '%': /* literal % */
2867 ast_str_append(&prompt, 0, "%c", '%');
2868 break;
2869 case '\0': /* % is last character - prevent bug */
2870 t--;
2871 break;
2872 }
2873 } else {
2874 ast_str_append(&prompt, 0, "%c", *t);
2875 }
2876 t++;
2877 }
2878 if (color_used) {
2879 /* Force colors back to normal at end */
2881 }
2882 } else {
2883 ast_str_set(&prompt, 0, "%s%s",
2886 }
2887
2888 return ast_str_buffer(prompt);
2889}
static struct ast_str * prompt
Definition: asterisk.c:2763
#define ASTERISK_PROMPT
Definition: asterisk.c:2592
int getloadavg(double *list, int nelem)
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
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
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:1136
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:758
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:693
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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:1110
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 2200 of file asterisk.c.

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

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

◆ consolehandler()

static void consolehandler ( const char *  s)
static

Definition at line 2282 of file asterisk.c.

2283{
2284 printf("%s", term_end());
2285 fflush(stdout);
2286
2287 /* Called when readline data is available */
2288 if (!ast_all_zeros(s))
2290 /* The real handler for bang */
2291 if (s[0] == '!') {
2292 if (s[1])
2293 ast_safe_system(s+1);
2294 else
2295 ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
2296 } else
2297 ast_cli_command(STDOUT_FILENO, s);
2298}
static int ast_el_add_history(const char *)
Definition: asterisk.c:3133
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: asterisk.c:1231
static int ast_all_zeros(const char *s)
Definition: asterisk.c:2271
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 3532 of file asterisk.c.

3533{
3534 setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
3535 setenv("AST_BUILD_HOST", ast_build_hostname, 1);
3536 setenv("AST_BUILD_DATE", ast_build_date, 1);
3537 setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
3538 setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
3539 setenv("AST_BUILD_OS", ast_build_os, 1);
3540 setenv("AST_BUILD_USER", ast_build_user, 1);
3541 setenv("AST_VERSION", ast_get_version(), 1);
3542}
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 1074 of file asterisk.c.

1075{
1076 return write(fd, s, strlen(s));
1077}

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

1069{
1070 return write(fd, s, strlen(s) + 1);
1071}

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

2475{
2476 switch (cmd) {
2477 case CLI_INIT:
2478 e->command = "core abort shutdown";
2479 e->usage =
2480 "Usage: core abort shutdown\n"
2481 " Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
2482 " call operations.\n";
2484 return NULL;
2485 case CLI_GENERATE:
2486 return NULL;
2487 }
2488
2489 if (a->argc != e->args)
2490 return CLI_SHOWUSAGE;
2491
2493
2494 return CLI_SUCCESS;
2495}
int ast_cancel_shutdown(void)
Cancel an existing shutdown and return to normal operation.
Definition: asterisk.c:1877
#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:3058
@ 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 2497 of file asterisk.c.

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

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

943{
944 int i, min, max;
945 const char *search = NULL;
946 switch (cmd) {
947 case CLI_INIT:
948 e->command = "core clear profile";
949 e->usage = "Usage: core clear profile\n"
950 " clear profile information";
951 return NULL;
952 case CLI_GENERATE:
953 return NULL;
954 }
955
956 if (prof_data == NULL)
957 return 0;
958
960 for (i= min; i < max; i++) {
961 if (!search || strstr(prof_data->e[i].name, search)) {
962 prof_data->e[i].value = 0;
963 prof_data->e[i].events = 0;
964 }
965 }
966 return CLI_SUCCESS;
967}
#define DEFINE_PROFILE_MIN_MAX_VALUES
Definition: asterisk.c:894
#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 2432 of file asterisk.c.

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

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

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

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

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

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

908{
909 int i, min, max;
910 const char *search = NULL;
911 switch (cmd) {
912 case CLI_INIT:
913 e->command = "core show profile";
914 e->usage = "Usage: core show profile\n"
915 " show profile information";
916 return NULL;
917 case CLI_GENERATE:
918 return NULL;
919 }
920
921 if (prof_data == NULL)
922 return 0;
923
925 ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
927 ast_cli(a->fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events",
928 "Value", "Average", "Name");
929 for (i = min; i < max; i++) {
930 struct profile_entry *entry = &prof_data->e[i];
931 if (!search || strstr(entry->name, search))
932 ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n",
933 i,
934 (long)entry->scale,
935 (long)entry->events, (long long)entry->value,
936 (long long)(entry->events ? entry->value / entry->events : entry->value),
937 entry->name);
938 }
939 return CLI_SUCCESS;
940}
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, " ABI related Build Options: %s\n", S_OR(ast_get_build_opts(), "(none)"));
495 ast_cli(a->fd, " All Build Options: %s\n", S_OR(ast_get_build_opts_all(), "(none)"));
497 ast_cli(a->fd, " Maximum calls: %d (Current %d)\n", ast_option_maxcalls, ast_active_channels());
498 else
499 ast_cli(a->fd, " Maximum calls: Not set\n");
500
501 if (getrlimit(RLIMIT_NOFILE, &limits)) {
502 ast_cli(a->fd, " Maximum open file handles: Error because of %s\n", strerror(errno));
503 } else if (limits.rlim_cur == RLIM_INFINITY) {
504 ast_cli(a->fd, " Maximum open file handles: Unlimited\n");
505 } else if (limits.rlim_cur < ast_option_maxfiles) {
506 ast_cli(a->fd, " Maximum open file handles: %d (is) %d (requested)\n", (int) limits.rlim_cur, ast_option_maxfiles);
507 } else {
508 ast_cli(a->fd, " Maximum open file handles: %d\n", (int) limits.rlim_cur);
509 }
510
511 ast_cli(a->fd, " Root console verbosity: %d\n", option_verbose);
512 ast_cli(a->fd, " Current console verbosity: %d\n", ast_verb_console_get());
513 ast_cli(a->fd, " Debug level: %d\n", option_debug);
514 ast_cli(a->fd, " Trace level: %d\n", option_trace);
515 ast_cli(a->fd, " Dump core on crash: %s\n", ast_opt_dump_core ? "Yes" : "No");
516 print_file(a->fd, " Core dump file: ", "/proc/sys/kernel/core_pattern");
517 ast_cli(a->fd, " Maximum load average: %lf\n", ast_option_maxload);
518#if defined(HAVE_SYSINFO)
519 ast_cli(a->fd, " Minimum free memory: %ld MB\n", option_minmemfree);
520#endif
521 if (ast_localtime(&ast_startuptime, &tm, NULL)) {
522 ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
523 ast_cli(a->fd, " Startup time: %s\n", buf);
524 }
526 ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
527 ast_cli(a->fd, " Last reload time: %s\n", buf);
528 }
529 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);
530 ast_cli(a->fd, " System name: %s\n", ast_config_AST_SYSTEM_NAME);
531 ast_cli(a->fd, " Entity ID: %s\n", eid_str);
532 ast_cli(a->fd, " PBX UUID: %s\n", pbx_uuid);
533 ast_cli(a->fd, " Default language: %s\n", ast_defaultlanguage);
534 ast_cli(a->fd, " Language prefix: %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
535 ast_cli(a->fd, " User name and group: %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
536#if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
537#if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
538#define eaccess euidaccess
539#endif
540 if (!getcwd(dir, sizeof(dir))) {
541 if (eaccess(dir, R_OK | X_OK | F_OK)) {
542 ast_cli(a->fd, " Running directory: %s\n", "Unable to access");
543 } else {
544 ast_cli(a->fd, " Running directory: %s (%s)\n", dir, "Unable to access");
545 }
546 } else {
547 ast_cli(a->fd, " Running directory: %s\n", dir);
548 }
549#endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */
550 ast_cli(a->fd, " Executable includes: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
551 ast_cli(a->fd, " Transcode via SLIN: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
552 ast_cli(a->fd, " Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled");
553 ast_cli(a->fd, " Generic PLC: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");
554 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");
555 ast_cli(a->fd, " Hide Msg Chan AMI events: %s\n", ast_opt_hide_messaging_ami_events ? "Enabled" : "Disabled");
556 ast_cli(a->fd, " Sounds search custom dir: %s\n", ast_opt_sounds_search_custom ? "Enabled" : "Disabled");
557 ast_cli(a->fd, " Min DTMF duration:: %u\n", option_dtmfminduration);
558#if !defined(LOW_MEMORY)
559 ast_cli(a->fd, " Cache media frames: %s\n", ast_opt_cache_media_frames ? "Enabled" : "Disabled");
560#endif
561 ast_cli(a->fd, " RTP use dynamic payloads: %u\n", ast_option_rtpusedynamic);
562
564 ast_cli(a->fd, " RTP dynamic payload types: %u,%u-%u\n",
568 ast_cli(a->fd, " RTP dynamic payload types: %u-%u,%u-%u\n",
571 } else {
572 ast_cli(a->fd, " RTP dynamic payload types: %u-%u\n",
574 }
575
576 ast_cli(a->fd, "\n* Subsystems\n");
577 ast_cli(a->fd, " -------------\n");
578 ast_cli(a->fd, " Manager (AMI): %s\n", ast_manager_check_enabled() ? "Enabled" : "Disabled");
579 ast_cli(a->fd, " Web Manager (AMI/HTTP): %s\n", ast_webmanager_check_enabled() ? "Enabled" : "Disabled");
580 ast_cli(a->fd, " Call data records: %s\n", ast_cdr_is_enabled() ? "Enabled" : "Disabled");
581 ast_cli(a->fd, " Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
582
583 /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues */
584
585 ast_cli(a->fd, "\n* Directories\n");
586 ast_cli(a->fd, " -------------\n");
587 ast_cli(a->fd, " Configuration file: %s\n", ast_config_AST_CONFIG_FILE);
588 ast_cli(a->fd, " Configuration directory: %s\n", ast_config_AST_CONFIG_DIR);
589 ast_cli(a->fd, " Module directory: %s\n", ast_config_AST_MODULE_DIR);
590 ast_cli(a->fd, " Spool directory: %s\n", ast_config_AST_SPOOL_DIR);
591 ast_cli(a->fd, " Log directory: %s\n", ast_config_AST_LOG_DIR);
592 ast_cli(a->fd, " Run/Sockets directory: %s\n", ast_config_AST_RUN_DIR);
593 ast_cli(a->fd, " PID file: %s\n", ast_config_AST_PID);
594 ast_cli(a->fd, " VarLib directory: %s\n", ast_config_AST_VAR_DIR);
595 ast_cli(a->fd, " Data directory: %s\n", ast_config_AST_DATA_DIR);
596 ast_cli(a->fd, " ASTDB: %s\n", ast_config_AST_DB);
597 ast_cli(a->fd, " IAX2 Keys directory: %s\n", ast_config_AST_KEY_DIR);
598 ast_cli(a->fd, " AGI Scripts directory: %s\n", ast_config_AST_AGI_DIR);
599 ast_cli(a->fd, "\n\n");
600 return CLI_SUCCESS;
601}
const char * ast_get_build_opts(void)
const char * ast_get_build_opts_all(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:2923
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:2070
int ast_webmanager_check_enabled(void)
Check if AMI/HTTP is enabled.
Definition: manager.c:2075
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:100
@ 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:102
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
Definition: main/config.c:3455
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_sounds_search_custom
Definition: options.h:138
#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: utils.c:2835
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_build_opts_all(), 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_opt_sounds_search_custom, 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 669 of file asterisk.c.

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

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

604{
605 int count = 0;
606 struct thread_list_t *cur;
607 switch (cmd) {
608 case CLI_INIT:
609 e->command = "core show threads";
610 e->usage =
611 "Usage: core show threads\n"
612 " List threads currently active in the system.\n";
613 return NULL;
614 case CLI_GENERATE:
615 return NULL;
616 }
617
619 AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
620 ast_cli(a->fd, "%p %d %s\n", (void *)cur->id, cur->lwp, cur->name);
621 count++;
622 }
624 ast_cli(a->fd, "%d threads listed.\n", count);
625 return CLI_SUCCESS;
626}
#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 2369 of file asterisk.c.

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

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

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

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

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

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

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

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

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

Referenced by ast_ari_validate_dialplan_cep(), and asterisk_daemon().

◆ listener()

static void * listener ( void *  unused)
static

Definition at line 1514 of file asterisk.c.

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

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_shutdown(), 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_shutdown(), test_state_changed(), test_task_pushed(), threadpool_tps_emptied(), threadpool_tps_shutdown(), threadpool_tps_task_pushed(), and wait_for_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.
The q option is never used anywhere, only defined
Can ONLY be used with remote console

Definition at line 3562 of file asterisk.c.

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

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

3558{
3560}
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 3440 of file asterisk.c.

3441{
3442 for (;;) {
3443 struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
3444
3445 ast_poll(&p, 1, -1);
3446 if (sig_flags.need_reload) {
3447 sig_flags.need_reload = 0;
3449 }
3450 if (sig_flags.need_quit) {
3451 sig_flags.need_quit = 0;
3452 if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
3453 sig_flags.need_quit_handler = 1;
3454 pthread_kill(consolethread, SIGURG);
3455 } else {
3457 }
3458 }
3460 }
3461
3462 return NULL;
3463}
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:1567

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

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

References ast_cli_command_multiple_full(), ast_copy_string(), ast_get_version(), ast_log, ast_mainpid, ast_opt_hide_connect, ast_poll, ast_verb, ast_verb_console_register(), ast_verb_console_unregister(), errno, console::fd, fdprint(), console::gid, hostname, inbuf(), LOG_ERROR, LOG_WARNING, MAXHOSTNAMELEN, NULL, console::option_verbose, console::p, read_credentials(), and console::uid.

Referenced by listener().

◆ print_file()

static int print_file ( int  fd,
char *  desc,
const char *  filename 
)
static

Print the contents of a file.

Definition at line 450 of file asterisk.c.

451{
452 FILE *f;
453 char c;
454 if (!(f = fopen(filename, "r"))) {
455 return -1;
456 }
457 ast_cli(fd, "%s", desc);
458 while ((c = fgetc(f)) != EOF) {
459 ast_cli(fd, "%c", c);
460 }
461 fclose(f);
462 /* no need for trailing new line, the file already has one */
463 return 0;
464}
static const char desc[]
Definition: cdr_radius.c:84

References ast_cli(), c, and desc.

Referenced by handle_show_settings().

◆ print_intro_message()

static void print_intro_message ( const char *  runuser,
const char *  rungroup 
)
static

Definition at line 3544 of file asterisk.c.

3545{
3548 if (runuser) {
3549 ast_verbose("Running as user '%s'\n", runuser);
3550 }
3551 if (rungroup) {
3552 ast_verbose("Running under group '%s'\n", rungroup);
3553 }
3554 }
3555}

References ast_opt_console, ast_opt_exec, ast_opt_remote, ast_verbose(), option_verbose, and WELCOME_MESSAGE.

Referenced by asterisk_daemon(), and main().

◆ process_histfile()

static void process_histfile ( int(*)(const char *filename)  readwrite)
static

Definition at line 3176 of file asterisk.c.

3177{
3178 struct passwd *pw = getpwuid(geteuid());
3179 int ret = 0;
3180 char *name = NULL;
3181
3182 if (!pw || ast_strlen_zero(pw->pw_dir)) {
3183 ast_log(LOG_ERROR, "Unable to determine home directory. History read/write disabled.\n");
3184 return;
3185 }
3186
3187 ret = ast_asprintf(&name, "%s/.asterisk_history", pw->pw_dir);
3188 if (ret <= 0) {
3189 ast_log(LOG_ERROR, "Unable to create history file name. History read/write disabled.\n");
3190 return;
3191 }
3192
3193 ret = readwrite(name);
3194 if (ret < 0) {
3195 ast_log(LOG_ERROR, "Unable to read or write history file '%s'\n", name);
3196 }
3197
3198 ast_free(name);
3199
3200 return;
3201}

References ast_asprintf, ast_free, ast_log, ast_strlen_zero(), LOG_ERROR, name, and NULL.

Referenced by ast_el_read_default_histfile(), and ast_el_write_default_histfile().

◆ publish_fully_booted()

static void publish_fully_booted ( void  )
static

Definition at line 977 of file asterisk.c.

978{
979 struct ast_json *json_object;
980 int uptime = 0;
981 int lastreloaded = 0;
982 struct timeval tmp;
983 struct timeval curtime = ast_tvnow();
984
985 if (ast_startuptime.tv_sec) {
986 tmp = ast_tvsub(curtime, ast_startuptime);
987 uptime = (int) tmp.tv_sec;
988 }
989
990 if (ast_lastreloadtime.tv_sec) {
991 tmp = ast_tvsub(curtime, ast_lastreloadtime);
992 lastreloaded = (int) tmp.tv_sec;
993 }
994
995 json_object = ast_json_pack("{s: s, s: i, s: i}",
996 "Status", "Fully Booted",
997 "Uptime", uptime,
998 "LastReload", lastreloaded);
999 ast_manager_publish_event("FullyBooted", EVENT_FLAG_SYSTEM, json_object);
1000 ast_json_unref(json_object);
1001}
void ast_manager_publish_event(const char *type, int class_type, struct ast_json *obj)
Publish an event to AMI.
Definition: manager.c:2024
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:602
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
Abstract JSON element (object, array, string, int, ...).
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2297

References ast_json_pack(), ast_json_unref(), ast_lastreloadtime, ast_manager_publish_event(), ast_startuptime, ast_tvnow(), ast_tvsub(), EVENT_FLAG_SYSTEM, and tmp().

Referenced by asterisk_daemon().

◆ quit_handler()

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

Definition at line 1907 of file asterisk.c.

1908{
1909 if (can_safely_quit(niceness, restart)) {
1910 really_quit(num, niceness, restart);
1911 /* No one gets here. */
1912 }
1913 /* It wasn't our time. */
1914}
static int can_safely_quit(shutdown_nice_t niceness, int restart)
Definition: asterisk.c:1959
static void really_quit(int num, shutdown_nice_t niceness, int restart)
Definition: asterisk.c:2042

References can_safely_quit(), and really_quit().

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

◆ rdtsc()

static __inline uint64_t rdtsc ( void  )
static

Definition at line 866 of file asterisk.c.

867{
868 return 0;
869}

Referenced by ast_mark().

◆ read_credentials()

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

read() function supporting the reception of user credentials.

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

Definition at line 1374 of file asterisk.c.

1375{
1376#if defined(SO_PEERCRED)
1377#ifdef HAVE_STRUCT_SOCKPEERCRED_UID
1378#define HAVE_STRUCT_UCRED_UID
1379 struct sockpeercred cred;
1380#else
1381 struct ucred cred;
1382#endif
1383 socklen_t len = sizeof(cred);
1384#endif
1385#if defined(HAVE_GETPEEREID)
1386 uid_t uid;
1387 gid_t gid;
1388#else
1389 int uid, gid;
1390#endif
1391 int result;
1392
1393 result = read(fd, buffer, size);
1394 if (result < 0) {
1395 return result;
1396 }
1397
1398#if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
1399 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
1400 return result;
1401 }
1402#if defined(HAVE_STRUCT_UCRED_UID)
1403 uid = cred.uid;
1404 gid = cred.gid;
1405#else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
1406 uid = cred.cr_uid;
1407 gid = cred.cr_gid;
1408#endif /* defined(HAVE_STRUCT_UCRED_UID) */
1409
1410#elif defined(HAVE_GETPEEREID)
1411 if (getpeereid(fd, &uid, &gid)) {
1412 return result;
1413 }
1414#else
1415 return result;
1416#endif
1417 con->uid = uid;
1418 con->gid = gid;
1419
1420 return result;
1421}
static PGresult * result
Definition: cel_pgsql.c:84

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

Referenced by netconsole().

◆ read_pjproject_startup_options()

static void read_pjproject_startup_options ( void  )
static

Definition at line 3406 of file asterisk.c.

3407{
3408 struct ast_config *cfg;
3409 struct ast_variable *v;
3410 struct ast_flags config_flags = {