Sat Apr 12 07:12:33 2008

Asterisk developer's documentation


asterisk.c File Reference

Top level source file for Asterisk - the Open Source PBX. Implementation of PBX core functions and CLI interface. More...

#include "asterisk.h"
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <sched.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <sys/resource.h>
#include <grp.h>
#include <pwd.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/image.h"
#include "asterisk/tdd.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/cdr.h"
#include "asterisk/pbx.h"
#include "asterisk/enum.h"
#include "asterisk/rtp.h"
#include "asterisk/http.h"
#include "asterisk/udptl.h"
#include "asterisk/app.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/io.h"
#include "editline/histedit.h"
#include "asterisk/config.h"
#include "asterisk/version.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"
#include "asterisk/module.h"
#include "asterisk/doxyref.h"
#include "../defaults.h"

Include dependency graph for asterisk.c:

Go to the source code of this file.

Data Structures

struct  ast_atexit
struct  console
struct  file_version
struct  profile_data
struct  profile_entry
struct  thread_list_t

Defines

#define AF_LOCAL   AF_UNIX
#define AST_MAX_CONNECTS   128
#define ASTERISK_PROMPT   "*CLI> "
#define ASTERISK_PROMPT2   "%s*CLI> "
#define FORMAT   "%-25.25s %-40.40s\n"
#define FORMAT   "%-25.25s %-40.40s\n"
#define NUM_MSGS   64
#define PF_LOCAL   PF_UNIX
#define WELCOME_MESSAGE
 Welcome message when starting a CLI interface.

Functions

static void __quit_handler (int num)
int ast_add_profile (const char *name, uint64_t scale)
 allocates a counter with a given name and scale.
static int ast_all_zeros (char *s)
static int ast_cli_display_match_list (char **matches, int len, int max)
void ast_console_puts (const char *string)
void ast_console_puts_mutable (const char *string)
 log the string to the console, and all attached console clients
void ast_console_toggle_mute (int fd, int silent)
 mute or unmute a console from logging
static int ast_el_add_history (char *)
static int ast_el_initialize (void)
static int ast_el_read_char (EditLine *el, char *cp)
static int ast_el_read_history (char *)
static int ast_el_sort_compare (const void *i1, const void *i2)
static char ** ast_el_strtoarr (char *buf)
static int ast_el_write_history (char *)
static AST_LIST_HEAD_STATIC (thread_list, thread_list_t)
static AST_LIST_HEAD_STATIC (file_versions, file_version)
static AST_LIST_HEAD_STATIC (atexits, ast_atexit)
static int ast_makesocket (void)
int64_t ast_mark (int i, int startstop)
 AST_MUTEX_DEFINE_STATIC (safe_system_lock)
static void ast_network_puts (const char *string)
 write the string to all attached console clients
static void ast_network_puts_mutable (const char *string)
 log the string to all attached console clients
int64_t ast_profile (int i, int64_t delta)
static void ast_readconfig (void)
int ast_register_atexit (void(*func)(void))
 Register a function to be executed before Asterisk exits.
void ast_register_file_version (const char *file, const char *version)
 Register the version of a source code file with the core.
void ast_register_thread (char *name)
static void ast_remotecontrol (char *data)
void ast_replace_sigchld (void)
 Replace the SIGCHLD handler.
static void ast_run_atexits (void)
int ast_safe_system (const char *s)
int ast_set_priority (int pri)
 We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy activity on it, this is a good thing.
static int ast_tryconnect (void)
void ast_unregister_atexit (void(*func)(void))
 Unregister a function registered with ast_register_atexit().
void ast_unregister_file_version (const char *file)
 Unregister a source code file from the core.
void ast_unregister_thread (void *id)
void ast_unreplace_sigchld (void)
 Restore the SIGCHLD handler.
static void child_handler (int sig)
static char * cli_complete (EditLine *el, int ch)
static char * cli_prompt (EditLine *el)
static char * complete_show_version_files (const char *line, const char *word, int pos, int state)
static char * complete_show_version_files_deprecated (const char *line, const char *word, int pos, int state)
static void console_verboser (const char *s)
static void consolehandler (char *s)
static int fdprint (int fd, const char *s)
static const char * fix_header (char *outbuf, int maxout, const char *s, char *cmp)
static int handle_abort_halt (int fd, int argc, char *argv[])
static int handle_bang (int fd, int argc, char *argv[])
static int handle_restart_gracefully (int fd, int argc, char *argv[])
static int handle_restart_now (int fd, int argc, char *argv[])
static int handle_restart_when_convenient (int fd, int argc, char *argv[])
static int handle_show_profile (int fd, int argc, char *argv[])
static int handle_show_profile_deprecated (int fd, int argc, char *argv[])
static int handle_show_threads (int fd, int argc, char *argv[])
static int handle_show_version_files (int fd, int argc, char *argv[])
static int handle_show_version_files_deprecated (int fd, int argc, char *argv[])
 CLI command to list module versions.
static int handle_shutdown_gracefully (int fd, int argc, char *argv[])
static int handle_shutdown_now (int fd, int argc, char *argv[])
static int handle_shutdown_when_convenient (int fd, int argc, char *argv[])
static int handle_version (int fd, int argc, char *argv[])
static int handle_version_deprecated (int fd, int argc, char *argv[])
static void hup_handler (int num)
static void * listener (void *unused)
int main (int argc, char *argv[])
static void * monitor_sig_flags (void *unused)
static void * netconsole (void *vconsole)
static void network_verboser (const char *s)
static void null_sig_handler (int signal)
 NULL handler so we can collect the child exit status.
static void quit_handler (int num, int nice, int safeshutdown, int restart)
static __inline uint64_t rdtsc (void)
static int remoteconsolehandler (char *s)
static void set_icon (char *text)
static void set_title (char *text)
 Set an X-term or screen title.
static int show_cli_help (void)
static int show_license (int fd, int argc, char *argv[])
static int show_version (void)
static int show_warranty (int fd, int argc, char *argv[])
static void urg_handler (int num)
 Urgent handler.

Variables

static char * _argv [256]
static char abort_halt_help []
const char * ast_build_date
const char * ast_build_hostname
const char * ast_build_kernel
const char * ast_build_machine
const char * ast_build_os
const char * ast_build_user
char ast_config_AST_AGI_DIR [PATH_MAX]
char ast_config_AST_CONFIG_DIR [PATH_MAX]
char ast_config_AST_CONFIG_FILE [PATH_MAX]
char ast_config_AST_CTL [PATH_MAX] = "asterisk.ctl"
char ast_config_AST_CTL_GROUP [PATH_MAX] = "\0"
char ast_config_AST_CTL_OWNER [PATH_MAX] = "\0"
char ast_config_AST_CTL_PERMISSIONS [PATH_MAX]
char ast_config_AST_DATA_DIR [PATH_MAX]
char ast_config_AST_DB [PATH_MAX]
char ast_config_AST_KEY_DIR [PATH_MAX]
char ast_config_AST_LOG_DIR [PATH_MAX]
char ast_config_AST_MODULE_DIR [PATH_MAX]
char ast_config_AST_MONITOR_DIR [PATH_MAX]
char ast_config_AST_PID [PATH_MAX]
char ast_config_AST_RUN_DIR [PATH_MAX]
char ast_config_AST_RUN_GROUP [PATH_MAX]
char ast_config_AST_RUN_USER [PATH_MAX]
char ast_config_AST_SOCKET [PATH_MAX]
char ast_config_AST_SPOOL_DIR [PATH_MAX]
char ast_config_AST_SYSTEM_NAME [20] = ""
char ast_config_AST_VAR_DIR [PATH_MAX]
static int ast_consock = -1
time_t ast_lastreloadtime
pid_t ast_mainpid
struct ast_flags ast_options = { AST_DEFAULT_OPTIONS }
static int ast_socket = -1
time_t ast_startuptime
static char bang_help []
static struct ast_cli_entry cli_asterisk []
static struct ast_cli_entry cli_clear_profile_deprecated
static struct ast_cli_entry cli_show_profile_deprecated
static struct ast_cli_entry cli_show_version_deprecated
static struct ast_cli_entry cli_show_version_files_deprecated
struct console consoles [AST_MAX_CONNECTS]
static pthread_t consolethread = AST_PTHREADT_NULL
char debug_filename [AST_FILENAME_MAX] = ""
char defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE
static EditLine * el
static History * el_hist
static const char * license_lines []
static pthread_t lthread
int option_debug
int option_maxcalls
double option_maxload
int option_verbose
static struct profile_dataprof_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 []


Detailed Description

Top level source file for Asterisk - the Open Source PBX. Implementation of PBX core functions and CLI interface.

Definition in file asterisk.c.


Define Documentation

#define AF_LOCAL   AF_UNIX

Definition at line 133 of file asterisk.c.

Referenced by ast_makesocket(), ast_tryconnect(), listener(), and NBScat_exec().

#define AST_MAX_CONNECTS   128

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 1631 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 1633 of file asterisk.c.

Referenced by cli_prompt().

#define FORMAT   "%-25.25s %-40.40s\n"

#define FORMAT   "%-25.25s %-40.40s\n"

#define NUM_MSGS   64

Definition at line 138 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

Definition at line 134 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 141 of file asterisk.c.

Referenced by ast_el_read_char(), and main().


Function Documentation

static void __quit_handler ( int  num  )  [static]

Definition at line 1332 of file asterisk.c.

References sig_flags.

Referenced by main().

01333 {
01334    int a = 0;
01335    sig_flags.need_quit = 1;
01336    if (sig_alert_pipe[1] != -1)
01337       write(sig_alert_pipe[1], &a, sizeof(a));
01338    /* There is no need to restore the signal handler here, since the app
01339     * is going to exit */
01340 }

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

allocates a counter with a given name and scale.

support for event profiling

Returns:
Returns the identifier of the counter.

Definition at line 372 of file asterisk.c.

References ast_calloc, ast_realloc, ast_strdup, profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, profile_data::max_size, profile_entry::name, profile_entry::scale, and profile_entry::value.

Referenced by extension_match_core().

00373 {
00374    int l = sizeof(struct profile_data);
00375    int n = 10; /* default entries */
00376 
00377    if (prof_data == NULL) {
00378       prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
00379       if (prof_data == NULL)
00380          return -1;
00381       prof_data->entries = 0;
00382       prof_data->max_size = n;
00383    }
00384    if (prof_data->entries >= prof_data->max_size) {
00385       void *p;
00386       n = prof_data->max_size + 20;
00387       p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
00388       if (p == NULL)
00389          return -1;
00390       prof_data = p;
00391       prof_data->max_size = n;
00392    }
00393    n = prof_data->entries++;
00394    prof_data->e[n].name = ast_strdup(name);
00395    prof_data->e[n].value = 0;
00396    prof_data->e[n].events = 0;
00397    prof_data->e[n].mark = 0;
00398    prof_data->e[n].scale = scale;
00399    return n;
00400 }

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1374 of file asterisk.c.

Referenced by ast_el_read_history(), consolehandler(), and remoteconsolehandler().

01375 {
01376    while (*s) {
01377       if (*s > 32)
01378          return 0;
01379       s++;  
01380    }
01381    return 1;
01382 }

static int ast_cli_display_match_list ( char **  matches,
int  len,
int  max 
) [static]

Definition at line 1996 of file asterisk.c.

References ast_el_sort_compare(), ast_get_termcols(), and free.

Referenced by cli_complete().

01997 {
01998    int i, idx, limit, count;
01999    int screenwidth = 0;
02000    int numoutput = 0, numoutputline = 0;
02001 
02002    screenwidth = ast_get_termcols(STDOUT_FILENO);
02003 
02004    /* find out how many entries can be put on one line, with two spaces between strings */
02005    limit = screenwidth / (max + 2);
02006    if (limit == 0)
02007       limit = 1;
02008 
02009    /* how many lines of output */
02010    count = len / limit;
02011    if (count * limit < len)
02012       count++;
02013 
02014    idx = 1;
02015 
02016    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
02017 
02018    for (; count > 0; count--) {
02019       numoutputline = 0;
02020       for (i=0; i < limit && matches[idx]; i++, idx++) {
02021 
02022          /* Don't print dupes */
02023          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
02024             i--;
02025             free(matches[idx]);
02026             matches[idx] = NULL;
02027             continue;
02028          }
02029 
02030          numoutput++;
02031          numoutputline++;
02032          fprintf(stdout, "%-*s  ", max, matches[idx]);
02033          free(matches[idx]);
02034          matches[idx] = NULL;
02035       }
02036       if (numoutputline > 0)
02037          fprintf(stdout, "\n");
02038    }
02039 
02040    return numoutput;
02041 }

void ast_console_puts ( const char *  string  ) 

write the string to the console, and all attached console clients

Definition at line 897 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

00898 {
00899    fputs(string, stdout);
00900    fflush(stdout);
00901    ast_network_puts(string);
00902 }

void ast_console_puts_mutable ( const char *  string  ) 

log the string to the console, and all attached console clients

Definition at line 874 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by ast_log().

00875 {
00876    fputs(string, stdout);
00877    fflush(stdout);
00878    ast_network_puts_mutable(string);
00879 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 837 of file asterisk.c.

References ast_cli(), AST_MAX_CONNECTS, consoles, and console::mute.

Referenced by handle_logger_mute().

00837                                                  {
00838    int x;
00839    for (x = 0;x < AST_MAX_CONNECTS; x++) {
00840       if (fd == consoles[x].fd) {
00841          if (consoles[x].mute) {
00842             consoles[x].mute = 0;
00843             if (!silent)
00844                ast_cli(fd, "Console is not muted anymore.\n");
00845          } else {
00846             consoles[x].mute = 1;
00847             if (!silent)
00848                ast_cli(fd, "Console is muted.\n");
00849          }
00850          return;
00851       }
00852    }
00853    ast_cli(fd, "Couldn't find remote console.\n");
00854 }

static int ast_el_add_history ( char *  buf  )  [static]

Definition at line 2190 of file asterisk.c.

References ast_el_initialize().

Referenced by ast_el_read_history(), consolehandler(), and remoteconsolehandler().

02191 {
02192    HistEvent ev;
02193 
02194    if (el_hist == NULL || el == NULL)
02195       ast_el_initialize();
02196    if (strlen(buf) > 256)
02197       return 0;
02198    return (history(el_hist, &ev, H_ENTER, buf));
02199 }

static int ast_el_initialize ( void   )  [static]

Definition at line 2155 of file asterisk.c.

References cli_complete(), and cli_prompt().

Referenced by ast_el_add_history(), ast_el_read_history(), ast_el_write_history(), ast_remotecontrol(), and main().

02156 {
02157    HistEvent ev;
02158    char *editor = getenv("AST_EDITOR");
02159 
02160    if (el != NULL)
02161       el_end(el);
02162    if (el_hist != NULL)
02163       history_end(el_hist);
02164 
02165    el = el_init("asterisk", stdin, stdout, stderr);
02166    el_set(el, EL_PROMPT, cli_prompt);
02167 
02168    el_set(el, EL_EDITMODE, 1);      
02169    el_set(el, EL_EDITOR, editor ? editor : "emacs");     
02170    el_hist = history_init();
02171    if (!el || !el_hist)
02172       return -1;
02173 
02174    /* setup history with 100 entries */
02175    history(el_hist, &ev, H_SETSIZE, 100);
02176 
02177    el_set(el, EL_HIST, history, el_hist);
02178 
02179    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02180    /* Bind <tab> to command completion */
02181    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02182    /* Bind ? to command completion */
02183    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02184    /* Bind ^D to redisplay */
02185    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02186 
02187    return 0;
02188 }

static int ast_el_read_char ( EditLine *  el,
char *  cp 
) [static]

Definition at line 1720 of file asterisk.c.

References ast_log(), ast_opt_exec, ast_opt_mute, ast_opt_reconnect, ast_tryconnect(), errno, pollfd::events, pollfd::fd, fdprint(), LOG_ERROR, poll(), POLLIN, quit_handler(), pollfd::revents, term_quit(), and WELCOME_MESSAGE.

Referenced by ast_remotecontrol().

01721 {
01722    int num_read = 0;
01723    int lastpos = 0;
01724    struct pollfd fds[2];
01725    int res;
01726    int max;
01727    char buf[512];
01728 
01729    for (;;) {
01730       max = 1;
01731       fds[0].fd = ast_consock;
01732       fds[0].events = POLLIN;
01733       if (!ast_opt_exec) {
01734          fds[1].fd = STDIN_FILENO;
01735          fds[1].events = POLLIN;
01736          max++;
01737       }
01738       res = poll(fds, max, -1);
01739       if (res < 0) {
01740          if (errno == EINTR)
01741             continue;
01742          ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
01743          break;
01744       }
01745 
01746       if (!ast_opt_exec && fds[1].revents) {
01747          num_read = read(STDIN_FILENO, cp, 1);
01748          if (num_read < 1) {
01749             break;
01750          } else 
01751             return (num_read);
01752       }
01753       if (fds[0].revents) {
01754          res = read(ast_consock, buf, sizeof(buf) - 1);
01755          /* if the remote side disappears exit */
01756          if (res < 1) {
01757             fprintf(stderr, "\nDisconnected from Asterisk server\n");
01758             if (!ast_opt_reconnect) {
01759                quit_handler(0, 0, 0, 0);
01760             } else {
01761                int tries;
01762                int reconnects_per_second = 20;
01763                fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
01764                for (tries=0; tries < 30 * reconnects_per_second; tries++) {
01765                   if (ast_tryconnect()) {
01766                      fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
01767                      printf(term_quit());
01768                      WELCOME_MESSAGE;
01769                      if (!ast_opt_mute)
01770                         fdprint(ast_consock, "logger mute silent");
01771                      else 
01772                         printf("log and verbose output currently muted ('logger mute' to unmute)\n");
01773                      break;
01774                   } else {
01775                      usleep(1000000 / reconnects_per_second);
01776                   }
01777                }
01778                if (tries >= 30 * reconnects_per_second) {
01779                   fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
01780                   quit_handler(0, 0, 0, 0);
01781                }
01782             }
01783          }
01784 
01785          buf[res] = '\0';
01786 
01787          if (!ast_opt_exec && !lastpos)
01788             write(STDOUT_FILENO, "\r", 1);
01789          write(STDOUT_FILENO, buf, res);
01790          if ((buf[res-1] == '\n') || (buf[res-2] == '\n')) {
01791             *cp = CC_REFRESH;
01792             return(1);
01793          } else {
01794             lastpos = 1;
01795          }
01796       }
01797    }
01798 
01799    *cp = '\0';
01800    return (0);
01801 }

static int ast_el_read_history ( char *  filename  )  [static]

Definition at line 2211 of file asterisk.c.

References ast_all_zeros(), ast_el_add_history(), ast_el_initialize(), and f.

Referenced by ast_remotecontrol(), and main().

02212 {
02213    char buf[256];
02214    FILE *f;
02215    int ret = -1;
02216 
02217    if (el_hist == NULL || el == NULL)
02218       ast_el_initialize();
02219 
02220    if ((f = fopen(filename, "r")) == NULL)
02221       return ret;
02222 
02223    while (!feof(f)) {
02224       fgets(buf, sizeof(buf), f);
02225       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02226          continue;
02227       if (ast_all_zeros(buf))
02228          continue;
02229       if ((ret = ast_el_add_history(buf)) == -1)
02230          break;
02231    }
02232    fclose(f);
02233 
02234    return ret;
02235 }

static int ast_el_sort_compare ( const void *  i1,
const void *  i2 
) [static]

Definition at line 1986 of file asterisk.c.

Referenced by ast_cli_display_match_list().

01987 {
01988    char *s1, *s2;
01989 
01990    s1 = ((char **)i1)[0];
01991    s2 = ((char **)i2)[0];
01992 
01993    return strcasecmp(s1, s2);
01994 }

static char** ast_el_strtoarr ( char *  buf  )  [static]

Definition at line 1951 of file asterisk.c.

References AST_CLI_COMPLETE_EOF, ast_realloc, strdup, and strsep().

Referenced by cli_complete().

01952 {
01953    char **match_list = NULL, *retstr;
01954    size_t match_list_len;
01955    int matches = 0;
01956 
01957    match_list_len = 1;
01958    while ( (retstr = strsep(&buf, " ")) != NULL) {
01959 
01960       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
01961          break;
01962       if (matches + 1 >= match_list_len) {
01963          match_list_len <<= 1;
01964          if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
01965             /* TODO: Handle memory allocation failure */
01966          }
01967       }
01968 
01969       match_list[matches++] = strdup(retstr);
01970    }
01971 
01972    if (!match_list)
01973       return (char **) NULL;
01974 
01975    if (matches >= match_list_len) {
01976       if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
01977          /* TODO: Handle memory allocation failure */
01978       }
01979    }
01980 
01981    match_list[matches] = (char *) NULL;
01982 
01983    return match_list;
01984 }

static int ast_el_write_history ( char *  filename  )  [static]

Definition at line 2201 of file asterisk.c.

References ast_el_initialize().

Referenced by quit_handler().

02202 {
02203    HistEvent ev;
02204 
02205    if (el_hist == NULL || el == NULL)
02206       ast_el_initialize();
02207 
02208    return (history(el_hist, &ev, H_SAVE, filename));
02209 }

static AST_LIST_HEAD_STATIC ( thread_list  ,
thread_list_t   
) [static]

static AST_LIST_HEAD_STATIC ( file_versions  ,
file_version   
) [static]

static AST_LIST_HEAD_STATIC ( atexits  ,
ast_atexit   
) [static]

static int ast_makesocket ( void   )  [static]

Definition at line 1032 of file asterisk.c.

References AF_LOCAL, ast_log(), AST_MAX_CONNECTS, ast_pthread_create_background, ast_register_verbose(), ast_strlen_zero(), consoles, errno, group, listener(), LOG_WARNING, network_verboser(), and PF_LOCAL.

Referenced by main().

01033 {
01034    struct sockaddr_un sunaddr;
01035    int res;
01036    int x;
01037    uid_t uid = -1;
01038    gid_t gid = -1;
01039 
01040    for (x = 0; x < AST_MAX_CONNECTS; x++) 
01041       consoles[x].fd = -1;
01042    unlink(ast_config_AST_SOCKET);
01043    ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
01044    if (ast_socket < 0) {
01045       ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
01046       return -1;
01047    }     
01048    memset(&sunaddr, 0, sizeof(sunaddr));
01049    sunaddr.sun_family = AF_LOCAL;
01050    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01051    res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01052    if (res) {
01053       ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01054       close(ast_socket);
01055       ast_socket = -1;
01056       return -1;
01057    }
01058    res = listen(ast_socket, 2);
01059    if (res < 0) {
01060       ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01061       close(ast_socket);
01062       ast_socket = -1;
01063       return -1;
01064    }
01065    ast_register_verbose(network_verboser);
01066    ast_pthread_create_background(&lthread, NULL, listener, NULL);
01067 
01068    if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
01069       struct passwd *pw;
01070       if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL) {
01071          ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
01072       } else {
01073          uid = pw->pw_uid;
01074       }
01075    }
01076       
01077    if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
01078       struct group *grp;
01079       if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL) {
01080          ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
01081       } else {
01082          gid = grp->gr_gid;
01083       }
01084    }
01085 
01086    if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
01087       ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01088 
01089    if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
01090       int p1;
01091       mode_t p;
01092       sscanf(ast_config_AST_CTL_PERMISSIONS, "%o", &p1);
01093       p = p1;
01094       if ((chmod(ast_config_AST_SOCKET, p)) < 0)
01095          ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
01096    }
01097 
01098    return 0;
01099 }

int64_t ast_mark ( int  i,
int  startstop 
)

Definition at line 434 of file asterisk.c.

References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::mark, rdtsc(), profile_entry::scale, and profile_entry::value.

Referenced by extension_match_core().

00435 {
00436    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00437       return 0;
00438    if (startstop == 1)
00439       prof_data->e[i].mark = rdtsc();
00440    else {
00441       prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
00442       if (prof_data->e[i].scale > 1)
00443          prof_data->e[i].mark /= prof_data->e[i].scale;
00444       prof_data->e[i].value += prof_data->e[i].mark;
00445       prof_data->e[i].events++;
00446    }
00447    return prof_data->e[i].mark;
00448 }

AST_MUTEX_DEFINE_STATIC ( safe_system_lock   ) 

static void ast_network_puts ( const char *  string  )  [static]

write the string to all attached console clients

Definition at line 884 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

00885 {
00886    int x;
00887    for (x=0; x < AST_MAX_CONNECTS; x++) {
00888       if (consoles[x].fd > -1) 
00889          fdprint(consoles[x].p[1], string);
00890    }
00891 }

static void ast_network_puts_mutable ( const char *  string  )  [static]

log the string to all attached console clients

Definition at line 859 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts_mutable(), and network_verboser().

00860 {
00861    int x;
00862    for (x = 0;x < AST_MAX_CONNECTS; x++) {
00863       if (consoles[x].mute)
00864          continue;
00865       if (consoles[x].fd > -1) 
00866          fdprint(consoles[x].p[1], string);
00867    }
00868 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 402 of file asterisk.c.

References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::scale, and profile_entry::value.

00403 {
00404    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00405       return 0;
00406    if (prof_data->e[i].scale > 1)
00407       delta /= prof_data->e[i].scale;
00408    prof_data->e[i].value += delta;
00409    prof_data->e[i].events++;
00410    return prof_data->e[i].value;
00411 }

static void ast_readconfig ( void   )  [static]

Definition at line 2362 of file asterisk.c.

References AST_AGI_DIR, AST_CACHE_DIR_LEN, ast_config_destroy(), AST_CONFIG_DIR, AST_CONFIG_FILE, ast_config_load(), AST_DATA_DIR, AST_DB, AST_KEY_DIR, ast_language_is_prefix, ast_log(), AST_LOG_DIR, AST_MODULE_DIR, AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DONT_WARN, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC_INCLUDES, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_TIMESTAMP, AST_OPT_FLAG_TRANSCODE_VIA_SLIN, AST_OPT_FLAG_TRANSMIT_SILENCE, ast_opt_override_config, AST_PID, AST_RUN_DIR, ast_set2_flag, AST_SOCKET, AST_SPOOL_DIR, AST_SYSTEM_NAME, ast_true(), AST_VAR_DIR, ast_variable_browse(), config, getloadavg(), LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by main().

02363 {
02364    struct ast_config *cfg;
02365    struct ast_variable *v;
02366    char *config = AST_CONFIG_FILE;
02367 
02368    if (ast_opt_override_config) {
02369       cfg = ast_config_load(ast_config_AST_CONFIG_FILE);
02370       if (!cfg)
02371          ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
02372    } else {
02373       cfg = ast_config_load(config);
02374    }
02375 
02376    /* init with buildtime config */
02377    ast_copy_string(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR, sizeof(ast_config_AST_CONFIG_DIR));
02378    ast_copy_string(ast_config_AST_SPOOL_DIR, AST_SPOOL_DIR, sizeof(ast_config_AST_SPOOL_DIR));
02379    ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_MODULE_DIR));
02380    snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR);
02381    ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR));
02382    ast_copy_string(ast_config_AST_DATA_DIR, AST_DATA_DIR, sizeof(ast_config_AST_DATA_DIR));
02383    ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR));
02384    ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR));
02385    ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB));
02386    ast_copy_string(ast_config_AST_KEY_DIR, AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR));
02387    ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID));
02388    ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET));
02389    ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR));
02390    ast_copy_string(ast_config_AST_SYSTEM_NAME, AST_SYSTEM_NAME, sizeof(ast_config_AST_SYSTEM_NAME));
02391 
02392    /* no asterisk.conf? no problem, use buildtime config! */
02393    if (!cfg) {
02394       return;
02395    }
02396 
02397    for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
02398       if (!strcasecmp(v->name, "astctlpermissions")) {
02399          ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
02400       } else if (!strcasecmp(v->name, "astctlowner")) {
02401          ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
02402       } else if (!strcasecmp(v->name, "astctlgroup")) {
02403          ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
02404       } else if (!strcasecmp(v->name, "astctl")) {
02405          ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
02406       }
02407    }
02408 
02409    for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
02410       if (!strcasecmp(v->name, "astetcdir")) {
02411          ast_copy_string(ast_config_AST_CONFIG_DIR, v->value, sizeof(ast_config_AST_CONFIG_DIR));
02412       } else if (!strcasecmp(v->name, "astspooldir")) {
02413          ast_copy_string(ast_config_AST_SPOOL_DIR, v->value, sizeof(ast_config_AST_SPOOL_DIR));
02414          snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", v->value);
02415       } else if (!strcasecmp(v->name, "astvarlibdir")) {
02416          ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR));
02417          snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/astdb", v->value);
02418       } else if (!strcasecmp(v->name, "astdatadir")) {
02419          ast_copy_string(ast_config_AST_DATA_DIR, v->value, sizeof(ast_config_AST_DATA_DIR));
02420          snprintf(ast_config_AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR), "%s/keys", v->value);
02421       } else if (!strcasecmp(v->name, "astlogdir")) {
02422          ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR));
02423       } else if (!strcasecmp(v->name, "astagidir")) {
02424          ast_copy_string(ast_config_AST_AGI_DIR, v->value, sizeof(ast_config_AST_AGI_DIR));
02425       } else if (!strcasecmp(v->name, "astrundir")) {
02426          snprintf(ast_config_AST_PID, sizeof(ast_config_AST_PID), "%s/%s", v->value, "asterisk.pid");
02427          snprintf(ast_config_AST_SOCKET, sizeof(ast_config_AST_SOCKET), "%s/%s", v->value, ast_config_AST_CTL);
02428          ast_copy_string(ast_config_AST_RUN_DIR, v->value, sizeof(ast_config_AST_RUN_DIR));
02429       } else if (!strcasecmp(v->name, "astmoddir")) {
02430          ast_copy_string(ast_config_AST_MODULE_DIR, v->value, sizeof(ast_config_AST_MODULE_DIR));
02431       }
02432    }
02433 
02434    for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
02435       /* verbose level (-v at startup) */
02436       if (!strcasecmp(v->name, "verbose")) {
02437          option_verbose = atoi(v->value);
02438       /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
02439       } else if (!strcasecmp(v->name, "timestamp")) {
02440          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
02441       /* whether or not to support #exec in config files */
02442       } else if (!strcasecmp(v->name, "execincludes")) {
02443          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
02444       /* debug level (-d at startup) */
02445       } else if (!strcasecmp(v->name, "debug")) {
02446          option_debug = 0;
02447          if (sscanf(v->value, "%d", &option_debug) != 1) {
02448             option_debug = ast_true(v->value);
02449          }
02450 #if HAVE_WORKING_FORK
02451       /* Disable forking (-f at startup) */
02452       } else if (!strcasecmp(v->name, "nofork")) {
02453          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
02454       /* Always fork, even if verbose or debug are enabled (-F at startup) */
02455       } else if (!strcasecmp(v->name, "alwaysfork")) {
02456          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
02457 #endif
02458       /* Run quietly (-q at startup ) */
02459       } else if (!strcasecmp(v->name, "quiet")) {
02460          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
02461       /* Run as console (-c at startup, implies nofork) */
02462       } else if (!strcasecmp(v->name, "console")) {
02463          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CONSOLE);
02464       /* Run with high priority if the O/S permits (-p at startup) */
02465       } else if (!strcasecmp(v->name, "highpriority")) {
02466          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
02467       /* Initialize RSA auth keys (IAX2) (-i at startup) */
02468       } else if (!strcasecmp(v->name, "initcrypto")) {
02469          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
02470       /* Disable ANSI colors for console (-c at startup) */
02471       } else if (!strcasecmp(v->name, "nocolor")) {
02472          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
02473       /* Disable some usage warnings for picky people :p */
02474       } else if (!strcasecmp(v->name, "dontwarn")) {
02475          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
02476       /* Dump core in case of crash (-g) */
02477       } else if (!strcasecmp(v->name, "dumpcore")) {
02478          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
02479       /* Cache recorded sound files to another directory during recording */
02480       } else if (!strcasecmp(v->name, "cache_record_files")) {
02481          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
02482       /* Specify cache directory */
02483       }  else if (!strcasecmp(v->name, "record_cache_dir")) {
02484          ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
02485       /* Build transcode paths via SLINEAR, instead of directly */
02486       } else if (!strcasecmp(v->name, "transcode_via_sln")) {
02487          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
02488       /* Transmit SLINEAR silence while a channel is being recorded */
02489       } else if (!strcasecmp(v->name, "transmit_silence_during_record")) {
02490          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
02491       /* Enable internal timing */
02492       } else if (!strcasecmp(v->name, "internal_timing")) {
02493          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING);
02494       } else if (!strcasecmp(v->name, "maxcalls")) {
02495          if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
02496             option_maxcalls = 0;
02497          }
02498       } else if (!strcasecmp(v->name, "maxload")) {
02499          double test[1];
02500 
02501          if (getloadavg(test, 1) == -1) {
02502             ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
02503             option_maxload = 0.0;
02504          } else if ((sscanf(v->value, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
02505             option_maxload = 0.0;
02506          }
02507       /* What user to run as */
02508       } else if (!strcasecmp(v->name, "runuser")) {
02509          ast_copy_string(ast_config_AST_RUN_USER, v->value, sizeof(ast_config_AST_RUN_USER));
02510       /* What group to run as */
02511       } else if (!strcasecmp(v->name, "rungroup")) {
02512          ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP));
02513       } else if (!strcasecmp(v->name, "systemname")) {
02514          ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME));
02515       } else if (!strcasecmp(v->name, "uniquename")) {
02516          ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME));
02517       } else if (!strcasecmp(v->name, "languageprefix")) {
02518          ast_language_is_prefix = ast_true(v->value);
02519       }
02520    }
02521    ast_config_destroy(cfg);
02522 }

int ast_register_atexit ( void(*)(void)  func  ) 

Register a function to be executed before Asterisk exits.

Parameters:
func The callback function to use.
Returns:
Zero on success, -1 on error.

Definition at line 702 of file asterisk.c.

References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_unregister_atexit(), func, and ast_atexit::func.

Referenced by do_reload(), and load_module().

00703 {
00704    struct ast_atexit *ae;
00705 
00706    if (!(ae = ast_calloc(1, sizeof(*ae))))
00707       return -1;
00708 
00709    ae->func = func;
00710 
00711    ast_unregister_atexit(func);  
00712 
00713    AST_LIST_LOCK(&atexits);
00714    AST_LIST_INSERT_HEAD(&atexits, ae, list);
00715    AST_LIST_UNLOCK(&atexits);
00716 
00717    return 0;
00718 }

void ast_register_file_version ( const char *  file,
const char *  version 
)

Register the version of a source code file with the core.

Parameters:
file the source file name
version the version string (typically a CVS revision keyword string)
Returns:
nothing
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to register a file with the core.

Definition at line 256 of file asterisk.c.

References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_strdupa, and ast_strip_quoted().

00257 {
00258    struct file_version *new;
00259    char *work;
00260    size_t version_length;
00261 
00262    work = ast_strdupa(version);
00263    work = ast_strip(ast_strip_quoted(work, "$", "$"));
00264    version_length = strlen(work) + 1;
00265    
00266    if (!(new = ast_calloc(1, sizeof(*new) + version_length)))
00267       return;
00268 
00269    new->file = file;
00270    new->version = (char *) new + sizeof(*new);
00271    memcpy(new->version, work, version_length);
00272    AST_LIST_LOCK(&file_versions);
00273    AST_LIST_INSERT_HEAD(&file_versions, new, list);
00274    AST_LIST_UNLOCK(&file_versions);
00275 }

void ast_register_thread ( char *  name  ) 

Definition at line 306 of file asterisk.c.

References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, and AST_LIST_UNLOCK.

Referenced by dummy_start().

00307 { 
00308    struct thread_list_t *new = ast_calloc(1, sizeof(*new));
00309 
00310    if (!new)
00311       return;
00312    new->id = pthread_self();
00313    new->name = name; /* steal the allocated memory for the thread name */
00314    AST_LIST_LOCK(&thread_list);
00315    AST_LIST_INSERT_HEAD(&thread_list, new, list);
00316    AST_LIST_UNLOCK(&thread_list);
00317 }

static void ast_remotecontrol ( char *  data  )  [static]

Definition at line 2237 of file asterisk.c.

References ast_el_initialize(), ast_el_read_char(), ast_el_read_history(), ast_log(), ast_opt_exec, ast_opt_mute, ast_strlen_zero(), ast_verbose(), errno, pollfd::events, pollfd::fd, fdprint(), hostname, LOG_WARNING, poll(), POLLIN, remoteconsolehandler(), pollfd::revents, and strsep().

Referenced by main().

02238 {
02239    char buf[80];
02240    int res;
02241    char filename[80] = "";
02242    char *hostname;
02243    char *cpid;
02244    char *version;
02245    int pid;
02246    char tmp[80];
02247    char *stringp = NULL;
02248 
02249    char *ebuf;
02250    int num = 0;
02251 
02252    read(ast_consock, buf, sizeof(buf));
02253    if (data)
02254       write(ast_consock, data, strlen(data) + 1);
02255    stringp = buf;
02256    hostname = strsep(&stringp, "/");
02257    cpid = strsep(&stringp, "/");
02258    version = strsep(&stringp, "\n");
02259    if (!version)
02260       version = "<Version Unknown>";
02261    stringp = hostname;
02262    strsep(&stringp, ".");
02263    if (cpid)
02264       pid = atoi(cpid);
02265    else
02266       pid = -1;
02267    if (!data) {
02268       snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
02269       fdprint(ast_consock, tmp);
02270       snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
02271       fdprint(ast_consock, tmp);
02272       if (!ast_opt_mute)
02273          fdprint(ast_consock, "logger mute silent");
02274       else 
02275          printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02276    }
02277    ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
02278    remotehostname = hostname;
02279    if (getenv("HOME")) 
02280       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
02281    if (el_hist == NULL || el == NULL)
02282       ast_el_initialize();
02283 
02284    el_set(el, EL_GETCFN, ast_el_read_char);
02285 
02286    if (!ast_strlen_zero(filename))
02287       ast_el_read_history(filename);
02288 
02289    if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
02290       char tempchar;
02291       struct pollfd fds;
02292       fds.fd = ast_consock;
02293       fds.events = POLLIN;
02294       fds.revents = 0;
02295       while (poll(&fds, 1, 100) > 0)
02296          ast_el_read_char(el, &tempchar);
02297       return;
02298    }
02299    for (;;) {
02300       ebuf = (char *)el_gets(el, &num);
02301 
02302       if (!ebuf && write(1, "", 1) < 0)
02303          break;
02304 
02305       if (!ast_strlen_zero(ebuf)) {
02306          if (ebuf[strlen(ebuf)-1] == '\n')
02307             ebuf[strlen(ebuf)-1] = '\0';
02308          if (!remoteconsolehandler(ebuf)) {
02309             res = write(ast_consock, ebuf, strlen(ebuf) + 1);
02310             if (res < 1) {
02311                ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
02312                break;
02313             }
02314          }
02315       }
02316    }
02317    printf("\nDisconnected from Asterisk server\n");
02318 }

void ast_replace_sigchld ( void   ) 

Replace the SIGCHLD handler.

Normally, Asterisk has a SIGCHLD handler that is cleaning up all zombie processes from forking elsewhere in Asterisk. However, if you want to wait*() on the process to retrieve information about it's exit status, then this signal handler needs to be temporaraly replaced.

Code that executes this function *must* call ast_unreplace_sigchld() after it is finished doing the wait*().

Definition at line 755 of file asterisk.c.

References ast_mutex_lock(), ast_mutex_unlock(), and null_sig_handler().

Referenced by ast_safe_system().

00756 {
00757    unsigned int level;
00758 
00759    ast_mutex_lock(&safe_system_lock);
00760    level = safe_system_level++;
00761 
00762    /* only replace the handler if it has not already been done */
00763    if (level == 0)
00764       safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
00765 
00766    ast_mutex_unlock(&safe_system_lock);
00767 }

static void ast_run_atexits ( void   )  [static]

Definition at line 1211 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_atexit::func.

Referenced by quit_handler().

01212 {
01213    struct ast_atexit *ae;
01214    AST_LIST_LOCK(&atexits);
01215    AST_LIST_TRAVERSE(&atexits, ae, list) {
01216       if (ae->func) 
01217          ae->func();
01218    }
01219    AST_LIST_UNLOCK(&atexits);
01220 }

int ast_safe_system ( const char *  s  ) 

Safely spawn an external program while closing file descriptors

Note:
This replaces the system call in all Asterisk modules

Definition at line 783 of file asterisk.c.

References ast_log(), ast_opt_high_priority, ast_replace_sigchld(), ast_set_priority(), ast_unreplace_sigchld(), errno, LOG_WARNING, WEXITSTATUS, and WIFEXITED.

Referenced by alarmreceiver_exec(), ast_closestream(), ast_monitor_change_fname(), ast_monitor_start(), ast_monitor_stop(), consolehandler(), make_email_file(), mixmonitor_thread(), process_text_line(), remoteconsolehandler(), run_externnotify(), sendmail(), sendpage(), system_exec_helper(), and vm_change_password_shell().

00784 {
00785    pid_t pid;
00786 #ifdef HAVE_WORKING_FORK
00787    int x;
00788 #endif
00789    int res;
00790    struct rusage rusage;
00791    int status;
00792 
00793 #if defined(HAVE_WORKING_FORK) || defined(HAVE_WORKING_VFORK)
00794    ast_replace_sigchld();
00795 
00796 #ifdef HAVE_WORKING_FORK
00797    pid = fork();
00798 #else
00799    pid = vfork();
00800 #endif   
00801 
00802    if (pid == 0) {
00803 #ifdef HAVE_WORKING_FORK
00804       if (ast_opt_high_priority)
00805          ast_set_priority(0);
00806       /* Close file descriptors and launch system command */
00807       for (x = STDERR_FILENO + 1; x < 4096; x++)
00808          close(x);
00809 #endif
00810       execl("/bin/sh", "/bin/sh", "-c", s, (char *) NULL);
00811       _exit(1);
00812    } else if (pid > 0) {
00813       for(;;) {
00814          res = wait4(pid, &status, 0, &rusage);
00815          if (res > -1) {
00816             res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
00817             break;
00818          } else if (errno != EINTR) 
00819             break;
00820       }
00821    } else {
00822       ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
00823       res = -1;
00824    }
00825 
00826    ast_unreplace_sigchld();
00827 #else
00828    res = -1;
00829 #endif
00830 
00831    return res;
00832 }

int ast_set_priority ( int   ) 

We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy activity on it, this is a good thing.

Provided by asterisk.c

Definition at line 1177 of file asterisk.c.

References ast_log(), ast_verbose(), LOG_WARNING, sched_setscheduler, and setpriority.

Referenced by app_exec(), ast_safe_system(), icesencode(), launch_script(), main(), mp3play(), NBScatplay(), send_waveform_to_fd(), spawn_mp3(), and spawn_ras().

01178 {
01179    struct sched_param sched;
01180    memset(&sched, 0, sizeof(sched));
01181 #ifdef __linux__
01182    if (pri) {  
01183       sched.sched_priority = 10;
01184       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01185          ast_log(LOG_WARNING, "Unable to set high priority\n");
01186          return -1;
01187       } else
01188          if (option_verbose)
01189             ast_verbose("Set to realtime thread\n");
01190    } else {
01191       sched.sched_priority = 0;
01192       /* According to the manpage, these parameters can never fail. */
01193       sched_setscheduler(0, SCHED_OTHER, &sched);
01194    }
01195 #else
01196    if (pri) {
01197       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01198          ast_log(LOG_WARNING, "Unable to set high priority\n");
01199          return -1;
01200       } else
01201          if (option_verbose)
01202             ast_verbose("Set to high priority\n");
01203    } else {
01204       /* According to the manpage, these parameters can never fail. */
01205       setpriority(PRIO_PROCESS, 0, 0);
01206    }
01207 #endif
01208    return 0;
01209 }

static int ast_tryconnect ( void   )  [static]

Definition at line 1101 of file asterisk.c.

References AF_LOCAL, ast_log(), errno, LOG_WARNING, and PF_LOCAL.

Referenced by ast_el_read_char(), and main().

01102 {
01103    struct sockaddr_un sunaddr;
01104    int res;
01105    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01106    if (ast_consock < 0) {
01107       ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
01108       return 0;
01109    }
01110    memset(&sunaddr, 0, sizeof(sunaddr));
01111    sunaddr.sun_family = AF_LOCAL;
01112    ast_copy_string(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01113    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01114    if (res) {
01115       close(ast_consock);
01116       ast_consock = -1;
01117       return 0;
01118    } else
01119       return 1;
01120 }

void ast_unregister_atexit ( void(*)(void)  func  ) 

Unregister a function registered with ast_register_atexit().

Parameters:
func The callback function to unregister.

Definition at line 720 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, free, func, and ast_atexit::func.

Referenced by ast_register_atexit(), and do_reload().

00721 {
00722    struct ast_atexit *ae = NULL;
00723 
00724    AST_LIST_LOCK(&atexits);
00725    AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
00726       if (ae->func == func) {
00727          AST_LIST_REMOVE_CURRENT(&atexits, list);
00728          break;
00729       }
00730    }
00731    AST_LIST_TRAVERSE_SAFE_END
00732    AST_LIST_UNLOCK(&atexits);
00733 
00734    if (ae)
00735       free(ae);
00736 }

void ast_unregister_file_version ( const char *  file  ) 

Unregister a source code file from the core.

Parameters:
file the source file name
Returns:
nothing
This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to automatically unregister the file when the module is unloaded.

Definition at line 277 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, and free.

00278 {
00279    struct file_version *find;
00280 
00281    AST_LIST_LOCK(&file_versions);
00282    AST_LIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
00283       if (!strcasecmp(find->file, file)) {
00284          AST_LIST_REMOVE_CURRENT(&file_versions, list);
00285          break;
00286       }
00287    }
00288    AST_LIST_TRAVERSE_SAFE_END;
00289    AST_LIST_UNLOCK(&file_versions);
00290    if (find)
00291       free(find);
00292 }

void ast_unregister_thread ( void *  id  ) 

Definition at line 319 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, and free.

Referenced by dummy_start().

00320 {
00321    struct thread_list_t *x;
00322 
00323    AST_LIST_LOCK(&thread_list);
00324    AST_LIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
00325       if ((void *) x->id == id) {
00326          AST_LIST_REMOVE_CURRENT(&thread_list, list);
00327          break;
00328       }
00329    }
00330    AST_LIST_TRAVERSE_SAFE_END;
00331    AST_LIST_UNLOCK(&thread_list);
00332    if (x) {
00333       free(x->name);
00334       free(x);
00335    }
00336 }

void ast_unreplace_sigchld ( void   ) 

Restore the SIGCHLD handler.

This function is called after a call to ast_replace_sigchld. It restores the SIGCHLD handler that cleans up any zombie processes.

Definition at line 769 of file asterisk.c.

References ast_mutex_lock(), and ast_mutex_unlock().

Referenced by agi_exec_full(), and ast_safe_system().

00770 {
00771    unsigned int level;
00772 
00773    ast_mutex_lock(&safe_system_lock);
00774    level = --safe_system_level;
00775 
00776    /* only restore the handler if we are the last one */
00777    if (level == 0)
00778       signal(SIGCHLD, safe_system_prev_handler);
00779 
00780    ast_mutex_unlock(&safe_system_lock);
00781 }

static void child_handler ( int  sig  )  [static]

Definition at line 1147 of file asterisk.c.

Referenced by main().

01148 {
01149    /* Must not ever ast_log or ast_verbose within signal handler */
01150    int n, status;
01151 
01152    /*
01153     * Reap all dead children -- not just one
01154     */
01155    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01156       ;
01157    if (n == 0 && option_debug)   
01158       printf("Huh?  Child handler, but nobody there?\n");
01159    signal(sig, child_handler);
01160 }

static char* cli_complete ( EditLine *  el,
int  ch 
) [static]

Definition at line 2044 of file asterisk.c.

References AST_CLI_COMPLETE_EOF, ast_cli_completion_matches(), ast_cli_display_match_list(), ast_el_strtoarr(), ast_malloc, ast_opt_remote, ast_realloc, fdprint(), free, and len.

Referenced by ast_el_initialize().

02045 {
02046    int len = 0;
02047    char *ptr;
02048    int nummatches = 0;
02049    char **matches;
02050    int retval = CC_ERROR;
02051    char buf[2048];
02052    int res;
02053 
02054    LineInfo *lf = (LineInfo *)el_line(el);
02055 
02056    *(char *)lf->cursor = '\0';
02057    ptr = (char *)lf->cursor;
02058    if (ptr) {
02059       while (ptr > lf->buffer) {
02060          if (isspace(*ptr)) {
02061             ptr++;
02062             break;
02063          }
02064          ptr--;
02065       }
02066    }
02067 
02068    len = lf->cursor - ptr;
02069 
02070    if (ast_opt_remote) {
02071       snprintf(buf, sizeof(buf),"_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 
02072       fdprint(ast_consock, buf);
02073       res = read(ast_consock, buf, sizeof(buf));
02074       buf[res] = '\0';
02075       nummatches = atoi(buf);
02076 
02077       if (nummatches > 0) {
02078          char *mbuf;
02079          int mlen = 0, maxmbuf = 2048;
02080          /* Start with a 2048 byte buffer */       
02081          if (!(mbuf = ast_malloc(maxmbuf)))
02082             return (char *)(CC_ERROR);
02083          snprintf(buf, sizeof(buf),"_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 
02084          fdprint(ast_consock, buf);
02085          res = 0;
02086          mbuf[0] = '\0';
02087          while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
02088             if (mlen + 1024 > maxmbuf) {
02089                /* Every step increment buffer 1024 bytes */
02090                maxmbuf += 1024;              
02091                if (!(mbuf = ast_realloc(mbuf, maxmbuf)))
02092                   return (char *)(CC_ERROR);
02093             }
02094             /* Only read 1024 bytes at a time */
02095             res = read(ast_consock, mbuf + mlen, 1024);
02096             if (res > 0)
02097                mlen += res;
02098          }
02099          mbuf[mlen] = '\0';
02100 
02101          matches = ast_el_strtoarr(mbuf);
02102          free(mbuf);
02103       } else
02104          matches = (char **) NULL;
02105    } else {
02106       char **p, *oldbuf=NULL;
02107       nummatches = 0;
02108       matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
02109       for (p = matches; p && *p; p++) {
02110          if (!oldbuf || strcmp(*p,oldbuf))
02111             nummatches++;
02112          oldbuf = *p;
02113       }
02114    }
02115 
02116    if (matches) {
02117       int i;
02118       int matches_num, maxlen, match_len;
02119 
02120       if (matches[0][0] != '\0') {
02121          el_deletestr(el, (int) len);
02122          el_insertstr(el, matches[0]);
02123          retval = CC_REFRESH;
02124       }
02125 
02126       if (nummatches == 1) {
02127          /* Found an exact match */
02128          el_insertstr(el, " ");
02129          retval = CC_REFRESH;
02130       } else {
02131          /* Must be more than one match */
02132          for (i=1, maxlen=0; matches[i]; i++) {
02133             match_len = strlen(matches[i]);
02134             if (match_len > maxlen)
02135                maxlen = match_len;
02136          }
02137          matches_num = i - 1;
02138          if (matches_num >1) {
02139             fprintf(stdout, "\n");
02140             ast_cli_display_match_list(matches, nummatches, maxlen);
02141             retval = CC_REDISPLAY;
02142          } else { 
02143             el_insertstr(el," ");
02144             retval = CC_REFRESH;
02145          }
02146       }
02147       for (i = 0; matches[i]; i++)
02148          free(matches[i]);
02149       free(matches);
02150    }
02151 
02152    return (char *)(long)retval;
02153 }

static char* cli_prompt ( EditLine *  el  )  [static]

Definition at line 1803 of file asterisk.c.

References ast_localtime(), ast_opt_remote, ASTERISK_PROMPT, ASTERISK_PROMPT2, COLOR_BLACK, COLOR_WHITE, hostname, t, and term_color_code().

Referenced by ast_el_initialize().

01804 {
01805    static char prompt[200];
01806    char *pfmt;
01807    int color_used = 0;
01808    char term_code[20];
01809 
01810    if ((pfmt = getenv("ASTERISK_PROMPT"))) {
01811       char *t = pfmt, *p = prompt;
01812       memset(prompt, 0, sizeof(prompt));
01813       while (*t != '\0' && *p < sizeof(prompt)) {
01814          if (*t == '%') {
01815             char hostname[MAXHOSTNAMELEN]="";
01816             int i;
01817             time_t ts;
01818             struct tm tm;
01819 #ifdef linux
01820             FILE *LOADAVG;
01821 #endif
01822             int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
01823 
01824             t++;
01825             switch (*t) {
01826             case 'C': /* color */
01827                t++;
01828                if (sscanf(t, "%d;%d%n", &fgcolor, &bgcolor, &i) == 2) {
01829                   strncat(p, term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
01830                   t += i - 1;
01831                } else if (sscanf(t, "%d%n", &fgcolor, &i) == 1) {
01832                   strncat(p, term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
01833                   t += i - 1;
01834                }
01835 
01836                /* If the color has been reset correctly, then there's no need to reset it later */
01837                if ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) {
01838                   color_used = 0;
01839                } else {
01840                   color_used = 1;
01841                }
01842                break;
01843             case 'd': /* date */
01844                memset(&tm, 0, sizeof(tm));
01845                time(&ts);
01846                if (ast_localtime(&ts, &tm, NULL)) {
01847                   strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm);
01848                }
01849                break;
01850             case 'h': /* hostname */
01851                if (!gethostname(hostname, sizeof(hostname) - 1)) {
01852                   strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
01853                } else {
01854                   strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
01855                }
01856                break;
01857             case 'H': /* short hostname */
01858                if (!gethostname(hostname, sizeof(hostname) - 1)) {
01859                   for (i = 0; i < sizeof(hostname); i++) {
01860                      if (hostname[i] == '.') {
01861                         hostname[i] = '\0';
01862                         break;
01863                      }
01864                   }
01865                   strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
01866                } else {
01867                   strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
01868                }
01869                break;
01870 #ifdef linux
01871             case 'l': /* load avg */
01872                t++;
01873                if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
01874                   float avg1, avg2, avg3;
01875                   int actproc, totproc, npid, which;
01876                   fscanf(LOADAVG, "%f %f %f %d/%d %d",
01877                      &avg1, &avg2, &avg3, &actproc, &totproc, &npid);
01878                   if (sscanf(t, "%d", &which) == 1) {
01879                      switch (which) {
01880                      case 1:
01881                         snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1);
01882                         break;
01883                      case 2:
01884                         snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2);
01885                         break;
01886                      case 3:
01887                         snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3);
01888                         break;
01889                      case 4:
01890                         snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc);
01891                         break;
01892                      case 5:
01893                         snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid);
01894                         break;
01895                      }
01896                   }
01897                }
01898                break;
01899 #endif
01900             case 's': /* Asterisk system name (from asterisk.conf) */
01901                strncat(p, ast_config_AST_SYSTEM_NAME, sizeof(prompt) - strlen(prompt) - 1);
01902                break;
01903             case 't': /* time */
01904                memset(&tm, 0, sizeof(tm));
01905                time(&ts);
01906                if (ast_localtime(&ts, &tm, NULL)) {
01907                   strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm);
01908                }
01909                break;
01910             case '#': /* process console or remote? */
01911                if (!ast_opt_remote) {
01912                   strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1);
01913                } else {
01914                   strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1);
01915                }
01916                break;
01917             case '%': /* literal % */
01918                strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1);
01919                break;
01920             case '\0': /* % is last character - prevent bug */
01921                t--;
01922                break;
01923             }
01924             while (*p != '\0') {
01925                p++;
01926             }
01927             t++;
01928          } else {
01929             *p = *t;
01930             p++;
01931             t++;
01932          }
01933       }
01934       if (color_used) {
01935          /* Force colors back to normal at end */
01936          term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code));
01937          if (strlen(term_code) > sizeof(prompt) - strlen(prompt)) {
01938             strncat(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code));
01939          } else {
01940             strncat(p, term_code, sizeof(term_code));
01941          }
01942       }
01943    } else if (remotehostname)
01944       snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT2, remotehostname);
01945    else
01946       snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT);
01947 
01948    return(prompt);   
01949 }

static char* complete_show_version_files ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 678 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.

00679 {
00680    struct file_version *find;
00681    int which = 0;
00682    char *ret = NULL;
00683    int matchlen = strlen(word);
00684    
00685    if (pos != 4)
00686       return NULL;
00687 
00688    AST_LIST_LOCK(&file_versions);
00689    AST_LIST_TRAVERSE(&file_versions, find, list) {
00690       if (!strncasecmp(word, find->file, matchlen) && ++which > state) {
00691          ret = ast_strdup(find->file);
00692          break;
00693       }
00694    }
00695    AST_LIST_UNLOCK(&file_versions);
00696 
00697    return ret;
00698 }

static char* complete_show_version_files_deprecated ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 656 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.

00657 {
00658    struct file_version *find;
00659    int which = 0;
00660    char *ret = NULL;
00661    int matchlen = strlen(word);
00662 
00663    if (pos != 3)
00664       return NULL;
00665 
00666    AST_LIST_LOCK(&file_versions);
00667    AST_LIST_TRAVERSE(&file_versions, find, list) {
00668       if (!strncasecmp(word, find->file, matchlen) && ++which > state) {
00669          ret = ast_strdup(find->file);
00670          break;
00671       }
00672    }
00673    AST_LIST_UNLOCK(&file_versions);
00674 
00675    return ret;
00676 }

static void console_verboser ( const char *  s  )  [static]

Definition at line 1353 of file asterisk.c.

References ast_opt_console, AST_PTHREADT_NULL, fix_header(), VERBOSE_PREFIX_1, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.

Referenced by main().

01354 {
01355    char tmp[80];
01356    const char *c = NULL;
01357 
01358    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01359        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01360        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01361        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
01362       fputs(tmp, stdout);
01363       fputs(c, stdout);
01364    } else
01365       fputs(s, stdout);
01366 
01367    fflush(stdout);
01368    
01369    /* Wake up a poll()ing console */
01370    if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
01371       pthread_kill(consolethread, SIGURG);
01372 }

static void consolehandler ( char *  s  )  [static]

Definition at line 1384 of file asterisk.c.

References ast_all_zeros(), ast_cli_command(), ast_el_add_history(), ast_safe_system(), and term_end().

Referenced by main().

01385 {
01386    printf(term_end());
01387    fflush(stdout);
01388 
01389    /* Called when readline data is available */
01390    if (!ast_all_zeros(s))
01391       ast_el_add_history(s);
01392    /* The real handler for bang */
01393    if (s[0] == '!') {
01394       if (s[1])
01395          ast_safe_system(s+1);
01396       else
01397          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01398    } else 
01399       ast_cli_command(STDOUT_FILENO, s);
01400 }

static int fdprint ( int  fd,
const char *  s 
) [static]

Definition at line 738 of file asterisk.c.

Referenced by ast_el_read_char(), ast_network_puts(), ast_network_puts_mutable(), ast_remotecontrol(), cli_complete(), listener(), and netconsole().

00739 {
00740    return write(fd, s, strlen(s) + 1);
00741 }

static const char* fix_header ( char *  outbuf,
int  maxout,
const char *  s,
char *  cmp 
) [static]

Definition at line 1342 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01343 {
01344    const char *c;
01345    if (!strncmp(s, cmp, strlen(cmp))) {
01346       c = s + strlen(cmp);
01347       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01348       return c;
01349    }
01350    return NULL;
01351 }

static int handle_abort_halt ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1554 of file asterisk.c.

References ast_cancel_shutdown(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01555 {
01556    if (argc != 2)
01557       return RESULT_SHOWUSAGE;
01558    ast_cancel_shutdown();
01559    shuttingdown = 0;
01560    return RESULT_SUCCESS;
01561 }

static int handle_bang ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1563 of file asterisk.c.

References RESULT_SUCCESS.

01564 {
01565    return RESULT_SUCCESS;
01566 }

static int handle_restart_gracefully ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1537 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01538 {
01539    if (argc != 2)
01540       return RESULT_SHOWUSAGE;
01541    quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
01542    return RESULT_SUCCESS;
01543 }

static int handle_restart_now ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1529 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01530 {
01531    if (argc != 2)
01532       return RESULT_SHOWUSAGE;
01533    quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */);
01534    return RESULT_SUCCESS;
01535 }

static int handle_restart_when_convenient ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1545 of file asterisk.c.

References ast_cli(), quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01546 {
01547    if (argc != 3)
01548       return RESULT_SHOWUSAGE;
01549    ast_cli(fd, "Waiting for inactivity to perform restart\n");
01550    quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */);
01551    return RESULT_SUCCESS;
01552 }

static int handle_show_profile ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 496 of file asterisk.c.

References ast_cli(), profile_data::e, profile_data::entries, profile_entry::events, profile_data::max_size, profile_entry::name, profile_entry::scale, and profile_entry::value.

00497 {
00498    int i, min, max;
00499    char *search = NULL;
00500 
00501    if (prof_data == NULL)
00502       return 0;
00503 
00504    min = 0;
00505    max = prof_data->entries;
00506    if  (argc > 3) { /* specific entries */
00507       if (isdigit(argv[3][0])) {
00508          min = atoi(argv[3]);
00509          if (argc == 5 && strcmp(argv[4], "-"))
00510             max = atoi(argv[4]);
00511       } else
00512          search = argv[3];
00513    }
00514    if (max > prof_data->entries)
00515       max = prof_data->entries;
00516    if (!strcmp(argv[1], "clear")) {
00517       for (i= min; i < max; i++) {
00518          if (!search || strstr(prof_data->e[i].name, search)) {
00519             prof_data->e[i].value = 0;
00520             prof_data->e[i].events = 0;
00521          }
00522       }
00523       return 0;
00524    }
00525    ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n",
00526       prof_data->entries, prof_data->max_size);
00527    ast_cli(fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
00528          "Value", "Average", "Name");
00529    for (i = min; i < max; i++) {
00530       struct profile_entry *e = &prof_data->e[i];
00531       if (!search || strstr(prof_data->e[i].name, search))
00532           ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
00533          i,
00534          (long)e->scale,
00535          (long)e->events, (long long)e->value,
00536          (long long)(e->events ? e->value / e->events : e->value),
00537          e->name);
00538    }
00539    return 0;
00540 }

static int handle_show_profile_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 450 of file asterisk.c.

References ast_cli(), profile_data::e, profile_data::entries, profile_entry::events, profile_data::max_size, profile_entry::name, profile_entry::scale, and profile_entry::value.

00451 {
00452    int i, min, max;
00453    char *search = NULL;
00454 
00455    if (prof_data == NULL)
00456       return 0;
00457 
00458    min = 0;
00459    max = prof_data->entries;
00460    if  (argc >= 3) { /* specific entries */
00461       if (isdigit(argv[2][0])) {
00462          min = atoi(argv[2]);
00463          if (argc == 4 && strcmp(argv[3], "-"))
00464             max = atoi(argv[3]);
00465       } else
00466          search = argv[2];
00467    }
00468    if (max > prof_data->entries)
00469       max = prof_data->entries;
00470    if (!strcmp(argv[0], "clear")) {
00471       for (i= min; i < max; i++) {
00472          if (!search || strstr(prof_data->e[i].name, search)) {
00473             prof_data->e[i].value = 0;
00474             prof_data->e[i].events = 0;
00475          }
00476       }
00477       return 0;
00478    }
00479    ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n",
00480       prof_data->entries, prof_data->max_size);
00481    ast_cli(fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
00482          "Value", "Average", "Name");
00483    for (i = min; i < max; i++) {
00484       struct profile_entry *e = &prof_data->e[i];
00485       if (!search || strstr(prof_data->e[i].name, search))
00486           ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
00487          i,
00488          (long)e->scale,
00489          (long)e->events, (long long)e->value,
00490          (long long)(e->events ? e->value / e->events : e->value),
00491          e->name);
00492    }
00493    return 0;
00494 }

static int handle_show_threads ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 338 of file asterisk.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

00339 {
00340    int count = 0;
00341    struct thread_list_t *cur;
00342 
00343    AST_LIST_LOCK(&thread_list);
00344    AST_LIST_TRAVERSE(&thread_list, cur, list) {
00345       ast_cli(fd, "%p %s\n", (void *)cur->id, cur->name);
00346       count++;
00347    }
00348         AST_LIST_UNLOCK(&thread_list);
00349    ast_cli(fd, "%d threads listed.\n", count);
00350    return 0;
00351 }

static int handle_show_version_files ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 602 of file asterisk.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, FORMAT, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00603 {
00604 #define FORMAT "%-25.25s %-40.40s\n"
00605    struct file_version *iterator;
00606    regex_t regexbuf;
00607    int havepattern = 0;
00608    int havename = 0;
00609    int count_files = 0;
00610 
00611    switch (argc) {
00612    case 6:
00613       if (!strcasecmp(argv[4], "like")) {
00614          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
00615             return RESULT_SHOWUSAGE;
00616          havepattern = 1;
00617       } else
00618          return RESULT_SHOWUSAGE;
00619       break;
00620    case 5:
00621       havename = 1;
00622       break;
00623    case 4:
00624       break;
00625    default:
00626       return RESULT_SHOWUSAGE;
00627    }
00628 
00629    ast_cli(fd, FORMAT, "File", "Revision");
00630    ast_cli(fd, FORMAT, "----", "--------");
00631    AST_LIST_LOCK(&file_versions);
00632    AST_LIST_TRAVERSE(&file_versions, iterator, list) {
00633       if (havename && strcasecmp(iterator->file, argv[4]))
00634          continue;
00635       
00636       if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
00637          continue;
00638 
00639       ast_cli(fd, FORMAT, iterator->file, iterator->version);
00640       count_files++;
00641       if (havename)
00642          break;
00643    }
00644    AST_LIST_UNLOCK(&file_versions);
00645    if (!havename) {
00646       ast_cli(fd, "%d files listed.\n", count_files);
00647    }
00648 
00649    if (havepattern)
00650       regfree(&regexbuf);
00651 
00652    return RESULT_SUCCESS;
00653 #undef FORMAT
00654 }

static int handle_show_version_files_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

CLI command to list module versions.

Definition at line 548 of file asterisk.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, FORMAT, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00549 {
00550 #define FORMAT "%-25.25s %-40.40s\n"
00551    struct file_version *iterator;
00552    regex_t regexbuf;
00553    int havepattern = 0;
00554    int havename = 0;
00555    int count_files = 0;
00556 
00557    switch (argc) {
00558    case 5:
00559       if (!strcasecmp(argv[3], "like")) {
00560          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
00561             return RESULT_SHOWUSAGE;
00562          havepattern = 1;
00563       } else
00564          return RESULT_SHOWUSAGE;
00565       break;
00566    case 4:
00567       havename = 1;
00568       break;
00569    case 3:
00570       break;
00571    default:
00572       return RESULT_SHOWUSAGE;
00573    }
00574 
00575    ast_cli(fd, FORMAT, "File", "Revision");
00576    ast_cli(fd, FORMAT, "----", "--------");
00577    AST_LIST_LOCK(&file_versions);
00578    AST_LIST_TRAVERSE(&file_versions, iterator, list) {
00579       if (havename && strcasecmp(iterator->file, argv[3]))
00580          continue;
00581 
00582       if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
00583          continue;
00584 
00585       ast_cli(fd, FORMAT, iterator->file, iterator->version);
00586       count_files++;
00587       if (havename)
00588          break;
00589    }
00590    AST_LIST_UNLOCK(&file_versions);
00591    if (!havename) {
00592       ast_cli(fd, "%d files listed.\n", count_files);
00593    }
00594 
00595    if (havepattern)
00596       regfree(&regexbuf);
00597 
00598    return RESULT_SUCCESS;
00599 #undef FORMAT
00600 }

static int handle_shutdown_gracefully ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1512 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01513 {
01514    if (argc != 2)
01515       return RESULT_SHOWUSAGE;
01516    quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
01517    return RESULT_SUCCESS;
01518 }

static int handle_shutdown_now ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1504 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01505 {
01506    if (argc != 2)
01507       return RESULT_SHOWUSAGE;
01508    quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */);
01509    return RESULT_SUCCESS;
01510 }

static int handle_shutdown_when_convenient ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1520 of file asterisk.c.

References ast_cli(), quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01521 {
01522    if (argc != 3)
01523       return RESULT_SHOWUSAGE;
01524    ast_cli(fd, "Waiting for inactivity to perform halt\n");
01525    quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
01526    return RESULT_SUCCESS;
01527 }

static int handle_version ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1484 of file asterisk.c.

References ast_cli(), ASTERISK_VERSION, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01485 {
01486    if (argc != 3)
01487       return RESULT_SHOWUSAGE;
01488    ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
01489       ASTERISK_VERSION, ast_build_user, ast_build_hostname,
01490       ast_build_machine, ast_build_os, ast_build_date);
01491    return RESULT_SUCCESS;
01492 }

static int handle_version_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1474 of file asterisk.c.

References ast_cli(), ASTERISK_VERSION, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01475 {
01476    if (argc != 2)
01477       return RESULT_SHOWUSAGE;
01478    ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
01479       ASTERISK_VERSION, ast_build_user, ast_build_hostname,
01480       ast_build_machine, ast_build_os, ast_build_date);
01481    return RESULT_SUCCESS;
01482 }

static void hup_handler ( int  num  )  [static]

Definition at line 1134 of file asterisk.c.

References sig_flags.

Referenced by main().

01135 {
01136    int a = 0;
01137    if (option_verbose > 1) 
01138       printf("Received HUP signal -- Reloading configs\n");
01139    if (restartnow)
01140       execvp(_argv[0], _argv);
01141    sig_flags.need_reload = 1;
01142    if (sig_alert_pipe[1] != -1)
01143       write(sig_alert_pipe[1], &a, sizeof(a));
01144    signal(num, hup_handler);
01145 }

static void* listener ( void *  unused  )  [static]

Definition at line 966 of file asterisk.c.

References AF_LOCAL, ast_log(), AST_MAX_CONNECTS, ast_pthread_create_background, ast_verbose(), consoles, errno, pollfd::events, console::fd, pollfd::fd, fdprint(), len, LOG_ERROR, LOG_WARNING, console::mute, netconsole(), poll(), POLLIN, s, t, and VERBOSE_PREFIX_3.

Referenced by ast_makesocket().

00967 {
00968    struct sockaddr_un sunaddr;
00969    int s;
00970    socklen_t len;
00971    int x;
00972    int flags;
00973    struct pollfd fds[1];
00974    pthread_attr_t attr;
00975    pthread_attr_init(&attr);
00976    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00977    for (;;) {
00978       if (ast_socket < 0)
00979          return NULL;
00980       fds[0].fd = ast_socket;
00981       fds[0].events = POLLIN;
00982       s = poll(fds, 1, -1);
00983       pthread_testcancel();
00984       if (s < 0) {
00985          if (errno != EINTR)
00986             ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
00987          continue;
00988       }
00989       len = sizeof(sunaddr);
00990       s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
00991       if (s < 0) {
00992          if (errno != EINTR)
00993             ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
00994       } else {
00995          for (x = 0; x < AST_MAX_CONNECTS; x++) {
00996             if (consoles[x].fd < 0) {
00997                if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
00998                   ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
00999                   consoles[x].fd = -1;
01000                   fdprint(s, "Server failed to create pipe\n");
01001                   close(s);
01002                   break;
01003                }
01004                flags = fcntl(consoles[x].p[1], F_GETFL);
01005                fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
01006                consoles[x].fd = s;
01007                consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
01008                if (ast_pthread_create_background(&consoles[x].t, &attr, netconsole, &consoles[x])) {
01009                   ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
01010                   close(consoles[x].p[0]);
01011                   close(consoles[x].p[1]);
01012                   consoles[x].fd = -1;
01013                   fdprint(s, "Server failed to spawn thread\n");
01014                   close(s);
01015                }
01016                break;
01017             }
01018          }
01019          if (x >= AST_MAX_CONNECTS) {
01020             fdprint(s, "No more connections allowed\n");
01021             ast_log(LOG_WARNING, "No more connections allowed\n");
01022             close(s);
01023          } else if (consoles[x].fd > -1) {
01024             if (option_verbose > 2) 
01025                ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection\n");
01026          }
01027       }
01028    }
01029    return NULL;
01030 }

int main ( int  argc,
char *  argv[] 
)

Definition at line 2544 of file asterisk.c.

References __ast_mm_init(), __quit_handler(), ast_alaw_init(), ast_builtins_init(), ast_cdr_engine_init(), ast_channels_init(), ast_clear_flag, ast_cli_register_multiple(), ast_device_state_engine_init(), ast_el_initialize(), ast_el_read_history(), ast_enum_init(), ast_file_init(), ast_http_init(), ast_image_init(), ast_log(), ast_makesocket(), ast_opt_always_fork, ast_opt_console, ast_opt_dump_core, ast_opt_exec, AST_OPT_FLAG_ALWAYS_FORK, AST_OPT_FLAG_CACHE_RECORD_FILES, AST_OPT_FLAG_CONSOLE, AST_OPT_FLAG_DUMP_CORE, AST_OPT_FLAG_EXEC, AST_OPT_FLAG_FULLY_BOOTED, AST_OPT_FLAG_HIGH_PRIORITY, AST_OPT_FLAG_INIT_KEYS, AST_OPT_FLAG_INTERNAL_TIMING, AST_OPT_FLAG_MUTE, AST_OPT_FLAG_NO_COLOR, AST_OPT_FLAG_NO_FORK, AST_OPT_FLAG_OVERRIDE_CONFIG, AST_OPT_FLAG_QUIET, AST_OPT_FLAG_RECONNECT, AST_OPT_FLAG_REMOTE, AST_OPT_FLAG_TIMESTAMP, ast_opt_high_priority, ast_opt_no_fork, ast_opt_remote, ast_pthread_create, ast_readconfig(), ast_register_verbose(), ast_remotecontrol(), ast_rtp_init(), ast_set_flag, ast_set_priority(), ast_strlen_zero(), ast_term_init(), ast_test_flag, ast_tryconnect(), ast_udptl_init(), ast_ulaw_init(), ast_utils_init(), ast_verbose(), astdb_init(), astobj2_init(), callerid_init(), child_handler(), COLOR_BLACK, COLOR_BRWHITE, console_verboser(), consolehandler(), dnsmgr_init(), dnsmgr_start_refresh(), errno, f, group, hostname, hup_handler(), init_framer(), init_logger(), init_manager(), load_modules(), load_pbx(), LOG_ERROR, LOG_WARNING, monitor_sig_flags(), quit_handler(), read_config_maps(), register_config_cli(), set_icon(), set_title(), show_cli_help(), show_version(), tdd_init(), term_color(), term_end(), term_quit(), test_for_thread_safety(), threadstorage_init(), urg_handler(), and WELCOME_MESSAGE.

02545 {
02546    int c;
02547    char filename[80] = "";
02548    char hostname[MAXHOSTNAMELEN] = "";
02549    char tmp[80];
02550    char * xarg = NULL;
02551    int x;
02552    FILE *f;
02553    sigset_t sigs;
02554    int num;
02555    int isroot = 1;
02556    char *buf;
02557    char *runuser = NULL, *rungroup = NULL;
02558 
02559    /* Remember original args for restart */
02560    if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) {
02561       fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1);
02562       argc = sizeof(_argv) / sizeof(_argv[0]) - 1;
02563    }
02564    for (x=0; x<argc; x++)
02565       _argv[x] = argv[x];
02566    _argv[x] = NULL;
02567 
02568    if (geteuid() != 0)
02569       isroot = 0;
02570 
02571    /* if the progname is rasterisk consider it a remote console */
02572    if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
02573       ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
02574    }
02575    if (gethostname(hostname, sizeof(hostname)-1))
02576       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
02577    ast_mainpid = getpid();
02578    ast_ulaw_init();
02579    ast_alaw_init();
02580    callerid_init();
02581    ast_builtins_init();
02582    ast_utils_init();
02583    tdd_init();
02584 
02585    if (getenv("HOME")) 
02586       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
02587    /* Check for options */
02588    while ((c = getopt(argc, argv, "mtThfFdvVqprRgciInx:U:G:C:L:M:")) != -1) {
02589       switch (c) {
02590 #if HAVE_WORKING_FORK
02591       case 'F':
02592          ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
02593          break;
02594       case 'f':
02595          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
02596          break;
02597 #endif
02598       case 'd':
02599          option_debug++;
02600          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
02601          break;
02602       case 'c':
02603          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
02604          break;
02605       case 'n':
02606          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
02607          break;
02608       case 'r':
02609          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
02610          break;
02611       case 'R':
02612          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
02613          break;
02614       case 'p':
02615          ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
02616          break;
02617       case 'v':
02618          option_verbose++;
02619          ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
02620          break;
02621       case 'm':
02622          ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
02623          break;
02624       case 'M':
02625          if ((sscanf(optarg, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0))
02626             option_maxcalls = 0;
02627          break;
02628       case 'L':
02629          if ((sscanf(optarg, "%lf", &option_maxload) != 1) || (option_maxload < 0.0))
02630             option_maxload = 0.0;
02631          break;
02632       case 'q':
02633          ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
02634          break;
02635       case 't':
02636          ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
02637          break;
02638       case 'T':
02639          ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
02640          break;
02641       case 'x':
02642          ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC);
02643          xarg = optarg;
02644          break;
02645       case 'C':
02646          ast_copy_string(ast_config_AST_CONFIG_FILE, optarg, sizeof(ast_config_AST_CONFIG_FILE));
02647          ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
02648          break;
02649       case 'I':
02650          ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING);
02651          break;
02652       case 'i':
02653          ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
02654          break;
02655       case 'g':
02656          ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
02657          break;
02658       case 'h':
02659          show_cli_help();
02660          exit(0);
02661       case 'V':
02662          show_version();
02663          exit(0);
02664       case 'U':
02665          runuser = optarg;
02666          break;
02667       case 'G':
02668          rungroup = optarg;
02669          break;
02670       case '?':
02671          exit(1);
02672       }
02673    }
02674 
02675    if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
02676       ast_register_verbose(console_verboser);
02677       WELCOME_MESSAGE;
02678    }
02679 
02680    if (ast_opt_console && !option_verbose) 
02681       ast_verbose("[ Booting...\n");
02682 
02683    if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
02684       ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
02685       ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
02686    }
02687 
02688    /* For remote connections, change the name of the remote connection.
02689     * We do this for the benefit of init scripts (which need to know if/when
02690     * the main asterisk process has died yet). */
02691    if (ast_opt_remote) {
02692       strcpy(argv[0], "rasterisk");
02693       for (x = 1; x < argc; x++) {
02694          argv[x] = argv[0] + 10;
02695       }
02696    }
02697 
02698    if (ast_opt_console && !option_verbose) 
02699       ast_verbose("[ Reading Master Configuration ]\n");
02700    ast_readconfig();
02701 
02702    if (ast_opt_dump_core) {
02703       struct rlimit l;
02704       memset(&l, 0, sizeof(l));
02705       l.rlim_cur = RLIM_INFINITY;
02706       l.rlim_max = RLIM_INFINITY;
02707       if (setrlimit(RLIMIT_CORE, &l)) {
02708          ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
02709       }
02710    }
02711 
02712    if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
02713       rungroup = ast_config_AST_RUN_GROUP;
02714    if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
02715       runuser = ast_config_AST_RUN_USER;
02716 
02717 #ifndef __CYGWIN__
02718 
02719    if (isroot) 
02720       ast_set_priority(ast_opt_high_priority);
02721 
02722    if (isroot && rungroup) {
02723       struct group *gr;
02724       gr = getgrnam(rungroup);
02725       if (!gr) {
02726          ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
02727          exit(1);
02728       }
02729       if (setgid(gr->gr_gid)) {
02730          ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
02731          exit(1);
02732       }
02733       if (setgroups(0, NULL)) {
02734          ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
02735          exit(1);
02736       }
02737       if (option_verbose)
02738          ast_verbose("Running as group '%s'\n", rungroup);
02739    }
02740 
02741    if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
02742 #ifdef HAVE_CAP
02743       int has_cap = 1;
02744 #endif /* HAVE_CAP */
02745       struct passwd *pw;
02746       pw = getpwnam(runuser);
02747       if (!pw) {
02748          ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
02749          exit(1);
02750       }
02751 #ifdef HAVE_CAP
02752       if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
02753          ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
02754          has_cap = 0;
02755       }
02756 #endif /* HAVE_CAP */
02757       if (!isroot && pw->pw_uid != geteuid()) {
02758          ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
02759          exit(1);
02760       }
02761       if (!rungroup) {
02762          if (setgid(pw->pw_gid)) {
02763             ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
02764             exit(1);
02765          }
02766          if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
02767             ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser);
02768             exit(1);
02769          }
02770       }
02771       if (setuid(pw->pw_uid)) {
02772          ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
02773          exit(1);
02774       }
02775       if (option_verbose)
02776          ast_verbose("Running as user '%s'\n", runuser);
02777 #ifdef HAVE_CAP
02778       if (has_cap) {
02779          cap_t cap;
02780 
02781          cap = cap_from_text("cap_net_admin=ep");
02782 
02783          if (cap_set_proc(cap))
02784             ast_log(LOG_WARNING, "Unable to install capabilities.\n");
02785 
02786          if (cap_free(cap))
02787             ast_log(LOG_WARNING, "Unable to drop capabilities.\n");
02788       }
02789 #endif /* HAVE_CAP */
02790    }
02791 
02792 #endif /* __CYGWIN__ */
02793 
02794 #ifdef linux
02795    if (geteuid() && ast_opt_dump_core) {
02796       if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
02797          ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
02798       }  
02799    }
02800 #endif
02801 
02802    ast_term_init();
02803    printf(term_end());
02804    fflush(stdout);
02805 
02806    if (ast_opt_console && !option_verbose) 
02807       ast_verbose("[ Initializing Custom Configuration Options ]\n");
02808    /* custom config setup */
02809    register_config_cli();
02810    read_config_maps();
02811    
02812    if (ast_opt_console) {
02813       if (el_hist == NULL || el == NULL)
02814          ast_el_initialize();
02815 
02816       if (!ast_strlen_zero(filename))
02817          ast_el_read_history(filename);
02818    }
02819 
02820    if (ast_tryconnect()) {
02821       /* One is already running */
02822       if (ast_opt_remote) {
02823          if (ast_opt_exec) {
02824             ast_remotecontrol(xarg);
02825             quit_handler(0, 0, 0, 0);
02826             exit(0);
02827          }
02828          printf(term_quit());
02829          ast_remotecontrol(NULL);
02830          quit_handler(0, 0, 0, 0);
02831          exit(0);
02832       } else {
02833          ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
02834          printf(term_quit());
02835          exit(1);
02836       }
02837    } else if (ast_opt_remote || ast_opt_exec) {
02838       ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
02839       printf(term_quit());
02840       exit(1);
02841    }
02842    /* Blindly write pid file since we couldn't connect */
02843    unlink(ast_config_AST_PID);
02844    f = fopen(ast_config_AST_PID, "w");
02845    if (f) {
02846       fprintf(f, "%ld\n", (long)getpid());
02847       fclose(f);
02848    } else
02849       ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
02850 
02851 #if HAVE_WORKING_FORK
02852    if (ast_opt_always_fork || !ast_opt_no_fork) {
02853       daemon(1, 0);
02854       ast_mainpid = getpid();
02855       /* Blindly re-write pid file since we are forking */
02856       unlink(ast_config_AST_PID);
02857       f = fopen(ast_config_AST_PID, "w");
02858       if (f) {
02859          fprintf(f, "%ld\n", (long)ast_mainpid);
02860          fclose(f);
02861       } else
02862          ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
02863    }
02864 #endif
02865 
02866    /* Test recursive mutex locking. */
02867    if (test_for_thread_safety())
02868       ast_verbose("Warning! Asterisk is not thread safe.\n");
02869 
02870    ast_makesocket();
02871    sigemptyset(&sigs);
02872    sigaddset(&sigs, SIGHUP);
02873    sigaddset(&sigs, SIGTERM);
02874    sigaddset(&sigs, SIGINT);
02875    sigaddset(&sigs, SIGPIPE);
02876    sigaddset(&sigs, SIGWINCH);
02877    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
02878    signal(SIGURG, urg_handler);
02879    signal(SIGINT, __quit_handler);
02880    signal(SIGTERM, __quit_handler);
02881    signal(SIGHUP, hup_handler);
02882    signal(SIGCHLD, child_handler);
02883    signal(SIGPIPE, SIG_IGN);
02884 
02885    /* ensure that the random number generators are seeded with a different value every time
02886       Asterisk is started
02887    */
02888    srand((unsigned int) getpid() + (unsigned int) time(NULL));
02889    initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
02890 
02891    if (init_logger()) {
02892       printf(term_quit());
02893       exit(1);
02894    }
02895 
02896    threadstorage_init();
02897 
02898    astobj2_init();
02899 
02900    if (load_modules(1)) {
02901       printf(term_quit());
02902       exit(1);
02903    }
02904 
02905    if (dnsmgr_init()) {
02906       printf(term_quit());
02907       exit(1);
02908    }
02909 
02910    ast_http_init();
02911 
02912    ast_channels_init();
02913 
02914    if (init_manager()) {
02915       printf(term_quit());
02916       exit(1);
02917    }
02918 
02919    if (ast_cdr_engine_init()) {
02920       printf(term_quit());
02921       exit(1);
02922    }
02923 
02924    if (ast_device_state_engine_init()) {
02925       printf(term_quit());
02926       exit(1);
02927    }
02928 
02929    ast_rtp_init();
02930 
02931    ast_udptl_init();
02932 
02933    if (ast_image_init()) {
02934       printf(term_quit());
02935       exit(1);
02936    }
02937 
02938    if (ast_file_init()) {
02939       printf(term_quit());
02940       exit(1);
02941    }
02942 
02943    if (load_pbx()) {
02944       printf(term_quit());
02945       exit(1);
02946    }
02947 
02948    if (init_framer()) {
02949       printf(term_quit());
02950       exit(1);
02951    }
02952 
02953    if (astdb_init()) {
02954       printf(term_quit());
02955       exit(1);
02956    }
02957 
02958    if (ast_enum_init()) {
02959       printf(term_quit());
02960       exit(1);
02961    }
02962 
02963    if (load_modules(0)) {
02964       printf(term_quit());
02965       exit(1);
02966    }
02967 
02968    dnsmgr_start_refresh();
02969 
02970    /* We might have the option of showing a console, but for now just
02971       do nothing... */
02972    if (ast_opt_console && !option_verbose)
02973       ast_verbose(" ]\n");
02974    if (option_verbose || ast_opt_console)
02975       ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
02976    if (ast_opt_no_fork)
02977       consolethread = pthread_self();
02978 
02979    if (pipe(sig_alert_pipe))
02980       sig_alert_pipe[0] = sig_alert_pipe[1] = -1;
02981 
02982    ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
02983    pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
02984 
02985 #ifdef __AST_DEBUG_MALLOC
02986    __ast_mm_init();
02987 #endif   
02988 
02989    time(&ast_startuptime);
02990    ast_cli_register_multiple(cli_asterisk, sizeof(cli_asterisk) / sizeof(struct ast_cli_entry));
02991 
02992    if (ast_opt_console) {
02993       /* Console stuff now... */
02994       /* Register our quit function */
02995       char title[256];
02996       pthread_attr_t attr;
02997       pthread_t dont_care;
02998 
02999       pthread_attr_init(&attr);
03000       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
03001       ast_pthread_create(&dont_care, &attr, monitor_sig_flags, NULL);
03002       pthread_attr_destroy(&attr);
03003 
03004       set_icon("Asterisk");
03005       snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
03006       set_title(title);
03007 
03008       for (;;) {
03009          buf = (char *)el_gets(el, &num);
03010 
03011          if (!buf && write(1, "", 1) < 0)
03012             goto lostterm;
03013 
03014          if (buf) {
03015             if (buf[strlen(buf)-1] == '\n')
03016                buf[strlen(buf)-1] = '\0';
03017 
03018             consolehandler((char *)buf);
03019          } else if (ast_opt_remote && (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
03020                strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0)) {
03021             /* Whoa, stdout disappeared from under us... Make /dev/null's */
03022             int fd;
03023             fd = open("/dev/null", O_RDWR);
03024             if (fd > -1) {
03025                dup2(fd, STDOUT_FILENO);
03026                dup2(fd, STDIN_FILENO);
03027             } else
03028                ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
03029             break;
03030          }
03031       }
03032    }
03033 
03034    monitor_sig_flags(NULL);
03035 
03036 lostterm:
03037    return 0;
03038 }

static void* monitor_sig_flags ( void *  unused  )  [static]

Definition at line 2524 of file asterisk.c.

References ast_module_reload(), poll(), POLLIN, quit_handler(), and sig_flags.

Referenced by main().

02525 {
02526    for (;;) {
02527       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
02528       int a;
02529       poll(&p, 1, -1);
02530       if (sig_flags.need_reload) {
02531          sig_flags.need_reload = 0;
02532          ast_module_reload(NULL);
02533       }
02534       if (sig_flags.need_quit) {
02535          sig_flags.need_quit = 0;
02536          quit_handler(0, 0, 1, 0);
02537       }
02538       read(sig_alert_pipe[0], &a, sizeof(a));
02539    }
02540 
02541    return NULL;
02542 }

static void* netconsole ( void *  vconsole  )  [static]

Definition at line 911 of file asterisk.c.

References ast_cli_command_multiple(), ast_log(), ast_verbose(), ASTERISK_VERSION, errno, pollfd::events, pollfd::fd, console::fd, fdprint(), hostname, LOG_ERROR, LOG_WARNING, console::p, poll(), POLLIN, pollfd::revents, and VERBOSE_PREFIX_3.

Referenced by listener().

00912 {
00913    struct console *con = vconsole;
00914    char hostname[MAXHOSTNAMELEN] = "";
00915    char tmp[512];
00916    int res;
00917    struct pollfd fds[2];
00918    
00919    if (gethostname(hostname, sizeof(hostname)-1))
00920       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
00921    snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ASTERISK_VERSION);
00922    fdprint(con->fd, tmp);
00923    for(;;) {
00924       fds[0].fd = con->fd;
00925       fds[0].events = POLLIN;
00926       fds[0].revents = 0;
00927       fds[1].fd = con->p[0];
00928       fds[1].events = POLLIN;
00929       fds[1].revents = 0;
00930 
00931       res = poll(fds, 2, -1);
00932       if (res < 0) {
00933          if (errno != EINTR)
00934             ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
00935          continue;
00936       }
00937       if (fds[0].revents) {
00938          res = read(con->fd, tmp, sizeof(tmp));
00939          if (res < 1) {
00940             break;
00941          }
00942          tmp[res] = 0;
00943          ast_cli_command_multiple(con->fd, res, tmp);
00944       }
00945       if (fds[1].revents) {
00946          res = read(con->p[0], tmp, sizeof(tmp));
00947          if (res < 1) {
00948             ast_log(LOG_ERROR, "read returned %d\n", res);
00949             break;
00950          }
00951          res = write(con->fd, tmp, res);
00952          if (res < 1)
00953             break;
00954       }
00955    }
00956    if (option_verbose > 2) 
00957       ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection disconnected\n");
00958    close(con->fd);
00959    close(con->p[0]);
00960    close(con->p[1]);
00961    con->fd = -1;
00962    
00963    return NULL;
00964 }

static void network_verboser ( const char *  s  )  [static]

Definition at line 904 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by ast_makesocket().

00905 {
00906    ast_network_puts_mutable(s);
00907 }

static void null_sig_handler ( int  signal  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 744 of file asterisk.c.

Referenced by ast_replace_sigchld().

00745 {
00746 
00747 }

static void quit_handler ( int  num,
int  nice,
int  safeshutdown,
int  restart 
) [static]

Definition at line 1222 of file asterisk.c.

References ast_active_channels(), ast_begin_shutdown(), ast_cdr_engine_term(), ast_el_write_history(), ast_log(), ast_module_shutdown(), ast_opt_console, ast_opt_remote, AST_PTHREADT_NULL, ast_run_atexits(), ast_strlen_zero(), ast_verbose(), close_logger(), EVENT_FLAG_SYSTEM, LOG_DEBUG, manager_event(), s, and term_quit().

Referenced by ast_el_read_char(), handle_restart_gracefully(), handle_restart_now(), handle_restart_when_convenient(), handle_shutdown_gracefully(), handle_shutdown_now(), handle_shutdown_when_convenient(), main(), monitor_sig_flags(), and remoteconsolehandler().

01223 {
01224    char filename[80] = "";
01225    time_t s,e;
01226    int x;
01227    /* Try to get as many CDRs as possible submitted to the backend engines (if in batch mode) */
01228    ast_cdr_engine_term();
01229    if (safeshutdown) {
01230       shuttingdown = 1;
01231       if (!nice) {
01232          /* Begin shutdown routine, hanging up active channels */
01233          ast_begin_shutdown(1);
01234          if (option_verbose && ast_opt_console)
01235             ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
01236          time(&s);
01237          for (;;) {
01238             time(&e);
01239             /* Wait up to 15 seconds for all channels to go away */
01240             if ((e - s) > 15)
01241                break;
01242             if (!ast_active_channels())
01243                break;
01244             if (!shuttingdown)
01245                break;
01246             /* Sleep 1/10 of a second */
01247             usleep(100000);
01248          }
01249       } else {
01250          if (nice < 2)
01251             ast_begin_shutdown(0);
01252          if (option_verbose && ast_opt_console)
01253             ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
01254          for (;;) {
01255             if (!ast_active_channels())
01256                break;
01257             if (!shuttingdown)
01258                break;
01259             sleep(1);
01260          }
01261       }
01262 
01263       if (!shuttingdown) {
01264          if (option_verbose && ast_opt_console)
01265             ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
01266          return;
01267       }
01268 
01269       if (nice)
01270          ast_module_shutdown();
01271    }
01272    if (ast_opt_console || ast_opt_remote) {
01273       if (getenv("HOME")) 
01274          snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
01275       if (!ast_strlen_zero(filename))
01276          ast_el_write_history(filename);
01277       if (el != NULL)
01278          el_end(el);
01279       if (el_hist != NULL)
01280          history_end(el_hist);
01281    }
01282    if (option_verbose)
01283       ast_verbose("Executing last minute cleanups\n");
01284    ast_run_atexits();
01285    /* Called on exit */
01286    if (option_verbose && ast_opt_console)
01287       ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
01288    if (option_debug)
01289       ast_log(LOG_DEBUG, "Asterisk ending (%d).\n", num);
01290    manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
01291    if (ast_socket > -1) {
01292       pthread_cancel(lthread);
01293       close(ast_socket);
01294       ast_socket = -1;
01295       unlink(ast_config_AST_SOCKET);
01296    }
01297    if (ast_consock > -1)
01298       close(ast_consock);
01299    if (!ast_opt_remote)
01300       unlink(ast_config_AST_PID);
01301    printf(term_quit());
01302    if (restart) {
01303       if (option_verbose || ast_opt_console)
01304          ast_verbose("Preparing for Asterisk restart...\n");
01305       /* Mark all FD's for closing on exec */
01306       for (x=3; x < 32768; x++) {
01307          fcntl(x, F_SETFD, FD_CLOEXEC);
01308       }
01309       if (option_verbose || ast_opt_console)
01310          ast_verbose("Asterisk is now restarting...\n");
01311       restartnow = 1;
01312 
01313       /* close logger */
01314       close_logger();
01315 
01316       /* If there is a consolethread running send it a SIGHUP 
01317          so it can execvp, otherwise we can do it ourselves */
01318       if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
01319          pthread_kill(consolethread, SIGHUP);
01320          /* Give the signal handler some time to complete */
01321          sleep(2);
01322       } else
01323          execvp(_argv[0], _argv);
01324    
01325    } else {
01326       /* close logger */
01327       close_logger();
01328    }
01329    exit(0);
01330 }

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 428 of file asterisk.c.

Referenced by ast_mark().

00429 {
00430    return 0;
00431 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1402 of file asterisk.c.

References ast_all_zeros(), ast_el_add_history(), ast_safe_system(), and quit_handler().

Referenced by ast_remotecontrol().

01403 {
01404    int ret = 0;
01405 
01406    /* Called when readline data is available */
01407    if (!ast_all_zeros(s))
01408       ast_el_add_history(s);
01409    /* The real handler for bang */
01410    if (s[0] == '!') {
01411       if (s[1])
01412          ast_safe_system(s+1);
01413       else
01414          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01415       ret = 1;
01416    }
01417    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
01418        (s[4] == '\0' || isspace(s[4]))) {
01419       quit_handler(0, 0, 0, 0);
01420       ret = 1;
01421    }
01422 
01423    return ret;
01424 }

static void set_icon ( char *  text  )  [static]

Definition at line 1169 of file asterisk.c.

Referenced by main().

01170 {
01171    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01172       fprintf(stdout, "\033]1;%s\007", text);
01173 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1163 of file asterisk.c.

Referenced by main().

01164 {
01165    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01166       fprintf(stdout, "\033]2;%s\007", text);
01167 }

static int show_cli_help ( void   )  [static]

Definition at line 2326 of file asterisk.c.

References ASTERISK_VERSION.

Referenced by main().

02326                                {
02327    printf("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2007, Digium, Inc. and others.\n");
02328    printf("Usage: asterisk [OPTIONS]\n");
02329    printf("Valid Options:\n");
02330    printf("   -V              Display version number and exit\n");
02331    printf("   -C <configfile> Use an alternate configuration file\n");
02332    printf("   -G <group>      Run as a group other than the caller\n");
02333    printf("   -U <user>       Run as a user other than the caller\n");
02334    printf("   -c              Provide console CLI\n");
02335    printf("   -d              Enable extra debugging\n");
02336 #if HAVE_WORKING_FORK
02337    printf("   -f              Do not fork\n");
02338    printf("   -F              Always fork\n");
02339 #endif
02340    printf("   -g              Dump core in case of a crash\n");
02341    printf("   -h              This help screen\n");
02342    printf("   -i              Initialize crypto keys at startup\n");
02343    printf("   -I              Enable internal timing if Zaptel timer is available\n");
02344    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
02345    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
02346    printf("   -m              Mute debugging and console output on the console\n");
02347    printf("   -n              Disable console colorization\n");
02348    printf("   -p              Run as pseudo-realtime thread\n");
02349    printf("   -q              Quiet mode (suppress output)\n");
02350    printf("   -r              Connect to Asterisk on this machine\n");
02351    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
02352    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
02353    printf("                   belong after they are done\n");
02354    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
02355    printf("                   of output to the CLI\n");
02356    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
02357    printf("   -x <cmd>        Execute command <cmd> (only valid with -r)\n");
02358    printf("\n");
02359    return 0;
02360 }

static int show_license ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1621 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

01622 {
01623    int x;
01624 
01625    for (x = 0; x < sizeof(license_lines) / sizeof(license_lines[0]); x++)
01626       ast_cli(fd, (char *) license_lines[x]);
01627 
01628    return RESULT_SUCCESS;
01629 }

static int show_version ( void   )  [static]

Definition at line 2320 of file asterisk.c.

References ASTERISK_VERSION.

Referenced by main().

02321 {
02322    printf("Asterisk " ASTERISK_VERSION "\n");
02323    return 0;
02324 }

static int show_warranty ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1592 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

01593 {
01594    int x;
01595 
01596    for (x = 0; x < sizeof(warranty_lines) / sizeof(warranty_lines[0]); x++)
01597       ast_cli(fd, (char *) warranty_lines[x]);
01598 
01599    return RESULT_SUCCESS;
01600 }

static void urg_handler ( int  num  )  [static]

Urgent handler.

Called by soft_hangup to interrupt the poll, read, or other system call. We don't actually need to do anything though. Remember: Cannot EVER ast_log from within a signal handler

Definition at line 1128 of file asterisk.c.

Referenced by main().

01129 {
01130    signal(num, urg_handler);
01131    return;
01132 }


Variable Documentation

char* _argv[256] [static]

Definition at line 234 of file asterisk.c.

char abort_halt_help[] [static]

Initial value:

 
"Usage: abort shutdown\n"
"       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
"       call operations.\n"

Definition at line 1426 of file asterisk.c.

const char* ast_build_date

Definition at line 32 of file buildinfo.c.

const char* ast_build_hostname

Definition at line 28 of file buildinfo.c.

const char* ast_build_kernel

Definition at line 29 of file buildinfo.c.

const char* ast_build_machine

Definition at line 30 of file buildinfo.c.

const char* ast_build_os

Definition at line 31 of file buildinfo.c.

const char* ast_build_user

Definition at line 33 of file buildinfo.c.

char ast_config_AST_AGI_DIR[PATH_MAX]

Definition at line 213 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_CONFIG_DIR[PATH_MAX]

Definition at line 206 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl"

Definition at line 224 of file asterisk.c.

char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0"

Definition at line 223 of file asterisk.c.

char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0"

Definition at line 222 of file asterisk.c.

Definition at line 221 of file asterisk.c.

char ast_config_AST_DATA_DIR[PATH_MAX]

char ast_config_AST_DB[PATH_MAX]

Definition at line 214 of file asterisk.c.

Referenced by dbinit().

char ast_config_AST_KEY_DIR[PATH_MAX]

Definition at line 215 of file asterisk.c.

Referenced by crypto_load(), init_keys(), launch_script(), and osp_create_provider().

char ast_config_AST_LOG_DIR[PATH_MAX]

char ast_config_AST_MODULE_DIR[PATH_MAX]

char ast_config_AST_PID[PATH_MAX]

Definition at line 216 of file asterisk.c.

char ast_config_AST_RUN_DIR[PATH_MAX]

Definition at line 218 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_RUN_GROUP[PATH_MAX]

Definition at line 220 of file asterisk.c.

char ast_config_AST_RUN_USER[PATH_MAX]

Definition at line 219 of file asterisk.c.

char ast_config_AST_SOCKET[PATH_MAX]

Definition at line 217 of file asterisk.c.

char ast_config_AST_SPOOL_DIR[PATH_MAX]

char ast_config_AST_VAR_DIR[PATH_MAX]

Definition at line 210 of file asterisk.c.

Referenced by ael2_semantic_check(), and launch_script().

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

Definition at line 174 of file asterisk.c.

Definition at line 191 of file asterisk.c.

Referenced by ast_module_reload(), handle_showuptime(), and handle_showuptime_deprecated().

pid_t ast_mainpid

Definition at line 175 of file asterisk.c.

Referenced by ast_alloc_uniqueid(), ast_channel_alloc(), safe_append(), and scan_service().

int ast_socket = -1 [static]

UNIX Socket for allowing remote control

Definition at line 173 of file asterisk.c.

Definition at line 190 of file asterisk.c.

Referenced by handle_showuptime(), and handle_showuptime_deprecated().

char bang_help[] [static]

Initial value:

"Usage: !<command>\n"
"       Executes a given shell command\n"

Definition at line 1458 of file asterisk.c.

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 1657 of file asterisk.c.

Initial value:

 {
   { "clear", "profile", NULL },
   handle_show_profile_deprecated, NULL,
   NULL }

Definition at line 1651 of file asterisk.c.

Initial value:

 {
   { "show", "profile", NULL },
   handle_show_profile_deprecated, NULL,
   NULL }

Definition at line 1646 of file asterisk.c.

Initial value:

 {
   { "show", "version", NULL },
   handle_version_deprecated, "Display version info",
   version_help }

Definition at line 1635 of file asterisk.c.

Initial value:

 {
   { "show", "version", "files", NULL },
   handle_show_version_files_deprecated, NULL,
   NULL, complete_show_version_files_deprecated }

Definition at line 1641 of file asterisk.c.

struct console consoles[AST_MAX_CONNECTS]

pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 237 of file asterisk.c.

Referenced by show_console().

char debug_filename[AST_FILENAME_MAX] = ""

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 199 of file asterisk.c.

Referenced by ast_channel_alloc().

EditLine* el [static]

History* el_hist [static]

Definition at line 193 of file asterisk.c.

const char* license_lines[] [static]

Definition at line 1602 of file asterisk.c.

pthread_t lthread [static]

Definition at line 909 of file asterisk.c.

unsigned int need_quit

Definition at line 244 of file asterisk.c.

unsigned int need_reload

Definition at line 243 of file asterisk.c.

struct profile_data* prof_data [static]

Definition at line 367 of file asterisk.c.

char randompool[256] [static]

Definition at line 239 of file asterisk.c.

char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR

Definition at line 170 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 195 of file asterisk.c.

char restart_gracefully_help[] [static]

Initial value:

 
"Usage: restart gracefully\n"
"       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
"       restart when all active calls have ended.\n"

Definition at line 1449 of file asterisk.c.

char restart_now_help[] [static]

Initial value:

 
"Usage: restart now\n"
"       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
"       restart.\n"

Definition at line 1444 of file asterisk.c.

Initial value:

 
"Usage: restart when convenient\n"
"       Causes Asterisk to perform a cold restart when all active calls have ended.\n"

Definition at line 1454 of file asterisk.c.

int restartnow [static]

Definition at line 236 of file asterisk.c.

unsigned int safe_system_level = 0 [static]

Keep track of how many threads are currently trying to wait*() on a child process.

Definition at line 752 of file asterisk.c.

void* safe_system_prev_handler [static]

Definition at line 753 of file asterisk.c.

char show_license_help[] [static]

Initial value:

"Usage: core show license\n"
"  Shows the license(s) for this copy of Asterisk.\n"

Definition at line 1466 of file asterisk.c.

char show_threads_help[] [static]

Initial value:

"Usage: core show threads\n"
"       List threads currently active in the system.\n"

Definition at line 302 of file asterisk.c.

char show_version_files_help[] [static]

Initial value:

 
"Usage: core show file version [like <pattern>]\n"
"       Lists the revision numbers of the files used to build this copy of Asterisk.\n"
"       Optional regular expression pattern is used to filter the file list.\n"

Definition at line 542 of file asterisk.c.

char show_warranty_help[] [static]

Initial value:

"Usage: core show warranty\n"
"  Shows the warranty (if any) for this copy of Asterisk.\n"

Definition at line 1462 of file asterisk.c.

char shutdown_gracefully_help[] [static]

Initial value:

 
"Usage: stop gracefully\n"
"       Causes Asterisk to not accept new calls, and exit when all\n"
"       active calls have terminated normally.\n"

Definition at line 1435 of file asterisk.c.

char shutdown_now_help[] [static]

Initial value:

 
"Usage: stop now\n"
"       Shuts down a running Asterisk immediately, hanging up all active calls .\n"

Definition at line 1431 of file asterisk.c.

Initial value:

 
"Usage: stop when convenient\n"
"       Causes Asterisk to perform a shutdown when all active calls have ended.\n"

Definition at line 1440 of file asterisk.c.

int shuttingdown [static]

Definition at line 235 of file asterisk.c.

int sig_alert_pipe[2] = { -1, -1 } [static]

Definition at line 241 of file asterisk.c.

struct { ... } sig_flags [static]

char version_help[] [static]

Initial value:

"Usage: core show version\n"
"       Shows Asterisk version information.\n"

Definition at line 1470 of file asterisk.c.

const char* warranty_lines[] [static]

Definition at line 1567 of file asterisk.c.


Generated on Sat Apr 12 07:12:34 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.5