#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"
Include dependency graph for asterisk.c:
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 | EL_BUF_SIZE 512 |
#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) |
support for event profiling | |
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 void | set_ulimit (int value) |
Set maximum open files. | |
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 |
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 |
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 EL_BUF_SIZE 512 |
Referenced by ast_el_read_char().
#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 1352 of file asterisk.c.
References sig_flags.
Referenced by main().
01353 { 01354 int a = 0; 01355 sig_flags.need_quit = 1; 01356 if (sig_alert_pipe[1] != -1) 01357 write(sig_alert_pipe[1], &a, sizeof(a)); 01358 /* There is no need to restore the signal handler here, since the app 01359 * is going to exit */ 01360 }
int ast_add_profile | ( | const char * | name, | |
uint64_t | scale | |||
) |
support for event profiling
Definition at line 369 of file asterisk.c.
References ast_calloc, ast_realloc, ast_strdup, profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, profile_data::max_size, profile_entry::name, prof_data, profile_entry::scale, and profile_entry::value.
Referenced by extension_match_core().
00370 { 00371 int l = sizeof(struct profile_data); 00372 int n = 10; /* default entries */ 00373 00374 if (prof_data == NULL) { 00375 prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry)); 00376 if (prof_data == NULL) 00377 return -1; 00378 prof_data->entries = 0; 00379 prof_data->max_size = n; 00380 } 00381 if (prof_data->entries >= prof_data->max_size) { 00382 void *p; 00383 n = prof_data->max_size + 20; 00384 p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry)); 00385 if (p == NULL) 00386 return -1; 00387 prof_data = p; 00388 prof_data->max_size = n; 00389 } 00390 n = prof_data->entries++; 00391 prof_data->e[n].name = ast_strdup(name); 00392 prof_data->e[n].value = 0; 00393 prof_data->e[n].events = 0; 00394 prof_data->e[n].mark = 0; 00395 prof_data->e[n].scale = scale; 00396 return n; 00397 }
static int ast_all_zeros | ( | char * | s | ) | [static] |
Definition at line 1394 of file asterisk.c.
Referenced by ast_el_read_history(), consolehandler(), and remoteconsolehandler().
01395 { 01396 while (*s) { 01397 if (*s > 32) 01398 return 0; 01399 s++; 01400 } 01401 return 1; 01402 }
static int ast_cli_display_match_list | ( | char ** | matches, | |
int | len, | |||
int | max | |||
) | [static] |
Definition at line 2018 of file asterisk.c.
References ast_el_sort_compare(), ast_get_termcols(), and free.
Referenced by cli_complete().
02019 { 02020 int i, idx, limit, count; 02021 int screenwidth = 0; 02022 int numoutput = 0, numoutputline = 0; 02023 02024 screenwidth = ast_get_termcols(STDOUT_FILENO); 02025 02026 /* find out how many entries can be put on one line, with two spaces between strings */ 02027 limit = screenwidth / (max + 2); 02028 if (limit == 0) 02029 limit = 1; 02030 02031 /* how many lines of output */ 02032 count = len / limit; 02033 if (count * limit < len) 02034 count++; 02035 02036 idx = 1; 02037 02038 qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare); 02039 02040 for (; count > 0; count--) { 02041 numoutputline = 0; 02042 for (i=0; i < limit && matches[idx]; i++, idx++) { 02043 02044 /* Don't print dupes */ 02045 if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) { 02046 i--; 02047 free(matches[idx]); 02048 matches[idx] = NULL; 02049 continue; 02050 } 02051 02052 numoutput++; 02053 numoutputline++; 02054 fprintf(stdout, "%-*s ", max, matches[idx]); 02055 free(matches[idx]); 02056 matches[idx] = NULL; 02057 } 02058 if (numoutputline > 0) 02059 fprintf(stdout, "\n"); 02060 } 02061 02062 return numoutput; 02063 }
void ast_console_puts | ( | const char * | string | ) |
write the string to the console, and all attached console clients
Definition at line 894 of file asterisk.c.
References ast_network_puts().
Referenced by chan_misdn_log().
00895 { 00896 fputs(string, stdout); 00897 fflush(stdout); 00898 ast_network_puts(string); 00899 }
void ast_console_puts_mutable | ( | const char * | string | ) |
log the string to the console, and all attached console clients
Definition at line 871 of file asterisk.c.
References ast_network_puts_mutable().
Referenced by ast_log().
00872 { 00873 fputs(string, stdout); 00874 fflush(stdout); 00875 ast_network_puts_mutable(string); 00876 }
void ast_console_toggle_mute | ( | int | fd, | |
int | silent | |||
) |
mute or unmute a console from logging
Definition at line 834 of file asterisk.c.
References ast_cli(), AST_MAX_CONNECTS, consoles, and console::mute.
Referenced by handle_logger_mute().
00834 { 00835 int x; 00836 for (x = 0;x < AST_MAX_CONNECTS; x++) { 00837 if (fd == consoles[x].fd) { 00838 if (consoles[x].mute) { 00839 consoles[x].mute = 0; 00840 if (!silent) 00841 ast_cli(fd, "Console is not muted anymore.\n"); 00842 } else { 00843 consoles[x].mute = 1; 00844 if (!silent) 00845 ast_cli(fd, "Console is muted.\n"); 00846 } 00847 return; 00848 } 00849 } 00850 ast_cli(fd, "Couldn't find remote console.\n"); 00851 }
static int ast_el_add_history | ( | char * | ) | [static] |
Definition at line 2212 of file asterisk.c.
References ast_el_initialize().
Referenced by ast_el_read_history(), consolehandler(), and remoteconsolehandler().
02213 { 02214 HistEvent ev; 02215 02216 if (el_hist == NULL || el == NULL) 02217 ast_el_initialize(); 02218 if (strlen(buf) > 256) 02219 return 0; 02220 return (history(el_hist, &ev, H_ENTER, buf)); 02221 }
static int ast_el_initialize | ( | void | ) | [static] |
Definition at line 2177 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().
02178 { 02179 HistEvent ev; 02180 char *editor = getenv("AST_EDITOR"); 02181 02182 if (el != NULL) 02183 el_end(el); 02184 if (el_hist != NULL) 02185 history_end(el_hist); 02186 02187 el = el_init("asterisk", stdin, stdout, stderr); 02188 el_set(el, EL_PROMPT, cli_prompt); 02189 02190 el_set(el, EL_EDITMODE, 1); 02191 el_set(el, EL_EDITOR, editor ? editor : "emacs"); 02192 el_hist = history_init(); 02193 if (!el || !el_hist) 02194 return -1; 02195 02196 /* setup history with 100 entries */ 02197 history(el_hist, &ev, H_SETSIZE, 100); 02198 02199 el_set(el, EL_HIST, history, el_hist); 02200 02201 el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete); 02202 /* Bind <tab> to command completion */ 02203 el_set(el, EL_BIND, "^I", "ed-complete", NULL); 02204 /* Bind ? to command completion */ 02205 el_set(el, EL_BIND, "?", "ed-complete", NULL); 02206 /* Bind ^D to redisplay */ 02207 el_set(el, EL_BIND, "^D", "ed-redisplay", NULL); 02208 02209 return 0; 02210 }
static int ast_el_read_char | ( | EditLine * | el, | |
char * | cp | |||
) | [static] |
Definition at line 1740 of file asterisk.c.
References ast_log(), ast_opt_exec, ast_opt_mute, ast_opt_reconnect, ast_tryconnect(), EL_BUF_SIZE, errno, pollfd::events, pollfd::fd, fdprint(), LOG_ERROR, poll(), POLLIN, quit_handler(), pollfd::revents, term_quit(), and WELCOME_MESSAGE.
Referenced by ast_remotecontrol().
01741 { 01742 int num_read = 0; 01743 int lastpos = 0; 01744 struct pollfd fds[2]; 01745 int res; 01746 int max; 01747 #define EL_BUF_SIZE 512 01748 char buf[EL_BUF_SIZE]; 01749 01750 for (;;) { 01751 max = 1; 01752 fds[0].fd = ast_consock; 01753 fds[0].events = POLLIN; 01754 if (!ast_opt_exec) { 01755 fds[1].fd = STDIN_FILENO; 01756 fds[1].events = POLLIN; 01757 max++; 01758 } 01759 res = poll(fds, max, -1); 01760 if (res < 0) { 01761 if (errno == EINTR) 01762 continue; 01763 ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno)); 01764 break; 01765 } 01766 01767 if (!ast_opt_exec && fds[1].revents) { 01768 num_read = read(STDIN_FILENO, cp, 1); 01769 if (num_read < 1) { 01770 break; 01771 } else 01772 return (num_read); 01773 } 01774 if (fds[0].revents) { 01775 res = read(ast_consock, buf, sizeof(buf) - 1); 01776 /* if the remote side disappears exit */ 01777 if (res < 1) { 01778 fprintf(stderr, "\nDisconnected from Asterisk server\n"); 01779 if (!ast_opt_reconnect) { 01780 quit_handler(0, 0, 0, 0); 01781 } else { 01782 int tries; 01783 int reconnects_per_second = 20; 01784 fprintf(stderr, "Attempting to reconnect for 30 seconds\n"); 01785 for (tries=0; tries < 30 * reconnects_per_second; tries++) { 01786 if (ast_tryconnect()) { 01787 fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries); 01788 printf(term_quit()); 01789 WELCOME_MESSAGE; 01790 if (!ast_opt_mute) 01791 fdprint(ast_consock, "logger mute silent"); 01792 else 01793 printf("log and verbose output currently muted ('logger mute' to unmute)\n"); 01794 break; 01795 } else { 01796 usleep(1000000 / reconnects_per_second); 01797 } 01798 } 01799 if (tries >= 30 * reconnects_per_second) { 01800 fprintf(stderr, "Failed to reconnect for 30 seconds. Quitting.\n"); 01801 quit_handler(0, 0, 0, 0); 01802 } 01803 } 01804 } 01805 01806 buf[res] = '\0'; 01807 01808 if (!ast_opt_exec && !lastpos) 01809 write(STDOUT_FILENO, "\r", 1); 01810 write(STDOUT_FILENO, buf, res); 01811 if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) { 01812 *cp = CC_REFRESH; 01813 return(1); 01814 } else { 01815 lastpos = 1; 01816 } 01817 } 01818 } 01819 01820 *cp = '\0'; 01821 return (0); 01822 }
static int ast_el_read_history | ( | char * | ) | [static] |
Definition at line 2233 of file asterisk.c.
References ast_all_zeros(), ast_el_add_history(), ast_el_initialize(), and f.
Referenced by ast_remotecontrol(), and main().
02234 { 02235 char buf[256]; 02236 FILE *f; 02237 int ret = -1; 02238 02239 if (el_hist == NULL || el == NULL) 02240 ast_el_initialize(); 02241 02242 if ((f = fopen(filename, "r")) == NULL) 02243 return ret; 02244 02245 while (!feof(f)) { 02246 fgets(buf, sizeof(buf), f); 02247 if (!strcmp(buf, "_HiStOrY_V2_\n")) 02248 continue; 02249 if (ast_all_zeros(buf)) 02250 continue; 02251 if ((ret = ast_el_add_history(buf)) == -1) 02252 break; 02253 } 02254 fclose(f); 02255 02256 return ret; 02257 }
static int ast_el_sort_compare | ( | const void * | i1, | |
const void * | i2 | |||
) | [static] |
Definition at line 2008 of file asterisk.c.
Referenced by ast_cli_display_match_list().
02009 { 02010 char *s1, *s2; 02011 02012 s1 = ((char **)i1)[0]; 02013 s2 = ((char **)i2)[0]; 02014 02015 return strcasecmp(s1, s2); 02016 }
static char** ast_el_strtoarr | ( | char * | buf | ) | [static] |
Definition at line 1973 of file asterisk.c.
References AST_CLI_COMPLETE_EOF, ast_realloc, strdup, and strsep().
Referenced by cli_complete().
01974 { 01975 char **match_list = NULL, *retstr; 01976 size_t match_list_len; 01977 int matches = 0; 01978 01979 match_list_len = 1; 01980 while ( (retstr = strsep(&buf, " ")) != NULL) { 01981 01982 if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) 01983 break; 01984 if (matches + 1 >= match_list_len) { 01985 match_list_len <<= 1; 01986 if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(char *)))) { 01987 /* TODO: Handle memory allocation failure */ 01988 } 01989 } 01990 01991 match_list[matches++] = strdup(retstr); 01992 } 01993 01994 if (!match_list) 01995 return (char **) NULL; 01996 01997 if (matches >= match_list_len) { 01998 if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) { 01999 /* TODO: Handle memory allocation failure */ 02000 } 02001 } 02002 02003 match_list[matches] = (char *) NULL; 02004 02005 return match_list; 02006 }
static int ast_el_write_history | ( | char * | ) | [static] |
Definition at line 2223 of file asterisk.c.
References ast_el_initialize().
Referenced by quit_handler().
02224 { 02225 HistEvent ev; 02226 02227 if (el_hist == NULL || el == NULL) 02228 ast_el_initialize(); 02229 02230 return (history(el_hist, &ev, H_SAVE, filename)); 02231 }
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 1029 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().
01030 { 01031 struct sockaddr_un sunaddr; 01032 int res; 01033 int x; 01034 uid_t uid = -1; 01035 gid_t gid = -1; 01036 01037 for (x = 0; x < AST_MAX_CONNECTS; x++) 01038 consoles[x].fd = -1; 01039 unlink(ast_config_AST_SOCKET); 01040 ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0); 01041 if (ast_socket < 0) { 01042 ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno)); 01043 return -1; 01044 } 01045 memset(&sunaddr, 0, sizeof(sunaddr)); 01046 sunaddr.sun_family = AF_LOCAL; 01047 ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path)); 01048 res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr)); 01049 if (res) { 01050 ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01051 close(ast_socket); 01052 ast_socket = -1; 01053 return -1; 01054 } 01055 res = listen(ast_socket, 2); 01056 if (res < 0) { 01057 ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01058 close(ast_socket); 01059 ast_socket = -1; 01060 return -1; 01061 } 01062 ast_register_verbose(network_verboser); 01063 ast_pthread_create_background(<hread, NULL, listener, NULL); 01064 01065 if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) { 01066 struct passwd *pw; 01067 if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL) { 01068 ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER); 01069 } else { 01070 uid = pw->pw_uid; 01071 } 01072 } 01073 01074 if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) { 01075 struct group *grp; 01076 if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL) { 01077 ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP); 01078 } else { 01079 gid = grp->gr_gid; 01080 } 01081 } 01082 01083 if (chown(ast_config_AST_SOCKET, uid, gid) < 0) 01084 ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01085 01086 if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) { 01087 int p1; 01088 mode_t p; 01089 sscanf(ast_config_AST_CTL_PERMISSIONS, "%o", &p1); 01090 p = p1; 01091 if ((chmod(ast_config_AST_SOCKET, p)) < 0) 01092 ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); 01093 } 01094 01095 return 0; 01096 }
int64_t ast_mark | ( | int | i, | |
int | startstop | |||
) |
Definition at line 431 of file asterisk.c.
References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, prof_data, rdtsc(), profile_entry::scale, and profile_entry::value.
Referenced by extension_match_core().
00432 { 00433 if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */ 00434 return 0; 00435 if (startstop == 1) 00436 prof_data->e[i].mark = rdtsc(); 00437 else { 00438 prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark); 00439 if (prof_data->e[i].scale > 1) 00440 prof_data->e[i].mark /= prof_data->e[i].scale; 00441 prof_data->e[i].value += prof_data->e[i].mark; 00442 prof_data->e[i].events++; 00443 } 00444 return prof_data->e[i].mark; 00445 }
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 881 of file asterisk.c.
References AST_MAX_CONNECTS, consoles, and fdprint().
Referenced by ast_console_puts().
00882 { 00883 int x; 00884 for (x=0; x < AST_MAX_CONNECTS; x++) { 00885 if (consoles[x].fd > -1) 00886 fdprint(consoles[x].p[1], string); 00887 } 00888 }
static void ast_network_puts_mutable | ( | const char * | string | ) | [static] |
log the string to all attached console clients
Definition at line 856 of file asterisk.c.
References AST_MAX_CONNECTS, consoles, and fdprint().
Referenced by ast_console_puts_mutable(), and network_verboser().
00857 { 00858 int x; 00859 for (x = 0;x < AST_MAX_CONNECTS; x++) { 00860 if (consoles[x].mute) 00861 continue; 00862 if (consoles[x].fd > -1) 00863 fdprint(consoles[x].p[1], string); 00864 } 00865 }
int64_t ast_profile | ( | int | i, | |
int64_t | delta | |||
) |
Definition at line 399 of file asterisk.c.
References profile_data::e, profile_data::entries, profile_entry::events, prof_data, profile_entry::scale, and profile_entry::value.
00400 { 00401 if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */ 00402 return 0; 00403 if (prof_data->e[i].scale > 1) 00404 delta /= prof_data->e[i].scale; 00405 prof_data->e[i].value += delta; 00406 prof_data->e[i].events++; 00407 return prof_data->e[i].value; 00408 }
static void ast_readconfig | ( | void | ) | [static] |
Definition at line 2384 of file asterisk.c.
References ast_config_load(), ast_log(), ast_opt_override_config, ast_variable_browse(), config, LOG_WARNING, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by main().
02385 { 02386 struct ast_config *cfg; 02387 struct ast_variable *v; 02388 char *config = AST_CONFIG_FILE; 02389 02390 if (ast_opt_override_config) { 02391 cfg = ast_config_load(ast_config_AST_CONFIG_FILE); 02392 if (!cfg) 02393 ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE); 02394 } else { 02395 cfg = ast_config_load(config); 02396 } 02397 02398 /* init with buildtime config */ 02399 ast_copy_string(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR, sizeof(ast_config_AST_CONFIG_DIR)); 02400 ast_copy_string(ast_config_AST_SPOOL_DIR, AST_SPOOL_DIR, sizeof(ast_config_AST_SPOOL_DIR)); 02401 ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_MODULE_DIR)); 02402 snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR); 02403 ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR)); 02404 ast_copy_string(ast_config_AST_DATA_DIR, AST_DATA_DIR, sizeof(ast_config_AST_DATA_DIR)); 02405 ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR)); 02406 ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR)); 02407 ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB)); 02408 ast_copy_string(ast_config_AST_KEY_DIR, AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR)); 02409 ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID)); 02410 ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET)); 02411 ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR)); 02412 02413 /* no asterisk.conf? no problem, use buildtime config! */ 02414 if (!cfg) { 02415 return; 02416 } 02417 02418 for (v = ast_variable_browse(cfg, "files"); v; v = v->next) { 02419 if (!strcasecmp(v->name, "astctlpermissions")) { 02420 ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS)); 02421 } else if (!strcasecmp(v->name, "astctlowner")) { 02422 ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER)); 02423 } else if (!strcasecmp(v->name, "astctlgroup")) { 02424 ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP)); 02425 } else if (!strcasecmp(v->name, "astctl")) { 02426 ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL)); 02427 } 02428 } 02429 02430 for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) { 02431 if (!strcasecmp(v->name, "astetcdir")) { 02432 ast_copy_string(ast_config_AST_CONFIG_DIR, v->value, sizeof(ast_config_AST_CONFIG_DIR)); 02433 } else if (!strcasecmp(v->name, "astspooldir")) { 02434 ast_copy_string(ast_config_AST_SPOOL_DIR, v->value, sizeof(ast_config_AST_SPOOL_DIR)); 02435 snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", v->value); 02436 } else if (!strcasecmp(v->name, "astvarlibdir")) { 02437 ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR)); 02438 snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/astdb", v->value); 02439 } else if (!strcasecmp(v->name, "astdatadir")) { 02440 ast_copy_string(ast_config_AST_DATA_DIR, v->value, sizeof(ast_config_AST_DATA_DIR)); 02441 snprintf(ast_config_AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR), "%s/keys", v->value); 02442 } else if (!strcasecmp(v->name, "astlogdir")) { 02443 ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR)); 02444 } else if (!strcasecmp(v->name, "astagidir")) { 02445 ast_copy_string(ast_config_AST_AGI_DIR, v->value, sizeof(ast_config_AST_AGI_DIR)); 02446 } else if (!strcasecmp(v->name, "astrundir")) { 02447 snprintf(ast_config_AST_PID, sizeof(ast_config_AST_PID), "%s/%s", v->value, "asterisk.pid"); 02448 snprintf(ast_config_AST_SOCKET, sizeof(ast_config_AST_SOCKET), "%s/%s", v->value, ast_config_AST_CTL); 02449 ast_copy_string(ast_config_AST_RUN_DIR, v->value, sizeof(ast_config_AST_RUN_DIR)); 02450 } else if (!strcasecmp(v->name, "astmoddir")) { 02451 ast_copy_string(ast_config_AST_MODULE_DIR, v->value, sizeof(ast_config_AST_MODULE_DIR)); 02452 } 02453 } 02454 02455 for (v = ast_variable_browse(cfg, "options"); v; v = v->next) { 02456 /* verbose level (-v at startup) */ 02457 if (!strcasecmp(v->name, "verbose")) { 02458 option_verbose = atoi(v->value); 02459 /* whether or not to force timestamping in CLI verbose output. (-T at startup) */ 02460 } else if (!strcasecmp(v->name, "timestamp")) { 02461 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP); 02462 /* whether or not to support #exec in config files */ 02463 } else if (!strcasecmp(v->name, "execincludes")) { 02464 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES); 02465 /* debug level (-d at startup) */ 02466 } else if (!strcasecmp(v->name, "debug")) { 02467 option_debug = 0; 02468 if (sscanf(v->value, "%d", &option_debug) != 1) { 02469 option_debug = ast_true(v->value); 02470 } 02471 #if HAVE_WORKING_FORK 02472 /* Disable forking (-f at startup) */ 02473 } else if (!strcasecmp(v->name, "nofork")) { 02474 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK); 02475 /* Always fork, even if verbose or debug are enabled (-F at startup) */ 02476 } else if (!strcasecmp(v->name, "alwaysfork")) { 02477 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK); 02478 #endif 02479 /* Run quietly (-q at startup ) */ 02480 } else if (!strcasecmp(v->name, "quiet")) { 02481 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET); 02482 /* Run as console (-c at startup, implies nofork) */ 02483 } else if (!strcasecmp(v->name, "console")) { 02484 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CONSOLE); 02485 /* Run with high priority if the O/S permits (-p at startup) */ 02486 } else if (!strcasecmp(v->name, "highpriority")) { 02487 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY); 02488 /* Initialize RSA auth keys (IAX2) (-i at startup) */ 02489 } else if (!strcasecmp(v->name, "initcrypto")) { 02490 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS); 02491 /* Disable ANSI colors for console (-c at startup) */ 02492 } else if (!strcasecmp(v->name, "nocolor")) { 02493 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR); 02494 /* Disable some usage warnings for picky people :p */ 02495 } else if (!strcasecmp(v->name, "dontwarn")) { 02496 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN); 02497 /* Dump core in case of crash (-g) */ 02498 } else if (!strcasecmp(v->name, "dumpcore")) { 02499 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE); 02500 /* Cache recorded sound files to another directory during recording */ 02501 } else if (!strcasecmp(v->name, "cache_record_files")) { 02502 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES); 02503 /* Specify cache directory */ 02504 } else if (!strcasecmp(v->name, "record_cache_dir")) { 02505 ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN); 02506 /* Build transcode paths via SLINEAR, instead of directly */ 02507 } else if (!strcasecmp(v->name, "transcode_via_sln")) { 02508 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN); 02509 /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */ 02510 } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) { 02511 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE); 02512 /* Enable internal timing */ 02513 } else if (!strcasecmp(v->name, "internal_timing")) { 02514 ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING); 02515 } else if (!strcasecmp(v->name, "maxcalls")) { 02516 if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) { 02517 option_maxcalls = 0; 02518 } 02519 } else if (!strcasecmp(v->name, "maxload")) { 02520 double test[1]; 02521 02522 if (getloadavg(test, 1) == -1) { 02523 ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n"); 02524 option_maxload = 0.0; 02525 } else if ((sscanf(v->value, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) { 02526 option_maxload = 0.0; 02527 } 02528 /* Set the maximum amount of open files */ 02529 } else if (!strcasecmp(v->name, "maxfiles")) { 02530 set_ulimit(atoi(v->value)); 02531 /* What user to run as */ 02532 } else if (!strcasecmp(v->name, "runuser")) { 02533 ast_copy_string(ast_config_AST_RUN_USER, v->value, sizeof(ast_config_AST_RUN_USER)); 02534 /* What group to run as */ 02535 } else if (!strcasecmp(v->name, "rungroup")) { 02536 ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP)); 02537 } else if (!strcasecmp(v->name, "systemname")) { 02538 ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME)); 02539 } else if (!strcasecmp(v->name, "languageprefix")) { 02540 ast_language_is_prefix = ast_true(v->value); 02541 } 02542 } 02543 ast_config_destroy(cfg); 02544 }
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 699 of file asterisk.c.
References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, and ast_unregister_atexit().
Referenced by do_reload(), and load_module().
00700 { 00701 struct ast_atexit *ae; 00702 00703 if (!(ae = ast_calloc(1, sizeof(*ae)))) 00704 return -1; 00705 00706 ae->func = func; 00707 00708 ast_unregister_atexit(func); 00709 00710 AST_LIST_LOCK(&atexits); 00711 AST_LIST_INSERT_HEAD(&atexits, ae, list); 00712 AST_LIST_UNLOCK(&atexits); 00713 00714 return 0; 00715 }
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 253 of file asterisk.c.
References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_strdupa, and ast_strip_quoted().
00254 { 00255 struct file_version *new; 00256 char *work; 00257 size_t version_length; 00258 00259 work = ast_strdupa(version); 00260 work = ast_strip(ast_strip_quoted(work, "$", "$")); 00261 version_length = strlen(work) + 1; 00262 00263 if (!(new = ast_calloc(1, sizeof(*new) + version_length))) 00264 return; 00265 00266 new->file = file; 00267 new->version = (char *) new + sizeof(*new); 00268 memcpy(new->version, work, version_length); 00269 AST_LIST_LOCK(&file_versions); 00270 AST_LIST_INSERT_HEAD(&file_versions, new, list); 00271 AST_LIST_UNLOCK(&file_versions); 00272 }
void ast_register_thread | ( | char * | name | ) |
Definition at line 303 of file asterisk.c.
References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, and AST_LIST_UNLOCK.
Referenced by dummy_start().
00304 { 00305 struct thread_list_t *new = ast_calloc(1, sizeof(*new)); 00306 00307 if (!new) 00308 return; 00309 new->id = pthread_self(); 00310 new->name = name; /* steal the allocated memory for the thread name */ 00311 AST_LIST_LOCK(&thread_list); 00312 AST_LIST_INSERT_HEAD(&thread_list, new, list); 00313 AST_LIST_UNLOCK(&thread_list); 00314 }
static void ast_remotecontrol | ( | char * | data | ) | [static] |
Definition at line 2259 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().
02260 { 02261 char buf[80]; 02262 int res; 02263 char filename[80] = ""; 02264 char *hostname; 02265 char *cpid; 02266 char *version; 02267 int pid; 02268 char tmp[80]; 02269 char *stringp = NULL; 02270 02271 char *ebuf; 02272 int num = 0; 02273 02274 read(ast_consock, buf, sizeof(buf)); 02275 if (data) 02276 write(ast_consock, data, strlen(data) + 1); 02277 stringp = buf; 02278 hostname = strsep(&stringp, "/"); 02279 cpid = strsep(&stringp, "/"); 02280 version = strsep(&stringp, "\n"); 02281 if (!version) 02282 version = "<Version Unknown>"; 02283 stringp = hostname; 02284 strsep(&stringp, "."); 02285 if (cpid) 02286 pid = atoi(cpid); 02287 else 02288 pid = -1; 02289 if (!data) { 02290 snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose); 02291 fdprint(ast_consock, tmp); 02292 snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug); 02293 fdprint(ast_consock, tmp); 02294 if (!ast_opt_mute) 02295 fdprint(ast_consock, "logger mute silent"); 02296 else 02297 printf("log and verbose output currently muted ('logger mute' to unmute)\n"); 02298 } 02299 ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid); 02300 remotehostname = hostname; 02301 if (getenv("HOME")) 02302 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); 02303 if (el_hist == NULL || el == NULL) 02304 ast_el_initialize(); 02305 02306 el_set(el, EL_GETCFN, ast_el_read_char); 02307 02308 if (!ast_strlen_zero(filename)) 02309 ast_el_read_history(filename); 02310 02311 if (ast_opt_exec && data) { /* hack to print output then exit if asterisk -rx is used */ 02312 char tempchar; 02313 struct pollfd fds; 02314 fds.fd = ast_consock; 02315 fds.events = POLLIN; 02316 fds.revents = 0; 02317 while (poll(&fds, 1, 100) > 0) 02318 ast_el_read_char(el, &tempchar); 02319 return; 02320 } 02321 for (;;) { 02322 ebuf = (char *)el_gets(el, &num); 02323 02324 if (!ebuf && write(1, "", 1) < 0) 02325 break; 02326 02327 if (!ast_strlen_zero(ebuf)) { 02328 if (ebuf[strlen(ebuf)-1] == '\n') 02329 ebuf[strlen(ebuf)-1] = '\0'; 02330 if (!remoteconsolehandler(ebuf)) { 02331 res = write(ast_consock, ebuf, strlen(ebuf) + 1); 02332 if (res < 1) { 02333 ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno)); 02334 break; 02335 } 02336 } 02337 } 02338 } 02339 printf("\nDisconnected from Asterisk server\n"); 02340 }
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 752 of file asterisk.c.
References ast_mutex_lock(), ast_mutex_unlock(), and null_sig_handler().
Referenced by ast_safe_system().
00753 { 00754 unsigned int level; 00755 00756 ast_mutex_lock(&safe_system_lock); 00757 level = safe_system_level++; 00758 00759 /* only replace the handler if it has not already been done */ 00760 if (level == 0) 00761 safe_system_prev_handler = signal(SIGCHLD, null_sig_handler); 00762 00763 ast_mutex_unlock(&safe_system_lock); 00764 }
static void ast_run_atexits | ( | void | ) | [static] |
Definition at line 1231 of file asterisk.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_atexit::func.
Referenced by quit_handler().
01232 { 01233 struct ast_atexit *ae; 01234 AST_LIST_LOCK(&atexits); 01235 AST_LIST_TRAVERSE(&atexits, ae, list) { 01236 if (ae->func) 01237 ae->func(); 01238 } 01239 AST_LIST_UNLOCK(&atexits); 01240 }
int ast_safe_system | ( | const char * | s | ) |
Safely spawn an external program while closing file descriptors
Definition at line 780 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().
00781 { 00782 pid_t pid; 00783 #ifdef HAVE_WORKING_FORK 00784 int x; 00785 #endif 00786 int res; 00787 struct rusage rusage; 00788 int status; 00789 00790 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK) 00791 ast_replace_sigchld(); 00792 00793 #ifdef HAVE_WORKING_FORK 00794 pid = fork(); 00795 #else 00796 pid = vfork(); 00797 #endif 00798 00799 if (pid == 0) { 00800 #ifdef HAVE_WORKING_FORK 00801 if (ast_opt_high_priority) 00802 ast_set_priority(0); 00803 /* Close file descriptors and launch system command */ 00804 for (x = STDERR_FILENO + 1; x < 4096; x++) 00805 close(x); 00806 #endif 00807 execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL); 00808 _exit(1); 00809 } else if (pid > 0) { 00810 for(;;) { 00811 res = wait4(pid, &status, 0, &rusage); 00812 if (res > -1) { 00813 res = WIFEXITED(status) ? WEXITSTATUS(status) : -1; 00814 break; 00815 } else if (errno != EINTR) 00816 break; 00817 } 00818 } else { 00819 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno)); 00820 res = -1; 00821 } 00822 00823 ast_unreplace_sigchld(); 00824 #else 00825 res = -1; 00826 #endif 00827 00828 return res; 00829 }
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 1197 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().
01198 { 01199 struct sched_param sched; 01200 memset(&sched, 0, sizeof(sched)); 01201 #ifdef __linux__ 01202 if (pri) { 01203 sched.sched_priority = 10; 01204 if (sched_setscheduler(0, SCHED_RR, &sched)) { 01205 ast_log(LOG_WARNING, "Unable to set high priority\n"); 01206 return -1; 01207 } else 01208 if (option_verbose) 01209 ast_verbose("Set to realtime thread\n"); 01210 } else { 01211 sched.sched_priority = 0; 01212 /* According to the manpage, these parameters can never fail. */ 01213 sched_setscheduler(0, SCHED_OTHER, &sched); 01214 } 01215 #else 01216 if (pri) { 01217 if (setpriority(PRIO_PROCESS, 0, -10) == -1) { 01218 ast_log(LOG_WARNING, "Unable to set high priority\n"); 01219 return -1; 01220 } else 01221 if (option_verbose) 01222 ast_verbose("Set to high priority\n"); 01223 } else { 01224 /* According to the manpage, these parameters can never fail. */ 01225 setpriority(PRIO_PROCESS, 0, 0); 01226 } 01227 #endif 01228 return 0; 01229 }
static int ast_tryconnect | ( | void | ) | [static] |
Definition at line 1098 of file asterisk.c.
References AF_LOCAL, ast_log(), errno, LOG_WARNING, and PF_LOCAL.
Referenced by ast_el_read_char(), and main().
01099 { 01100 struct sockaddr_un sunaddr; 01101 int res; 01102 ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0); 01103 if (ast_consock < 0) { 01104 ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); 01105 return 0; 01106 } 01107 memset(&sunaddr, 0, sizeof(sunaddr)); 01108 sunaddr.sun_family = AF_LOCAL; 01109 ast_copy_string(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path)); 01110 res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)); 01111 if (res) { 01112 close(ast_consock); 01113 ast_consock = -1; 01114 return 0; 01115 } else 01116 return 1; 01117 }
void ast_unregister_atexit | ( | void(*)(void) | func | ) |
Unregister a function registered with ast_register_atexit().
func | The callback function to unregister. |
Definition at line 717 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, and ast_atexit::func.
Referenced by ast_register_atexit(), and do_reload().
00718 { 00719 struct ast_atexit *ae = NULL; 00720 00721 AST_LIST_LOCK(&atexits); 00722 AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) { 00723 if (ae->func == func) { 00724 AST_LIST_REMOVE_CURRENT(&atexits, list); 00725 break; 00726 } 00727 } 00728 AST_LIST_TRAVERSE_SAFE_END 00729 AST_LIST_UNLOCK(&atexits); 00730 00731 if (ae) 00732 free(ae); 00733 }
void ast_unregister_file_version | ( | const char * | file | ) |
Unregister a source code file from the core.
file | the source file name |
Definition at line 274 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.
00275 { 00276 struct file_version *find; 00277 00278 AST_LIST_LOCK(&file_versions); 00279 AST_LIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) { 00280 if (!strcasecmp(find->file, file)) { 00281 AST_LIST_REMOVE_CURRENT(&file_versions, list); 00282 break; 00283 } 00284 } 00285 AST_LIST_TRAVERSE_SAFE_END; 00286 AST_LIST_UNLOCK(&file_versions); 00287 if (find) 00288 free(find); 00289 }
void ast_unregister_thread | ( | void * | id | ) |
Definition at line 316 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().
00317 { 00318 struct thread_list_t *x; 00319 00320 AST_LIST_LOCK(&thread_list); 00321 AST_LIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) { 00322 if ((void *) x->id == id) { 00323 AST_LIST_REMOVE_CURRENT(&thread_list, list); 00324 break; 00325 } 00326 } 00327 AST_LIST_TRAVERSE_SAFE_END; 00328 AST_LIST_UNLOCK(&thread_list); 00329 if (x) { 00330 free(x->name); 00331 free(x); 00332 } 00333 }
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 766 of file asterisk.c.
References ast_mutex_lock(), and ast_mutex_unlock().
Referenced by agi_exec_full(), and ast_safe_system().
00767 { 00768 unsigned int level; 00769 00770 ast_mutex_lock(&safe_system_lock); 00771 level = --safe_system_level; 00772 00773 /* only restore the handler if we are the last one */ 00774 if (level == 0) 00775 signal(SIGCHLD, safe_system_prev_handler); 00776 00777 ast_mutex_unlock(&safe_system_lock); 00778 }
static void child_handler | ( | int | sig | ) | [static] |
Definition at line 1144 of file asterisk.c.
Referenced by main().
01145 { 01146 /* Must not ever ast_log or ast_verbose within signal handler */ 01147 int n, status; 01148 01149 /* 01150 * Reap all dead children -- not just one 01151 */ 01152 for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++) 01153 ; 01154 if (n == 0 && option_debug) 01155 printf("Huh? Child handler, but nobody there?\n"); 01156 signal(sig, child_handler); 01157 }
static char* cli_complete | ( | EditLine * | el, | |
int | ch | |||
) | [static] |
Definition at line 2066 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().
02067 { 02068 int len = 0; 02069 char *ptr; 02070 int nummatches = 0; 02071 char **matches; 02072 int retval = CC_ERROR; 02073 char buf[2048]; 02074 int res; 02075 02076 LineInfo *lf = (LineInfo *)el_line(el); 02077 02078 *(char *)lf->cursor = '\0'; 02079 ptr = (char *)lf->cursor; 02080 if (ptr) { 02081 while (ptr > lf->buffer) { 02082 if (isspace(*ptr)) { 02083 ptr++; 02084 break; 02085 } 02086 ptr--; 02087 } 02088 } 02089 02090 len = lf->cursor - ptr; 02091 02092 if (ast_opt_remote) { 02093 snprintf(buf, sizeof(buf),"_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 02094 fdprint(ast_consock, buf); 02095 res = read(ast_consock, buf, sizeof(buf)); 02096 buf[res] = '\0'; 02097 nummatches = atoi(buf); 02098 02099 if (nummatches > 0) { 02100 char *mbuf; 02101 int mlen = 0, maxmbuf = 2048; 02102 /* Start with a 2048 byte buffer */ 02103 if (!(mbuf = ast_malloc(maxmbuf))) 02104 return (char *)(CC_ERROR); 02105 snprintf(buf, sizeof(buf),"_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 02106 fdprint(ast_consock, buf); 02107 res = 0; 02108 mbuf[0] = '\0'; 02109 while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) { 02110 if (mlen + 1024 > maxmbuf) { 02111 /* Every step increment buffer 1024 bytes */ 02112 maxmbuf += 1024; 02113 if (!(mbuf = ast_realloc(mbuf, maxmbuf))) 02114 return (char *)(CC_ERROR); 02115 } 02116 /* Only read 1024 bytes at a time */ 02117 res = read(ast_consock, mbuf + mlen, 1024); 02118 if (res > 0) 02119 mlen += res; 02120 } 02121 mbuf[mlen] = '\0'; 02122 02123 matches = ast_el_strtoarr(mbuf); 02124 free(mbuf); 02125 } else 02126 matches = (char **) NULL; 02127 } else { 02128 char **p, *oldbuf=NULL; 02129 nummatches = 0; 02130 matches = ast_cli_completion_matches((char *)lf->buffer,ptr); 02131 for (p = matches; p && *p; p++) { 02132 if (!oldbuf || strcmp(*p,oldbuf)) 02133 nummatches++; 02134 oldbuf = *p; 02135 } 02136 } 02137 02138 if (matches) { 02139 int i; 02140 int matches_num, maxlen, match_len; 02141 02142 if (matches[0][0] != '\0') { 02143 el_deletestr(el, (int) len); 02144 el_insertstr(el, matches[0]); 02145 retval = CC_REFRESH; 02146 } 02147 02148 if (nummatches == 1) { 02149 /* Found an exact match */ 02150 el_insertstr(el, " "); 02151 retval = CC_REFRESH; 02152 } else { 02153 /* Must be more than one match */ 02154 for (i=1, maxlen=0; matches[i]; i++) { 02155 match_len = strlen(matches[i]); 02156 if (match_len > maxlen) 02157 maxlen = match_len; 02158 } 02159 matches_num = i - 1; 02160 if (matches_num >1) { 02161 fprintf(stdout, "\n"); 02162 ast_cli_display_match_list(matches, nummatches, maxlen); 02163 retval = CC_REDISPLAY; 02164 } else { 02165 el_insertstr(el," "); 02166 retval = CC_REFRESH; 02167 } 02168 } 02169 for (i = 0; matches[i]; i++) 02170 free(matches[i]); 02171 free(matches); 02172 } 02173 02174 return (char *)(long)retval; 02175 }
static char* cli_prompt | ( | EditLine * | el | ) | [static] |
Definition at line 1824 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().
01825 { 01826 static char prompt[200]; 01827 char *pfmt; 01828 int color_used = 0; 01829 char term_code[20]; 01830 01831 if ((pfmt = getenv("ASTERISK_PROMPT"))) { 01832 char *t = pfmt, *p = prompt; 01833 memset(prompt, 0, sizeof(prompt)); 01834 while (*t != '\0' && *p < sizeof(prompt)) { 01835 if (*t == '%') { 01836 char hostname[MAXHOSTNAMELEN]=""; 01837 int i; 01838 time_t ts; 01839 struct tm tm; 01840 #ifdef linux 01841 FILE *LOADAVG; 01842 #endif 01843 int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK; 01844 01845 t++; 01846 switch (*t) { 01847 case 'C': /* color */ 01848 t++; 01849 if (sscanf(t, "%d;%d%n", &fgcolor, &bgcolor, &i) == 2) { 01850 strncat(p, term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1); 01851 t += i - 1; 01852 } else if (sscanf(t, "%d%n", &fgcolor, &i) == 1) { 01853 strncat(p, term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1); 01854 t += i - 1; 01855 } 01856 01857 /* If the color has been reset correctly, then there's no need to reset it later */ 01858 if ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) { 01859 color_used = 0; 01860 } else { 01861 color_used = 1; 01862 } 01863 break; 01864 case 'd': /* date */ 01865 memset(&tm, 0, sizeof(tm)); 01866 time(&ts); 01867 if (ast_localtime(&ts, &tm, NULL)) { 01868 strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm); 01869 } 01870 break; 01871 case 'h': /* hostname */ 01872 if (!gethostname(hostname, sizeof(hostname) - 1)) { 01873 strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1); 01874 } else { 01875 strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1); 01876 } 01877 break; 01878 case 'H': /* short hostname */ 01879 if (!gethostname(hostname, sizeof(hostname) - 1)) { 01880 for (i = 0; i < sizeof(hostname); i++) { 01881 if (hostname[i] == '.') { 01882 hostname[i] = '\0'; 01883 break; 01884 } 01885 } 01886 strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1); 01887 } else { 01888 strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1); 01889 } 01890 break; 01891 #ifdef linux 01892 case 'l': /* load avg */ 01893 t++; 01894 if ((LOADAVG = fopen("/proc/loadavg", "r"))) { 01895 float avg1, avg2, avg3; 01896 int actproc, totproc, npid, which; 01897 fscanf(LOADAVG, "%f %f %f %d/%d %d", 01898 &avg1, &avg2, &avg3, &actproc, &totproc, &npid); 01899 if (sscanf(t, "%d", &which) == 1) { 01900 switch (which) { 01901 case 1: 01902 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1); 01903 break; 01904 case 2: 01905 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2); 01906 break; 01907 case 3: 01908 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3); 01909 break; 01910 case 4: 01911 snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc); 01912 break; 01913 case 5: 01914 snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid); 01915 break; 01916 } 01917 } 01918 } 01919 break; 01920 #endif 01921 case 's': /* Asterisk system name (from asterisk.conf) */ 01922 strncat(p, ast_config_AST_SYSTEM_NAME, sizeof(prompt) - strlen(prompt) - 1); 01923 break; 01924 case 't': /* time */ 01925 memset(&tm, 0, sizeof(tm)); 01926 time(&ts); 01927 if (ast_localtime(&ts, &tm, NULL)) { 01928 strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm); 01929 } 01930 break; 01931 case '#': /* process console or remote? */ 01932 if (!ast_opt_remote) { 01933 strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1); 01934 } else { 01935 strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1); 01936 } 01937 break; 01938 case '%': /* literal % */ 01939 strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1); 01940 break; 01941 case '\0': /* % is last character - prevent bug */ 01942 t--; 01943 break; 01944 } 01945 while (*p != '\0') { 01946 p++; 01947 } 01948 t++; 01949 } else { 01950 *p = *t; 01951 p++; 01952 t++; 01953 } 01954 } 01955 if (color_used) { 01956 /* Force colors back to normal at end */ 01957 term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code)); 01958 if (strlen(term_code) > sizeof(prompt) - strlen(prompt) - 1) { 01959 ast_copy_string(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code) + 1); 01960 } else { 01961 /* This looks wrong, but we've already checked the length of term_code to ensure it's safe */ 01962 strncat(p, term_code, sizeof(term_code)); 01963 } 01964 } 01965 } else if (remotehostname) 01966 snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT2, remotehostname); 01967 else 01968 snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT); 01969 01970 return(prompt); 01971 }
static char* complete_show_version_files | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 675 of file asterisk.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.
00676 { 00677 struct file_version *find; 00678 int which = 0; 00679 char *ret = NULL; 00680 int matchlen = strlen(word); 00681 00682 if (pos != 4) 00683 return NULL; 00684 00685 AST_LIST_LOCK(&file_versions); 00686 AST_LIST_TRAVERSE(&file_versions, find, list) { 00687 if (!strncasecmp(word, find->file, matchlen) && ++which > state) { 00688 ret = ast_strdup(find->file); 00689 break; 00690 } 00691 } 00692 AST_LIST_UNLOCK(&file_versions); 00693 00694 return ret; 00695 }
static char* complete_show_version_files_deprecated | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 653 of file asterisk.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.
00654 { 00655 struct file_version *find; 00656 int which = 0; 00657 char *ret = NULL; 00658 int matchlen = strlen(word); 00659 00660 if (pos != 3) 00661 return NULL; 00662 00663 AST_LIST_LOCK(&file_versions); 00664 AST_LIST_TRAVERSE(&file_versions, find, list) { 00665 if (!strncasecmp(word, find->file, matchlen) && ++which > state) { 00666 ret = ast_strdup(find->file); 00667 break; 00668 } 00669 } 00670 AST_LIST_UNLOCK(&file_versions); 00671 00672 return ret; 00673 }
static void console_verboser | ( | const char * | s | ) | [static] |
Definition at line 1373 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().
01374 { 01375 char tmp[80]; 01376 const char *c = NULL; 01377 01378 if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) || 01379 (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) || 01380 (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) || 01381 (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) { 01382 fputs(tmp, stdout); 01383 fputs(c, stdout); 01384 } else 01385 fputs(s, stdout); 01386 01387 fflush(stdout); 01388 01389 /* Wake up a poll()ing console */ 01390 if (ast_opt_console && consolethread != AST_PTHREADT_NULL) 01391 pthread_kill(consolethread, SIGURG); 01392 }
static void consolehandler | ( | char * | s | ) | [static] |
Definition at line 1404 of file asterisk.c.
References ast_all_zeros(), ast_cli_command(), ast_el_add_history(), ast_safe_system(), and term_end().
Referenced by main().
01405 { 01406 printf(term_end()); 01407 fflush(stdout); 01408 01409 /* Called when readline data is available */ 01410 if (!ast_all_zeros(s)) 01411 ast_el_add_history(s); 01412 /* The real handler for bang */ 01413 if (s[0] == '!') { 01414 if (s[1]) 01415 ast_safe_system(s+1); 01416 else 01417 ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); 01418 } else 01419 ast_cli_command(STDOUT_FILENO, s); 01420 }
static int fdprint | ( | int | fd, | |
const char * | s | |||
) | [static] |
Definition at line 735 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 1362 of file asterisk.c.
References COLOR_GRAY, and term_color().
Referenced by console_verboser().
01363 { 01364 const char *c; 01365 if (!strncmp(s, cmp, strlen(cmp))) { 01366 c = s + strlen(cmp); 01367 term_color(outbuf, cmp, COLOR_GRAY, 0, maxout); 01368 return c; 01369 } 01370 return NULL; 01371 }
static int handle_abort_halt | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1574 of file asterisk.c.
References ast_cancel_shutdown(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01575 { 01576 if (argc != 2) 01577 return RESULT_SHOWUSAGE; 01578 ast_cancel_shutdown(); 01579 shuttingdown = 0; 01580 return RESULT_SUCCESS; 01581 }
static int handle_bang | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1583 of file asterisk.c.
References RESULT_SUCCESS.
01584 { 01585 return RESULT_SUCCESS; 01586 }
static int handle_restart_gracefully | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1557 of file asterisk.c.
References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01558 { 01559 if (argc != 2) 01560 return RESULT_SHOWUSAGE; 01561 quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */); 01562 return RESULT_SUCCESS; 01563 }
static int handle_restart_now | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1549 of file asterisk.c.
References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01550 { 01551 if (argc != 2) 01552 return RESULT_SHOWUSAGE; 01553 quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */); 01554 return RESULT_SUCCESS; 01555 }
static int handle_restart_when_convenient | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1565 of file asterisk.c.
References ast_cli(), quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01566 { 01567 if (argc != 3) 01568 return RESULT_SHOWUSAGE; 01569 ast_cli(fd, "Waiting for inactivity to perform restart\n"); 01570 quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */); 01571 return RESULT_SUCCESS; 01572 }
static int handle_show_profile | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 493 of file asterisk.c.
References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::name, prof_data, and profile_entry::value.
00494 { 00495 int i, min, max; 00496 char *search = NULL; 00497 00498 if (prof_data == NULL) 00499 return 0; 00500 00501 min = 0; 00502 max = prof_data->entries; 00503 if (argc > 3) { /* specific entries */ 00504 if (isdigit(argv[3][0])) { 00505 min = atoi(argv[3]); 00506 if (argc == 5 && strcmp(argv[4], "-")) 00507 max = atoi(argv[4]); 00508 } else 00509 search = argv[3]; 00510 } 00511 if (max > prof_data->entries) 00512 max = prof_data->entries; 00513 if (!strcmp(argv[1], "clear")) { 00514 for (i= min; i < max; i++) { 00515 if (!search || strstr(prof_data->e[i].name, search)) { 00516 prof_data->e[i].value = 0; 00517 prof_data->e[i].events = 0; 00518 } 00519 } 00520 return 0; 00521 } 00522 ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n", 00523 prof_data->entries, prof_data->max_size); 00524 ast_cli(fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events", 00525 "Value", "Average", "Name"); 00526 for (i = min; i < max; i++) { 00527 struct profile_entry *e = &prof_data->e[i]; 00528 if (!search || strstr(prof_data->e[i].name, search)) 00529 ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n", 00530 i, 00531 (long)e->scale, 00532 (long)e->events, (long long)e->value, 00533 (long long)(e->events ? e->value / e->events : e->value), 00534 e->name); 00535 } 00536 return 0; 00537 }
static int handle_show_profile_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 447 of file asterisk.c.
References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::name, prof_data, and profile_entry::value.
00448 { 00449 int i, min, max; 00450 char *search = NULL; 00451 00452 if (prof_data == NULL) 00453 return 0; 00454 00455 min = 0; 00456 max = prof_data->entries; 00457 if (argc >= 3) { /* specific entries */ 00458 if (isdigit(argv[2][0])) { 00459 min = atoi(argv[2]); 00460 if (argc == 4 && strcmp(argv[3], "-")) 00461 max = atoi(argv[3]); 00462 } else 00463 search = argv[2]; 00464 } 00465 if (max > prof_data->entries) 00466 max = prof_data->entries; 00467 if (!strcmp(argv[0], "clear")) { 00468 for (i= min; i < max; i++) { 00469 if (!search || strstr(prof_data->e[i].name, search)) { 00470 prof_data->e[i].value = 0; 00471 prof_data->e[i].events = 0; 00472 } 00473 } 00474 return 0; 00475 } 00476 ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n", 00477 prof_data->entries, prof_data->max_size); 00478 ast_cli(fd, "%6s %8s %10s %12s %12s %s\n", "ID", "Scale", "Events", 00479 "Value", "Average", "Name"); 00480 for (i = min; i < max; i++) { 00481 struct profile_entry *e = &prof_data->e[i]; 00482 if (!search || strstr(prof_data->e[i].name, search)) 00483 ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n", 00484 i, 00485 (long)e->scale, 00486 (long)e->events, (long long)e->value, 00487 (long long)(e->events ? e->value / e->events : e->value), 00488 e->name); 00489 } 00490 return 0; 00491 }
static int handle_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 335 of file asterisk.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.
00336 { 00337 int count = 0; 00338 struct thread_list_t *cur; 00339 00340 AST_LIST_LOCK(&thread_list); 00341 AST_LIST_TRAVERSE(&thread_list, cur, list) { 00342 ast_cli(fd, "%p %s\n", (void *)cur->id, cur->name); 00343 count++; 00344 } 00345 AST_LIST_UNLOCK(&thread_list); 00346 ast_cli(fd, "%d threads listed.\n", count); 00347 return 0; 00348 }
static int handle_show_version_files | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 599 of file asterisk.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, FORMAT, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00600 { 00601 #define FORMAT "%-25.25s %-40.40s\n" 00602 struct file_version *iterator; 00603 regex_t regexbuf; 00604 int havepattern = 0; 00605 int havename = 0; 00606 int count_files = 0; 00607 00608 switch (argc) { 00609 case 6: 00610 if (!strcasecmp(argv[4], "like")) { 00611 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 00612 return RESULT_SHOWUSAGE; 00613 havepattern = 1; 00614 } else 00615 return RESULT_SHOWUSAGE; 00616 break; 00617 case 5: 00618 havename = 1; 00619 break; 00620 case 4: 00621 break; 00622 default: 00623 return RESULT_SHOWUSAGE; 00624 } 00625 00626 ast_cli(fd, FORMAT, "File", "Revision"); 00627 ast_cli(fd, FORMAT, "----", "--------"); 00628 AST_LIST_LOCK(&file_versions); 00629 AST_LIST_TRAVERSE(&file_versions, iterator, list) { 00630 if (havename && strcasecmp(iterator->file, argv[4])) 00631 continue; 00632 00633 if (havepattern && regexec(®exbuf, iterator->file, 0, NULL, 0)) 00634 continue; 00635 00636 ast_cli(fd, FORMAT, iterator->file, iterator->version); 00637 count_files++; 00638 if (havename) 00639 break; 00640 } 00641 AST_LIST_UNLOCK(&file_versions); 00642 if (!havename) { 00643 ast_cli(fd, "%d files listed.\n", count_files); 00644 } 00645 00646 if (havepattern) 00647 regfree(®exbuf); 00648 00649 return RESULT_SUCCESS; 00650 #undef FORMAT 00651 }
static int handle_show_version_files_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list module versions.
Definition at line 545 of file asterisk.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, FORMAT, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00546 { 00547 #define FORMAT "%-25.25s %-40.40s\n" 00548 struct file_version *iterator; 00549 regex_t regexbuf; 00550 int havepattern = 0; 00551 int havename = 0; 00552 int count_files = 0; 00553 00554 switch (argc) { 00555 case 5: 00556 if (!strcasecmp(argv[3], "like")) { 00557 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 00558 return RESULT_SHOWUSAGE; 00559 havepattern = 1; 00560 } else 00561 return RESULT_SHOWUSAGE; 00562 break; 00563 case 4: 00564 havename = 1; 00565 break; 00566 case 3: 00567 break; 00568 default: 00569 return RESULT_SHOWUSAGE; 00570 } 00571 00572 ast_cli(fd, FORMAT, "File", "Revision"); 00573 ast_cli(fd, FORMAT, "----", "--------"); 00574 AST_LIST_LOCK(&file_versions); 00575 AST_LIST_TRAVERSE(&file_versions, iterator, list) { 00576 if (havename && strcasecmp(iterator->file, argv[3])) 00577 continue; 00578 00579 if (havepattern && regexec(®exbuf, iterator->file, 0, NULL, 0)) 00580 continue; 00581 00582 ast_cli(fd, FORMAT, iterator->file, iterator->version); 00583 count_files++; 00584 if (havename) 00585 break; 00586 } 00587 AST_LIST_UNLOCK(&file_versions); 00588 if (!havename) { 00589 ast_cli(fd, "%d files listed.\n", count_files); 00590 } 00591 00592 if (havepattern) 00593 regfree(®exbuf); 00594 00595 return RESULT_SUCCESS; 00596 #undef FORMAT 00597 }
static int handle_shutdown_gracefully | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1532 of file asterisk.c.
References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01533 { 01534 if (argc != 2) 01535 return RESULT_SHOWUSAGE; 01536 quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */); 01537 return RESULT_SUCCESS; 01538 }
static int handle_shutdown_now | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1524 of file asterisk.c.
References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01525 { 01526 if (argc != 2) 01527 return RESULT_SHOWUSAGE; 01528 quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */); 01529 return RESULT_SUCCESS; 01530 }
static int handle_shutdown_when_convenient | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1540 of file asterisk.c.
References ast_cli(), quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01541 { 01542 if (argc != 3) 01543 return RESULT_SHOWUSAGE; 01544 ast_cli(fd, "Waiting for inactivity to perform halt\n"); 01545 quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */); 01546 return RESULT_SUCCESS; 01547 }
static int handle_version | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1504 of file asterisk.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01505 { 01506 if (argc != 3) 01507 return RESULT_SHOWUSAGE; 01508 ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n", 01509 ASTERISK_VERSION, ast_build_user, ast_build_hostname, 01510 ast_build_machine, ast_build_os, ast_build_date); 01511 return RESULT_SUCCESS; 01512 }
static int handle_version_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1494 of file asterisk.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01495 { 01496 if (argc != 2) 01497 return RESULT_SHOWUSAGE; 01498 ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n", 01499 ASTERISK_VERSION, ast_build_user, ast_build_hostname, 01500 ast_build_machine, ast_build_os, ast_build_date); 01501 return RESULT_SUCCESS; 01502 }
static void hup_handler | ( | int | num | ) | [static] |
Definition at line 1131 of file asterisk.c.
References sig_flags.
Referenced by main().
01132 { 01133 int a = 0; 01134 if (option_verbose > 1) 01135 printf("Received HUP signal -- Reloading configs\n"); 01136 if (restartnow) 01137 execvp(_argv[0], _argv); 01138 sig_flags.need_reload = 1; 01139 if (sig_alert_pipe[1] != -1) 01140 write(sig_alert_pipe[1], &a, sizeof(a)); 01141 signal(num, hup_handler); 01142 }
static void* listener | ( | void * | unused | ) | [static] |
Definition at line 963 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().
00964 { 00965 struct sockaddr_un sunaddr; 00966 int s; 00967 socklen_t len; 00968 int x; 00969 int flags; 00970 struct pollfd fds[1]; 00971 pthread_attr_t attr; 00972 pthread_attr_init(&attr); 00973 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00974 for (;;) { 00975 if (ast_socket < 0) 00976 return NULL; 00977 fds[0].fd = ast_socket; 00978 fds[0].events = POLLIN; 00979 s = poll(fds, 1, -1); 00980 pthread_testcancel(); 00981 if (s < 0) { 00982 if (errno != EINTR) 00983 ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno)); 00984 continue; 00985 } 00986 len = sizeof(sunaddr); 00987 s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len); 00988 if (s < 0) { 00989 if (errno != EINTR) 00990 ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno)); 00991 } else { 00992 for (x = 0; x < AST_MAX_CONNECTS; x++) { 00993 if (consoles[x].fd < 0) { 00994 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) { 00995 ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno)); 00996 consoles[x].fd = -1; 00997 fdprint(s, "Server failed to create pipe\n"); 00998 close(s); 00999 break; 01000 } 01001 flags = fcntl(consoles[x].p[1], F_GETFL); 01002 fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK); 01003 consoles[x].fd = s; 01004 consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */ 01005 if (ast_pthread_create_background(&consoles[x].t, &attr, netconsole, &consoles[x])) { 01006 ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno)); 01007 close(consoles[x].p[0]); 01008 close(consoles[x].p[1]); 01009 consoles[x].fd = -1; 01010 fdprint(s, "Server failed to spawn thread\n"); 01011 close(s); 01012 } 01013 break; 01014 } 01015 } 01016 if (x >= AST_MAX_CONNECTS) { 01017 fdprint(s, "No more connections allowed\n"); 01018 ast_log(LOG_WARNING, "No more connections allowed\n"); 01019 close(s); 01020 } else if (consoles[x].fd > -1) { 01021 if (option_verbose > 2) 01022 ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection\n"); 01023 } 01024 } 01025 } 01026 return NULL; 01027 }
int main | ( | int | argc, | |
char * | argv[] | |||
) |
Definition at line 2566 of file asterisk.c.
References __ast_mm_init(), __quit_handler(), ast_alaw_init(), ast_autoservice_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_options, ast_pthread_create, ast_readconfig(), ast_register_verbose(), ast_remotecontrol(), ast_rtp_init(), ast_set_flag, ast_set_priority(), ast_strdupa, 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(), cli_asterisk, 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.
02567 { 02568 int c; 02569 char filename[80] = ""; 02570 char hostname[MAXHOSTNAMELEN] = ""; 02571 char tmp[80]; 02572 char * xarg = NULL; 02573 int x; 02574 FILE *f; 02575 sigset_t sigs; 02576 int num; 02577 int isroot = 1; 02578 char *buf; 02579 char *runuser = NULL, *rungroup = NULL; 02580 02581 /* Remember original args for restart */ 02582 if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) { 02583 fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1); 02584 argc = sizeof(_argv) / sizeof(_argv[0]) - 1; 02585 } 02586 for (x=0; x<argc; x++) 02587 _argv[x] = argv[x]; 02588 _argv[x] = NULL; 02589 02590 if (geteuid() != 0) 02591 isroot = 0; 02592 02593 /* if the progname is rasterisk consider it a remote console */ 02594 if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) { 02595 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE); 02596 } 02597 if (gethostname(hostname, sizeof(hostname)-1)) 02598 ast_copy_string(hostname, "<Unknown>", sizeof(hostname)); 02599 ast_mainpid = getpid(); 02600 ast_ulaw_init(); 02601 ast_alaw_init(); 02602 callerid_init(); 02603 ast_builtins_init(); 02604 ast_utils_init(); 02605 tdd_init(); 02606 02607 if (getenv("HOME")) 02608 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); 02609 /* Check for options */ 02610 while ((c = getopt(argc, argv, "mtThfFdvVqprRgciInx:U:G:C:L:M:")) != -1) { 02611 switch (c) { 02612 #if HAVE_WORKING_FORK 02613 case 'F': 02614 ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK); 02615 break; 02616 case 'f': 02617 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); 02618 break; 02619 #endif 02620 case 'd': 02621 option_debug++; 02622 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); 02623 break; 02624 case 'c': 02625 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE); 02626 break; 02627 case 'n': 02628 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR); 02629 break; 02630 case 'r': 02631 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE); 02632 break; 02633 case 'R': 02634 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT); 02635 break; 02636 case 'p': 02637 ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY); 02638 break; 02639 case 'v': 02640 option_verbose++; 02641 ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); 02642 break; 02643 case 'm': 02644 ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE); 02645 break; 02646 case 'M': 02647 if ((sscanf(optarg, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) 02648 option_maxcalls = 0; 02649 break; 02650 case 'L': 02651 if ((sscanf(optarg, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) 02652 option_maxload = 0.0; 02653 break; 02654 case 'q': 02655 ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET); 02656 break; 02657 case 't': 02658 ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES); 02659 break; 02660 case 'T': 02661 ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP); 02662 break; 02663 case 'x': 02664 ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC); 02665 xarg = ast_strdupa(optarg); 02666 break; 02667 case 'C': 02668 ast_copy_string(ast_config_AST_CONFIG_FILE, optarg, sizeof(ast_config_AST_CONFIG_FILE)); 02669 ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG); 02670 break; 02671 case 'I': 02672 ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING); 02673 break; 02674 case 'i': 02675 ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS); 02676 break; 02677 case 'g': 02678 ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE); 02679 break; 02680 case 'h': 02681 show_cli_help(); 02682 exit(0); 02683 case 'V': 02684 show_version(); 02685 exit(0); 02686 case 'U': 02687 runuser = ast_strdupa(optarg); 02688 break; 02689 case 'G': 02690 rungroup = ast_strdupa(optarg); 02691 break; 02692 case '?': 02693 exit(1); 02694 } 02695 } 02696 02697 if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) { 02698 ast_register_verbose(console_verboser); 02699 WELCOME_MESSAGE; 02700 } 02701 02702 if (ast_opt_console && !option_verbose) 02703 ast_verbose("[ Booting...\n"); 02704 02705 if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) { 02706 ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n"); 02707 ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK); 02708 } 02709 02710 /* For remote connections, change the name of the remote connection. 02711 * We do this for the benefit of init scripts (which need to know if/when 02712 * the main asterisk process has died yet). */ 02713 if (ast_opt_remote) { 02714 strcpy(argv[0], "rasterisk"); 02715 for (x = 1; x < argc; x++) { 02716 argv[x] = argv[0] + 10; 02717 } 02718 } 02719 02720 if (ast_opt_console && !option_verbose) 02721 ast_verbose("[ Reading Master Configuration ]\n"); 02722 ast_readconfig(); 02723 02724 if (ast_opt_dump_core) { 02725 struct rlimit l; 02726 memset(&l, 0, sizeof(l)); 02727 l.rlim_cur = RLIM_INFINITY; 02728 l.rlim_max = RLIM_INFINITY; 02729 if (setrlimit(RLIMIT_CORE, &l)) { 02730 ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno)); 02731 } 02732 } 02733 02734 if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP)) 02735 rungroup = ast_config_AST_RUN_GROUP; 02736 if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER)) 02737 runuser = ast_config_AST_RUN_USER; 02738 02739 #ifndef __CYGWIN__ 02740 02741 if (isroot) 02742 ast_set_priority(ast_opt_high_priority); 02743 02744 if (isroot && rungroup) { 02745 struct group *gr; 02746 gr = getgrnam(rungroup); 02747 if (!gr) { 02748 ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup); 02749 exit(1); 02750 } 02751 if (setgid(gr->gr_gid)) { 02752 ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup); 02753 exit(1); 02754 } 02755 if (setgroups(0, NULL)) { 02756 ast_log(LOG_WARNING, "Unable to drop unneeded groups\n"); 02757 exit(1); 02758 } 02759 if (option_verbose) 02760 ast_verbose("Running as group '%s'\n", rungroup); 02761 } 02762 02763 if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) { 02764 #ifdef HAVE_CAP 02765 int has_cap = 1; 02766 #endif /* HAVE_CAP */ 02767 struct passwd *pw; 02768 pw = getpwnam(runuser); 02769 if (!pw) { 02770 ast_log(LOG_WARNING, "No such user '%s'!\n", runuser); 02771 exit(1); 02772 } 02773 #ifdef HAVE_CAP 02774 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { 02775 ast_log(LOG_WARNING, "Unable to keep capabilities.\n"); 02776 has_cap = 0; 02777 } 02778 #endif /* HAVE_CAP */ 02779 if (!isroot && pw->pw_uid != geteuid()) { 02780 ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser); 02781 exit(1); 02782 } 02783 if (!rungroup) { 02784 if (setgid(pw->pw_gid)) { 02785 ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid); 02786 exit(1); 02787 } 02788 if (isroot && initgroups(pw->pw_name, pw->pw_gid)) { 02789 ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser); 02790 exit(1); 02791 } 02792 } 02793 if (setuid(pw->pw_uid)) { 02794 ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser); 02795 exit(1); 02796 } 02797 if (option_verbose) 02798 ast_verbose("Running as user '%s'\n", runuser); 02799 #ifdef HAVE_CAP 02800 if (has_cap) { 02801 cap_t cap; 02802 02803 cap = cap_from_text("cap_net_admin=ep"); 02804 02805 if (cap_set_proc(cap)) 02806 ast_log(LOG_WARNING, "Unable to install capabilities.\n"); 02807 02808 if (cap_free(cap)) 02809 ast_log(LOG_WARNING, "Unable to drop capabilities.\n"); 02810 } 02811 #endif /* HAVE_CAP */ 02812 } 02813 02814 #endif /* __CYGWIN__ */ 02815 02816 #ifdef linux 02817 if (geteuid() && ast_opt_dump_core) { 02818 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { 02819 ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno)); 02820 } 02821 } 02822 #endif 02823 02824 ast_term_init(); 02825 printf(term_end()); 02826 fflush(stdout); 02827 02828 if (ast_opt_console && !option_verbose) 02829 ast_verbose("[ Initializing Custom Configuration Options ]\n"); 02830 /* custom config setup */ 02831 register_config_cli(); 02832 read_config_maps(); 02833 02834 if (ast_opt_console) { 02835 if (el_hist == NULL || el == NULL) 02836 ast_el_initialize(); 02837 02838 if (!ast_strlen_zero(filename)) 02839 ast_el_read_history(filename); 02840 } 02841 02842 if (ast_tryconnect()) { 02843 /* One is already running */ 02844 if (ast_opt_remote) { 02845 if (ast_opt_exec) { 02846 ast_remotecontrol(xarg); 02847 quit_handler(0, 0, 0, 0); 02848 exit(0); 02849 } 02850 printf(term_quit()); 02851 ast_remotecontrol(NULL); 02852 quit_handler(0, 0, 0, 0); 02853 exit(0); 02854 } else { 02855 ast_log(LOG_ERROR, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET); 02856 printf(term_quit()); 02857 exit(1); 02858 } 02859 } else if (ast_opt_remote || ast_opt_exec) { 02860 ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET); 02861 printf(term_quit()); 02862 exit(1); 02863 } 02864 /* Blindly write pid file since we couldn't connect */ 02865 unlink(ast_config_AST_PID); 02866 f = fopen(ast_config_AST_PID, "w"); 02867 if (f) { 02868 fprintf(f, "%ld\n", (long)getpid()); 02869 fclose(f); 02870 } else 02871 ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno)); 02872 02873 #if HAVE_WORKING_FORK 02874 if (ast_opt_always_fork || !ast_opt_no_fork) { 02875 #ifndef HAVE_SBIN_LAUNCHD 02876 daemon(1, 0); 02877 ast_mainpid = getpid(); 02878 /* Blindly re-write pid file since we are forking */ 02879 unlink(ast_config_AST_PID); 02880 f = fopen(ast_config_AST_PID, "w"); 02881 if (f) { 02882 fprintf(f, "%ld\n", (long)ast_mainpid); 02883 fclose(f); 02884 } else 02885 ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno)); 02886 #else 02887 ast_log(LOG_WARNING, "Mac OS X detected. Use '/sbin/launchd -d' to launch with the nofork option.\n"); 02888 #endif 02889 } 02890 #endif 02891 02892 /* Test recursive mutex locking. */ 02893 if (test_for_thread_safety()) 02894 ast_verbose("Warning! Asterisk is not thread safe.\n"); 02895 02896 ast_makesocket(); 02897 sigemptyset(&sigs); 02898 sigaddset(&sigs, SIGHUP); 02899 sigaddset(&sigs, SIGTERM); 02900 sigaddset(&sigs, SIGINT); 02901 sigaddset(&sigs, SIGPIPE); 02902 sigaddset(&sigs, SIGWINCH); 02903 pthread_sigmask(SIG_BLOCK, &sigs, NULL); 02904 signal(SIGURG, urg_handler); 02905 signal(SIGINT, __quit_handler); 02906 signal(SIGTERM, __quit_handler); 02907 signal(SIGHUP, hup_handler); 02908 signal(SIGCHLD, child_handler); 02909 signal(SIGPIPE, SIG_IGN); 02910 02911 /* ensure that the random number generators are seeded with a different value every time 02912 Asterisk is started 02913 */ 02914 srand((unsigned int) getpid() + (unsigned int) time(NULL)); 02915 initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool)); 02916 02917 if (init_logger()) { 02918 printf(term_quit()); 02919 exit(1); 02920 } 02921 02922 threadstorage_init(); 02923 02924 astobj2_init(); 02925 02926 ast_autoservice_init(); 02927 02928 if (load_modules(1)) { 02929 printf(term_quit()); 02930 exit(1); 02931 } 02932 02933 if (dnsmgr_init()) { 02934 printf(term_quit()); 02935 exit(1); 02936 } 02937 02938 ast_http_init(); 02939 02940 ast_channels_init(); 02941 02942 if (init_manager()) { 02943 printf(term_quit()); 02944 exit(1); 02945 } 02946 02947 if (ast_cdr_engine_init()) { 02948 printf(term_quit()); 02949 exit(1); 02950 } 02951 02952 if (ast_device_state_engine_init()) { 02953 printf(term_quit()); 02954 exit(1); 02955 } 02956 02957 ast_rtp_init(); 02958 02959 ast_udptl_init(); 02960 02961 if (ast_image_init()) { 02962 printf(term_quit()); 02963 exit(1); 02964 } 02965 02966 if (ast_file_init()) { 02967 printf(term_quit()); 02968 exit(1); 02969 } 02970 02971 if (load_pbx()) { 02972 printf(term_quit()); 02973 exit(1); 02974 } 02975 02976 if (init_framer()) { 02977 printf(term_quit()); 02978 exit(1); 02979 } 02980 02981 if (astdb_init()) { 02982 printf(term_quit()); 02983 exit(1); 02984 } 02985 02986 if (ast_enum_init()) { 02987 printf(term_quit()); 02988 exit(1); 02989 } 02990 02991 if (load_modules(0)) { 02992 printf(term_quit()); 02993 exit(1); 02994 } 02995 02996 dnsmgr_start_refresh(); 02997 02998 /* We might have the option of showing a console, but for now just 02999 do nothing... */ 03000 if (ast_opt_console && !option_verbose) 03001 ast_verbose(" ]\n"); 03002 if (option_verbose || ast_opt_console) 03003 ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp))); 03004 if (ast_opt_no_fork) 03005 consolethread = pthread_self(); 03006 03007 if (pipe(sig_alert_pipe)) 03008 sig_alert_pipe[0] = sig_alert_pipe[1] = -1; 03009 03010 ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED); 03011 pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); 03012 03013 #ifdef __AST_DEBUG_MALLOC 03014 __ast_mm_init(); 03015 #endif 03016 03017 time(&ast_startuptime); 03018 ast_cli_register_multiple(cli_asterisk, sizeof(cli_asterisk) / sizeof(struct ast_cli_entry)); 03019 03020 if (ast_opt_console) { 03021 /* Console stuff now... */ 03022 /* Register our quit function */ 03023 char title[256]; 03024 pthread_attr_t attr; 03025 pthread_t dont_care; 03026 03027 pthread_attr_init(&attr); 03028 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 03029 ast_pthread_create(&dont_care, &attr, monitor_sig_flags, NULL); 03030 pthread_attr_destroy(&attr); 03031 03032 set_icon("Asterisk"); 03033 snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid); 03034 set_title(title); 03035 03036 for (;;) { 03037 buf = (char *)el_gets(el, &num); 03038 03039 if (!buf && write(1, "", 1) < 0) 03040 goto lostterm; 03041 03042 if (buf) { 03043 if (buf[strlen(buf)-1] == '\n') 03044 buf[strlen(buf)-1] = '\0'; 03045 03046 consolehandler((char *)buf); 03047 } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n", 03048 strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) { 03049 /* Whoa, stdout disappeared from under us... Make /dev/null's */ 03050 int fd; 03051 fd = open("/dev/null", O_RDWR); 03052 if (fd > -1) { 03053 dup2(fd, STDOUT_FILENO); 03054 dup2(fd, STDIN_FILENO); 03055 } else 03056 ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n"); 03057 break; 03058 } 03059 } 03060 } 03061 03062 monitor_sig_flags(NULL); 03063 03064 lostterm: 03065 return 0; 03066 }
static void* monitor_sig_flags | ( | void * | unused | ) | [static] |
Definition at line 2546 of file asterisk.c.
References ast_module_reload(), poll(), POLLIN, quit_handler(), and sig_flags.
Referenced by main().
02547 { 02548 for (;;) { 02549 struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 }; 02550 int a; 02551 poll(&p, 1, -1); 02552 if (sig_flags.need_reload) { 02553 sig_flags.need_reload = 0; 02554 ast_module_reload(NULL); 02555 } 02556 if (sig_flags.need_quit) { 02557 sig_flags.need_quit = 0; 02558 quit_handler(0, 0, 1, 0); 02559 } 02560 read(sig_alert_pipe[0], &a, sizeof(a)); 02561 } 02562 02563 return NULL; 02564 }
static void* netconsole | ( | void * | vconsole | ) | [static] |
Definition at line 908 of file asterisk.c.
References ast_cli_command_multiple(), ast_log(), ast_verbose(), 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().
00909 { 00910 struct console *con = vconsole; 00911 char hostname[MAXHOSTNAMELEN] = ""; 00912 char tmp[512]; 00913 int res; 00914 struct pollfd fds[2]; 00915 00916 if (gethostname(hostname, sizeof(hostname)-1)) 00917 ast_copy_string(hostname, "<Unknown>", sizeof(hostname)); 00918 snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ASTERISK_VERSION); 00919 fdprint(con->fd, tmp); 00920 for(;;) { 00921 fds[0].fd = con->fd; 00922 fds[0].events = POLLIN; 00923 fds[0].revents = 0; 00924 fds[1].fd = con->p[0]; 00925 fds[1].events = POLLIN; 00926 fds[1].revents = 0; 00927 00928 res = poll(fds, 2, -1); 00929 if (res < 0) { 00930 if (errno != EINTR) 00931 ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno)); 00932 continue; 00933 } 00934 if (fds[0].revents) { 00935 res = read(con->fd, tmp, sizeof(tmp)); 00936 if (res < 1) { 00937 break; 00938 } 00939 tmp[res] = 0; 00940 ast_cli_command_multiple(con->fd, res, tmp); 00941 } 00942 if (fds[1].revents) { 00943 res = read(con->p[0], tmp, sizeof(tmp)); 00944 if (res < 1) { 00945 ast_log(LOG_ERROR, "read returned %d\n", res); 00946 break; 00947 } 00948 res = write(con->fd, tmp, res); 00949 if (res < 1) 00950 break; 00951 } 00952 } 00953 if (option_verbose > 2) 00954 ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection disconnected\n"); 00955 close(con->fd); 00956 close(con->p[0]); 00957 close(con->p[1]); 00958 con->fd = -1; 00959 00960 return NULL; 00961 }
static void network_verboser | ( | const char * | s | ) | [static] |
Definition at line 901 of file asterisk.c.
References ast_network_puts_mutable().
Referenced by ast_makesocket().
00902 { 00903 ast_network_puts_mutable(s); 00904 }
static void null_sig_handler | ( | int | signal | ) | [static] |
NULL handler so we can collect the child exit status.
Definition at line 741 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 1242 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().
01243 { 01244 char filename[80] = ""; 01245 time_t s,e; 01246 int x; 01247 /* Try to get as many CDRs as possible submitted to the backend engines (if in batch mode) */ 01248 ast_cdr_engine_term(); 01249 if (safeshutdown) { 01250 shuttingdown = 1; 01251 if (!nice) { 01252 /* Begin shutdown routine, hanging up active channels */ 01253 ast_begin_shutdown(1); 01254 if (option_verbose && ast_opt_console) 01255 ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown"); 01256 time(&s); 01257 for (;;) { 01258 time(&e); 01259 /* Wait up to 15 seconds for all channels to go away */ 01260 if ((e - s) > 15) 01261 break; 01262 if (!ast_active_channels()) 01263 break; 01264 if (!shuttingdown) 01265 break; 01266 /* Sleep 1/10 of a second */ 01267 usleep(100000); 01268 } 01269 } else { 01270 if (nice < 2) 01271 ast_begin_shutdown(0); 01272 if (option_verbose && ast_opt_console) 01273 ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt"); 01274 for (;;) { 01275 if (!ast_active_channels()) 01276 break; 01277 if (!shuttingdown) 01278 break; 01279 sleep(1); 01280 } 01281 } 01282 01283 if (!shuttingdown) { 01284 if (option_verbose && ast_opt_console) 01285 ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown"); 01286 return; 01287 } 01288 01289 if (nice) 01290 ast_module_shutdown(); 01291 } 01292 if (ast_opt_console || ast_opt_remote) { 01293 if (getenv("HOME")) 01294 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); 01295 if (!ast_strlen_zero(filename)) 01296 ast_el_write_history(filename); 01297 if (el != NULL) 01298 el_end(el); 01299 if (el_hist != NULL) 01300 history_end(el_hist); 01301 } 01302 if (option_verbose) 01303 ast_verbose("Executing last minute cleanups\n"); 01304 ast_run_atexits(); 01305 /* Called on exit */ 01306 if (option_verbose && ast_opt_console) 01307 ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num); 01308 if (option_debug) 01309 ast_log(LOG_DEBUG, "Asterisk ending (%d).\n", num); 01310 manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False"); 01311 if (ast_socket > -1) { 01312 pthread_cancel(lthread); 01313 close(ast_socket); 01314 ast_socket = -1; 01315 unlink(ast_config_AST_SOCKET); 01316 } 01317 if (ast_consock > -1) 01318 close(ast_consock); 01319 if (!ast_opt_remote) 01320 unlink(ast_config_AST_PID); 01321 printf(term_quit()); 01322 if (restart) { 01323 if (option_verbose || ast_opt_console) 01324 ast_verbose("Preparing for Asterisk restart...\n"); 01325 /* Mark all FD's for closing on exec */ 01326 for (x=3; x < 32768; x++) { 01327 fcntl(x, F_SETFD, FD_CLOEXEC); 01328 } 01329 if (option_verbose || ast_opt_console) 01330 ast_verbose("Asterisk is now restarting...\n"); 01331 restartnow = 1; 01332 01333 /* close logger */ 01334 close_logger(); 01335 01336 /* If there is a consolethread running send it a SIGHUP 01337 so it can execvp, otherwise we can do it ourselves */ 01338 if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) { 01339 pthread_kill(consolethread, SIGHUP); 01340 /* Give the signal handler some time to complete */ 01341 sleep(2); 01342 } else 01343 execvp(_argv[0], _argv); 01344 01345 } else { 01346 /* close logger */ 01347 close_logger(); 01348 } 01349 exit(0); 01350 }
static __inline uint64_t rdtsc | ( | void | ) | [static] |
static int remoteconsolehandler | ( | char * | s | ) | [static] |
Definition at line 1422 of file asterisk.c.
References ast_all_zeros(), ast_el_add_history(), ast_safe_system(), and quit_handler().
Referenced by ast_remotecontrol().
01423 { 01424 int ret = 0; 01425 01426 /* Called when readline data is available */ 01427 if (!ast_all_zeros(s)) 01428 ast_el_add_history(s); 01429 /* The real handler for bang */ 01430 if (s[0] == '!') { 01431 if (s[1]) 01432 ast_safe_system(s+1); 01433 else 01434 ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); 01435 ret = 1; 01436 } 01437 if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) && 01438 (s[4] == '\0' || isspace(s[4]))) { 01439 quit_handler(0, 0, 0, 0); 01440 ret = 1; 01441 } 01442 01443 return ret; 01444 }
static void set_icon | ( | char * | text | ) | [static] |
Definition at line 1189 of file asterisk.c.
Referenced by main().
01190 { 01191 if (getenv("TERM") && strstr(getenv("TERM"), "xterm")) 01192 fprintf(stdout, "\033]1;%s\007", text); 01193 }
static void set_title | ( | char * | text | ) | [static] |
Set an X-term or screen title.
Definition at line 1183 of file asterisk.c.
Referenced by main().
01184 { 01185 if (getenv("TERM") && strstr(getenv("TERM"), "xterm")) 01186 fprintf(stdout, "\033]2;%s\007", text); 01187 }
static void set_ulimit | ( | int | value | ) | [static] |
Set maximum open files.
Definition at line 1160 of file asterisk.c.
References ast_log(), errno, LOG_NOTICE, and LOG_WARNING.
01161 { 01162 struct rlimit l = {0, 0}; 01163 01164 if (value <= 0) { 01165 ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value); 01166 return; 01167 } 01168 01169 l.rlim_cur = value; 01170 l.rlim_max = value; 01171 01172 if (setrlimit(RLIMIT_NOFILE, &l)) { 01173 ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno)); 01174 return; 01175 } 01176 01177 ast_log(LOG_NOTICE, "Setting max files open to %d\n",value); 01178 01179 return; 01180 }
static int show_cli_help | ( | void | ) | [static] |
Definition at line 2348 of file asterisk.c.
Referenced by main().
02348 { 02349 printf("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2008, Digium, Inc. and others.\n"); 02350 printf("Usage: asterisk [OPTIONS]\n"); 02351 printf("Valid Options:\n"); 02352 printf(" -V Display version number and exit\n"); 02353 printf(" -C <configfile> Use an alternate configuration file\n"); 02354 printf(" -G <group> Run as a group other than the caller\n"); 02355 printf(" -U <user> Run as a user other than the caller\n"); 02356 printf(" -c Provide console CLI\n"); 02357 printf(" -d Enable extra debugging\n"); 02358 #if HAVE_WORKING_FORK 02359 printf(" -f Do not fork\n"); 02360 printf(" -F Always fork\n"); 02361 #endif 02362 printf(" -g Dump core in case of a crash\n"); 02363 printf(" -h This help screen\n"); 02364 printf(" -i Initialize crypto keys at startup\n"); 02365 printf(" -I Enable internal timing if Zaptel timer is available\n"); 02366 printf(" -L <load> Limit the maximum load average before rejecting new calls\n"); 02367 printf(" -M <value> Limit the maximum number of calls to the specified value\n"); 02368 printf(" -m Mute debugging and console output on the console\n"); 02369 printf(" -n Disable console colorization\n"); 02370 printf(" -p Run as pseudo-realtime thread\n"); 02371 printf(" -q Quiet mode (suppress output)\n"); 02372 printf(" -r Connect to Asterisk on this machine\n"); 02373 printf(" -R Same as -r, except attempt to reconnect if disconnected\n"); 02374 printf(" -t Record soundfiles in /var/tmp and move them where they\n"); 02375 printf(" belong after they are done\n"); 02376 printf(" -T Display the time in [Mmm dd hh:mm:ss] format for each line\n"); 02377 printf(" of output to the CLI\n"); 02378 printf(" -v Increase verbosity (multiple v's = more verbose)\n"); 02379 printf(" -x <cmd> Execute command <cmd> (only valid with -r)\n"); 02380 printf("\n"); 02381 return 0; 02382 }
static int show_license | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1641 of file asterisk.c.
References ast_cli(), and RESULT_SUCCESS.
01642 { 01643 int x; 01644 01645 for (x = 0; x < sizeof(license_lines) / sizeof(license_lines[0]); x++) 01646 ast_cli(fd, (char *) license_lines[x]); 01647 01648 return RESULT_SUCCESS; 01649 }
static int show_version | ( | void | ) | [static] |
static int show_warranty | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1612 of file asterisk.c.
References ast_cli(), and RESULT_SUCCESS.
01613 { 01614 int x; 01615 01616 for (x = 0; x < sizeof(warranty_lines) / sizeof(warranty_lines[0]); x++) 01617 ast_cli(fd, (char *) warranty_lines[x]); 01618 01619 return RESULT_SUCCESS; 01620 }
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 1125 of file asterisk.c.
Referenced by main().
01126 { 01127 signal(num, urg_handler); 01128 return; 01129 }
char* _argv[256] [static] |
Definition at line 231 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 1446 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 202 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 221 of file asterisk.c.
char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0" |
Definition at line 220 of file asterisk.c.
char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0" |
Definition at line 219 of file asterisk.c.
char ast_config_AST_CTL_PERMISSIONS[PATH_MAX] |
Definition at line 218 of file asterisk.c.
char ast_config_AST_DATA_DIR[PATH_MAX] |
Definition at line 208 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 212 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 209 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 204 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 206 of file asterisk.c.
Referenced by ast_monitor_change_fname(), ast_monitor_start(), ast_monitor_stop(), chanspy_exec(), extenspy_exec(), launch_script(), and mixmonitor_exec().
char ast_config_AST_PID[PATH_MAX] |
Definition at line 213 of file asterisk.c.
char ast_config_AST_RUN_DIR[PATH_MAX] |
char ast_config_AST_RUN_GROUP[PATH_MAX] |
Definition at line 217 of file asterisk.c.
char ast_config_AST_RUN_USER[PATH_MAX] |
Definition at line 216 of file asterisk.c.
char ast_config_AST_SOCKET[PATH_MAX] |
Definition at line 214 of file asterisk.c.
char ast_config_AST_SPOOL_DIR[PATH_MAX] |
Definition at line 205 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 222 of file asterisk.c.
Referenced by authenticate(), pbx_retrieve_variable(), and realtime_update_peer().
char ast_config_AST_VAR_DIR[PATH_MAX] |
Definition at line 207 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 171 of file asterisk.c.
time_t ast_lastreloadtime |
Definition at line 188 of file asterisk.c.
Referenced by ast_module_reload(), handle_showuptime(), and handle_showuptime_deprecated().
pid_t ast_mainpid |
int ast_socket = -1 [static] |
UNIX Socket for allowing remote control
Definition at line 170 of file asterisk.c.
time_t ast_startuptime |
Definition at line 187 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 1478 of file asterisk.c.
struct ast_cli_entry cli_asterisk[] [static] |
struct ast_cli_entry cli_clear_profile_deprecated [static] |
Initial value:
{ { "clear", "profile", NULL }, handle_show_profile_deprecated, NULL, NULL }
Definition at line 1671 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 1666 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 1655 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 1661 of file asterisk.c.
Definition at line 194 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 168 of file asterisk.c.
Referenced by ast_log(), handle_debuglevel_deprecated(), handle_nodebug(), and handle_set_debug().
char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE |
Definition at line 196 of file asterisk.c.
EditLine* el [static] |
Definition at line 191 of file asterisk.c.
Referenced by __ast_context_destroy(), add_pri(), ast_add_extension2(), handle_save_dialplan(), and show_dialplan_helper().
History* el_hist [static] |
Definition at line 190 of file asterisk.c.
const char* license_lines[] [static] |
Definition at line 1622 of file asterisk.c.
pthread_t lthread [static] |
Definition at line 906 of file asterisk.c.
unsigned int need_quit |
Definition at line 241 of file asterisk.c.
unsigned int need_reload |
Definition at line 240 of file asterisk.c.
struct profile_data* prof_data [static] |
Definition at line 364 of file asterisk.c.
Referenced by ast_add_profile(), ast_mark(), ast_profile(), handle_show_profile(), and handle_show_profile_deprecated().
char randompool[256] [static] |
Definition at line 236 of file asterisk.c.
char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR |
char* remotehostname [static] |
Definition at line 192 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 1469 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 1464 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 1474 of file asterisk.c.
int restartnow [static] |
Definition at line 233 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 749 of file asterisk.c.
void* safe_system_prev_handler [static] |
Definition at line 750 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 1486 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 299 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 539 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 1482 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 1455 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 1451 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 1460 of file asterisk.c.
int shuttingdown [static] |
Definition at line 232 of file asterisk.c.
int sig_alert_pipe[2] = { -1, -1 } [static] |
Definition at line 238 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 1490 of file asterisk.c.
const char* warranty_lines[] [static] |
Definition at line 1587 of file asterisk.c.