Asterisk - The Open Source Telephony Project GIT-master-55f4e6d
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 2605 of file asterisk.c.

◆ CHAR_T_LIBEDIT

#define CHAR_T_LIBEDIT   wchar_t

Definition at line 2670 of file asterisk.c.

◆ CHAR_TO_LIBEDIT

#define CHAR_TO_LIBEDIT (   c)    btowc(c)

Definition at line 2671 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 3144 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 1917 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 2211 of file asterisk.c.

2214{

◆ __quit_handler()

static void __quit_handler ( int  num)
static

Definition at line 2139 of file asterisk.c.

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

2150{
2151 sig_flags.need_quit = 1;
2152}

References sig_flags.

Referenced by ast_remotecontrol().

◆ _child_handler()

static void _child_handler ( int  sig)
static

Definition at line 1741 of file asterisk.c.

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

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

1709{
1710 return;
1711}

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

2285{
2286 while (*s) {
2287 if (*s > 32)
2288 return 0;
2289 s++;
2290 }
2291 return 1;
2292}

Referenced by consolehandler(), and remoteconsolehandler().

◆ ast_begin_shutdown()

static void ast_begin_shutdown ( void  )
static

Definition at line 1896 of file asterisk.c.

1897{
1900 shutdown_pending = 1;
1901 }
1903}
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 1878 of file asterisk.c.

1879{
1880 int shutdown_aborted = 0;
1881
1883 if (shuttingdown >= SHUTDOWN_FAST) {
1885 shutdown_pending = 0;
1886 shutdown_aborted = 1;
1887 }
1889 return shutdown_aborted;
1890}

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

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

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

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

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

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

1321{
1322 /* Send to the root console */
1324
1325 /* Wake up a poll()ing console */
1327 pthread_kill(consolethread, SIGURG);
1328 }
1329
1330 /* Send to any network console clients */
1331 ast_network_puts_mutable(message, level, sublevel);
1332}
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:1294
static pthread_t consolethread
Definition: asterisk.c:384
static int console_print(const char *s)
Definition: asterisk.c:2213
#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 1248 of file asterisk.c.

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

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

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

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

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

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

3222{
3224}
static int ast_el_read_history(const char *)
Definition: asterisk.c:3178
static void process_histfile(int(*readwrite)(const char *filename))
Definition: asterisk.c:3194

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

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

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

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

3227{
3229}
static int ast_el_write_history(const char *)
Definition: asterisk.c:3168

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

3169{
3170 HistEvent ev;
3171
3172 if (el_hist == NULL || el == NULL)
3174
3175 return (history(el_hist, &ev, H_SAVE, filename));
3176}

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

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

1338{
1339 int x;
1340
1341 for (x = 0; x < AST_MAX_CONNECTS; ++x) {
1342 if (consoles[x].fd < 0) {
1343 continue;
1344 }
1345 fdprint(consoles[x].p[1], string);
1346 }
1347}
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 1294 of file asterisk.c.

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

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

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

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

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

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

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

1869{
1871}

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

1874{
1875 return shutdown_pending;
1876}

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

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

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 level = --safe_system_level;
1122
1123 /* only restore the handler if we are the last one */
1124 if (level == 0) {
1125 sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
1126 }
1127
1129}

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

Referenced by safe_exec_wait().

◆ asterisk_daemon()

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

Definition at line 4083 of file asterisk.c.

4084{
4085 FILE *f;
4086 sigset_t sigs;
4087 int num;
4088 char *buf;
4089 char pbx_uuid[AST_UUID_STR_LEN];
4090
4091 /* Set time as soon as possible */
4093
4094 /* This needs to remain as high up in the initial start up as possible.
4095 * daemon causes a fork to occur, which has all sorts of unintended
4096 * consequences for things that interact with threads. This call *must*
4097 * occur before anything in Asterisk spawns or manipulates thread related
4098 * primitives. */
4099#if HAVE_WORKING_FORK
4101#ifndef HAVE_SBIN_LAUNCHD
4102 if (daemon(1, 0) < 0) {
4103 fprintf(stderr, "daemon() failed: %s\n", strerror(errno));
4104 } else {
4105 ast_mainpid = getpid();
4106 }
4107#else
4108 fprintf(stderr, "Mac OS X detected. Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
4109#endif
4110 }
4111#endif
4112
4113 /* At this point everything has been forked successfully,
4114 * we have determined that we aren't attempting to connect to
4115 * an Asterisk instance, and that there isn't one already running. */
4117
4119
4120 /* Check whether high prio was successfully set by us or some
4121 * other incantation. */
4122 if (has_priority()) {
4124 } else {
4126 }
4127
4128 /* Spawning of astcanary must happen AFTER the call to daemon(3) */
4130 snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
4131
4132 /* Don't let the canary child kill Asterisk, if it dies immediately */
4133 sigaction(SIGPIPE, &ignore_sig_handler, NULL);
4134
4135 canary_pid = fork();
4136 if (canary_pid == 0) {
4137 char canary_binary[PATH_MAX], ppid[12];
4138
4139 /* Reset signal handler */
4140 signal(SIGCHLD, SIG_DFL);
4141 signal(SIGPIPE, SIG_DFL);
4142
4145 snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid);
4146
4147 /* Use the astcanary binary that we installed */
4148 snprintf(canary_binary, sizeof(canary_binary), "%s/astcanary", ast_config_AST_SBIN_DIR);
4149 execl(canary_binary, "astcanary", canary_filename, ppid, (char *)NULL);
4150
4151 /* Should never happen */
4152 _exit(1);
4153 } else if (canary_pid > 0) {
4154 pthread_t dont_care;
4156 }
4157
4158 /* Kill the canary when we exit */
4160 }
4161
4162 /* Blindly write the PID file. */
4163 unlink(ast_config_AST_PID);
4164 f = fopen(ast_config_AST_PID, "w");
4165 if (f) {
4166 fprintf(f, "%ld\n", (long)ast_mainpid);
4167 fclose(f);
4168 } else {
4169 fprintf(stderr, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
4170 }
4171
4172 /* Initialize the terminal. Since all processes have been forked,
4173 * we can now start using the standard log messages.
4174 */
4175 ast_term_init();
4176 printf("%s", term_end());
4177 fflush(stdout);
4178
4179 print_intro_message(runuser, rungroup);
4180
4182
4183 check_init(astobj2_init(), "AO2");
4184 check_init(ast_named_locks_init(), "Named Locks");
4185
4186 if (ast_opt_console) {
4187 if (el_hist == NULL || el == NULL)
4190 }
4191
4192#ifdef AST_XML_DOCS
4193 /* Load XML documentation. */
4195#endif
4196
4197 check_init(astdb_init(), "ASTdb");
4198
4199 ast_uuid_init();
4200
4201 if (ast_pbx_uuid_get(pbx_uuid, sizeof(pbx_uuid))) {
4202 ast_uuid_generate_str(pbx_uuid, sizeof(pbx_uuid));
4203 ast_db_put("pbx", "UUID", pbx_uuid);
4204 }
4205 ast_verb(0, "PBX UUID: %s\n", pbx_uuid);
4206
4207 check_init(ast_json_init(), "libjansson");
4208 ast_ulaw_init();
4209 ast_alaw_init();
4210 ast_utf8_init();
4211 tdd_init();
4212 callerid_init();
4214
4215 check_init(ast_utils_init(), "Utilities");
4216 check_init(ast_tps_init(), "Task Processor Core");
4217 check_init(ast_fd_init(), "File Descriptor Debugging");
4218 check_init(ast_pbx_init(), "ast_pbx_init");
4219 check_init(aco_init(), "Configuration Option Framework");
4220 check_init(stasis_init(), "Stasis");
4221#ifdef TEST_FRAMEWORK
4222 check_init(ast_test_init(), "Test Framework");
4223#endif
4224 check_init(ast_translate_init(), "Translator Core");
4225
4227
4228 check_init(ast_sorcery_init(), "Sorcery");
4229 check_init(ast_codec_init(), "Codecs");
4230 check_init(ast_format_init(), "Formats");
4231 check_init(ast_format_cache_init(), "Format Cache");
4232 check_init(ast_codec_builtin_init(), "Built-in Codecs");
4233 check_init(ast_bucket_init(), "Bucket API");
4234 check_init(ast_stasis_system_init(), "Stasis system-level information");
4235 check_init(ast_endpoint_stasis_init(), "Stasis Endpoint");
4236
4238 /* GCC 4.9 gives a bogus "right-hand operand of comma expression has
4239 * no effect" warning */
4240 (void) sigemptyset(&sigs);
4241 (void) sigaddset(&sigs, SIGHUP);
4242 (void) sigaddset(&sigs, SIGTERM);
4243 (void) sigaddset(&sigs, SIGINT);
4244 (void) sigaddset(&sigs, SIGPIPE);
4245 (void) sigaddset(&sigs, SIGWINCH);
4246 pthread_sigmask(SIG_BLOCK, &sigs, NULL);
4247 sigaction(SIGURG, &urg_handler, NULL);
4248 signal(SIGINT, __quit_handler);
4249 signal(SIGTERM, __quit_handler);
4250 sigaction(SIGHUP, &hup_handler, NULL);
4251 sigaction(SIGPIPE, &ignore_sig_handler, NULL);
4252
4253 /* ensure that the random number generators are seeded with a different value every time
4254 Asterisk is started
4255 */
4256 srand((unsigned int) getpid() + (unsigned int) time(NULL));
4257 initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
4258
4260
4261 check_init(init_logger(), "Logger");
4262 check_init(ast_rtp_engine_init(), "RTP Engine");
4263
4265
4266 check_init(ast_timing_init(), "Timing");
4267 check_init(ast_ssl_init(), "SSL");
4269 check_init(ast_pj_init(), "Embedded PJProject");
4270 check_init(app_init(), "App Core");
4271 check_init(mwi_init(), "MWI Core");
4272 check_init(devstate_init(), "Device State Core");
4273 check_init(ast_msg_init(), "Messaging API");
4274 check_init(ast_channels_init(), "Channel");
4275 check_init(ast_endpoint_init(), "Endpoints");
4276 check_init(ast_pickup_init(), "Call Pickup");
4277 check_init(ast_bridging_init(), "Bridging");
4278 check_init(ast_parking_stasis_init(), "Parking Core");
4279 check_init(ast_device_state_engine_init(), "Device State Engine");
4280 check_init(ast_presence_state_engine_init(), "Presence State Engine");
4281 check_init(dns_core_init(), "DNS Resolver Core");
4282 check_init(ast_dns_system_resolver_init(), "Default DNS resolver");
4283 check_init(ast_security_stasis_init(), "Security Stasis Topic and Events");
4284 check_init(ast_image_init(), "Image");
4285 check_init(ast_file_init(), "Generic File Format Support");
4286 check_init(load_pbx(), "load_pbx");
4287 check_init(load_pbx_builtins(), "Builtin PBX Applications");
4288 check_init(load_pbx_functions_cli(), "PBX Functions Support");
4289 check_init(load_pbx_variables(), "PBX Variables Support");
4290 check_init(load_pbx_switch(), "PBX Switch Support");
4291 check_init(load_pbx_app(), "PBX Application Support");
4292 check_init(load_pbx_hangup_handler(), "PBX Hangup Handler Support");
4293 check_init(ast_local_init(), "Local Proxy Channel Driver");
4294 check_init(ast_refer_init(), "Refer API");
4295
4296 /* We should avoid most config loads before this point as they can't use realtime. */
4297 check_init(load_modules(), "Module");
4298
4299 /*
4300 * This has to load after the dynamic modules load, as items in the media
4301 * cache can't be constructed from items in the AstDB without their
4302 * bucket backends.
4303 */
4304 check_init(ast_media_cache_init(), "Media Cache");
4305
4306 /* loads the cli_permissions.conf file needed to implement cli restrictions. */
4308 ast_cli_channels_init(); /* Not always safe to access CLI commands until startup is complete. */
4309
4310 ast_stun_init();
4311
4313
4314 if (ast_opt_no_fork) {
4315 consolethread = pthread_self();
4316 }
4317
4319
4321
4324
4325 pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
4326
4328
4332
4334 ast_sd_notify("READY=1");
4335
4336 ast_verb(0, COLORIZE_FMT "\n", COLORIZE(COLOR_BRGREEN, 0, "Asterisk Ready."));
4337
4339
4340 if (ast_opt_console) {
4341 /* Console stuff now... */
4342 /* Register our quit function */
4343 char title[256];
4344 char hostname[MAXHOSTNAMELEN] = "";
4345
4346 if (gethostname(hostname, sizeof(hostname) - 1)) {
4347 ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
4348 }
4349
4351
4352 set_icon("Asterisk");
4353 snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
4354 set_title(title);
4355
4356 el_set(el, EL_GETCFN, ast_el_read_char);
4357
4358 for (;;) {
4359 if (sig_flags.need_el_end) {
4360 el_end(el);
4361
4362 return;
4363 }
4364
4365 if (sig_flags.need_quit || sig_flags.need_quit_handler) {
4367 break;
4368 }
4369 buf = (char *) el_gets(el, &num);
4370
4371 if (!buf && write(1, "", 1) < 0)
4372 return; /* quit */
4373
4374 if (buf) {
4375 if (buf[strlen(buf)-1] == '\n')
4376 buf[strlen(buf)-1] = '\0';
4377
4379 }
4380 }
4381 }
4382
4383 /* Stall until a quit signal is given */
4385}
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:2245
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:1228
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:3779
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:8007
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:2238
void ast_autoservice_init(void)
Definition: autoservice.c:380
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:614
int load_pbx(void)
Definition: pbx.c:8421
int astobj2_init(void)
Definition: astobj2.c:1169
int load_pbx_app(void)
Definition: pbx_app.c:538
int ast_dns_system_resolver_init(void)
Initializes the resolver.
int ast_ssl_init(void)
int ast_cli_perms_init(int reload)
Definition: main/cli.c:2105
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:342
static void canary_exit(void)
Definition: asterisk.c:3512
static void check_init(int init_result, const char *name)
Definition: asterisk.c:4070
static void publish_fully_booted(void)
Definition: asterisk.c:978
static void main_atexit(void)
Definition: asterisk.c:3575
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:1838
static int has_priority(void)
Check whether we were set to high(er) priority.
Definition: asterisk.c:1775
static struct sigaction hup_handler
Definition: asterisk.c:1736
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:3458
static void consolehandler(const char *s)
Definition: asterisk.c:2295
static struct ast_cli_entry cli_asterisk_shutdown[]
Shutdown Asterisk CLI commands.
Definition: asterisk.c:2615
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:1762
static int ast_makesocket(void)
Definition: asterisk.c:1595
static int canary_pid
Definition: asterisk.c:386
static void * canary_thread(void *unused)
Definition: asterisk.c:3483
static struct ast_cli_entry cli_asterisk[]
Definition: asterisk.c:2624
static void run_startup_commands(void)
Definition: asterisk.c:3522
struct timeval ast_startuptime
Definition: asterisk.c:336
static void read_pjproject_startup_options(void)
Definition: asterisk.c:3424
pid_t ast_mainpid
Definition: asterisk.c:315
static void __quit_handler(int num)
Definition: asterisk.c:2139
static void set_icon(char *text)
Definition: asterisk.c:1768
static void print_intro_message(const char *runuser, const char *rungroup)
Definition: asterisk.c:3562
static struct sigaction ignore_sig_handler
Definition: asterisk.c:1090
static struct sigaction urg_handler
Definition: asterisk.c:1713
int ast_pbx_init(void)
Definition: pbx.c:8989
int ast_fd_init(void)
Definition: astfd.c:370
#define PATH_MAX
Definition: asterisk.h:40
int ast_bucket_init(void)
Initialize bucket support.
Definition: bucket.c:954
void callerid_init(void)
CallerID Initialization.
Definition: callerid.c: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:4236
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:3061
int ast_endpoint_stasis_init(void)
Initialization function for endpoint stasis support.
int ast_stasis_system_init(void)
Initialize the stasis system topic and message types.
void tdd_init(void)
Definition: tdd.c:94
#define COLOR_BRGREEN
Definition: term.h:55
#define COLORIZE(fg, bg, str)
Definition: term.h:72
#define COLORIZE_FMT
Shortcut macros for coloring a set of text.
Definition: term.h:71
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
int ast_translate_init(void)
Initialize the translation matrix and index to format conversion table.
Definition: translate.c: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 1960 of file asterisk.c.

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

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

Referenced by quit_handler().

◆ canary_exit()

static void canary_exit ( void  )
static

Definition at line 3512 of file asterisk.c.

3513{
3514 if (canary_pid > 0) {
3515 int status;
3516 kill(canary_pid, SIGKILL);
3517 waitpid(canary_pid, &status, 0);
3518 }
3519}

References canary_pid, and status.

Referenced by asterisk_daemon().

◆ canary_thread()

static void * canary_thread ( void *  unused)
static

Definition at line 3483 of file asterisk.c.

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

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

4071{
4072 if (init_result) {
4074 ast_log(LOG_ERROR, "%s initialization failed. ASTERISK EXITING!\n%s", name, term_quit());
4075 } else {
4076 fprintf(stderr, "%s initialization failed. ASTERISK EXITING!\n%s", name, term_quit());
4077 }
4078 ast_run_atexits(0);
4079 exit(init_result == -2 ? 2 : 1);
4080 }
4081}
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 2965 of file asterisk.c.

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

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

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

2205{
2206 struct console_state_data *state = ptr;
2207 state->verbose_line_level = 0;
2208 return 0;
2209}

◆ consolehandler()

static void consolehandler ( const char *  s)
static

Definition at line 2295 of file asterisk.c.

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

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

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

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

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

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

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

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

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

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

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:2923
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:499
int ast_manager_check_enabled(void)
Check if AMI is enabled.
Definition: manager.c:2109
int ast_webmanager_check_enabled(void)
Check if AMI/HTTP is enabled.
Definition: manager.c:2114
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:3544
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 2382 of file asterisk.c.

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

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

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

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

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

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

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

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

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

Referenced by ast_ari_validate_dialplan_cep(), and asterisk_daemon().

◆ listener()

static void * listener ( void *  unused)
static

Definition at line 1515 of file asterisk.c.

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

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

3576{
3578}
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 3458 of file asterisk.c.

3459{
3460 for (;;) {
3461 struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
3462
3463 ast_poll(&p, 1, -1);
3464 if (sig_flags.need_reload) {
3465 sig_flags.need_reload = 0;
3467 }
3468 if (sig_flags.need_quit) {
3469 sig_flags.need_quit = 0;
3470 if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
3471 sig_flags.need_quit_handler = 1;
3472 pthread_kill(consolethread, SIGURG);
3473 } else {
3475 }
3476 }
3478 }
3479
3480 return NULL;
3481}
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 1425 of file asterisk.c.

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

3563{
3566 if (runuser) {
3567 ast_verbose("Running as user '%s'\n", runuser);
3568 }
3569 if (rungroup) {
3570 ast_verbose("Running under group '%s'\n", rungroup);
3571 }
3572 }
3573}

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

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

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:2063
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 1908 of file asterisk.c.

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

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

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

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

Referenced by netconsole().