#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 "asterisk/paths.h"
#include "asterisk/network.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/features.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/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/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 | 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 | 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 | __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) |
support for event profiling | |
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 console, and all attached console clients | |
void | ast_console_toggle_loglevel (int fd, int level, int state) |
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) | |
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 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. | |
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 (void) |
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 void | console_verboser (const char *s) |
static void | consolehandler (char *s) |
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 *cmp) |
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 * | monitor_sig_flags (void *unused) |
static void * | netconsole (void *vconsole) |
static void | network_verboser (const char *s) |
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 | remoteconsolehandler (char *s) |
static void | run_startup_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] |
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_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 |
ast_eid | ast_eid_default |
Global EID. | |
unsigned int | ast_FD_SETSIZE |
timeval | ast_lastreloadtime |
pid_t | ast_mainpid |
ast_flags | ast_options = { AST_DEFAULT_OPTIONS } |
static int | ast_socket = -1 |
timeval | ast_startuptime |
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 [] |
console | consoles [AST_MAX_CONNECTS] |
static pthread_t | consolethread = AST_PTHREADT_NULL |
char | defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE |
static EditLine * | el |
static History * | el_hist |
static struct sigaction | hup_handler |
static struct sigaction | ignore_sig_handler |
static const char | license_lines [] |
static pthread_t | lthread |
static pthread_t | mon_sig_flags |
static struct sigaction | null_sig_handler |
int | option_debug |
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 sigaction | urg_handler |
static const char | warranty_lines [] |
Definition in file asterisk.c.
#define AF_LOCAL AF_UNIX |
Definition at line 150 of file asterisk.c.
#define AST_MAX_CONNECTS 128 |
Definition at line 154 of file asterisk.c.
Referenced by ast_console_toggle_loglevel(), ast_console_toggle_mute(), ast_makesocket(), ast_network_puts(), ast_network_puts_mutable(), and listener().
#define ASTERISK_PROMPT "*CLI> " |
#define ASTERISK_PROMPT2 "%s*CLI> " |
#define DEFINE_PROFILE_MIN_MAX_VALUES |
Definition at line 781 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 2674 of file asterisk.c.
Referenced by ast_el_add_history(), and ast_el_read_history().
#define NUM_MSGS 64 |
Definition at line 155 of file asterisk.c.
#define PF_LOCAL PF_UNIX |
#define WELCOME_MESSAGE |
Welcome message when starting a CLI interface.
Definition at line 158 of file asterisk.c.
Referenced by ast_el_read_char(), and main().
enum shutdown_nice_t |
NOT_SHUTTING_DOWN | |
SHUTTING_DOWN | |
SHUTDOWN_FAST | |
SHUTDOWN_NORMAL | |
SHUTDOWN_NICE | |
SHUTDOWN_REALLY_NICE |
Definition at line 278 of file asterisk.c.
00278 { 00279 NOT_SHUTTING_DOWN = -2, 00280 SHUTTING_DOWN = -1, 00281 /* Valid values for quit_handler niceness below: */ 00282 SHUTDOWN_FAST, 00283 SHUTDOWN_NORMAL, 00284 SHUTDOWN_NICE, 00285 SHUTDOWN_REALLY_NICE 00286 } shutdown_nice_t;
static void __quit_handler | ( | int | num | ) | [static] |
Definition at line 1776 of file asterisk.c.
References errno, sig_alert_pipe, and sig_flags.
Referenced by main().
01777 { 01778 int a = 0; 01779 sig_flags.need_quit = 1; 01780 if (sig_alert_pipe[1] != -1) { 01781 if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) { 01782 fprintf(stderr, "quit_handler: write() failed: %s\n", strerror(errno)); 01783 } 01784 } 01785 /* There is no need to restore the signal handler here, since the app 01786 * is going to exit */ 01787 }
static void __remote_quit_handler | ( | int | num | ) | [static] |
Definition at line 1789 of file asterisk.c.
References sig_flags.
Referenced by ast_remotecontrol().
01790 { 01791 sig_flags.need_quit = 1; 01792 }
static void _child_handler | ( | int | sig | ) | [static] |
Definition at line 1516 of file asterisk.c.
01517 { 01518 /* Must not ever ast_log or ast_verbose within signal handler */ 01519 int n, status, save_errno = errno; 01520 01521 /* 01522 * Reap all dead children -- not just one 01523 */ 01524 for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++) 01525 ; 01526 if (n == 0 && option_debug) 01527 printf("Huh? Child handler, but nobody there?\n"); 01528 errno = save_errno; 01529 }
static void _hup_handler | ( | int | num | ) | [static] |
Definition at line 1495 of file asterisk.c.
References _argv, errno, restartnow, sig_alert_pipe, and sig_flags.
01496 { 01497 int a = 0, save_errno = errno; 01498 if (option_verbose > 1) 01499 printf("Received HUP signal -- Reloading configs\n"); 01500 if (restartnow) 01501 execvp(_argv[0], _argv); 01502 sig_flags.need_reload = 1; 01503 if (sig_alert_pipe[1] != -1) { 01504 if (write(sig_alert_pipe[1], &a, sizeof(a)) < 0) { 01505 fprintf(stderr, "hup_handler: write() failed: %s\n", strerror(errno)); 01506 } 01507 } 01508 errno = save_errno; 01509 }
static void _null_sig_handler | ( | int | sig | ) | [static] |
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 1485 of file asterisk.c.
int ast_add_profile | ( | const char * | name, | |
uint64_t | scale | |||
) |
support for event profiling
Definition at line 700 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().
00701 { 00702 int l = sizeof(struct profile_data); 00703 int n = 10; /* default entries */ 00704 00705 if (prof_data == NULL) { 00706 prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry)); 00707 if (prof_data == NULL) 00708 return -1; 00709 prof_data->entries = 0; 00710 prof_data->max_size = n; 00711 } 00712 if (prof_data->entries >= prof_data->max_size) { 00713 void *p; 00714 n = prof_data->max_size + 20; 00715 p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry)); 00716 if (p == NULL) 00717 return -1; 00718 prof_data = p; 00719 prof_data->max_size = n; 00720 } 00721 n = prof_data->entries++; 00722 prof_data->e[n].name = ast_strdup(name); 00723 prof_data->e[n].value = 0; 00724 prof_data->e[n].events = 0; 00725 prof_data->e[n].mark = 0; 00726 prof_data->e[n].scale = scale; 00727 return n; 00728 }
static int ast_all_zeros | ( | char * | s | ) | [static] |
Definition at line 1836 of file asterisk.c.
Referenced by ast_el_read_history(), consolehandler(), and remoteconsolehandler().
01837 { 01838 while (*s) { 01839 if (*s > 32) 01840 return 0; 01841 s++; 01842 } 01843 return 1; 01844 }
static int ast_cli_display_match_list | ( | char ** | matches, | |
int | len, | |||
int | max | |||
) | [static] |
Definition at line 2473 of file asterisk.c.
References ast_el_sort_compare(), ast_free, and ast_get_termcols().
Referenced by cli_complete().
02474 { 02475 int i, idx, limit, count; 02476 int screenwidth = 0; 02477 int numoutput = 0, numoutputline = 0; 02478 02479 screenwidth = ast_get_termcols(STDOUT_FILENO); 02480 02481 /* find out how many entries can be put on one line, with two spaces between strings */ 02482 limit = screenwidth / (max + 2); 02483 if (limit == 0) 02484 limit = 1; 02485 02486 /* how many lines of output */ 02487 count = len / limit; 02488 if (count * limit < len) 02489 count++; 02490 02491 idx = 1; 02492 02493 qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare); 02494 02495 for (; count > 0; count--) { 02496 numoutputline = 0; 02497 for (i = 0; i < limit && matches[idx]; i++, idx++) { 02498 02499 /* Don't print dupes */ 02500 if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) { 02501 i--; 02502 ast_free(matches[idx]); 02503 matches[idx] = NULL; 02504 continue; 02505 } 02506 02507 numoutput++; 02508 numoutputline++; 02509 fprintf(stdout, "%-*s ", max, matches[idx]); 02510 ast_free(matches[idx]); 02511 matches[idx] = NULL; 02512 } 02513 if (numoutputline > 0) 02514 fprintf(stdout, "\n"); 02515 } 02516 02517 return numoutput; 02518 }
char* ast_complete_source_filename | ( | const char * | partial, | |
int | n | |||
) |
Definition at line 351 of file asterisk.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, file_version::file, len(), and ast_atexit::list.
Referenced by handle_verbose().
00352 { 00353 struct file_version *find; 00354 size_t len = strlen(partial); 00355 int count = 0; 00356 char *res = NULL; 00357 00358 AST_RWLIST_RDLOCK(&file_versions); 00359 AST_RWLIST_TRAVERSE(&file_versions, find, list) { 00360 if (!strncasecmp(find->file, partial, len) && ++count > n) { 00361 res = ast_strdup(find->file); 00362 break; 00363 } 00364 } 00365 AST_RWLIST_UNLOCK(&file_versions); 00366 return res; 00367 }
void ast_console_puts | ( | const char * | string | ) |
write the string to the console, and all attached console clients
Definition at line 1178 of file asterisk.c.
References ast_network_puts().
Referenced by chan_misdn_log().
01179 { 01180 fputs(string, stdout); 01181 fflush(stdout); 01182 ast_network_puts(string); 01183 }
void ast_console_puts_mutable | ( | const char * | string, | |
int | level | |||
) |
log the string to the console, and all attached console clients
Definition at line 1155 of file asterisk.c.
References ast_network_puts_mutable().
Referenced by init_logger_chain(), logger_print_normal(), and make_logchannel().
01156 { 01157 fputs(string, stdout); 01158 fflush(stdout); 01159 ast_network_puts_mutable(string, level); 01160 }
void ast_console_toggle_loglevel | ( | int | fd, | |
int | level, | |||
int | state | |||
) |
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 1097 of file asterisk.c.
References AST_MAX_CONNECTS, consoles, and levels.
Referenced by handle_logger_set_level().
01098 { 01099 int x; 01100 for (x = 0;x < AST_MAX_CONNECTS; x++) { 01101 if (fd == consoles[x].fd) { 01102 /* 01103 * Since the logging occurs when levels are false, set to 01104 * flipped iinput because this function accepts 0 as off and 1 as on 01105 */ 01106 consoles[x].levels[level] = state ? 0 : 1; 01107 return; 01108 } 01109 } 01110 }
void ast_console_toggle_mute | ( | int | fd, | |
int | silent | |||
) |
mute or unmute a console from logging
Definition at line 1115 of file asterisk.c.
References ast_cli(), AST_MAX_CONNECTS, consoles, console::mute, and mute.
Referenced by handle_logger_mute().
01116 { 01117 int x; 01118 for (x = 0;x < AST_MAX_CONNECTS; x++) { 01119 if (fd == consoles[x].fd) { 01120 if (consoles[x].mute) { 01121 consoles[x].mute = 0; 01122 if (!silent) 01123 ast_cli(fd, "Console is not muted anymore.\n"); 01124 } else { 01125 consoles[x].mute = 1; 01126 if (!silent) 01127 ast_cli(fd, "Console is muted.\n"); 01128 } 01129 return; 01130 } 01131 } 01132 ast_cli(fd, "Couldn't find remote console.\n"); 01133 }
static int ast_el_add_history | ( | char * | ) | [static] |
Definition at line 2676 of file asterisk.c.
References ast_el_initialize(), ast_strdupa, ast_strip(), el, el_hist, and MAX_HISTORY_COMMAND_LENGTH.
Referenced by ast_el_read_history(), consolehandler(), and remoteconsolehandler().
02677 { 02678 HistEvent ev; 02679 02680 if (el_hist == NULL || el == NULL) 02681 ast_el_initialize(); 02682 if (strlen(buf) > (MAX_HISTORY_COMMAND_LENGTH - 1)) 02683 return 0; 02684 return (history(el_hist, &ev, H_ENTER, ast_strip(ast_strdupa(buf)))); 02685 }
static int ast_el_initialize | ( | void | ) | [static] |
Definition at line 2639 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().
02640 { 02641 HistEvent ev; 02642 char *editor = getenv("AST_EDITOR"); 02643 02644 if (el != NULL) 02645 el_end(el); 02646 if (el_hist != NULL) 02647 history_end(el_hist); 02648 02649 el = el_init("asterisk", stdin, stdout, stderr); 02650 el_set(el, EL_PROMPT, cli_prompt); 02651 02652 el_set(el, EL_EDITMODE, 1); 02653 el_set(el, EL_EDITOR, editor ? editor : "emacs"); 02654 el_hist = history_init(); 02655 if (!el || !el_hist) 02656 return -1; 02657 02658 /* setup history with 100 entries */ 02659 history(el_hist, &ev, H_SETSIZE, 100); 02660 02661 el_set(el, EL_HIST, history, el_hist); 02662 02663 el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete); 02664 /* Bind <tab> to command completion */ 02665 el_set(el, EL_BIND, "^I", "ed-complete", NULL); 02666 /* Bind ? to command completion */ 02667 el_set(el, EL_BIND, "?", "ed-complete", NULL); 02668 /* Bind ^D to redisplay */ 02669 el_set(el, EL_BIND, "^D", "ed-redisplay", NULL); 02670 02671 return 0; 02672 }
static int ast_el_read_char | ( | EditLine * | editline, | |
char * | cp | |||
) | [static] |
Definition at line 2193 of file asterisk.c.
References ast_log(), ast_opt_exec, ast_opt_mute, ast_opt_reconnect, ast_poll, ast_tryconnect(), EL_BUF_SIZE, errno, fdsend(), LOG_ERROR, quit_handler(), SHUTDOWN_FAST, sig_flags, term_quit(), and WELCOME_MESSAGE.
Referenced by ast_remotecontrol(), and main().
02194 { 02195 int num_read = 0; 02196 int lastpos = 0; 02197 struct pollfd fds[2]; 02198 int res; 02199 int max; 02200 #define EL_BUF_SIZE 512 02201 char buf[EL_BUF_SIZE]; 02202 02203 for (;;) { 02204 max = 1; 02205 fds[0].fd = ast_consock; 02206 fds[0].events = POLLIN; 02207 if (!ast_opt_exec) { 02208 fds[1].fd = STDIN_FILENO; 02209 fds[1].events = POLLIN; 02210 max++; 02211 } 02212 res = ast_poll(fds, max, -1); 02213 if (res < 0) { 02214 if (sig_flags.need_quit || sig_flags.need_quit_handler) 02215 break; 02216 if (errno == EINTR) 02217 continue; 02218 ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno)); 02219 break; 02220 } 02221 02222 if (!ast_opt_exec && fds[1].revents) { 02223 num_read = read(STDIN_FILENO, cp, 1); 02224 if (num_read < 1) { 02225 break; 02226 } else 02227 return (num_read); 02228 } 02229 if (fds[0].revents) { 02230 char *tmp; 02231 res = read(ast_consock, buf, sizeof(buf) - 1); 02232 /* if the remote side disappears exit */ 02233 if (res < 1) { 02234 fprintf(stderr, "\nDisconnected from Asterisk server\n"); 02235 if (!ast_opt_reconnect) { 02236 quit_handler(0, SHUTDOWN_FAST, 0); 02237 } else { 02238 int tries; 02239 int reconnects_per_second = 20; 02240 fprintf(stderr, "Attempting to reconnect for 30 seconds\n"); 02241 for (tries = 0; tries < 30 * reconnects_per_second; tries++) { 02242 if (ast_tryconnect()) { 02243 fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries); 02244 printf("%s", term_quit()); 02245 WELCOME_MESSAGE; 02246 if (!ast_opt_mute) 02247 fdsend(ast_consock, "logger mute silent"); 02248 else 02249 printf("log and verbose output currently muted ('logger mute' to unmute)\n"); 02250 break; 02251 } else 02252 usleep(1000000 / reconnects_per_second); 02253 } 02254 if (tries >= 30 * reconnects_per_second) { 02255 fprintf(stderr, "Failed to reconnect for 30 seconds. Quitting.\n"); 02256 quit_handler(0, SHUTDOWN_FAST, 0); 02257 } 02258 } 02259 } 02260 02261 buf[res] = '\0'; 02262 02263 /* Strip preamble from asynchronous events, too */ 02264 for (tmp = buf; *tmp; tmp++) { 02265 if (*tmp == 127) { 02266 memmove(tmp, tmp + 1, strlen(tmp)); 02267 tmp--; 02268 res--; 02269 } 02270 } 02271 02272 /* Write over the CLI prompt */ 02273 if (!ast_opt_exec && !lastpos) { 02274 if (write(STDOUT_FILENO, "\r[0K", 5) < 0) { 02275 } 02276 } 02277 if (write(STDOUT_FILENO, buf, res) < 0) { 02278 } 02279 if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) { 02280 *cp = CC_REFRESH; 02281 return(1); 02282 } else 02283 lastpos = 1; 02284 } 02285 } 02286 02287 *cp = '\0'; 02288 return (0); 02289 }
static int ast_el_read_history | ( | char * | ) | [static] |
Definition at line 2697 of file asterisk.c.
References ast_all_zeros(), ast_el_add_history(), ast_el_initialize(), el, el_hist, f, and MAX_HISTORY_COMMAND_LENGTH.
Referenced by ast_remotecontrol(), and main().
02698 { 02699 char buf[MAX_HISTORY_COMMAND_LENGTH]; 02700 FILE *f; 02701 int ret = -1; 02702 02703 if (el_hist == NULL || el == NULL) 02704 ast_el_initialize(); 02705 02706 if ((f = fopen(filename, "r")) == NULL) 02707 return ret; 02708 02709 while (!feof(f)) { 02710 if (!fgets(buf, sizeof(buf), f)) 02711 break; 02712 if (!strcmp(buf, "_HiStOrY_V2_\n")) 02713 continue; 02714 if (ast_all_zeros(buf)) 02715 continue; 02716 if ((ret = ast_el_add_history(buf)) == -1) 02717 break; 02718 } 02719 fclose(f); 02720 02721 return ret; 02722 }
static int ast_el_sort_compare | ( | const void * | i1, | |
const void * | i2 | |||
) | [static] |
Definition at line 2463 of file asterisk.c.
Referenced by ast_cli_display_match_list().
02464 { 02465 char *s1, *s2; 02466 02467 s1 = ((char **)i1)[0]; 02468 s2 = ((char **)i2)[0]; 02469 02470 return strcasecmp(s1, s2); 02471 }
static char** ast_el_strtoarr | ( | char * | buf | ) | [static] |
Definition at line 2420 of file asterisk.c.
References AST_CLI_COMPLETE_EOF, ast_free, ast_realloc, ast_strdup, and strsep().
Referenced by cli_complete().
02421 { 02422 char **match_list = NULL, **match_list_tmp, *retstr; 02423 size_t match_list_len; 02424 int matches = 0; 02425 02426 match_list_len = 1; 02427 while ( (retstr = strsep(&buf, " ")) != NULL) { 02428 02429 if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) 02430 break; 02431 if (matches + 1 >= match_list_len) { 02432 match_list_len <<= 1; 02433 if ((match_list_tmp = ast_realloc(match_list, match_list_len * sizeof(char *)))) { 02434 match_list = match_list_tmp; 02435 } else { 02436 if (match_list) 02437 ast_free(match_list); 02438 return (char **) NULL; 02439 } 02440 } 02441 02442 match_list[matches++] = ast_strdup(retstr); 02443 } 02444 02445 if (!match_list) 02446 return (char **) NULL; 02447 02448 if (matches >= match_list_len) { 02449 if ((match_list_tmp = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) { 02450 match_list = match_list_tmp; 02451 } else { 02452 if (match_list) 02453 ast_free(match_list); 02454 return (char **) NULL; 02455 } 02456 } 02457 02458 match_list[matches] = (char *) NULL; 02459 02460 return match_list; 02461 }
static int ast_el_write_history | ( | char * | ) | [static] |
Definition at line 2687 of file asterisk.c.
References ast_el_initialize(), el, and el_hist.
Referenced by really_quit().
02688 { 02689 HistEvent ev; 02690 02691 if (el_hist == NULL || el == NULL) 02692 ast_el_initialize(); 02693 02694 return (history(el_hist, &ev, H_SAVE, filename)); 02695 }
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 370 of file asterisk.c.
References AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, file_version::file, ast_atexit::list, and file_version::version.
Referenced by manager_modulecheck().
00371 { 00372 struct file_version *iterator; 00373 00374 AST_RWLIST_WRLOCK(&file_versions); 00375 AST_RWLIST_TRAVERSE(&file_versions, iterator, list) { 00376 if (!strcasecmp(iterator->file, file)) 00377 break; 00378 } 00379 AST_RWLIST_UNLOCK(&file_versions); 00380 if (iterator) 00381 return iterator->version; 00382 return NULL; 00383 }
static int ast_makesocket | ( | void | ) | [static] |
Definition at line 1388 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().
01389 { 01390 struct sockaddr_un sunaddr; 01391 int res; 01392 int x; 01393 uid_t uid = -1; 01394 gid_t gid = -1; 01395 01396 for (x = 0; x < AST_MAX_CONNECTS; x++) 01397 consoles[x].fd = -1; 01398 unlink(ast_config_AST_SOCKET); 01399 ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0); 01400 if (ast_socket < 0) { 01401 ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno)); 01402 return -1; 01403 } 01404 memset(&sunaddr, 0, sizeof(sunaddr)); 01405 sunaddr.sun_family = AF_LOCAL; 01406 ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path)); 01407 res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr)); 01408 if (res) { 01409 ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01410 close(ast_socket); 01411 ast_socket = -1; 01412 return -1; 01413 } 01414 res = listen(ast_socket, 2); 01415 if (res < 0) { 01416 ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01417 close(ast_socket); 01418 ast_socket = -1; 01419 return -1; 01420 } 01421 if (ast_register_verbose(network_verboser)) { 01422 ast_log(LOG_WARNING, "Unable to register network verboser?\n"); 01423 } 01424 01425 ast_pthread_create_background(<hread, NULL, listener, NULL); 01426 01427 if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) { 01428 struct passwd *pw; 01429 if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL) 01430 ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER); 01431 else 01432 uid = pw->pw_uid; 01433 } 01434 01435 if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) { 01436 struct group *grp; 01437 if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL) 01438 ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP); 01439 else 01440 gid = grp->gr_gid; 01441 } 01442 01443 if (chown(ast_config_AST_SOCKET, uid, gid) < 0) 01444 ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01445 01446 if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) { 01447 int p1; 01448 mode_t p; 01449 sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1); 01450 p = p1; 01451 if ((chmod(ast_config_AST_SOCKET, p)) < 0) 01452 ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01453 } 01454 01455 return 0; 01456 }
int64_t ast_mark | ( | int | i, | |
int | startstop | |||
) |
Definition at line 765 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().
00766 { 00767 if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */ 00768 return 0; 00769 if (startstop == 1) 00770 prof_data->e[i].mark = rdtsc(); 00771 else { 00772 prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark); 00773 if (prof_data->e[i].scale > 1) 00774 prof_data->e[i].mark /= prof_data->e[i].scale; 00775 prof_data->e[i].value += prof_data->e[i].mark; 00776 prof_data->e[i].events++; 00777 } 00778 return prof_data->e[i].mark; 00779 }
static void ast_network_puts | ( | const char * | string | ) | [static] |
write the string to all attached console clients
Definition at line 1165 of file asterisk.c.
References AST_MAX_CONNECTS, consoles, and fdprint().
Referenced by ast_console_puts().
01166 { 01167 int x; 01168 for (x = 0; x < AST_MAX_CONNECTS; x++) { 01169 if (consoles[x].fd > -1) 01170 fdprint(consoles[x].p[1], string); 01171 } 01172 }
static void ast_network_puts_mutable | ( | const char * | string, | |
int | level | |||
) | [static] |
log the string to all attached console clients
Definition at line 1138 of file asterisk.c.
References AST_MAX_CONNECTS, consoles, fdprint(), levels, and mute.
Referenced by ast_console_puts_mutable(), and network_verboser().
01139 { 01140 int x; 01141 for (x = 0;x < AST_MAX_CONNECTS; x++) { 01142 if (consoles[x].mute) 01143 continue; 01144 if (consoles[x].fd > -1) { 01145 if (!consoles[x].levels[level]) 01146 fdprint(consoles[x].p[1], string); 01147 } 01148 } 01149 }
int64_t ast_profile | ( | int | i, | |
int64_t | delta | |||
) |
Definition at line 730 of file asterisk.c.
References profile_data::e, profile_data::entries, profile_entry::events, prof_data, profile_entry::scale, and profile_entry::value.
00731 { 00732 if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */ 00733 return 0; 00734 if (prof_data->e[i].scale > 1) 00735 delta /= prof_data->e[i].scale; 00736 prof_data->e[i].value += delta; 00737 prof_data->e[i].events++; 00738 return prof_data->e[i].value; 00739 }
static void ast_readconfig | ( | void | ) | [static] |
Definition at line 2915 of file asterisk.c.
References _cfg_paths::agi_dir, 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_load2(), ast_copy_string(), ast_eid_default, ast_log(), ast_opt_override_config, ast_set_default_eid(), ast_variable_browse(), cfg_paths, config, _cfg_paths::config_dir, CONFIG_FLAG_NOREALTIME, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, _cfg_paths::data_dir, _cfg_paths::db_path, DEFAULT_AGI_DIR, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILE, DEFAULT_DATA_DIR, DEFAULT_DB, DEFAULT_KEY_DIR, DEFAULT_LOG_DIR, DEFAULT_MODULE_DIR, DEFAULT_PID, DEFAULT_RUN_DIR, DEFAULT_SOCKET, DEFAULT_SPOOL_DIR, DEFAULT_VAR_DIR, hostname, _cfg_paths::key_dir, _cfg_paths::log_dir, LOG_WARNING, MAXHOSTNAMELEN, _cfg_paths::module_dir, _cfg_paths::monitor_dir, ast_variable::name, ast_variable::next, _cfg_paths::pid_path, _cfg_paths::run_dir, _cfg_paths::socket_path, _cfg_paths::spool_dir, ast_variable::value, and _cfg_paths::var_dir.
Referenced by main().
02916 { 02917 struct ast_config *cfg; 02918 struct ast_variable *v; 02919 char *config = DEFAULT_CONFIG_FILE; 02920 char hostname[MAXHOSTNAMELEN] = ""; 02921 struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME }; 02922 struct { 02923 unsigned int dbdir:1; 02924 unsigned int keydir:1; 02925 } found = { 0, 0 }; 02926 02927 if (ast_opt_override_config) { 02928 cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags); 02929 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) 02930 ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE); 02931 } else 02932 cfg = ast_config_load2(config, "" /* core, can't reload */, config_flags); 02933 02934 /* init with buildtime config */ 02935 ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir)); 02936 ast_copy_string(cfg_paths.spool_dir, DEFAULT_SPOOL_DIR, sizeof(cfg_paths.spool_dir)); 02937 ast_copy_string(cfg_paths.module_dir, DEFAULT_MODULE_DIR, sizeof(cfg_paths.module_dir)); 02938 snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", cfg_paths.spool_dir); 02939 ast_copy_string(cfg_paths.var_dir, DEFAULT_VAR_DIR, sizeof(cfg_paths.var_dir)); 02940 ast_copy_string(cfg_paths.data_dir, DEFAULT_DATA_DIR, sizeof(cfg_paths.data_dir)); 02941 ast_copy_string(cfg_paths.log_dir, DEFAULT_LOG_DIR, sizeof(cfg_paths.log_dir)); 02942 ast_copy_string(cfg_paths.agi_dir, DEFAULT_AGI_DIR, sizeof(cfg_paths.agi_dir)); 02943 ast_copy_string(cfg_paths.db_path, DEFAULT_DB, sizeof(cfg_paths.db_path)); 02944 ast_copy_string(cfg_paths.key_dir, DEFAULT_KEY_DIR, sizeof(cfg_paths.key_dir)); 02945 ast_copy_string(cfg_paths.pid_path, DEFAULT_PID, sizeof(cfg_paths.pid_path)); 02946 ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path)); 02947 ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir)); 02948 02949 ast_set_default_eid(&ast_eid_default); 02950 02951 /* no asterisk.conf? no problem, use buildtime config! */ 02952 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) { 02953 return; 02954 } 02955 02956 for (v = ast_variable_browse(cfg, "files"); v; v = v->next) { 02957 if (!strcasecmp(v->name, "astctlpermissions")) 02958 ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS)); 02959 else if (!strcasecmp(v->name, "astctlowner")) 02960 ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER)); 02961 else if (!strcasecmp(v->name, "astctlgroup")) 02962 ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP)); 02963 else if (!strcasecmp(v->name, "astctl")) 02964 ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL)); 02965 } 02966 02967 for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) { 02968 if (!strcasecmp(v->name, "astetcdir")) { 02969 ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir)); 02970 } else if (!strcasecmp(v->name, "astspooldir")) { 02971 ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir)); 02972 snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value); 02973 } else if (!strcasecmp(v->name, "astvarlibdir")) { 02974 ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir)); 02975 if (!found.dbdir) 02976 snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value); 02977 } else if (!strcasecmp(v->name, "astdbdir")) { 02978 snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value); 02979 found.dbdir = 1; 02980 } else if (!strcasecmp(v->name, "astdatadir")) { 02981 ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir)); 02982 if (!found.keydir) 02983 snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value); 02984 } else if (!strcasecmp(v->name, "astkeydir")) { 02985 snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value); 02986 found.keydir = 1; 02987 } else if (!strcasecmp(v->name, "astlogdir")) { 02988 ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir)); 02989 } else if (!strcasecmp(v->name, "astagidir")) { 02990 ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir)); 02991 } else if (!strcasecmp(v->name, "astrundir")) { 02992 snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid"); 02993 snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", v->value, ast_config_AST_CTL); 02994 ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir)); 02995 } else if (!strcasecmp(v->name, "astmoddir")) { 02996 ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir)); 02997 } 02998 } 02999 03000 for (v = ast_variable_browse(cfg, "options"); v; v = v->next) { 03001 /* verbose level (-v at startup) */ 03002 if (!strcasecmp(v->name, "verbose")) { 03003 option_verbose = atoi(v->value); 03004 /* whether or not to force timestamping in CLI verbose output. (-T at startup) */ 03005 } else if (!strcasecmp(v->name, "timestamp")) { 03006 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP); 03007 /* whether or not to support #exec in config files */ 03008 } else if (!strcasecmp(v->name, "execincludes")) { 03009 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES); 03010 /* debug level (-d at startup) */ 03011 } else if (!strcasecmp(v->name, "debug")) { 03012 option_debug = 0; 03013 if (sscanf(v->value, "%30d", &option_debug) != 1) { 03014 option_debug = ast_true(v->value); 03015 } 03016 #if HAVE_WORKING_FORK 03017 /* Disable forking (-f at startup) */ 03018 } else if (!strcasecmp(v->name, "nofork")) { 03019 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK); 03020 /* Always fork, even if verbose or debug are enabled (-F at startup) */ 03021 } else if (!strcasecmp(v->name, "alwaysfork")) { 03022 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK); 03023 #endif 03024 /* Run quietly (-q at startup ) */ 03025 } else if (!strcasecmp(v->name, "quiet")) { 03026 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET); 03027 /* Run as console (-c at startup, implies nofork) */ 03028 } else if (!strcasecmp(v->name, "console")) { 03029 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE); 03030 /* Run with high priority if the O/S permits (-p at startup) */ 03031 } else if (!strcasecmp(v->name, "highpriority")) { 03032 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY); 03033 /* Initialize RSA auth keys (IAX2) (-i at startup) */ 03034 } else if (!strcasecmp(v->name, "initcrypto")) { 03035 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS); 03036 /* Disable ANSI colors for console (-c at startup) */ 03037 } else if (!strcasecmp(v->name, "nocolor")) { 03038 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR); 03039 /* Disable some usage warnings for picky people :p */ 03040 } else if (!strcasecmp(v->name, "dontwarn")) { 03041 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN); 03042 /* Dump core in case of crash (-g) */ 03043 } else if (!strcasecmp(v->name, "dumpcore")) { 03044 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE); 03045 /* Cache recorded sound files to another directory during recording */ 03046 } else if (!strcasecmp(v->name, "cache_record_files")) { 03047 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES); 03048 /* Specify cache directory */ 03049 } else if (!strcasecmp(v->name, "record_cache_dir")) { 03050 ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN); 03051 /* Build transcode paths via SLINEAR, instead of directly */ 03052 } else if (!strcasecmp(v->name, "transcode_via_sln")) { 03053 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN); 03054 /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */ 03055 } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) { 03056 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE); 03057 /* Enable internal timing */ 03058 } else if (!strcasecmp(v->name, "internal_timing")) { 03059 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING); 03060 } else if (!strcasecmp(v->name, "maxcalls")) { 03061 if ((sscanf(v->value, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) { 03062 option_maxcalls = 0; 03063 } 03064 } else if (!strcasecmp(v->name, "maxload")) { 03065 double test[1]; 03066 03067 if (getloadavg(test, 1) == -1) { 03068 ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n"); 03069 option_maxload = 0.0; 03070 } else if ((sscanf(v->value, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) { 03071 option_maxload = 0.0; 03072 } 03073 /* Set the maximum amount of open files */ 03074 } else if (!strcasecmp(v->name, "maxfiles")) { 03075 option_maxfiles = atoi(v->value); 03076 set_ulimit(option_maxfiles); 03077 /* What user to run as */ 03078 } else if (!strcasecmp(v->name, "runuser")) { 03079 ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user)); 03080 /* What group to run as */ 03081 } else if (!strcasecmp(v->name, "rungroup")) { 03082 ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group)); 03083 } else if (!strcasecmp(v->name, "systemname")) { 03084 ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name)); 03085 } else if (!strcasecmp(v->name, "autosystemname")) { 03086 if (ast_true(v->value)) { 03087 if (!gethostname(hostname, sizeof(hostname) - 1)) 03088 ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name)); 03089 else { 03090 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){ 03091 ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name)); 03092 } 03093 ast_log(LOG_ERROR, "Cannot obtain hostname for this system. Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME); 03094 } 03095 } 03096 } else if (!strcasecmp(v->name, "languageprefix")) { 03097 ast_language_is_prefix = ast_true(v->value); 03098 } else if (!strcasecmp(v->name, "defaultlanguage")) { 03099 ast_copy_string(defaultlanguage, v->value, MAX_LANGUAGE); 03100 } else if (!strcasecmp(v->name, "lockmode")) { 03101 if (!strcasecmp(v->value, "lockfile")) { 03102 ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE); 03103 } else if (!strcasecmp(v->value, "flock")) { 03104 ast_set_lock_type(AST_LOCK_TYPE_FLOCK); 03105 } else { 03106 ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, " 03107 "defaulting to 'lockfile'\n", v->value); 03108 ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE); 03109 } 03110 #if defined(HAVE_SYSINFO) 03111 } else if (!strcasecmp(v->name, "minmemfree")) { 03112 /* specify the minimum amount of free memory to retain. Asterisk should stop accepting new calls 03113 * if the amount of free memory falls below this watermark */ 03114 if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) { 03115 option_minmemfree = 0; 03116 } 03117 #endif 03118 } else if (!strcasecmp(v->name, "entityid")) { 03119 struct ast_eid tmp_eid; 03120 if (!ast_str_to_eid(&tmp_eid, v->value)) { 03121 ast_verbose("Successfully set global EID to '%s'\n", v->value); 03122 ast_eid_default = tmp_eid; 03123 } else 03124 ast_verbose("Invalid Entity ID '%s' provided\n", v->value); 03125 } else if (!strcasecmp(v->name, "lightbackground")) { 03126 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND); 03127 } else if (!strcasecmp(v->name, "forceblackbackground")) { 03128 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND); 03129 } else if (!strcasecmp(v->name, "hideconnect")) { 03130 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT); 03131 } else if (!strcasecmp(v->name, "lockconfdir")) { 03132 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LOCK_CONFIG_DIR); 03133 } 03134 } 03135 for (v = ast_variable_browse(cfg, "compat"); v; v = v->next) { 03136 float version; 03137 if (sscanf(v->value, "%30f", &version) != 1) { 03138 ast_log(LOG_WARNING, "Compatibility version for option '%s' is not a number: '%s'\n", v->name, v->value); 03139 continue; 03140 } 03141 if (!strcasecmp(v->name, "app_set")) { 03142 ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_APP_SET); 03143 } else if (!strcasecmp(v->name, "res_agi")) { 03144 ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_RES_AGI); 03145 } else if (!strcasecmp(v->name, "pbx_realtime")) { 03146 ast_set2_flag(&ast_compat, version < 1.5 ? 1 : 0, AST_COMPAT_DELIM_PBX_REALTIME); 03147 } 03148 } 03149 ast_config_destroy(cfg); 03150 }
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 941 of file asterisk.c.
References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_unregister_atexit(), and ast_atexit::list.
Referenced by ast_cel_engine_init(), do_reload(), load_module(), and main().
00942 { 00943 struct ast_atexit *ae; 00944 00945 if (!(ae = ast_calloc(1, sizeof(*ae)))) 00946 return -1; 00947 00948 ae->func = func; 00949 00950 ast_unregister_atexit(func); 00951 00952 AST_RWLIST_WRLOCK(&atexits); 00953 AST_RWLIST_INSERT_HEAD(&atexits, ae, list); 00954 AST_RWLIST_UNLOCK(&atexits); 00955 00956 return 0; 00957 }
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) |
Definition at line 312 of file asterisk.c.
References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdupa, ast_strip(), ast_strip_quoted(), and ast_atexit::list.
00313 { 00314 struct file_version *new; 00315 char *work; 00316 size_t version_length; 00317 00318 work = ast_strdupa(version); 00319 work = ast_strip(ast_strip_quoted(work, "$", "$")); 00320 version_length = strlen(work) + 1; 00321 00322 if (!(new = ast_calloc(1, sizeof(*new) + version_length))) 00323 return; 00324 00325 new->file = file; 00326 new->version = (char *) new + sizeof(*new); 00327 memcpy(new->version, work, version_length); 00328 AST_RWLIST_WRLOCK(&file_versions); 00329 AST_RWLIST_INSERT_HEAD(&file_versions, new, list); 00330 AST_RWLIST_UNLOCK(&file_versions); 00331 }
void ast_register_thread | ( | char * | name | ) |
Definition at line 395 of file asterisk.c.
References ast_calloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_atexit::list.
Referenced by dummy_start().
00396 { 00397 struct thread_list_t *new = ast_calloc(1, sizeof(*new)); 00398 00399 if (!new) 00400 return; 00401 new->id = pthread_self(); 00402 new->name = name; /* steal the allocated memory for the thread name */ 00403 AST_RWLIST_WRLOCK(&thread_list); 00404 AST_RWLIST_INSERT_HEAD(&thread_list, new, list); 00405 AST_RWLIST_UNLOCK(&thread_list); 00406 }
static void ast_remotecontrol | ( | char * | data | ) | [static] |
Definition at line 2724 of file asterisk.c.
References __remote_quit_handler(), ast_el_initialize(), ast_el_read_char(), ast_el_read_history(), ast_log(), ast_opt_exec, ast_opt_mute, ast_poll, ast_strlen_zero(), ast_verbose, el, el_hist, errno, fdsend(), hostname, LOG_ERROR, LOG_WARNING, prefix, remoteconsolehandler(), remotehostname, sig_flags, strsep(), and version.
Referenced by main().
02725 { 02726 char buf[80]; 02727 int res; 02728 char filename[80] = ""; 02729 char *hostname; 02730 char *cpid; 02731 char *version; 02732 int pid; 02733 char *stringp = NULL; 02734 02735 char *ebuf; 02736 int num = 0; 02737 02738 memset(&sig_flags, 0, sizeof(sig_flags)); 02739 signal(SIGINT, __remote_quit_handler); 02740 signal(SIGTERM, __remote_quit_handler); 02741 signal(SIGHUP, __remote_quit_handler); 02742 02743 if (read(ast_consock, buf, sizeof(buf)) < 0) { 02744 ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno)); 02745 return; 02746 } 02747 if (data) { 02748 char prefix[] = "cli quit after "; 02749 char *tmp = alloca(strlen(data) + strlen(prefix) + 1); 02750 sprintf(tmp, "%s%s", prefix, data); 02751 if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) { 02752 ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno)); 02753 if (sig_flags.need_quit || sig_flags.need_quit_handler) { 02754 return; 02755 } 02756 } 02757 } 02758 stringp = buf; 02759 hostname = strsep(&stringp, "/"); 02760 cpid = strsep(&stringp, "/"); 02761 version = strsep(&stringp, "\n"); 02762 if (!version) 02763 version = "<Version Unknown>"; 02764 stringp = hostname; 02765 strsep(&stringp, "."); 02766 if (cpid) 02767 pid = atoi(cpid); 02768 else 02769 pid = -1; 02770 if (!data) { 02771 char tmp[80]; 02772 snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose); 02773 fdsend(ast_consock, tmp); 02774 snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug); 02775 fdsend(ast_consock, tmp); 02776 if (!ast_opt_mute) 02777 fdsend(ast_consock, "logger mute silent"); 02778 else 02779 printf("log and verbose output currently muted ('logger mute' to unmute)\n"); 02780 } 02781 02782 if (ast_opt_exec && data) { /* hack to print output then exit if asterisk -rx is used */ 02783 struct pollfd fds; 02784 fds.fd = ast_consock; 02785 fds.events = POLLIN; 02786 fds.revents = 0; 02787 while (ast_poll(&fds, 1, 60000) > 0) { 02788 char buffer[512] = "", *curline = buffer, *nextline; 02789 int not_written = 1; 02790 02791 if (sig_flags.need_quit || sig_flags.need_quit_handler) { 02792 break; 02793 } 02794 02795 if (read(ast_consock, buffer, sizeof(buffer) - 1) <= 0) { 02796 break; 02797 } 02798 02799 do { 02800 if ((nextline = strchr(curline, '\n'))) { 02801 nextline++; 02802 } else { 02803 nextline = strchr(curline, '\0'); 02804 } 02805 02806 /* Skip verbose lines */ 02807 if (*curline != 127) { 02808 not_written = 0; 02809 if (write(STDOUT_FILENO, curline, nextline - curline) < 0) { 02810 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 02811 } 02812 } 02813 curline = nextline; 02814 } while (!ast_strlen_zero(curline)); 02815 02816 /* No non-verbose output in 60 seconds. */ 02817 if (not_written) { 02818 break; 02819 } 02820 } 02821 return; 02822 } 02823 02824 ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid); 02825 remotehostname = hostname; 02826 if (getenv("HOME")) 02827 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); 02828 if (el_hist == NULL || el == NULL) 02829 ast_el_initialize(); 02830 02831 el_set(el, EL_GETCFN, ast_el_read_char); 02832 02833 if (!ast_strlen_zero(filename)) 02834 ast_el_read_history(filename); 02835 02836 for (;;) { 02837 ebuf = (char *)el_gets(el, &num); 02838 02839 if (sig_flags.need_quit || sig_flags.need_quit_handler) { 02840 break; 02841 } 02842 02843 if (!ebuf && write(1, "", 1) < 0) 02844 break; 02845 02846 if (!ast_strlen_zero(ebuf)) { 02847 if (ebuf[strlen(ebuf)-1] == '\n') 02848 ebuf[strlen(ebuf)-1] = '\0'; 02849 if (!remoteconsolehandler(ebuf)) { 02850 /* Strip preamble from output */ 02851 char *temp; 02852 for (temp = ebuf; *temp; temp++) { 02853 if (*temp == 127) { 02854 memmove(temp, temp + 1, strlen(temp)); 02855 temp--; 02856 } 02857 } 02858 res = write(ast_consock, ebuf, strlen(ebuf) + 1); 02859 if (res < 1) { 02860 ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno)); 02861 break; 02862 } 02863 } 02864 } 02865 } 02866 printf("\nDisconnected from Asterisk server\n"); 02867 }
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 1008 of file asterisk.c.
References ast_mutex_lock, ast_mutex_unlock, safe_system_level, and safe_system_lock.
Referenced by ast_safe_fork(), and ast_safe_system().
01009 { 01010 unsigned int level; 01011 01012 ast_mutex_lock(&safe_system_lock); 01013 level = safe_system_level++; 01014 01015 /* only replace the handler if it has not already been done */ 01016 if (level == 0) { 01017 sigaction(SIGCHLD, &null_sig_handler, &safe_system_prev_handler); 01018 } 01019 01020 ast_mutex_unlock(&safe_system_lock); 01021 }
static void ast_run_atexits | ( | void | ) | [static] |
Definition at line 1608 of file asterisk.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_atexit::func, and ast_atexit::list.
Referenced by really_quit().
01609 { 01610 struct ast_atexit *ae; 01611 AST_RWLIST_RDLOCK(&atexits); 01612 AST_RWLIST_TRAVERSE(&atexits, ae, list) { 01613 if (ae->func) 01614 ae->func(); 01615 } 01616 AST_RWLIST_UNLOCK(&atexits); 01617 }
int ast_safe_system | ( | const char * | s | ) |
Safely spawn an external program while closing file descriptors.
Definition at line 1038 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, status, WEXITSTATUS, and WIFEXITED.
Referenced by add_email_attachment(), alarmreceiver_exec(), ast_monitor_stop(), consolehandler(), mixmonitor_thread(), notify_message(), process_text_line(), remoteconsolehandler(), rotate_file(), run_externnotify(), sendmail(), sendpage(), system_exec_helper(), and vm_change_password_shell().
01039 { 01040 pid_t pid; 01041 int res; 01042 struct rusage rusage; 01043 int status; 01044 01045 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK) 01046 ast_replace_sigchld(); 01047 01048 #ifdef HAVE_WORKING_FORK 01049 pid = fork(); 01050 #else 01051 pid = vfork(); 01052 #endif 01053 01054 if (pid == 0) { 01055 #ifdef HAVE_CAP 01056 cap_t cap = cap_from_text("cap_net_admin-eip"); 01057 01058 if (cap_set_proc(cap)) { 01059 /* Careful with order! Logging cannot happen after we close FDs */ 01060 ast_log(LOG_WARNING, "Unable to remove capabilities.\n"); 01061 } 01062 cap_free(cap); 01063 #endif 01064 #ifdef HAVE_WORKING_FORK 01065 if (ast_opt_high_priority) 01066 ast_set_priority(0); 01067 /* Close file descriptors and launch system command */ 01068 ast_close_fds_above_n(STDERR_FILENO); 01069 #endif 01070 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL); 01071 _exit(1); 01072 } else if (pid > 0) { 01073 for (;;) { 01074 res = wait4(pid, &status, 0, &rusage); 01075 if (res > -1) { 01076 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1; 01077 break; 01078 } else if (errno != EINTR) 01079 break; 01080 } 01081 } else { 01082 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno)); 01083 res = -1; 01084 } 01085 01086 ast_unreplace_sigchld(); 01087 #else /* !defined(HAVE_WORKING_FORK) && !defined(HAVE_WORKING_VFORK) */ 01088 res = -1; 01089 #endif 01090 01091 return res; 01092 }
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 1574 of file asterisk.c.
References ast_log(), ast_verbose, LOG_WARNING, sched_setscheduler, and setpriority.
Referenced by ast_safe_system(), canary_thread(), icesencode(), launch_script(), main(), mp3play(), NBScatplay(), send_waveform_to_fd(), spawn_mp3(), and spawn_ras().
01575 { 01576 struct sched_param sched; 01577 memset(&sched, 0, sizeof(sched)); 01578 #ifdef __linux__ 01579 if (pri) { 01580 sched.sched_priority = 10; 01581 if (sched_setscheduler(0, SCHED_RR, &sched)) { 01582 ast_log(LOG_WARNING, "Unable to set high priority\n"); 01583 return -1; 01584 } else 01585 if (option_verbose) 01586 ast_verbose("Set to realtime thread\n"); 01587 } else { 01588 sched.sched_priority = 0; 01589 /* According to the manpage, these parameters can never fail. */ 01590 sched_setscheduler(0, SCHED_OTHER, &sched); 01591 } 01592 #else 01593 if (pri) { 01594 if (setpriority(PRIO_PROCESS, 0, -10) == -1) { 01595 ast_log(LOG_WARNING, "Unable to set high priority\n"); 01596 return -1; 01597 } else 01598 if (option_verbose) 01599 ast_verbose("Set to high priority\n"); 01600 } else { 01601 /* According to the manpage, these parameters can never fail. */ 01602 setpriority(PRIO_PROCESS, 0, 0); 01603 } 01604 #endif 01605 return 0; 01606 }
static int ast_tryconnect | ( | void | ) | [static] |
Definition at line 1458 of file asterisk.c.
References AF_LOCAL, ast_config_AST_SOCKET, ast_copy_string(), ast_log(), errno, LOG_WARNING, and PF_LOCAL.
Referenced by ast_el_read_char(), and main().
01459 { 01460 struct sockaddr_un sunaddr; 01461 int res; 01462 ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0); 01463 if (ast_consock < 0) { 01464 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 01465 return 0; 01466 } 01467 memset(&sunaddr, 0, sizeof(sunaddr)); 01468 sunaddr.sun_family = AF_LOCAL; 01469 ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path)); 01470 res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)); 01471 if (res) { 01472 close(ast_consock); 01473 ast_consock = -1; 01474 return 0; 01475 } else 01476 return 1; 01477 }
void ast_unregister_atexit | ( | void(*)(void) | func | ) |
Unregister a function registered with ast_register_atexit().
func | The callback function to unregister. |
Definition at line 959 of file asterisk.c.
References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free, ast_atexit::func, and ast_atexit::list.
Referenced by ast_register_atexit(), do_reload(), and unload_module().
00960 { 00961 struct ast_atexit *ae = NULL; 00962 00963 AST_RWLIST_WRLOCK(&atexits); 00964 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) { 00965 if (ae->func == func) { 00966 AST_RWLIST_REMOVE_CURRENT(list); 00967 break; 00968 } 00969 } 00970 AST_RWLIST_TRAVERSE_SAFE_END; 00971 AST_RWLIST_UNLOCK(&atexits); 00972 00973 free(ae); 00974 }
void ast_unregister_file_version | ( | const char * | file | ) |
Unregister a source code file from the core.
file | the source file name |
Definition at line 333 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, file_version::file, and ast_atexit::list.
00334 { 00335 struct file_version *find; 00336 00337 AST_RWLIST_WRLOCK(&file_versions); 00338 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) { 00339 if (!strcasecmp(find->file, file)) { 00340 AST_RWLIST_REMOVE_CURRENT(list); 00341 break; 00342 } 00343 } 00344 AST_RWLIST_TRAVERSE_SAFE_END; 00345 AST_RWLIST_UNLOCK(&file_versions); 00346 00347 if (find) 00348 ast_free(find); 00349 }
void ast_unregister_thread | ( | void * | id | ) |
Definition at line 408 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, thread_list_t::id, ast_atexit::list, and thread_list_t::name.
Referenced by dummy_start().
00409 { 00410 struct thread_list_t *x; 00411 00412 AST_RWLIST_WRLOCK(&thread_list); 00413 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) { 00414 if ((void *) x->id == id) { 00415 AST_RWLIST_REMOVE_CURRENT(list); 00416 break; 00417 } 00418 } 00419 AST_RWLIST_TRAVERSE_SAFE_END; 00420 AST_RWLIST_UNLOCK(&thread_list); 00421 if (x) { 00422 ast_free(x->name); 00423 ast_free(x); 00424 } 00425 }
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 1023 of file asterisk.c.
References ast_mutex_lock, ast_mutex_unlock, safe_system_level, and safe_system_lock.
Referenced by ast_safe_fork_cleanup(), and ast_safe_system().
01024 { 01025 unsigned int level; 01026 01027 ast_mutex_lock(&safe_system_lock); 01028 level = --safe_system_level; 01029 01030 /* only restore the handler if we are the last one */ 01031 if (level == 0) { 01032 sigaction(SIGCHLD, &safe_system_prev_handler, NULL); 01033 } 01034 01035 ast_mutex_unlock(&safe_system_lock); 01036 }
static int can_safely_quit | ( | shutdown_nice_t | niceness, | |
int | restart | |||
) | [static] |
Definition at line 1631 of file asterisk.c.
References ast_active_channels(), ast_begin_shutdown(), ast_cdr_engine_term(), ast_mutex_lock, ast_mutex_unlock, ast_opt_console, ast_verbose, NOT_SHUTTING_DOWN, safe_system_lock, SHUTDOWN_NICE, SHUTDOWN_NORMAL, SHUTDOWN_REALLY_NICE, SHUTTING_DOWN, and shuttingdown.
Referenced by quit_handler().
01632 { 01633 /* Check if someone else isn't already doing this. */ 01634 ast_mutex_lock(&safe_system_lock); 01635 if (shuttingdown != NOT_SHUTTING_DOWN && niceness >= shuttingdown) { 01636 /* Already in progress and other request was less nice. */ 01637 ast_mutex_unlock(&safe_system_lock); 01638 ast_verbose("Ignoring asterisk %s request, already in progress.\n", restart ? "restart" : "shutdown"); 01639 return 0; 01640 } 01641 shuttingdown = niceness; 01642 ast_mutex_unlock(&safe_system_lock); 01643 01644 /* Try to get as many CDRs as possible submitted to the backend engines 01645 * (if in batch mode). really_quit happens to call it again when running 01646 * the atexit handlers, otherwise this would be a bit early. */ 01647 ast_cdr_engine_term(); 01648 01649 if (niceness == SHUTDOWN_NORMAL) { 01650 time_t s, e; 01651 /* Begin shutdown routine, hanging up active channels */ 01652 ast_begin_shutdown(1); 01653 if (option_verbose && ast_opt_console) { 01654 ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown"); 01655 } 01656 time(&s); 01657 for (;;) { 01658 time(&e); 01659 /* Wait up to 15 seconds for all channels to go away */ 01660 if ((e - s) > 15 || !ast_active_channels() || shuttingdown != niceness) { 01661 break; 01662 } 01663 /* Sleep 1/10 of a second */ 01664 usleep(100000); 01665 } 01666 } else if (niceness >= SHUTDOWN_NICE) { 01667 if (niceness != SHUTDOWN_REALLY_NICE) { 01668 ast_begin_shutdown(0); 01669 } 01670 if (option_verbose && ast_opt_console) { 01671 ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt"); 01672 } 01673 for (;;) { 01674 if (!ast_active_channels() || shuttingdown != niceness) { 01675 break; 01676 } 01677 sleep(1); 01678 } 01679 } 01680 01681 /* Re-acquire lock and check if someone changed the niceness, in which 01682 * case someone else has taken over the shutdown. */ 01683 ast_mutex_lock(&safe_system_lock); 01684 if (shuttingdown != niceness) { 01685 if (shuttingdown == NOT_SHUTTING_DOWN && option_verbose && ast_opt_console) { 01686 ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown"); 01687 } 01688 ast_mutex_unlock(&safe_system_lock); 01689 return 0; 01690 } 01691 shuttingdown = SHUTTING_DOWN; 01692 ast_mutex_unlock(&safe_system_lock); 01693 01694 return 1; 01695 }
static void canary_exit | ( | void | ) | [static] |
Definition at line 3208 of file asterisk.c.
References canary_pid.
Referenced by main().
03209 { 03210 if (canary_pid > 0) 03211 kill(canary_pid, SIGKILL); 03212 }
static void* canary_thread | ( | void * | unused | ) | [static] |
Definition at line 3178 of file asterisk.c.
References ast_log(), ast_set_priority(), ast_tvnow(), canary_filename, and LOG_WARNING.
Referenced by main().
03179 { 03180 struct stat canary_stat; 03181 struct timeval now; 03182 03183 /* Give the canary time to sing */ 03184 sleep(120); 03185 03186 for (;;) { 03187 stat(canary_filename, &canary_stat); 03188 now = ast_tvnow(); 03189 if (now.tv_sec > canary_stat.st_mtime + 60) { 03190 ast_log(LOG_WARNING, 03191 "The canary is no more. He has ceased to be! " 03192 "He's expired and gone to meet his maker! " 03193 "He's a stiff! Bereft of life, he rests in peace. " 03194 "His metabolic processes are now history! He's off the twig! " 03195 "He's kicked the bucket. He's shuffled off his mortal coil, " 03196 "run down the curtain, and joined the bleeding choir invisible!! " 03197 "THIS is an EX-CANARY. (Reducing priority)\n"); 03198 ast_set_priority(0); 03199 pthread_exit(NULL); 03200 } 03201 03202 /* Check the canary once a minute */ 03203 sleep(60); 03204 } 03205 }
static char* cli_complete | ( | EditLine * | editline, | |
int | ch | |||
) | [static] |
Definition at line 2521 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().
02522 { 02523 int len = 0; 02524 char *ptr; 02525 int nummatches = 0; 02526 char **matches; 02527 int retval = CC_ERROR; 02528 char buf[2048], savechr; 02529 int res; 02530 02531 LineInfo *lf = (LineInfo *)el_line(editline); 02532 02533 savechr = *(char *)lf->cursor; 02534 *(char *)lf->cursor = '\0'; 02535 ptr = (char *)lf->cursor; 02536 if (ptr) { 02537 while (ptr > lf->buffer) { 02538 if (isspace(*ptr)) { 02539 ptr++; 02540 break; 02541 } 02542 ptr--; 02543 } 02544 } 02545 02546 len = lf->cursor - ptr; 02547 02548 if (ast_opt_remote) { 02549 snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 02550 fdsend(ast_consock, buf); 02551 res = read(ast_consock, buf, sizeof(buf) - 1); 02552 buf[res] = '\0'; 02553 nummatches = atoi(buf); 02554 02555 if (nummatches > 0) { 02556 char *mbuf; 02557 int mlen = 0, maxmbuf = 2048; 02558 /* Start with a 2048 byte buffer */ 02559 if (!(mbuf = ast_malloc(maxmbuf))) { 02560 lf->cursor[0] = savechr; 02561 return (char *)(CC_ERROR); 02562 } 02563 snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 02564 fdsend(ast_consock, buf); 02565 res = 0; 02566 mbuf[0] = '\0'; 02567 while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) { 02568 if (mlen + 1024 > maxmbuf) { 02569 /* Every step increment buffer 1024 bytes */ 02570 maxmbuf += 1024; 02571 if (!(mbuf = ast_realloc(mbuf, maxmbuf))) { 02572 lf->cursor[0] = savechr; 02573 return (char *)(CC_ERROR); 02574 } 02575 } 02576 /* Only read 1024 bytes at a time */ 02577 res = read(ast_consock, mbuf + mlen, 1024); 02578 if (res > 0) 02579 mlen += res; 02580 } 02581 mbuf[mlen] = '\0'; 02582 02583 matches = ast_el_strtoarr(mbuf); 02584 ast_free(mbuf); 02585 } else 02586 matches = (char **) NULL; 02587 } else { 02588 char **p, *oldbuf=NULL; 02589 nummatches = 0; 02590 matches = ast_cli_completion_matches((char *)lf->buffer,ptr); 02591 for (p = matches; p && *p; p++) { 02592 if (!oldbuf || strcmp(*p,oldbuf)) 02593 nummatches++; 02594 oldbuf = *p; 02595 } 02596 } 02597 02598 if (matches) { 02599 int i; 02600 int matches_num, maxlen, match_len; 02601 02602 if (matches[0][0] != '\0') { 02603 el_deletestr(editline, (int) len); 02604 el_insertstr(editline, matches[0]); 02605 retval = CC_REFRESH; 02606 } 02607 02608 if (nummatches == 1) { 02609 /* Found an exact match */ 02610 el_insertstr(editline, " "); 02611 retval = CC_REFRESH; 02612 } else { 02613 /* Must be more than one match */ 02614 for (i = 1, maxlen = 0; matches[i]; i++) { 02615 match_len = strlen(matches[i]); 02616 if (match_len > maxlen) 02617 maxlen = match_len; 02618 } 02619 matches_num = i - 1; 02620 if (matches_num >1) { 02621 fprintf(stdout, "\n"); 02622 ast_cli_display_match_list(matches, nummatches, maxlen); 02623 retval = CC_REDISPLAY; 02624 } else { 02625 el_insertstr(editline," "); 02626 retval = CC_REFRESH; 02627 } 02628 } 02629 for (i = 0; matches[i]; i++) 02630 ast_free(matches[i]); 02631 ast_free(matches); 02632 } 02633 02634 lf->cursor[0] = savechr; 02635 02636 return (char *)(long)retval; 02637 }
static char* cli_prompt | ( | EditLine * | editline | ) | [static] |
Definition at line 2293 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, getloadavg(), hostname, ast_atexit::list, MAXHOSTNAMELEN, prompt, remotehostname, and term_color_code().
Referenced by ast_el_initialize().
02294 { 02295 char tmp[100]; 02296 char *pfmt; 02297 int color_used = 0; 02298 static int cli_prompt_changes = 0; 02299 char term_code[20]; 02300 struct passwd *pw; 02301 struct group *gr; 02302 02303 if (prompt == NULL) { 02304 prompt = ast_str_create(100); 02305 } else if (!cli_prompt_changes) { 02306 return ast_str_buffer(prompt); 02307 } else { 02308 ast_str_reset(prompt); 02309 } 02310 02311 if ((pfmt = getenv("ASTERISK_PROMPT"))) { 02312 char *t = pfmt; 02313 struct timeval ts = ast_tvnow(); 02314 while (*t != '\0') { 02315 if (*t == '%') { 02316 char hostname[MAXHOSTNAMELEN] = ""; 02317 int i, which; 02318 struct ast_tm tm = { 0, }; 02319 int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK; 02320 02321 t++; 02322 switch (*t) { 02323 case 'C': /* color */ 02324 t++; 02325 if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) { 02326 ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code))); 02327 t += i - 1; 02328 } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) { 02329 ast_str_append(&prompt, 0, "%s", term_color_code(term_code, fgcolor, 0, sizeof(term_code))); 02330 t += i - 1; 02331 } 02332 02333 /* If the color has been reset correctly, then there's no need to reset it later */ 02334 color_used = ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) ? 0 : 1; 02335 break; 02336 case 'd': /* date */ 02337 if (ast_localtime(&ts, &tm, NULL)) { 02338 ast_strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm); 02339 ast_str_append(&prompt, 0, "%s", tmp); 02340 cli_prompt_changes++; 02341 } 02342 break; 02343 case 'g': /* group */ 02344 if ((gr = getgrgid(getgid()))) { 02345 ast_str_append(&prompt, 0, "%s", gr->gr_name); 02346 } 02347 break; 02348 case 'h': /* hostname */ 02349 if (!gethostname(hostname, sizeof(hostname) - 1)) { 02350 ast_str_append(&prompt, 0, "%s", hostname); 02351 } else { 02352 ast_str_append(&prompt, 0, "%s", "localhost"); 02353 } 02354 break; 02355 case 'H': /* short hostname */ 02356 if (!gethostname(hostname, sizeof(hostname) - 1)) { 02357 char *dotptr; 02358 if ((dotptr = strchr(hostname, '.'))) { 02359 *dotptr = '\0'; 02360 } 02361 ast_str_append(&prompt, 0, "%s", hostname); 02362 } else { 02363 ast_str_append(&prompt, 0, "%s", "localhost"); 02364 } 02365 break; 02366 #ifdef HAVE_GETLOADAVG 02367 case 'l': /* load avg */ 02368 t++; 02369 if (sscanf(t, "%30d", &which) == 1 && which > 0 && which <= 3) { 02370 double list[3]; 02371 getloadavg(list, 3); 02372 ast_str_append(&prompt, 0, "%.2f", list[which - 1]); 02373 cli_prompt_changes++; 02374 } 02375 break; 02376 #endif 02377 case 's': /* Asterisk system name (from asterisk.conf) */ 02378 ast_str_append(&prompt, 0, "%s", ast_config_AST_SYSTEM_NAME); 02379 break; 02380 case 't': /* time */ 02381 if (ast_localtime(&ts, &tm, NULL)) { 02382 ast_strftime(tmp, sizeof(tmp), "%H:%M:%S", &tm); 02383 ast_str_append(&prompt, 0, "%s", tmp); 02384 cli_prompt_changes++; 02385 } 02386 break; 02387 case 'u': /* username */ 02388 if ((pw = getpwuid(getuid()))) { 02389 ast_str_append(&prompt, 0, "%s", pw->pw_name); 02390 } 02391 break; 02392 case '#': /* process console or remote? */ 02393 ast_str_append(&prompt, 0, "%c", ast_opt_remote ? '>' : '#'); 02394 break; 02395 case '%': /* literal % */ 02396 ast_str_append(&prompt, 0, "%c", '%'); 02397 break; 02398 case '\0': /* % is last character - prevent bug */ 02399 t--; 02400 break; 02401 } 02402 } else { 02403 ast_str_append(&prompt, 0, "%c", *t); 02404 } 02405 t++; 02406 } 02407 if (color_used) { 02408 /* Force colors back to normal at end */ 02409 ast_str_append(&prompt, 0, "%s", term_color_code(term_code, 0, 0, sizeof(term_code))); 02410 } 02411 } else if (remotehostname) { 02412 ast_str_set(&prompt, 0, ASTERISK_PROMPT2, remotehostname); 02413 } else { 02414 ast_str_set(&prompt, 0, "%s", ASTERISK_PROMPT); 02415 } 02416 02417 return ast_str_buffer(prompt); 02418 }
static void console_verboser | ( | const char * | s | ) | [static] |
Definition at line 1811 of file asterisk.c.
References ast_opt_console, AST_PTHREADT_NULL, consolethread, fix_header(), VERBOSE_PREFIX_1, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.
Referenced by main().
01812 { 01813 char tmp[80]; 01814 const char *c = NULL; 01815 01816 if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) || 01817 (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) || 01818 (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) || 01819 (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) { 01820 fputs(tmp, stdout); 01821 fputs(c, stdout); 01822 } else { 01823 if (*s == 127) { 01824 s++; 01825 } 01826 fputs(s, stdout); 01827 } 01828 01829 fflush(stdout); 01830 01831 /* Wake up a poll()ing console */ 01832 if (ast_opt_console && consolethread != AST_PTHREADT_NULL) 01833 pthread_kill(consolethread, SIGURG); 01834 }
static void consolehandler | ( | char * | s | ) | [static] |
Definition at line 1846 of file asterisk.c.
References ast_all_zeros(), ast_cli_command, ast_el_add_history(), ast_safe_system(), and term_end().
Referenced by main().
01847 { 01848 printf("%s", term_end()); 01849 fflush(stdout); 01850 01851 /* Called when readline data is available */ 01852 if (!ast_all_zeros(s)) 01853 ast_el_add_history(s); 01854 /* The real handler for bang */ 01855 if (s[0] == '!') { 01856 if (s[1]) 01857 ast_safe_system(s+1); 01858 else 01859 ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); 01860 } else 01861 ast_cli_command(STDOUT_FILENO, s); 01862 }
static void env_init | ( | void | ) | [static] |
Definition at line 3242 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, ast_get_version(), and setenv().
Referenced by main().
03243 { 03244 setenv("AST_SYSTEMNAME", ast_config_AST_SYSTEM_NAME, 1); 03245 setenv("AST_BUILD_HOST", ast_build_hostname, 1); 03246 setenv("AST_BUILD_DATE", ast_build_date, 1); 03247 setenv("AST_BUILD_KERNEL", ast_build_kernel, 1); 03248 setenv("AST_BUILD_MACHINE", ast_build_machine, 1); 03249 setenv("AST_BUILD_OS", ast_build_os, 1); 03250 setenv("AST_BUILD_USER", ast_build_user, 1); 03251 setenv("AST_VERSION", ast_get_version(), 1); 03252 }
static int fdprint | ( | int | fd, | |
const char * | s | |||
) | [static] |
Definition at line 983 of file asterisk.c.
Referenced by ast_network_puts(), ast_network_puts_mutable(), listener(), and netconsole().
static int fdsend | ( | int | fd, | |
const char * | s | |||
) | [static] |
Definition at line 977 of file asterisk.c.
Referenced by ast_el_read_char(), ast_remotecontrol(), and cli_complete().
static const char* fix_header | ( | char * | outbuf, | |
int | maxout, | |||
const char * | s, | |||
char * | cmp | |||
) | [static] |
Definition at line 1794 of file asterisk.c.
References COLOR_GRAY, and term_color().
Referenced by console_verboser().
01795 { 01796 const char *c; 01797 01798 /* Check for verboser preamble */ 01799 if (*s == 127) { 01800 s++; 01801 } 01802 01803 if (!strncmp(s, cmp, strlen(cmp))) { 01804 c = s + strlen(cmp); 01805 term_color(outbuf, cmp, COLOR_GRAY, 0, maxout); 01806 return c; 01807 } 01808 return NULL; 01809 }
static char* handle_abort_shutdown | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2038 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.
02039 { 02040 int aborting_shutdown = 0; 02041 02042 switch (cmd) { 02043 case CLI_INIT: 02044 e->command = "core abort shutdown"; 02045 e->usage = 02046 "Usage: core abort shutdown\n" 02047 " Causes Asterisk to abort an executing shutdown or restart, and resume normal\n" 02048 " call operations.\n"; 02049 return NULL; 02050 case CLI_GENERATE: 02051 return NULL; 02052 } 02053 02054 if (a->argc != e->args) 02055 return CLI_SHOWUSAGE; 02056 02057 ast_mutex_lock(&safe_system_lock); 02058 if (shuttingdown >= SHUTDOWN_FAST) { 02059 aborting_shutdown = 1; 02060 shuttingdown = NOT_SHUTTING_DOWN; 02061 } 02062 ast_mutex_unlock(&safe_system_lock); 02063 02064 if (aborting_shutdown) { 02065 ast_cancel_shutdown(); 02066 } 02067 return CLI_SUCCESS; 02068 }
static char* handle_bang | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2070 of file asterisk.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
02071 { 02072 switch (cmd) { 02073 case CLI_INIT: 02074 e->command = "!"; 02075 e->usage = 02076 "Usage: !<command>\n" 02077 " Executes a given shell command\n"; 02078 return NULL; 02079 case CLI_GENERATE: 02080 return NULL; 02081 } 02082 02083 return CLI_SUCCESS; 02084 }
static char* handle_clear_profile | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 829 of file asterisk.c.
References CLI_GENERATE, CLI_INIT, DEFINE_PROFILE_MIN_MAX_VALUES, profile_data::e, profile_entry::events, profile_entry::name, prof_data, and profile_entry::value.
00830 { 00831 int i, min, max; 00832 const char *search = NULL; 00833 switch (cmd) { 00834 case CLI_INIT: 00835 e->command = "core clear profile"; 00836 e->usage = "Usage: core clear profile\n" 00837 " clear profile information"; 00838 return NULL; 00839 case CLI_GENERATE: 00840 return NULL; 00841 } 00842 00843 if (prof_data == NULL) 00844 return 0; 00845 00846 DEFINE_PROFILE_MIN_MAX_VALUES; 00847 for (i= min; i < max; i++) { 00848 if (!search || strstr(prof_data->e[i].name, search)) { 00849 prof_data->e[i].value = 0; 00850 prof_data->e[i].events = 0; 00851 } 00852 } 00853 return CLI_SUCCESS; 00854 }
static char* handle_restart_gracefully | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1998 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.
01999 { 02000 switch (cmd) { 02001 case CLI_INIT: 02002 e->command = "core restart gracefully"; 02003 e->usage = 02004 "Usage: core restart gracefully\n" 02005 " Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n" 02006 " restart when all active calls have ended.\n"; 02007 return NULL; 02008 case CLI_GENERATE: 02009 return NULL; 02010 } 02011 02012 if (a->argc != e->args) 02013 return CLI_SHOWUSAGE; 02014 quit_handler(0, SHUTDOWN_NICE, 1 /* restart */); 02015 return CLI_SUCCESS; 02016 }
static char* handle_restart_now | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1978 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.
01979 { 01980 switch (cmd) { 01981 case CLI_INIT: 01982 e->command = "core restart now"; 01983 e->usage = 01984 "Usage: core restart now\n" 01985 " Causes Asterisk to hangup all calls and exec() itself performing a cold\n" 01986 " restart.\n"; 01987 return NULL; 01988 case CLI_GENERATE: 01989 return NULL; 01990 } 01991 01992 if (a->argc != e->args) 01993 return CLI_SHOWUSAGE; 01994 quit_handler(0, SHUTDOWN_NORMAL, 1 /* restart */); 01995 return CLI_SUCCESS; 01996 }
static char* handle_restart_when_convenient | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2018 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.
02019 { 02020 switch (cmd) { 02021 case CLI_INIT: 02022 e->command = "core restart when convenient"; 02023 e->usage = 02024 "Usage: core restart when convenient\n" 02025 " Causes Asterisk to perform a cold restart when all active calls have ended.\n"; 02026 return NULL; 02027 case CLI_GENERATE: 02028 return NULL; 02029 } 02030 02031 if (a->argc != e->args) 02032 return CLI_SHOWUSAGE; 02033 ast_cli(a->fd, "Waiting for inactivity to perform restart\n"); 02034 quit_handler(0, SHUTDOWN_REALLY_NICE, 1 /* restart */); 02035 return CLI_SUCCESS; 02036 }
static char* handle_show_profile | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 794 of file asterisk.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, DEFINE_PROFILE_MIN_MAX_VALUES, profile_data::e, profile_data::entries, ast_cli_args::fd, profile_data::max_size, and prof_data.
00795 { 00796 int i, min, max; 00797 const char *search = NULL; 00798 switch (cmd) { 00799 case CLI_INIT: 00800 e->command = "core show profile"; 00801 e->usage = "Usage: core show profile\n" 00802 " show profile information"; 00803 return NULL; 00804 case CLI_GENERATE: 00805 return NULL; 00806 } 00807 00808 if (prof_data == NULL) 00809 return 0; 00810 00811 DEFINE_PROFILE_MIN_MAX_VALUES; 00812 ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n", 00813 prof_data->entries, prof_data->max_size); 00814 ast_cli(a->fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events", 00815 "Value", "Average", "Name"); 00816 for (i = min; i < max; i++) { 00817 struct profile_entry *entry = &prof_data->e[i]; 00818 if (!search || strstr(entry->name, search)) 00819 ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n", 00820 i, 00821 (long)entry->scale, 00822 (long)entry->events, (long long)entry->value, 00823 (long long)(entry->events ? entry->value / entry->events : entry->value), 00824 entry->name); 00825 } 00826 return CLI_SUCCESS; 00827 }
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 428 of file asterisk.c.
References ast_active_channels(), ast_build_date, ast_build_kernel, ast_build_machine, ast_build_os, ast_build_user, AST_BUILDOPTS, 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_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_options, ast_realtime_enabled(), ast_startuptime, ast_strftime(), ast_test_flag, check_cdr_enabled(), check_manager_enabled(), check_webmanager_enabled(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, defaultlanguage, ast_cli_args::fd, S_OR, and ast_cli_entry::usage.
00429 { 00430 char buf[BUFSIZ]; 00431 struct ast_tm tm; 00432 char eid_str[128]; 00433 00434 switch (cmd) { 00435 case CLI_INIT: 00436 e->command = "core show settings"; 00437 e->usage = "Usage: core show settings\n" 00438 " Show core misc settings"; 00439 return NULL; 00440 case CLI_GENERATE: 00441 return NULL; 00442 } 00443 00444 ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default); 00445 00446 ast_cli(a->fd, "\nPBX Core settings\n"); 00447 ast_cli(a->fd, "-----------------\n"); 00448 ast_cli(a->fd, " Version: %s\n", ast_get_version()); 00449 ast_cli(a->fd, " Build Options: %s\n", S_OR(AST_BUILDOPTS, "(none)")); 00450 if (option_maxcalls) 00451 ast_cli(a->fd, " Maximum calls: %d (Current %d)\n", option_maxcalls, ast_active_channels()); 00452 else 00453 ast_cli(a->fd, " Maximum calls: Not set\n"); 00454 if (option_maxfiles) 00455 ast_cli(a->fd, " Maximum open file handles: %d\n", option_maxfiles); 00456 else 00457 ast_cli(a->fd, " Maximum open file handles: Not set\n"); 00458 ast_cli(a->fd, " Verbosity: %d\n", option_verbose); 00459 ast_cli(a->fd, " Debug level: %d\n", option_debug); 00460 ast_cli(a->fd, " Maximum load average: %lf\n", option_maxload); 00461 #if defined(HAVE_SYSINFO) 00462 ast_cli(a->fd, " Minimum free memory: %ld MB\n", option_minmemfree); 00463 #endif 00464 if (ast_localtime(&ast_startuptime, &tm, NULL)) { 00465 ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm); 00466 ast_cli(a->fd, " Startup time: %s\n", buf); 00467 } 00468 if (ast_localtime(&ast_lastreloadtime, &tm, NULL)) { 00469 ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm); 00470 ast_cli(a->fd, " Last reload time: %s\n", buf); 00471 } 00472 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); 00473 ast_cli(a->fd, " System name: %s\n", ast_config_AST_SYSTEM_NAME); 00474 ast_cli(a->fd, " Entity ID: %s\n", eid_str); 00475 ast_cli(a->fd, " Default language: %s\n", defaultlanguage); 00476 ast_cli(a->fd, " Language prefix: %s\n", ast_language_is_prefix ? "Enabled" : "Disabled"); 00477 ast_cli(a->fd, " User name and group: %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP); 00478 ast_cli(a->fd, " Executable includes: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled"); 00479 ast_cli(a->fd, " Transcode via SLIN: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled"); 00480 ast_cli(a->fd, " Internal timing: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled"); 00481 ast_cli(a->fd, " Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled"); 00482 ast_cli(a->fd, " Generic PLC: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled"); 00483 00484 ast_cli(a->fd, "\n* Subsystems\n"); 00485 ast_cli(a->fd, " -------------\n"); 00486 ast_cli(a->fd, " Manager (AMI): %s\n", check_manager_enabled() ? "Enabled" : "Disabled"); 00487 ast_cli(a->fd, " Web Manager (AMI/HTTP): %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled"); 00488 ast_cli(a->fd, " Call data records: %s\n", check_cdr_enabled() ? "Enabled" : "Disabled"); 00489 ast_cli(a->fd, " Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled"); 00490 00491 /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues */ 00492 00493 ast_cli(a->fd, "\n* Directories\n"); 00494 ast_cli(a->fd, " -------------\n"); 00495 ast_cli(a->fd, " Configuration file: %s\n", ast_config_AST_CONFIG_FILE); 00496 ast_cli(a->fd, " Configuration directory: %s\n", ast_config_AST_CONFIG_DIR); 00497 ast_cli(a->fd, " Module directory: %s\n", ast_config_AST_MODULE_DIR); 00498 ast_cli(a->fd, " Spool directory: %s\n", ast_config_AST_SPOOL_DIR); 00499 ast_cli(a->fd, " Log directory: %s\n", ast_config_AST_LOG_DIR); 00500 ast_cli(a->fd, " Run/Sockets directory: %s\n", ast_config_AST_RUN_DIR); 00501 ast_cli(a->fd, " PID file: %s\n", ast_config_AST_PID); 00502 ast_cli(a->fd, " VarLib directory: %s\n", ast_config_AST_VAR_DIR); 00503 ast_cli(a->fd, " Data directory: %s\n", ast_config_AST_DATA_DIR); 00504 ast_cli(a->fd, " ASTDB: %s\n", ast_config_AST_DB); 00505 ast_cli(a->fd, " IAX2 Keys directory: %s\n", ast_config_AST_KEY_DIR); 00506 ast_cli(a->fd, " AGI Scripts directory: %s\n", ast_config_AST_AGI_DIR); 00507 ast_cli(a->fd, "\n\n"); 00508 return CLI_SUCCESS; 00509 }
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 583 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.
00584 { 00585 uint64_t physmem, freeram; 00586 uint64_t freeswap = 0; 00587 int nprocs = 0; 00588 long uptime = 0; 00589 int totalswap = 0; 00590 #if defined(HAVE_SYSINFO) 00591 struct sysinfo sys_info; 00592 sysinfo(&sys_info); 00593 uptime = sys_info.uptime / 3600; 00594 physmem = sys_info.totalram * sys_info.mem_unit; 00595 freeram = (sys_info.freeram * sys_info.mem_unit) / 1024; 00596 totalswap = (sys_info.totalswap * sys_info.mem_unit) / 1024; 00597 freeswap = (sys_info.freeswap * sys_info.mem_unit) / 1024; 00598 nprocs = sys_info.procs; 00599 #elif defined(HAVE_SYSCTL) 00600 static int pageshift; 00601 struct vmtotal vmtotal; 00602 struct timeval boottime; 00603 time_t now; 00604 int mib[2], pagesize, usedswap = 0; 00605 size_t len; 00606 /* calculate the uptime by looking at boottime */ 00607 time(&now); 00608 mib[0] = CTL_KERN; 00609 mib[1] = KERN_BOOTTIME; 00610 len = sizeof(boottime); 00611 if (sysctl(mib, 2, &boottime, &len, NULL, 0) != -1) { 00612 uptime = now - boottime.tv_sec; 00613 } 00614 uptime = uptime/3600; 00615 /* grab total physical memory */ 00616 mib[0] = CTL_HW; 00617 #if defined(HW_PHYSMEM64) 00618 mib[1] = HW_PHYSMEM64; 00619 #else 00620 mib[1] = HW_PHYSMEM; 00621 #endif 00622 len = sizeof(physmem); 00623 sysctl(mib, 2, &physmem, &len, NULL, 0); 00624 00625 pagesize = getpagesize(); 00626 pageshift = 0; 00627 while (pagesize > 1) { 00628 pageshift++; 00629 pagesize >>= 1; 00630 } 00631 00632 /* we only need the amount of log(2)1024 for our conversion */ 00633 pageshift -= 10; 00634 00635 /* grab vm totals */ 00636 mib[0] = CTL_VM; 00637 mib[1] = VM_METER; 00638 len = sizeof(vmtotal); 00639 sysctl(mib, 2, &vmtotal, &len, NULL, 0); 00640 freeram = (vmtotal.t_free << pageshift); 00641 /* generate swap usage and totals */ 00642 swapmode(&usedswap, &totalswap); 00643 freeswap = (totalswap - usedswap); 00644 /* grab number of processes */ 00645 #if defined(__OpenBSD__) 00646 mib[0] = CTL_KERN; 00647 mib[1] = KERN_NPROCS; 00648 len = sizeof(nprocs); 00649 sysctl(mib, 2, &nprocs, &len, NULL, 0); 00650 #endif 00651 #endif 00652 00653 switch (cmd) { 00654 case CLI_INIT: 00655 e->command = "core show sysinfo"; 00656 e->usage = 00657 "Usage: core show sysinfo\n" 00658 " List current system information.\n"; 00659 return NULL; 00660 case CLI_GENERATE: 00661 return NULL; 00662 } 00663 00664 ast_cli(a->fd, "\nSystem Statistics\n"); 00665 ast_cli(a->fd, "-----------------\n"); 00666 ast_cli(a->fd, " System Uptime: %lu hours\n", uptime); 00667 ast_cli(a->fd, " Total RAM: %" PRIu64 " KiB\n", physmem / 1024); 00668 ast_cli(a->fd, " Free RAM: %" PRIu64 " KiB\n", freeram); 00669 #if defined(HAVE_SYSINFO) 00670 ast_cli(a->fd, " Buffer RAM: %" PRIu64 " KiB\n", ((uint64_t) sys_info.bufferram * sys_info.mem_unit) / 1024); 00671 #endif 00672 #if defined (HAVE_SYSCTL) || defined(HAVE_SWAPCTL) 00673 ast_cli(a->fd, " Total Swap Space: %u KiB\n", totalswap); 00674 ast_cli(a->fd, " Free Swap Space: %" PRIu64 " KiB\n\n", freeswap); 00675 #endif 00676 ast_cli(a->fd, " Number of Processes: %d \n\n", nprocs); 00677 return CLI_SUCCESS; 00678 }
static char* handle_show_threads | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 511 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, thread_list_t::id, ast_atexit::list, thread_list_t::name, and ast_cli_entry::usage.
00512 { 00513 int count = 0; 00514 struct thread_list_t *cur; 00515 switch (cmd) { 00516 case CLI_INIT: 00517 e->command = "core show threads"; 00518 e->usage = 00519 "Usage: core show threads\n" 00520 " List threads currently active in the system.\n"; 00521 return NULL; 00522 case CLI_GENERATE: 00523 return NULL; 00524 } 00525 00526 AST_RWLIST_RDLOCK(&thread_list); 00527 AST_RWLIST_TRAVERSE(&thread_list, cur, list) { 00528 ast_cli(a->fd, "%p %s\n", (void *)cur->id, cur->name); 00529 count++; 00530 } 00531 AST_RWLIST_UNLOCK(&thread_list); 00532 ast_cli(a->fd, "%d threads listed.\n", count); 00533 return CLI_SUCCESS; 00534 }
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 858 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, file_version::file, FORMAT, ast_atexit::list, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, file_version::version, and ast_cli_args::word.
00859 { 00860 #define FORMAT "%-25.25s %-40.40s\n" 00861 struct file_version *iterator; 00862 regex_t regexbuf; 00863 int havepattern = 0; 00864 int havename = 0; 00865 int count_files = 0; 00866 char *ret = NULL; 00867 int matchlen, which = 0; 00868 struct file_version *find; 00869 00870 switch (cmd) { 00871 case CLI_INIT: 00872 e->command = "core show file version [like]"; 00873 e->usage = 00874 "Usage: core show file version [like <pattern>]\n" 00875 " Lists the revision numbers of the files used to build this copy of Asterisk.\n" 00876 " Optional regular expression pattern is used to filter the file list.\n"; 00877 return NULL; 00878 case CLI_GENERATE: 00879 matchlen = strlen(a->word); 00880 if (a->pos != 3) 00881 return NULL; 00882 AST_RWLIST_RDLOCK(&file_versions); 00883 AST_RWLIST_TRAVERSE(&file_versions, find, list) { 00884 if (!strncasecmp(a->word, find->file, matchlen) && ++which > a->n) { 00885 ret = ast_strdup(find->file); 00886 break; 00887 } 00888 } 00889 AST_RWLIST_UNLOCK(&file_versions); 00890 return ret; 00891 } 00892 00893 00894 switch (a->argc) { 00895 case 6: 00896 if (!strcasecmp(a->argv[4], "like")) { 00897 if (regcomp(®exbuf, a->argv[5], REG_EXTENDED | REG_NOSUB)) 00898 return CLI_SHOWUSAGE; 00899 havepattern = 1; 00900 } else 00901 return CLI_SHOWUSAGE; 00902 break; 00903 case 5: 00904 havename = 1; 00905 break; 00906 case 4: 00907 break; 00908 default: 00909 return CLI_SHOWUSAGE; 00910 } 00911 00912 ast_cli(a->fd, FORMAT, "File", "Revision"); 00913 ast_cli(a->fd, FORMAT, "----", "--------"); 00914 AST_RWLIST_RDLOCK(&file_versions); 00915 AST_RWLIST_TRAVERSE(&file_versions, iterator, list) { 00916 if (havename && strcasecmp(iterator->file, a->argv[4])) 00917 continue; 00918 00919 if (havepattern && regexec(®exbuf, iterator->file, 0, NULL, 0)) 00920 continue; 00921 00922 ast_cli(a->fd, FORMAT, iterator->file, iterator->version); 00923 count_files++; 00924 if (havename) 00925 break; 00926 } 00927 AST_RWLIST_UNLOCK(&file_versions); 00928 if (!havename) { 00929 ast_cli(a->fd, "%d files listed.\n", count_files); 00930 } 00931 00932 if (havepattern) 00933 regfree(®exbuf); 00934 00935 return CLI_SUCCESS; 00936 #undef FORMAT 00937 }
static char* handle_stop_gracefully | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1938 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.
01939 { 01940 switch (cmd) { 01941 case CLI_INIT: 01942 e->command = "core stop gracefully"; 01943 e->usage = 01944 "Usage: core stop gracefully\n" 01945 " Causes Asterisk to not accept new calls, and exit when all\n" 01946 " active calls have terminated normally.\n"; 01947 return NULL; 01948 case CLI_GENERATE: 01949 return NULL; 01950 } 01951 01952 if (a->argc != e->args) 01953 return CLI_SHOWUSAGE; 01954 quit_handler(0, SHUTDOWN_NICE, 0 /* no restart */); 01955 return CLI_SUCCESS; 01956 }
static char* handle_stop_now | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1919 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.
01920 { 01921 switch (cmd) { 01922 case CLI_INIT: 01923 e->command = "core stop now"; 01924 e->usage = 01925 "Usage: core stop now\n" 01926 " Shuts down a running Asterisk immediately, hanging up all active calls .\n"; 01927 return NULL; 01928 case CLI_GENERATE: 01929 return NULL; 01930 } 01931 01932 if (a->argc != e->args) 01933 return CLI_SHOWUSAGE; 01934 quit_handler(0, SHUTDOWN_NORMAL, 0 /* not restart */); 01935 return CLI_SUCCESS; 01936 }
static char* handle_stop_when_convenient | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1958 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.
01959 { 01960 switch (cmd) { 01961 case CLI_INIT: 01962 e->command = "core stop when convenient"; 01963 e->usage = 01964 "Usage: core stop when convenient\n" 01965 " Causes Asterisk to perform a shutdown when all active calls have ended.\n"; 01966 return NULL; 01967 case CLI_GENERATE: 01968 return NULL; 01969 } 01970 01971 if (a->argc != e->args) 01972 return CLI_SHOWUSAGE; 01973 ast_cli(a->fd, "Waiting for inactivity to perform halt\n"); 01974 quit_handler(0, SHUTDOWN_REALLY_NICE, 0 /* don't restart */); 01975 return CLI_SUCCESS; 01976 }
static char* handle_version | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1888 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.
01889 { 01890 switch (cmd) { 01891 case CLI_INIT: 01892 e->command = "core show version"; 01893 e->usage = 01894 "Usage: core show version\n" 01895 " Shows Asterisk version information.\n"; 01896 return NULL; 01897 case CLI_GENERATE: 01898 return NULL; 01899 } 01900 01901 if (a->argc != 3) 01902 return CLI_SHOWUSAGE; 01903 ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n", 01904 ast_get_version(), ast_build_user, ast_build_hostname, 01905 ast_build_machine, ast_build_os, ast_build_date); 01906 return CLI_SUCCESS; 01907 }
static void* listener | ( | void * | unused | ) | [static] |
Definition at line 1311 of file asterisk.c.
References AF_LOCAL, ast_log(), AST_MAX_CONNECTS, ast_opt_hide_connect, ast_poll, ast_pthread_create_detached_background, ast_verb, consoles, errno, console::fd, fdprint(), console::gid, len(), LOG_ERROR, LOG_WARNING, console::mute, netconsole(), and console::uid.
Referenced by ast_makesocket().
01312 { 01313 struct sockaddr_un sunaddr; 01314 int s; 01315 socklen_t len; 01316 int x; 01317 int flags; 01318 struct pollfd fds[1]; 01319 for (;;) { 01320 if (ast_socket < 0) 01321 return NULL; 01322 fds[0].fd = ast_socket; 01323 fds[0].events = POLLIN; 01324 s = ast_poll(fds, 1, -1); 01325 pthread_testcancel(); 01326 if (s < 0) { 01327 if (errno != EINTR) 01328 ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno)); 01329 continue; 01330 } 01331 len = sizeof(sunaddr); 01332 s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len); 01333 if (s < 0) { 01334 if (errno != EINTR) 01335 ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno)); 01336 } else { 01337 #if !defined(SO_PASSCRED) 01338 { 01339 #else 01340 int sckopt = 1; 01341 /* turn on socket credentials passing. */ 01342 if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) { 01343 ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n"); 01344 } else { 01345 #endif 01346 for (x = 0; x < AST_MAX_CONNECTS; x++) { 01347 if (consoles[x].fd >= 0) { 01348 continue; 01349 } 01350 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) { 01351 ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno)); 01352 consoles[x].fd = -1; 01353 fdprint(s, "Server failed to create pipe\n"); 01354 close(s); 01355 break; 01356 } 01357 flags = fcntl(consoles[x].p[1], F_GETFL); 01358 fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK); 01359 consoles[x].fd = s; 01360 consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */ 01361 /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able 01362 to know if the user didn't send the credentials. */ 01363 consoles[x].uid = -2; 01364 consoles[x].gid = -2; 01365 if (ast_pthread_create_detached_background(&consoles[x].t, NULL, netconsole, &consoles[x])) { 01366 ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno)); 01367 close(consoles[x].p[0]); 01368 close(consoles[x].p[1]); 01369 consoles[x].fd = -1; 01370 fdprint(s, "Server failed to spawn thread\n"); 01371 close(s); 01372 } 01373 break; 01374 } 01375 if (x >= AST_MAX_CONNECTS) { 01376 fdprint(s, "No more connections allowed\n"); 01377 ast_log(LOG_WARNING, "No more connections allowed\n"); 01378 close(s); 01379 } else if ((consoles[x].fd > -1) && (!ast_opt_hide_connect)) { 01380 ast_verb(3, "Remote UNIX connection\n"); 01381 } 01382 } 01383 } 01384 } 01385 return NULL; 01386 }
int main | ( | int | argc, | |
char * | argv[] | |||
) |
Definition at line 3254 of file asterisk.c.
References __ast_mm_init(), __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_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_http_init(), ast_image_init(), ast_indications_init(), ast_language_is_prefix, ast_lastreloadtime, ast_log(), ast_makesocket(), 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_options, ast_pbx_init(), ast_process_pending_reloads(), ast_pthread_create_detached, ast_readconfig(), ast_register_atexit(), ast_register_verbose(), ast_remotecontrol(), ast_select(), ast_set_flag, ast_set_priority(), ast_ssl_init(), ast_startuptime, ast_strdupa, ast_strlen_zero(), ast_stun_init(), ast_term_init(), ast_test_flag, ast_test_init(), ast_timing_init(), ast_tps_init(), ast_tryconnect(), ast_tvnow(), ast_udptl_init(), ast_ulaw_init(), ast_utils_init(), ast_verbose, ast_xmldoc_load_documentation(), astdb_init(), astobj2_init(), callerid_init(), canary_exit(), canary_filename, canary_pid, canary_thread(), cfg_paths, cli_asterisk, COLOR_BLACK, COLOR_BRWHITE, _cfg_paths::config_file, console_verboser(), consolehandler(), consolethread, dnsmgr_init(), dnsmgr_start_refresh(), el, el_hist, env_init(), errno, EVENT_FLAG_SYSTEM, f, FD_SET, FD_ZERO, init_framer(), init_logger(), init_manager(), load_modules(), load_pbx(), LOG_ERROR, LOG_WARNING, manager_event, MAXHOSTNAMELEN, mon_sig_flags, monitor_sig_flags(), 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(), threadstorage_init(), and WELCOME_MESSAGE.
03255 { 03256 int c; 03257 char filename[80] = ""; 03258 char hostname[MAXHOSTNAMELEN] = ""; 03259 char tmp[80]; 03260 char * xarg = NULL; 03261 int x; 03262 FILE *f; 03263 sigset_t sigs; 03264 int num; 03265 int isroot = 1, rundir_exists = 0; 03266 char *buf; 03267 const char *runuser = NULL, *rungroup = NULL; 03268 char *remotesock = NULL; 03269 int moduleresult; /*!< Result from the module load subsystem */ 03270 struct rlimit l; 03271 03272 /* Remember original args for restart */ 03273 if (argc > ARRAY_LEN(_argv) - 1) { 03274 fprintf(stderr, "Truncating argument size to %d\n", (int)ARRAY_LEN(_argv) - 1); 03275 argc = ARRAY_LEN(_argv) - 1; 03276 } 03277 for (x = 0; x < argc; x++) 03278 _argv[x] = argv[x]; 03279 _argv[x] = NULL; 03280 03281 if (geteuid() != 0) 03282 isroot = 0; 03283 03284 /* if the progname is rasterisk consider it a remote console */ 03285 if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) { 03286 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE); 03287 } 03288 if (gethostname(hostname, sizeof(hostname)-1)) 03289 ast_copy_string(hostname, "<Unknown>", sizeof(hostname)); 03290 ast_mainpid = getpid(); 03291 ast_ulaw_init(); 03292 ast_alaw_init(); 03293 callerid_init(); 03294 ast_builtins_init(); 03295 ast_utils_init(); 03296 tdd_init(); 03297 ast_tps_init(); 03298 ast_fd_init(); 03299 ast_pbx_init(); 03300 03301 if (getenv("HOME")) 03302 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); 03303 /* Check for options */ 03304 while ((c = getopt(argc, argv, "BC:cde:FfG:ghIiL:M:mnpqRrs:TtU:VvWXx:")) != -1) { 03305 /*!\note Please keep the ordering here to alphabetical, capital letters 03306 * first. This will make it easier in the future to select unused 03307 * option flags for new features. */ 03308 switch (c) { 03309 case 'B': /* Force black background */ 03310 ast_set_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND); 03311 ast_clear_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND); 03312 break; 03313 case 'X': 03314 ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES); 03315 break; 03316 case 'C': 03317 ast_copy_string(cfg_paths.config_file, optarg, sizeof(cfg_paths.config_file)); 03318 ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG); 03319 break; 03320 case 'c': 03321 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE); 03322 break; 03323 case 'd': 03324 option_debug++; 03325 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); 03326 break; 03327 #if defined(HAVE_SYSINFO) 03328 case 'e': 03329 if ((sscanf(&optarg[1], "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) { 03330 option_minmemfree = 0; 03331 } 03332 break; 03333 #endif 03334 #if HAVE_WORKING_FORK 03335 case 'F': 03336 ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK); 03337 break; 03338 case 'f': 03339 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); 03340 break; 03341 #endif 03342 case 'G': 03343 rungroup = ast_strdupa(optarg); 03344 break; 03345 case 'g': 03346 ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE); 03347 break; 03348 case 'h': 03349 show_cli_help(); 03350 exit(0); 03351 case 'I': 03352 ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING); 03353 break; 03354 case 'i': 03355 ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS); 03356 break; 03357 case 'L': 03358 if ((sscanf(optarg, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) { 03359 option_maxload = 0.0; 03360 } 03361 break; 03362 case 'M': 03363 if ((sscanf(optarg, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) { 03364 option_maxcalls = 0; 03365 } 03366 break; 03367 case 'm': 03368 ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE); 03369 break; 03370 case 'n': 03371 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR); 03372 break; 03373 case 'p': 03374 ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY); 03375 break; 03376 case 'q': 03377 ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET); 03378 break; 03379 case 'R': 03380 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT); 03381 break; 03382 case 'r': 03383 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE); 03384 break; 03385 case 's': 03386 remotesock = ast_strdupa(optarg); 03387 break; 03388 case 'T': 03389 ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP); 03390 break; 03391 case 't': 03392 ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES); 03393 break; 03394 case 'U': 03395 runuser = ast_strdupa(optarg); 03396 break; 03397 case 'V': 03398 show_version(); 03399 exit(0); 03400 case 'v': 03401 option_verbose++; 03402 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); 03403 break; 03404 case 'W': /* White background */ 03405 ast_set_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND); 03406 ast_clear_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND); 03407 break; 03408 case 'x': 03409 /* -r is implied by -x so set the flags -r sets as well. */ 03410 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE); 03411 03412 ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC | AST_OPT_FLAG_NO_COLOR); 03413 xarg = ast_strdupa(optarg); 03414 break; 03415 case '?': 03416 exit(1); 03417 } 03418 } 03419 03420 if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) { 03421 if (ast_register_verbose(console_verboser)) { 03422 ast_log(LOG_WARNING, "Unable to register console verboser?\n"); 03423 } 03424 WELCOME_MESSAGE; 03425 } 03426 03427 if (ast_opt_console && !option_verbose) 03428 ast_verbose("[ Booting...\n"); 03429 03430 /* For remote connections, change the name of the remote connection. 03431 * We do this for the benefit of init scripts (which need to know if/when 03432 * the main asterisk process has died yet). */ 03433 if (ast_opt_remote) { 03434 strcpy(argv[0], "rasterisk"); 03435 for (x = 1; x < argc; x++) { 03436 argv[x] = argv[0] + 10; 03437 } 03438 } 03439 03440 if (ast_opt_console && !option_verbose) { 03441 ast_verbose("[ Reading Master Configuration ]\n"); 03442 } 03443 03444 ast_readconfig(); 03445 env_init(); 03446 03447 if (ast_opt_remote && remotesock != NULL) 03448 ast_copy_string((char *) cfg_paths.socket_path, remotesock, sizeof(cfg_paths.socket_path)); 03449 03450 if (!ast_language_is_prefix && !ast_opt_remote) 03451 ast_log(LOG_WARNING, "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"); 03452 03453 if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) { 03454 ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n"); 03455 ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK); 03456 } 03457 03458 if (ast_opt_dump_core) { 03459 memset(&l, 0, sizeof(l)); 03460 l.rlim_cur = RLIM_INFINITY; 03461 l.rlim_max = RLIM_INFINITY; 03462 if (setrlimit(RLIMIT_CORE, &l)) { 03463 ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno)); 03464 } 03465 } 03466 03467 if (getrlimit(RLIMIT_NOFILE, &l)) { 03468 ast_log(LOG_WARNING, "Unable to check file descriptor limit: %s\n", strerror(errno)); 03469 } 03470 03471 #if !defined(CONFIGURE_RAN_AS_ROOT) 03472 /* Check if select(2) will run with more file descriptors */ 03473 do { 03474 int fd, fd2; 03475 ast_fdset readers; 03476 struct timeval tv = { 0, }; 03477 03478 if (l.rlim_cur <= FD_SETSIZE) { 03479 /* The limit of select()able FDs is irrelevant, because we'll never 03480 * open one that high. */ 03481 break; 03482 } 03483 03484 if (!(fd = open("/dev/null", O_RDONLY))) { 03485 ast_log(LOG_ERROR, "Cannot open a file descriptor at boot? %s\n", strerror(errno)); 03486 break; /* XXX Should we exit() here? XXX */ 03487 } 03488 03489 fd2 = (l.rlim_cur > sizeof(readers) * 8 ? sizeof(readers) * 8 : l.rlim_cur) - 1; 03490 if (dup2(fd, fd2) < 0) { 03491 ast_log(LOG_WARNING, "Cannot open maximum file descriptor %d at boot? %s\n", fd2, strerror(errno)); 03492 close(fd); 03493 break; 03494 } 03495 03496 FD_ZERO(&readers); 03497 FD_SET(fd2, &readers); 03498 if (ast_select(fd2 + 1, &readers, NULL, NULL, &tv) < 0) { 03499 ast_log(LOG_WARNING, "Maximum select()able file descriptor is %d\n", FD_SETSIZE); 03500 } 03501 ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur; 03502 close(fd); 03503 close(fd2); 03504 } while (0); 03505 #elif defined(HAVE_VARIABLE_FDSET) 03506 ast_FD_SETSIZE = l.rlim_cur > ast_FDMAX ? ast_FDMAX : l.rlim_cur; 03507 #endif /* !defined(CONFIGURE_RAN_AS_ROOT) */ 03508 03509 if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP)) 03510 rungroup = ast_config_AST_RUN_GROUP; 03511 if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER)) 03512 runuser = ast_config_AST_RUN_USER; 03513 03514 /* Must install this signal handler up here to ensure that if the canary 03515 * fails to execute that it doesn't kill the Asterisk process. 03516 */ 03517 sigaction(SIGCHLD, &child_handler, NULL); 03518 03519 /* It's common on some platforms to clear /var/run at boot. Create the 03520 * socket file directory before we drop privileges. */ 03521 if (mkdir(ast_config_AST_RUN_DIR, 0755)) { 03522 if (errno == EEXIST) { 03523 rundir_exists = 1; 03524 } else { 03525 ast_log(LOG_WARNING, "Unable to create socket file directory. Remote consoles will not be able to connect! (%s)\n", strerror(x)); 03526 } 03527 } 03528 03529 #ifndef __CYGWIN__ 03530 03531 if (isroot) { 03532 ast_set_priority(ast_opt_high_priority); 03533 } 03534 03535 if (isroot && rungroup) { 03536 struct group *gr; 03537 gr = getgrnam(rungroup); 03538 if (!gr) { 03539 ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup); 03540 exit(1); 03541 } 03542 if (!rundir_exists && chown(ast_config_AST_RUN_DIR, -1, gr->gr_gid)) { 03543 ast_log(LOG_WARNING, "Unable to chgrp run directory to %d (%s)\n", (int) gr->gr_gid, rungroup); 03544 } 03545 if (setgid(gr->gr_gid)) { 03546 ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup); 03547 exit(1); 03548 } 03549 if (setgroups(0, NULL)) { 03550 ast_log(LOG_WARNING, "Unable to drop unneeded groups\n"); 03551 exit(1); 03552 } 03553 if (option_verbose) 03554 ast_verbose("Running as group '%s'\n", rungroup); 03555 } 03556 03557 if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) { 03558 #ifdef HAVE_CAP 03559 int has_cap = 1; 03560 #endif /* HAVE_CAP */ 03561 struct passwd *pw; 03562 pw = getpwnam(runuser); 03563 if (!pw) { 03564 ast_log(LOG_WARNING, "No such user '%s'!\n", runuser); 03565 exit(1); 03566 } 03567 if (chown(ast_config_AST_RUN_DIR, pw->pw_uid, -1)) { 03568 ast_log(LOG_WARNING, "Unable to chown run directory to %d (%s)\n", (int) pw->pw_uid, runuser); 03569 } 03570 #ifdef HAVE_CAP 03571 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { 03572 ast_log(LOG_WARNING, "Unable to keep capabilities.\n"); 03573 has_cap = 0; 03574 } 03575 #endif /* HAVE_CAP */ 03576 if (!isroot && pw->pw_uid != geteuid()) { 03577 ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser); 03578 exit(1); 03579 } 03580 if (!rungroup) { 03581 if (setgid(pw->pw_gid)) { 03582 ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid); 03583 exit(1); 03584 } 03585 if (isroot && initgroups(pw->pw_name, pw->pw_gid)) { 03586 ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser); 03587 exit(1); 03588 } 03589 } 03590 if (setuid(pw->pw_uid)) { 03591 ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser); 03592 exit(1); 03593 } 03594 if (option_verbose) 03595 ast_verbose("Running as user '%s'\n", runuser); 03596 #ifdef HAVE_CAP 03597 if (has_cap) { 03598 cap_t cap; 03599 03600 cap = cap_from_text("cap_net_admin=eip"); 03601 03602 if (cap_set_proc(cap)) 03603 ast_log(LOG_WARNING, "Unable to install capabilities.\n"); 03604 03605 if (cap_free(cap)) 03606 ast_log(LOG_WARNING, "Unable to drop capabilities.\n"); 03607 } 03608 #endif /* HAVE_CAP */ 03609 } 03610 03611 #endif /* __CYGWIN__ */ 03612 03613 #ifdef linux 03614 if (geteuid() && ast_opt_dump_core) { 03615 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { 03616 ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno)); 03617 } 03618 } 03619 #endif 03620 03621 { 03622 #if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) 03623 #if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS) 03624 #define eaccess euidaccess 03625 #endif 03626 char dir[PATH_MAX]; 03627 if (!getcwd(dir, sizeof(dir)) || eaccess(dir, R_OK | X_OK | F_OK)) { 03628 ast_log(LOG_ERROR, "Unable to access the running directory (%s). Changing to '/' for compatibility.\n", strerror(errno)); 03629 /* If we cannot access the CWD, then we couldn't dump core anyway, 03630 * so chdir("/") won't break anything. */ 03631 if (chdir("/")) { 03632 /* chdir(/) should never fail, so this ends up being a no-op */ 03633 ast_log(LOG_ERROR, "chdir(\"/\") failed?!! %s\n", strerror(errno)); 03634 } 03635 } else 03636 #endif /* defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS) */ 03637 if (!ast_opt_no_fork && !ast_opt_dump_core) { 03638 /* Backgrounding, but no cores, so chdir won't break anything. */ 03639 if (chdir("/")) { 03640 ast_log(LOG_ERROR, "Unable to chdir(\"/\") ?!! %s\n", strerror(errno)); 03641 } 03642 } 03643 } 03644 03645 ast_term_init(); 03646 printf("%s", term_end()); 03647 fflush(stdout); 03648 03649 if (ast_opt_console && !option_verbose) 03650 ast_verbose("[ Initializing Custom Configuration Options ]\n"); 03651 /* custom config setup */ 03652 register_config_cli(); 03653 read_config_maps(); 03654 03655 if (ast_opt_console) { 03656 if (el_hist == NULL || el == NULL) 03657 ast_el_initialize(); 03658 03659 if (!ast_strlen_zero(filename)) 03660 ast_el_read_history(filename); 03661 } 03662 03663 if (ast_tryconnect()) { 03664 /* One is already running */ 03665 if (ast_opt_remote) { 03666 if (ast_opt_exec) { 03667 ast_remotecontrol(xarg); 03668 quit_handler(0, SHUTDOWN_FAST, 0); 03669 exit(0); 03670 } 03671 printf("%s", term_quit()); 03672 ast_remotecontrol(NULL); 03673 quit_handler(0, SHUTDOWN_FAST, 0); 03674 exit(0); 03675 } else { 03676 ast_log(LOG_ERROR, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET); 03677 printf("%s", term_quit()); 03678 exit(1); 03679 } 03680 } else if (ast_opt_remote || ast_opt_exec) { 03681 ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET); 03682 printf("%s", term_quit()); 03683 exit(1); 03684 } 03685 /* Blindly write pid file since we couldn't connect */ 03686 unlink(ast_config_AST_PID); 03687 f = fopen(ast_config_AST_PID, "w"); 03688 if (f) { 03689 fprintf(f, "%ld\n", (long)getpid()); 03690 fclose(f); 03691 } else 03692 ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno)); 03693 03694 #if HAVE_WORKING_FORK 03695 if (ast_opt_always_fork || !ast_opt_no_fork) { 03696 #ifndef HAVE_SBIN_LAUNCHD 03697 if (daemon(1, 0) < 0) { 03698 ast_log(LOG_ERROR, "daemon() failed: %s\n", strerror(errno)); 03699 } 03700 ast_mainpid = getpid(); 03701 /* Blindly re-write pid file since we are forking */ 03702 unlink(ast_config_AST_PID); 03703 f = fopen(ast_config_AST_PID, "w"); 03704 if (f) { 03705 fprintf(f, "%ld\n", (long)ast_mainpid); 03706 fclose(f); 03707 } else 03708 ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno)); 03709 #else 03710 ast_log(LOG_WARNING, "Mac OS X detected. Use 'launchctl load /Library/LaunchDaemon/org.asterisk.asterisk.plist'.\n"); 03711 #endif 03712 } 03713 #endif 03714 03715 /* Spawning of astcanary must happen AFTER the call to daemon(3) */ 03716 if (isroot && ast_opt_high_priority) { 03717 snprintf(canary_filename, sizeof(canary_filename), "%s/alt.asterisk.canary.tweet.tweet.tweet", ast_config_AST_RUN_DIR); 03718 03719 /* Don't let the canary child kill Asterisk, if it dies immediately */ 03720 sigaction(SIGPIPE, &ignore_sig_handler, NULL); 03721 03722 canary_pid = fork(); 03723 if (canary_pid == 0) { 03724 char canary_binary[128], *lastslash, ppid[12]; 03725 03726 /* Reset signal handler */ 03727 signal(SIGCHLD, SIG_DFL); 03728 signal(SIGPIPE, SIG_DFL); 03729 03730 ast_close_fds_above_n(0); 03731 ast_set_priority(0); 03732 snprintf(ppid, sizeof(ppid), "%d", (int) ast_mainpid); 03733 03734 execlp("astcanary", "astcanary", canary_filename, ppid, (char *)NULL); 03735 03736 /* If not found, try the same path as used to execute asterisk */ 03737 ast_copy_string(canary_binary, argv[0], sizeof(canary_binary)); 03738 if ((lastslash = strrchr(canary_binary, '/'))) { 03739 ast_copy_string(lastslash + 1, "astcanary", sizeof(canary_binary) + canary_binary - (lastslash + 1)); 03740 execl(canary_binary, "astcanary", canary_filename, ppid, (char *)NULL); 03741 } 03742 03743 /* Should never happen */ 03744 _exit(1); 03745 } else if (canary_pid > 0) { 03746 pthread_t dont_care; 03747 ast_pthread_create_detached(&dont_care, NULL, canary_thread, NULL); 03748 } 03749 03750 /* Kill the canary when we exit */ 03751 ast_register_atexit(canary_exit); 03752 } 03753 03754 if (ast_event_init()) { 03755 printf("%s", term_quit()); 03756 exit(1); 03757 } 03758 03759 #ifdef TEST_FRAMEWORK 03760 if (ast_test_init()) { 03761 printf("%s", term_quit()); 03762 exit(1); 03763 } 03764 #endif 03765 03766 ast_aoc_cli_init(); 03767 03768 ast_makesocket(); 03769 sigemptyset(&sigs); 03770 sigaddset(&sigs, SIGHUP); 03771 sigaddset(&sigs, SIGTERM); 03772 sigaddset(&sigs, SIGINT); 03773 sigaddset(&sigs, SIGPIPE); 03774 sigaddset(&sigs, SIGWINCH); 03775 pthread_sigmask(SIG_BLOCK, &sigs, NULL); 03776 sigaction(SIGURG, &urg_handler, NULL); 03777 signal(SIGINT, __quit_handler); 03778 signal(SIGTERM, __quit_handler); 03779 sigaction(SIGHUP, &hup_handler, NULL); 03780 sigaction(SIGPIPE, &ignore_sig_handler, NULL); 03781 03782 /* ensure that the random number generators are seeded with a different value every time 03783 Asterisk is started 03784 */ 03785 srand((unsigned int) getpid() + (unsigned int) time(NULL)); 03786 initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool)); 03787 03788 if (init_logger()) { /* Start logging subsystem */ 03789 printf("%s", term_quit()); 03790 exit(1); 03791 } 03792 03793 threadstorage_init(); 03794 03795 astobj2_init(); 03796 03797 ast_autoservice_init(); 03798 03799 if (ast_timing_init()) { 03800 printf("%s", term_quit()); 03801 exit(1); 03802 } 03803 03804 if (ast_ssl_init()) { 03805 printf("%s", term_quit()); 03806 exit(1); 03807 } 03808 03809 #ifdef AST_XML_DOCS 03810 /* Load XML documentation. */ 03811 ast_xmldoc_load_documentation(); 03812 #endif 03813 03814 /* initialize the data retrieval API */ 03815 if (ast_data_init()) { 03816 printf ("%s", term_quit()); 03817 exit(1); 03818 } 03819 03820 ast_channels_init(); 03821 03822 if ((moduleresult = load_modules(1))) { /* Load modules, pre-load only */ 03823 printf("%s", term_quit()); 03824 exit(moduleresult == -2 ? 2 : 1); 03825 } 03826 03827 if (dnsmgr_init()) { /* Initialize the DNS manager */ 03828 printf("%s", term_quit()); 03829 exit(1); 03830 } 03831 03832 ast_http_init(); /* Start the HTTP server, if needed */ 03833 03834 if (init_manager()) { 03835 printf("%s", term_quit()); 03836 exit(1); 03837 } 03838 03839 if (ast_cdr_engine_init()) { 03840 printf("%s", term_quit()); 03841 exit(1); 03842 } 03843 03844 if (ast_cel_engine_init()) { 03845 printf("%s", term_quit()); 03846 exit(1); 03847 } 03848 03849 if (ast_device_state_engine_init()) { 03850 printf("%s", term_quit()); 03851 exit(1); 03852 } 03853 03854 ast_dsp_init(); 03855 ast_udptl_init(); 03856 03857 if (ast_image_init()) { 03858 printf("%s", term_quit()); 03859 exit(1); 03860 } 03861 03862 if (ast_file_init()) { 03863 printf("%s", term_quit()); 03864 exit(1); 03865 } 03866 03867 if (load_pbx()) { 03868 printf("%s", term_quit()); 03869 exit(1); 03870 } 03871 03872 if (ast_indications_init()) { 03873 printf("%s", term_quit()); 03874 exit(1); 03875 } 03876 03877 if (ast_features_init()) { 03878 printf("%s", term_quit()); 03879 exit(1); 03880 } 03881 03882 if (init_framer()) { 03883 printf("%s", term_quit()); 03884 exit(1); 03885 } 03886 03887 if (astdb_init()) { 03888 printf("%s", term_quit()); 03889 exit(1); 03890 } 03891 03892 if (ast_enum_init()) { 03893 printf("%s", term_quit()); 03894 exit(1); 03895 } 03896 03897 if (ast_cc_init()) { 03898 printf("%s", term_quit()); 03899 exit(1); 03900 } 03901 03902 if ((moduleresult = load_modules(0))) { /* Load modules */ 03903 printf("%s", term_quit()); 03904 exit(moduleresult == -2 ? 2 : 1); 03905 } 03906 03907 /* loads the cli_permissoins.conf file needed to implement cli restrictions. */ 03908 ast_cli_perms_init(0); 03909 03910 ast_stun_init(); 03911 03912 dnsmgr_start_refresh(); 03913 03914 /* We might have the option of showing a console, but for now just 03915 do nothing... */ 03916 if (ast_opt_console && !option_verbose) 03917 ast_verbose(" ]\n"); 03918 if (option_verbose || ast_opt_console) 03919 ast_verbose("%s", term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp))); 03920 if (ast_opt_no_fork) 03921 consolethread = pthread_self(); 03922 03923 if (pipe(sig_alert_pipe)) 03924 sig_alert_pipe[0] = sig_alert_pipe[1] = -1; 03925 03926 ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED); 03927 manager_event(EVENT_FLAG_SYSTEM, "FullyBooted", "Status: Fully Booted\r\n"); 03928 03929 ast_process_pending_reloads(); 03930 03931 pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); 03932 03933 #ifdef __AST_DEBUG_MALLOC 03934 __ast_mm_init(); 03935 #endif 03936 03937 ast_lastreloadtime = ast_startuptime = ast_tvnow(); 03938 ast_cli_register_multiple(cli_asterisk, ARRAY_LEN(cli_asterisk)); 03939 03940 run_startup_commands(); 03941 03942 if (ast_opt_console) { 03943 /* Console stuff now... */ 03944 /* Register our quit function */ 03945 char title[256]; 03946 03947 ast_pthread_create_detached(&mon_sig_flags, NULL, monitor_sig_flags, NULL); 03948 03949 set_icon("Asterisk"); 03950 snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid); 03951 set_title(title); 03952 03953 el_set(el, EL_GETCFN, ast_el_read_char); 03954 03955 for (;;) { 03956 if (sig_flags.need_quit || sig_flags.need_quit_handler) { 03957 quit_handler(0, SHUTDOWN_FAST, 0); 03958 break; 03959 } 03960 buf = (char *) el_gets(el, &num); 03961 03962 if (!buf && write(1, "", 1) < 0) 03963 goto lostterm; 03964 03965 if (buf) { 03966 if (buf[strlen(buf)-1] == '\n') 03967 buf[strlen(buf)-1] = '\0'; 03968 03969 consolehandler((char *)buf); 03970 } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n", 03971 strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) { 03972 /* Whoa, stdout disappeared from under us... Make /dev/null's */ 03973 int fd; 03974 fd = open("/dev/null", O_RDWR); 03975 if (fd > -1) { 03976 dup2(fd, STDOUT_FILENO); 03977 dup2(fd, STDIN_FILENO); 03978 } else 03979 ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n"); 03980 break; 03981 } 03982 } 03983 } 03984 03985 monitor_sig_flags(NULL); 03986 03987 lostterm: 03988 return 0; 03989 }
static void* monitor_sig_flags | ( | void * | unused | ) | [static] |
Definition at line 3152 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().
03153 { 03154 for (;;) { 03155 struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 }; 03156 int a; 03157 ast_poll(&p, 1, -1); 03158 if (sig_flags.need_reload) { 03159 sig_flags.need_reload = 0; 03160 ast_module_reload(NULL); 03161 } 03162 if (sig_flags.need_quit) { 03163 sig_flags.need_quit = 0; 03164 if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) { 03165 sig_flags.need_quit_handler = 1; 03166 pthread_kill(consolethread, SIGURG); 03167 } else { 03168 quit_handler(0, SHUTDOWN_NORMAL, 0); 03169 } 03170 } 03171 if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) { 03172 } 03173 } 03174 03175 return NULL; 03176 }
static void* netconsole | ( | void * | vconsole | ) | [static] |
Definition at line 1251 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, errno, console::fd, fdprint(), console::gid, hostname, LOG_ERROR, LOG_WARNING, MAXHOSTNAMELEN, console::p, read_credentials(), and console::uid.
Referenced by listener().
01252 { 01253 struct console *con = vconsole; 01254 char hostname[MAXHOSTNAMELEN] = ""; 01255 char tmp[512]; 01256 int res; 01257 struct pollfd fds[2]; 01258 01259 if (gethostname(hostname, sizeof(hostname)-1)) 01260 ast_copy_string(hostname, "<Unknown>", sizeof(hostname)); 01261 snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version()); 01262 fdprint(con->fd, tmp); 01263 for (;;) { 01264 fds[0].fd = con->fd; 01265 fds[0].events = POLLIN; 01266 fds[0].revents = 0; 01267 fds[1].fd = con->p[0]; 01268 fds[1].events = POLLIN; 01269 fds[1].revents = 0; 01270 01271 res = ast_poll(fds, 2, -1); 01272 if (res < 0) { 01273 if (errno != EINTR) 01274 ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno)); 01275 continue; 01276 } 01277 if (fds[0].revents) { 01278 res = read_credentials(con->fd, tmp, sizeof(tmp) - 1, con); 01279 if (res < 1) { 01280 break; 01281 } 01282 tmp[res] = 0; 01283 if (strncmp(tmp, "cli quit after ", 15) == 0) { 01284 ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res - 15, tmp + 15); 01285 break; 01286 } 01287 ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res, tmp); 01288 } 01289 if (fds[1].revents) { 01290 res = read_credentials(con->p[0], tmp, sizeof(tmp), con); 01291 if (res < 1) { 01292 ast_log(LOG_ERROR, "read returned %d\n", res); 01293 break; 01294 } 01295 res = write(con->fd, tmp, res); 01296 if (res < 1) 01297 break; 01298 } 01299 } 01300 if (!ast_opt_hide_connect) { 01301 ast_verb(3, "Remote UNIX connection disconnected\n"); 01302 } 01303 close(con->fd); 01304 close(con->p[0]); 01305 close(con->p[1]); 01306 con->fd = -1; 01307 01308 return NULL; 01309 }
static void network_verboser | ( | const char * | s | ) | [static] |
Definition at line 1185 of file asterisk.c.
References __LOG_VERBOSE, and ast_network_puts_mutable().
Referenced by ast_makesocket().
01186 { 01187 ast_network_puts_mutable(s, __LOG_VERBOSE); 01188 }
static void quit_handler | ( | int | num, | |
shutdown_nice_t | niceness, | |||
int | restart | |||
) | [static] |
Definition at line 1622 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().
01623 { 01624 if (can_safely_quit(niceness, restart)) { 01625 really_quit(num, niceness, restart); 01626 /* No one gets here. */ 01627 } 01628 /* It wasn't our time. */ 01629 }
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 1202 of file asterisk.c.
References console::gid, len(), and console::uid.
Referenced by netconsole().
01203 { 01204 #if defined(SO_PEERCRED) 01205 #ifdef HAVE_STRUCT_SOCKPEERCRED_UID 01206 #define HAVE_STRUCT_UCRED_UID 01207 struct sockpeercred cred; 01208 #else 01209 struct ucred cred; 01210 #endif 01211 socklen_t len = sizeof(cred); 01212 #endif 01213 #if defined(HAVE_GETPEEREID) 01214 uid_t uid; 01215 gid_t gid; 01216 #else 01217 int uid, gid; 01218 #endif 01219 int result; 01220 01221 result = read(fd, buffer, size); 01222 if (result < 0) { 01223 return result; 01224 } 01225 01226 #if defined(SO_PEERCRED) && (defined(HAVE_STRUCT_UCRED_UID) || defined(HAVE_STRUCT_UCRED_CR_UID)) 01227 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) { 01228 return result; 01229 } 01230 #if defined(HAVE_STRUCT_UCRED_UID) 01231 uid = cred.uid; 01232 gid = cred.gid; 01233 #else /* defined(HAVE_STRUCT_UCRED_CR_UID) */ 01234 uid = cred.cr_uid; 01235 gid = cred.cr_gid; 01236 #endif /* defined(HAVE_STRUCT_UCRED_UID) */ 01237 01238 #elif defined(HAVE_GETPEEREID) 01239 if (getpeereid(fd, &uid, &gid)) { 01240 return result; 01241 } 01242 #else 01243 return result; 01244 #endif 01245 con->uid = uid; 01246 con->gid = gid; 01247 01248 return result; 01249 }
static void really_quit | ( | int | num, | |
shutdown_nice_t | niceness, | |||
int | restart | |||
) | [static] |
Definition at line 1697 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_verbose, close_logger(), consolethread, el, el_hist, EVENT_FLAG_SYSTEM, lthread, manager_event, mon_sig_flags, restartnow, SHUTDOWN_NICE, and term_quit().
Referenced by quit_handler().
01698 { 01699 if (niceness >= SHUTDOWN_NICE) { 01700 ast_module_shutdown(); 01701 } 01702 01703 if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) { 01704 char filename[80] = ""; 01705 if (getenv("HOME")) { 01706 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); 01707 } 01708 if (!ast_strlen_zero(filename)) { 01709 ast_el_write_history(filename); 01710 } 01711 if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) { 01712 /* Only end if we are the consolethread, otherwise there's a race with that thread. */ 01713 if (el != NULL) { 01714 el_end(el); 01715 } 01716 if (el_hist != NULL) { 01717 history_end(el_hist); 01718 } 01719 } else if (mon_sig_flags == pthread_self()) { 01720 if (consolethread != AST_PTHREADT_NULL) { 01721 pthread_kill(consolethread, SIGURG); 01722 } 01723 } 01724 } 01725 if (option_verbose) 01726 ast_verbose("Executing last minute cleanups\n"); 01727 ast_run_atexits(); 01728 /* Called on exit */ 01729 if (option_verbose && ast_opt_console) 01730 ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num); 01731 ast_debug(1, "Asterisk ending (%d).\n", num); 01732 manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False"); 01733 if (ast_socket > -1) { 01734 pthread_cancel(lthread); 01735 close(ast_socket); 01736 ast_socket = -1; 01737 unlink(ast_config_AST_SOCKET); 01738 } 01739 if (ast_consock > -1) 01740 close(ast_consock); 01741 if (!ast_opt_remote) 01742 unlink(ast_config_AST_PID); 01743 printf("%s", term_quit()); 01744 if (restart) { 01745 int i; 01746 if (option_verbose || ast_opt_console) 01747 ast_verbose("Preparing for Asterisk restart...\n"); 01748 /* Mark all FD's for closing on exec */ 01749 for (i = 3; i < 32768; i++) { 01750 fcntl(i, F_SETFD, FD_CLOEXEC); 01751 } 01752 if (option_verbose || ast_opt_console) 01753 ast_verbose("Asterisk is now restarting...\n"); 01754 restartnow = 1; 01755 01756 /* close logger */ 01757 close_logger(); 01758 01759 /* If there is a consolethread running send it a SIGHUP 01760 so it can execvp, otherwise we can do it ourselves */ 01761 if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) { 01762 pthread_kill(consolethread, SIGHUP); 01763 /* Give the signal handler some time to complete */ 01764 sleep(2); 01765 } else 01766 execvp(_argv[0], _argv); 01767 01768 } else { 01769 /* close logger */ 01770 close_logger(); 01771 } 01772 01773 exit(0); 01774 }
static int remoteconsolehandler | ( | char * | s | ) | [static] |
Definition at line 1864 of file asterisk.c.
References ast_all_zeros(), ast_el_add_history(), ast_safe_system(), quit_handler(), and SHUTDOWN_FAST.
Referenced by ast_remotecontrol().
01865 { 01866 int ret = 0; 01867 01868 /* Called when readline data is available */ 01869 if (!ast_all_zeros(s)) 01870 ast_el_add_history(s); 01871 /* The real handler for bang */ 01872 if (s[0] == '!') { 01873 if (s[1]) 01874 ast_safe_system(s+1); 01875 else 01876 ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); 01877 ret = 1; 01878 } 01879 if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) && 01880 (s[4] == '\0' || isspace(s[4]))) { 01881 quit_handler(0, SHUTDOWN_FAST, 0); 01882 ret = 1; 01883 } 01884 01885 return ret; 01886 }
static void run_startup_commands | ( | void | ) | [static] |
Definition at line 3214 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().
03215 { 03216 int fd; 03217 struct ast_config *cfg; 03218 struct ast_flags cfg_flags = { 0 }; 03219 struct ast_variable *v; 03220 03221 if (!(cfg = ast_config_load2("cli.conf", "" /* core, can't reload */, cfg_flags))) 03222 return; 03223 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) { 03224 return; 03225 } 03226 03227 fd = open("/dev/null", O_RDWR); 03228 if (fd < 0) { 03229 ast_config_destroy(cfg); 03230 return; 03231 } 03232 03233 for (v = ast_variable_browse(cfg, "startup_commands"); v; v = v->next) { 03234 if (ast_true(v->value)) 03235 ast_cli_command(fd, v->name); 03236 } 03237 03238 close(fd); 03239 ast_config_destroy(cfg); 03240 }
static void set_icon | ( | char * | text | ) | [static] |
Definition at line 1566 of file asterisk.c.
Referenced by main().
01567 { 01568 if (getenv("TERM") && strstr(getenv("TERM"), "xterm")) 01569 fprintf(stdout, "\033]1;%s\007", text); 01570 }
static void set_title | ( | char * | text | ) | [static] |
Set an X-term or screen title.
Definition at line 1560 of file asterisk.c.
Referenced by main().
01561 { 01562 if (getenv("TERM") && strstr(getenv("TERM"), "xterm")) 01563 fprintf(stdout, "\033]2;%s\007", text); 01564 }
static void set_ulimit | ( | int | value | ) | [static] |
Set maximum open files.
Definition at line 1537 of file asterisk.c.
References ast_log(), errno, LOG_NOTICE, and LOG_WARNING.
01538 { 01539 struct rlimit l = {0, 0}; 01540 01541 if (value <= 0) { 01542 ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value); 01543 return; 01544 } 01545 01546 l.rlim_cur = value; 01547 l.rlim_max = value; 01548 01549 if (setrlimit(RLIMIT_NOFILE, &l)) { 01550 ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno)); 01551 return; 01552 } 01553 01554 ast_log(LOG_NOTICE, "Setting max files open to %d\n",value); 01555 01556 return; 01557 }
static int show_cli_help | ( | void | ) | [static] |
Definition at line 2875 of file asterisk.c.
References ast_get_version().
Referenced by main().
02876 { 02877 printf("Asterisk %s, Copyright (C) 1999 - 2012, Digium, Inc. and others.\n", ast_get_version()); 02878 printf("Usage: asterisk [OPTIONS]\n"); 02879 printf("Valid Options:\n"); 02880 printf(" -V Display version number and exit\n"); 02881 printf(" -C <configfile> Use an alternate configuration file\n"); 02882 printf(" -G <group> Run as a group other than the caller\n"); 02883 printf(" -U <user> Run as a user other than the caller\n"); 02884 printf(" -c Provide console CLI\n"); 02885 printf(" -d Enable extra debugging\n"); 02886 #if HAVE_WORKING_FORK 02887 printf(" -f Do not fork\n"); 02888 printf(" -F Always fork\n"); 02889 #endif 02890 printf(" -g Dump core in case of a crash\n"); 02891 printf(" -h This help screen\n"); 02892 printf(" -i Initialize crypto keys at startup\n"); 02893 printf(" -I Enable internal timing if DAHDI timer is available\n"); 02894 printf(" -L <load> Limit the maximum load average before rejecting new calls\n"); 02895 printf(" -M <value> Limit the maximum number of calls to the specified value\n"); 02896 printf(" -m Mute debugging and console output on the console\n"); 02897 printf(" -n Disable console colorization\n"); 02898 printf(" -p Run as pseudo-realtime thread\n"); 02899 printf(" -q Quiet mode (suppress output)\n"); 02900 printf(" -r Connect to Asterisk on this machine\n"); 02901 printf(" -R Same as -r, except attempt to reconnect if disconnected\n"); 02902 printf(" -s <socket> Connect to Asterisk via socket <socket> (only valid with -r)\n"); 02903 printf(" -t Record soundfiles in /var/tmp and move them where they\n"); 02904 printf(" belong after they are done\n"); 02905 printf(" -T Display the time in [Mmm dd hh:mm:ss] format for each line\n"); 02906 printf(" of output to the CLI\n"); 02907 printf(" -v Increase verbosity (multiple v's = more verbose)\n"); 02908 printf(" -x <cmd> Execute command <cmd> (implies -r)\n"); 02909 printf(" -X Execute includes by default (allows #exec in asterisk.conf)\n"); 02910 printf(" -W Adjust terminal colors to compensate for a light background\n"); 02911 printf("\n"); 02912 return 0; 02913 }
static char* show_license | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2147 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.
02148 { 02149 switch (cmd) { 02150 case CLI_INIT: 02151 e->command = "core show license"; 02152 e->usage = 02153 "Usage: core show license\n" 02154 " Shows the license(s) for this copy of Asterisk.\n"; 02155 return NULL; 02156 case CLI_GENERATE: 02157 return NULL; 02158 } 02159 02160 ast_cli(a->fd, "%s", license_lines); 02161 02162 return CLI_SUCCESS; 02163 }
static int show_version | ( | void | ) | [static] |
Definition at line 2869 of file asterisk.c.
References ast_get_version().
Referenced by main().
02870 { 02871 printf("Asterisk %s\n", ast_get_version()); 02872 return 0; 02873 }
static char* show_warranty | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2110 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.
02111 { 02112 switch (cmd) { 02113 case CLI_INIT: 02114 e->command = "core show warranty"; 02115 e->usage = 02116 "Usage: core show warranty\n" 02117 " Shows the warranty (if any) for this copy of Asterisk.\n"; 02118 return NULL; 02119 case CLI_GENERATE: 02120 return NULL; 02121 } 02122 02123 ast_cli(a->fd, "%s", warranty_lines); 02124 02125 return CLI_SUCCESS; 02126 }
char* _argv[256] [static] |
const char* ast_config_AST_AGI_DIR = cfg_paths.agi_dir |
Definition at line 259 of file asterisk.c.
Referenced by handle_show_settings(), and launch_script().
const char* ast_config_AST_CONFIG_DIR = cfg_paths.config_dir |
Definition at line 251 of file asterisk.c.
Referenced by action_createconfig(), ast_module_reload(), 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 252 of file asterisk.c.
Referenced by ast_readconfig(), handle_show_settings(), and launch_script().
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] [static] |
const char* ast_config_AST_DATA_DIR = cfg_paths.data_dir |
Definition at line 257 of file asterisk.c.
Referenced by ast_linear_stream(), 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 |
const char* ast_config_AST_KEY_DIR = cfg_paths.key_dir |
Definition at line 260 of file asterisk.c.
Referenced by 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 258 of file asterisk.c.
Referenced by apply_general_options(), 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(), OpenHistory(), reload_logger(), testclient_exec(), testserver_exec(), write_history(), and writefile().
const char* ast_config_AST_MODULE_DIR = cfg_paths.module_dir |
Definition at line 253 of file asterisk.c.
Referenced by complete_fn(), handle_show_settings(), launch_script(), and load_dynamic_module().
const char* ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir |
Definition at line 255 of file asterisk.c.
Referenced by ast_monitor_change_fname(), ast_monitor_start(), chanspy_exec(), extenspy_exec(), launch_script(), and mixmonitor_exec().
const char* ast_config_AST_PID = cfg_paths.pid_path |
Definition at line 264 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 261 of file asterisk.c.
Referenced by handle_show_settings(), launch_script(), and main().
const char* ast_config_AST_RUN_GROUP = cfg_paths.run_group |
Definition at line 267 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 266 of file asterisk.c.
Referenced by action_coresettings(), handle_show_settings(), and main().
const char* ast_config_AST_SOCKET = cfg_paths.socket_path |
Definition at line 265 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 254 of file asterisk.c.
Referenced by app_exec(), conf_run(), dictate_exec(), handle_show_settings(), launch_script(), load_module(), sms_nextoutgoing(), and sms_writefile().
const char* ast_config_AST_SYSTEM_NAME = cfg_paths.system_name |
Definition at line 268 of file asterisk.c.
Referenced by __ast_channel_alloc_ap(), __init_manager(), action_coresettings(), ast_str_retrieve_variable(), cli_prompt(), env_init(), handle_show_settings(), realtime_update_peer(), and reload_config().
const char* ast_config_AST_VAR_DIR = cfg_paths.var_dir |
Definition at line 256 of file asterisk.c.
Referenced by ael2_semantic_check(), handle_show_settings(), and launch_script().
int ast_consock = -1 [static] |
UNIX Socket for controlling another asterisk
Definition at line 194 of file asterisk.c.
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 188 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(), evt_event_deliver_cb(), handle_show_settings(), and set_config().
unsigned int ast_FD_SETSIZE |
struct timeval ast_lastreloadtime |
Definition at line 214 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 |
int ast_socket = -1 [static] |
UNIX Socket for allowing remote control
Definition at line 193 of file asterisk.c.
struct timeval ast_startuptime |
Definition at line 213 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] |
int canary_pid = 0 [static] |
struct _cfg_paths cfg_paths [static] |
struct sigaction child_handler [static] |
Initial value:
{ .sa_handler = _child_handler, .sa_flags = SA_RESTART, }
Definition at line 1531 of file asterisk.c.
struct ast_cli_entry cli_asterisk[] [static] |
Definition at line 220 of file asterisk.c.
Referenced by ast_console_toggle_loglevel(), ast_console_toggle_mute(), ast_makesocket(), ast_network_puts(), ast_network_puts_mutable(), and listener().
pthread_t consolethread = AST_PTHREADT_NULL [static] |
Definition at line 289 of file asterisk.c.
Referenced by console_verboser(), main(), monitor_sig_flags(), and really_quit().
char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE |
Definition at line 222 of file asterisk.c.
Referenced by __ast_channel_alloc_ap(), and handle_show_settings().
EditLine* el [static] |
Definition at line 217 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 216 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 sigaction hup_handler [static] |
Initial value:
{ .sa_handler = _hup_handler, .sa_flags = SA_RESTART, }
Definition at line 1511 of file asterisk.c.
struct sigaction ignore_sig_handler [static] |
const char license_lines[] [static] |
Definition at line 2128 of file asterisk.c.
pthread_t lthread [static] |
pthread_t mon_sig_flags [static] |
unsigned int need_quit |
Definition at line 299 of file asterisk.c.
unsigned int need_quit_handler |
Definition at line 300 of file asterisk.c.
unsigned int need_reload |
Definition at line 298 of file asterisk.c.
struct sigaction null_sig_handler [static] |
Initial value:
{ .sa_handler = _null_sig_handler, .sa_flags = SA_RESTART, }
Definition at line 993 of file asterisk.c.
struct profile_data* prof_data [static] |
Definition at line 695 of file asterisk.c.
Referenced by ast_add_profile(), ast_mark(), ast_profile(), handle_clear_profile(), and handle_show_profile().
Definition at line 2291 of file asterisk.c.
Referenced by auth_exec(), cli_prompt(), handle_speechrecognize(), minivm_accmess_exec(), and pw_cb().
char randompool[256] [static] |
char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR |
char* remotehostname [static] |
int restartnow [static] |
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 1005 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 1002 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 1006 of file asterisk.c.
shutdown_nice_t shuttingdown = NOT_SHUTTING_DOWN [static] |
Definition at line 287 of file asterisk.c.
Referenced by can_safely_quit(), and handle_abort_shutdown().
int sig_alert_pipe[2] = { -1, -1 } [static] |
Definition at line 296 of file asterisk.c.
Referenced by __quit_handler(), _hup_handler(), main(), and monitor_sig_flags().
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 sigaction urg_handler [static] |
Initial value:
{ .sa_handler = _urg_handler, .sa_flags = SA_RESTART, }
Definition at line 1490 of file asterisk.c.
const char warranty_lines[] [static] |
Definition at line 2085 of file asterisk.c.