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