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