Fri Aug 24 02:23:06 2007

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

Variables

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

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

#define AST_MAX_CONNECTS   128

Definition at line 138 of file asterisk.c.

Referenced by ast_console_toggle_mute(), ast_makesocket(), ast_network_puts(), ast_network_puts_mutable(), and listener().

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 1643 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 1645 of file asterisk.c.

Referenced by cli_prompt().

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

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

Referenced by __iax2_show_peers(), __sip_show_channels(), _sip_show_peers(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), handle_show_version_files(), handle_show_version_files_deprecated(), iax2_show_channels(), iax2_show_firmware(), iax2_show_registry(), iax2_show_users(), show_channeltypes(), show_file_formats(), show_file_formats_deprecated(), show_image_formats(), show_image_formats_deprecated(), sip_show_domains(), sip_show_inuse(), sip_show_registry(), sip_show_users(), zap_show_channels(), and zap_show_status().

#define NUM_MSGS   64

Definition at line 139 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

Definition at line 135 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 142 of file asterisk.c.

Referenced by ast_el_read_char(), and main().


Function Documentation

static void __quit_handler ( int  num  )  [static]

Definition at line 1344 of file asterisk.c.

References sig_flags.

Referenced by main().

01345 {
01346    int a = 0;
01347    sig_flags.need_quit = 1;
01348    if (sig_alert_pipe[1] != -1)
01349       write(sig_alert_pipe[1], &a, sizeof(a));
01350    /* There is no need to restore the signal handler here, since the app
01351     * is going to exit */
01352 }

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

support for event profiling

Returns:
Returns the identifier of the counter.

Definition at line 370 of file asterisk.c.

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

Referenced by extension_match_core(), and handle_astobj2_test().

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

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1386 of file asterisk.c.

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

01387 {
01388    while (*s) {
01389       if (*s > 32)
01390          return 0;
01391       s++;  
01392    }
01393    return 1;
01394 }

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

Definition at line 2004 of file asterisk.c.

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

Referenced by cli_complete().

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

void ast_console_puts ( const char *  string  ) 

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

Definition at line 886 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

00887 {
00888    fputs(string, stdout);
00889    fflush(stdout);
00890    ast_network_puts(string);
00891 }

void ast_console_puts_mutable ( const char *  string  ) 

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

Definition at line 863 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by ast_log().

00864 {
00865    fputs(string, stdout);
00866    fflush(stdout);
00867    ast_network_puts_mutable(string);
00868 }

void ast_console_toggle_mute ( int  fd  ) 

mute or unmute a console from logging

Definition at line 828 of file asterisk.c.

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

Referenced by handle_logger_mute().

00828                                      {
00829    int x;
00830    for (x = 0;x < AST_MAX_CONNECTS; x++) {
00831       if (fd == consoles[x].fd) {
00832          if (consoles[x].mute) {
00833             consoles[x].mute = 0;
00834             ast_cli(fd, "Console is not muted anymore.\n");
00835          } else {
00836             consoles[x].mute = 1;
00837             ast_cli(fd, "Console is muted.\n");
00838          }
00839          return;
00840       }
00841    }
00842    ast_cli(fd, "Couldn't find remote console.\n");
00843 }

static int ast_el_add_history ( char *   )  [static]

Definition at line 2198 of file asterisk.c.

References ast_el_initialize().

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

02199 {
02200    HistEvent ev;
02201 
02202    if (el_hist == NULL || el == NULL)
02203       ast_el_initialize();
02204    if (strlen(buf) > 256)
02205       return 0;
02206    return (history(el_hist, &ev, H_ENTER, buf));
02207 }

static int ast_el_initialize ( void   )  [static]

Definition at line 2163 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().

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

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

Definition at line 1732 of file asterisk.c.

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

Referenced by ast_remotecontrol().

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

static int ast_el_read_history ( char *   )  [static]

Definition at line 2219 of file asterisk.c.

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

Referenced by ast_remotecontrol(), and main().

02220 {
02221    char buf[256];
02222    FILE *f;
02223    int ret = -1;
02224 
02225    if (el_hist == NULL || el == NULL)
02226       ast_el_initialize();
02227 
02228    if ((f = fopen(filename, "r")) == NULL)
02229       return ret;
02230 
02231    while (!feof(f)) {
02232       fgets(buf, sizeof(buf), f);
02233       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02234          continue;
02235       if (ast_all_zeros(buf))
02236          continue;
02237       if ((ret = ast_el_add_history(buf)) == -1)
02238          break;
02239    }
02240    fclose(f);
02241 
02242    return ret;
02243 }

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

Definition at line 1994 of file asterisk.c.

Referenced by ast_cli_display_match_list().

01995 {
01996    char *s1, *s2;
01997 
01998    s1 = ((char **)i1)[0];
01999    s2 = ((char **)i2)[0];
02000 
02001    return strcasecmp(s1, s2);
02002 }

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

Definition at line 1959 of file asterisk.c.

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

Referenced by cli_complete().

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

static int ast_el_write_history ( char *   )  [static]

Definition at line 2209 of file asterisk.c.

References ast_el_initialize().

Referenced by quit_handler().

02210 {
02211    HistEvent ev;
02212 
02213    if (el_hist == NULL || el == NULL)
02214       ast_el_initialize();
02215 
02216    return (history(el_hist, &ev, H_SAVE, filename));
02217 }

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 1021 of file asterisk.c.

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

Referenced by main().

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

int64_t ast_mark ( int  i,
int  startstop 
)

Definition at line 432 of file asterisk.c.

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

Referenced by extension_match_core(), and handle_astobj2_test().

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

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 873 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

00874 {
00875    int x;
00876    for (x=0; x < AST_MAX_CONNECTS; x++) {
00877       if (consoles[x].fd > -1) 
00878          fdprint(consoles[x].p[1], string);
00879    }
00880 }

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

log the string to all attached console clients

Definition at line 848 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts_mutable(), and network_verboser().

00849 {
00850    int x;
00851    for (x = 0;x < AST_MAX_CONNECTS; x++) {
00852       if (consoles[x].mute)
00853          continue;
00854       if (consoles[x].fd > -1) 
00855          fdprint(consoles[x].p[1], string);
00856    }
00857 }

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 400 of file asterisk.c.

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

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

static void ast_readconfig ( void   )  [static]

Definition at line 2366 of file asterisk.c.

References ast_config_load(), ast_log(), ast_opt_override_config, ast_variable_browse(), config, LOG_WARNING, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by main().

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

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 700 of file asterisk.c.

References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, and ast_unregister_atexit().

Referenced by do_reload(), and load_module().

00701 {
00702    int res = -1;
00703    struct ast_atexit *ae;
00704    ast_unregister_atexit(func);  
00705    AST_LIST_LOCK(&atexits);
00706    if ((ae = ast_calloc(1, sizeof(*ae)))) {
00707       AST_LIST_INSERT_HEAD(&atexits, ae, list);
00708       ae->func = func;
00709       res = 0;
00710    }
00711    AST_LIST_UNLOCK(&atexits);
00712    return res;
00713 }

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 254 of file asterisk.c.

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

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

void ast_register_thread ( char *  name  ) 

Definition at line 304 of file asterisk.c.

References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, and AST_LIST_UNLOCK.

Referenced by dummy_start().

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

static void ast_remotecontrol ( char *  data  )  [static]

Definition at line 2245 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(), pollfd::events, pollfd::fd, fdprint(), hostname, LOG_WARNING, poll(), POLLIN, remoteconsolehandler(), pollfd::revents, and strsep().

Referenced by main().

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

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 746 of file asterisk.c.

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

Referenced by ast_safe_system().

00747 {
00748    unsigned int level;
00749 
00750    ast_mutex_lock(&safe_system_lock);
00751    level = safe_system_level++;
00752 
00753    /* only replace the handler if it has not already been done */
00754    if (level == 0)
00755       safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
00756 
00757    ast_mutex_unlock(&safe_system_lock);
00758 }

static void ast_run_atexits ( void   )  [static]

Definition at line 1223 of file asterisk.c.

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

Referenced by quit_handler().

01224 {
01225    struct ast_atexit *ae;
01226    AST_LIST_LOCK(&atexits);
01227    AST_LIST_TRAVERSE(&atexits, ae, list) {
01228       if (ae->func) 
01229          ae->func();
01230    }
01231    AST_LIST_UNLOCK(&atexits);
01232 }

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 774 of file asterisk.c.

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

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().

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

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 1189 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().

01190 {
01191    struct sched_param sched;
01192    memset(&sched, 0, sizeof(sched));
01193 #ifdef __linux__
01194    if (pri) {  
01195       sched.sched_priority = 10;
01196       if (sched_setscheduler(0, SCHED_RR, &sched)) {
01197          ast_log(LOG_WARNING, "Unable to set high priority\n");
01198          return -1;
01199       } else
01200          if (option_verbose)
01201             ast_verbose("Set to realtime thread\n");
01202    } else {
01203       sched.sched_priority = 0;
01204       /* According to the manpage, these parameters can never fail. */
01205       sched_setscheduler(0, SCHED_OTHER, &sched);
01206    }
01207 #else
01208    if (pri) {
01209       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
01210          ast_log(LOG_WARNING, "Unable to set high priority\n");
01211          return -1;
01212       } else
01213          if (option_verbose)
01214             ast_verbose("Set to high priority\n");
01215    } else {
01216       /* According to the manpage, these parameters can never fail. */
01217       setpriority(PRIO_PROCESS, 0, 0);
01218    }
01219 #endif
01220    return 0;
01221 }

static int ast_tryconnect ( void   )  [static]

Definition at line 1090 of file asterisk.c.

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

Referenced by ast_el_read_char(), and main().

01091 {
01092    struct sockaddr_un sunaddr;
01093    int res;
01094    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01095    if (ast_consock < 0) {
01096       ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
01097       return 0;
01098    }
01099    memset(&sunaddr, 0, sizeof(sunaddr));
01100    sunaddr.sun_family = AF_LOCAL;
01101    ast_copy_string(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01102    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01103    if (res) {
01104       close(ast_consock);
01105       ast_consock = -1;
01106       return 0;
01107    } else
01108       return 1;
01109 }

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 715 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 ast_atexit::func.

Referenced by ast_register_atexit(), and do_reload().

00716 {
00717    struct ast_atexit *ae;
00718    AST_LIST_LOCK(&atexits);
00719    AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
00720       if (ae->func == func) {
00721          AST_LIST_REMOVE_CURRENT(&atexits, list);
00722          break;
00723       }
00724    }
00725    AST_LIST_TRAVERSE_SAFE_END
00726    AST_LIST_UNLOCK(&atexits);
00727 }

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 275 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.

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

void ast_unregister_thread ( void *  id  ) 

Definition at line 317 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().

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

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 760 of file asterisk.c.

References ast_mutex_lock(), and ast_mutex_unlock().

Referenced by agi_exec_full(), and ast_safe_system().

00761 {
00762    unsigned int level;
00763 
00764    ast_mutex_lock(&safe_system_lock);
00765    level = --safe_system_level;
00766 
00767    /* only restore the handler if we are the last one */
00768    if (level == 0)
00769       signal(SIGCHLD, safe_system_prev_handler);
00770 
00771    ast_mutex_unlock(&safe_system_lock);
00772 }

static void child_handler ( int  sig  )  [static]

Definition at line 1136 of file asterisk.c.

Referenced by main().

01137 {
01138    /* Must not ever ast_log or ast_verbose within signal handler */
01139    int n, status;
01140 
01141    /*
01142     * Reap all dead children -- not just one
01143     */
01144    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01145       ;
01146    if (n == 0 && option_debug)   
01147       printf("Huh?  Child handler, but nobody there?\n");
01148    signal(sig, child_handler);
01149 }

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

Definition at line 2052 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().

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

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

Definition at line 1811 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().

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

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

Definition at line 676 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.

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

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

Definition at line 654 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.

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

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

Definition at line 1365 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().

01366 {
01367    char tmp[80];
01368    const char *c = NULL;
01369 
01370    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01371        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01372        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01373        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
01374       fputs(tmp, stdout);
01375       fputs(c, stdout);
01376    } else
01377       fputs(s, stdout);
01378 
01379    fflush(stdout);
01380    
01381    /* Wake up a poll()ing console */
01382    if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
01383       pthread_kill(consolethread, SIGURG);
01384 }

static void consolehandler ( char *  s  )  [static]

Definition at line 1396 of file asterisk.c.

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

Referenced by main().

01397 {
01398    printf(term_end());
01399    fflush(stdout);
01400 
01401    /* Called when readline data is available */
01402    if (!ast_all_zeros(s))
01403       ast_el_add_history(s);
01404    /* The real handler for bang */
01405    if (s[0] == '!') {
01406       if (s[1])
01407          ast_safe_system(s+1);
01408       else
01409          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01410    } else 
01411       ast_cli_command(STDOUT_FILENO, s);
01412 }

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

Definition at line 729 of file asterisk.c.

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

00730 {
00731    return write(fd, s, strlen(s) + 1);
00732 }

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

Definition at line 1354 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01355 {
01356    const char *c;
01357    if (!strncmp(s, cmp, strlen(cmp))) {
01358       c = s + strlen(cmp);
01359       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01360       return c;
01361    }
01362    return NULL;
01363 }

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

Definition at line 1566 of file asterisk.c.

References ast_cancel_shutdown(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01567 {
01568    if (argc != 2)
01569       return RESULT_SHOWUSAGE;
01570    ast_cancel_shutdown();
01571    shuttingdown = 0;
01572    return RESULT_SUCCESS;
01573 }

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

Definition at line 1575 of file asterisk.c.

References RESULT_SUCCESS.

01576 {
01577    return RESULT_SUCCESS;
01578 }

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

Definition at line 1549 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01550 {
01551    if (argc != 2)
01552       return RESULT_SHOWUSAGE;
01553    quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
01554    return RESULT_SUCCESS;
01555 }

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

Definition at line 1541 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01542 {
01543    if (argc != 2)
01544       return RESULT_SHOWUSAGE;
01545    quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */);
01546    return RESULT_SUCCESS;
01547 }

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

Definition at line 1557 of file asterisk.c.

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

01558 {
01559    if (argc != 3)
01560       return RESULT_SHOWUSAGE;
01561    ast_cli(fd, "Waiting for inactivity to perform restart\n");
01562    quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */);
01563    return RESULT_SUCCESS;
01564 }

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

Definition at line 494 of file asterisk.c.

References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::name, prof_data, and profile_entry::value.

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

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

Definition at line 448 of file asterisk.c.

References profile_data::e, profile_data::entries, profile_entry::events, profile_entry::name, prof_data, and profile_entry::value.

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

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

Definition at line 336 of file asterisk.c.

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

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

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

Definition at line 600 of file asterisk.c.

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

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

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

CLI command to list module versions.

Definition at line 546 of file asterisk.c.

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

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

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

Definition at line 1524 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01525 {
01526    if (argc != 2)
01527       return RESULT_SHOWUSAGE;
01528    quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
01529    return RESULT_SUCCESS;
01530 }

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

Definition at line 1516 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01517 {
01518    if (argc != 2)
01519       return RESULT_SHOWUSAGE;
01520    quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */);
01521    return RESULT_SUCCESS;
01522 }

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

Definition at line 1532 of file asterisk.c.

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

01533 {
01534    if (argc != 3)
01535       return RESULT_SHOWUSAGE;
01536    ast_cli(fd, "Waiting for inactivity to perform halt\n");
01537    quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
01538    return RESULT_SUCCESS;
01539 }

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

Definition at line 1496 of file asterisk.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01497 {
01498    if (argc != 3)
01499       return RESULT_SHOWUSAGE;
01500    ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
01501       ASTERISK_VERSION, ast_build_user, ast_build_hostname,
01502       ast_build_machine, ast_build_os, ast_build_date);
01503    return RESULT_SUCCESS;
01504 }

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

Definition at line 1486 of file asterisk.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

static void hup_handler ( int  num  )  [static]

Definition at line 1123 of file asterisk.c.

References sig_flags.

Referenced by main().

01124 {
01125    int a = 0;
01126    if (option_verbose > 1) 
01127       printf("Received HUP signal -- Reloading configs\n");
01128    if (restartnow)
01129       execvp(_argv[0], _argv);
01130    sig_flags.need_reload = 1;
01131    if (sig_alert_pipe[1] != -1)
01132       write(sig_alert_pipe[1], &a, sizeof(a));
01133    signal(num, hup_handler);
01134 }

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

Definition at line 955 of file asterisk.c.

References AF_LOCAL, ast_log(), AST_MAX_CONNECTS, ast_opt_mute, ast_pthread_create_background, ast_verbose(), consoles, 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().

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

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

Definition at line 2548 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_options, 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_tryconnect(), ast_udptl_init(), ast_ulaw_init(), ast_utils_init(), ast_verbose(), astdb_init(), callerid_init(), child_handler(), cli_asterisk, COLOR_BLACK, COLOR_BRWHITE, console_verboser(), consolehandler(), dnsmgr_init(), dnsmgr_start_refresh(), 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(), setenv(), show_cli_help(), show_version(), tdd_init(), term_color(), term_end(), term_quit(), test_for_thread_safety(), threadstorage_init(), urg_handler(), and WELCOME_MESSAGE.

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

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

Definition at line 2528 of file asterisk.c.

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

Referenced by main().

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

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

Definition at line 900 of file asterisk.c.

References ast_cli_command(), ast_log(), ast_verbose(), 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().

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

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

Definition at line 893 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by ast_makesocket().

00894 {
00895    ast_network_puts_mutable(s);
00896 }

static void null_sig_handler ( int  signal  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 735 of file asterisk.c.

Referenced by ast_replace_sigchld().

00736 {
00737 
00738 }

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

Definition at line 1234 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().

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

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 426 of file asterisk.c.

Referenced by ast_mark().

00427 {
00428    return 0;
00429 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1414 of file asterisk.c.

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

Referenced by ast_remotecontrol().

01415 {
01416    int ret = 0;
01417 
01418    /* Called when readline data is available */
01419    if (!ast_all_zeros(s))
01420       ast_el_add_history(s);
01421    /* The real handler for bang */
01422    if (s[0] == '!') {
01423       if (s[1])
01424          ast_safe_system(s+1);
01425       else
01426          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01427       ret = 1;
01428    }
01429    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
01430        (s[4] == '\0' || isspace(s[4]))) {
01431       quit_handler(0, 0, 0, 0);
01432       ret = 1;
01433    }
01434 
01435    return ret;
01436 }

static void set_icon ( char *  text  )  [static]

Definition at line 1181 of file asterisk.c.

Referenced by main().

01182 {
01183    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01184       fprintf(stdout, "\033]1;%s\007", text);
01185 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1175 of file asterisk.c.

Referenced by main().

01176 {
01177    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01178       fprintf(stdout, "\033]2;%s\007", text);
01179 }

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1152 of file asterisk.c.

References ast_log(), LOG_NOTICE, and LOG_WARNING.

01153 {
01154    struct rlimit l = {0, 0};
01155    
01156    if (value <= 0) {
01157       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01158       return;
01159    }
01160    
01161    l.rlim_cur = value;
01162    l.rlim_max = value;
01163    
01164    if (setrlimit(RLIMIT_NOFILE, &l)) {
01165       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01166       return;
01167    }
01168    
01169    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01170    
01171    return;
01172 }

static int show_cli_help ( void   )  [static]

Definition at line 2332 of file asterisk.c.

Referenced by main().

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

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

Definition at line 1633 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

01634 {
01635    int x;
01636 
01637    for (x = 0; x < sizeof(license_lines) / sizeof(license_lines[0]); x++)
01638       ast_cli(fd, (char *) license_lines[x]);
01639 
01640    return RESULT_SUCCESS;
01641 }

static int show_version ( void   )  [static]

Definition at line 2326 of file asterisk.c.

Referenced by main().

02327 {
02328    printf("Asterisk " ASTERISK_VERSION "\n");
02329    return 0;
02330 }

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

Definition at line 1604 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

01605 {
01606    int x;
01607 
01608    for (x = 0; x < sizeof(warranty_lines) / sizeof(warranty_lines[0]); x++)
01609       ast_cli(fd, (char *) warranty_lines[x]);
01610 
01611    return RESULT_SUCCESS;
01612 }

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 1117 of file asterisk.c.

Referenced by main().

01118 {
01119    signal(num, urg_handler);
01120    return;
01121 }


Variable Documentation

char* _argv[256] [static]

Definition at line 232 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 1438 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 211 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_CONFIG_DIR[PATH_MAX]

Definition at line 203 of file asterisk.c.

Referenced by compile_script(), config_text_file_load(), config_text_file_save(), handle_save_dialplan(), ices_exec(), launch_script(), and pbx_load_module().

char ast_config_AST_CONFIG_FILE[PATH_MAX]

Definition at line 204 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl"

Definition at line 222 of file asterisk.c.

char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0"

Definition at line 221 of file asterisk.c.

char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0"

Definition at line 220 of file asterisk.c.

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX]

Definition at line 219 of file asterisk.c.

char ast_config_AST_DATA_DIR[PATH_MAX]

Definition at line 209 of file asterisk.c.

Referenced by ast_linear_stream(), build_filename(), launch_script(), make_filename(), reload_firmware(), and static_callback().

char ast_config_AST_DB[PATH_MAX]

Definition at line 212 of file asterisk.c.

Referenced by dbinit().

char ast_config_AST_KEY_DIR[PATH_MAX]

Definition at line 213 of file asterisk.c.

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

char ast_config_AST_LOG_DIR[PATH_MAX]

Definition at line 210 of file asterisk.c.

Referenced by csv_log(), init_logger(), launch_script(), load_config(), load_module(), make_logchannel(), reload_logger(), testclient_exec(), testserver_exec(), and writefile().

char ast_config_AST_MODULE_DIR[PATH_MAX]

Definition at line 205 of file asterisk.c.

Referenced by add_module(), complete_fn_2(), complete_fn_3(), file_ok_sel(), launch_script(), and load_modules().

char ast_config_AST_MONITOR_DIR[PATH_MAX]

Definition at line 207 of file asterisk.c.

Referenced by ast_monitor_change_fname(), ast_monitor_start(), ast_monitor_stop(), chanspy_exec(), extenspy_exec(), launch_script(), and mixmonitor_exec().

char ast_config_AST_PID[PATH_MAX]

Definition at line 214 of file asterisk.c.

char ast_config_AST_RUN_DIR[PATH_MAX]

Definition at line 216 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_RUN_GROUP[PATH_MAX]

Definition at line 218 of file asterisk.c.

char ast_config_AST_RUN_USER[PATH_MAX]

Definition at line 217 of file asterisk.c.

char ast_config_AST_SOCKET[PATH_MAX]

Definition at line 215 of file asterisk.c.

char ast_config_AST_SPOOL_DIR[PATH_MAX]

Definition at line 206 of file asterisk.c.

Referenced by app_exec(), conf_run(), dictate_exec(), launch_script(), load_module(), and play_mailbox_owner().

char ast_config_AST_SYSTEM_NAME[20] = ""

Definition at line 223 of file asterisk.c.

Referenced by authenticate(), pbx_retrieve_variable(), realtime_update_peer(), and reload_config().

char ast_config_AST_VAR_DIR[PATH_MAX]

Definition at line 208 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 172 of file asterisk.c.

time_t ast_lastreloadtime

Definition at line 189 of file asterisk.c.

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

pid_t ast_mainpid

Definition at line 173 of file asterisk.c.

Referenced by safe_append(), and scan_service().

int ast_socket = -1 [static]

UNIX Socket for allowing remote control

Definition at line 171 of file asterisk.c.

time_t ast_startuptime

Definition at line 188 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 1470 of file asterisk.c.

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 1669 of file asterisk.c.

Referenced by main().

struct ast_cli_entry cli_clear_profile_deprecated [static]

Initial value:

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

Definition at line 1663 of file asterisk.c.

struct ast_cli_entry cli_show_profile_deprecated [static]

Initial value:

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

Definition at line 1658 of file asterisk.c.

struct ast_cli_entry cli_show_version_deprecated [static]

Initial value:

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

Definition at line 1647 of file asterisk.c.

struct ast_cli_entry cli_show_version_files_deprecated [static]

Initial value:

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

Definition at line 1653 of file asterisk.c.

struct console consoles[AST_MAX_CONNECTS]

Definition at line 195 of file asterisk.c.

Referenced by ast_console_toggle_mute(), ast_makesocket(), ast_network_puts(), ast_network_puts_mutable(), and listener().

pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 235 of file asterisk.c.

Referenced by show_console().

char debug_filename[AST_FILENAME_MAX] = ""

Definition at line 169 of file asterisk.c.

Referenced by ast_log(), handle_debuglevel_deprecated(), handle_nodebug(), and handle_set_debug().

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 197 of file asterisk.c.

EditLine* el [static]

Definition at line 192 of file asterisk.c.

Referenced by __ast_context_destroy(), add_pri(), ast_add_extension2(), handle_save_dialplan(), and show_dialplan_helper().

History* el_hist [static]

Definition at line 191 of file asterisk.c.

const char* license_lines[] [static]

Definition at line 1614 of file asterisk.c.

pthread_t lthread [static]

Definition at line 898 of file asterisk.c.

unsigned int need_quit

Definition at line 242 of file asterisk.c.

unsigned int need_reload

Definition at line 241 of file asterisk.c.

struct profile_data* prof_data [static]

Definition at line 365 of file asterisk.c.

Referenced by ast_add_profile(), ast_mark(), ast_profile(), handle_show_profile(), and handle_show_profile_deprecated().

char randompool[256] [static]

Definition at line 237 of file asterisk.c.

char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR

Definition at line 168 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 193 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 1461 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 1456 of file asterisk.c.

char restart_when_convenient_help[] [static]

Initial value:

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

Definition at line 1466 of file asterisk.c.

int restartnow [static]

Definition at line 234 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 743 of file asterisk.c.

void* safe_system_prev_handler [static]

Definition at line 744 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 1478 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 300 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 540 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 1474 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 1447 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 1443 of file asterisk.c.

char shutdown_when_convenient_help[] [static]

Initial value:

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

Definition at line 1452 of file asterisk.c.

int shuttingdown [static]

Definition at line 233 of file asterisk.c.

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

Definition at line 239 of file asterisk.c.

struct { ... } sig_flags [static]

Referenced by __quit_handler(), hup_handler(), and monitor_sig_flags().

char version_help[] [static]

Initial value:

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

Definition at line 1482 of file asterisk.c.

const char* warranty_lines[] [static]

Definition at line 1579 of file asterisk.c.


Generated on Fri Aug 24 02:23:07 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1