#include "asterisk.h"
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <sched.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <sys/resource.h>
#include <grp.h>
#include <pwd.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/image.h"
#include "asterisk/tdd.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/cdr.h"
#include "asterisk/pbx.h"
#include "asterisk/enum.h"
#include "asterisk/rtp.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/version.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"
#include "asterisk/module.h"
#include "asterisk/doxyref.h"
#include "../defaults.h"
Go to the source code of this file.
Data Structures | |
struct | ast_atexit |
struct | console |
struct | file_version |
struct | profile_data |
struct | profile_entry |
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 | FORMAT "%-25.25s %-40.40s\n" |
#define | FORMAT "%-25.25s %-40.40s\n" |
#define | NUM_MSGS 64 |
#define | PF_LOCAL PF_UNIX |
#define | WELCOME_MESSAGE |
Welcome message when starting a CLI interface. | |
Functions | |
static void | __quit_handler (int num) |
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) |
void | ast_console_puts (const char *string) |
void | ast_console_puts_mutable (const char *string) |
log the string to the console, and all attached console clients | |
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 *el, 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 *) |
static | AST_LIST_HEAD_STATIC (thread_list, thread_list_t) |
static | AST_LIST_HEAD_STATIC (file_versions, file_version) |
static | AST_LIST_HEAD_STATIC (atexits, ast_atexit) |
static int | ast_makesocket (void) |
int64_t | ast_mark (int i, int startstop) |
AST_MUTEX_DEFINE_STATIC (safe_system_lock) | |
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) |
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) |
int | ast_set_priority (int pri) |
We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy activity on it, this is a good thing. | |
static int | ast_tryconnect (void) |
void | ast_unregister_atexit (void(*func)(void)) |
Unregister a function registered with ast_register_atexit(). | |
void | ast_unregister_file_version (const char *file) |
Unregister a source code file from the core. | |
void | ast_unregister_thread (void *id) |
void | ast_unreplace_sigchld (void) |
Restore the SIGCHLD handler. | |
static void | child_handler (int sig) |
static char * | cli_complete (EditLine *el, int ch) |
static char * | cli_prompt (EditLine *el) |
static char * | complete_show_version_files (const char *line, const char *word, int pos, int state) |
static char * | complete_show_version_files_deprecated (const char *line, const char *word, int pos, int state) |
static void | console_verboser (const char *s) |
static void | consolehandler (char *s) |
static int | fdprint (int fd, const char *s) |
static const char * | fix_header (char *outbuf, int maxout, const char *s, char *cmp) |
static int | handle_abort_halt (int fd, int argc, char *argv[]) |
static int | handle_bang (int fd, int argc, char *argv[]) |
static int | handle_restart_gracefully (int fd, int argc, char *argv[]) |
static int | handle_restart_now (int fd, int argc, char *argv[]) |
static int | handle_restart_when_convenient (int fd, int argc, char *argv[]) |
static int | handle_show_profile (int fd, int argc, char *argv[]) |
static int | handle_show_profile_deprecated (int fd, int argc, char *argv[]) |
static int | handle_show_threads (int fd, int argc, char *argv[]) |
static int | handle_show_version_files (int fd, int argc, char *argv[]) |
static int | handle_show_version_files_deprecated (int fd, int argc, char *argv[]) |
CLI command to list module versions. | |
static int | handle_shutdown_gracefully (int fd, int argc, char *argv[]) |
static int | handle_shutdown_now (int fd, int argc, char *argv[]) |
static int | handle_shutdown_when_convenient (int fd, int argc, char *argv[]) |
static int | handle_version (int fd, int argc, char *argv[]) |
static int | handle_version_deprecated (int fd, int argc, char *argv[]) |
static void | hup_handler (int num) |
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 | null_sig_handler (int signal) |
NULL handler so we can collect the child exit status. | |
static void | quit_handler (int num, int nice, int safeshutdown, int restart) |
static __inline uint64_t | rdtsc (void) |
static int | remoteconsolehandler (char *s) |
static void | set_icon (char *text) |
static void | set_title (char *text) |
Set an X-term or screen title. | |
static int | show_cli_help (void) |
static int | show_license (int fd, int argc, char *argv[]) |
static int | show_version (void) |
static int | show_warranty (int fd, int argc, char *argv[]) |
static void | urg_handler (int num) |
Urgent handler. | |
Variables | |
static char * | _argv [256] |
static char | abort_halt_help [] |
const char * | ast_build_date |
const char * | ast_build_hostname |
const char * | ast_build_kernel |
const char * | ast_build_machine |
const char * | ast_build_os |
const char * | ast_build_user |
char | ast_config_AST_AGI_DIR [PATH_MAX] |
char | ast_config_AST_CONFIG_DIR [PATH_MAX] |
char | ast_config_AST_CONFIG_FILE [PATH_MAX] |
char | ast_config_AST_CTL [PATH_MAX] = "asterisk.ctl" |
char | ast_config_AST_CTL_GROUP [PATH_MAX] = "\0" |
char | ast_config_AST_CTL_OWNER [PATH_MAX] = "\0" |
char | ast_config_AST_CTL_PERMISSIONS [PATH_MAX] |
char | ast_config_AST_DATA_DIR [PATH_MAX] |
char | ast_config_AST_DB [PATH_MAX] |
char | ast_config_AST_KEY_DIR [PATH_MAX] |
char | ast_config_AST_LOG_DIR [PATH_MAX] |
char | ast_config_AST_MODULE_DIR [PATH_MAX] |
char | ast_config_AST_MONITOR_DIR [PATH_MAX] |
char | ast_config_AST_PID [PATH_MAX] |
char | ast_config_AST_RUN_DIR [PATH_MAX] |
char | ast_config_AST_RUN_GROUP [PATH_MAX] |
char | ast_config_AST_RUN_USER [PATH_MAX] |
char | ast_config_AST_SOCKET [PATH_MAX] |
char | ast_config_AST_SPOOL_DIR [PATH_MAX] |
char | ast_config_AST_SYSTEM_NAME [20] = "" |
char | ast_config_AST_VAR_DIR [PATH_MAX] |
static int | ast_consock = -1 |
time_t | ast_lastreloadtime |
pid_t | ast_mainpid |
struct ast_flags | ast_options = { AST_DEFAULT_OPTIONS } |
static int | ast_socket = -1 |
time_t | ast_startuptime |
static char | bang_help [] |
static struct ast_cli_entry | cli_asterisk [] |
static struct ast_cli_entry | cli_clear_profile_deprecated |
static struct ast_cli_entry | cli_show_profile_deprecated |
static struct ast_cli_entry | cli_show_version_deprecated |
static struct ast_cli_entry | cli_show_version_files_deprecated |
struct console | consoles [AST_MAX_CONNECTS] |
static pthread_t | consolethread = AST_PTHREADT_NULL |
char | debug_filename [AST_FILENAME_MAX] = "" |
char | defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE |
static EditLine * | el |
static History * | el_hist |
static const char * | license_lines [] |
static pthread_t | lthread |
int | option_debug |
int | option_maxcalls |
double | option_maxload |
int | option_verbose |
static struct profile_data * | prof_data |
static char | randompool [256] |
char | record_cache_dir [AST_CACHE_DIR_LEN] = AST_TMP_DIR |
static char * | remotehostname |
static char | restart_gracefully_help [] |
static char | restart_now_help [] |
static char | restart_when_convenient_help [] |
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 void * | safe_system_prev_handler |
static char | show_license_help [] |
static char | show_threads_help [] |
static char | show_version_files_help [] |
static char | show_warranty_help [] |
static char | shutdown_gracefully_help [] |
static char | shutdown_now_help [] |
static char | shutdown_when_convenient_help [] |
static int | shuttingdown |
static int | sig_alert_pipe [2] = { -1, -1 } |
struct { | |
unsigned int need_quit:1 | |
unsigned int need_reload:1 | |
} | sig_flags |
static char | version_help [] |
static const char * | warranty_lines [] |
Definition in file asterisk.c.
#define AF_LOCAL AF_UNIX |
Definition at line 133 of file asterisk.c.
Referenced by ast_makesocket(), ast_tryconnect(), listener(), and NBScat_exec().
#define AST_MAX_CONNECTS 128 |
Definition at line 137 of file asterisk.c.
Referenced by 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 FORMAT "%-25.25s %-40.40s\n" |
#define FORMAT "%-25.25s %-40.40s\n" |
Referenced by __iax2_show_peers(), __sip_show_channels(), _sip_show_peers(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), gtalk_show_channels(), handle_show_version_files(), handle_show_version_files_deprecated(), iax2_show_channels(), iax2_show_firmware(), iax2_show_registry(), iax2_show_users(), show_channeltypes(), show_file_formats(), show_file_formats_deprecated(), show_image_formats(), show_image_formats_deprecated(), sip_show_domains(), sip_show_inuse(), sip_show_registry(), sip_show_users(), zap_show_channels(), and zap_show_status().
#define NUM_MSGS 64 |
Definition at line 138 of file asterisk.c.
#define PF_LOCAL PF_UNIX |
#define WELCOME_MESSAGE |
Welcome message when starting a CLI interface.
Definition at line 141 of file asterisk.c.
Referenced by ast_el_read_char(), and main().
static void __quit_handler | ( | int | num | ) | [static] |
Definition at line 1332 of file asterisk.c.
References sig_flags.
Referenced by main().
01333 { 01334 int a = 0; 01335 sig_flags.need_quit = 1; 01336 if (sig_alert_pipe[1] != -1) 01337 write(sig_alert_pipe[1], &a, sizeof(a)); 01338 /* There is no need to restore the signal handler here, since the app 01339 * is going to exit */ 01340 }
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 372 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, profile_entry::scale, and profile_entry::value.
Referenced by extension_match_core().
00373 { 00374 int l = sizeof(struct profile_data); 00375 int n = 10; /* default entries */ 00376 00377 if (prof_data == NULL) { 00378 prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry)); 00379 if (prof_data == NULL) 00380 return -1; 00381 prof_data->entries = 0; 00382 prof_data->max_size = n; 00383 } 00384 if (prof_data->entries >= prof_data->max_size) { 00385 void *p; 00386 n = prof_data->max_size + 20; 00387 p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry)); 00388 if (p == NULL) 00389 return -1; 00390 prof_data = p; 00391 prof_data->max_size = n; 00392 } 00393 n = prof_data->entries++; 00394 prof_data->e[n].name = ast_strdup(name); 00395 prof_data->e[n].value = 0; 00396 prof_data->e[n].events = 0; 00397 prof_data->e[n].mark = 0; 00398 prof_data->e[n].scale = scale; 00399 return n; 00400 }
static int ast_all_zeros | ( | char * | s | ) | [static] |
Definition at line 1374 of file asterisk.c.
Referenced by ast_el_read_history(), consolehandler(), and remoteconsolehandler().
01375 { 01376 while (*s) { 01377 if (*s > 32) 01378 return 0; 01379 s++; 01380 } 01381 return 1; 01382 }
static int ast_cli_display_match_list | ( | char ** | matches, | |
int | len, | |||
int | max | |||
) | [static] |
Definition at line 1996 of file asterisk.c.
References ast_el_sort_compare(), ast_get_termcols(), and free.
Referenced by cli_complete().
01997 { 01998 int i, idx, limit, count; 01999 int screenwidth = 0; 02000 int numoutput = 0, numoutputline = 0; 02001 02002 screenwidth = ast_get_termcols(STDOUT_FILENO); 02003 02004 /* find out how many entries can be put on one line, with two spaces between strings */ 02005 limit = screenwidth / (max + 2); 02006 if (limit == 0) 02007 limit = 1; 02008 02009 /* how many lines of output */ 02010 count = len / limit; 02011 if (count * limit < len) 02012 count++; 02013 02014 idx = 1; 02015 02016 qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare); 02017 02018 for (; count > 0; count--) { 02019 numoutputline = 0; 02020 for (i=0; i < limit && matches[idx]; i++, idx++) { 02021 02022 /* Don't print dupes */ 02023 if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) { 02024 i--; 02025 free(matches[idx]); 02026 matches[idx] = NULL; 02027 continue; 02028 } 02029 02030 numoutput++; 02031 numoutputline++; 02032 fprintf(stdout, "%-*s ", max, matches[idx]); 02033 free(matches[idx]); 02034 matches[idx] = NULL; 02035 } 02036 if (numoutputline > 0) 02037 fprintf(stdout, "\n"); 02038 } 02039 02040 return numoutput; 02041 }
void ast_console_puts | ( | const char * | string | ) |
write the string to the console, and all attached console clients
Definition at line 897 of file asterisk.c.
References ast_network_puts().
Referenced by chan_misdn_log().
00898 { 00899 fputs(string, stdout); 00900 fflush(stdout); 00901 ast_network_puts(string); 00902 }
void ast_console_puts_mutable | ( | const char * | string | ) |
log the string to the console, and all attached console clients
Definition at line 874 of file asterisk.c.
References ast_network_puts_mutable().
Referenced by ast_log().
00875 { 00876 fputs(string, stdout); 00877 fflush(stdout); 00878 ast_network_puts_mutable(string); 00879 }
void ast_console_toggle_mute | ( | int | fd, | |
int | silent | |||
) |
mute or unmute a console from logging
Definition at line 837 of file asterisk.c.
References ast_cli(), AST_MAX_CONNECTS, consoles, and console::mute.
Referenced by handle_logger_mute().
00837 { 00838 int x; 00839 for (x = 0;x < AST_MAX_CONNECTS; x++) { 00840 if (fd == consoles[x].fd) { 00841 if (consoles[x].mute) { 00842 consoles[x].mute = 0; 00843 if (!silent) 00844 ast_cli(fd, "Console is not muted anymore.\n"); 00845 } else { 00846 consoles[x].mute = 1; 00847 if (!silent) 00848 ast_cli(fd, "Console is muted.\n"); 00849 } 00850 return; 00851 } 00852 } 00853 ast_cli(fd, "Couldn't find remote console.\n"); 00854 }
static int ast_el_add_history | ( | char * | buf | ) | [static] |
Definition at line 2190 of file asterisk.c.
References ast_el_initialize().
Referenced by ast_el_read_history(), consolehandler(), and remoteconsolehandler().
02191 { 02192 HistEvent ev; 02193 02194 if (el_hist == NULL || el == NULL) 02195 ast_el_initialize(); 02196 if (strlen(buf) > 256) 02197 return 0; 02198 return (history(el_hist, &ev, H_ENTER, buf)); 02199 }
static int ast_el_initialize | ( | void | ) | [static] |
Definition at line 2155 of file asterisk.c.
References cli_complete(), and cli_prompt().
Referenced by ast_el_add_history(), ast_el_read_history(), ast_el_write_history(), ast_remotecontrol(), and main().
02156 { 02157 HistEvent ev; 02158 char *editor = getenv("AST_EDITOR"); 02159 02160 if (el != NULL) 02161 el_end(el); 02162 if (el_hist != NULL) 02163 history_end(el_hist); 02164 02165 el = el_init("asterisk", stdin, stdout, stderr); 02166 el_set(el, EL_PROMPT, cli_prompt); 02167 02168 el_set(el, EL_EDITMODE, 1); 02169 el_set(el, EL_EDITOR, editor ? editor : "emacs"); 02170 el_hist = history_init(); 02171 if (!el || !el_hist) 02172 return -1; 02173 02174 /* setup history with 100 entries */ 02175 history(el_hist, &ev, H_SETSIZE, 100); 02176 02177 el_set(el, EL_HIST, history, el_hist); 02178 02179 el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete); 02180 /* Bind <tab> to command completion */ 02181 el_set(el, EL_BIND, "^I", "ed-complete", NULL); 02182 /* Bind ? to command completion */ 02183 el_set(el, EL_BIND, "?", "ed-complete", NULL); 02184 /* Bind ^D to redisplay */ 02185 el_set(el, EL_BIND, "^D", "ed-redisplay", NULL); 02186 02187 return 0; 02188 }
static int ast_el_read_char | ( | EditLine * | el, | |
char * | cp | |||
) | [static] |
Definition at line 1720 of file asterisk.c.
References ast_log(), ast_opt_exec, ast_opt_mute, ast_opt_reconnect, ast_tryconnect(), errno, pollfd::events, pollfd::fd, fdprint(), LOG_ERROR, poll(), POLLIN, quit_handler(), pollfd::revents, term_quit(), and WELCOME_MESSAGE.
Referenced by ast_remotecontrol().
01721 { 01722 int num_read = 0; 01723 int lastpos = 0; 01724 struct pollfd fds[2]; 01725 int res; 01726 int max; 01727 char buf[512]; 01728 01729 for (;;) { 01730 max = 1; 01731 fds[0].fd = ast_consock; 01732 fds[0].events = POLLIN; 01733 if (!ast_opt_exec) { 01734 fds[1].fd = STDIN_FILENO; 01735 fds[1].events = POLLIN; 01736 max++; 01737 } 01738 res = poll(fds, max, -1); 01739 if (res < 0) { 01740 if (errno == EINTR) 01741 continue; 01742 ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno)); 01743 break; 01744 } 01745 01746 if (!ast_opt_exec && fds[1].revents) { 01747 num_read = read(STDIN_FILENO, cp, 1); 01748 if (num_read < 1) { 01749 break; 01750 } else 01751 return (num_read); 01752 } 01753 if (fds[0].revents) { 01754 res = read(ast_consock, buf, sizeof(buf) - 1); 01755 /* if the remote side disappears exit */ 01756 if (res < 1) { 01757 fprintf(stderr, "\nDisconnected from Asterisk server\n"); 01758 if (!ast_opt_reconnect) { 01759 quit_handler(0, 0, 0, 0); 01760 } else { 01761 int tries; 01762 int reconnects_per_second = 20; 01763 fprintf(stderr, "Attempting to reconnect for 30 seconds\n"); 01764 for (tries=0; tries < 30 * reconnects_per_second; tries++) { 01765 if (ast_tryconnect()) { 01766 fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries); 01767 printf(term_quit()); 01768 WELCOME_MESSAGE; 01769 if (!ast_opt_mute) 01770 fdprint(ast_consock, "logger mute silent"); 01771 else 01772 printf("log and verbose output currently muted ('logger mute' to unmute)\n"); 01773 break; 01774 } else { 01775 usleep(1000000 / reconnects_per_second); 01776 } 01777 } 01778 if (tries >= 30 * reconnects_per_second) { 01779 fprintf(stderr, "Failed to reconnect for 30 seconds. Quitting.\n"); 01780 quit_handler(0, 0, 0, 0); 01781 } 01782 } 01783 } 01784 01785 buf[res] = '\0'; 01786 01787 if (!ast_opt_exec && !lastpos) 01788 write(STDOUT_FILENO, "\r", 1); 01789 write(STDOUT_FILENO, buf, res); 01790 if ((buf[res-1] == '\n') || (buf[res-2] == '\n')) { 01791 *cp = CC_REFRESH; 01792 return(1); 01793 } else { 01794 lastpos = 1; 01795 } 01796 } 01797 } 01798 01799 *cp = '\0'; 01800 return (0); 01801 }
static int ast_el_read_history | ( | char * | filename | ) | [static] |
Definition at line 2211 of file asterisk.c.
References ast_all_zeros(), ast_el_add_history(), ast_el_initialize(), and f.
Referenced by ast_remotecontrol(), and main().
02212 { 02213 char buf[256]; 02214 FILE *f; 02215 int ret = -1; 02216 02217 if (el_hist == NULL || el == NULL) 02218 ast_el_initialize(); 02219 02220 if ((f = fopen(filename, "r")) == NULL) 02221 return ret; 02222 02223 while (!feof(f)) { 02224 fgets(buf, sizeof(buf), f); 02225 if (!strcmp(buf, "_HiStOrY_V2_\n")) 02226 continue; 02227 if (ast_all_zeros(buf)) 02228 continue; 02229 if ((ret = ast_el_add_history(buf)) == -1) 02230 break; 02231 } 02232 fclose(f); 02233 02234 return ret; 02235 }
static int ast_el_sort_compare | ( | const void * | i1, | |
const void * | i2 | |||
) | [static] |
Definition at line 1986 of file asterisk.c.
Referenced by ast_cli_display_match_list().
01987 { 01988 char *s1, *s2; 01989 01990 s1 = ((char **)i1)[0]; 01991 s2 = ((char **)i2)[0]; 01992 01993 return strcasecmp(s1, s2); 01994 }
static char** ast_el_strtoarr | ( | char * | buf | ) | [static] |
Definition at line 1951 of file asterisk.c.
References AST_CLI_COMPLETE_EOF, ast_realloc, strdup, and strsep().
Referenced by cli_complete().
01952 { 01953 char **match_list = NULL, *retstr; 01954 size_t match_list_len; 01955 int matches = 0; 01956 01957 match_list_len = 1; 01958 while ( (retstr = strsep(&buf, " ")) != NULL) { 01959 01960 if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) 01961 break; 01962 if (matches + 1 >= match_list_len) { 01963 match_list_len <<= 1; 01964 if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(char *)))) { 01965 /* TODO: Handle memory allocation failure */ 01966 } 01967 } 01968 01969 match_list[matches++] = strdup(retstr); 01970 } 01971 01972 if (!match_list) 01973 return (char **) NULL; 01974 01975 if (matches >= match_list_len) { 01976 if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) { 01977 /* TODO: Handle memory allocation failure */ 01978 } 01979 } 01980 01981 match_list[matches] = (char *) NULL; 01982 01983 return match_list; 01984 }
static int ast_el_write_history | ( | char * | filename | ) | [static] |
Definition at line 2201 of file asterisk.c.
References ast_el_initialize().
Referenced by quit_handler().
02202 { 02203 HistEvent ev; 02204 02205 if (el_hist == NULL || el == NULL) 02206 ast_el_initialize(); 02207 02208 return (history(el_hist, &ev, H_SAVE, filename)); 02209 }
static AST_LIST_HEAD_STATIC | ( | thread_list | , | |
thread_list_t | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | file_versions | , | |
file_version | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | atexits | , | |
ast_atexit | ||||
) | [static] |
static int ast_makesocket | ( | void | ) | [static] |
Definition at line 1032 of file asterisk.c.
References AF_LOCAL, ast_log(), AST_MAX_CONNECTS, ast_pthread_create_background, ast_register_verbose(), ast_strlen_zero(), consoles, errno, group, listener(), LOG_WARNING, network_verboser(), and PF_LOCAL.
Referenced by main().
01033 { 01034 struct sockaddr_un sunaddr; 01035 int res; 01036 int x; 01037 uid_t uid = -1; 01038 gid_t gid = -1; 01039 01040 for (x = 0; x < AST_MAX_CONNECTS; x++) 01041 consoles[x].fd = -1; 01042 unlink(ast_config_AST_SOCKET); 01043 ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0); 01044 if (ast_socket < 0) { 01045 ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno)); 01046 return -1; 01047 } 01048 memset(&sunaddr, 0, sizeof(sunaddr)); 01049 sunaddr.sun_family = AF_LOCAL; 01050 ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path)); 01051 res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr)); 01052 if (res) { 01053 ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01054 close(ast_socket); 01055 ast_socket = -1; 01056 return -1; 01057 } 01058 res = listen(ast_socket, 2); 01059 if (res < 0) { 01060 ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01061 close(ast_socket); 01062 ast_socket = -1; 01063 return -1; 01064 } 01065 ast_register_verbose(network_verboser); 01066 ast_pthread_create_background(<hread, NULL, listener, NULL); 01067 01068 if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) { 01069 struct passwd *pw; 01070 if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL) { 01071 ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER); 01072 } else { 01073 uid = pw->pw_uid; 01074 } 01075 } 01076 01077 if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) { 01078 struct group *grp; 01079 if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL) { 01080 ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP); 01081 } else { 01082 gid = grp->gr_gid; 01083 } 01084 } 01085 01086 if (chown(ast_config_AST_SOCKET, uid, gid) < 0) 01087 ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01088 01089 if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) { 01090 int p1; 01091 mode_t p; 01092 sscanf(ast_config_AST_CTL_PERMISSIONS, "%o", &p1); 01093 p = p1; 01094 if ((chmod(ast_config_AST_SOCKET, p)) < 0) 01095 ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01096 } 01097 01098 return 0; 01099 }
int64_t ast_mark | ( | int | i, | |
int | startstop | |||
) |
Definition at line 434 of file asterisk.c.
References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, rdtsc(), profile_entry::scale, and profile_entry::value.
Referenced by extension_match_core().
00435 { 00436 if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */ 00437 return 0; 00438 if (startstop == 1) 00439 prof_data->e[i].mark = rdtsc(); 00440 else { 00441 prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark); 00442 if (prof_data->e[i].scale > 1) 00443 prof_data->e[i].mark /= prof_data->e[i].scale; 00444 prof_data->e[i].value += prof_data->e[i].mark; 00445 prof_data->e[i].events++; 00446 } 00447 return prof_data->e[i].mark; 00448 }
AST_MUTEX_DEFINE_STATIC | ( | safe_system_lock | ) |
static void ast_network_puts | ( | const char * | string | ) | [static] |
write the string to all attached console clients
Definition at line 884 of file asterisk.c.
References AST_MAX_CONNECTS, consoles, and fdprint().
Referenced by ast_console_puts().
00885 { 00886 int x; 00887 for (x=0; x < AST_MAX_CONNECTS; x++) { 00888 if (consoles[x].fd > -1) 00889 fdprint(consoles[x].p[1], string); 00890 } 00891 }
static void ast_network_puts_mutable | ( | const char * | string | ) | [static] |
log the string to all attached console clients
Definition at line 859 of file asterisk.c.
References AST_MAX_CONNECTS, consoles, and fdprint().
Referenced by ast_console_puts_mutable(), and network_verboser().
00860 { 00861 int x; 00862 for (x = 0;x < AST_MAX_CONNECTS; x++) { 00863 if (consoles[x].mute) 00864 continue; 00865 if (consoles[x].fd > -1) 00866 fdprint(consoles[x].p[1], string); 00867 } 00868 }
int64_t ast_profile | ( | int | i, | |
int64_t | delta | |||
) |
Definition at line 402 of file asterisk.c.
References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::scale, and profile_entry::value.
00403 { 00404 if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */ 00405 return 0; 00406 if (prof_data->e[i].scale > 1) 00407 delta /= prof_data->e[i].scale; 00408 prof_data->e[i].value += delta; 00409 prof_data->e[i].events++; 00410 return prof_data->e[i].value; 00411 }
static void ast_readconfig | ( | void | ) | [static] |
Definition at line 2362 of file asterisk.c.
References AST_AGI_DIR, AST_CACHE_DIR_LEN, ast_config_destroy(), AST_CONFIG_DIR, AST_CONFIG_FILE, ast_config_load(), AST_DATA_DIR, AST_DB, AST_KEY_DIR, ast_language_is_prefix, ast_log(), AST_LOG_DIR, AST_MODULE_DIR, 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_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, 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_PID, AST_RUN_DIR, ast_set2_flag, AST_SOCKET, AST_SPOOL_DIR, AST_SYSTEM_NAME, ast_true(), AST_VAR_DIR, ast_variable_browse(), config, getloadavg(), LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by main().
02363 { 02364 struct ast_config *cfg; 02365 struct ast_variable *v; 02366 char *config = AST_CONFIG_FILE; 02367 02368 if (ast_opt_override_config) { 02369 cfg = ast_config_load(ast_config_AST_CONFIG_FILE); 02370 if (!cfg) 02371 ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE); 02372 } else { 02373 cfg = ast_config_load(config); 02374 } 02375 02376 /* init with buildtime config */ 02377 ast_copy_string(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR, sizeof(ast_config_AST_CONFIG_DIR)); 02378 ast_copy_string(ast_config_AST_SPOOL_DIR, AST_SPOOL_DIR, sizeof(ast_config_AST_SPOOL_DIR)); 02379 ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_MODULE_DIR)); 02380 snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR); 02381 ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR)); 02382 ast_copy_string(ast_config_AST_DATA_DIR, AST_DATA_DIR, sizeof(ast_config_AST_DATA_DIR)); 02383 ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR)); 02384 ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR)); 02385 ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB)); 02386 ast_copy_string(ast_config_AST_KEY_DIR, AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR)); 02387 ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID)); 02388 ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET)); 02389 ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR)); 02390 ast_copy_string(ast_config_AST_SYSTEM_NAME, AST_SYSTEM_NAME, sizeof(ast_config_AST_SYSTEM_NAME)); 02391 02392 /* no asterisk.conf? no problem, use buildtime config! */ 02393 if (!cfg) { 02394 return; 02395 } 02396 02397 for (v = ast_variable_browse(cfg, "files"); v; v = v->next) { 02398 if (!strcasecmp(v->name, "astctlpermissions")) { 02399 ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS)); 02400 } else if (!strcasecmp(v->name, "astctlowner")) { 02401 ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER)); 02402 } else if (!strcasecmp(v->name, "astctlgroup")) { 02403 ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP)); 02404 } else if (!strcasecmp(v->name, "astctl")) { 02405 ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL)); 02406 } 02407 } 02408 02409 for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) { 02410 if (!strcasecmp(v->name, "astetcdir")) { 02411 ast_copy_string(ast_config_AST_CONFIG_DIR, v->value, sizeof(ast_config_AST_CONFIG_DIR)); 02412 } else if (!strcasecmp(v->name, "astspooldir")) { 02413 ast_copy_string(ast_config_AST_SPOOL_DIR, v->value, sizeof(ast_config_AST_SPOOL_DIR)); 02414 snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", v->value); 02415 } else if (!strcasecmp(v->name, "astvarlibdir")) { 02416 ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR)); 02417 snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/astdb", v->value); 02418 } else if (!strcasecmp(v->name, "astdatadir")) { 02419 ast_copy_string(ast_config_AST_DATA_DIR, v->value, sizeof(ast_config_AST_DATA_DIR)); 02420 snprintf(ast_config_AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR), "%s/keys", v->value); 02421 } else if (!strcasecmp(v->name, "astlogdir")) { 02422 ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR)); 02423 } else if (!strcasecmp(v->name, "astagidir")) { 02424 ast_copy_string(ast_config_AST_AGI_DIR, v->value, sizeof(ast_config_AST_AGI_DIR)); 02425 } else if (!strcasecmp(v->name, "astrundir")) { 02426 snprintf(ast_config_AST_PID, sizeof(ast_config_AST_PID), "%s/%s", v->value, "asterisk.pid"); 02427 snprintf(ast_config_AST_SOCKET, sizeof(ast_config_AST_SOCKET), "%s/%s", v->value, ast_config_AST_CTL); 02428 ast_copy_string(ast_config_AST_RUN_DIR, v->value, sizeof(ast_config_AST_RUN_DIR)); 02429 } else if (!strcasecmp(v->name, "astmoddir")) { 02430 ast_copy_string(ast_config_AST_MODULE_DIR, v->value, sizeof(ast_config_AST_MODULE_DIR)); 02431 } 02432 } 02433 02434 for (v = ast_variable_browse(cfg, "options"); v; v = v->next) { 02435 /* verbose level (-v at startup) */ 02436 if (!strcasecmp(v->name, "verbose")) { 02437 option_verbose = atoi(v->value); 02438 /* whether or not to force timestamping in CLI verbose output. (-T at startup) */ 02439 } else if (!strcasecmp(v->name, "timestamp")) { 02440 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP); 02441 /* whether or not to support #exec in config files */ 02442 } else if (!strcasecmp(v->name, "execincludes")) { 02443 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES); 02444 /* debug level (-d at startup) */ 02445 } else if (!strcasecmp(v->name, "debug")) { 02446 option_debug = 0; 02447 if (sscanf(v->value, "%d", &option_debug) != 1) { 02448 option_debug = ast_true(v->value); 02449 } 02450 #if HAVE_WORKING_FORK 02451 /* Disable forking (-f at startup) */ 02452 } else if (!strcasecmp(v->name, "nofork")) { 02453 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK); 02454 /* Always fork, even if verbose or debug are enabled (-F at startup) */ 02455 } else if (!strcasecmp(v->name, "alwaysfork")) { 02456 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK); 02457 #endif 02458 /* Run quietly (-q at startup ) */ 02459 } else if (!strcasecmp(v->name, "quiet")) { 02460 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET); 02461 /* Run as console (-c at startup, implies nofork) */ 02462 } else if (!strcasecmp(v->name, "console")) { 02463 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CONSOLE); 02464 /* Run with high priority if the O/S permits (-p at startup) */ 02465 } else if (!strcasecmp(v->name, "highpriority")) { 02466 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY); 02467 /* Initialize RSA auth keys (IAX2) (-i at startup) */ 02468 } else if (!strcasecmp(v->name, "initcrypto")) { 02469 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS); 02470 /* Disable ANSI colors for console (-c at startup) */ 02471 } else if (!strcasecmp(v->name, "nocolor")) { 02472 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR); 02473 /* Disable some usage warnings for picky people :p */ 02474 } else if (!strcasecmp(v->name, "dontwarn")) { 02475 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN); 02476 /* Dump core in case of crash (-g) */ 02477 } else if (!strcasecmp(v->name, "dumpcore")) { 02478 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE); 02479 /* Cache recorded sound files to another directory during recording */ 02480 } else if (!strcasecmp(v->name, "cache_record_files")) { 02481 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES); 02482 /* Specify cache directory */ 02483 } else if (!strcasecmp(v->name, "record_cache_dir")) { 02484 ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN); 02485 /* Build transcode paths via SLINEAR, instead of directly */ 02486 } else if (!strcasecmp(v->name, "transcode_via_sln")) { 02487 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN); 02488 /* Transmit SLINEAR silence while a channel is being recorded */ 02489 } else if (!strcasecmp(v->name, "transmit_silence_during_record")) { 02490 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE); 02491 /* Enable internal timing */ 02492 } else if (!strcasecmp(v->name, "internal_timing")) { 02493 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING); 02494 } else if (!strcasecmp(v->name, "maxcalls")) { 02495 if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) { 02496 option_maxcalls = 0; 02497 } 02498 } else if (!strcasecmp(v->name, "maxload")) { 02499 double test[1]; 02500 02501 if (getloadavg(test, 1) == -1) { 02502 ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n"); 02503 option_maxload = 0.0; 02504 } else if ((sscanf(v->value, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) { 02505 option_maxload = 0.0; 02506 } 02507 /* What user to run as */ 02508 } else if (!strcasecmp(v->name, "runuser")) { 02509 ast_copy_string(ast_config_AST_RUN_USER, v->value, sizeof(ast_config_AST_RUN_USER)); 02510 /* What group to run as */ 02511 } else if (!strcasecmp(v->name, "rungroup")) { 02512 ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP)); 02513 } else if (!strcasecmp(v->name, "systemname")) { 02514 ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME)); 02515 } else if (!strcasecmp(v->name, "uniquename")) { 02516 ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME)); 02517 } else if (!strcasecmp(v->name, "languageprefix")) { 02518 ast_language_is_prefix = ast_true(v->value); 02519 } 02520 } 02521 ast_config_destroy(cfg); 02522 }
int ast_register_atexit | ( | void(*)(void) | func | ) |
Register a function to be executed before Asterisk exits.
func | The callback function to use. |
Definition at line 702 of file asterisk.c.
References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_unregister_atexit(), func, and ast_atexit::func.
Referenced by do_reload(), and load_module().
00703 { 00704 struct ast_atexit *ae; 00705 00706 if (!(ae = ast_calloc(1, sizeof(*ae)))) 00707 return -1; 00708 00709 ae->func = func; 00710 00711 ast_unregister_atexit(func); 00712 00713 AST_LIST_LOCK(&atexits); 00714 AST_LIST_INSERT_HEAD(&atexits, ae, list); 00715 AST_LIST_UNLOCK(&atexits); 00716 00717 return 0; 00718 }
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 CVS revision keyword string) |
Definition at line 256 of file asterisk.c.
References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_strdupa, and ast_strip_quoted().
00257 { 00258 struct file_version *new; 00259 char *work; 00260 size_t version_length; 00261 00262 work = ast_strdupa(version); 00263 work = ast_strip(ast_strip_quoted(work, "$", "$")); 00264 version_length = strlen(work) + 1; 00265 00266 if (!(new = ast_calloc(1, sizeof(*new) + version_length))) 00267 return; 00268 00269 new->file = file; 00270 new->version = (char *) new + sizeof(*new); 00271 memcpy(new->version, work, version_length); 00272 AST_LIST_LOCK(&file_versions); 00273 AST_LIST_INSERT_HEAD(&file_versions, new, list); 00274 AST_LIST_UNLOCK(&file_versions); 00275 }
void ast_register_thread | ( | char * | name | ) |
Definition at line 306 of file asterisk.c.
References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, and AST_LIST_UNLOCK.
Referenced by dummy_start().
00307 { 00308 struct thread_list_t *new = ast_calloc(1, sizeof(*new)); 00309 00310 if (!new) 00311 return; 00312 new->id = pthread_self(); 00313 new->name = name; /* steal the allocated memory for the thread name */ 00314 AST_LIST_LOCK(&thread_list); 00315 AST_LIST_INSERT_HEAD(&thread_list, new, list); 00316 AST_LIST_UNLOCK(&thread_list); 00317 }
static void ast_remotecontrol | ( | char * | data | ) | [static] |
Definition at line 2237 of file asterisk.c.
References ast_el_initialize(), ast_el_read_char(), ast_el_read_history(), ast_log(), ast_opt_exec, ast_opt_mute, ast_strlen_zero(), ast_verbose(), errno, pollfd::events, pollfd::fd, fdprint(), hostname, LOG_WARNING, poll(), POLLIN, remoteconsolehandler(), pollfd::revents, and strsep().
Referenced by main().
02238 { 02239 char buf[80]; 02240 int res; 02241 char filename[80] = ""; 02242 char *hostname; 02243 char *cpid; 02244 char *version; 02245 int pid; 02246 char tmp[80]; 02247 char *stringp = NULL; 02248 02249 char *ebuf; 02250 int num = 0; 02251 02252 read(ast_consock, buf, sizeof(buf)); 02253 if (data) 02254 write(ast_consock, data, strlen(data) + 1); 02255 stringp = buf; 02256 hostname = strsep(&stringp, "/"); 02257 cpid = strsep(&stringp, "/"); 02258 version = strsep(&stringp, "\n"); 02259 if (!version) 02260 version = "<Version Unknown>"; 02261 stringp = hostname; 02262 strsep(&stringp, "."); 02263 if (cpid) 02264 pid = atoi(cpid); 02265 else 02266 pid = -1; 02267 if (!data) { 02268 snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose); 02269 fdprint(ast_consock, tmp); 02270 snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug); 02271 fdprint(ast_consock, tmp); 02272 if (!ast_opt_mute) 02273 fdprint(ast_consock, "logger mute silent"); 02274 else 02275 printf("log and verbose output currently muted ('logger mute' to unmute)\n"); 02276 } 02277 ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid); 02278 remotehostname = hostname; 02279 if (getenv("HOME")) 02280 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); 02281 if (el_hist == NULL || el == NULL) 02282 ast_el_initialize(); 02283 02284 el_set(el, EL_GETCFN, ast_el_read_char); 02285 02286 if (!ast_strlen_zero(filename)) 02287 ast_el_read_history(filename); 02288 02289 if (ast_opt_exec && data) { /* hack to print output then exit if asterisk -rx is used */ 02290 char tempchar; 02291 struct pollfd fds; 02292 fds.fd = ast_consock; 02293 fds.events = POLLIN; 02294 fds.revents = 0; 02295 while (poll(&fds, 1, 100) > 0) 02296 ast_el_read_char(el, &tempchar); 02297 return; 02298 } 02299 for (;;) { 02300 ebuf = (char *)el_gets(el, &num); 02301 02302 if (!ebuf && write(1, "", 1) < 0) 02303 break; 02304 02305 if (!ast_strlen_zero(ebuf)) { 02306 if (ebuf[strlen(ebuf)-1] == '\n') 02307 ebuf[strlen(ebuf)-1] = '\0'; 02308 if (!remoteconsolehandler(ebuf)) { 02309 res = write(ast_consock, ebuf, strlen(ebuf) + 1); 02310 if (res < 1) { 02311 ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno)); 02312 break; 02313 } 02314 } 02315 } 02316 } 02317 printf("\nDisconnected from Asterisk server\n"); 02318 }
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 temporaraly replaced.
Code that executes this function *must* call ast_unreplace_sigchld() after it is finished doing the wait*().
Definition at line 755 of file asterisk.c.
References ast_mutex_lock(), ast_mutex_unlock(), and null_sig_handler().
Referenced by ast_safe_system().
00756 { 00757 unsigned int level; 00758 00759 ast_mutex_lock(&safe_system_lock); 00760 level = safe_system_level++; 00761 00762 /* only replace the handler if it has not already been done */ 00763 if (level == 0) 00764 safe_system_prev_handler = signal(SIGCHLD, null_sig_handler); 00765 00766 ast_mutex_unlock(&safe_system_lock); 00767 }
static void ast_run_atexits | ( | void | ) | [static] |
Definition at line 1211 of file asterisk.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_atexit::func.
Referenced by quit_handler().
01212 { 01213 struct ast_atexit *ae; 01214 AST_LIST_LOCK(&atexits); 01215 AST_LIST_TRAVERSE(&atexits, ae, list) { 01216 if (ae->func) 01217 ae->func(); 01218 } 01219 AST_LIST_UNLOCK(&atexits); 01220 }
int ast_safe_system | ( | const char * | s | ) |
Safely spawn an external program while closing file descriptors
Definition at line 783 of file asterisk.c.
References ast_log(), ast_opt_high_priority, ast_replace_sigchld(), ast_set_priority(), ast_unreplace_sigchld(), errno, LOG_WARNING, WEXITSTATUS, and WIFEXITED.
Referenced by alarmreceiver_exec(), ast_closestream(), ast_monitor_change_fname(), ast_monitor_start(), ast_monitor_stop(), consolehandler(), make_email_file(), mixmonitor_thread(), process_text_line(), remoteconsolehandler(), run_externnotify(), sendmail(), sendpage(), system_exec_helper(), and vm_change_password_shell().
00784 { 00785 pid_t pid; 00786 #ifdef HAVE_WORKING_FORK 00787 int x; 00788 #endif 00789 int res; 00790 struct rusage rusage; 00791 int status; 00792 00793 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK) 00794 ast_replace_sigchld(); 00795 00796 #ifdef HAVE_WORKING_FORK 00797 pid = fork(); 00798 #else 00799 pid = vfork(); 00800 #endif 00801 00802 if (pid == 0) { 00803 #ifdef HAVE_WORKING_FORK 00804 if (ast_opt_high_priority) 00805 ast_set_priority(0); 00806 /* Close file descriptors and launch system command */ 00807 for (x = STDERR_FILENO + 1; x < 4096; x++) 00808 close(x); 00809 #endif 00810 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL); 00811 _exit(1); 00812 } else if (pid > 0) { 00813 for(;;) { 00814 res = wait4(pid, &status, 0, &rusage); 00815 if (res > -1) { 00816 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1; 00817 break; 00818 } else if (errno != EINTR) 00819 break; 00820 } 00821 } else { 00822 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno)); 00823 res = -1; 00824 } 00825 00826 ast_unreplace_sigchld(); 00827 #else 00828 res = -1; 00829 #endif 00830 00831 return res; 00832 }
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 1177 of file asterisk.c.
References ast_log(), ast_verbose(), LOG_WARNING, sched_setscheduler, and setpriority.
Referenced by app_exec(), ast_safe_system(), icesencode(), launch_script(), main(), mp3play(), NBScatplay(), send_waveform_to_fd(), spawn_mp3(), and spawn_ras().
01178 { 01179 struct sched_param sched; 01180 memset(&sched, 0, sizeof(sched)); 01181 #ifdef __linux__ 01182 if (pri) { 01183 sched.sched_priority = 10; 01184 if (sched_setscheduler(0, SCHED_RR, &sched)) { 01185 ast_log(LOG_WARNING, "Unable to set high priority\n"); 01186 return -1; 01187 } else 01188 if (option_verbose) 01189 ast_verbose("Set to realtime thread\n"); 01190 } else { 01191 sched.sched_priority = 0; 01192 /* According to the manpage, these parameters can never fail. */ 01193 sched_setscheduler(0, SCHED_OTHER, &sched); 01194 } 01195 #else 01196 if (pri) { 01197 if (setpriority(PRIO_PROCESS, 0, -10) == -1) { 01198 ast_log(LOG_WARNING, "Unable to set high priority\n"); 01199 return -1; 01200 } else 01201 if (option_verbose) 01202 ast_verbose("Set to high priority\n"); 01203 } else { 01204 /* According to the manpage, these parameters can never fail. */ 01205 setpriority(PRIO_PROCESS, 0, 0); 01206 } 01207 #endif 01208 return 0; 01209 }
static int ast_tryconnect | ( | void | ) | [static] |
Definition at line 1101 of file asterisk.c.
References AF_LOCAL, ast_log(), errno, LOG_WARNING, and PF_LOCAL.
Referenced by ast_el_read_char(), and main().
01102 { 01103 struct sockaddr_un sunaddr; 01104 int res; 01105 ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0); 01106 if (ast_consock < 0) { 01107 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 01108 return 0; 01109 } 01110 memset(&sunaddr, 0, sizeof(sunaddr)); 01111 sunaddr.sun_family = AF_LOCAL; 01112 ast_copy_string(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path)); 01113 res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)); 01114 if (res) { 01115 close(ast_consock); 01116 ast_consock = -1; 01117 return 0; 01118 } else 01119 return 1; 01120 }
void ast_unregister_atexit | ( | void(*)(void) | func | ) |
Unregister a function registered with ast_register_atexit().
func | The callback function to unregister. |
Definition at line 720 of file asterisk.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, free, func, and ast_atexit::func.
Referenced by ast_register_atexit(), and do_reload().
00721 { 00722 struct ast_atexit *ae = NULL; 00723 00724 AST_LIST_LOCK(&atexits); 00725 AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) { 00726 if (ae->func == func) { 00727 AST_LIST_REMOVE_CURRENT(&atexits, list); 00728 break; 00729 } 00730 } 00731 AST_LIST_TRAVERSE_SAFE_END 00732 AST_LIST_UNLOCK(&atexits); 00733 00734 if (ae) 00735 free(ae); 00736 }
void ast_unregister_file_version | ( | const char * | file | ) |
Unregister a source code file from the core.
file | the source file name |
Definition at line 277 of file asterisk.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, and free.
00278 { 00279 struct file_version *find; 00280 00281 AST_LIST_LOCK(&file_versions); 00282 AST_LIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) { 00283 if (!strcasecmp(find->file, file)) { 00284 AST_LIST_REMOVE_CURRENT(&file_versions, list); 00285 break; 00286 } 00287 } 00288 AST_LIST_TRAVERSE_SAFE_END; 00289 AST_LIST_UNLOCK(&file_versions); 00290 if (find) 00291 free(find); 00292 }
void ast_unregister_thread | ( | void * | id | ) |
Definition at line 319 of file asterisk.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, and free.
Referenced by dummy_start().
00320 { 00321 struct thread_list_t *x; 00322 00323 AST_LIST_LOCK(&thread_list); 00324 AST_LIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) { 00325 if ((void *) x->id == id) { 00326 AST_LIST_REMOVE_CURRENT(&thread_list, list); 00327 break; 00328 } 00329 } 00330 AST_LIST_TRAVERSE_SAFE_END; 00331 AST_LIST_UNLOCK(&thread_list); 00332 if (x) { 00333 free(x->name); 00334 free(x); 00335 } 00336 }
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 769 of file asterisk.c.
References ast_mutex_lock(), and ast_mutex_unlock().
Referenced by agi_exec_full(), and ast_safe_system().
00770 { 00771 unsigned int level; 00772 00773 ast_mutex_lock(&safe_system_lock); 00774 level = --safe_system_level; 00775 00776 /* only restore the handler if we are the last one */ 00777 if (level == 0) 00778 signal(SIGCHLD, safe_system_prev_handler); 00779 00780 ast_mutex_unlock(&safe_system_lock); 00781 }
static void child_handler | ( | int | sig | ) | [static] |
Definition at line 1147 of file asterisk.c.
Referenced by main().
01148 { 01149 /* Must not ever ast_log or ast_verbose within signal handler */ 01150 int n, status; 01151 01152 /* 01153 * Reap all dead children -- not just one 01154 */ 01155 for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++) 01156 ; 01157 if (n == 0 && option_debug) 01158 printf("Huh? Child handler, but nobody there?\n"); 01159 signal(sig, child_handler); 01160 }
static char* cli_complete | ( | EditLine * | el, | |
int | ch | |||
) | [static] |
Definition at line 2044 of file asterisk.c.
References AST_CLI_COMPLETE_EOF, ast_cli_completion_matches(), ast_cli_display_match_list(), ast_el_strtoarr(), ast_malloc, ast_opt_remote, ast_realloc, fdprint(), free, and len.
Referenced by ast_el_initialize().
02045 { 02046 int len = 0; 02047 char *ptr; 02048 int nummatches = 0; 02049 char **matches; 02050 int retval = CC_ERROR; 02051 char buf[2048]; 02052 int res; 02053 02054 LineInfo *lf = (LineInfo *)el_line(el); 02055 02056 *(char *)lf->cursor = '\0'; 02057 ptr = (char *)lf->cursor; 02058 if (ptr) { 02059 while (ptr > lf->buffer) { 02060 if (isspace(*ptr)) { 02061 ptr++; 02062 break; 02063 } 02064 ptr--; 02065 } 02066 } 02067 02068 len = lf->cursor - ptr; 02069 02070 if (ast_opt_remote) { 02071 snprintf(buf, sizeof(buf),"_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 02072 fdprint(ast_consock, buf); 02073 res = read(ast_consock, buf, sizeof(buf)); 02074 buf[res] = '\0'; 02075 nummatches = atoi(buf); 02076 02077 if (nummatches > 0) { 02078 char *mbuf; 02079 int mlen = 0, maxmbuf = 2048; 02080 /* Start with a 2048 byte buffer */ 02081 if (!(mbuf = ast_malloc(maxmbuf))) 02082 return (char *)(CC_ERROR); 02083 snprintf(buf, sizeof(buf),"_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 02084 fdprint(ast_consock, buf); 02085 res = 0; 02086 mbuf[0] = '\0'; 02087 while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) { 02088 if (mlen + 1024 > maxmbuf) { 02089 /* Every step increment buffer 1024 bytes */ 02090 maxmbuf += 1024; 02091 if (!(mbuf = ast_realloc(mbuf, maxmbuf))) 02092 return (char *)(CC_ERROR); 02093 } 02094 /* Only read 1024 bytes at a time */ 02095 res = read(ast_consock, mbuf + mlen, 1024); 02096 if (res > 0) 02097 mlen += res; 02098 } 02099 mbuf[mlen] = '\0'; 02100 02101 matches = ast_el_strtoarr(mbuf); 02102 free(mbuf); 02103 } else 02104 matches = (char **) NULL; 02105 } else { 02106 char **p, *oldbuf=NULL; 02107 nummatches = 0; 02108 matches = ast_cli_completion_matches((char *)lf->buffer,ptr); 02109 for (p = matches; p && *p; p++) { 02110 if (!oldbuf || strcmp(*p,oldbuf)) 02111 nummatches++; 02112 oldbuf = *p; 02113 } 02114 } 02115 02116 if (matches) { 02117 int i; 02118 int matches_num, maxlen, match_len; 02119 02120 if (matches[0][0] != '\0') { 02121 el_deletestr(el, (int) len); 02122 el_insertstr(el, matches[0]); 02123 retval = CC_REFRESH; 02124 } 02125 02126 if (nummatches == 1) { 02127 /* Found an exact match */ 02128 el_insertstr(el, " "); 02129 retval = CC_REFRESH; 02130 } else { 02131 /* Must be more than one match */ 02132 for (i=1, maxlen=0; matches[i]; i++) { 02133 match_len = strlen(matches[i]); 02134 if (match_len > maxlen) 02135 maxlen = match_len; 02136 } 02137 matches_num = i - 1; 02138 if (matches_num >1) { 02139 fprintf(stdout, "\n"); 02140 ast_cli_display_match_list(matches, nummatches, maxlen); 02141 retval = CC_REDISPLAY; 02142 } else { 02143 el_insertstr(el," "); 02144 retval = CC_REFRESH; 02145 } 02146 } 02147 for (i = 0; matches[i]; i++) 02148 free(matches[i]); 02149 free(matches); 02150 } 02151 02152 return (char *)(long)retval; 02153 }
static char* cli_prompt | ( | EditLine * | el | ) | [static] |
Definition at line 1803 of file asterisk.c.
References ast_localtime(), ast_opt_remote, ASTERISK_PROMPT, ASTERISK_PROMPT2, COLOR_BLACK, COLOR_WHITE, hostname, t, and term_color_code().
Referenced by ast_el_initialize().
01804 { 01805 static char prompt[200]; 01806 char *pfmt; 01807 int color_used = 0; 01808 char term_code[20]; 01809 01810 if ((pfmt = getenv("ASTERISK_PROMPT"))) { 01811 char *t = pfmt, *p = prompt; 01812 memset(prompt, 0, sizeof(prompt)); 01813 while (*t != '\0' && *p < sizeof(prompt)) { 01814 if (*t == '%') { 01815 char hostname[MAXHOSTNAMELEN]=""; 01816 int i; 01817 time_t ts; 01818 struct tm tm; 01819 #ifdef linux 01820 FILE *LOADAVG; 01821 #endif 01822 int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK; 01823 01824 t++; 01825 switch (*t) { 01826 case 'C': /* color */ 01827 t++; 01828 if (sscanf(t, "%d;%d%n", &fgcolor, &bgcolor, &i) == 2) { 01829 strncat(p, term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1); 01830 t += i - 1; 01831 } else if (sscanf(t, "%d%n", &fgcolor, &i) == 1) { 01832 strncat(p, term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1); 01833 t += i - 1; 01834 } 01835 01836 /* If the color has been reset correctly, then there's no need to reset it later */ 01837 if ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) { 01838 color_used = 0; 01839 } else { 01840 color_used = 1; 01841 } 01842 break; 01843 case 'd': /* date */ 01844 memset(&tm, 0, sizeof(tm)); 01845 time(&ts); 01846 if (ast_localtime(&ts, &tm, NULL)) { 01847 strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm); 01848 } 01849 break; 01850 case 'h': /* hostname */ 01851 if (!gethostname(hostname, sizeof(hostname) - 1)) { 01852 strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1); 01853 } else { 01854 strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1); 01855 } 01856 break; 01857 case 'H': /* short hostname */ 01858 if (!gethostname(hostname, sizeof(hostname) - 1)) { 01859 for (i = 0; i < sizeof(hostname); i++) { 01860 if (hostname[i] == '.') { 01861 hostname[i] = '\0'; 01862 break; 01863 } 01864 } 01865 strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1); 01866 } else { 01867 strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1); 01868 } 01869 break; 01870 #ifdef linux 01871 case 'l': /* load avg */ 01872 t++; 01873 if ((LOADAVG = fopen("/proc/loadavg", "r"))) { 01874 float avg1, avg2, avg3; 01875 int actproc, totproc, npid, which; 01876 fscanf(LOADAVG, "%f %f %f %d/%d %d", 01877 &avg1, &avg2, &avg3, &actproc, &totproc, &npid); 01878 if (sscanf(t, "%d", &which) == 1) { 01879 switch (which) { 01880 case 1: 01881 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1); 01882 break; 01883 case 2: 01884 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2); 01885 break; 01886 case 3: 01887 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3); 01888 break; 01889 case 4: 01890 snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc); 01891 break; 01892 case 5: 01893 snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid); 01894 break; 01895 } 01896 } 01897 } 01898 break; 01899 #endif 01900 case 's': /* Asterisk system name (from asterisk.conf) */ 01901 strncat(p, ast_config_AST_SYSTEM_NAME, sizeof(prompt) - strlen(prompt) - 1); 01902 break; 01903 case 't': /* time */ 01904 memset(&tm, 0, sizeof(tm)); 01905 time(&ts); 01906 if (ast_localtime(&ts, &tm, NULL)) { 01907 strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm); 01908 } 01909 break; 01910 case '#': /* process console or remote? */ 01911 if (!ast_opt_remote) { 01912 strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1); 01913 } else { 01914 strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1); 01915 } 01916 break; 01917 case '%': /* literal % */ 01918 strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1); 01919 break; 01920 case '\0': /* % is last character - prevent bug */ 01921 t--; 01922 break; 01923 } 01924 while (*p != '\0') { 01925 p++; 01926 } 01927 t++; 01928 } else { 01929 *p = *t; 01930 p++; 01931 t++; 01932 } 01933 } 01934 if (color_used) { 01935 /* Force colors back to normal at end */ 01936 term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code)); 01937 if (strlen(term_code) > sizeof(prompt) - strlen(prompt)) { 01938 strncat(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code)); 01939 } else { 01940 strncat(p, term_code, sizeof(term_code)); 01941 } 01942 } 01943 } else if (remotehostname) 01944 snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT2, remotehostname); 01945 else 01946 snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT); 01947 01948 return(prompt); 01949 }
static char* complete_show_version_files | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 678 of file asterisk.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.
00679 { 00680 struct file_version *find; 00681 int which = 0; 00682 char *ret = NULL; 00683 int matchlen = strlen(word); 00684 00685 if (pos != 4) 00686 return NULL; 00687 00688 AST_LIST_LOCK(&file_versions); 00689 AST_LIST_TRAVERSE(&file_versions, find, list) { 00690 if (!strncasecmp(word, find->file, matchlen) && ++which > state) { 00691 ret = ast_strdup(find->file); 00692 break; 00693 } 00694 } 00695 AST_LIST_UNLOCK(&file_versions); 00696 00697 return ret; 00698 }
static char* complete_show_version_files_deprecated | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 656 of file asterisk.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.
00657 { 00658 struct file_version *find; 00659 int which = 0; 00660 char *ret = NULL; 00661 int matchlen = strlen(word); 00662 00663 if (pos != 3) 00664 return NULL; 00665 00666 AST_LIST_LOCK(&file_versions); 00667 AST_LIST_TRAVERSE(&file_versions, find, list) { 00668 if (!strncasecmp(word, find->file, matchlen) && ++which > state) { 00669 ret = ast_strdup(find->file); 00670 break; 00671 } 00672 } 00673 AST_LIST_UNLOCK(&file_versions); 00674 00675 return ret; 00676 }
static void console_verboser | ( | const char * | s | ) | [static] |
Definition at line 1353 of file asterisk.c.
References ast_opt_console, AST_PTHREADT_NULL, fix_header(), VERBOSE_PREFIX_1, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.
Referenced by main().
01354 { 01355 char tmp[80]; 01356 const char *c = NULL; 01357 01358 if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) || 01359 (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) || 01360 (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) || 01361 (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) { 01362 fputs(tmp, stdout); 01363 fputs(c, stdout); 01364 } else 01365 fputs(s, stdout); 01366 01367 fflush(stdout); 01368 01369 /* Wake up a poll()ing console */ 01370 if (ast_opt_console && consolethread != AST_PTHREADT_NULL) 01371 pthread_kill(consolethread, SIGURG); 01372 }
static void consolehandler | ( | char * | s | ) | [static] |
Definition at line 1384 of file asterisk.c.
References ast_all_zeros(), ast_cli_command(), ast_el_add_history(), ast_safe_system(), and term_end().
Referenced by main().
01385 { 01386 printf(term_end()); 01387 fflush(stdout); 01388 01389 /* Called when readline data is available */ 01390 if (!ast_all_zeros(s)) 01391 ast_el_add_history(s); 01392 /* The real handler for bang */ 01393 if (s[0] == '!') { 01394 if (s[1]) 01395 ast_safe_system(s+1); 01396 else 01397 ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); 01398 } else 01399 ast_cli_command(STDOUT_FILENO, s); 01400 }
static int fdprint | ( | int | fd, | |
const char * | s | |||
) | [static] |
Definition at line 738 of file asterisk.c.
Referenced by ast_el_read_char(), ast_network_puts(), ast_network_puts_mutable(), ast_remotecontrol(), cli_complete(), listener(), and netconsole().
static const char* fix_header | ( | char * | outbuf, | |
int | maxout, | |||
const char * | s, | |||
char * | cmp | |||
) | [static] |
Definition at line 1342 of file asterisk.c.
References COLOR_GRAY, and term_color().
Referenced by console_verboser().
01343 { 01344 const char *c; 01345 if (!strncmp(s, cmp, strlen(cmp))) { 01346 c = s + strlen(cmp); 01347 term_color(outbuf, cmp, COLOR_GRAY, 0, maxout); 01348 return c; 01349 } 01350 return NULL; 01351 }
static int handle_abort_halt | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1554 of file asterisk.c.
References ast_cancel_shutdown(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01555 { 01556 if (argc != 2) 01557 return RESULT_SHOWUSAGE; 01558 ast_cancel_shutdown(); 01559 shuttingdown = 0; 01560 return RESULT_SUCCESS; 01561 }
static int handle_bang | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1563 of file asterisk.c.
References RESULT_SUCCESS.
01564 { 01565 return RESULT_SUCCESS; 01566 }
static int handle_restart_gracefully | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1537 of file asterisk.c.
References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01538 { 01539 if (argc != 2) 01540 return RESULT_SHOWUSAGE; 01541 quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */); 01542 return RESULT_SUCCESS; 01543 }
static int handle_restart_now | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1529 of file asterisk.c.
References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01530 { 01531 if (argc != 2) 01532 return RESULT_SHOWUSAGE; 01533 quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */); 01534 return RESULT_SUCCESS; 01535 }
static int handle_restart_when_convenient | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1545 of file asterisk.c.
References ast_cli(), quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01546 { 01547 if (argc != 3) 01548 return RESULT_SHOWUSAGE; 01549 ast_cli(fd, "Waiting for inactivity to perform restart\n"); 01550 quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */); 01551 return RESULT_SUCCESS; 01552 }
static int handle_show_profile | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 496 of file asterisk.c.
References ast_cli(), profile_data::e, profile_data::entries, profile_entry::events, profile_data::max_size, profile_entry::name, profile_entry::scale, and profile_entry::value.
00497 { 00498 int i, min, max; 00499 char *search = NULL; 00500 00501 if (prof_data == NULL) 00502 return 0; 00503 00504 min = 0; 00505 max = prof_data->entries; 00506 if (argc > 3) { /* specific entries */ 00507 if (isdigit(argv[3][0])) { 00508 min = atoi(argv[3]); 00509 if (argc == 5 && strcmp(argv[4], "-")) 00510 max = atoi(argv[4]); 00511 } else 00512 search = argv[3]; 00513 } 00514 if (max > prof_data->entries) 00515 max = prof_data->entries; 00516 if (!strcmp(argv[1], "clear")) { 00517 for (i= min; i < max; i++) { 00518 if (!search || strstr(prof_data->e[i].name, search)) { 00519 prof_data->e[i].value = 0; 00520 prof_data->e[i].events = 0; 00521 } 00522 } 00523 return 0; 00524 } 00525 ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n", 00526 prof_data->entries, prof_data->max_size); 00527 ast_cli(fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events", 00528 "Value", "Average", "Name"); 00529 for (i = min; i < max; i++) { 00530 struct profile_entry *e = &prof_data->e[i]; 00531 if (!search || strstr(prof_data->e[i].name, search)) 00532 ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n", 00533 i, 00534 (long)e->scale, 00535 (long)e->events, (long long)e->value, 00536 (long long)(e->events ? e->value / e->events : e->value), 00537 e->name); 00538 } 00539 return 0; 00540 }
static int handle_show_profile_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 450 of file asterisk.c.
References ast_cli(), profile_data::e, profile_data::entries, profile_entry::events, profile_data::max_size, profile_entry::name, profile_entry::scale, and profile_entry::value.
00451 { 00452 int i, min, max; 00453 char *search = NULL; 00454 00455 if (prof_data == NULL) 00456 return 0; 00457 00458 min = 0; 00459 max = prof_data->entries; 00460 if (argc >= 3) { /* specific entries */ 00461 if (isdigit(argv[2][0])) { 00462 min = atoi(argv[2]); 00463 if (argc == 4 && strcmp(argv[3], "-")) 00464 max = atoi(argv[3]); 00465 } else 00466 search = argv[2]; 00467 } 00468 if (max > prof_data->entries) 00469 max = prof_data->entries; 00470 if (!strcmp(argv[0], "clear")) { 00471 for (i= min; i < max; i++) { 00472 if (!search || strstr(prof_data->e[i].name, search)) { 00473 prof_data->e[i].value = 0; 00474 prof_data->e[i].events = 0; 00475 } 00476 } 00477 return 0; 00478 } 00479 ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n", 00480 prof_data->entries, prof_data->max_size); 00481 ast_cli(fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events", 00482 "Value", "Average", "Name"); 00483 for (i = min; i < max; i++) { 00484 struct profile_entry *e = &prof_data->e[i]; 00485 if (!search || strstr(prof_data->e[i].name, search)) 00486 ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n", 00487 i, 00488 (long)e->scale, 00489 (long)e->events, (long long)e->value, 00490 (long long)(e->events ? e->value / e->events : e->value), 00491 e->name); 00492 } 00493 return 0; 00494 }
static int handle_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 338 of file asterisk.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.
00339 { 00340 int count = 0; 00341 struct thread_list_t *cur; 00342 00343 AST_LIST_LOCK(&thread_list); 00344 AST_LIST_TRAVERSE(&thread_list, cur, list) { 00345 ast_cli(fd, "%p %s\n", (void *)cur->id, cur->name); 00346 count++; 00347 } 00348 AST_LIST_UNLOCK(&thread_list); 00349 ast_cli(fd, "%d threads listed.\n", count); 00350 return 0; 00351 }
static int handle_show_version_files | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 602 of file asterisk.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, FORMAT, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00603 { 00604 #define FORMAT "%-25.25s %-40.40s\n" 00605 struct file_version *iterator; 00606 regex_t regexbuf; 00607 int havepattern = 0; 00608 int havename = 0; 00609 int count_files = 0; 00610 00611 switch (argc) { 00612 case 6: 00613 if (!strcasecmp(argv[4], "like")) { 00614 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 00615 return RESULT_SHOWUSAGE; 00616 havepattern = 1; 00617 } else 00618 return RESULT_SHOWUSAGE; 00619 break; 00620 case 5: 00621 havename = 1; 00622 break; 00623 case 4: 00624 break; 00625 default: 00626 return RESULT_SHOWUSAGE; 00627 } 00628 00629 ast_cli(fd, FORMAT, "File", "Revision"); 00630 ast_cli(fd, FORMAT, "----", "--------"); 00631 AST_LIST_LOCK(&file_versions); 00632 AST_LIST_TRAVERSE(&file_versions, iterator, list) { 00633 if (havename && strcasecmp(iterator->file, argv[4])) 00634 continue; 00635 00636 if (havepattern && regexec(®exbuf, iterator->file, 0, NULL, 0)) 00637 continue; 00638 00639 ast_cli(fd, FORMAT, iterator->file, iterator->version); 00640 count_files++; 00641 if (havename) 00642 break; 00643 } 00644 AST_LIST_UNLOCK(&file_versions); 00645 if (!havename) { 00646 ast_cli(fd, "%d files listed.\n", count_files); 00647 } 00648 00649 if (havepattern) 00650 regfree(®exbuf); 00651 00652 return RESULT_SUCCESS; 00653 #undef FORMAT 00654 }
static int handle_show_version_files_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list module versions.
Definition at line 548 of file asterisk.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, FORMAT, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00549 { 00550 #define FORMAT "%-25.25s %-40.40s\n" 00551 struct file_version *iterator; 00552 regex_t regexbuf; 00553 int havepattern = 0; 00554 int havename = 0; 00555 int count_files = 0; 00556 00557 switch (argc) { 00558 case 5: 00559 if (!strcasecmp(argv[3], "like")) { 00560 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 00561 return RESULT_SHOWUSAGE; 00562 havepattern = 1; 00563 } else 00564 return RESULT_SHOWUSAGE; 00565 break; 00566 case 4: 00567 havename = 1; 00568 break; 00569 case 3: 00570 break; 00571 default: 00572 return RESULT_SHOWUSAGE; 00573 } 00574 00575 ast_cli(fd, FORMAT, "File", "Revision"); 00576 ast_cli(fd, FORMAT, "----", "--------"); 00577 AST_LIST_LOCK(&file_versions); 00578 AST_LIST_TRAVERSE(&file_versions, iterator, list) { 00579 if (havename && strcasecmp(iterator->file, argv[3])) 00580 continue; 00581 00582 if (havepattern && regexec(®exbuf, iterator->file, 0, NULL, 0)) 00583 continue; 00584 00585 ast_cli(fd, FORMAT, iterator->file, iterator->version); 00586 count_files++; 00587 if (havename) 00588 break; 00589 } 00590 AST_LIST_UNLOCK(&file_versions); 00591 if (!havename) { 00592 ast_cli(fd, "%d files listed.\n", count_files); 00593 } 00594 00595 if (havepattern) 00596 regfree(®exbuf); 00597 00598 return RESULT_SUCCESS; 00599 #undef FORMAT 00600 }
static int handle_shutdown_gracefully | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1512 of file asterisk.c.
References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01513 { 01514 if (argc != 2) 01515 return RESULT_SHOWUSAGE; 01516 quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */); 01517 return RESULT_SUCCESS; 01518 }
static int handle_shutdown_now | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1504 of file asterisk.c.
References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01505 { 01506 if (argc != 2) 01507 return RESULT_SHOWUSAGE; 01508 quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */); 01509 return RESULT_SUCCESS; 01510 }
static int handle_shutdown_when_convenient | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1520 of file asterisk.c.
References ast_cli(), quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01521 { 01522 if (argc != 3) 01523 return RESULT_SHOWUSAGE; 01524 ast_cli(fd, "Waiting for inactivity to perform halt\n"); 01525 quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */); 01526 return RESULT_SUCCESS; 01527 }
static int handle_version | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1484 of file asterisk.c.
References ast_cli(), ASTERISK_VERSION, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01485 { 01486 if (argc != 3) 01487 return RESULT_SHOWUSAGE; 01488 ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n", 01489 ASTERISK_VERSION, ast_build_user, ast_build_hostname, 01490 ast_build_machine, ast_build_os, ast_build_date); 01491 return RESULT_SUCCESS; 01492 }
static int handle_version_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1474 of file asterisk.c.
References ast_cli(), ASTERISK_VERSION, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01475 { 01476 if (argc != 2) 01477 return RESULT_SHOWUSAGE; 01478 ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n", 01479 ASTERISK_VERSION, ast_build_user, ast_build_hostname, 01480 ast_build_machine, ast_build_os, ast_build_date); 01481 return RESULT_SUCCESS; 01482 }
static void hup_handler | ( | int | num | ) | [static] |
Definition at line 1134 of file asterisk.c.
References sig_flags.
Referenced by main().
01135 { 01136 int a = 0; 01137 if (option_verbose > 1) 01138 printf("Received HUP signal -- Reloading configs\n"); 01139 if (restartnow) 01140 execvp(_argv[0], _argv); 01141 sig_flags.need_reload = 1; 01142 if (sig_alert_pipe[1] != -1) 01143 write(sig_alert_pipe[1], &a, sizeof(a)); 01144 signal(num, hup_handler); 01145 }
static void* listener | ( | void * | unused | ) | [static] |
Definition at line 966 of file asterisk.c.
References AF_LOCAL, ast_log(), AST_MAX_CONNECTS, ast_pthread_create_background, ast_verbose(), consoles, errno, pollfd::events, console::fd, pollfd::fd, fdprint(), len, LOG_ERROR, LOG_WARNING, console::mute, netconsole(), poll(), POLLIN, s, t, and VERBOSE_PREFIX_3.
Referenced by ast_makesocket().
00967 { 00968 struct sockaddr_un sunaddr; 00969 int s; 00970 socklen_t len; 00971 int x; 00972 int flags; 00973 struct pollfd fds[1]; 00974 pthread_attr_t attr; 00975 pthread_attr_init(&attr); 00976 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00977 for (;;) { 00978 if (ast_socket < 0) 00979 return NULL; 00980 fds[0].fd = ast_socket; 00981 fds[0].events = POLLIN; 00982 s = poll(fds, 1, -1); 00983 pthread_testcancel(); 00984 if (s < 0) { 00985 if (errno != EINTR) 00986 ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno)); 00987 continue; 00988 } 00989 len = sizeof(sunaddr); 00990 s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len); 00991 if (s < 0) { 00992 if (errno != EINTR) 00993 ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno)); 00994 } else { 00995 for (x = 0; x < AST_MAX_CONNECTS; x++) { 00996 if (consoles[x].fd < 0) { 00997 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) { 00998 ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno)); 00999 consoles[x].fd = -1; 01000 fdprint(s, "Server failed to create pipe\n"); 01001 close(s); 01002 break; 01003 } 01004 flags = fcntl(consoles[x].p[1], F_GETFL); 01005 fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK); 01006 consoles[x].fd = s; 01007 consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */ 01008 if (ast_pthread_create_background(&consoles[x].t, &attr, netconsole, &consoles[x])) { 01009 ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno)); 01010 close(consoles[x].p[0]); 01011 close(consoles[x].p[1]); 01012 consoles[x].fd = -1; 01013 fdprint(s, "Server failed to spawn thread\n"); 01014 close(s); 01015 } 01016 break; 01017 } 01018 } 01019 if (x >= AST_MAX_CONNECTS) { 01020 fdprint(s, "No more connections allowed\n"); 01021 ast_log(LOG_WARNING, "No more connections allowed\n"); 01022 close(s); 01023 } else if (consoles[x].fd > -1) { 01024 if (option_verbose > 2) 01025 ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection\n"); 01026 } 01027 } 01028 } 01029 return NULL; 01030 }
int main | ( | int | argc, | |
char * | argv[] | |||
) |
Definition at line 2544 of file asterisk.c.
References __ast_mm_init(), __quit_handler(), ast_alaw_init(), ast_builtins_init(), ast_cdr_engine_init(), ast_channels_init(), ast_clear_flag, ast_cli_register_multiple(), ast_device_state_engine_init(), ast_el_initialize(), ast_el_read_history(), ast_enum_init(), ast_file_init(), ast_http_init(), ast_image_init(), ast_log(), ast_makesocket(), ast_opt_always_fork, ast_opt_console, ast_opt_dump_core, ast_opt_exec, AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC, AST_OPT_FLAG_FULLY_BOOTED, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, 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_pthread_create, ast_readconfig(), ast_register_verbose(), ast_remotecontrol(), ast_rtp_init(), ast_set_flag, ast_set_priority(), ast_strlen_zero(), ast_term_init(), ast_test_flag, ast_tryconnect(), ast_udptl_init(), ast_ulaw_init(), ast_utils_init(), ast_verbose(), astdb_init(), astobj2_init(), callerid_init(), child_handler(), COLOR_BLACK, COLOR_BRWHITE, console_verboser(), consolehandler(), dnsmgr_init(), dnsmgr_start_refresh(), errno, f, group, hostname, hup_handler(), init_framer(), init_logger(), init_manager(), load_modules(), load_pbx(), LOG_ERROR, LOG_WARNING, monitor_sig_flags(), quit_handler(), read_config_maps(), register_config_cli(), set_icon(), set_title(), show_cli_help(), show_version(), tdd_init(), term_color(), term_end(), term_quit(), test_for_thread_safety(), threadstorage_init(), urg_handler(), and WELCOME_MESSAGE.
02545 { 02546 int c; 02547 char filename[80] = ""; 02548 char hostname[MAXHOSTNAMELEN] = ""; 02549 char tmp[80]; 02550 char * xarg = NULL; 02551 int x; 02552 FILE *f; 02553 sigset_t sigs; 02554 int num; 02555 int isroot = 1; 02556 char *buf; 02557 char *runuser = NULL, *rungroup = NULL; 02558 02559 /* Remember original args for restart */ 02560 if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) { 02561 fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1); 02562 argc = sizeof(_argv) / sizeof(_argv[0]) - 1; 02563 } 02564 for (x=0; x<argc; x++) 02565 _argv[x] = argv[x]; 02566 _argv[x] = NULL; 02567 02568 if (geteuid() != 0) 02569 isroot = 0; 02570 02571 /* if the progname is rasterisk consider it a remote console */ 02572 if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) { 02573 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE); 02574 } 02575 if (gethostname(hostname, sizeof(hostname)-1)) 02576 ast_copy_string(hostname, "<Unknown>", sizeof(hostname)); 02577 ast_mainpid = getpid(); 02578 ast_ulaw_init(); 02579 ast_alaw_init(); 02580 callerid_init(); 02581 ast_builtins_init(); 02582 ast_utils_init(); 02583 tdd_init(); 02584 02585 if (getenv("HOME")) 02586 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); 02587 /* Check for options */ 02588 while ((c = getopt(argc, argv, "mtThfFdvVqprRgciInx:U:G:C:L:M:")) != -1) { 02589 switch (c) { 02590 #if HAVE_WORKING_FORK 02591 case 'F': 02592 ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK); 02593 break; 02594 case 'f': 02595 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); 02596 break; 02597 #endif 02598 case 'd': 02599 option_debug++; 02600 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); 02601 break; 02602 case 'c': 02603 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE); 02604 break; 02605 case 'n': 02606 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR); 02607 break; 02608 case 'r': 02609 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE); 02610 break; 02611 case 'R': 02612 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT); 02613 break; 02614 case 'p': 02615 ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY); 02616 break; 02617 case 'v': 02618 option_verbose++; 02619 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); 02620 break; 02621 case 'm': 02622 ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE); 02623 break; 02624 case 'M': 02625 if ((sscanf(optarg, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) 02626 option_maxcalls = 0; 02627 break; 02628 case 'L': 02629 if ((sscanf(optarg, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) 02630 option_maxload = 0.0; 02631 break; 02632 case 'q': 02633 ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET); 02634 break; 02635 case 't': 02636 ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES); 02637 break; 02638 case 'T': 02639 ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP); 02640 break; 02641 case 'x': 02642 ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC); 02643 xarg = optarg; 02644 break; 02645 case 'C': 02646 ast_copy_string(ast_config_AST_CONFIG_FILE, optarg, sizeof(ast_config_AST_CONFIG_FILE)); 02647 ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG); 02648 break; 02649 case 'I': 02650 ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING); 02651 break; 02652 case 'i': 02653 ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS); 02654 break; 02655 case 'g': 02656 ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE); 02657 break; 02658 case 'h': 02659 show_cli_help(); 02660 exit(0); 02661 case 'V': 02662 show_version(); 02663 exit(0); 02664 case 'U': 02665 runuser = optarg; 02666 break; 02667 case 'G': 02668 rungroup = optarg; 02669 break; 02670 case '?': 02671 exit(1); 02672 } 02673 } 02674 02675 if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) { 02676 ast_register_verbose(console_verboser); 02677 WELCOME_MESSAGE; 02678 } 02679 02680 if (ast_opt_console && !option_verbose) 02681 ast_verbose("[ Booting...\n"); 02682 02683 if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) { 02684 ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n"); 02685 ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK); 02686 } 02687 02688 /* For remote connections, change the name of the remote connection. 02689 * We do this for the benefit of init scripts (which need to know if/when 02690 * the main asterisk process has died yet). */ 02691 if (ast_opt_remote) { 02692 strcpy(argv[0], "rasterisk"); 02693 for (x = 1; x < argc; x++) { 02694 argv[x] = argv[0] + 10; 02695 } 02696 } 02697 02698 if (ast_opt_console && !option_verbose) 02699 ast_verbose("[ Reading Master Configuration ]\n"); 02700 ast_readconfig(); 02701 02702 if (ast_opt_dump_core) { 02703 struct rlimit l; 02704 memset(&l, 0, sizeof(l)); 02705 l.rlim_cur = RLIM_INFINITY; 02706 l.rlim_max = RLIM_INFINITY; 02707 if (setrlimit(RLIMIT_CORE, &l)) { 02708 ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno)); 02709 } 02710 } 02711 02712 if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP)) 02713 rungroup = ast_config_AST_RUN_GROUP; 02714 if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER)) 02715 runuser = ast_config_AST_RUN_USER; 02716 02717 #ifndef __CYGWIN__ 02718 02719 if (isroot) 02720 ast_set_priority(ast_opt_high_priority); 02721 02722 if (isroot && rungroup) { 02723 struct group *gr; 02724 gr = getgrnam(rungroup); 02725 if (!gr) { 02726 ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup); 02727 exit(1); 02728 } 02729 if (setgid(gr->gr_gid)) { 02730 ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup); 02731 exit(1); 02732 } 02733 if (setgroups(0, NULL)) { 02734 ast_log(LOG_WARNING, "Unable to drop unneeded groups\n"); 02735 exit(1); 02736 } 02737 if (option_verbose) 02738 ast_verbose("Running as group '%s'\n", rungroup); 02739 } 02740 02741 if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) { 02742 #ifdef HAVE_CAP 02743 int has_cap = 1; 02744 #endif /* HAVE_CAP */ 02745 struct passwd *pw; 02746 pw = getpwnam(runuser); 02747 if (!pw) { 02748 ast_log(LOG_WARNING, "No such user '%s'!\n", runuser); 02749 exit(1); 02750 } 02751 #ifdef HAVE_CAP 02752 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { 02753 ast_log(LOG_WARNING, "Unable to keep capabilities.\n"); 02754 has_cap = 0; 02755 } 02756 #endif /* HAVE_CAP */ 02757 if (!isroot && pw->pw_uid != geteuid()) { 02758 ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser); 02759 exit(1); 02760 } 02761 if (!rungroup) { 02762 if (setgid(pw->pw_gid)) { 02763 ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid); 02764 exit(1); 02765 } 02766 if (isroot && initgroups(pw->pw_name, pw->pw_gid)) { 02767 ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser); 02768 exit(1); 02769 } 02770 } 02771 if (setuid(pw->pw_uid)) { 02772 ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser); 02773 exit(1); 02774 } 02775 if (option_verbose) 02776 ast_verbose("Running as user '%s'\n", runuser); 02777 #ifdef HAVE_CAP 02778 if (has_cap) { 02779 cap_t cap; 02780 02781 cap = cap_from_text("cap_net_admin=ep"); 02782 02783 if (cap_set_proc(cap)) 02784 ast_log(LOG_WARNING, "Unable to install capabilities.\n"); 02785 02786 if (cap_free(cap)) 02787 ast_log(LOG_WARNING, "Unable to drop capabilities.\n"); 02788 } 02789 #endif /* HAVE_CAP */ 02790 } 02791 02792 #endif /* __CYGWIN__ */ 02793 02794 #ifdef linux 02795 if (geteuid() && ast_opt_dump_core) { 02796 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { 02797 ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno)); 02798 } 02799 } 02800 #endif 02801 02802 ast_term_init(); 02803 printf(term_end()); 02804 fflush(stdout); 02805 02806 if (ast_opt_console && !option_verbose) 02807 ast_verbose("[ Initializing Custom Configuration Options ]\n"); 02808 /* custom config setup */ 02809 register_config_cli(); 02810 read_config_maps(); 02811 02812 if (ast_opt_console) { 02813 if (el_hist == NULL || el == NULL) 02814 ast_el_initialize(); 02815 02816 if (!ast_strlen_zero(filename)) 02817 ast_el_read_history(filename); 02818 } 02819 02820 if (ast_tryconnect()) { 02821 /* One is already running */ 02822 if (ast_opt_remote) { 02823 if (ast_opt_exec) { 02824 ast_remotecontrol(xarg); 02825 quit_handler(0, 0, 0, 0); 02826 exit(0); 02827 } 02828 printf(term_quit()); 02829 ast_remotecontrol(NULL); 02830 quit_handler(0, 0, 0, 0); 02831 exit(0); 02832 } else { 02833 ast_log(LOG_ERROR, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET); 02834 printf(term_quit()); 02835 exit(1); 02836 } 02837 } else if (ast_opt_remote || ast_opt_exec) { 02838 ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET); 02839 printf(term_quit()); 02840 exit(1); 02841 } 02842 /* Blindly write pid file since we couldn't connect */ 02843 unlink(ast_config_AST_PID); 02844 f = fopen(ast_config_AST_PID, "w"); 02845 if (f) { 02846 fprintf(f, "%ld\n", (long)getpid()); 02847 fclose(f); 02848 } else 02849 ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno)); 02850 02851 #if HAVE_WORKING_FORK 02852 if (ast_opt_always_fork || !ast_opt_no_fork) { 02853 daemon(1, 0); 02854 ast_mainpid = getpid(); 02855 /* Blindly re-write pid file since we are forking */ 02856 unlink(ast_config_AST_PID); 02857 f = fopen(ast_config_AST_PID, "w"); 02858 if (f) { 02859 fprintf(f, "%ld\n", (long)ast_mainpid); 02860 fclose(f); 02861 } else 02862 ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno)); 02863 } 02864 #endif 02865 02866 /* Test recursive mutex locking. */ 02867 if (test_for_thread_safety()) 02868 ast_verbose("Warning! Asterisk is not thread safe.\n"); 02869 02870 ast_makesocket(); 02871 sigemptyset(&sigs); 02872 sigaddset(&sigs, SIGHUP); 02873 sigaddset(&sigs, SIGTERM); 02874 sigaddset(&sigs, SIGINT); 02875 sigaddset(&sigs, SIGPIPE); 02876 sigaddset(&sigs, SIGWINCH); 02877 pthread_sigmask(SIG_BLOCK, &sigs, NULL); 02878 signal(SIGURG, urg_handler); 02879 signal(SIGINT, __quit_handler); 02880 signal(SIGTERM, __quit_handler); 02881 signal(SIGHUP, hup_handler); 02882 signal(SIGCHLD, child_handler); 02883 signal(SIGPIPE, SIG_IGN); 02884 02885 /* ensure that the random number generators are seeded with a different value every time 02886 Asterisk is started 02887 */ 02888 srand((unsigned int) getpid() + (unsigned int) time(NULL)); 02889 initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool)); 02890 02891 if (init_logger()) { 02892 printf(term_quit()); 02893 exit(1); 02894 } 02895 02896 threadstorage_init(); 02897 02898 astobj2_init(); 02899 02900 if (load_modules(1)) { 02901 printf(term_quit()); 02902 exit(1); 02903 } 02904 02905 if (dnsmgr_init()) { 02906 printf(term_quit()); 02907 exit(1); 02908 } 02909 02910 ast_http_init(); 02911 02912 ast_channels_init(); 02913 02914 if (init_manager()) { 02915 printf(term_quit()); 02916 exit(1); 02917 } 02918 02919 if (ast_cdr_engine_init()) { 02920 printf(term_quit()); 02921 exit(1); 02922 } 02923 02924 if (ast_device_state_engine_init()) { 02925 printf(term_quit()); 02926 exit(1); 02927 } 02928 02929 ast_rtp_init(); 02930 02931 ast_udptl_init(); 02932 02933 if (ast_image_init()) { 02934 printf(term_quit()); 02935 exit(1); 02936 } 02937 02938 if (ast_file_init()) { 02939 printf(term_quit()); 02940 exit(1); 02941 } 02942 02943 if (load_pbx()) { 02944 printf(term_quit()); 02945 exit(1); 02946 } 02947 02948 if (init_framer()) { 02949 printf(term_quit()); 02950 exit(1); 02951 } 02952 02953 if (astdb_init()) { 02954 printf(term_quit()); 02955 exit(1); 02956 } 02957 02958 if (ast_enum_init()) { 02959 printf(term_quit()); 02960 exit(1); 02961 } 02962 02963 if (load_modules(0)) { 02964 printf(term_quit()); 02965 exit(1); 02966 } 02967 02968 dnsmgr_start_refresh(); 02969 02970 /* We might have the option of showing a console, but for now just 02971 do nothing... */ 02972 if (ast_opt_console && !option_verbose) 02973 ast_verbose(" ]\n"); 02974 if (option_verbose || ast_opt_console) 02975 ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp))); 02976 if (ast_opt_no_fork) 02977 consolethread = pthread_self(); 02978 02979 if (pipe(sig_alert_pipe)) 02980 sig_alert_pipe[0] = sig_alert_pipe[1] = -1; 02981 02982 ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED); 02983 pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); 02984 02985 #ifdef __AST_DEBUG_MALLOC 02986 __ast_mm_init(); 02987 #endif 02988 02989 time(&ast_startuptime); 02990 ast_cli_register_multiple(cli_asterisk, sizeof(cli_asterisk) / sizeof(struct ast_cli_entry)); 02991 02992 if (ast_opt_console) { 02993 /* Console stuff now... */ 02994 /* Register our quit function */ 02995 char title[256]; 02996 pthread_attr_t attr; 02997 pthread_t dont_care; 02998 02999 pthread_attr_init(&attr); 03000 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 03001 ast_pthread_create(&dont_care, &attr, monitor_sig_flags, NULL); 03002 pthread_attr_destroy(&attr); 03003 03004 set_icon("Asterisk"); 03005 snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid); 03006 set_title(title); 03007 03008 for (;;) { 03009 buf = (char *)el_gets(el, &num); 03010 03011 if (!buf && write(1, "", 1) < 0) 03012 goto lostterm; 03013 03014 if (buf) { 03015 if (buf[strlen(buf)-1] == '\n') 03016 buf[strlen(buf)-1] = '\0'; 03017 03018 consolehandler((char *)buf); 03019 } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n", 03020 strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) { 03021 /* Whoa, stdout disappeared from under us... Make /dev/null's */ 03022 int fd; 03023 fd = open("/dev/null", O_RDWR); 03024 if (fd > -1) { 03025 dup2(fd, STDOUT_FILENO); 03026 dup2(fd, STDIN_FILENO); 03027 } else 03028 ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n"); 03029 break; 03030 } 03031 } 03032 } 03033 03034 monitor_sig_flags(NULL); 03035 03036 lostterm: 03037 return 0; 03038 }
static void* monitor_sig_flags | ( | void * | unused | ) | [static] |
Definition at line 2524 of file asterisk.c.
References ast_module_reload(), poll(), POLLIN, quit_handler(), and sig_flags.
Referenced by main().
02525 { 02526 for (;;) { 02527 struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 }; 02528 int a; 02529 poll(&p, 1, -1); 02530 if (sig_flags.need_reload) { 02531 sig_flags.need_reload = 0; 02532 ast_module_reload(NULL); 02533 } 02534 if (sig_flags.need_quit) { 02535 sig_flags.need_quit = 0; 02536 quit_handler(0, 0, 1, 0); 02537 } 02538 read(sig_alert_pipe[0], &a, sizeof(a)); 02539 } 02540 02541 return NULL; 02542 }
static void* netconsole | ( | void * | vconsole | ) | [static] |
Definition at line 911 of file asterisk.c.
References ast_cli_command_multiple(), ast_log(), ast_verbose(), ASTERISK_VERSION, errno, pollfd::events, pollfd::fd, console::fd, fdprint(), hostname, LOG_ERROR, LOG_WARNING, console::p, poll(), POLLIN, pollfd::revents, and VERBOSE_PREFIX_3.
Referenced by listener().
00912 { 00913 struct console *con = vconsole; 00914 char hostname[MAXHOSTNAMELEN] = ""; 00915 char tmp[512]; 00916 int res; 00917 struct pollfd fds[2]; 00918 00919 if (gethostname(hostname, sizeof(hostname)-1)) 00920 ast_copy_string(hostname, "<Unknown>", sizeof(hostname)); 00921 snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ASTERISK_VERSION); 00922 fdprint(con->fd, tmp); 00923 for(;;) { 00924 fds[0].fd = con->fd; 00925 fds[0].events = POLLIN; 00926 fds[0].revents = 0; 00927 fds[1].fd = con->p[0]; 00928 fds[1].events = POLLIN; 00929 fds[1].revents = 0; 00930 00931 res = poll(fds, 2, -1); 00932 if (res < 0) { 00933 if (errno != EINTR) 00934 ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno)); 00935 continue; 00936 } 00937 if (fds[0].revents) { 00938 res = read(con->fd, tmp, sizeof(tmp)); 00939 if (res < 1) { 00940 break; 00941 } 00942 tmp[res] = 0; 00943 ast_cli_command_multiple(con->fd, res, tmp); 00944 } 00945 if (fds[1].revents) { 00946 res = read(con->p[0], tmp, sizeof(tmp)); 00947 if (res < 1) { 00948 ast_log(LOG_ERROR, "read returned %d\n", res); 00949 break; 00950 } 00951 res = write(con->fd, tmp, res); 00952 if (res < 1) 00953 break; 00954 } 00955 } 00956 if (option_verbose > 2) 00957 ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection disconnected\n"); 00958 close(con->fd); 00959 close(con->p[0]); 00960 close(con->p[1]); 00961 con->fd = -1; 00962 00963 return NULL; 00964 }
static void network_verboser | ( | const char * | s | ) | [static] |
Definition at line 904 of file asterisk.c.
References ast_network_puts_mutable().
Referenced by ast_makesocket().
00905 { 00906 ast_network_puts_mutable(s); 00907 }
static void null_sig_handler | ( | int | signal | ) | [static] |
NULL handler so we can collect the child exit status.
Definition at line 744 of file asterisk.c.
Referenced by ast_replace_sigchld().
static void quit_handler | ( | int | num, | |
int | nice, | |||
int | safeshutdown, | |||
int | restart | |||
) | [static] |
Definition at line 1222 of file asterisk.c.
References ast_active_channels(), ast_begin_shutdown(), ast_cdr_engine_term(), ast_el_write_history(), ast_log(), ast_module_shutdown(), ast_opt_console, ast_opt_remote, AST_PTHREADT_NULL, ast_run_atexits(), ast_strlen_zero(), ast_verbose(), close_logger(), EVENT_FLAG_SYSTEM, LOG_DEBUG, manager_event(), s, and term_quit().
Referenced by ast_el_read_char(), handle_restart_gracefully(), handle_restart_now(), handle_restart_when_convenient(), handle_shutdown_gracefully(), handle_shutdown_now(), handle_shutdown_when_convenient(), main(), monitor_sig_flags(), and remoteconsolehandler().
01223 { 01224 char filename[80] = ""; 01225 time_t s,e; 01226 int x; 01227 /* Try to get as many CDRs as possible submitted to the backend engines (if in batch mode) */ 01228 ast_cdr_engine_term(); 01229 if (safeshutdown) { 01230 shuttingdown = 1; 01231 if (!nice) { 01232 /* Begin shutdown routine, hanging up active channels */ 01233 ast_begin_shutdown(1); 01234 if (option_verbose && ast_opt_console) 01235 ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown"); 01236 time(&s); 01237 for (;;) { 01238 time(&e); 01239 /* Wait up to 15 seconds for all channels to go away */ 01240 if ((e - s) > 15) 01241 break; 01242 if (!ast_active_channels()) 01243 break; 01244 if (!shuttingdown) 01245 break; 01246 /* Sleep 1/10 of a second */ 01247 usleep(100000); 01248 } 01249 } else { 01250 if (nice < 2) 01251 ast_begin_shutdown(0); 01252 if (option_verbose && ast_opt_console) 01253 ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt"); 01254 for (;;) { 01255 if (!ast_active_channels()) 01256 break; 01257 if (!shuttingdown) 01258 break; 01259 sleep(1); 01260 } 01261 } 01262 01263 if (!shuttingdown) { 01264 if (option_verbose && ast_opt_console) 01265 ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown"); 01266 return; 01267 } 01268 01269 if (nice) 01270 ast_module_shutdown(); 01271 } 01272 if (ast_opt_console || ast_opt_remote) { 01273 if (getenv("HOME")) 01274 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); 01275 if (!ast_strlen_zero(filename)) 01276 ast_el_write_history(filename); 01277 if (el != NULL) 01278 el_end(el); 01279 if (el_hist != NULL) 01280 history_end(el_hist); 01281 } 01282 if (option_verbose) 01283 ast_verbose("Executing last minute cleanups\n"); 01284 ast_run_atexits(); 01285 /* Called on exit */ 01286 if (option_verbose && ast_opt_console) 01287 ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num); 01288 if (option_debug) 01289 ast_log(LOG_DEBUG, "Asterisk ending (%d).\n", num); 01290 manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False"); 01291 if (ast_socket > -1) { 01292 pthread_cancel(lthread); 01293 close(ast_socket); 01294 ast_socket = -1; 01295 unlink(ast_config_AST_SOCKET); 01296 } 01297 if (ast_consock > -1) 01298 close(ast_consock); 01299 if (!ast_opt_remote) 01300 unlink(ast_config_AST_PID); 01301 printf(term_quit()); 01302 if (restart) { 01303 if (option_verbose || ast_opt_console) 01304 ast_verbose("Preparing for Asterisk restart...\n"); 01305 /* Mark all FD's for closing on exec */ 01306 for (x=3; x < 32768; x++) { 01307 fcntl(x, F_SETFD, FD_CLOEXEC); 01308 } 01309 if (option_verbose || ast_opt_console) 01310 ast_verbose("Asterisk is now restarting...\n"); 01311 restartnow = 1; 01312 01313 /* close logger */ 01314 close_logger(); 01315 01316 /* If there is a consolethread running send it a SIGHUP 01317 so it can execvp, otherwise we can do it ourselves */ 01318 if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) { 01319 pthread_kill(consolethread, SIGHUP); 01320 /* Give the signal handler some time to complete */ 01321 sleep(2); 01322 } else 01323 execvp(_argv[0], _argv); 01324 01325 } else { 01326 /* close logger */ 01327 close_logger(); 01328 } 01329 exit(0); 01330 }
static __inline uint64_t rdtsc | ( | void | ) | [static] |
static int remoteconsolehandler | ( | char * | s | ) | [static] |
Definition at line 1402 of file asterisk.c.
References ast_all_zeros(), ast_el_add_history(), ast_safe_system(), and quit_handler().
Referenced by ast_remotecontrol().
01403 { 01404 int ret = 0; 01405 01406 /* Called when readline data is available */ 01407 if (!ast_all_zeros(s)) 01408 ast_el_add_history(s); 01409 /* The real handler for bang */ 01410 if (s[0] == '!') { 01411 if (s[1]) 01412 ast_safe_system(s+1); 01413 else 01414 ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); 01415 ret = 1; 01416 } 01417 if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) && 01418 (s[4] == '\0' || isspace(s[4]))) { 01419 quit_handler(0, 0, 0, 0); 01420 ret = 1; 01421 } 01422 01423 return ret; 01424 }
static void set_icon | ( | char * | text | ) | [static] |
Definition at line 1169 of file asterisk.c.
Referenced by main().
01170 { 01171 if (getenv("TERM") && strstr(getenv("TERM"), "xterm")) 01172 fprintf(stdout, "\033]1;%s\007", text); 01173 }
static void set_title | ( | char * | text | ) | [static] |
Set an X-term or screen title.
Definition at line 1163 of file asterisk.c.
Referenced by main().
01164 { 01165 if (getenv("TERM") && strstr(getenv("TERM"), "xterm")) 01166 fprintf(stdout, "\033]2;%s\007", text); 01167 }
static int show_cli_help | ( | void | ) | [static] |
Definition at line 2326 of file asterisk.c.
References ASTERISK_VERSION.
Referenced by main().
02326 { 02327 printf("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2007, Digium, Inc. and others.\n"); 02328 printf("Usage: asterisk [OPTIONS]\n"); 02329 printf("Valid Options:\n"); 02330 printf(" -V Display version number and exit\n"); 02331 printf(" -C <configfile> Use an alternate configuration file\n"); 02332 printf(" -G <group> Run as a group other than the caller\n"); 02333 printf(" -U <user> Run as a user other than the caller\n"); 02334 printf(" -c Provide console CLI\n"); 02335 printf(" -d Enable extra debugging\n"); 02336 #if HAVE_WORKING_FORK 02337 printf(" -f Do not fork\n"); 02338 printf(" -F Always fork\n"); 02339 #endif 02340 printf(" -g Dump core in case of a crash\n"); 02341 printf(" -h This help screen\n"); 02342 printf(" -i Initialize crypto keys at startup\n"); 02343 printf(" -I Enable internal timing if Zaptel timer is available\n"); 02344 printf(" -L <load> Limit the maximum load average before rejecting new calls\n"); 02345 printf(" -M <value> Limit the maximum number of calls to the specified value\n"); 02346 printf(" -m Mute debugging and console output on the console\n"); 02347 printf(" -n Disable console colorization\n"); 02348 printf(" -p Run as pseudo-realtime thread\n"); 02349 printf(" -q Quiet mode (suppress output)\n"); 02350 printf(" -r Connect to Asterisk on this machine\n"); 02351 printf(" -R Same as -r, except attempt to reconnect if disconnected\n"); 02352 printf(" -t Record soundfiles in /var/tmp and move them where they\n"); 02353 printf(" belong after they are done\n"); 02354 printf(" -T Display the time in [Mmm dd hh:mm:ss] format for each line\n"); 02355 printf(" of output to the CLI\n"); 02356 printf(" -v Increase verbosity (multiple v's = more verbose)\n"); 02357 printf(" -x <cmd> Execute command <cmd> (only valid with -r)\n"); 02358 printf("\n"); 02359 return 0; 02360 }
static int show_license | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1621 of file asterisk.c.
References ast_cli(), and RESULT_SUCCESS.
01622 { 01623 int x; 01624 01625 for (x = 0; x < sizeof(license_lines) / sizeof(license_lines[0]); x++) 01626 ast_cli(fd, (char *) license_lines[x]); 01627 01628 return RESULT_SUCCESS; 01629 }
static int show_version | ( | void | ) | [static] |
Definition at line 2320 of file asterisk.c.
References ASTERISK_VERSION.
Referenced by main().
02321 { 02322 printf("Asterisk " ASTERISK_VERSION "\n"); 02323 return 0; 02324 }
static int show_warranty | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1592 of file asterisk.c.
References ast_cli(), and RESULT_SUCCESS.
01593 { 01594 int x; 01595 01596 for (x = 0; x < sizeof(warranty_lines) / sizeof(warranty_lines[0]); x++) 01597 ast_cli(fd, (char *) warranty_lines[x]); 01598 01599 return RESULT_SUCCESS; 01600 }
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 1128 of file asterisk.c.
Referenced by main().
01129 { 01130 signal(num, urg_handler); 01131 return; 01132 }
char* _argv[256] [static] |
Definition at line 234 of file asterisk.c.
char abort_halt_help[] [static] |
Initial value:
"Usage: abort shutdown\n" " Causes Asterisk to abort an executing shutdown or restart, and resume normal\n" " call operations.\n"
Definition at line 1426 of file asterisk.c.
const char* ast_build_date |
Definition at line 32 of file buildinfo.c.
const char* ast_build_hostname |
Definition at line 28 of file buildinfo.c.
const char* ast_build_kernel |
Definition at line 29 of file buildinfo.c.
const char* ast_build_machine |
Definition at line 30 of file buildinfo.c.
const char* ast_build_os |
Definition at line 31 of file buildinfo.c.
const char* ast_build_user |
Definition at line 33 of file buildinfo.c.
char ast_config_AST_AGI_DIR[PATH_MAX] |
char ast_config_AST_CONFIG_DIR[PATH_MAX] |
Definition at line 205 of file asterisk.c.
Referenced by compile_script(), config_text_file_load(), config_text_file_save(), handle_save_dialplan(), ices_exec(), launch_script(), and pbx_load_module().
char ast_config_AST_CONFIG_FILE[PATH_MAX] |
char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl" |
Definition at line 224 of file asterisk.c.
char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0" |
Definition at line 223 of file asterisk.c.
char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0" |
Definition at line 222 of file asterisk.c.
char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] |
Definition at line 221 of file asterisk.c.
char ast_config_AST_DATA_DIR[PATH_MAX] |
Definition at line 211 of file asterisk.c.
Referenced by ast_linear_stream(), build_filename(), launch_script(), make_filename(), reload_firmware(), and static_callback().
char ast_config_AST_DB[PATH_MAX] |
char ast_config_AST_KEY_DIR[PATH_MAX] |
Definition at line 215 of file asterisk.c.
Referenced by crypto_load(), init_keys(), launch_script(), and osp_create_provider().
char ast_config_AST_LOG_DIR[PATH_MAX] |
Definition at line 212 of file asterisk.c.
Referenced by csv_log(), init_logger(), launch_script(), load_config(), load_module(), make_logchannel(), reload_logger(), testclient_exec(), testserver_exec(), and writefile().
char ast_config_AST_MODULE_DIR[PATH_MAX] |
Definition at line 207 of file asterisk.c.
Referenced by add_module(), complete_fn_2(), complete_fn_3(), file_ok_sel(), launch_script(), and load_modules().
char ast_config_AST_MONITOR_DIR[PATH_MAX] |
Definition at line 209 of file asterisk.c.
Referenced by ast_monitor_change_fname(), ast_monitor_start(), ast_monitor_stop(), chanspy_exec(), chanspychan_exec(), extenspy_exec(), launch_script(), and mixmonitor_exec().
char ast_config_AST_PID[PATH_MAX] |
Definition at line 216 of file asterisk.c.
char ast_config_AST_RUN_DIR[PATH_MAX] |
char ast_config_AST_RUN_GROUP[PATH_MAX] |
Definition at line 220 of file asterisk.c.
char ast_config_AST_RUN_USER[PATH_MAX] |
Definition at line 219 of file asterisk.c.
char ast_config_AST_SOCKET[PATH_MAX] |
Definition at line 217 of file asterisk.c.
char ast_config_AST_SPOOL_DIR[PATH_MAX] |
Definition at line 208 of file asterisk.c.
Referenced by app_exec(), conf_run(), dictate_exec(), launch_script(), load_module(), and play_mailbox_owner().
char ast_config_AST_SYSTEM_NAME[20] = "" |
Definition at line 225 of file asterisk.c.
Referenced by ast_alloc_uniqueid(), ast_channel_alloc(), authenticate(), pbx_retrieve_variable(), realtime_update_peer(), and reload_config().
char ast_config_AST_VAR_DIR[PATH_MAX] |
Definition at line 210 of file asterisk.c.
Referenced by ael2_semantic_check(), and launch_script().
int ast_consock = -1 [static] |
UNIX Socket for controlling another asterisk
Definition at line 174 of file asterisk.c.
time_t ast_lastreloadtime |
Definition at line 191 of file asterisk.c.
Referenced by ast_module_reload(), handle_showuptime(), and handle_showuptime_deprecated().
pid_t ast_mainpid |
Definition at line 175 of file asterisk.c.
Referenced by ast_alloc_uniqueid(), ast_channel_alloc(), safe_append(), and scan_service().
int ast_socket = -1 [static] |
UNIX Socket for allowing remote control
Definition at line 173 of file asterisk.c.
time_t ast_startuptime |
Definition at line 190 of file asterisk.c.
Referenced by handle_showuptime(), and handle_showuptime_deprecated().
char bang_help[] [static] |
Initial value:
"Usage: !<command>\n" " Executes a given shell command\n"
Definition at line 1458 of file asterisk.c.
struct ast_cli_entry cli_asterisk[] [static] |
Definition at line 1657 of file asterisk.c.
struct ast_cli_entry cli_clear_profile_deprecated [static] |
Initial value:
{ { "clear", "profile", NULL }, handle_show_profile_deprecated, NULL, NULL }
Definition at line 1651 of file asterisk.c.
struct ast_cli_entry cli_show_profile_deprecated [static] |
Initial value:
{ { "show", "profile", NULL }, handle_show_profile_deprecated, NULL, NULL }
Definition at line 1646 of file asterisk.c.
struct ast_cli_entry cli_show_version_deprecated [static] |
Initial value:
{ { "show", "version", NULL }, handle_version_deprecated, "Display version info", version_help }
Definition at line 1635 of file asterisk.c.
struct ast_cli_entry cli_show_version_files_deprecated [static] |
Initial value:
{ { "show", "version", "files", NULL }, handle_show_version_files_deprecated, NULL, NULL, complete_show_version_files_deprecated }
Definition at line 1641 of file asterisk.c.
Definition at line 197 of file asterisk.c.
Referenced by ast_console_toggle_mute(), ast_makesocket(), ast_network_puts(), ast_network_puts_mutable(), and listener().
pthread_t consolethread = AST_PTHREADT_NULL [static] |
char debug_filename[AST_FILENAME_MAX] = "" |
Definition at line 171 of file asterisk.c.
Referenced by ast_log(), handle_debuglevel_deprecated(), handle_nodebug(), and handle_set_debug().
char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE |
EditLine* el [static] |
Definition at line 194 of file asterisk.c.
Referenced by __ast_context_destroy(), ast_add_extension2(), handle_save_dialplan(), and show_dialplan_helper().
History* el_hist [static] |
Definition at line 193 of file asterisk.c.
const char* license_lines[] [static] |
Definition at line 1602 of file asterisk.c.
pthread_t lthread [static] |
Definition at line 909 of file asterisk.c.
unsigned int need_quit |
Definition at line 244 of file asterisk.c.
unsigned int need_reload |
Definition at line 243 of file asterisk.c.
struct profile_data* prof_data [static] |
Definition at line 367 of file asterisk.c.
char randompool[256] [static] |
Definition at line 239 of file asterisk.c.
char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR |
char* remotehostname [static] |
Definition at line 195 of file asterisk.c.
char restart_gracefully_help[] [static] |
Initial value:
"Usage: restart gracefully\n" " Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n" " restart when all active calls have ended.\n"
Definition at line 1449 of file asterisk.c.
char restart_now_help[] [static] |
Initial value:
"Usage: restart now\n" " Causes Asterisk to hangup all calls and exec() itself performing a cold\n" " restart.\n"
Definition at line 1444 of file asterisk.c.
char restart_when_convenient_help[] [static] |
Initial value:
"Usage: restart when convenient\n" " Causes Asterisk to perform a cold restart when all active calls have ended.\n"
Definition at line 1454 of file asterisk.c.
int restartnow [static] |
Definition at line 236 of file asterisk.c.
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 752 of file asterisk.c.
void* safe_system_prev_handler [static] |
Definition at line 753 of file asterisk.c.
char show_license_help[] [static] |
Initial value:
"Usage: core show license\n" " Shows the license(s) for this copy of Asterisk.\n"
Definition at line 1466 of file asterisk.c.
char show_threads_help[] [static] |
Initial value:
"Usage: core show threads\n" " List threads currently active in the system.\n"
Definition at line 302 of file asterisk.c.
char show_version_files_help[] [static] |
Initial value:
"Usage: core show file version [like <pattern>]\n" " Lists the revision numbers of the files used to build this copy of Asterisk.\n" " Optional regular expression pattern is used to filter the file list.\n"
Definition at line 542 of file asterisk.c.
char show_warranty_help[] [static] |
Initial value:
"Usage: core show warranty\n" " Shows the warranty (if any) for this copy of Asterisk.\n"
Definition at line 1462 of file asterisk.c.
char shutdown_gracefully_help[] [static] |
Initial value:
"Usage: stop gracefully\n" " Causes Asterisk to not accept new calls, and exit when all\n" " active calls have terminated normally.\n"
Definition at line 1435 of file asterisk.c.
char shutdown_now_help[] [static] |
Initial value:
"Usage: stop now\n" " Shuts down a running Asterisk immediately, hanging up all active calls .\n"
Definition at line 1431 of file asterisk.c.
char shutdown_when_convenient_help[] [static] |
Initial value:
"Usage: stop when convenient\n" " Causes Asterisk to perform a shutdown when all active calls have ended.\n"
Definition at line 1440 of file asterisk.c.
int shuttingdown [static] |
Definition at line 235 of file asterisk.c.
int sig_alert_pipe[2] = { -1, -1 } [static] |
Definition at line 241 of file asterisk.c.
struct { ... } sig_flags [static] |
Referenced by __quit_handler(), hup_handler(), and monitor_sig_flags().
char version_help[] [static] |
Initial value:
"Usage: core show version\n" " Shows Asterisk version information.\n"
Definition at line 1470 of file asterisk.c.
const char* warranty_lines[] [static] |
Definition at line 1567 of file asterisk.c.