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/features.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/cel.h"#include "asterisk/pbx.h"#include "asterisk/enum.h"#include "asterisk/http.h"#include "asterisk/udptl.h"#include "asterisk/app.h"#include "asterisk/lock.h"#include "asterisk/utils.h"#include "asterisk/file.h"#include "asterisk/io.h"#include "editline/histedit.h"#include "asterisk/config.h"#include "asterisk/ast_version.h"#include "asterisk/linkedlists.h"#include "asterisk/devicestate.h"#include "asterisk/presencestate.h"#include "asterisk/module.h"#include "asterisk/dsp.h"#include "asterisk/buildinfo.h"#include "asterisk/xmldoc.h"#include "asterisk/poll-compat.h"#include "asterisk/ccss.h"#include "asterisk/test.h"#include "asterisk/rtp_engine.h"#include "asterisk/format.h"#include "asterisk/aoc.h"#include "../defaults.h"Go to the source code of this file.
Data Structures | |
| struct | _cfg_paths |
| struct | ast_atexit |
| struct | atexits |
| struct | console |
| struct | console_state_data |
| struct | file_version |
| struct | file_versions |
| struct | profile_data |
| struct | profile_entry |
| struct | thread_list |
| struct | thread_list_t |
Defines | |
| #define | AF_LOCAL AF_UNIX |
| #define | AST_MAX_CONNECTS 128 |
| #define | AST_MIN_DTMF_DURATION 80 |
| #define | ASTERISK_PROMPT "*CLI> " |
| #define | ASTERISK_PROMPT2 "%s*CLI> " |
| #define | DEFINE_PROFILE_MIN_MAX_VALUES |
| #define | EL_BUF_SIZE 512 |
| #define | FORMAT "%-25.25s %-40.40s\n" |
| #define | MAX_HISTORY_COMMAND_LENGTH 256 |
| #define | NUM_MSGS 64 |
| #define | PF_LOCAL PF_UNIX |
| #define | WELCOME_MESSAGE |
| Welcome message when starting a CLI interface. | |
Enumerations | |
| enum | shutdown_nice_t { NOT_SHUTTING_DOWN = -2, SHUTTING_DOWN = -1, 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. | |
| static void | _urg_handler (int num) |
| Urgent handler. | |
| int | ast_add_profile (const char *name, uint64_t scale) |
| allocates a counter with a given name and scale. | |
| static int | ast_all_zeros (char *s) |
| static int | ast_cli_display_match_list (char **matches, int len, int max) |
| char * | ast_complete_source_filename (const char *partial, int n) |
| void | ast_console_puts (const char *string) |
| void | ast_console_puts_mutable (const char *string, int level) |
| log the string to the root console, and all attached network console clients | |
| void | ast_console_toggle_loglevel (int fd, int level, int state) |
| enable or disable a logging level to a specified console | |
| void | ast_console_toggle_mute (int fd, int silent) |
| mute or unmute a console from logging | |
| static int | ast_el_add_history (char *) |
| static int | ast_el_initialize (void) |
| static int | ast_el_read_char (EditLine *editline, char *cp) |
| static int | ast_el_read_history (char *) |
| static int | ast_el_sort_compare (const void *i1, const void *i2) |
| static char ** | ast_el_strtoarr (char *buf) |
| static int | ast_el_write_history (char *) |
| const char * | ast_file_version_find (const char *file) |
| Find version for given module name. | |
| static int | ast_makesocket (void) |
| int64_t | ast_mark (int i, int startstop) |
| static void | ast_network_puts (const char *string) |
| write the string to all attached console clients | |
| static void | ast_network_puts_mutable (const char *string, int level) |
| log the string to all attached network console clients | |
| int64_t | ast_profile (int i, int64_t delta) |
| static void | ast_readconfig (void) |
| int | ast_register_atexit (void(*func)(void)) |
| Register a function to be executed before Asterisk exits. | |
| int | ast_register_cleanup (void(*func)(void)) |
| Register a function to be executed before Asterisk gracefully exits. | |
| void | ast_register_file_version (const char *file, const char *version) |
| Register the version of a source code file with the core. | |
| void | ast_register_thread (char *name) |
| static void | ast_remotecontrol (char *data) |
| void | ast_replace_sigchld (void) |
| Replace the SIGCHLD handler. | |
| static void | ast_run_atexits (int run_cleanups) |
| int | ast_safe_system (const char *s) |
| Safely spawn an external program while closing file descriptors. | |
| int | ast_set_priority (int pri) |
| We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy activity on it, this is a good thing. | |
| static int | ast_tryconnect (void) |
| void | ast_unregister_atexit (void(*func)(void)) |
| Unregister a function registered with ast_register_atexit(). | |
| void | ast_unregister_file_version (const char *file) |
| Unregister a source code file from the core. | |
| void | ast_unregister_thread (void *id) |
| void | ast_unreplace_sigchld (void) |
| Restore the SIGCHLD handler. | |
| static int | can_safely_quit (shutdown_nice_t niceness, int restart) |
| static void | canary_exit (void) |
| static void * | canary_thread (void *unused) |
| static char * | cli_complete (EditLine *editline, int ch) |
| static char * | cli_prompt (EditLine *editline) |
| static int | console_print (const char *s, int local) |
| static int | console_state_init (void *ptr) |
| static void | console_verboser (const char *s) |
| static void | consolehandler (char *s) |
| static void | destroy_match_list (char **match_list, int matches) |
| static void | env_init (void) |
| static int | fdprint (int fd, const char *s) |
| static int | fdsend (int fd, const char *s) |
| static const char * | fix_header (char *outbuf, int maxout, const char *s, char level) |
| static char * | handle_abort_shutdown (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_bang (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_clear_profile (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_restart_gracefully (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_restart_now (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_restart_when_convenient (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_show_profile (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Give an overview of core settings. | |
| static char * | handle_show_sysinfo (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Give an overview of system statistics. | |
| static char * | handle_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_show_version_files (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command to list module versions. | |
| static char * | handle_stop_gracefully (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_stop_now (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_stop_when_convenient (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_version (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static void * | listener (void *unused) |
| int | main (int argc, char *argv[]) |
| static void | main_atexit (void) |
| static void * | monitor_sig_flags (void *unused) |
| static void * | netconsole (void *vconsole) |
| static void | network_verboser (const char *string) |
| static void | print_intro_message (const char *runuser, const char *rungroup) |
| 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. | |
| 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 (char *s) |
| static void | run_startup_commands (void) |
| static void | send_rasterisk_connect_commands (void) |
| static void | set_icon (char *text) |
| static void | set_title (char *text) |
| Set an X-term or screen title. | |
| static void | set_ulimit (int value) |
| Set maximum open files. | |
| static int | show_cli_help (void) |
| static char * | show_license (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static int | show_version (void) |
| static char * | show_warranty (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Variables | |
| static char * | _argv [256] |
| struct ast_flags | ast_compat = { 0 } |
| const char * | ast_config_AST_AGI_DIR = cfg_paths.agi_dir |
| const char * | ast_config_AST_CONFIG_DIR = cfg_paths.config_dir |
| const char * | ast_config_AST_CONFIG_FILE = cfg_paths.config_file |
| static char | ast_config_AST_CTL [PATH_MAX] = "asterisk.ctl" |
| static char | ast_config_AST_CTL_GROUP [PATH_MAX] = "\0" |
| static char | ast_config_AST_CTL_OWNER [PATH_MAX] = "\0" |
| static char | ast_config_AST_CTL_PERMISSIONS [PATH_MAX] |
| const char * | ast_config_AST_DATA_DIR = cfg_paths.data_dir |
| const char * | ast_config_AST_DB = cfg_paths.db_path |
| const char * | ast_config_AST_KEY_DIR = cfg_paths.key_dir |
| const char * | ast_config_AST_LOG_DIR = cfg_paths.log_dir |
| const char * | ast_config_AST_MODULE_DIR = cfg_paths.module_dir |
| const char * | ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir |
| const char * | ast_config_AST_PID = cfg_paths.pid_path |
| const char * | ast_config_AST_RUN_DIR = cfg_paths.run_dir |
| const char * | ast_config_AST_RUN_GROUP = cfg_paths.run_group |
| const char * | ast_config_AST_RUN_USER = cfg_paths.run_user |
| const char * | ast_config_AST_SBIN_DIR = cfg_paths.sbin_dir |
| const char * | ast_config_AST_SOCKET = cfg_paths.socket_path |
| const char * | ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir |
| const char * | ast_config_AST_SYSTEM_NAME = cfg_paths.system_name |
| const char * | ast_config_AST_VAR_DIR = cfg_paths.var_dir |
| static int | ast_consock = -1 |
| char | ast_defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE |
| struct ast_eid | ast_eid_default |
| Global EID. | |
| unsigned int | ast_FD_SETSIZE |
| struct timeval | ast_lastreloadtime |
| pid_t | ast_mainpid |
| struct ast_flags | ast_options = { AST_DEFAULT_OPTIONS } |
| static int | ast_socket = -1 |
| struct timeval | ast_startuptime |
| int | ast_verb_sys_level |
| static struct atexits | atexits |
| static char | canary_filename [128] |
| static int | canary_pid = 0 |
| static struct _cfg_paths | cfg_paths |
| static struct sigaction | child_handler |
| static struct ast_cli_entry | cli_asterisk [] |
| static struct ast_cli_entry | cli_asterisk_shutdown [] |
| Shutdown Asterisk CLI commands. | |
| 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 file_versions | file_versions |
| static struct sigaction | hup_handler |
| static struct sigaction | ignore_sig_handler |
| static const char | license_lines [] |
| static pthread_t | lthread |
| static pthread_t | mon_sig_flags |
| static int | multi_thread_safe |
| static struct sigaction | null_sig_handler |
| int | option_debug |
| unsigned int | option_dtmfminduration |
| int | option_maxcalls |
| int | option_maxfiles |
| double | option_maxload |
| long | option_minmemfree |
| int | option_verbose |
| static struct profile_data * | prof_data |
| static struct ast_str * | prompt = NULL |
| static char | randompool [256] |
| char | record_cache_dir [AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR |
| static char * | remotehostname |
| static int | restartnow |
| static unsigned int | safe_system_level = 0 |
| Keep track of how many threads are currently trying to wait*() on a child process. | |
| static ast_mutex_t | safe_system_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
| static struct sigaction | safe_system_prev_handler |
| static shutdown_nice_t | shuttingdown = NOT_SHUTTING_DOWN |
| static int | sig_alert_pipe [2] = { -1, -1 } |
| struct { | |
| unsigned int need_quit:1 | |
| unsigned int need_quit_handler:1 | |
| unsigned int need_reload:1 | |
| } | sig_flags |
| static struct thread_list | thread_list |
| static struct sigaction | urg_handler |
| static const char | warranty_lines [] |
Top level source file for Asterisk - the Open Source PBX. Implementation of PBX core functions and CLI interface.
Definition in file asterisk.c.
| #define AF_LOCAL AF_UNIX |
Definition at line 163 of file asterisk.c.
Referenced by ast_makesocket(), ast_tryconnect(), and listener().
| #define AST_MAX_CONNECTS 128 |
Definition at line 167 of file asterisk.c.
Referenced by ast_console_toggle_loglevel(), ast_console_toggle_mute(), ast_makesocket(), ast_network_puts(), ast_network_puts_mutable(), listener(), and network_verboser().
| #define AST_MIN_DTMF_DURATION 80 |
Default minimum DTMF digit length - 80ms
Definition at line 171 of file asterisk.c.
Referenced by ast_readconfig().
| #define ASTERISK_PROMPT "*CLI> " |
Definition at line 2449 of file asterisk.c.
Referenced by cli_prompt().
| #define ASTERISK_PROMPT2 "%s*CLI> " |
Definition at line 2451 of file asterisk.c.
Referenced by cli_prompt().
| #define DEFINE_PROFILE_MIN_MAX_VALUES |
Definition at line 814 of file asterisk.c.
Referenced by handle_clear_profile(), and handle_show_profile().
| #define EL_BUF_SIZE 512 |
Referenced by ast_el_read_char().
| #define FORMAT "%-25.25s %-40.40s\n" |
| #define MAX_HISTORY_COMMAND_LENGTH 256 |
Definition at line 3026 of file asterisk.c.
Referenced by ast_el_add_history().
| #define NUM_MSGS 64 |
Definition at line 168 of file asterisk.c.
| #define PF_LOCAL PF_UNIX |
Definition at line 164 of file asterisk.c.
Referenced by ast_makesocket(), and ast_tryconnect().
| #define WELCOME_MESSAGE |
Welcome message when starting a CLI interface.
Definition at line 175 of file asterisk.c.
Referenced by ast_el_read_char(), and print_intro_message().
| enum shutdown_nice_t |
| NOT_SHUTTING_DOWN | |
| SHUTTING_DOWN | |
| SHUTDOWN_FAST | |
| SHUTDOWN_NORMAL | |
| SHUTDOWN_NICE | |
| SHUTDOWN_REALLY_NICE |
Definition at line 304 of file asterisk.c.
{
NOT_SHUTTING_DOWN = -2,
SHUTTING_DOWN = -1,
/* Valid values for quit_handler niceness below: */
SHUTDOWN_FAST,
SHUTDOWN_NORMAL,
SHUTDOWN_NICE,
SHUTDOWN_REALLY_NICE
} shutdown_nice_t;
| static void __ast_unregister_atexit | ( | void(*)(void) | func | ) | [static] |
Definition at line 988 of file asterisk.c.
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().
{
struct ast_atexit *ae;
AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
if (ae->func == func) {
AST_LIST_REMOVE_CURRENT(list);
ast_free(ae);
break;
}
}
AST_LIST_TRAVERSE_SAFE_END;
}
| static void __init_console_state | ( | void | ) | [static] |
Definition at line 1983 of file asterisk.c.
{
| static void __quit_handler | ( | int | num | ) | [static] |
Definition at line 1929 of file asterisk.c.
References errno, sig_alert_pipe, and sig_flags.
Referenced by main().
{
int a = 0;
sig_flags.need_quit = 1;
if (sig_alert_pipe[1] != -1) {
if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno));
}
}
/* There is no need to restore the signal handler here, since the app
* is going to exit */
}
| static void __remote_quit_handler | ( | int | num | ) | [static] |
Definition at line 1942 of file asterisk.c.
References sig_flags.
Referenced by ast_remotecontrol().
{
sig_flags.need_quit = 1;
}
| static void _child_handler | ( | int | sig | ) | [static] |
Definition at line 1641 of file asterisk.c.
{
/* Must not ever ast_log or ast_verbose within signal handler */
int n, status, save_errno = errno;
/*
* Reap all dead children -- not just one
*/
for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
;
if (n == 0 && option_debug)
printf("Huh? Child handler, but nobody there?\n");
errno = save_errno;
}
| static void _hup_handler | ( | int | num | ) | [static] |
Definition at line 1621 of file asterisk.c.
References _argv, errno, restartnow, sig_alert_pipe, and sig_flags.
{
int a = 0, save_errno = errno;
printf("Received HUP signal -- Reloading configs\n");
if (restartnow)
execvp(_argv[0], _argv);
sig_flags.need_reload = 1;
if (sig_alert_pipe[1] != -1) {
if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) {
fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno));
}
}
errno = save_errno;
}
| static void _null_sig_handler | ( | int | sig | ) | [static] |
NULL handler so we can collect the child exit status.
Definition at line 1051 of file asterisk.c.
{
}
| static void _urg_handler | ( | int | num | ) | [static] |
Urgent handler.
Called by soft_hangup to interrupt the poll, read, or other system call. We don't actually need to do anything though. Remember: Cannot EVER ast_log from within a signal handler
Definition at line 1611 of file asterisk.c.
{
return;
}
| int ast_add_profile | ( | const char * | name, |
| uint64_t | scale | ||
| ) |
allocates a counter with a given name and scale.
support for event profiling
Definition at line 733 of file asterisk.c.
References ast_calloc, ast_realloc, ast_strdup, profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, profile_data::max_size, profile_entry::name, prof_data, profile_entry::scale, and profile_entry::value.
Referenced by extension_match_core().
{
int l = sizeof(struct profile_data);
int n = 10; /* default entries */
if (prof_data == NULL) {
prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
if (prof_data == NULL)
return -1;
prof_data->entries = 0;
prof_data->max_size = n;
}
if (prof_data->entries >= prof_data->max_size) {
void *p;
n = prof_data->max_size + 20;
p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
if (p == NULL)
return -1;
prof_data = p;
prof_data->max_size = n;
}
n = prof_data->entries++;
prof_data->e[n].name = ast_strdup(name);
prof_data->e[n].value = 0;
prof_data->e[n].events = 0;
prof_data->e[n].mark = 0;
prof_data->e[n].scale = scale;
return n;
}
| static int ast_all_zeros | ( | char * | s | ) | [static] |
Definition at line 2069 of file asterisk.c.
Referenced by consolehandler(), and remoteconsolehandler().
{
while (*s) {
if (*s > 32)
return 0;
s++;
}
return 1;
}
| static int ast_cli_display_match_list | ( | char ** | matches, |
| int | len, | ||
| int | max | ||
| ) | [static] |
Definition at line 2800 of file asterisk.c.
References ast_el_sort_compare(), ast_free, and ast_get_termcols().
Referenced by cli_complete().
{
int i, idx, limit, count;
int screenwidth = 0;
int numoutput = 0, numoutputline = 0;
screenwidth = ast_get_termcols(STDOUT_FILENO);
/* find out how many entries can be put on one line, with two spaces between strings */
limit = screenwidth / (max + 2);
if (limit == 0)
limit = 1;
/* how many lines of output */
count = len / limit;
if (count * limit < len)
count++;
idx = 1;
qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
for (; count > 0; count--) {
numoutputline = 0;
for (i = 0; i < limit && matches[idx]; i++, idx++) {
/* Don't print dupes */
if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
i--;
ast_free(matches[idx]);
matches[idx] = NULL;
continue;
}
numoutput++;
numoutputline++;
fprintf(stdout, "%-*s ", max, matches[idx]);
ast_free(matches[idx]);
matches[idx] = NULL;
}
if (numoutputline > 0)
fprintf(stdout, "\n");
}
return numoutput;
}
| char* ast_complete_source_filename | ( | const char * | partial, |
| int | n | ||
| ) |
Definition at line 378 of file asterisk.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, len(), and ast_atexit::list.
Referenced by handle_debug().
{
struct file_version *find;
size_t len = strlen(partial);
int count = 0;
char *res = NULL;
AST_RWLIST_RDLOCK(&file_versions);
AST_RWLIST_TRAVERSE(&file_versions, find, list) {
if (!strncasecmp(find->file, partial, len) && ++count > n) {
res = ast_strdup(find->file);
break;
}
}
AST_RWLIST_UNLOCK(&file_versions);
return res;
}
| void ast_console_puts | ( | const char * | string | ) |
write the string to the root console, and all attached network console clients
Definition at line 1252 of file asterisk.c.
References ast_network_puts().
{
/* Send to the root console */
fputs(string, stdout);
fflush(stdout);
/* Send to any network console clients */
ast_network_puts(string);
}
| 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 1223 of file asterisk.c.
References ast_network_puts_mutable().
Referenced by init_logger_chain(), logger_print_normal(), and make_logchannel().
{
/* Send to the root console */
fputs(string, stdout);
fflush(stdout);
/* Send to any network console clients */
ast_network_puts_mutable(string, level);
}
| 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 1159 of file asterisk.c.
References AST_MAX_CONNECTS, consoles, console::levels, and NUMLOGLEVELS.
Referenced by handle_logger_set_level().
{
int x;
if (level >= NUMLOGLEVELS) {
level = NUMLOGLEVELS - 1;
}
for (x = 0;x < AST_MAX_CONNECTS; x++) {
if (fd == consoles[x].fd) {
/*
* Since the logging occurs when levels are false, set to
* flipped iinput because this function accepts 0 as off and 1 as on
*/
consoles[x].levels[level] = state ? 0 : 1;
return;
}
}
}
| void ast_console_toggle_mute | ( | int | fd, |
| int | silent | ||
| ) |
mute or unmute a console from logging
Definition at line 1182 of file asterisk.c.
References ast_cli(), AST_MAX_CONNECTS, consoles, mute, and console::mute.
Referenced by handle_logger_mute().
{
int x;
for (x = 0;x < AST_MAX_CONNECTS; x++) {
if (fd == consoles[x].fd) {
if (consoles[x].mute) {
consoles[x].mute = 0;
if (!silent)
ast_cli(fd, "Console is not muted anymore.\n");
} else {
consoles[x].mute = 1;
if (!silent)
ast_cli(fd, "Console is muted.\n");
}
return;
}
}
ast_cli(fd, "Couldn't find remote console.\n");
}
| static int ast_el_add_history | ( | char * | buf | ) | [static] |
Definition at line 3028 of file asterisk.c.
References ast_el_initialize(), ast_strip(), el, el_hist, and MAX_HISTORY_COMMAND_LENGTH.
Referenced by consolehandler(), and remoteconsolehandler().
{
HistEvent ev;
if (el_hist == NULL || el == NULL)
ast_el_initialize();
if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1))
return 0;
return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf))));
}
| static int ast_el_initialize | ( | void | ) | [static] |
Definition at line 2973 of file asterisk.c.
References cli_complete(), cli_prompt(), el, and el_hist.
Referenced by ast_el_add_history(), ast_el_read_history(), ast_el_write_history(), ast_remotecontrol(), and main().
{
HistEvent ev;
char *editor, *editrc = getenv("EDITRC");
if (!(editor = getenv("AST_EDITMODE"))) {
if (!(editor = getenv("AST_EDITOR"))) {
editor = "emacs";
}
}
if (el != NULL)
el_end(el);
if (el_hist != NULL)
history_end(el_hist);
el = el_init("asterisk", stdin, stdout, stderr);
el_set(el, EL_PROMPT, cli_prompt);
el_set(el, EL_EDITMODE, 1);
el_set(el, EL_EDITOR, editor);
el_hist = history_init();
if (!el || !el_hist)
return -1;
/* setup history with 100 entries */
history(el_hist, &ev, H_SETSIZE, 100);
el_set(el, EL_HIST, history, el_hist);
el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
/* Bind <tab> to command completion */
el_set(el, EL_BIND, "^I", "ed-complete", NULL);
/* Bind ? to command completion */
el_set(el, EL_BIND, "?", "ed-complete", NULL);
/* Bind ^D to redisplay */
el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
/* Bind Delete to delete char left */
el_set(el, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
/* Bind Home and End to move to line start and end */
el_set(el, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
el_set(el, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
/* Bind C-left and C-right to move by word (not all terminals) */
el_set(el, EL_BIND, "\\eOC", "vi-next-word", NULL);
el_set(el, EL_BIND, "\\eOD", "vi-prev-word", NULL);
if (editrc) {
el_source(el, editrc);
}
return 0;
}
| static int ast_el_read_char | ( | EditLine * | editline, |
| char * | cp | ||
| ) | [static] |
Definition at line 2513 of file asterisk.c.
References ast_consock, ast_opt_exec, ast_opt_reconnect, ast_poll, ast_tryconnect(), console_print(), EL_BUF_SIZE, errno, quit_handler(), send_rasterisk_connect_commands(), SHUTDOWN_FAST, sig_flags, term_quit(), and WELCOME_MESSAGE.
Referenced by ast_remotecontrol(), and main().
{
int num_read = 0;
int lastpos = 0;
struct pollfd fds[2];
int res;
int max;
#define EL_BUF_SIZE 512
char buf[EL_BUF_SIZE];
for (;;) {
max = 1;
fds[0].fd = ast_consock;
fds[0].events = POLLIN;
if (!ast_opt_exec) {
fds[1].fd = STDIN_FILENO;
fds[1].events = POLLIN;
max++;
}
res = ast_poll(fds, max, -1);
if (res < 0) {
if (sig_flags.need_quit || sig_flags.need_quit_handler)
break;
if (errno == EINTR)
continue;
fprintf(stderr, "poll failed: %s\n", strerror(errno));
break;
}
if (!ast_opt_exec && fds[1].revents) {
num_read = read(STDIN_FILENO, cp, 1);
if (num_read < 1) {
break;
} else {
return (num_read);
}
}
if (fds[0].revents) {
res = read(ast_consock, buf, sizeof(buf) - 1);
/* if the remote side disappears exit */
if (res < 1) {
fprintf(stderr, "\nDisconnected from Asterisk server\n");
if (!ast_opt_reconnect) {
quit_handler(0, SHUTDOWN_FAST, 0);
} else {
int tries;
int reconnects_per_second = 20;
fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
for (tries = 0; tries < 30 * reconnects_per_second; tries++) {
if (ast_tryconnect()) {
fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
printf("%s", term_quit());
WELCOME_MESSAGE;
send_rasterisk_connect_commands();
break;
} else
usleep(1000000 / reconnects_per_second);
}
if (tries >= 30 * reconnects_per_second) {
fprintf(stderr, "Failed to reconnect for 30 seconds. Quitting.\n");
quit_handler(0, SHUTDOWN_FAST, 0);
}
}
continue;
}
buf[res] = '\0';
/* Write over the CLI prompt */
if (!ast_opt_exec && !lastpos) {
if (write(STDOUT_FILENO, "\r[0K", 5) < 0) {
}
}
console_print(buf, 0);
if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
*cp = CC_REFRESH;
return(1);
} else
lastpos = 1;
}
}
*cp = '\0';
return (0);
}
| static int ast_el_read_history | ( | char * | filename | ) | [static] |
Definition at line 3049 of file asterisk.c.
References ast_el_initialize(), el, and el_hist.
Referenced by ast_remotecontrol(), and main().
{
HistEvent ev;
if (el_hist == NULL || el == NULL) {
ast_el_initialize();
}
return history(el_hist, &ev, H_LOAD, filename);
}
| static int ast_el_sort_compare | ( | const void * | i1, |
| const void * | i2 | ||
| ) | [static] |
Definition at line 2790 of file asterisk.c.
Referenced by ast_cli_display_match_list().
{
char *s1, *s2;
s1 = ((char **)i1)[0];
s2 = ((char **)i2)[0];
return strcasecmp(s1, s2);
}
| static char** ast_el_strtoarr | ( | char * | buf | ) | [static] |
Definition at line 2742 of file asterisk.c.
References AST_CLI_COMPLETE_EOF, ast_realloc, ast_strdup, and destroy_match_list().
Referenced by cli_complete().
{
char *retstr;
char **match_list = NULL;
char **new_list;
size_t match_list_len = 1;
int matches = 0;
while ((retstr = strsep(&buf, " "))) {
if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
break;
}
if (matches + 1 >= match_list_len) {
match_list_len <<= 1;
new_list = ast_realloc(match_list, match_list_len * sizeof(char *));
if (!new_list) {
destroy_match_list(match_list, matches);
return NULL;
}
match_list = new_list;
}
retstr = ast_strdup(retstr);
if (!retstr) {
destroy_match_list(match_list, matches);
return NULL;
}
match_list[matches++] = retstr;
}
if (!match_list) {
return NULL;
}
if (matches >= match_list_len) {
new_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *));
if (!new_list) {
destroy_match_list(match_list, matches);
return NULL;
}
match_list = new_list;
}
match_list[matches] = NULL;
return match_list;
}
| static int ast_el_write_history | ( | char * | filename | ) | [static] |
Definition at line 3039 of file asterisk.c.
References ast_el_initialize(), el, and el_hist.
Referenced by really_quit().
{
HistEvent ev;
if (el_hist == NULL || el == NULL)
ast_el_initialize();
return (history(el_hist, &ev, H_SAVE, filename));
}
| const char* ast_file_version_find | ( | const char * | file | ) |
Find version for given module name.
| file | Module name (i.e. chan_sip.so) |
Definition at line 397 of file asterisk.c.
References AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_atexit::list.
Referenced by manager_modulecheck().
{
struct file_version *iterator;
AST_RWLIST_WRLOCK(&file_versions);
AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
if (!strcasecmp(iterator->file, file))
break;
}
AST_RWLIST_UNLOCK(&file_versions);
if (iterator)
return iterator->version;
return NULL;
}
| static int ast_makesocket | ( | void | ) | [static] |
Definition at line 1510 of file asterisk.c.
References AF_LOCAL, ast_config_AST_CTL_GROUP, ast_config_AST_CTL_OWNER, ast_config_AST_CTL_PERMISSIONS, ast_config_AST_SOCKET, ast_copy_string(), ast_log(), AST_MAX_CONNECTS, ast_pthread_create_background, ast_register_verbose(), ast_strlen_zero(), consoles, errno, listener(), LOG_WARNING, lthread, network_verboser(), and PF_LOCAL.
Referenced by main().
{
struct sockaddr_un sunaddr;
int res;
int x;
uid_t uid = -1;
gid_t gid = -1;
for (x = 0; x < AST_MAX_CONNECTS; x++)
consoles[x].fd = -1;
unlink(ast_config_AST_SOCKET);
ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
if (ast_socket < 0) {
ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
return -1;
}
memset(&sunaddr, 0, sizeof(sunaddr));
sunaddr.sun_family = AF_LOCAL;
ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
if (res) {
ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
close(ast_socket);
ast_socket = -1;
return -1;
}
res = listen(ast_socket, 2);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
close(ast_socket);
ast_socket = -1;
return -1;
}
if (ast_register_verbose(network_verboser)) {
ast_log(LOG_WARNING, "Unable to register network verboser?\n");
}
if (ast_pthread_create_background(<hread, NULL, listener, NULL)) {
ast_log(LOG_WARNING, "Unable to create listener thread.\n");
close(ast_socket);
return -1;
}
if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
struct passwd *pw;
if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL)
ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
else
uid = pw->pw_uid;
}
if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
struct group *grp;
if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL)
ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
else
gid = grp->gr_gid;
}
if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
int p1;
mode_t p;
sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
p = p1;
if ((chmod(ast_config_AST_SOCKET, p)) < 0)
ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
}
return 0;
}
| int64_t ast_mark | ( | int | i, |
| int | startstop | ||
| ) |
Definition at line 798 of file asterisk.c.
References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, prof_data, rdtsc(), profile_entry::scale, and profile_entry::value.
Referenced by __ast_pthread_mutex_lock(), and extension_match_core().
{
if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
return 0;
if (startstop == 1)
prof_data->e[i].mark = rdtsc();
else {
prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
if (prof_data->e[i].scale > 1)
prof_data->e[i].mark /= prof_data->e[i].scale;
prof_data->e[i].value += prof_data->e[i].mark;
prof_data->e[i].events++;
}
return prof_data->e[i].mark;
}
| static void ast_network_puts | ( | const char * | string | ) | [static] |
write the string to all attached console clients
Definition at line 1236 of file asterisk.c.
References AST_MAX_CONNECTS, consoles, and fdprint().
Referenced by ast_console_puts().
{
int x;
for (x = 0; x < AST_MAX_CONNECTS; ++x) {
if (consoles[x].fd < 0) {
continue;
}
fdprint(consoles[x].p[1], string);
}
}
| static void ast_network_puts_mutable | ( | const char * | string, |
| int | level | ||
| ) | [static] |
log the string to all attached network console clients
Definition at line 1205 of file asterisk.c.
References AST_MAX_CONNECTS, consoles, fdprint(), levels, and mute.
Referenced by ast_console_puts_mutable().
| int64_t ast_profile | ( | int | i, |
| int64_t | delta | ||
| ) |
Definition at line 763 of file asterisk.c.
References profile_data::e, profile_data::entries, profile_entry::events, prof_data, profile_entry::scale, and profile_entry::value.
| static void ast_readconfig | ( | void | ) | [static] |
Definition at line 3253 of file asterisk.c.
References _cfg_paths::agi_dir, AST_CACHE_DIR_LEN, ast_clear_flag, AST_COMPAT_APP_SET, AST_COMPAT_DELIM_PBX_REALTIME, AST_COMPAT_DELIM_RES_AGI, ast_config_AST_CONFIG_FILE, ast_config_AST_CTL, ast_config_AST_CTL_GROUP, ast_config_AST_CTL_OWNER, ast_config_AST_CTL_PERMISSIONS, ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_defaultlanguage, ast_eid_default, ast_language_is_prefix, AST_LOCK_TYPE_FLOCK, AST_LOCK_TYPE_LOCKFILE, ast_log(), AST_MIN_DTMF_DURATION, AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DONT_WARN, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND, AST_OPT_FLAG_HIDE_CONSOLE_CONNECT, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_LIGHT_BACKGROUND, AST_OPT_FLAG_LOCK_CONFIG_DIR, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_STDEXTEN_MACRO, AST_OPT_FLAG_TIMESTAMP, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_opt_override_config, ast_opt_remote, ast_set2_flag, ast_set_default_eid(), ast_set_flag, ast_set_lock_type(), ast_str_to_eid(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_verbose(), cfg_paths, config, _cfg_paths::config_dir, CONFIG_FLAG_NOREALTIME, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, _cfg_paths::data_dir, _cfg_paths::db_path, hostname, _cfg_paths::key_dir, live_dangerously, _cfg_paths::log_dir, LOG_ERROR, LOG_WARNING, MAX_LANGUAGE, _cfg_paths::module_dir, _cfg_paths::monitor_dir, ast_variable::name, ast_variable::next, pbx_live_dangerously(), _cfg_paths::pid_path, _cfg_paths::run_dir, _cfg_paths::run_group, _cfg_paths::run_user, _cfg_paths::sbin_dir, set_ulimit(), _cfg_paths::socket_path, _cfg_paths::spool_dir, _cfg_paths::system_name, ast_variable::value, _cfg_paths::var_dir, and version.
Referenced by main().
{
struct ast_config *cfg;
struct ast_variable *v;
char *config = DEFAULT_CONFIG_FILE;
char hostname[MAXHOSTNAMELEN] = "";
struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME };
struct {
unsigned int dbdir:1;
unsigned int keydir:1;
} found = { 0, 0 };
/* Default to true for backward compatibility */
int live_dangerously = 1;
/* Set default value */
option_dtmfminduration = AST_MIN_DTMF_DURATION;
if (ast_opt_override_config) {
cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
fprintf(stderr, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
}
} else {
cfg = ast_config_load2(config, "" /* core, can't reload */, config_flags);
}
/* init with buildtime config */
ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir));
ast_copy_string(cfg_paths.spool_dir, DEFAULT_SPOOL_DIR, sizeof(cfg_paths.spool_dir));
ast_copy_string(cfg_paths.module_dir, DEFAULT_MODULE_DIR, sizeof(cfg_paths.module_dir));
snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", cfg_paths.spool_dir);
ast_copy_string(cfg_paths.var_dir, DEFAULT_VAR_DIR, sizeof(cfg_paths.var_dir));
ast_copy_string(cfg_paths.data_dir, DEFAULT_DATA_DIR, sizeof(cfg_paths.data_dir));
ast_copy_string(cfg_paths.log_dir, DEFAULT_LOG_DIR, sizeof(cfg_paths.log_dir));
ast_copy_string(cfg_paths.agi_dir, DEFAULT_AGI_DIR, sizeof(cfg_paths.agi_dir));
ast_copy_string(cfg_paths.db_path, DEFAULT_DB, sizeof(cfg_paths.db_path));
ast_copy_string(cfg_paths.sbin_dir, DEFAULT_SBIN_DIR, sizeof(cfg_paths.sbin_dir));
ast_copy_string(cfg_paths.key_dir, DEFAULT_KEY_DIR, sizeof(cfg_paths.key_dir));
ast_copy_string(cfg_paths.pid_path, DEFAULT_PID, sizeof(cfg_paths.pid_path));
ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path));
ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir));
ast_set_default_eid(&ast_eid_default);
/* no asterisk.conf? no problem, use buildtime config! */
if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
return;
}
for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
if (!strcasecmp(v->name, "astctlpermissions"))
ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
else if (!strcasecmp(v->name, "astctlowner"))
ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
else if (!strcasecmp(v->name, "astctlgroup"))
ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
else if (!strcasecmp(v->name, "astctl"))
ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
}
for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
if (!strcasecmp(v->name, "astetcdir")) {
ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir));
} else if (!strcasecmp(v->name, "astspooldir")) {
ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir));
snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value);
} else if (!strcasecmp(v->name, "astvarlibdir")) {
ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir));
if (!found.dbdir)
snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
} else if (!strcasecmp(v->name, "astdbdir")) {
snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
found.dbdir = 1;
} else if (!strcasecmp(v->name, "astdatadir")) {
ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir));
if (!found.keydir)
snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
} else if (!strcasecmp(v->name, "astkeydir")) {
snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
found.keydir = 1;
} else if (!strcasecmp(v->name, "astlogdir")) {
ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir));
} else if (!strcasecmp(v->name, "astagidir")) {
ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir));
} else if (!strcasecmp(v->name, "astrundir")) {
snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid");
snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", v->value, ast_config_AST_CTL);
ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir));
} else if (!strcasecmp(v->name, "astmoddir")) {
ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir));
} else if (!strcasecmp(v->name, "astsbindir")) {
ast_copy_string(cfg_paths.sbin_dir, v->value, sizeof(cfg_paths.sbin_dir));
}
}
for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
/* verbose level (-v at startup) */
if (!strcasecmp(v->name, "verbose")) {
option_verbose = atoi(v->value);
/* whether or not to force timestamping in CLI verbose output. (-T at startup) */
} else if (!strcasecmp(v->name, "timestamp")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
/* whether or not to support #exec in config files */
} else if (!strcasecmp(v->name, "execincludes")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
/* debug level (-d at startup) */
} else if (!strcasecmp(v->name, "debug")) {
option_debug = 0;
if (sscanf(v->value, "%30d", &option_debug) != 1) {
option_debug = ast_true(v->value);
}
#if HAVE_WORKING_FORK
/* Disable forking (-f at startup) */
} else if (!strcasecmp(v->name, "nofork")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
/* Always fork, even if verbose or debug are enabled (-F at startup) */
} else if (!strcasecmp(v->name, "alwaysfork")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
#endif
/* Run quietly (-q at startup ) */
} else if (!strcasecmp(v->name, "quiet")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
/* Run as console (-c at startup, implies nofork) */
} else if (!strcasecmp(v->name, "console")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
/* Run with high priority if the O/S permits (-p at startup) */
} else if (!strcasecmp(v->name, "highpriority")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
/* Initialize RSA auth keys (IAX2) (-i at startup) */
} else if (!strcasecmp(v->name, "initcrypto")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
/* Disable ANSI colors for console (-c at startup) */
} else if (!strcasecmp(v->name, "nocolor")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
/* Disable some usage warnings for picky people :p */
} else if (!strcasecmp(v->name, "dontwarn")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
/* Dump core in case of crash (-g) */
} else if (!strcasecmp(v->name, "dumpcore")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
/* Cache recorded sound files to another directory during recording */
} else if (!strcasecmp(v->name, "cache_record_files")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
/* Specify cache directory */
} else if (!strcasecmp(v->name, "record_cache_dir")) {
ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
/* Build transcode paths via SLINEAR, instead of directly */
} else if (!strcasecmp(v->name, "transcode_via_sln")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
/* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
} else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
/* Enable internal timing */
} else if (!strcasecmp(v->name, "internal_timing")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING);
} else if (!strcasecmp(v->name, "mindtmfduration")) {
if (sscanf(v->value, "%30u", &option_dtmfminduration) != 1) {
option_dtmfminduration = AST_MIN_DTMF_DURATION;
}
} else if (!strcasecmp(v->name, "maxcalls")) {
if ((sscanf(v->value, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
option_maxcalls = 0;
}
} else if (!strcasecmp(v->name, "maxload")) {
double test[1];
if (getloadavg(test, 1) == -1) {
ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
option_maxload = 0.0;
} else if ((sscanf(v->value, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
option_maxload = 0.0;
}
/* Set the maximum amount of open files */
} else if (!strcasecmp(v->name, "maxfiles")) {
option_maxfiles = atoi(v->value);
set_ulimit(option_maxfiles);
/* What user to run as */
} else if (!strcasecmp(v->name, "runuser")) {
ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user));
/* What group to run as */
} else if (!strcasecmp(v->name, "rungroup")) {
ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group));
} else if (!strcasecmp(v->name, "systemname")) {
ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name));
} else if (!strcasecmp(v->name, "autosystemname")) {
if (ast_true(v->value)) {
if (!gethostname(hostname, sizeof(hostname) - 1))
ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name));
else {
if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){
ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name));
}
ast_log(LOG_ERROR, "Cannot obtain hostname for this system. Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME);
}
}
} else if (!strcasecmp(v->name, "languageprefix")) {
ast_language_is_prefix = ast_true(v->value);
} else if (!strcasecmp(v->name, "defaultlanguage")) {
ast_copy_string(ast_defaultlanguage, v->value, MAX_LANGUAGE);
} else if (!strcasecmp(v->name, "lockmode")) {
if (!strcasecmp(v->value, "lockfile")) {
ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
} else if (!strcasecmp(v->value, "flock")) {
ast_set_lock_type(AST_LOCK_TYPE_FLOCK);
} else {
ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, "
"defaulting to 'lockfile'\n", v->value);
ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
}
#if defined(HAVE_SYSINFO)
} else if (!strcasecmp(v->name, "minmemfree")) {
/* specify the minimum amount of free memory to retain. Asterisk should stop accepting new calls
* if the amount of free memory falls below this watermark */
if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
option_minmemfree = 0;
}
#endif
} else if (!strcasecmp(v->name, "entityid")) {
struct ast_eid tmp_eid;
if (!ast_str_to_eid(&tmp_eid, v->value)) {
ast_verbose("Successfully set global EID to '%s'\n", v->value);
ast_eid_default = tmp_eid;
} else
ast_verbose("Invalid Entity ID '%s' provided\n", v->value);
} else if (!strcasecmp(v->name, "lightbackground")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND);
} else if (!strcasecmp(v->name, "forceblackbackground")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
} else if (!strcasecmp(v->name, "hideconnect")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT);
} else if (!strcasecmp(v->name, "lockconfdir")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LOCK_CONFIG_DIR);
} else if (!strcasecmp(v->name, "stdexten")) {
/* Choose how to invoke the extensions.conf stdexten */
if (!strcasecmp(v->value, "gosub")) {
ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
} else if (!strcasecmp(v->value, "macro")) {
ast_set_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
} else {
ast_log(LOG_WARNING,
"'%s' is not a valid setting for the stdexten option, defaulting to 'gosub'\n",
v->value);
ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
}
} else if (!strcasecmp(v->name, "live_dangerously")) {
live_dangerously = ast_true(v->value);
}
}
if (!ast_opt_remote) {
pbx_live_dangerously(live_dangerously);
}
for (v = ast_variable_browse(cfg, "compat"); v; v = v->next) {
float version;
if (sscanf(v->value, "%30f", &version) != 1) {
fprintf(stderr, "Compatibility version for option '%s' is not a number: '%s'\n", v->name, v->value);
continue;
}
if (!strcasecmp(v->name, "app_set")) {
ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_APP_SET);
} else if (!strcasecmp(v->name, "res_agi")) {
ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_RES_AGI);
} else if (!strcasecmp(v->name, "pbx_realtime")) {
ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_PBX_REALTIME);
}
}
ast_config_destroy(cfg);
}
| int ast_register_atexit | ( | void(*)(void) | func | ) |
Register a function to be executed before Asterisk exits.
| func | The callback function to use. |
| 0 | on success. |
| -1 | on error. |
Definition at line 1021 of file asterisk.c.
References ast_atexit::func, and register_atexit().
Referenced by __init_manager(), ast_aoc_cli_init(), ast_builtins_init(), ast_cc_init(), ast_cdr_engine_init(), ast_cel_engine_init(), ast_channels_init(), ast_data_init(), ast_event_init(), ast_features_init(), ast_file_init(), ast_format_list_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_msg_init(), ast_named_acl_init(), ast_pbx_init(), ast_stun_init(), ast_test_init(), ast_timing_init(), ast_tps_init(), ast_translate_init(), ast_udptl_init(), ast_utils_init(), ast_xmldoc_load_documentation(), astdb_init(), astobj2_init(), dnsmgr_init(), do_reload(), load_module(), load_pbx(), main(), and register_config_cli().
{
return register_atexit(func, 0);
}
| int ast_register_cleanup | ( | void(*)(void) | func | ) |
Register a function to be executed before Asterisk gracefully exits.
| func | The callback function to use. |
| 0 | on success. |
| -1 | on error. |
Definition at line 1026 of file asterisk.c.
References ast_atexit::func, and register_atexit().
Referenced by ast_format_attr_init().
{
return register_atexit(func, 1);
}
| void ast_register_file_version | ( | const char * | file, |
| const char * | version | ||
| ) |
Register the version of a source code file with the core.
| file | the source file name |
| version | the version string (typically a SVN revision keyword string) |
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to register a file with the core.
Definition at line 339 of file asterisk.c.
References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strip(), ast_strip_quoted(), and ast_atexit::list.
{
struct file_version *new;
char *work;
size_t version_length;
work = ast_strdupa(version);
work = ast_strip(ast_strip_quoted(work, "$", "$"));
version_length = strlen(work) + 1;
if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
return;
new->file = file;
new->version = (char *) new + sizeof(*new);
memcpy(new->version, work, version_length);
AST_RWLIST_WRLOCK(&file_versions);
AST_RWLIST_INSERT_HEAD(&file_versions, new, list);
AST_RWLIST_UNLOCK(&file_versions);
}
| void ast_register_thread | ( | char * | name | ) |
Definition at line 423 of file asterisk.c.
References ast_assert, ast_calloc, ast_get_tid(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_atexit::list, multi_thread_safe, and name.
Referenced by dummy_start().
{
struct thread_list_t *new = ast_calloc(1, sizeof(*new));
if (!new)
return;
ast_assert(multi_thread_safe);
new->id = pthread_self();
new->lwp = ast_get_tid();
new->name = name; /* steal the allocated memory for the thread name */
AST_RWLIST_WRLOCK(&thread_list);
AST_RWLIST_INSERT_HEAD(&thread_list, new, list);
AST_RWLIST_UNLOCK(&thread_list);
}
| static void ast_remotecontrol | ( | char * | data | ) | [static] |
Definition at line 3060 of file asterisk.c.
References __remote_quit_handler(), ast_alloca, ast_consock, ast_el_initialize(), ast_el_read_char(), ast_el_read_history(), ast_log(), ast_opt_exec, ast_poll, ast_strlen_zero(), ast_verbose(), el, el_hist, errno, hostname, LOG_ERROR, LOG_WARNING, prefix, remoteconsolehandler(), remotehostname, send_rasterisk_connect_commands(), sig_flags, and version.
Referenced by main().
{
char buf[80];
int res;
char filename[80] = "";
char *hostname;
char *cpid;
char *version;
int pid;
char *stringp = NULL;
char *ebuf;
int num = 0;
memset(&sig_flags, 0, sizeof(sig_flags));
signal(SIGINT, __remote_quit_handler);
signal(SIGTERM, __remote_quit_handler);
signal(SIGHUP, __remote_quit_handler);
if (read(ast_consock, buf, sizeof(buf)) < 0) {
ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
return;
}
if (data) {
char prefix[] = "cli quit after ";
char *tmp = ast_alloca(strlen(data) + strlen(prefix) + 1);
sprintf(tmp, "%s%s", prefix, data);
if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) {
ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
if (sig_flags.need_quit || sig_flags.need_quit_handler) {
return;
}
}
}
stringp = buf;
hostname = strsep(&stringp, "/");
cpid = strsep(&stringp, "/");
version = strsep(&stringp, "\n");
if (!version)
version = "<Version Unknown>";
stringp = hostname;
strsep(&stringp, ".");
if (cpid)
pid = atoi(cpid);
else
pid = -1;
if (!data) {
send_rasterisk_connect_commands();
}
if (ast_opt_exec && data) { /* hack to print output then exit if asterisk -rx is used */
int linefull = 1, prev_linefull = 1, prev_line_verbose = 0;
struct pollfd fds;
fds.fd = ast_consock;
fds.events = POLLIN;
fds.revents = 0;
while (ast_poll(&fds, 1, 60000) > 0) {
char buffer[512] = "", *curline = buffer, *nextline;
int not_written = 1;
if (sig_flags.need_quit || sig_flags.need_quit_handler) {
break;
}
if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) {
break;
}
do {
prev_linefull = linefull;
if ((nextline = strchr(curline, '\n'))) {
linefull = 1;
nextline++;
} else {
linefull = 0;
nextline = strchr(curline, '\0');
}
/* Skip verbose lines */
/* Prev line full? | Line is verbose | Last line verbose? | Print
* TRUE | TRUE* | TRUE | FALSE
* TRUE | TRUE* | FALSE | FALSE
* TRUE | FALSE* | TRUE | TRUE
* TRUE | FALSE* | FALSE | TRUE
* FALSE | TRUE | TRUE* | FALSE
* FALSE | TRUE | FALSE* | TRUE
* FALSE | FALSE | TRUE* | FALSE
* FALSE | FALSE | FALSE* | TRUE
*/
if ((!prev_linefull && !prev_line_verbose) || (prev_linefull && *curline > 0)) {
prev_line_verbose = 0;
not_written = 0;
if (write(STDOUT_FILENO, curline, nextline - curline) < 0) {
ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
}
} else {
prev_line_verbose = 1;
}
curline = nextline;
} while (!ast_strlen_zero(curline));
/* No non-verbose output in 60 seconds. */
if (not_written) {
break;
}
}
return;
}
ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
remotehostname = hostname;
if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
if (el_hist == NULL || el == NULL)
ast_el_initialize();
el_set(el, EL_GETCFN, ast_el_read_char);
if (!ast_strlen_zero(filename))
ast_el_read_history(filename);
for (;;) {
ebuf = (char *)el_gets(el, &num);
if (sig_flags.need_quit || sig_flags.need_quit_handler) {
break;
}
if (!ebuf && write(1, "", 1) < 0)
break;
if (!ast_strlen_zero(ebuf)) {
if (ebuf[strlen(ebuf)-1] == '\n')
ebuf[strlen(ebuf)-1] = '\0';
if (!remoteconsolehandler(ebuf)) {
res = write(ast_consock, ebuf, strlen(ebuf) + 1);
if (res < 1) {
ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
break;
}
}
}
}
printf("\nDisconnected from Asterisk server\n");
}
| void ast_replace_sigchld | ( | void | ) |
Replace the SIGCHLD handler.
Normally, Asterisk has a SIGCHLD handler that is cleaning up all zombie processes from forking elsewhere in Asterisk. However, if you want to wait*() on the process to retrieve information about it's exit status, then this signal handler needs to be temporarily replaced.
Code that executes this function *must* call ast_unreplace_sigchld() after it is finished doing the wait*().
Definition at line 1070 of file asterisk.c.
References ast_mutex_lock, ast_mutex_unlock, null_sig_handler, safe_system_level, safe_system_lock, and safe_system_prev_handler.
Referenced by ast_safe_fork(), and ast_safe_system().
{
unsigned int level;
ast_mutex_lock(&safe_system_lock);
level = safe_system_level++;
/* only replace the handler if it has not already been done */
if (level == 0) {
sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler);
}
ast_mutex_unlock(&safe_system_lock);
}
| static void ast_run_atexits | ( | int | run_cleanups | ) | [static] |
Definition at line 974 of file asterisk.c.
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 really_quit().
{
struct ast_atexit *ae;
AST_LIST_LOCK(&atexits);
while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
if (ae->func && (!ae->is_cleanup || run_cleanups)) {
ae->func();
}
ast_free(ae);
}
AST_LIST_UNLOCK(&atexits);
}
| int ast_safe_system | ( | const char * | s | ) |
Safely spawn an external program while closing file descriptors.
Definition at line 1100 of file asterisk.c.
References ast_close_fds_above_n(), ast_log(), ast_opt_high_priority, ast_replace_sigchld(), ast_set_priority(), ast_unreplace_sigchld(), errno, LOG_WARNING, and status.
Referenced by add_email_attachment(), alarmreceiver_exec(), ast_monitor_stop(), consolehandler(), convert_bdb_to_sqlite3(), mixmonitor_thread(), notify_message(), process_text_line(), remoteconsolehandler(), rotate_file(), run_externnotify(), sendmail(), sendpage(), system_exec_helper(), and vm_change_password_shell().
{
pid_t pid;
int res;
struct rusage rusage;
int status;
#if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
ast_replace_sigchld();
#ifdef HAVE_WORKING_FORK
pid = fork();
#else
pid = vfork();
#endif
if (pid == 0) {
#ifdef HAVE_CAP
cap_t cap = cap_from_text("cap_net_admin-eip");
if (cap_set_proc(cap)) {
/* Careful with order! Logging cannot happen after we close FDs */
ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
}
cap_free(cap);
#endif
#ifdef HAVE_WORKING_FORK
if (ast_opt_high_priority)
ast_set_priority(0);
/* Close file descriptors and launch system command */
ast_close_fds_above_n(STDERR_FILENO);
#endif
execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
_exit(1);
} else if (pid > 0) {
for (;;) {
res = wait4(pid, &status, 0, &rusage);
if (res > -1) {
res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
break;
} else if (errno != EINTR)
break;
}
} else {
ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
res = -1;
}
ast_unreplace_sigchld();
#else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */
res = -1;
#endif
return res;
}
| int ast_set_priority | ( | int | ) |
We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy activity on it, this is a good thing.
Provided by asterisk.c
Definition at line 1699 of file asterisk.c.
References ast_log(), ast_verb, LOG_WARNING, sched_setscheduler, and setpriority.
Referenced by app_exec(), ast_safe_system(), canary_thread(), icesencode(), launch_script(), main(), mp3play(), NBScatplay(), send_waveform_to_fd(), spawn_mp3(), and spawn_ras().
{
struct sched_param sched;
memset(&sched, 0, sizeof(sched));
#ifdef __linux__
if (pri) {
sched.sched_priority = 10;
if (sched_setscheduler(0, SCHED_RR, &sched)) {
ast_log(LOG_WARNING, "Unable to set high priority\n");
return -1;
} else
ast_verb(1, "Set to realtime thread\n");
} else {
sched.sched_priority = 0;
/* According to the manpage, these parameters can never fail. */
sched_setscheduler(0, SCHED_OTHER, &sched);
}
#else
if (pri) {
if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
ast_log(LOG_WARNING, "Unable to set high priority\n");
return -1;
} else
ast_verb(1, "Set to high priority\n");
} else {
/* According to the manpage, these parameters can never fail. */
setpriority(PRIO_PROCESS, 0, 0);
}
#endif
return 0;
}
| static int ast_tryconnect | ( | void | ) | [static] |
Definition at line 1584 of file asterisk.c.
References AF_LOCAL, ast_config_AST_SOCKET, ast_copy_string(), errno, and PF_LOCAL.
Referenced by ast_el_read_char(), and main().
{
struct sockaddr_un sunaddr;
int res;
ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
if (ast_consock < 0) {
fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
return 0;
}
memset(&sunaddr, 0, sizeof(sunaddr));
sunaddr.sun_family = AF_LOCAL;
ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
if (res) {
close(ast_consock);
ast_consock = -1;
return 0;
} else
return 1;
}
| void ast_unregister_atexit | ( | void(*)(void) | func | ) |
Unregister a function registered with ast_register_atexit().
| func | The callback function to unregister. |
Definition at line 1031 of file asterisk.c.
References __ast_unregister_atexit(), AST_LIST_LOCK, AST_LIST_UNLOCK, and ast_atexit::func.
Referenced by do_reload(), and unload_module().
{
AST_LIST_LOCK(&atexits);
__ast_unregister_atexit(func);
AST_LIST_UNLOCK(&atexits);
}
| void ast_unregister_file_version | ( | const char * | file | ) |
Unregister a source code file from the core.
| file | the source file name |
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to automatically unregister the file when the module is unloaded.
Definition at line 360 of file asterisk.c.
References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_atexit::list.
{
struct file_version *find;
AST_RWLIST_WRLOCK(&file_versions);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
if (!strcasecmp(find->file, file)) {
AST_RWLIST_REMOVE_CURRENT(list);
break;
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&file_versions);
if (find)
ast_free(find);
}
| void ast_unregister_thread | ( | void * | id | ) |
Definition at line 439 of file asterisk.c.
References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_atexit::list.
Referenced by dummy_start().
{
struct thread_list_t *x;
AST_RWLIST_WRLOCK(&thread_list);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
if ((void *) x->id == id) {
AST_RWLIST_REMOVE_CURRENT(list);
break;
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&thread_list);
if (x) {
ast_free(x->name);
ast_free(x);
}
}
| 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 1085 of file asterisk.c.
References ast_mutex_lock, ast_mutex_unlock, safe_system_level, safe_system_lock, and safe_system_prev_handler.
Referenced by ast_safe_fork_cleanup(), and ast_safe_system().
{
unsigned int level;
ast_mutex_lock(&safe_system_lock);
level = --safe_system_level;
/* only restore the handler if we are the last one */
if (level == 0) {
sigaction(SIGCHLD, &safe_system_prev_handler, NULL);
}
ast_mutex_unlock(&safe_system_lock);
}
| static int can_safely_quit | ( | shutdown_nice_t | niceness, |
| int | restart | ||
| ) | [static] |
Definition at line 1743 of file asterisk.c.
References ast_begin_shutdown(), ast_cdr_engine_term(), ast_msg_shutdown(), ast_mutex_lock, ast_mutex_unlock, ast_opt_console, ast_undestroyed_channels(), ast_verb, ast_verbose(), NOT_SHUTTING_DOWN, safe_system_lock, SHUTDOWN_NICE, SHUTDOWN_NORMAL, SHUTDOWN_REALLY_NICE, SHUTTING_DOWN, and shuttingdown.
Referenced by quit_handler().
{
/* Check if someone else isn't already doing this. */
ast_mutex_lock(&safe_system_lock);
if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) {
/* Already in progress and other request was less nice. */
ast_mutex_unlock(&safe_system_lock);
ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown");
return 0;
}
shuttingdown = niceness;
ast_mutex_unlock(&safe_system_lock);
/* Try to get as many CDRs as possible submitted to the backend engines
* (if in batch mode). really_quit happens to call it again when running
* the atexit handlers, otherwise this would be a bit early. */
ast_cdr_engine_term();
/* Shutdown the message queue for the technology agnostic message channel.
* This has to occur before we pause shutdown pending ast_undestroyed_channels. */
ast_msg_shutdown();
if (niceness == SHUTDOWN_NORMAL) {
time_t s, e;
/* Begin shutdown routine, hanging up active channels */
ast_begin_shutdown(1);
if (ast_opt_console) {
ast_verb(0, "Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
}
time(&s);
for (;;) {
time(&e);
/* Wait up to 15 seconds for all channels to go away */
if ((e - s) > 15 || !ast_undestroyed_channels() || shuttingdown != niceness) {
break;
}
/* Sleep 1/10 of a second */
usleep(100000);
}
} else if (niceness >= SHUTDOWN_NICE) {
if (niceness != SHUTDOWN_REALLY_NICE) {
ast_begin_shutdown(0);
}
if (ast_opt_console) {
ast_verb(0, "Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
}
for (;;) {
if (!ast_undestroyed_channels() || shuttingdown != niceness) {
break;
}
sleep(1);
}
}
/* Re-acquire lock and check if someone changed the niceness, in which
* case someone else has taken over the shutdown. */
ast_mutex_lock(&safe_system_lock);
if (shuttingdown != niceness) {
if (shuttingdown == NOT_SHUTTING_DOWN && ast_opt_console) {
ast_verb(0, "Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
}
ast_mutex_unlock(&safe_system_lock);
return 0;
}
shuttingdown = SHUTTING_DOWN;
ast_mutex_unlock(&safe_system_lock);
return 1;
}
| static void canary_exit | ( | void | ) | [static] |
Definition at line 3576 of file asterisk.c.
References canary_pid.
Referenced by main().
{
if (canary_pid > 0)
kill(canary_pid, SIGKILL);
}
| static void* canary_thread | ( | void * | unused | ) | [static] |
Definition at line 3547 of file asterisk.c.
References ast_log(), ast_set_priority(), ast_tvnow(), canary_filename, and LOG_WARNING.
Referenced by main().
{
struct stat canary_stat;
struct timeval now;
/* Give the canary time to sing */
sleep(120);
for (;;) {
now = ast_tvnow();
if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
ast_log(LOG_WARNING,
"The canary is no more. He has ceased to be! "
"He's expired and gone to meet his maker! "
"He's a stiff! Bereft of life, he rests in peace. "
"His metabolic processes are now history! He's off the twig! "
"He's kicked the bucket. He's shuffled off his mortal coil, "
"run down the curtain, and joined the bleeding choir invisible!! "
"THIS is an EX-CANARY. (Reducing priority)\n");
ast_set_priority(0);
pthread_exit(NULL);
}
/* Check the canary once a minute */
sleep(60);
}
}
| static char* cli_complete | ( | EditLine * | editline, |
| int | ch | ||
| ) | [static] |
Definition at line 2848 of file asterisk.c.
References AST_CLI_COMPLETE_EOF, ast_cli_completion_matches(), ast_cli_display_match_list(), ast_el_strtoarr(), ast_free, ast_malloc, ast_opt_remote, ast_realloc, and fdsend().
Referenced by ast_el_initialize().
{
int len = 0;
char *ptr;
int nummatches = 0;
char **matches;
int retval = CC_ERROR;
char buf[2048], savechr;
int res;
LineInfo *lf = (LineInfo *)el_line(editline);
savechr = *(char *)lf->cursor;
*(char *)lf->cursor = '\0';
ptr = (char *)lf->cursor;
if (ptr) {
while (ptr > lf->buffer) {
if (isspace(*ptr)) {
ptr++;
break;
}
ptr--;
}
}
len = lf->cursor - ptr;
if (ast_opt_remote) {
snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);
fdsend(ast_consock, buf);
if ((res = read(ast_consock, buf, sizeof(buf) - 1)) < 0) {
return (char*)(CC_ERROR);
}
buf[res] = '\0';
nummatches = atoi(buf);
if (nummatches > 0) {
char *mbuf;
char *new_mbuf;
int mlen = 0, maxmbuf = 2048;
/* Start with a 2048 byte buffer */
if (!(mbuf = ast_malloc(maxmbuf))) {
*((char *) lf->cursor) = savechr;
return (char *)(CC_ERROR);
}
snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);
fdsend(ast_consock, buf);
res = 0;
mbuf[0] = '\0';
while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
if (mlen + 1024 > maxmbuf) {
/* Every step increment buffer 1024 bytes */
maxmbuf += 1024;
new_mbuf = ast_realloc(mbuf, maxmbuf);
if (!new_mbuf) {
ast_free(mbuf);
*((char *) lf->cursor) = savechr;
return (char *)(CC_ERROR);
}
mbuf = new_mbuf;
}
/* Only read 1024 bytes at a time */
res = read(ast_consock, mbuf + mlen, 1024);
if (res > 0)
mlen += res;
}
mbuf[mlen] = '\0';
matches = ast_el_strtoarr(mbuf);
ast_free(mbuf);
} else
matches = (char **) NULL;
} else {
char **p, *oldbuf=NULL;
nummatches = 0;
matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
for (p = matches; p && *p; p++) {
if (!oldbuf || strcmp(*p,oldbuf))
nummatches++;
oldbuf = *p;
}
}
if (matches) {
int i;
int matches_num, maxlen, match_len;
if (matches[0][0] != '\0') {
el_deletestr(editline, (int) len);
el_insertstr(editline, matches[0]);
retval = CC_REFRESH;
}
if (nummatches == 1) {
/* Found an exact match */
el_insertstr(editline, " ");
retval = CC_REFRESH;
} else {
/* Must be more than one match */
for (i = 1, maxlen = 0; matches[i]; i++) {
match_len = strlen(matches[i]);
if (match_len > maxlen)
maxlen = match_len;
}
matches_num = i - 1;
if (matches_num >1) {
fprintf(stdout, "\n");
ast_cli_display_match_list(matches, nummatches, maxlen);
retval = CC_REDISPLAY;
} else {
el_insertstr(editline," ");
retval = CC_REFRESH;
}
}
for (i = 0; matches[i]; i++)
ast_free(matches[i]);
ast_free(matches);
}
*((char *) lf->cursor) = savechr;
return (char *)(long)retval;
}
| static char* cli_prompt | ( | EditLine * | editline | ) | [static] |
Definition at line 2603 of file asterisk.c.
References ast_config_AST_SYSTEM_NAME, ast_localtime(), ast_opt_remote, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_str_set(), ast_strftime(), ast_tvnow(), ASTERISK_PROMPT, ASTERISK_PROMPT2, COLOR_BLACK, COLOR_WHITE, hostname, ast_atexit::list, remotehostname, and term_color_code().
Referenced by ast_el_initialize().
{
char tmp[100];
char *pfmt;
int color_used = 0;
static int cli_prompt_changes = 0;
char term_code[20];
struct passwd *pw;
struct group *gr;
if (prompt == NULL) {
prompt = ast_str_create(100);
} else if (!cli_prompt_changes) {
return ast_str_buffer(prompt);
} else {
ast_str_reset(prompt);
}
if ((pfmt = getenv("ASTERISK_PROMPT"))) {
char *t = pfmt;
struct timeval ts = ast_tvnow();
while (*t != '\0') {
if (*t == '%') {
char hostname[MAXHOSTNAMELEN] = "";
int i, which;
struct ast_tm tm = { 0, };
int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
t++;
switch (*t) {
case 'C': /* color */
t++;
if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)));
t += i - 1;
} else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code)));
t += i - 1;
}
/* If the color has been reset correctly, then there's no need to reset it later */
color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1;
break;
case 'd': /* date */
if (ast_localtime(&ts, &tm, NULL)) {
ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm);
ast_str_append(&prompt, 0, "%s", tmp);
cli_prompt_changes++;
}
break;
case 'g': /* group */
if ((gr = getgrgid(getgid()))) {
ast_str_append(&prompt, 0, "%s", gr->gr_name);
}
break;
case 'h': /* hostname */
if (!gethostname(hostname, sizeof(hostname) - 1)) {
ast_str_append(&prompt, 0, "%s", hostname);
} else {
ast_str_append(&prompt, 0, "%s", "localhost");
}
break;
case 'H': /* short hostname */
if (!gethostname(hostname, sizeof(hostname) - 1)) {
char *dotptr;
if ((dotptr = strchr(hostname, '.'))) {
*dotptr = '\0';
}
ast_str_append(&prompt, 0, "%s", hostname);
} else {
ast_str_append(&prompt, 0, "%s", "localhost");
}
break;
#ifdef HAVE_GETLOADAVG
case 'l': /* load avg */
t++;
if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) {
double list[3];
getloadavg(list, 3);
ast_str_append(&prompt, 0, "%.2f", list[which - 1]);
cli_prompt_changes++;
}
break;
#endif
case 's': /* Asterisk system name (from asterisk.conf) */
ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME);
break;
case 't': /* time */
if (ast_localtime(&ts, &tm, NULL)) {
ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm);
ast_str_append(&prompt, 0, "%s", tmp);
cli_prompt_changes++;
}
break;
case 'u': /* username */
if ((pw = getpwuid(getuid()))) {
ast_str_append(&prompt, 0, "%s", pw->pw_name);
}
break;
case '#': /* process console or remote? */
ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#');
break;
case '%': /* literal % */
ast_str_append(&prompt, 0, "%c", '%');
break;
case '\0': /* % is last character - prevent bug */
t--;
break;
}
} else {
ast_str_append(&prompt, 0, "%c", *t);
}
t++;
}
if (color_used) {
/* Force colors back to normal at end */
ast_str_append(&prompt, 0, "%s", term_color_code(term_code, 0, 0, sizeof(term_code)));
}
} else if (remotehostname) {
ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname);
} else {
ast_str_set(&prompt, 0, "%s", ASTERISK_PROMPT);
}
return ast_str_buffer(prompt);
}
| static int console_print | ( | const char * | s, |
| int | local | ||
| ) | [static] |
Definition at line 1985 of file asterisk.c.
References ast_strlen_zero(), ast_threadstorage_get(), console_state, fix_header(), prefix, VERBOSE_HASMAGIC, console_state_data::verbose_line_level, and VERBOSE_MAGIC2LEVEL.
Referenced by ast_el_read_char(), and console_verboser().
{
struct console_state_data *state =
ast_threadstorage_get(&console_state, sizeof(*state));
char prefix[80];
const char *c;
int num, res = 0;
unsigned int newline;
do {
if (VERBOSE_HASMAGIC(s)) {
/* always use the given line's level, otherwise
we'll use the last line's level */
state->verbose_line_level = VERBOSE_MAGIC2LEVEL(s);
/* move past magic */
s++;
if (local) {
s = fix_header(prefix, sizeof(prefix), s,
state->verbose_line_level);
}
} else {
*prefix = '\0';
}
c = s;
/* for a given line separate on verbose magic, newline, and eol */
if ((s = strchr(c, '\n'))) {
++s;
newline = 1;
} else {
s = strchr(c, '\0');
newline = 0;
}
/* check if we should write this line after calculating begin/end
so we process the case of a higher level line embedded within
two lower level lines */
if (state->verbose_line_level > option_verbose) {
continue;
}
if (local && !ast_strlen_zero(prefix)) {
fputs(prefix, stdout);
}
num = s - c;
if (fwrite(c, sizeof(char), num, stdout) < num) {
break;
}
if (!res) {
/* if at least some info has been written
we'll want to return true */
res = 1;
}
} while (*s);
if (newline) {
/* if ending on a newline then reset last level to zero
since what follows may be not be logging output */
state->verbose_line_level = 0;
}
if (res) {
fflush(stdout);
}
return res;
}
| static int console_state_init | ( | void * | ptr | ) | [static] |
Definition at line 1976 of file asterisk.c.
References console_state_data::verbose_line_level.
{
struct console_state_data *state = ptr;
state->verbose_line_level = 0;
return 0;
}
| static void console_verboser | ( | const char * | s | ) | [static] |
Definition at line 2057 of file asterisk.c.
References ast_opt_console, AST_PTHREADT_NULL, console_print(), and consolethread.
Referenced by print_intro_message().
{
if (!console_print(s, 1)) {
return;
}
/* Wake up a poll()ing console */
if (ast_opt_console && consolethread != AST_PTHREADT_NULL) {
pthread_kill(consolethread, SIGURG);
}
}
| static void consolehandler | ( | char * | s | ) | [static] |
Definition at line 2080 of file asterisk.c.
References ast_all_zeros(), ast_el_add_history(), ast_safe_system(), and term_end().
Referenced by main().
{
printf("%s", term_end());
fflush(stdout);
/* Called when readline data is available */
if (!ast_all_zeros(s))
ast_el_add_history(s);
/* The real handler for bang */
if (s[0] == '!') {
if (s[1])
ast_safe_system(s+1);
else
ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
} else
ast_cli_command(STDOUT_FILENO, s);
}
| static void destroy_match_list | ( | char ** | match_list, |
| int | matches | ||
| ) | [static] |
| static void env_init | ( | void | ) | [static] |
Definition at line 3611 of file asterisk.c.
References ast_build_date, ast_build_hostname, ast_build_kernel, ast_build_machine, ast_build_os, ast_build_user, ast_config_AST_SYSTEM_NAME, and ast_get_version().
Referenced by main().
{
setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1);
setenv("AST_BUILD_HOST", ast_build_hostname, 1);
setenv("AST_BUILD_DATE", ast_build_date, 1);
setenv("AST_BUILD_KERNEL", ast_build_kernel, 1);
setenv("AST_BUILD_MACHINE", ast_build_machine, 1);
setenv("AST_BUILD_OS", ast_build_os, 1);
setenv("AST_BUILD_USER", ast_build_user, 1);
setenv("AST_VERSION", ast_get_version(), 1);
}
| static int fdprint | ( | int | fd, |
| const char * | s | ||
| ) | [static] |
Definition at line 1045 of file asterisk.c.
Referenced by ast_network_puts(), ast_network_puts_mutable(), listener(), netconsole(), and network_verboser().
{
return write(fd, s, strlen(s));
}
| static int fdsend | ( | int | fd, |
| const char * | s | ||
| ) | [static] |
Definition at line 1039 of file asterisk.c.
Referenced by cli_complete(), and send_rasterisk_connect_commands().
{
return write(fd, s, strlen(s) + 1);
}
| static const char* fix_header | ( | char * | outbuf, |
| int | maxout, | ||
| const char * | s, | ||
| char | level | ||
| ) | [static] |
Definition at line 1947 of file asterisk.c.
References COLOR_GRAY, term_color(), VERBOSE_PREFIX_1, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.
Referenced by console_print().
{
const char *cmp;
switch (level) {
case 0: *outbuf = '\0';
return s;
case 1: cmp = VERBOSE_PREFIX_1;
break;
case 2: cmp = VERBOSE_PREFIX_2;
break;
case 3: cmp = VERBOSE_PREFIX_3;
break;
default: cmp = VERBOSE_PREFIX_4;
break;
}
if (!strncmp(s, cmp, strlen(cmp))) {
s += strlen(cmp);
}
term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
return s;
}
| static char* handle_abort_shutdown | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2322 of file asterisk.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cancel_shutdown(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NOT_SHUTTING_DOWN, safe_system_lock, SHUTDOWN_FAST, shuttingdown, and ast_cli_entry::usage.
{
int aborting_shutdown = 0;
switch (cmd) {
case CLI_INIT:
e->command = "core abort shutdown";
e->usage =
"Usage: core abort shutdown\n"
" Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
" call operations.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != e->args)
return CLI_SHOWUSAGE;
ast_mutex_lock(&safe_system_lock);
if (shuttingdown >= SHUTDOWN_FAST) {
aborting_shutdown = 1;
shuttingdown = NOT_SHUTTING_DOWN;
}
ast_mutex_unlock(&safe_system_lock);
if (aborting_shutdown) {
ast_cancel_shutdown();
}
return CLI_SUCCESS;
}
| static char* handle_bang | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2354 of file asterisk.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "!";
e->usage =
"Usage: !<command>\n"
" Executes a given shell command\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
return CLI_SUCCESS;
}
| static char* handle_clear_profile | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 862 of file asterisk.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, DEFINE_PROFILE_MIN_MAX_VALUES, profile_data::e, profile_entry::events, profile_entry::name, prof_data, ast_cli_entry::usage, and profile_entry::value.
{
int i, min, max;
const char *search = NULL;
switch (cmd) {
case CLI_INIT:
e->command = "core clear profile";
e->usage = "Usage: core clear profile\n"
" clear profile information";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (prof_data == NULL)
return 0;
DEFINE_PROFILE_MIN_MAX_VALUES;
for (i= min; i < max; i++) {
if (!search || strstr(prof_data->e[i].name, search)) {
prof_data->e[i].value = 0;
prof_data->e[i].events = 0;
}
}
return CLI_SUCCESS;
}
| static char* handle_restart_gracefully | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2282 of file asterisk.c.
References ast_cli_args::argc, ast_cli_entry::args, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, quit_handler(), SHUTDOWN_NICE, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "core restart gracefully";
e->usage =
"Usage: core restart gracefully\n"
" Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
" restart when all active calls have ended.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != e->args)
return CLI_SHOWUSAGE;
quit_handler(0, SHUTDOWN_NICE, 1 /* restart */);
return CLI_SUCCESS;
}
| static char* handle_restart_now | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2262 of file asterisk.c.
References ast_cli_args::argc, ast_cli_entry::args, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, quit_handler(), SHUTDOWN_NORMAL, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "core restart now";
e->usage =
"Usage: core restart now\n"
" Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
" restart.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != e->args)
return CLI_SHOWUSAGE;
quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */);
return CLI_SUCCESS;
}
| static char* handle_restart_when_convenient | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2302 of file asterisk.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, quit_handler(), SHUTDOWN_REALLY_NICE, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "core restart when convenient";
e->usage =
"Usage: core restart when convenient\n"
" Causes Asterisk to perform a cold restart when all active calls have ended.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != e->args)
return CLI_SHOWUSAGE;
ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */);
return CLI_SUCCESS;
}
| static char* handle_show_profile | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 827 of file asterisk.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, DEFINE_PROFILE_MIN_MAX_VALUES, profile_data::e, profile_data::entries, profile_entry::events, ast_cli_args::fd, profile_data::max_size, profile_entry::name, prof_data, profile_entry::scale, ast_cli_entry::usage, and profile_entry::value.
{
int i, min, max;
const char *search = NULL;
switch (cmd) {
case CLI_INIT:
e->command = "core show profile";
e->usage = "Usage: core show profile\n"
" show profile information";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (prof_data == NULL)
return 0;
DEFINE_PROFILE_MIN_MAX_VALUES;
ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
prof_data->entries, prof_data->max_size);
ast_cli(a->fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events",
"Value", "Average", "Name");
for (i = min; i < max; i++) {
struct profile_entry *entry = &prof_data->e[i];
if (!search || strstr(entry->name, search))
ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n",
i,
(long)entry->scale,
(long)entry->events, (long long)entry->value,
(long long)(entry->events ? entry->value / entry->events : entry->value),
entry->name);
}
return CLI_SUCCESS;
}
| static char* handle_show_settings | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Give an overview of core settings.
Definition at line 459 of file asterisk.c.
References ast_active_channels(), ast_build_date, ast_build_kernel, ast_build_machine, ast_build_os, ast_build_user, ast_cli(), ast_config_AST_AGI_DIR, ast_config_AST_CONFIG_DIR, ast_config_AST_CONFIG_FILE, ast_config_AST_DATA_DIR, ast_config_AST_DB, ast_config_AST_KEY_DIR, ast_config_AST_LOG_DIR, ast_config_AST_MODULE_DIR, ast_config_AST_PID, ast_config_AST_RUN_DIR, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SPOOL_DIR, ast_config_AST_SYSTEM_NAME, ast_config_AST_VAR_DIR, ast_defaultlanguage, ast_eid_default, ast_eid_to_str(), ast_get_version(), ast_language_is_prefix, ast_lastreloadtime, ast_localtime(), AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_GENERIC_PLC, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_realtime_enabled(), ast_startuptime, ast_strftime(), ast_test_flag, ast_verb_console_get(), check_cdr_enabled(), check_manager_enabled(), check_webmanager_enabled(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, S_OR, and ast_cli_entry::usage.
{
char buf[BUFSIZ];
struct ast_tm tm;
char eid_str[128];
switch (cmd) {
case CLI_INIT:
e->command = "core show settings";
e->usage = "Usage: core show settings\n"
" Show core misc settings";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
ast_cli(a->fd, "\nPBX Core settings\n");
ast_cli(a->fd, "-----------------\n");
ast_cli(a->fd, " Version: %s\n", ast_get_version());
ast_cli(a->fd, " Build Options: %s\n", S_OR(AST_BUILDOPTS, "(none)"));
if (option_maxcalls)
ast_cli(a->fd, " Maximum calls: %d (Current %d)\n", option_maxcalls, ast_active_channels());
else
ast_cli(a->fd, " Maximum calls: Not set\n");
if (option_maxfiles)
ast_cli(a->fd, " Maximum open file handles: %d\n", option_maxfiles);
else
ast_cli(a->fd, " Maximum open file handles: Not set\n");
ast_cli(a->fd, " Root console verbosity: %d\n", option_verbose);
ast_cli(a->fd, " Current console verbosity: %d\n", ast_verb_console_get());
ast_cli(a->fd, " Debug level: %d\n", option_debug);
ast_cli(a->fd, " Maximum load average: %lf\n", option_maxload);
#if defined(HAVE_SYSINFO)
ast_cli(a->fd, " Minimum free memory: %ld MB\n", option_minmemfree);
#endif
if (ast_localtime(&ast_startuptime, &tm, NULL)) {
ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
ast_cli(a->fd, " Startup time: %s\n", buf);
}
if (ast_localtime(&ast_lastreloadtime, &tm, NULL)) {
ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
ast_cli(a->fd, " Last reload time: %s\n", buf);
}
ast_cli(a->fd, " System: %s/%s built by %s on %s %s\n", ast_build_os, ast_build_kernel, ast_build_user, ast_build_machine, ast_build_date);
ast_cli(a->fd, " System name: %s\n", ast_config_AST_SYSTEM_NAME);
ast_cli(a->fd, " Entity ID: %s\n", eid_str);
ast_cli(a->fd, " Default language: %s\n", ast_defaultlanguage);
ast_cli(a->fd, " Language prefix: %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
ast_cli(a->fd, " User name and group: %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
ast_cli(a->fd, " Executable includes: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
ast_cli(a->fd, " Transcode via SLIN: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
ast_cli(a->fd, " Internal timing: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled");
ast_cli(a->fd, " Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled");
ast_cli(a->fd, " Generic PLC: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");
ast_cli(a->fd, " Min DTMF duration:: %u\n", option_dtmfminduration);
ast_cli(a->fd, "\n* Subsystems\n");
ast_cli(a->fd, " -------------\n");
ast_cli(a->fd, " Manager (AMI): %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
ast_cli(a->fd, " Web Manager (AMI/HTTP): %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled");
ast_cli(a->fd, " Call data records: %s\n", check_cdr_enabled() ? "Enabled" : "Disabled");
ast_cli(a->fd, " Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
/*! \todo we could check musiconhold, voicemail, smdi, adsi, queues */
ast_cli(a->fd, "\n* Directories\n");
ast_cli(a->fd, " -------------\n");
ast_cli(a->fd, " Configuration file: %s\n", ast_config_AST_CONFIG_FILE);
ast_cli(a->fd, " Configuration directory: %s\n", ast_config_AST_CONFIG_DIR);
ast_cli(a->fd, " Module directory: %s\n", ast_config_AST_MODULE_DIR);
ast_cli(a->fd, " Spool directory: %s\n", ast_config_AST_SPOOL_DIR);
ast_cli(a->fd, " Log directory: %s\n", ast_config_AST_LOG_DIR);
ast_cli(a->fd, " Run/Sockets directory: %s\n", ast_config_AST_RUN_DIR);
ast_cli(a->fd, " PID file: %s\n", ast_config_AST_PID);
ast_cli(a->fd, " VarLib directory: %s\n", ast_config_AST_VAR_DIR);
ast_cli(a->fd, " Data directory: %s\n", ast_config_AST_DATA_DIR);
ast_cli(a->fd, " ASTDB: %s\n", ast_config_AST_DB);
ast_cli(a->fd, " IAX2 Keys directory: %s\n", ast_config_AST_KEY_DIR);
ast_cli(a->fd, " AGI Scripts directory: %s\n", ast_config_AST_AGI_DIR);
ast_cli(a->fd, "\n\n");
return CLI_SUCCESS;
}
| 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 616 of file asterisk.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, len(), and ast_cli_entry::usage.
{
uint64_t physmem, freeram;
uint64_t freeswap = 0;
int nprocs = 0;
long uptime = 0;
int totalswap = 0;
#if defined(HAVE_SYSINFO)
struct sysinfo sys_info;
sysinfo(&sys_info);
uptime = sys_info.uptime / 3600;
physmem = sys_info.totalram * sys_info.mem_unit;
freeram = (sys_info.freeram * sys_info.mem_unit) / 1024;
totalswap = (sys_info.totalswap * sys_info.mem_unit) / 1024;
freeswap = (sys_info.freeswap * sys_info.mem_unit) / 1024;
nprocs = sys_info.procs;
#elif defined(HAVE_SYSCTL)
static int pageshift;
struct vmtotal vmtotal;
struct timeval boottime;
time_t now;
int mib[2], pagesize, usedswap = 0;
size_t len;
/* calculate the uptime by looking at boottime */
time(&now);
mib[0] = CTL_KERN;
mib[1] = KERN_BOOTTIME;
len = sizeof(boottime);
if (sysctl(mib, 2, &boottime, &len, NULL, 0) != -1) {
uptime = now - boottime.tv_sec;
}
uptime = uptime/3600;
/* grab total physical memory */
mib[0] = CTL_HW;
#if defined(HW_PHYSMEM64)
mib[1] = HW_PHYSMEM64;
#else
mib[1] = HW_PHYSMEM;
#endif
len = sizeof(physmem);
sysctl(mib, 2, &physmem, &len, NULL, 0);
pagesize = getpagesize();
pageshift = 0;
while (pagesize > 1) {
pageshift++;
pagesize >>= 1;
}
/* we only need the amount of log(2)1024 for our conversion */
pageshift -= 10;
/* grab vm totals */
mib[0] = CTL_VM;
mib[1] = VM_METER;
len = sizeof(vmtotal);
sysctl(mib, 2, &vmtotal, &len, NULL, 0);
freeram = (vmtotal.t_free << pageshift);
/* generate swap usage and totals */
swapmode(&usedswap, &totalswap);
freeswap = (totalswap - usedswap);
/* grab number of processes */
#if defined(__OpenBSD__)
mib[0] = CTL_KERN;
mib[1] = KERN_NPROCS;
len = sizeof(nprocs);
sysctl(mib, 2, &nprocs, &len, NULL, 0);
#endif
#endif
switch (cmd) {
case CLI_INIT:
e->command = "core show sysinfo";
e->usage =
"Usage: core show sysinfo\n"
" List current system information.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_cli(a->fd, "\nSystem Statistics\n");
ast_cli(a->fd, "-----------------\n");
ast_cli(a->fd, " System Uptime: %lu hours\n", uptime);
ast_cli(a->fd, " Total RAM: %" PRIu64 " KiB\n", physmem / 1024);
ast_cli(a->fd, " Free RAM: %" PRIu64 " KiB\n", freeram);
#if defined(HAVE_SYSINFO)
ast_cli(a->fd, " Buffer RAM: %" PRIu64 " KiB\n", ((uint64_t) sys_info.bufferram * sys_info.mem_unit) / 1024);
#endif
#if defined (HAVE_SYSCTL) || defined(HAVE_SWAPCTL)
ast_cli(a->fd, " Total Swap Space: %u KiB\n", totalswap);
ast_cli(a->fd, " Free Swap Space: %" PRIu64 " KiB\n\n", freeswap);
#endif
ast_cli(a->fd, " Number of Processes: %d \n\n", nprocs);
return CLI_SUCCESS;
}
| static char* handle_show_threads | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 544 of file asterisk.c.
References ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_atexit::list, and ast_cli_entry::usage.
{
int count = 0;
struct thread_list_t *cur;
switch (cmd) {
case CLI_INIT:
e->command = "core show threads";
e->usage =
"Usage: core show threads\n"
" List threads currently active in the system.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
AST_RWLIST_RDLOCK(&thread_list);
AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
ast_cli(a->fd, "%p %d %s\n", (void *)cur->id, cur->lwp, cur->name);
count++;
}
AST_RWLIST_UNLOCK(&thread_list);
ast_cli(a->fd, "%d threads listed.\n", count);
return CLI_SUCCESS;
}
| static char* handle_show_version_files | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
CLI command to list module versions.
Definition at line 891 of file asterisk.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, ast_atexit::list, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
{
#define FORMAT "%-25.25s %-40.40s\n"
struct file_version *iterator;
regex_t regexbuf;
int havepattern = 0;
int havename = 0;
int count_files = 0;
char *ret = NULL;
int matchlen, which = 0;
struct file_version *find;
switch (cmd) {
case CLI_INIT:
e->command = "core show file version [like]";
e->usage =
"Usage: core show file version [like <pattern>]\n"
" Lists the revision numbers of the files used to build this copy of Asterisk.\n"
" Optional regular expression pattern is used to filter the file list.\n";
return NULL;
case CLI_GENERATE:
matchlen = strlen(a->word);
if (a->pos != 3)
return NULL;
AST_RWLIST_RDLOCK(&file_versions);
AST_RWLIST_TRAVERSE(&file_versions, find, list) {
if (!strncasecmp(a->word, find->file, matchlen) && ++which > a->n) {
ret = ast_strdup(find->file);
break;
}
}
AST_RWLIST_UNLOCK(&file_versions);
return ret;
}
switch (a->argc) {
case 6:
if (!strcasecmp(a->argv[4], "like")) {
if (regcomp(®exbuf, a->argv[5], REG_EXTENDED | REG_NOSUB))
return CLI_SHOWUSAGE;
havepattern = 1;
} else
return CLI_SHOWUSAGE;
break;
case 5:
havename = 1;
break;
case 4:
break;
default:
return CLI_SHOWUSAGE;
}
ast_cli(a->fd, FORMAT, "File", "Revision");
ast_cli(a->fd, FORMAT, "----", "--------");
AST_RWLIST_RDLOCK(&file_versions);
AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
if (havename && strcasecmp(iterator->file, a->argv[4]))
continue;
if (havepattern && regexec(®exbuf, iterator->file, 0, NULL, 0))
continue;
ast_cli(a->fd, FORMAT, iterator->file, iterator->version);
count_files++;
if (havename)
break;
}
AST_RWLIST_UNLOCK(&file_versions);
if (!havename) {
ast_cli(a->fd, "%d files listed.\n", count_files);
}
if (havepattern)
regfree(®exbuf);
return CLI_SUCCESS;
#undef FORMAT
}
| static char* handle_stop_gracefully | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2222 of file asterisk.c.
References ast_cli_args::argc, ast_cli_entry::args, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, quit_handler(), SHUTDOWN_NICE, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "core stop gracefully";
e->usage =
"Usage: core stop gracefully\n"
" Causes Asterisk to not accept new calls, and exit when all\n"
" active calls have terminated normally.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != e->args)
return CLI_SHOWUSAGE;
quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */);
return CLI_SUCCESS;
}
| static char* handle_stop_now | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2203 of file asterisk.c.
References ast_cli_args::argc, ast_cli_entry::args, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, quit_handler(), SHUTDOWN_NORMAL, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "core stop now";
e->usage =
"Usage: core stop now\n"
" Shuts down a running Asterisk immediately, hanging up all active calls .\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != e->args)
return CLI_SHOWUSAGE;
quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */);
return CLI_SUCCESS;
}
| static char* handle_stop_when_convenient | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2242 of file asterisk.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, quit_handler(), SHUTDOWN_REALLY_NICE, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "core stop when convenient";
e->usage =
"Usage: core stop when convenient\n"
" Causes Asterisk to perform a shutdown when all active calls have ended.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != e->args)
return CLI_SHOWUSAGE;
ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */);
return CLI_SUCCESS;
}
| static char* handle_version | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2172 of file asterisk.c.
References ast_cli_args::argc, ast_build_date, ast_build_hostname, ast_build_machine, ast_build_os, ast_build_user, ast_cli(), ast_get_version(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "core show version";
e->usage =
"Usage: core show version\n"
" Shows Asterisk version information.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != 3)
return CLI_SHOWUSAGE;
ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
ast_get_version(), ast_build_user, ast_build_hostname,
ast_build_machine, ast_build_os, ast_build_date);
return CLI_SUCCESS;
}
| static void* listener | ( | void * | unused | ) | [static] |
Definition at line 1432 of file asterisk.c.
References AF_LOCAL, ast_log(), AST_MAX_CONNECTS, ast_opt_hide_connect, ast_poll, ast_pthread_create_detached_background, ast_socket, ast_verb, consoles, errno, console::fd, fdprint(), console::gid, len(), LOG_ERROR, LOG_WARNING, console::mute, netconsole(), console::option_verbose, and console::uid.
Referenced by ast_makesocket().
{
struct sockaddr_un sunaddr;
int s;
socklen_t len;
int x;
int flags;
struct pollfd fds[1];
for (;;) {
if (ast_socket < 0)
return NULL;
fds[0].fd = ast_socket;
fds[0].events = POLLIN;
s = ast_poll(fds, 1, -1);
pthread_testcancel();
if (s < 0) {
if (errno != EINTR)
ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
continue;
}
len = sizeof(sunaddr);
s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
if (s < 0) {
if (errno != EINTR)
ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
} else {
#if !defined(SO_PASSCRED)
{
#else
int sckopt = 1;
/* turn on socket credentials passing. */
if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) {
ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n");
} else {
#endif
for (x = 0; x < AST_MAX_CONNECTS; x++) {
if (consoles[x].fd >= 0) {
continue;
}
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
fdprint(s, "Server failed to create pipe\n");
close(s);
break;
}
flags = fcntl(consoles[x].p[1], F_GETFL);
fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
/* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
to know if the user didn't send the credentials. */
consoles[x].uid = -2;
consoles[x].gid = -2;
/* Server default of remote console verbosity level is OFF. */
consoles[x].option_verbose = 0;
consoles[x].fd = s;
if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) {
consoles[x].fd = -1;
ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
close(consoles[x].p[0]);
close(consoles[x].p[1]);
fdprint(s, "Server failed to spawn thread\n");
close(s);
}
break;
}
if (x >= AST_MAX_CONNECTS) {
fdprint(s, "No more connections allowed\n");
ast_log(LOG_WARNING, "No more connections allowed\n");
close(s);
} else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) {
ast_verb(3, "Remote UNIX connection\n");
}
}
}
}
return NULL;
}
| int main | ( | int | argc, |
| char * | argv[] | ||
| ) |
< Result from the module load subsystem
Definition at line 3645 of file asterisk.c.
References __ast_mm_init_phase_1(), __ast_mm_init_phase_2(), __quit_handler(), _argv, ARRAY_LEN, ast_alaw_init(), ast_aoc_cli_init(), ast_autoservice_init(), ast_builtins_init(), ast_cc_init(), ast_cdr_engine_init(), ast_cel_engine_init(), ast_channels_init(), ast_clear_flag, ast_cli_perms_init(), ast_cli_register_multiple(), ast_close_fds_above_n(), ast_config_AST_PID, ast_config_AST_RUN_DIR, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SBIN_DIR, ast_config_AST_SOCKET, ast_copy_string(), ast_data_init(), ast_device_state_engine_init(), ast_dsp_init(), ast_el_initialize(), ast_el_read_char(), ast_el_read_history(), ast_enum_init(), ast_event_init(), ast_fd_init(), ast_FD_SETSIZE, ast_FDMAX, ast_features_init(), ast_file_init(), ast_format_attr_init(), ast_format_list_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_language_is_prefix, ast_lastreloadtime, ast_log(), ast_makesocket(), ast_msg_init(), ast_named_acl_init(), 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_FULLY_BOOTED, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_LIGHT_BACKGROUND, AST_OPT_FLAG_MUTE, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_OVERRIDE_CONFIG, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_RECONNECT, AST_OPT_FLAG_REMOTE, AST_OPT_FLAG_TIMESTAMP, ast_opt_high_priority, ast_opt_no_fork, ast_opt_remote, ast_pbx_init(), ast_presence_state_engine_init(), ast_process_pending_reloads(), ast_pthread_create_detached, ast_readconfig(), ast_register_atexit(), ast_remotecontrol(), ast_rtp_engine_init(), ast_select(), ast_set_flag, ast_set_priority(), ast_ssl_init(), ast_startuptime, ast_strlen_zero(), ast_stun_init(), ast_term_init(), ast_test_flag, ast_test_init(), ast_timing_init(), ast_tps_init(), ast_translate_init(), ast_tryconnect(), ast_tvnow(), ast_udptl_init(), ast_ulaw_init(), ast_utils_init(), ast_verb, ast_xmldoc_load_documentation(), astdb_init(), astobj2_init(), callerid_init(), canary_exit(), canary_filename, canary_pid, canary_thread(), cfg_paths, COLOR_BLACK, COLOR_BRWHITE, _cfg_paths::config_file, consolehandler(), consolethread, dnsmgr_init(), dnsmgr_start_refresh(), el, el_hist, env_init(), errno, EVENT_FLAG_SYSTEM, f, FD_SET, FD_ZERO, hostname, ignore_sig_handler, init_framer(), init_logger(), init_manager(), load_modules(), load_pbx(), LOG_WARNING, main_atexit(), manager_event, mon_sig_flags, monitor_sig_flags(), multi_thread_safe, option_verbose, print_intro_message(), quit_handler(), randompool, read_config_maps(), register_config_cli(), run_startup_commands(), set_icon(), set_title(), show_cli_help(), show_version(), SHUTDOWN_FAST, sig_alert_pipe, sig_flags, _cfg_paths::socket_path, tdd_init(), term_color(), term_end(), term_quit(), and threadstorage_init().
{
int c;
char filename[80] = "";
char hostname[MAXHOSTNAMELEN] = "";
char tmp[80];
char * xarg = NULL;
int x;
FILE *f;
sigset_t sigs;
int num;
int isroot = 1, rundir_exists = 0;
char *buf;
const char *runuser = NULL, *rungroup = NULL;
char *remotesock = NULL;
int moduleresult; /*!< Result from the module load subsystem */
struct rlimit l;
/* Remember original args for restart */
if (argc > ARRAY_LEN(_argv) - 1) {
fprintf(stderr, "Truncating argument size to %d\n", (int)ARRAY_LEN(_argv) - 1);
argc = ARRAY_LEN(_argv) - 1;
}
for (x = 0; x < argc; x++)
_argv[x] = argv[x];
_argv[x] = NULL;
if (geteuid() != 0)
isroot = 0;
/* if the progname is rasterisk consider it a remote console */
if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
}
if (gethostname(hostname, sizeof(hostname)-1))
ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
ast_mainpid = getpid();
if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
/* Check for options */
while ((c = getopt(argc, argv, "BC:cde:FfG:ghIiL:M:mnpqRrs:TtU:VvWXx:")) != -1) {
/*!\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. */
switch (c) {
case 'B': /* Force black background */
ast_set_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
ast_clear_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
break;
case 'X':
ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES);
break;
case 'C':
ast_copy_string(cfg_paths.config_file, optarg, sizeof(cfg_paths.config_file));
ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
break;
case 'c':
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
break;
case 'd':
option_debug++;
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
break;
#if defined(HAVE_SYSINFO)
case 'e':
if ((sscanf(&optarg[1], "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
option_minmemfree = 0;
}
break;
#endif
#if HAVE_WORKING_FORK
case 'F':
ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
break;
case 'f':
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
break;
#endif
case 'G':
rungroup = ast_strdupa(optarg);
break;
case 'g':
ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
break;
case 'h':
show_cli_help();
exit(0);
case 'I':
ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING);
break;
case 'i':
ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
break;
case 'L':
if ((sscanf(optarg, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
option_maxload = 0.0;
}
break;
case 'M':
if ((sscanf(optarg, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
option_maxcalls = 0;
}
break;
case 'm':
ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
break;
case 'n':
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
break;
case 'p':
ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
break;
case 'q':
ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
break;
case 'R':
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
break;
case 'r':
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
break;
case 's':
remotesock = ast_strdupa(optarg);
break;
case 'T':
ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
break;
case 't':
ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
break;
case 'U':
runuser = ast_strdupa(optarg);
break;
case 'V':
show_version();
exit(0);
case 'v':
option_verbose++;
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
break;
case 'W': /* White background */
ast_set_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND);
ast_clear_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
break;
case 'x':
/* -r is implied by -x so set the flags -r sets as well. */
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC | AST_OPT_FLAG_NO_COLOR);
xarg = ast_strdupa(optarg);
break;
case '?':
exit(1);
}
}
/* For remote connections, change the name of the remote connection.
* We do this for the benefit of init scripts (which need to know if/when
* the main asterisk process has died yet). */
if (ast_opt_remote) {
strcpy(argv[0], "rasterisk");
for (x = 1; x < argc; x++) {
argv[x] = argv[0] + 10;
}
}
ast_readconfig();
env_init();
if (ast_opt_remote && remotesock != NULL)
ast_copy_string((char *) cfg_paths.socket_path, remotesock, sizeof(cfg_paths.socket_path));
if (!ast_language_is_prefix && !ast_opt_remote) {
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");
}
if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
fprintf(stderr, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
}
if (ast_opt_dump_core) {
memset(&l, 0, sizeof(l));
l.rlim_cur = RLIM_INFINITY;
l.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_CORE, &l)) {
fprintf(stderr, "Unable to disable core size resource limit: %s\n", strerror(errno));
}
}
if (getrlimit(RLIMIT_NOFILE, &l)) {
fprintf(stderr, "Unable to check file descriptor limit: %s\n", strerror(errno));
}
#if !defined(CONFIGURE_RAN_AS_ROOT)
/* Check if select(2) will run with more file descriptors */
do {
int fd, fd2;
ast_fdset readers;
struct timeval tv = { 0, };
if (l.rlim_cur <= FD_SETSIZE) {
/* The limit of select()able FDs is irrelevant, because we'll never
* open one that high. */
break;
}
if (!(fd = open("/dev/null", O_RDONLY))) {
fprintf(stderr, "Cannot open a file descriptor at boot? %s\n", strerror(errno));
break; /* XXX Should we exit() here? XXX */
}
fd2 = ((l.rlim_cur > sizeof(readers) * 8) ? sizeof(readers) * 8 : l.rlim_cur) - 1;
if (dup2(fd, fd2) < 0) {
fprintf(stderr, "Cannot open maximum file descriptor %d at boot? %s\n", fd2, strerror(errno));
close(fd);
break;
}
FD_ZERO(&readers);
FD_SET(fd2, &readers);
if (ast_select(fd2 + 1, &readers, NULL, NULL, &tv) < 0) {
fprintf(stderr, "Maximum select()able file descriptor is %d\n", FD_SETSIZE);
}
ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
close(fd);
close(fd2);
} while (0);
#elif defined(HAVE_VARIABLE_FDSET)
ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur;
#endif /* !defined(CONFIGURE_RAN_AS_ROOT) */
if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
rungroup = ast_config_AST_RUN_GROUP;
if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
runuser = ast_config_AST_RUN_USER;
/* Must install this signal handler up here to ensure that if the canary
* fails to execute that it doesn't kill the Asterisk process.
*/
sigaction(SIGCHLD, &child_handler, NULL);
/* It's common on some platforms to clear /var/run at boot. Create the
* socket file directory before we drop privileges. */
if (mkdir(ast_config_AST_RUN_DIR, 0755)) {
if (errno == EEXIST) {
rundir_exists = 1;
} else {
fprintf(stderr, "Unable to create socket file directory. Remote consoles will not be able to connect! (%s)\n", strerror(x));
}
}
#ifndef __CYGWIN__
if (isroot) {
ast_set_priority(ast_opt_high_priority);
}
if (isroot && rungroup) {
struct group *gr;
gr = getgrnam(rungroup);
if (!gr) {
fprintf(stderr, "No such group '%s'!\n", rungroup);
exit(1);
}
if (!rundir_exists && chown(ast_config_AST_RUN_DIR, -1, gr->gr_gid)) {
fprintf(stderr, "Unable to chgrp run directory to %d (%s)\n", (int) gr->gr_gid, rungroup);
}
if (setgid(gr->gr_gid)) {
fprintf(stderr, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
exit(1);
}
if (setgroups(0, NULL)) {
fprintf(stderr, "Unable to drop unneeded groups\n");
exit(1);
}
}
if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
#ifdef HAVE_CAP
int has_cap = 1;
#endif /* HAVE_CAP */
struct passwd *pw;
pw = getpwnam(runuser);
if (!pw) {
fprintf(stderr, "No such user '%s'!\n", runuser);
exit(1);
}
if (chown(ast_config_AST_RUN_DIR, pw->pw_uid, -1)) {
fprintf(stderr, "Unable to chown run directory to %d (%s)\n", (int) pw->pw_uid, runuser);
}
#ifdef HAVE_CAP
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
has_cap = 0;
}
#endif /* HAVE_CAP */
if (!isroot && pw->pw_uid != geteuid()) {
fprintf(stderr, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
exit(1);
}
if (!rungroup) {
if (setgid(pw->pw_gid)) {
fprintf(stderr, "Unable to setgid to %d!\n", (int)pw->pw_gid);
exit(1);
}
if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
fprintf(stderr, "Unable to init groups for '%s'\n", runuser);
exit(1);
}
}
if (setuid(pw->pw_uid)) {
fprintf(stderr, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
exit(1);
}
#ifdef HAVE_CAP
if (has_cap) {
cap_t cap;
cap = cap_from_text("cap_net_admin=eip");
if (cap_set_proc(cap)) {
fprintf(stderr, "Unable to install capabilities.\n");
}
if (cap_free(cap)) {
fprintf(stderr, "Unable to drop capabilities.\n");
}
}
#endif /* HAVE_CAP */
}
#endif /* __CYGWIN__ */
#ifdef linux
if (geteuid() && ast_opt_dump_core) {
if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
fprintf(stderr, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
}
}
#endif
{
#if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
#if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
#define eaccess euidaccess
#endif
char dir[PATH_MAX];
if (!getcwd(dir, sizeof(dir)) || eaccess(dir, R_OK | X_OK | F_OK)) {
fprintf(stderr, "Unable to access the running directory (%s). Changing to '/' for compatibility.\n", strerror(errno));
/* If we cannot access the CWD, then we couldn't dump core anyway,
* so chdir("/") won't break anything. */
if (chdir("/")) {
/* chdir(/) should never fail, so this ends up being a no-op */
fprintf(stderr, "chdir(\"/\") failed?!! %s\n", strerror(errno));
}
} else
#endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */
if (!ast_opt_no_fork && !ast_opt_dump_core) {
/* Backgrounding, but no cores, so chdir won't break anything. */
if (chdir("/")) {
fprintf(stderr, "Unable to chdir(\"/\") ?!! %s\n", strerror(errno));
}
}
}
/* Initial value of the maximum active system verbosity level. */
ast_verb_sys_level = option_verbose;
if (ast_tryconnect()) {
/* One is already running */
if (ast_opt_remote) {
multi_thread_safe = 1;
if (ast_opt_exec) {
ast_remotecontrol(xarg);
quit_handler(0, SHUTDOWN_FAST, 0);
exit(0);
}
print_intro_message(runuser, rungroup);
printf("%s", term_quit());
ast_remotecontrol(NULL);
quit_handler(0, SHUTDOWN_FAST, 0);
exit(0);
} else {
fprintf(stderr, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
printf("%s", term_quit());
exit(1);
}
} else if (ast_opt_remote || ast_opt_exec) {
fprintf(stderr, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
printf("%s", term_quit());
exit(1);
}
/* This needs to remain as high up in the initial start up as possible.
* daemon causes a fork to occur, which has all sorts of unintended
* consequences for things that interact with threads. This call *must*
* occur before anything in Asterisk spawns or manipulates thread related
* primitives. */
#if HAVE_WORKING_FORK
if (ast_opt_always_fork || !ast_opt_no_fork) {
#ifndef HAVE_SBIN_LAUNCHD
if (daemon(1, 0) < 0) {
fprintf(stderr, "daemon() failed: %s\n", strerror(errno));
} else {
ast_mainpid = getpid();
}
#else
fprintf(stderr, "Mac OS X detected. Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n");
#endif
}
#endif
/* At this point everything has been forked successfully,
* we have determined that we aren't attempting to connect to
* an Asterisk instance, and that there isn't one already running. */
multi_thread_safe = 1;
#if defined(__AST_DEBUG_MALLOC)
__ast_mm_init_phase_1();
#endif /* defined(__AST_DEBUG_MALLOC) */
/* Spawning of astcanary must happen AFTER the call to daemon(3) */
if (isroot && ast_opt_high_priority) {
snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR);
/* Don't let the canary child kill Asterisk, if it dies immediately */
sigaction(SIGPIPE, &ignore_sig_handler, NULL);
canary_pid = fork();
if (canary_pid == 0) {
char canary_binary[PATH_MAX], ppid[12];
/* Reset signal handler */
signal(SIGCHLD, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
ast_close_fds_above_n(0);
ast_set_priority(0);
snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid);
/* Use the astcanary binary that we installed */
snprintf(canary_binary, sizeof(canary_binary), "%s/astcanary", ast_config_AST_SBIN_DIR);
execl(canary_binary, "astcanary", canary_filename, ppid, (char *)NULL);
/* Should never happen */
_exit(1);
} else if (canary_pid > 0) {
pthread_t dont_care;
ast_pthread_create_detached(&dont_care, NULL, canary_thread, NULL);
}
/* Kill the canary when we exit */
ast_register_atexit(canary_exit);
}
/* Blindly write the PID file. */
unlink(ast_config_AST_PID);
f = fopen(ast_config_AST_PID, "w");
if (f) {
fprintf(f, "%ld\n", (long)ast_mainpid);
fclose(f);
} else {
fprintf(stderr, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
}
/* Initialize the terminal. Since all processes have been forked,
* we can now start using the standard log messages.
*/
ast_term_init();
printf("%s", term_end());
fflush(stdout);
print_intro_message(runuser, rungroup);
if (ast_opt_console) {
ast_verb(0, "[ Initializing Custom Configuration Options ]\n");
}
/* custom config setup */
register_config_cli();
read_config_maps();
if (ast_opt_console) {
if (el_hist == NULL || el == NULL)
ast_el_initialize();
if (!ast_strlen_zero(filename))
ast_el_read_history(filename);
}
ast_ulaw_init();
ast_alaw_init();
tdd_init();
callerid_init();
ast_builtins_init();
if (ast_utils_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_tps_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_fd_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_pbx_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_event_init()) {
printf("%s", term_quit());
exit(1);
}
#ifdef TEST_FRAMEWORK
if (ast_test_init()) {
printf("%s", term_quit());
exit(1);
}
#endif
if (ast_translate_init()) {
printf("%s", term_quit());
exit(1);
}
ast_aoc_cli_init();
ast_makesocket();
sigemptyset(&sigs);
sigaddset(&sigs, SIGHUP);
sigaddset(&sigs, SIGTERM);
sigaddset(&sigs, SIGINT);
sigaddset(&sigs, SIGPIPE);
sigaddset(&sigs, SIGWINCH);
pthread_sigmask(SIG_BLOCK, &sigs, NULL);
sigaction(SIGURG, &urg_handler, NULL);
signal(SIGINT, __quit_handler);
signal(SIGTERM, __quit_handler);
sigaction(SIGHUP, &hup_handler, NULL);
sigaction(SIGPIPE, &ignore_sig_handler, NULL);
/* ensure that the random number generators are seeded with a different value every time
Asterisk is started
*/
srand((unsigned int) getpid() + (unsigned int) time(NULL));
initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
if (init_logger()) { /* Start logging subsystem */
printf("%s", term_quit());
exit(1);
}
threadstorage_init();
astobj2_init();
ast_format_attr_init();
ast_format_list_init();
ast_rtp_engine_init();
ast_autoservice_init();
if (ast_timing_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_ssl_init()) {
printf("%s", term_quit());
exit(1);
}
#ifdef AST_XML_DOCS
/* Load XML documentation. */
ast_xmldoc_load_documentation();
#endif
if (astdb_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_msg_init()) {
printf("%s", term_quit());
exit(1);
}
/* initialize the data retrieval API */
if (ast_data_init()) {
printf ("%s", term_quit());
exit(1);
}
ast_channels_init();
if ((moduleresult = load_modules(1))) { /* Load modules, pre-load only */
printf("%s", term_quit());
exit(moduleresult == -2 ? 2 : 1);
}
if (dnsmgr_init()) { /* Initialize the DNS manager */
printf("%s", term_quit());
exit(1);
}
if (ast_named_acl_init()) { /* Initialize the Named ACL system */
printf("%s", term_quit());
exit(1);
}
ast_http_init(); /* Start the HTTP server, if needed */
if (init_manager()) {
printf("%s", term_quit());
exit(1);
}
if (ast_cdr_engine_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_cel_engine_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_device_state_engine_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_presence_state_engine_init()) {
printf("%s", term_quit());
exit(1);
}
ast_dsp_init();
ast_udptl_init();
if (ast_image_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_file_init()) {
printf("%s", term_quit());
exit(1);
}
if (load_pbx()) {
printf("%s", term_quit());
exit(1);
}
if (ast_indications_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_features_init()) {
printf("%s", term_quit());
exit(1);
}
if (init_framer()) {
printf("%s", term_quit());
exit(1);
}
if (ast_enum_init()) {
printf("%s", term_quit());
exit(1);
}
if (ast_cc_init()) {
printf("%s", term_quit());
exit(1);
}
if ((moduleresult = load_modules(0))) { /* Load modules */
printf("%s", term_quit());
exit(moduleresult == -2 ? 2 : 1);
}
/* loads the cli_permissoins.conf file needed to implement cli restrictions. */
ast_cli_perms_init(0);
ast_stun_init();
dnsmgr_start_refresh();
/* We might have the option of showing a console, but for now just
do nothing... */
ast_verb(0, "%s\n", term_color(tmp, "Asterisk Ready.", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
if (ast_opt_no_fork) {
consolethread = pthread_self();
}
if (pipe(sig_alert_pipe)) {
sig_alert_pipe[0] = sig_alert_pipe[1] = -1;
}
ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
/*** DOCUMENTATION
<managerEventInstance>
<synopsis>Raised when all Asterisk initialization procedures have finished.</synopsis>
</managerEventInstance>
***/
manager_event(EVENT_FLAG_SYSTEM, "FullyBooted", "Status: Fully Booted\r\n");
ast_process_pending_reloads();
pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
#if defined(__AST_DEBUG_MALLOC)
__ast_mm_init_phase_2();
#endif /* defined(__AST_DEBUG_MALLOC) */
ast_lastreloadtime = ast_startuptime = ast_tvnow();
ast_cli_register_multiple(cli_asterisk_shutdown, ARRAY_LEN(cli_asterisk_shutdown));
ast_cli_register_multiple(cli_asterisk, ARRAY_LEN(cli_asterisk));
ast_register_atexit(main_atexit);
run_startup_commands();
if (ast_opt_console) {
/* Console stuff now... */
/* Register our quit function */
char title[256];
ast_pthread_create_detached(&mon_sig_flags, NULL, monitor_sig_flags, NULL);
set_icon("Asterisk");
snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
set_title(title);
el_set(el, EL_GETCFN, ast_el_read_char);
for (;;) {
if (sig_flags.need_quit || sig_flags.need_quit_handler) {
quit_handler(0, SHUTDOWN_FAST, 0);
break;
}
buf = (char *) el_gets(el, &num);
if (!buf && write(1, "", 1) < 0)
goto lostterm;
if (buf) {
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
consolehandler((char *)buf);
} else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) {
/* Whoa, stdout disappeared from under us... Make /dev/null's */
int fd;
fd = open("/dev/null", O_RDWR);
if (fd > -1) {
dup2(fd, STDOUT_FILENO);
dup2(fd, STDIN_FILENO);
} else
ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
break;
}
}
}
monitor_sig_flags(NULL);
lostterm:
return 0;
}
| static void main_atexit | ( | void | ) | [static] |
Definition at line 3640 of file asterisk.c.
References ARRAY_LEN, and ast_cli_unregister_multiple().
Referenced by main().
| static void* monitor_sig_flags | ( | void * | unused | ) | [static] |
Definition at line 3521 of file asterisk.c.
References ast_module_reload(), ast_poll, AST_PTHREADT_NULL, consolethread, quit_handler(), SHUTDOWN_NORMAL, sig_alert_pipe, and sig_flags.
Referenced by main().
{
for (;;) {
struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
int a;
ast_poll(&p, 1, -1);
if (sig_flags.need_reload) {
sig_flags.need_reload = 0;
ast_module_reload(NULL);
}
if (sig_flags.need_quit) {
sig_flags.need_quit = 0;
if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
sig_flags.need_quit_handler = 1;
pthread_kill(consolethread, SIGURG);
} else {
quit_handler(0, SHUTDOWN_NORMAL, 0);
}
}
if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) {
}
}
return NULL;
}
| static void* netconsole | ( | void * | vconsole | ) | [static] |
Definition at line 1342 of file asterisk.c.
References ast_cli_command_multiple_full(), ast_copy_string(), ast_get_version(), ast_log(), ast_opt_hide_connect, ast_poll, ast_verb, ast_verb_console_register(), ast_verb_console_unregister(), errno, console::fd, fdprint(), console::gid, hostname, inbuf(), LOG_ERROR, LOG_WARNING, console::option_verbose, console::p, read_credentials(), and console::uid.
Referenced by listener().
{
struct console *con = vconsole;
char hostname[MAXHOSTNAMELEN] = "";
char inbuf[512];
char outbuf[512];
const char * const end_buf = inbuf + sizeof(inbuf);
char *start_read = inbuf;
int res;
struct pollfd fds[2];
if (gethostname(hostname, sizeof(hostname)-1))
ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
snprintf(outbuf, sizeof(outbuf), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
fdprint(con->fd, outbuf);
ast_verb_console_register(&con->option_verbose);
for (;;) {
fds[0].fd = con->fd;
fds[0].events = POLLIN;
fds[0].revents = 0;
fds[1].fd = con->p[0];
fds[1].events = POLLIN;
fds[1].revents = 0;
res = ast_poll(fds, 2, -1);
if (res < 0) {
if (errno != EINTR)
ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
continue;
}
if (fds[0].revents) {
int cmds_read, bytes_read;
if ((bytes_read = read_credentials(con->fd, start_read, end_buf - start_read, con)) < 1) {
break;
}
/* XXX This will only work if it is the first command, and I'm not sure fixing it is worth the effort. */
if (strncmp(inbuf, "cli quit after ", 15) == 0) {
ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read - 15, inbuf + 15);
break;
}
/* ast_cli_command_multiple_full will only process individual commands terminated by a
* NULL and not trailing partial commands. */
if (!(cmds_read = ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read + start_read - inbuf, inbuf))) {
/* No commands were read. We either have a short read on the first command
* with space left, or a command that is too long */
if (start_read + bytes_read < end_buf) {
start_read += bytes_read;
} else {
ast_log(LOG_ERROR, "Command too long! Skipping\n");
start_read = inbuf;
}
continue;
}
if (start_read[bytes_read - 1] == '\0') {
/* The read ended on a command boundary, start reading again at the head of inbuf */
start_read = inbuf;
continue;
}
/* If we get this far, we have left over characters that have not been processed.
* Advance to the character after the last command read by ast_cli_command_multiple_full.
* We are guaranteed to have at least cmds_read NULLs */
while (cmds_read-- && (start_read = strchr(start_read, '\0'))) {
start_read++;
}
memmove(inbuf, start_read, end_buf - start_read);
start_read = end_buf - start_read + inbuf;
}
if (fds[1].revents) {
res = read_credentials(con->p[0], outbuf, sizeof(outbuf), con);
if (res < 1) {
ast_log(LOG_ERROR, "read returned %d\n", res);
break;
}
res = write(con->fd, outbuf, res);
if (res < 1)
break;
}
}
ast_verb_console_unregister();
if (!ast_opt_hide_connect) {
ast_verb(3, "Remote UNIX connection disconnected\n");
}
close(con->fd);
close(con->p[0]);
close(con->p[1]);
con->fd = -1;
return NULL;
}
| static void network_verboser | ( | const char * | string | ) | [static] |
Definition at line 1262 of file asterisk.c.
References __LOG_VERBOSE, AST_MAX_CONNECTS, consoles, fdprint(), levels, mute, and VERBOSE_MAGIC2LEVEL.
Referenced by ast_makesocket().
{
int x;
int verb_level;
/* Send to any network console clients if client verbocity allows. */
verb_level = VERBOSE_MAGIC2LEVEL(string);
for (x = 0; x < AST_MAX_CONNECTS; ++x) {
if (consoles[x].fd < 0
|| consoles[x].mute
|| consoles[x].levels[__LOG_VERBOSE]
|| consoles[x].option_verbose < verb_level) {
continue;
}
fdprint(consoles[x].p[1], string);
}
}
| static void print_intro_message | ( | const char * | runuser, |
| const char * | rungroup | ||
| ) | [static] |
Definition at line 3623 of file asterisk.c.
References ast_opt_console, ast_opt_exec, ast_opt_remote, ast_register_verbose(), ast_verbose(), console_verboser(), and WELCOME_MESSAGE.
Referenced by main().
{
if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
if (ast_register_verbose(console_verboser)) {
fprintf(stderr, "Unable to register console verboser?\n");
return;
}
WELCOME_MESSAGE;
if (runuser) {
ast_verbose("Running as user '%s'\n", runuser);
}
if (rungroup) {
ast_verbose("Running under group '%s'\n", rungroup);
}
}
}
| static void quit_handler | ( | int | num, |
| shutdown_nice_t | niceness, | ||
| int | restart | ||
| ) | [static] |
Definition at line 1734 of file asterisk.c.
References can_safely_quit(), and really_quit().
Referenced by ast_el_read_char(), handle_restart_gracefully(), handle_restart_now(), handle_restart_when_convenient(), handle_stop_gracefully(), handle_stop_now(), handle_stop_when_convenient(), main(), monitor_sig_flags(), and remoteconsolehandler().
{
if (can_safely_quit(niceness, restart)) {
really_quit(num, niceness, restart);
/* No one gets here. */
}
/* It wasn't our time. */
}
| static __inline uint64_t rdtsc | ( | void | ) | [static] |
| static int read_credentials | ( | int | fd, |
| char * | buffer, | ||
| size_t | size, | ||
| struct console * | con | ||
| ) | [static] |
read() function supporting the reception of user credentials.
| fd | Socket file descriptor. |
| buffer | Receive buffer. |
| size | 'buffer' size. |
| con | Console structure to set received credentials |
| -1 | on error |
| the | number of bytes received on success. |
Definition at line 1292 of file asterisk.c.
References console::gid, len(), and console::uid.
Referenced by netconsole().
{
#if defined(SO_PEERCRED)
#ifdef HAVE_STRUCT_SOCKPEERCRED_UID
#define HAVE_STRUCT_UCRED_UID
struct sockpeercred cred;
#else
struct ucred cred;
#endif
socklen_t len = sizeof(cred);
#endif
#if defined(HAVE_GETPEEREID)
uid_t uid;
gid_t gid;
#else
int uid, gid;
#endif
int result;
result = read(fd, buffer, size);
if (result < 0) {
return result;
}
#if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID))
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) {
return result;
}
#if defined(HAVE_STRUCT_UCRED_UID)
uid = cred.uid;
gid = cred.gid;
#else /* defined(HAVE_STRUCT_UCRED_CR_UID) */
uid = cred.cr_uid;
gid = cred.cr_gid;
#endif /* defined(HAVE_STRUCT_UCRED_UID) */
#elif defined(HAVE_GETPEEREID)
if (getpeereid(fd, &uid, &gid)) {
return result;
}
#else
return result;
#endif
con->uid = uid;
con->gid = gid;
return result;
}
| static void really_quit | ( | int | num, |
| shutdown_nice_t | niceness, | ||
| int | restart | ||
| ) | [static] |
Called when exiting is certain.
Definition at line 1814 of file asterisk.c.
References _argv, ast_active_channels(), ast_config_AST_PID, ast_config_AST_SOCKET, ast_debug, ast_el_write_history(), ast_module_shutdown(), ast_opt_console, ast_opt_exec, ast_opt_remote, AST_PTHREADT_NULL, ast_run_atexits(), ast_strlen_zero(), ast_verb, clean_time_zones(), close_logger(), consolethread, el, el_hist, EVENT_FLAG_SYSTEM, lthread, manager_event, mon_sig_flags, restartnow, SHUTDOWN_NICE, sig_alert_pipe, and term_quit().
Referenced by quit_handler().
{
int active_channels;
int run_cleanups = niceness >= SHUTDOWN_NICE;
if (run_cleanups) {
ast_module_shutdown();
}
if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
char filename[80] = "";
if (getenv("HOME")) {
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
}
if (!ast_strlen_zero(filename)) {
ast_el_write_history(filename);
}
if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
/* Only end if we are the consolethread, otherwise there's a race with that thread. */
if (el != NULL) {
el_end(el);
}
if (el_hist != NULL) {
history_end(el_hist);
}
} else if (mon_sig_flags == pthread_self()) {
if (consolethread != AST_PTHREADT_NULL) {
pthread_kill(consolethread, SIGURG);
}
}
}
active_channels = ast_active_channels();
/* The manager event for shutdown must happen prior to ast_run_atexits, as
* the manager interface will dispose of its sessions as part of its
* shutdown.
*/
/*** DOCUMENTATION
<managerEventInstance>
<synopsis>Raised when Asterisk is shutdown or restarted.</synopsis>
<syntax>
<parameter name="Shutdown">
<enumlist>
<enum name="Uncleanly"/>
<enum name="Cleanly"/>
</enumlist>
</parameter>
<parameter name="Restart">
<enumlist>
<enum name="True"/>
<enum name="False"/>
</enumlist>
</parameter>
</syntax>
</managerEventInstance>
***/
manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\n"
"Restart: %s\r\n",
active_channels ? "Uncleanly" : "Cleanly",
restart ? "True" : "False");
ast_verb(0, "Asterisk %s ending (%d).\n",
active_channels ? "uncleanly" : "cleanly", num);
ast_verb(0, "Executing last minute cleanups\n");
ast_run_atexits(run_cleanups);
ast_debug(1, "Asterisk ending (%d).\n", num);
if (ast_socket > -1) {
pthread_cancel(lthread);
close(ast_socket);
ast_socket = -1;
unlink(ast_config_AST_SOCKET);
pthread_kill(lthread, SIGURG);
pthread_join(lthread, NULL);
}
if (ast_consock > -1)
close(ast_consock);
if (!ast_opt_remote)
unlink(ast_config_AST_PID);
if (sig_alert_pipe[0])
close(sig_alert_pipe[0]);
if (sig_alert_pipe[1])
close(sig_alert_pipe[1]);
printf("%s", term_quit());
if (restart) {
int i;
ast_verb(0, "Preparing for Asterisk restart...\n");
/* Mark all FD's for closing on exec */
for (i = 3; i < 32768; i++) {
fcntl(i, F_SETFD, FD_CLOEXEC);
}
ast_verb(0, "Asterisk is now restarting...\n");
restartnow = 1;
/* close logger */
close_logger();
clean_time_zones();
/* If there is a consolethread running send it a SIGHUP
so it can execvp, otherwise we can do it ourselves */
if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
pthread_kill(consolethread, SIGHUP);
/* Give the signal handler some time to complete */
sleep(2);
} else
execvp(_argv[0], _argv);
} else {
/* close logger */
close_logger();
clean_time_zones();
}
exit(0);
}
| static int register_atexit | ( | void(*)(void) | func, |
| int | is_cleanup | ||
| ) | [static] |
Definition at line 1002 of file asterisk.c.
References __ast_unregister_atexit(), ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_atexit::func, ast_atexit::is_cleanup, and ast_atexit::list.
Referenced by ast_register_atexit(), and ast_register_cleanup().
{
struct ast_atexit *ae;
ae = ast_calloc(1, sizeof(*ae));
if (!ae) {
return -1;
}
ae->func = func;
ae->is_cleanup = is_cleanup;
AST_LIST_LOCK(&atexits);
__ast_unregister_atexit(func);
AST_LIST_INSERT_HEAD(&atexits, ae, list);
AST_LIST_UNLOCK(&atexits);
return 0;
}
| static int remoteconsolehandler | ( | char * | s | ) | [static] |
Definition at line 2098 of file asterisk.c.
References ast_all_zeros(), ast_el_add_history(), ast_safe_system(), ast_verb_console_get(), ast_verb_console_set(), quit_handler(), and SHUTDOWN_FAST.
Referenced by ast_remotecontrol().
{
int ret = 0;
/* Called when readline data is available */
if (!ast_all_zeros(s))
ast_el_add_history(s);
while (isspace(*s)) {
s++;
}
/* The real handler for bang */
if (s[0] == '!') {
if (s[1])
ast_safe_system(s+1);
else
ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
ret = 1;
} else if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
(s[4] == '\0' || isspace(s[4]))) {
quit_handler(0, SHUTDOWN_FAST, 0);
ret = 1;
} else if (s[0]) {
char *shrunk = ast_strdupa(s);
char *cur;
char *prev;
/*
* Remove duplicate spaces from shrunk for matching purposes.
*
* shrunk has at least one character in it to start with or we
* couldn't get here.
*/
for (prev = shrunk, cur = shrunk + 1; *cur; ++cur) {
if (*prev == ' ' && *cur == ' ') {
/* Skip repeated space delimiter. */
continue;
}
*++prev = *cur;
}
*++prev = '\0';
if (strncasecmp(shrunk, "core set verbose ", 17) == 0) {
/*
* We need to still set the rasterisk option_verbose in case we are
* talking to an earlier version which doesn't prefilter verbose
* levels. This is really a compromise as we should always take
* whatever the server sends.
*/
if (!strncasecmp(shrunk + 17, "off", 3)) {
ast_verb_console_set(0);
} else {
int verbose_new;
int atleast;
atleast = 8;
if (strncasecmp(shrunk + 17, "atleast ", atleast)) {
atleast = 0;
}
if (sscanf(shrunk + 17 + atleast, "%30d", &verbose_new) == 1) {
if (!atleast || ast_verb_console_get() < verbose_new) {
ast_verb_console_set(verbose_new);
}
}
}
}
}
return ret;
}
| static void run_startup_commands | ( | void | ) | [static] |
Definition at line 3583 of file asterisk.c.
References ast_config_destroy(), ast_config_load2(), ast_true(), ast_variable_browse(), CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by main().
{
int fd;
struct ast_config *cfg;
struct ast_flags cfg_flags = { 0 };
struct ast_variable *v;
if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags)))
return;
if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
return;
}
fd = open("/dev/null", O_RDWR);
if (fd < 0) {
ast_config_destroy(cfg);
return;
}
for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) {
if (ast_true(v->value))
ast_cli_command(fd, v->name);
}
close(fd);
ast_config_destroy(cfg);
}
| static void send_rasterisk_connect_commands | ( | void | ) | [static] |
Definition at line 2488 of file asterisk.c.
References ast_opt_mute, and fdsend().
Referenced by ast_el_read_char(), and ast_remotecontrol().
{
char buf[80];
/*
* Tell the server asterisk instance about the verbose level
* initially desired.
*/
if (option_verbose) {
snprintf(buf, sizeof(buf), "core set verbose atleast %d silent", option_verbose);
fdsend(ast_consock, buf);
}
if (option_debug) {
snprintf(buf, sizeof(buf), "core set debug atleast %d", option_debug);
fdsend(ast_consock, buf);
}
if (!ast_opt_mute) {
fdsend(ast_consock, "logger mute silent");
} else {
printf("log and verbose output currently muted ('logger mute' to unmute)\n");
}
}
| static void set_icon | ( | char * | text | ) | [static] |
Definition at line 1691 of file asterisk.c.
Referenced by main().
{
if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
fprintf(stdout, "\033]1;%s\007", text);
}
| static void set_title | ( | char * | text | ) | [static] |
Set an X-term or screen title.
Definition at line 1685 of file asterisk.c.
Referenced by main().
{
if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
fprintf(stdout, "\033]2;%s\007", text);
}
| static void set_ulimit | ( | int | value | ) | [static] |
Set maximum open files.
Definition at line 1662 of file asterisk.c.
References ast_log(), errno, LOG_NOTICE, LOG_WARNING, and value.
Referenced by ast_readconfig().
{
struct rlimit l = {0, 0};
if (value <= 0) {
ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
return;
}
l.rlim_cur = value;
l.rlim_max = value;
if (setrlimit(RLIMIT_NOFILE, &l)) {
ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
return;
}
ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
return;
}
| static int show_cli_help | ( | void | ) | [static] |
Definition at line 3213 of file asterisk.c.
References ast_get_version().
Referenced by main().
{
printf("Asterisk %s, Copyright (C) 1999 - 2013, Digium, Inc. and others.\n", ast_get_version());
printf("Usage: asterisk [OPTIONS]\n");
printf("Valid Options:\n");
printf(" -V Display version number and exit\n");
printf(" -C <configfile> Use an alternate configuration file\n");
printf(" -G <group> Run as a group other than the caller\n");
printf(" -U <user> Run as a user other than the caller\n");
printf(" -c Provide console CLI\n");
printf(" -d Enable extra debugging\n");
#if HAVE_WORKING_FORK
printf(" -f Do not fork\n");
printf(" -F Always fork\n");
#endif
printf(" -g Dump core in case of a crash\n");
printf(" -h This help screen\n");
printf(" -i Initialize crypto keys at startup\n");
printf(" -I Enable internal timing if DAHDI timer is available\n");
printf(" -L <load> Limit the maximum load average before rejecting new calls\n");
printf(" -M <value> Limit the maximum number of calls to the specified value\n");
printf(" -m Mute debugging and console output on the console\n");
printf(" -n Disable console colorization\n");
printf(" -p Run as pseudo-realtime thread\n");
printf(" -q Quiet mode (suppress output)\n");
printf(" -r Connect to Asterisk on this machine\n");
printf(" -R Same as -r, except attempt to reconnect if disconnected\n");
printf(" -s <socket> Connect to Asterisk via socket <socket> (only valid with -r)\n");
printf(" -t Record soundfiles in /var/tmp and move them where they\n");
printf(" belong after they are done\n");
printf(" -T Display the time in [Mmm dd hh:mm:ss] format for each line\n");
printf(" of output to the CLI\n");
printf(" -v Increase verbosity (multiple v's = more verbose)\n");
printf(" -x <cmd> Execute command <cmd> (implies -r)\n");
printf(" -X Execute includes by default (allows #exec in asterisk.conf)\n");
printf(" -W Adjust terminal colors to compensate for a light background\n");
printf("\n");
return 0;
}
| static char* show_license | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2431 of file asterisk.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "core show license";
e->usage =
"Usage: core show license\n"
" Shows the license(s) for this copy of Asterisk.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_cli(a->fd, "%s", license_lines);
return CLI_SUCCESS;
}
| static int show_version | ( | void | ) | [static] |
Definition at line 3207 of file asterisk.c.
References ast_get_version().
Referenced by main().
{
printf("Asterisk %s\n", ast_get_version());
return 0;
}
| static char* show_warranty | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 2394 of file asterisk.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "core show warranty";
e->usage =
"Usage: core show warranty\n"
" Shows the warranty (if any) for this copy of Asterisk.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_cli(a->fd, "%s", warranty_lines);
return CLI_SUCCESS;
}
char* _argv[256] [static] |
Definition at line 303 of file asterisk.c.
Referenced by _hup_handler(), main(), and really_quit().
| const char* ast_config_AST_AGI_DIR = cfg_paths.agi_dir |
Definition at line 284 of file asterisk.c.
Referenced by ast_str_retrieve_variable(), handle_show_settings(), and launch_script().
| const char* ast_config_AST_CONFIG_DIR = cfg_paths.config_dir |
Definition at line 276 of file asterisk.c.
Referenced by action_createconfig(), ast_module_reload(), ast_str_retrieve_variable(), compile_script(), config_text_file_load(), handle_cli_dialplan_save(), handle_show_settings(), ices_exec(), launch_script(), lua_read_extensions_file(), message_template_parse_filebody(), pbx_load_module(), and set_fn().
| const char* ast_config_AST_CONFIG_FILE = cfg_paths.config_file |
Definition at line 277 of file asterisk.c.
Referenced by ast_readconfig(), handle_show_settings(), and launch_script().
char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl" [static] |
Definition at line 299 of file asterisk.c.
Referenced by ast_readconfig().
char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0" [static] |
Definition at line 298 of file asterisk.c.
Referenced by ast_makesocket(), and ast_readconfig().
char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0" [static] |
Definition at line 297 of file asterisk.c.
Referenced by ast_makesocket(), and ast_readconfig().
char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] [static] |
Definition at line 296 of file asterisk.c.
Referenced by ast_makesocket(), and ast_readconfig().
| const char* ast_config_AST_DATA_DIR = cfg_paths.data_dir |
Definition at line 282 of file asterisk.c.
Referenced by ast_linear_stream(), ast_str_retrieve_variable(), ast_xmldoc_load_documentation(), build_filename(), handle_show_settings(), launch_script(), make_filename(), moh_scan_files(), phoneprov_callback(), pp_each_extension_helper(), reload_firmware(), setup_privacy_args(), and static_callback().
| const char* ast_config_AST_DB = cfg_paths.db_path |
Definition at line 289 of file asterisk.c.
Referenced by ast_str_retrieve_variable(), convert_bdb_to_sqlite3(), db_open(), and handle_show_settings().
| const char* ast_config_AST_KEY_DIR = cfg_paths.key_dir |
Definition at line 285 of file asterisk.c.
Referenced by ast_str_retrieve_variable(), crypto_load(), handle_cli_keys_init(), handle_show_settings(), launch_script(), and osp_create_provider().
| const char* ast_config_AST_LOG_DIR = cfg_paths.log_dir |
Definition at line 283 of file asterisk.c.
Referenced by apply_general_options(), ast_str_retrieve_variable(), csv_log(), dahdi_r2_set_context(), handle_show_settings(), init_logger(), launch_script(), load_config(), load_module(), logger_queue_init(), logger_queue_restart(), make_logchannel(), open_history(), reload_logger(), testclient_exec(), testserver_exec(), write_history(), and writefile().
| const char* ast_config_AST_MODULE_DIR = cfg_paths.module_dir |
Definition at line 278 of file asterisk.c.
Referenced by ast_str_retrieve_variable(), complete_fn(), handle_show_settings(), launch_script(), and load_modules().
| const char* ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir |
Definition at line 280 of file asterisk.c.
Referenced by ast_monitor_change_fname(), ast_monitor_start(), chanspy_exec(), extenspy_exec(), filename_parse(), and launch_script().
| const char* ast_config_AST_PID = cfg_paths.pid_path |
Definition at line 290 of file asterisk.c.
Referenced by handle_show_settings(), main(), and really_quit().
| const char* ast_config_AST_RUN_DIR = cfg_paths.run_dir |
Definition at line 286 of file asterisk.c.
Referenced by ast_str_retrieve_variable(), handle_show_settings(), launch_script(), and main().
| const char* ast_config_AST_RUN_GROUP = cfg_paths.run_group |
Definition at line 293 of file asterisk.c.
Referenced by action_coresettings(), handle_show_settings(), and main().
| const char* ast_config_AST_RUN_USER = cfg_paths.run_user |
Definition at line 292 of file asterisk.c.
Referenced by action_coresettings(), handle_show_settings(), and main().
| const char* ast_config_AST_SBIN_DIR = cfg_paths.sbin_dir |
Definition at line 287 of file asterisk.c.
Referenced by convert_bdb_to_sqlite3(), and main().
| const char* ast_config_AST_SOCKET = cfg_paths.socket_path |
Definition at line 291 of file asterisk.c.
Referenced by ast_makesocket(), ast_tryconnect(), ast_var_Config(), main(), and really_quit().
| const char* ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir |
Definition at line 279 of file asterisk.c.
Referenced by app_exec(), ast_str_retrieve_variable(), conf_rec_name(), conf_run(), dictate_exec(), filename_parse(), handle_show_settings(), launch_script(), load_module(), play_message_callerid(), sms_nextoutgoing(), and sms_writefile().
| const char* ast_config_AST_SYSTEM_NAME = cfg_paths.system_name |
Definition at line 294 of file asterisk.c.
Referenced by __ast_channel_alloc_ap(), action_coresettings(), ast_readconfig(), ast_str_retrieve_variable(), cli_prompt(), env_init(), handle_show_settings(), manager_set_defaults(), named_acl_find_realtime(), realtime_update_peer(), and reload_config().
| const char* ast_config_AST_VAR_DIR = cfg_paths.var_dir |
Definition at line 281 of file asterisk.c.
Referenced by ael2_semantic_check(), ast_str_retrieve_variable(), handle_show_settings(), launch_script(), and ustmtext().
int ast_consock = -1 [static] |
UNIX Socket for controlling another asterisk
Definition at line 215 of file asterisk.c.
Referenced by ast_el_read_char(), and ast_remotecontrol().
Definition at line 246 of file asterisk.c.
Referenced by __ast_channel_alloc_ap(), acf_vm_info(), ast_readconfig(), and handle_show_settings().
| struct ast_eid ast_eid_default |
Global EID.
This is set in asterisk.conf, or determined automatically by taking the mac address of an Ethernet interface on the system.
Definition at line 209 of file asterisk.c.
Referenced by aji_devstate_cb(), aji_handle_pubsub_event(), aji_mwi_cb(), aji_publish_device_state(), aji_publish_mwi(), ast_event_append_eid(), ast_event_cb(), ast_readconfig(), ast_str_retrieve_variable(), cpg_confchg_cb(), cpg_deliver_cb(), handle_show_settings(), set_config(), xmpp_pubsub_devstate_cb(), xmpp_pubsub_handle_event(), xmpp_pubsub_mwi_cb(), xmpp_pubsub_publish_device_state(), and xmpp_pubsub_publish_mwi().
| unsigned int ast_FD_SETSIZE |
| struct timeval ast_lastreloadtime |
Definition at line 238 of file asterisk.c.
Referenced by action_corestatus(), ast_module_reload(), ast_var_Config(), handle_show_settings(), handle_showuptime(), and main().
| pid_t ast_mainpid |
Definition at line 216 of file asterisk.c.
Referenced by safe_append(), and scan_service().
int ast_socket = -1 [static] |
UNIX Socket for allowing remote control
Definition at line 214 of file asterisk.c.
Referenced by listener().
| struct timeval ast_startuptime |
Definition at line 237 of file asterisk.c.
Referenced by action_corestatus(), ast_var_Config(), handle_show_settings(), handle_showcalls(), handle_showuptime(), and main().
char canary_filename[128] [static] |
Definition at line 318 of file asterisk.c.
Referenced by canary_thread(), and main().
int canary_pid = 0 [static] |
Definition at line 317 of file asterisk.c.
Referenced by canary_exit(), and main().
struct _cfg_paths cfg_paths [static] |
Definition at line 274 of file asterisk.c.
Referenced by ast_readconfig(), and main().
struct sigaction child_handler [static] |
{
.sa_handler = _child_handler,
.sa_flags = SA_RESTART,
}
Definition at line 1656 of file asterisk.c.
struct ast_cli_entry cli_asterisk[] [static] |
Definition at line 2470 of file asterisk.c.
struct ast_cli_entry cli_asterisk_shutdown[] [static] |
Shutdown Asterisk CLI commands.
Definition at line 2461 of file asterisk.c.
struct ast_threadstorage console_state = { .once = PTHREAD_ONCE_INIT , .key_init = __init_console_state , .custom_init = console_state_init , } [static] |
Definition at line 1983 of file asterisk.c.
Referenced by console_print().
| struct console consoles[AST_MAX_CONNECTS] |
Definition at line 244 of file asterisk.c.
Referenced by ast_console_toggle_loglevel(), ast_console_toggle_mute(), ast_makesocket(), ast_network_puts(), ast_network_puts_mutable(), listener(), and network_verboser().
pthread_t consolethread = AST_PTHREADT_NULL [static] |
Definition at line 315 of file asterisk.c.
Referenced by console_verboser(), main(), monitor_sig_flags(), and really_quit().
EditLine* el [static] |
Definition at line 241 of file asterisk.c.
Referenced by __ast_internal_context_destroy(), ast_add_extension2_lockopt(), ast_el_add_history(), ast_el_initialize(), ast_el_read_history(), ast_el_write_history(), ast_remotecontrol(), handle_cli_dialplan_save(), main(), really_quit(), and show_dialplan_helper().
History* el_hist [static] |
Definition at line 240 of file asterisk.c.
Referenced by ast_el_add_history(), ast_el_initialize(), ast_el_read_history(), ast_el_write_history(), ast_remotecontrol(), main(), and really_quit().
struct file_versions file_versions [static] |
struct sigaction hup_handler [static] |
{
.sa_handler = _hup_handler,
.sa_flags = SA_RESTART,
}
Definition at line 1636 of file asterisk.c.
struct sigaction ignore_sig_handler [static] |
{
.sa_handler = SIG_IGN,
}
Definition at line 1060 of file asterisk.c.
Referenced by main().
const char license_lines[] [static] |
Definition at line 2412 of file asterisk.c.
pthread_t lthread [static] |
Definition at line 1280 of file asterisk.c.
Referenced by ast_makesocket(), and really_quit().
pthread_t mon_sig_flags [static] |
Definition at line 316 of file asterisk.c.
Referenced by main(), and really_quit().
int multi_thread_safe [static] |
Definition at line 319 of file asterisk.c.
Referenced by ast_register_thread(), and main().
| unsigned int need_quit |
Definition at line 326 of file asterisk.c.
| unsigned int need_quit_handler |
Definition at line 327 of file asterisk.c.
| unsigned int need_reload |
Definition at line 325 of file asterisk.c.
struct sigaction null_sig_handler [static] |
{
.sa_handler = _null_sig_handler,
.sa_flags = SA_RESTART,
}
Definition at line 1055 of file asterisk.c.
Referenced by ast_replace_sigchld().
struct profile_data* prof_data [static] |
Definition at line 728 of file asterisk.c.
Referenced by ast_add_profile(), ast_mark(), ast_profile(), handle_clear_profile(), and handle_show_profile().
Definition at line 2601 of file asterisk.c.
Referenced by auth_exec(), handle_speechrecognize(), load_module(), minivm_accmess_exec(), play_files_helper(), and pw_cb().
char randompool[256] [static] |
Definition at line 321 of file asterisk.c.
Referenced by main().
| char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR |
Definition at line 212 of file asterisk.c.
Referenced by ast_writefile().
char* remotehostname [static] |
Definition at line 242 of file asterisk.c.
Referenced by ast_remotecontrol(), and cli_prompt().
int restartnow [static] |
Definition at line 314 of file asterisk.c.
Referenced by _hup_handler(), and really_quit().
unsigned int safe_system_level = 0 [static] |
Keep track of how many threads are currently trying to wait*() on a child process.
Definition at line 1067 of file asterisk.c.
Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().
ast_mutex_t safe_system_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 1064 of file asterisk.c.
Referenced by ast_replace_sigchld(), ast_unreplace_sigchld(), can_safely_quit(), and handle_abort_shutdown().
struct sigaction safe_system_prev_handler [static] |
Definition at line 1068 of file asterisk.c.
Referenced by ast_replace_sigchld(), and ast_unreplace_sigchld().
shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN [static] |
Definition at line 313 of file asterisk.c.
Referenced by can_safely_quit(), and handle_abort_shutdown().
int sig_alert_pipe[2] = { -1, -1 } [static] |
Definition at line 323 of file asterisk.c.
Referenced by __quit_handler(), _hup_handler(), main(), monitor_sig_flags(), and really_quit().
struct { ... } sig_flags [static] |
Referenced by __quit_handler(), __remote_quit_handler(), _hup_handler(), ast_el_read_char(), ast_remotecontrol(), main(), and monitor_sig_flags().
struct thread_list thread_list [static] |
struct sigaction urg_handler [static] |
{
.sa_handler = _urg_handler,
.sa_flags = SA_RESTART,
}
Definition at line 1616 of file asterisk.c.
const char warranty_lines[] [static] |
Definition at line 2369 of file asterisk.c.