Asterisk - The Open Source Telephony Project GIT-master-3dae2cf
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 2609 of file asterisk.c.

◆ CHAR_T_LIBEDIT

#define CHAR_T_LIBEDIT   wchar_t

Definition at line 2674 of file asterisk.c.

◆ CHAR_TO_LIBEDIT

#define CHAR_TO_LIBEDIT (   c)    btowc(c)

Definition at line 2675 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 895 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 3148 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 1921 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 1018 of file asterisk.c.

1019{
1020 struct ast_atexit *ae;
1021
1023 if (ae->func == func) {
1025 ast_free(ae);
1026 break;
1027 }
1028 }
1030}
#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 2215 of file asterisk.c.

2218{

◆ __quit_handler()

static void __quit_handler ( int  num)
static

Definition at line 2143 of file asterisk.c.

2144{
2145 sig_flags.need_quit = 1;
2147 fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
2148 }
2149 /* There is no need to restore the signal handler here, since the app
2150 * is going to exit */
2151}
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 2153 of file asterisk.c.

2154{
2155 sig_flags.need_quit = 1;
2156}

References sig_flags.

Referenced by ast_remotecontrol().

◆ _child_handler()

static void _child_handler ( int  sig)
static

Definition at line 1745 of file asterisk.c.

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

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

1082{
1083}

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

1713{
1714 return;
1715}

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

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

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

2289{
2290 while (*s) {
2291 if (*s > 32)
2292 return 0;
2293 s++;
2294 }
2295 return 1;
2296}

Referenced by consolehandler(), and remoteconsolehandler().

◆ ast_begin_shutdown()

static void ast_begin_shutdown ( void  )
static

Definition at line 1900 of file asterisk.c.

1901{
1904 shutdown_pending = 1;
1905 }
1907}
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:1094
#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 1882 of file asterisk.c.

1883{
1884 int shutdown_aborted = 0;
1885
1887 if (shuttingdown >= SHUTDOWN_FAST) {
1889 shutdown_pending = 0;
1890 shutdown_aborted = 1;
1891 }
1893 return shutdown_aborted;
1894}

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

2943{
2944 int idx = 1;
2945 /* find out how many entries can be put on one line, with two spaces between strings */
2946 int limit = ast_get_termcols(STDOUT_FILENO) / (max + 2);
2947
2948 if (limit == 0) {
2949 limit = 1;
2950 }
2951
2952 for (;;) {
2953 int numoutputline;
2954
2955 for (numoutputline = 0; numoutputline < limit && idx < AST_VECTOR_SIZE(matches); idx++) {
2956 numoutputline++;
2957 fprintf(stdout, "%-*s ", max, AST_VECTOR_GET(matches, idx));
2958 }
2959
2960 if (!numoutputline) {
2961 break;
2962 }
2963
2964 fprintf(stdout, "\n");
2965 }
2966}
#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 1357 of file asterisk.c.

1358{
1359 /* Send to the root console */
1360 fputs(string, stdout);
1361 fflush(stdout);
1362
1363 /* Send to any network console clients */
1364 ast_network_puts(string);
1365}
static void ast_network_puts(const char *string)
write the string to all attached console clients
Definition: asterisk.c:1341

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

1318{
1319 ast_console_puts_mutable_full(string, level, 0);
1320}
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:1324

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

1325{
1326 /* Send to the root console */
1328
1329 /* Wake up a poll()ing console */
1331 pthread_kill(consolethread, SIGURG);
1332 }
1333
1334 /* Send to any network console clients */
1335 ast_network_puts_mutable(message, level, sublevel);
1336}
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:1298
static pthread_t consolethread
Definition: asterisk.c:384
static int console_print(const char *s)
Definition: asterisk.c:2217
#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 1252 of file asterisk.c.

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

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

3151{
3152 HistEvent ev;
3153 char *stripped_buf;
3154
3155 if (el_hist == NULL || el == NULL) {
3157 }
3158 if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1)) {
3159 return 0;
3160 }
3161
3162 stripped_buf = ast_strip(ast_strdupa(buf));
3163
3164 /* HISTCONTROL=ignoredups */
3165 if (!history(el_hist, &ev, H_FIRST) && strcmp(ev.str, stripped_buf) == 0) {
3166 return 0;
3167 }
3168
3169 return history(el_hist, &ev, H_ENTER, stripped_buf);
3170}
static int ast_el_initialize(void)
Definition: asterisk.c:3095
static History * el_hist
Definition: asterisk.c:339
#define MAX_HISTORY_COMMAND_LENGTH
Definition: asterisk.c:3148
#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 3095 of file asterisk.c.

3096{
3097 HistEvent ev;
3098 char *editor, *editrc = getenv("EDITRC");
3099
3100 if (!(editor = getenv("AST_EDITMODE"))) {
3101 if (!(editor = getenv("AST_EDITOR"))) {
3102 editor = "emacs";
3103 }
3104 }
3105
3106 if (el != NULL)
3107 el_end(el);
3108 if (el_hist != NULL)
3109 history_end(el_hist);
3110
3111 el = el_init("asterisk", stdin, stdout, stderr);
3112 el_set(el, EL_PROMPT, cli_prompt);
3113
3114 el_set(el, EL_EDITMODE, 1);
3115 el_set(el, EL_EDITOR, editor);
3116 el_hist = history_init();
3117 if (!el || !el_hist)
3118 return -1;
3119
3120 /* setup history with 100 entries */
3121 history(el_hist, &ev, H_SETSIZE, 100);
3122
3123 el_set(el, EL_HIST, history, el_hist);
3124
3125 el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
3126 /* Bind <tab> to command completion */
3127 el_set(el, EL_BIND, "^I", "ed-complete", NULL);
3128 /* Bind ? to command completion */
3129 el_set(el, EL_BIND, "?", "ed-complete", NULL);
3130 /* Bind ^D to redisplay */
3131 el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
3132 /* Bind Delete to delete char left */
3133 el_set(el, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
3134 /* Bind Home and End to move to line start and end */
3135 el_set(el, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
3136 el_set(el, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
3137 /* Bind C-left and C-right to move by word (not all terminals) */
3138 el_set(el, EL_BIND, "\\eOC", "vi-next-word", NULL);
3139 el_set(el, EL_BIND, "\\eOD", "vi-prev-word", NULL);
3140
3141 if (editrc) {
3142 el_source(el, editrc);
3143 }
3144
3145 return 0;
3146}
static char * cli_complete(EditLine *editline, int ch)
Definition: asterisk.c:2969
static char * cli_prompt(EditLine *editline)
Definition: asterisk.c:2782

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

2682{
2683 int num_read = 0;
2684 int lastpos = 0;
2685 struct pollfd fds[2];
2686 int res;
2687 int max;
2688#define EL_BUF_SIZE 512
2689 char buf[EL_BUF_SIZE];
2690
2691 for (;;) {
2692 max = 1;
2693 fds[0].fd = ast_consock;
2694 fds[0].events = POLLIN;
2695 if (!ast_opt_exec) {
2696 fds[1].fd = STDIN_FILENO;
2697 fds[1].events = POLLIN;
2698 max++;
2699 }
2700 res = ast_poll(fds, max, -1);
2701 if (res < 0) {
2702 if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
2703 break;
2704 }
2705 if (errno == EINTR) {
2706 continue;
2707 }
2708 fprintf(stderr, "poll failed: %s\n", strerror(errno));
2709 break;
2710 }
2711
2712 if (!ast_opt_exec && fds[1].revents) {
2713 char c = '\0';
2714
2715 num_read = read(STDIN_FILENO, &c, 1);
2716 if (num_read < 1) {
2717 break;
2718 }
2719
2720 *cp = CHAR_TO_LIBEDIT(c);
2721
2722 return num_read;
2723 }
2724
2725 if (fds[0].revents) {
2726 res = read(ast_consock, buf, sizeof(buf) - 1);
2727 /* if the remote side disappears exit */
2728 if (res < 1) {
2729 fprintf(stderr, "\nDisconnected from Asterisk server\n");
2730 if (!ast_opt_reconnect) {
2732 } else {
2733 int tries;
2734 int reconnects_per_second = 20;
2735
2736 fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
2737 for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
2738 if (ast_tryconnect()) {
2739 fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
2740 printf("%s", term_quit());
2743 break;
2744 }
2745
2746 usleep(1000000 / reconnects_per_second);
2747 }
2748 if (tries >= 30 * reconnects_per_second) {
2749 fprintf(stderr, "Failed to reconnect for 30 seconds. Quitting.\n");
2751 }
2752 }
2753 continue;
2754 }
2755
2756 buf[res] = '\0';
2757
2758 /* Write over the CLI prompt */
2759 if (!ast_opt_exec && !lastpos) {
2760 if (write(STDOUT_FILENO, "\r␛[0K", 5) < 0) {
2761 }
2762 }
2763
2765
2766 if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (res >= 2 && buf[res-2] == '\n'))) {
2767 *cp = CHAR_TO_LIBEDIT(CC_REFRESH);
2768
2769 return 1;
2770 }
2771 lastpos = 1;
2772 }
2773 }
2774
2775 *cp = CHAR_TO_LIBEDIT('\0');
2776
2777 return 0;
2778}
#define WELCOME_MESSAGE
Welcome message when starting a CLI interface.
Definition: asterisk.c:303
static void send_rasterisk_connect_commands(void)
Definition: asterisk.c:2645
#define CHAR_TO_LIBEDIT(c)
Definition: asterisk.c:2675
static void quit_handler(int num, shutdown_nice_t niceness, int restart)
Definition: asterisk.c:1912
#define EL_BUF_SIZE
static int ast_tryconnect(void)
Definition: asterisk.c:1685
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 3225 of file asterisk.c.

3226{
3228}
static int ast_el_read_history(const char *)
Definition: asterisk.c:3182
static void process_histfile(int(*readwrite)(const char *filename))
Definition: asterisk.c:3198

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

3183{
3184 HistEvent ev;
3185
3186 if (el_hist == NULL || el == NULL) {
3188 }
3189
3190 if (access(filename, F_OK) == 0) {
3191 return history(el_hist, &ev, H_LOAD, filename);
3192 }
3193
3194 /* If the history file doesn't exist, failing to read it is unremarkable. */
3195 return 0;
3196}

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

2909{
2910 char *retstr;
2911 struct ast_vector_string *vec = ast_calloc(1, sizeof(*vec));
2912
2913 if (!vec) {
2914 return NULL;
2915 }
2916
2917 while ((retstr = strsep(&buf, " "))) {
2918 if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
2919 break;
2920 }
2921
2922 retstr = ast_strdup(retstr);
2923 if (!retstr || AST_VECTOR_APPEND(vec, retstr)) {
2924 ast_free(retstr);
2925 goto vector_cleanup;
2926 }
2927 }
2928
2929 if (!AST_VECTOR_SIZE(vec)) {
2930 goto vector_cleanup;
2931 }
2932
2933 return vec;
2934
2935vector_cleanup:
2938
2939 return NULL;
2940}
#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 3230 of file asterisk.c.

3231{
3233}
static int ast_el_write_history(const char *)
Definition: asterisk.c:3172

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

3173{
3174 HistEvent ev;
3175
3176 if (el_hist == NULL || el == NULL)
3178
3179 return (history(el_hist, &ev, H_SAVE, filename));
3180}

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

1600{
1601 struct sockaddr_un sunaddr;
1602 int res;
1603 int x;
1604 uid_t uid = -1;
1605 gid_t gid = -1;
1606
1607 for (x = 0; x < AST_MAX_CONNECTS; x++) {
1608 consoles[x].fd = -1;
1609 }
1610
1611 if (ast_socket_is_sd) {
1613
1614 goto start_lthread;
1615 }
1616
1617 unlink(ast_config_AST_SOCKET);
1618 ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
1619 if (ast_socket < 0) {
1620 ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
1621 return -1;
1622 }
1623 memset(&sunaddr, 0, sizeof(sunaddr));
1624 sunaddr.sun_family = AF_LOCAL;
1625 ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
1626 res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
1627 if (res) {
1628 ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1629 close(ast_socket);
1630 ast_socket = -1;
1631 return -1;
1632 }
1633 res = listen(ast_socket, 2);
1634 if (res < 0) {
1635 ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1636 close(ast_socket);
1637 ast_socket = -1;
1638 return -1;
1639 }
1640
1641start_lthread:
1643 ast_log(LOG_WARNING, "Unable to create listener thread.\n");
1644 close(ast_socket);
1645 return -1;
1646 }
1647
1648 if (ast_socket_is_sd) {
1649 /* owner/group/permissions are set by systemd, we might not even have access
1650 * to socket file so leave it alone */
1651 return 0;
1652 }
1653
1655 struct passwd *pw;
1656 if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
1657 ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
1658 else
1659 uid = pw->pw_uid;
1660 }
1661
1663 struct group *grp;
1664 if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
1665 ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
1666 else
1667 gid = grp->gr_gid;
1668 }
1669
1670 if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
1671 ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1672
1674 unsigned int p1;
1675 mode_t p;
1676 sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
1677 p = p1;
1678 if ((chmod(ast_config_AST_SOCKET, p)) < 0)
1679 ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
1680 }
1681
1682 return 0;
1683}
static int ast_socket_is_sd
Definition: asterisk.c:313
static pthread_t lthread
Definition: asterisk.c:1367
#define PF_LOCAL
Definition: asterisk.c:293
static void * listener(void *unused)
Definition: asterisk.c:1519
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 874 of file asterisk.c.

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

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

1342{
1343 int x;
1344
1345 for (x = 0; x < AST_MAX_CONNECTS; ++x) {
1346 if (consoles[x].fd < 0) {
1347 continue;
1348 }
1349 fdprint(consoles[x].p[1], string);
1350 }
1351}
static int fdprint(int fd, const char *s)
Definition: asterisk.c:1075

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

1299{
1300 int x;
1301
1302 for (x = 0; x < AST_MAX_CONNECTS; ++x) {
1303 if (consoles[x].fd < 0
1304 || consoles[x].mute
1305 || consoles[x].levels[level]
1306 || (level == __LOG_VERBOSE && consoles[x].option_verbose < sublevel)) {
1307 continue;
1308 }
1309 fdprint(consoles[x].p[1], string);
1310 }
1311}
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:214

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

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

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

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

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

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

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

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

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:2752

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

3236{
3237 char buf[256] = "";
3238 int res;
3239 char *hostname;
3240 char *cpid;
3241 char *version;
3242 int pid;
3243 char *stringp = NULL;
3244
3245 char *ebuf;
3246 int num = 0;
3247
3248 ast_term_init();
3249 printf("%s", term_end());
3250 fflush(stdout);
3251
3252 memset(&sig_flags, 0, sizeof(sig_flags));
3253 signal(SIGINT, __remote_quit_handler);
3254 signal(SIGTERM, __remote_quit_handler);
3255 signal(SIGHUP, __remote_quit_handler);
3256
3257 if (read(ast_consock, buf, sizeof(buf) - 1) < 0) {
3258 ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
3259 return;
3260 }
3261 if (data) {
3262 char prefix[] = "cli quit after ";
3263 char *tmp = ast_alloca(strlen(data) + strlen(prefix) + 1);
3264 sprintf(tmp, "%s%s", prefix, data);
3265 if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
3266 ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
3267 if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
3268 return;
3269 }
3270 }
3271 }
3272 stringp = buf;
3273 hostname = strsep(&stringp, "/");
3274 cpid = strsep(&stringp, "/");
3275 version = strsep(&stringp, "\n");
3276 if (!version)
3277 version = "<Version Unknown>";
3278 stringp = hostname;
3279 strsep(&stringp, ".");
3280 if (cpid)
3281 pid = atoi(cpid);
3282 else
3283 pid = -1;
3284 if (!data) {
3286 }
3287
3288 if (ast_opt_exec && data) { /* hack to print output then exit if asterisk -rx is used */
3289 int linefull = 1, prev_linefull = 1, prev_line_verbose = 0;
3290 struct pollfd fds;
3291 fds.fd = ast_consock;
3292 fds.events = POLLIN;
3293 fds.revents = 0;
3294
3295 while (ast_poll(&fds, 1, 60000) > 0) {
3296 char buffer[512] = "", *curline = buffer, *nextline;
3297 int not_written = 1;
3298
3299 if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
3300 break;
3301 }
3302
3303 if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
3304 break;
3305 }
3306
3307 do {
3308 prev_linefull = linefull;
3309 if ((nextline = strchr(curline, '\n'))) {
3310 linefull = 1;
3311 nextline++;
3312 } else {
3313 linefull = 0;
3314 nextline = strchr(curline, '\0');
3315 }
3316
3317 /* Skip verbose lines */
3318 /* Prev line full? | Line is verbose | Last line verbose? | Print
3319 * TRUE | TRUE* | TRUE | FALSE
3320 * TRUE | TRUE* | FALSE | FALSE
3321 * TRUE | FALSE* | TRUE | TRUE
3322 * TRUE | FALSE* | FALSE | TRUE
3323 * FALSE | TRUE | TRUE* | FALSE
3324 * FALSE | TRUE | FALSE* | TRUE
3325 * FALSE | FALSE | TRUE* | FALSE
3326 * FALSE | FALSE | FALSE* | TRUE
3327 */
3328 if ((!prev_linefull && !prev_line_verbose) || (prev_linefull && *curline > 0)) {
3329 prev_line_verbose = 0;
3330 not_written = 0;
3331 if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
3332 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
3333 }
3334 } else {
3335 prev_line_verbose = 1;
3336 }
3337 curline = nextline;
3338 } while (!ast_strlen_zero(curline));
3339
3340 /* No non-verbose output in 60 seconds. */
3341 if (not_written) {
3342 break;
3343 }
3344 }
3345 return;
3346 }
3347
3348 ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
3350
3352 if (el_hist == NULL || el == NULL)
3355
3356 el_set(el, EL_GETCFN, ast_el_read_char);
3357
3358 for (;;) {
3359 ebuf = (char *)el_gets(el, &num);
3360
3361 if (sig_flags.need_quit || sig_flags.need_quit_handler || sig_flags.need_el_end) {
3362 break;
3363 }
3364
3365 if (!ebuf && write(1, "", 1) < 0)
3366 break;
3367
3368 if (!ast_strlen_zero(ebuf)) {
3369 if (ebuf[strlen(ebuf)-1] == '\n')
3370 ebuf[strlen(ebuf)-1] = '\0';
3371 if (!remoteconsolehandler(ebuf)) {
3372 res = write(ast_consock, ebuf, strlen(ebuf) + 1);
3373 if (res < 1) {
3374 ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
3375 break;
3376 }
3377 }
3378 }
3379 }
3380 printf("\nDisconnected from Asterisk server\n");
3381}
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:2153
static int remoteconsolehandler(const char *s)
Definition: asterisk.c:2317
static int ast_el_read_char(EditLine *editline, CHAR_T_LIBEDIT *cp)
Definition: asterisk.c:2681
static void ast_el_read_default_histfile(void)
Definition: asterisk.c:3225
#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
void ast_init_logger_for_socket_console(void)
load logger.conf configuration for console socket connections
Definition: logger.c:713
static char prefix[MAX_PREFIX]
Definition: http.c:144
#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 1101 of file asterisk.c.

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

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

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

1224{
1225 pid_t pid = safe_exec_prep(dualfork);
1226
1227 if (pid == 0) {
1228 execvp(file, argv);
1229 _exit(1);
1230 /* noreturn from _exit */
1231 }
1232
1233 return safe_exec_wait(pid);
1234}
static int safe_exec_wait(pid_t pid)
wait for spawned application to complete and unreplace sigchld
Definition: asterisk.c:1197
static pid_t safe_exec_prep(int dualfork)
fork and perform other preparations for spawning applications
Definition: asterisk.c:1136

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

1237{
1238 pid_t pid = safe_exec_prep(0);
1239
1240 if (pid == 0) {
1241 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
1242 _exit(1);
1243 /* noreturn from _exit */
1244 }
1245
1246 return safe_exec_wait(pid);
1247}

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

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

1873{
1875}

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(), session_inv_on_tsx_state_changed(), and unload_module().

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

1878{
1879 return shutdown_pending;
1880}

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

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

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

1062{
1066}
static void __ast_unregister_atexit(void(*func)(void))
Definition: asterisk.c:1018

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

1117{
1118 unsigned int level;
1119
1121
1122 /* Wrapping around here is an error */
1124
1125 level = --safe_system_level;
1126
1127 /* only restore the handler if we are the last one */
1128 if (level == 0) {
1129 sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
1130 }
1131
1133}

References ast_assert, 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 4087 of file asterisk.c.

4088{
4089 FILE *f;
4090 sigset_t sigs;
4091 int num;
4092 char *buf;
4093 char pbx_uuid[AST_UUID_STR_LEN];
4094
4095 /* Set time as soon as possible */
4097
4098 /* This needs to remain as high up in the initial start up as possible.
4099 * daemon causes a fork to occur, which has all sorts of unintended
4100 * consequences for things that interact with threads. This call *must*
4101 * occur before anything in Asterisk spawns or manipulates thread related
4102 * primitives. */
4103#if HAVE_WORKING_FORK
4105#ifndef HAVE_SBIN_LAUNCHD
4106 if (daemon(1, 0) < 0) {
4107 fprintf(stderr, "daemon() failed: %s\n", strerror(errno));
4108 } else {
4109 ast_mainpid = getpid();
4110 }
4111#else
4112 fprintf(stderr, "Mac OS X detected. Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
4113#endif
4114 }
4115#endif
4116
4117 /* At this point everything has been forked successfully,
4118 * we have determined that we aren't attempting to connect to
4119 * an Asterisk instance, and that there isn't one already running. */
4121
4123
4124 /* Check whether high prio was successfully set by us or some
4125 * other incantation. */
4126 if (has_priority()) {
4128 } else {
4130 }
4131
4132 /* Spawning of astcanary must happen AFTER the call to daemon(3) */
4134 snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
4135
4136 /* Don't let the canary child kill Asterisk, if it dies immediately */
4137 sigaction(SIGPIPE, &ignore_sig_handler, NULL);
4138
4139 canary_pid = fork();
4140 if (canary_pid == 0) {
4141 char canary_binary[PATH_MAX], ppid[12];
4142
4143 /* Reset signal handler */
4144 signal(SIGCHLD, SIG_DFL);
4145 signal(SIGPIPE, SIG_DFL);
4146
4149 snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid);
4150
4151 /* Use the astcanary binary that we installed */
4152 snprintf(canary_binary, sizeof(canary_binary), "%s/astcanary", ast_config_AST_SBIN_DIR);
4153 execl(canary_binary, "astcanary", canary_filename, ppid, (char *)NULL);
4154
4155 /* Should never happen */
4156 _exit(1);
4157 } else if (canary_pid > 0) {
4158 pthread_t dont_care;
4160 }
4161
4162 /* Kill the canary when we exit */
4164 }
4165
4166 /* Blindly write the PID file. */
4167 unlink(ast_config_AST_PID);
4168 f = fopen(ast_config_AST_PID, "w");
4169 if (f) {
4170 fprintf(f, "%ld\n", (long)ast_mainpid);
4171 fclose(f);
4172 } else {
4173 fprintf(stderr, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
4174 }
4175
4176 /* Initialize the terminal. Since all processes have been forked,
4177 * we can now start using the standard log messages.
4178 */
4179 ast_term_init();
4180 printf("%s", term_end());
4181 fflush(stdout);
4182
4183 print_intro_message(runuser, rungroup);
4184
4186
4187 check_init(astobj2_init(), "AO2");
4188 check_init(ast_named_locks_init(), "Named Locks");
4189
4190 if (ast_opt_console) {
4191 if (el_hist == NULL || el == NULL)
4194 }
4195
4196#ifdef AST_XML_DOCS
4197 /* Load XML documentation. */
4199#endif
4200
4201 check_init(astdb_init(), "ASTdb");
4202
4203 ast_uuid_init();
4204
4205 if (ast_pbx_uuid_get(pbx_uuid, sizeof(pbx_uuid))) {
4206 ast_uuid_generate_str(pbx_uuid, sizeof(pbx_uuid));
4207 ast_db_put("pbx", "UUID", pbx_uuid);
4208 }
4209 ast_verb(0, "PBX UUID: %s\n", pbx_uuid);
4210
4211 check_init(ast_json_init(), "libjansson");
4212 ast_ulaw_init();
4213 ast_alaw_init();
4214 ast_utf8_init();
4215 tdd_init();
4216 callerid_init();
4218
4219 check_init(ast_utils_init(), "Utilities");
4220 check_init(ast_tps_init(), "Task Processor Core");
4221 check_init(ast_fd_init(), "File Descriptor Debugging");
4222 check_init(ast_pbx_init(), "ast_pbx_init");
4223 check_init(aco_init(), "Configuration Option Framework");
4224 check_init(stasis_init(), "Stasis");
4225#ifdef TEST_FRAMEWORK
4226 check_init(ast_test_init(), "Test Framework");
4227#endif
4228 check_init(ast_translate_init(), "Translator Core");
4229
4231
4232 check_init(ast_sorcery_init(), "Sorcery");
4233 check_init(ast_codec_init(), "Codecs");
4234 check_init(ast_format_init(), "Formats");
4235 check_init(ast_format_cache_init(), "Format Cache");
4236 check_init(ast_codec_builtin_init(), "Built-in Codecs");
4237 check_init(ast_bucket_init(), "Bucket API");
4238 check_init(ast_stasis_system_init(), "Stasis system-level information");
4239 check_init(ast_endpoint_stasis_init(), "Stasis Endpoint");
4240
4242 /* GCC 4.9 gives a bogus "right-hand operand of comma expression has
4243 * no effect" warning */
4244 (void) sigemptyset(&sigs);
4245 (void) sigaddset(&sigs, SIGHUP);
4246 (void) sigaddset(&sigs, SIGTERM);
4247 (void) sigaddset(&sigs, SIGINT);
4248 (void) sigaddset(&sigs, SIGPIPE);
4249 (void) sigaddset(&sigs, SIGWINCH);
4250 pthread_sigmask(SIG_BLOCK, &sigs, NULL);
4251 sigaction(SIGURG, &urg_handler, NULL);
4252 signal(SIGINT, __quit_handler);
4253 signal(SIGTERM, __quit_handler);
4254 sigaction(SIGHUP, &hup_handler, NULL);
4255 sigaction(SIGPIPE, &ignore_sig_handler, NULL);
4256
4257 /* ensure that the random number generators are seeded with a different value every time
4258 Asterisk is started
4259 */
4260 srand((unsigned int) getpid() + (unsigned int) time(NULL));
4261 initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
4262
4264
4265 check_init(init_logger(), "Logger");
4266 check_init(ast_rtp_engine_init(), "RTP Engine");
4267
4269
4270 check_init(ast_timing_init(), "Timing");
4271 check_init(ast_ssl_init(), "SSL");
4273 check_init(ast_pj_init(), "Embedded PJProject");
4274 check_init(app_init(), "App Core");
4275 check_init(mwi_init(), "MWI Core");
4276 check_init(devstate_init(), "Device State Core");
4277 check_init(ast_msg_init(), "Messaging API");
4278 check_init(ast_channels_init(), "Channel");
4279 check_init(ast_endpoint_init(), "Endpoints");
4280 check_init(ast_pickup_init(), "Call Pickup");
4281 check_init(ast_bridging_init(), "Bridging");
4282 check_init(ast_parking_stasis_init(), "Parking Core");
4283 check_init(ast_device_state_engine_init(), "Device State Engine");
4284 check_init(ast_presence_state_engine_init(), "Presence State Engine");
4285 check_init(dns_core_init(), "DNS Resolver Core");
4286 check_init(ast_dns_system_resolver_init(), "Default DNS resolver");
4287 check_init(ast_security_stasis_init(), "Security Stasis Topic and Events");
4288 check_init(ast_image_init(), "Image");
4289 check_init(ast_file_init(), "Generic File Format Support");
4290 check_init(load_pbx(), "load_pbx");
4291 check_init(load_pbx_builtins(), "Builtin PBX Applications");
4292 check_init(load_pbx_functions_cli(), "PBX Functions Support");
4293 check_init(load_pbx_variables(), "PBX Variables Support");
4294 check_init(load_pbx_switch(), "PBX Switch Support");
4295 check_init(load_pbx_app(), "PBX Application Support");
4296 check_init(load_pbx_hangup_handler(), "PBX Hangup Handler Support");
4297 check_init(ast_local_init(), "Local Proxy Channel Driver");
4298 check_init(ast_refer_init(), "Refer API");
4299
4300 /* We should avoid most config loads before this point as they can't use realtime. */
4301 check_init(load_modules(), "Module");
4302
4303 /*
4304 * This has to load after the dynamic modules load, as items in the media
4305 * cache can't be constructed from items in the AstDB without their
4306 * bucket backends.
4307 */
4308 check_init(ast_media_cache_init(), "Media Cache");
4309
4310 /* loads the cli_permissions.conf file needed to implement cli restrictions. */
4312 ast_cli_channels_init(); /* Not always safe to access CLI commands until startup is complete. */
4313
4314 ast_stun_init();
4315
4317
4318 if (ast_opt_no_fork) {
4319 consolethread = pthread_self();
4320 }
4321
4323
4325
4328
4329 pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
4330
4332
4336
4338 ast_sd_notify("READY=1");
4339
4340 ast_verb(0, COLORIZE_FMT "\n", COLORIZE(COLOR_BRGREEN, 0, "Asterisk Ready."));
4341
4343
4344 if (ast_opt_console) {
4345 /* Console stuff now... */
4346 /* Register our quit function */
4347 char title[296];
4348 char hostname[MAXHOSTNAMELEN] = "";
4349
4350 if (gethostname(hostname, sizeof(hostname) - 1)) {
4351 ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
4352 }
4353
4355
4356 set_icon("Asterisk");
4357 snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
4358 set_title(title);
4359
4360 el_set(el, EL_GETCFN, ast_el_read_char);
4361
4362 for (;;) {
4363 if (sig_flags.need_el_end) {
4364 el_end(el);
4365
4366 return;
4367 }
4368
4369 if (sig_flags.need_quit || sig_flags.need_quit_handler) {
4371 break;
4372 }
4373 buf = (char *) el_gets(el, &num);
4374
4375 if (!buf && write(1, "", 1) < 0)
4376 return; /* quit */
4377
4378 if (buf) {
4379 if (buf[strlen(buf)-1] == '\n')
4380 buf[strlen(buf)-1] = '\0';
4381
4383 }
4384 }
4385 }
4386
4387 /* Stall until a quit signal is given */
4389}
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:1566
int ast_bridging_init(void)
Initialize the bridging system.
Definition: bridge.c:5543
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:2508
void ast_cli_channels_init(void)
Definition: main/cli.c:2252
void logger_queue_start(void)
Start the ast_queue_log() logger.
Definition: logger.c:2186
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:1256
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:1139
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:3840
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:8029
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:2245
void ast_autoservice_init(void)
Definition: autoservice.c:387
int init_logger(void)
Definition: logger.c:2202
int ast_endpoint_init(void)
Endpoint support initialization.
int dns_core_init(void)
Definition: dns_core.c:616
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:2112
int ast_file_init(void)
Definition: file.c:2051
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:341
static void canary_exit(void)
Definition: asterisk.c:3516
static void check_init(int init_result, const char *name)
Definition: asterisk.c:4074
static void publish_fully_booted(void)
Definition: asterisk.c:978
static void main_atexit(void)
Definition: asterisk.c:3579
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:1056
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:1842
static int has_priority(void)
Check whether we were set to high(er) priority.
Definition: asterisk.c:1779
static struct sigaction hup_handler
Definition: asterisk.c:1740
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:973
struct timeval ast_lastreloadtime
Definition: asterisk.c:337
static void * monitor_sig_flags(void *unused)
Definition: asterisk.c:3462
static void consolehandler(const char *s)
Definition: asterisk.c:2299
static struct ast_cli_entry cli_asterisk_shutdown[]
Shutdown Asterisk CLI commands.
Definition: asterisk.c:2619
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:1051
static void set_title(char *text)
Set an X-term or screen title.
Definition: asterisk.c:1766
static int ast_makesocket(void)
Definition: asterisk.c:1599
static int canary_pid
Definition: asterisk.c:386
static void * canary_thread(void *unused)
Definition: asterisk.c:3487
static struct ast_cli_entry cli_asterisk[]
Definition: asterisk.c:2628
static void run_startup_commands(void)
Definition: asterisk.c:3526
struct timeval ast_startuptime
Definition: asterisk.c:336
static void read_pjproject_startup_options(void)
Definition: asterisk.c:3428
pid_t ast_mainpid
Definition: asterisk.c:315
static void __quit_handler(int num)
Definition: asterisk.c:2143
static void set_icon(char *text)
Definition: asterisk.c:1772
static void print_intro_message(const char *runuser, const char *rungroup)
Definition: asterisk.c:3566
static struct sigaction ignore_sig_handler
Definition: asterisk.c:1090
static struct sigaction urg_handler
Definition: asterisk.c:1717
int ast_pbx_init(void)
Definition: pbx.c:8989
int ast_fd_init(void)
Definition: astfd.c:371
#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:116
#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:3365
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:3202
int register_config_cli(void)
Exposed initialization method for core process.
Definition: main/config.c:4243
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:726
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:3062
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:1675
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:2617
#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 1964 of file asterisk.c.

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

3517{
3518 if (canary_pid > 0) {
3519 int status;
3520 kill(canary_pid, SIGKILL);
3521 waitpid(canary_pid, &status, 0);
3522 }
3523}

References canary_pid, and status.

Referenced by asterisk_daemon().

◆ canary_thread()

static void * canary_thread ( void *  unused)
static

Definition at line 3487 of file asterisk.c.

3488{
3489 struct stat canary_stat;
3490 struct timeval now;
3491
3492 /* Give the canary time to sing */
3493 sleep(120);
3494
3495 for (;;) {
3496 now = ast_tvnow();
3497 if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
3499 "The canary is no more. He has ceased to be! "
3500 "He's expired and gone to meet his maker! "
3501 "He's a stiff! Bereft of life, he rests in peace. "
3502 "His metabolic processes are now history! He's off the twig! "
3503 "He's kicked the bucket. He's shuffled off his mortal coil, "
3504 "run down the curtain, and joined the bleeding choir invisible!! "
3505 "THIS is an EX-CANARY. (Reducing priority)\n");
3507 pthread_exit(NULL);
3508 }
3509
3510 /* Check the canary once a minute */
3511 sleep(60);
3512 }
3513}
static int set_priority_all(int pri)
Set priority on all known threads.
Definition: asterisk.c:1799

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

4075{
4076 if (init_result) {
4078 ast_log(LOG_ERROR, "%s initialization failed. ASTERISK EXITING!\n%s", name, term_quit());
4079 } else {
4080 fprintf(stderr, "%s initialization failed. ASTERISK EXITING!\n%s", name, term_quit());
4081 }
4082 ast_run_atexits(0);
4083 exit(init_result == -2 ? 2 : 1);
4084 }
4085}
static void ast_run_atexits(int run_cleanups)
Definition: asterisk.c:1004
int ast_is_logger_initialized(void)
Test if logger is initialized.
Definition: logger.c:2175

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

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

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

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

2209{
2210 struct console_state_data *state = ptr;
2211 state->verbose_line_level = 0;
2212 return 0;
2213}

◆ consolehandler()

static void consolehandler ( const char *  s)
static

Definition at line 2299 of file asterisk.c.

2300{
2301 printf("%s", term_end());
2302 fflush(stdout);
2303
2304 /* Called when readline data is available */
2305 if (!ast_all_zeros(s))
2307 /* The real handler for bang */
2308 if (s[0] == '!') {
2309 if (s[1])
2310 ast_safe_system(s+1);
2311 else
2312 ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
2313 } else
2314 ast_cli_command(STDOUT_FILENO, s);
2315}
static int ast_el_add_history(const char *)
Definition: asterisk.c:3150
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: asterisk.c:1236
static int ast_all_zeros(const char *s)
Definition: asterisk.c:2288
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 3554 of file asterisk.c.

3555{
3556 setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
3557 setenv("AST_BUILD_HOST", ast_build_hostname, 1);
3558 setenv("AST_BUILD_DATE", ast_build_date, 1);
3559 setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
3560 setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
3561 setenv("AST_BUILD_OS", ast_build_os, 1);
3562 setenv("AST_BUILD_USER", ast_build_user, 1);
3563 setenv("AST_VERSION", ast_get_version(), 1);
3564}
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 1075 of file asterisk.c.

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

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

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

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

2492{
2493 switch (cmd) {
2494 case CLI_INIT:
2495 e->command = "core abort shutdown";
2496 e->usage =
2497 "Usage: core abort shutdown\n"
2498 " Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
2499 " call operations.\n";
2501 return NULL;
2502 case CLI_GENERATE:
2503 return NULL;
2504 }
2505
2506 if (a->argc != e->args)
2507 return CLI_SHOWUSAGE;
2508
2510
2511 return CLI_SUCCESS;
2512}
int ast_cancel_shutdown(void)
Cancel an existing shutdown and return to normal operation.
Definition: asterisk.c:1882
#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:3068
@ 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 2514 of file asterisk.c.

2515{
2516 switch (cmd) {
2517 case CLI_INIT:
2518 e->command = "!";
2519 e->usage =
2520 "Usage: !<command>\n"
2521 " Executes a given shell command\n";
2522 return NULL;
2523 case CLI_GENERATE:
2524 return NULL;
2525 }
2526
2527 return CLI_SUCCESS;
2528}

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

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

2450{
2451 switch (cmd) {
2452 case CLI_INIT:
2453 e->command = "core restart gracefully";
2454 e->usage =
2455 "Usage: core restart gracefully\n"
2456 " Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
2457 " restart when all active calls have ended.\n";
2459 return NULL;
2460 case CLI_GENERATE:
2461 return NULL;
2462 }
2463
2464 if (a->argc != e->args)
2465 return CLI_SHOWUSAGE;
2466 quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
2467 return CLI_SUCCESS;
2468}

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

2429{
2430 switch (cmd) {
2431 case CLI_INIT:
2432 e->command = "core restart now";
2433 e->usage =
2434 "Usage: core restart now\n"
2435 " Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
2436 " restart.\n";
2438 return NULL;
2439 case CLI_GENERATE:
2440 return NULL;
2441 }
2442
2443 if (a->argc != e->args)
2444 return CLI_SHOWUSAGE;
2445 quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
2446 return CLI_SUCCESS;
2447}

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

2471{
2472 switch (cmd) {
2473 case CLI_INIT:
2474 e->command = "core restart when convenient";
2475 e->usage =
2476 "Usage: core restart when convenient\n"
2477 " Causes Asterisk to perform a cold restart when all active calls have ended.\n";
2479 return NULL;
2480 case CLI_GENERATE:
2481 return NULL;
2482 }
2483
2484 if (a->argc != e->args)
2485 return CLI_SHOWUSAGE;
2486 ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
2487 quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
2488 return CLI_SUCCESS;
2489}

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

909{
910 int i, min, max;
911 const char *search = NULL;
912 switch (cmd) {
913 case CLI_INIT:
914 e->command = "core show profile";
915 e->usage = "Usage: core show profile\n"
916 " show profile information";
917 return NULL;
918 case CLI_GENERATE:
919 return NULL;
920 }
921
922 if (prof_data == NULL)
923 return 0;
924
926 ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
928 ast_cli(a->fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events",
929 "Value", "Average", "Name");
930 for (i = min; i < max; i++) {
931 struct profile_entry *entry = &prof_data->e[i];
932 if (!search || strstr(entry->name, search))
933 ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n",
934 i,
935 (long)entry->scale,
936 (long)entry->events, (long long)entry->value,
937 (long long)(entry->events ? entry->value / entry->events : entry->value),
938 entry->name);
939 }
940 return CLI_SUCCESS;
941}
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, " Cache directory: %s\n", ast_config_AST_CACHE_DIR);
600 ast_cli(a->fd, "\n\n");
601 return CLI_SUCCESS;
602}
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:2927
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:683
int ast_webmanager_check_enabled(void)
Check if AMI/HTTP is enabled.
Definition: manager.c:688
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:3551
int ast_verb_console_get(void)
Get this thread's console verbosity level.
Definition: logger.c:2673
#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_CACHE_DIR
Definition: options.c:150
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:2839
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_CACHE_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 670 of file asterisk.c.

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

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

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

2387{
2388 switch (cmd) {
2389 case CLI_INIT:
2390 e->command = "core stop gracefully";
2391 e->usage =
2392 "Usage: core stop gracefully\n"
2393 " Causes Asterisk to not accept new calls, and exit when all\n"
2394 " active calls have terminated normally.\n";
2396 return NULL;
2397 case CLI_GENERATE:
2398 return NULL;
2399 }
2400
2401 if (a->argc != e->args)
2402 return CLI_SHOWUSAGE;
2403 quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
2404 return CLI_SUCCESS;
2405}

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

2367{
2368 switch (cmd) {
2369 case CLI_INIT:
2370 e->command = "core stop now";
2371 e->usage =
2372 "Usage: core stop now\n"
2373 " Shuts down a running Asterisk immediately, hanging up all active calls .\n";
2375 return NULL;
2376 case CLI_GENERATE:
2377 return NULL;
2378 }
2379
2380 if (a->argc != e->args)
2381 return CLI_SHOWUSAGE;
2382 quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
2383 return CLI_SUCCESS;
2384}

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

2408{
2409 switch (cmd) {
2410 case CLI_INIT:
2411 e->command = "core stop when convenient";
2412 e->usage =
2413 "Usage: core stop when convenient\n"
2414 " Causes Asterisk to perform a shutdown when all active calls have ended.\n";
2416 return NULL;
2417 case CLI_GENERATE:
2418 return NULL;
2419 }
2420
2421 if (a->argc != e->args)
2422 return CLI_SHOWUSAGE;
2423 ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
2424 quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
2425 return CLI_SUCCESS;
2426}

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

2346{
2347 switch (cmd) {
2348 case CLI_INIT:
2349 e->command = "core show version";
2350 e->usage =
2351 "Usage: core show version\n"
2352 " Shows Asterisk version information.\n";
2353 return NULL;
2354 case CLI_GENERATE:
2355 return NULL;
2356 }
2357
2358 if (a->argc != 3)
2359 return CLI_SHOWUSAGE;
2360 ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
2363 return CLI_SUCCESS;
2364}

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

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

Referenced by ast_ari_validate_dialplan_cep(), and asterisk_daemon().

◆ listener()

static void * listener ( void *  unused)
static

Definition at line 1519 of file asterisk.c.

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

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

3580{
3582}
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 3462 of file asterisk.c.

3463{
3464 for (;;) {
3465 struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
3466
3467 ast_poll(&p, 1, -1);
3468 if (sig_flags.need_reload) {
3469 sig_flags.need_reload = 0;
3471 }
3472 if (sig_flags.need_quit) {
3473 sig_flags.need_quit = 0;
3474 if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
3475 sig_flags.need_quit_handler = 1;
3476 pthread_kill(consolethread, SIGURG);
3477 } else {
3479 }
3480 }
3482 }
3483
3484 return NULL;
3485}
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:1721

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

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

3567{
3570 if (runuser) {
3571 ast_verbose("Running as user '%s'\n", runuser);
3572 }
3573 if (rungroup) {
3574 ast_verbose("Running under group '%s'\n", rungroup);
3575 }
3576 }
3577}

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

3199{
3200 struct passwd *pw = getpwuid(geteuid());
3201 int ret = 0;
3202 char *name = NULL;
3203
3204 if (!pw || ast_strlen_zero(pw->pw_dir)) {
3205 ast_log(LOG_ERROR, "Unable to determine home directory. History read/write disabled.\n");
3206 return;
3207 }
3208
3209 ret = ast_asprintf(&name, "%s/.asterisk_history", pw->pw_dir);
3210 if (ret <= 0) {
3211 ast_log(LOG_ERROR, "Unable to create history file name. History read/write disabled.\n");
3212 return;
3213 }
3214
3215 ret = readwrite(name);
3216 if (ret < 0) {
3217 ast_log(LOG_ERROR, "Unable to read or write history file '%s'\n", name);
3218 }
3219
3220 ast_free(name);
3221
3222 return;
3223}

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

979{
980 struct ast_json *json_object;
981 int uptime = 0;
982 int lastreloaded = 0;
983 struct timeval tmp;
984 struct timeval curtime = ast_tvnow();
985
986 if (ast_startuptime.tv_sec) {
987 tmp = ast_tvsub(curtime, ast_startuptime);
988 uptime = (int) tmp.tv_sec;
989 }
990
991 if (ast_lastreloadtime.tv_sec) {
992 tmp = ast_tvsub(curtime, ast_lastreloadtime);
993 lastreloaded = (int) tmp.tv_sec;
994 }
995
996 json_object = ast_json_pack("{s: s, s: i, s: i}",
997 "Status", "Fully Booted",
998 "Uptime", uptime,
999 "LastReload", lastreloaded);
1000 ast_manager_publish_event("FullyBooted", EVENT_FLAG_SYSTEM, json_object);
1001 ast_json_unref(json_object);
1002}
void ast_manager_publish_event(const char *type, int class_type, struct ast_json *obj)
Publish an event to AMI.
Definition: manager.c:637
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:612
#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 1912 of file asterisk.c.

1913{
1914 if (can_safely_quit(niceness, restart)) {
1915 really_quit(num, niceness, restart);
1916 /* No one gets here. */
1917 }
1918 /* It wasn't our time. */
1919}
static int can_safely_quit(shutdown_nice_t niceness, int restart)
Definition: asterisk.c:1964
static void really_quit(int num, shutdown_nice_t niceness, int restart)
Definition: asterisk.c:2047

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

868{
869 return 0;
870}

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

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

Refere