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