Mon May 14 04:44:59 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/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 133 of file asterisk.c.

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

#define AST_MAX_CONNECTS   128

Definition at line 137 of file asterisk.c.

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

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 1639 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

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

#define PF_LOCAL   PF_UNIX

Definition at line 134 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 141 of file asterisk.c.

Referenced by ast_el_read_char(), and main().


Function Documentation

static void __quit_handler ( int  num  )  [static]

Definition at line 1340 of file asterisk.c.

References sig_flags.

Referenced by main().

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

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

support for event profiling

Returns:
Returns the identifier of the counter.

Definition at line 369 of file asterisk.c.

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

Referenced by extension_match_core().

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

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1382 of file asterisk.c.

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

01383 {
01384    while (*s) {
01385       if (*s > 32)
01386          return 0;
01387       s++;  
01388    }
01389    return 1;
01390 }

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

Definition at line 2000 of file asterisk.c.

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

Referenced by cli_complete().

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

void ast_console_puts ( const char *  string  ) 

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

Definition at line 885 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

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

void ast_console_puts_mutable ( const char *  string  ) 

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

Definition at line 862 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by ast_log().

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

void ast_console_toggle_mute ( int  fd  ) 

mute or unmute a console from logging

Definition at line 827 of file asterisk.c.

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

Referenced by handle_logger_mute().

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

static int ast_el_add_history ( char *   )  [static]

Definition at line 2194 of file asterisk.c.

References ast_el_initialize().

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

02195 {
02196    HistEvent ev;
02197 
02198    if (el_hist == NULL || el == NULL)
02199       ast_el_initialize();
02200    if (strlen(buf) > 256)
02201       return 0;
02202    return (history(el_hist, &ev, H_ENTER, buf));
02203 }

static int ast_el_initialize ( void   )  [static]

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

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

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

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

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

static int ast_el_read_history ( char *   )  [static]

Definition at line 2215 of file asterisk.c.

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

Referenced by ast_remotecontrol(), and main().

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

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

Definition at line 1990 of file asterisk.c.

Referenced by ast_cli_display_match_list().

01991 {
01992    char *s1, *s2;
01993 
01994    s1 = ((char **)i1)[0];
01995    s2 = ((char **)i2)[0];
01996 
01997    return strcasecmp(s1, s2);
01998 }

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

Definition at line 1955 of file asterisk.c.

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

Referenced by cli_complete().

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

static int ast_el_write_history ( char *   )  [static]

Definition at line 2205 of file asterisk.c.

References ast_el_initialize().

Referenced by quit_handler().

02206 {
02207    HistEvent ev;
02208 
02209    if (el_hist == NULL || el == NULL)
02210       ast_el_initialize();
02211 
02212    return (history(el_hist, &ev, H_SAVE, filename));
02213 }

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

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

int64_t ast_mark ( int  i,
int  startstop 
)

Definition at line 431 of file asterisk.c.

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

Referenced by extension_match_core().

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

AST_MUTEX_DEFINE_STATIC ( safe_system_lock   ) 

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

write the string to all attached console clients

Definition at line 872 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

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

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

log the string to all attached console clients

Definition at line 847 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts_mutable(), and network_verboser().

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

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 399 of file asterisk.c.

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

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

static void ast_readconfig ( void   )  [static]

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

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

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

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

Referenced by do_reload(), and load_module().

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

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

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

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

void ast_register_thread ( char *  name  ) 

Definition at line 303 of file asterisk.c.

References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, and AST_LIST_UNLOCK.

Referenced by dummy_start().

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

static void ast_remotecontrol ( char *  data  )  [static]

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

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

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

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

Referenced by ast_safe_system().

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

static void ast_run_atexits ( void   )  [static]

Definition at line 1222 of file asterisk.c.

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

Referenced by quit_handler().

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

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

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

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

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

static int ast_tryconnect ( void   )  [static]

Definition at line 1089 of file asterisk.c.

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

Referenced by ast_el_read_char(), and main().

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

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

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

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

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

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

void ast_unregister_thread ( void *  id  ) 

Definition at line 316 of file asterisk.c.

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

Referenced by dummy_start().

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

void ast_unreplace_sigchld ( void   ) 

Restore the SIGCHLD handler.

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

Definition at line 759 of file asterisk.c.

References ast_mutex_lock(), and ast_mutex_unlock().

Referenced by agi_exec_full(), and ast_safe_system().

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

static void child_handler ( int  sig  )  [static]

Definition at line 1135 of file asterisk.c.

Referenced by main().

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

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

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

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

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

Definition at line 1807 of file asterisk.c.

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

Referenced by ast_el_initialize().

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

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

Definition at line 675 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.

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

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

Definition at line 653 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.

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

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

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

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

static void consolehandler ( char *  s  )  [static]

Definition at line 1392 of file asterisk.c.

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

Referenced by main().

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

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

Definition at line 728 of file asterisk.c.

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

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

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

Definition at line 1350 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01351 {
01352    const char *c;
01353    if (!strncmp(s, cmp, strlen(cmp))) {
01354       c = s + strlen(cmp);
01355       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01356       return c;
01357    }
01358    return NULL;
01359 }

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

Definition at line 1562 of file asterisk.c.

References ast_cancel_shutdown(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01563 {
01564    if (argc != 2)
01565       return RESULT_SHOWUSAGE;
01566    ast_cancel_shutdown();
01567    shuttingdown = 0;
01568    return RESULT_SUCCESS;
01569 }

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

Definition at line 1571 of file asterisk.c.

References RESULT_SUCCESS.

01572 {
01573    return RESULT_SUCCESS;
01574 }

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

Definition at line 1545 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01546 {
01547    if (argc != 2)
01548       return RESULT_SHOWUSAGE;
01549    quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
01550    return RESULT_SUCCESS;
01551 }

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

Definition at line 1537 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1553 of file asterisk.c.

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

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

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

Definition at line 493 of file asterisk.c.

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

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

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

Definition at line 447 of file asterisk.c.

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

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

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

Definition at line 335 of file asterisk.c.

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

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

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

Definition at line 599 of file asterisk.c.

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

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

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

CLI command to list module versions.

Definition at line 545 of file asterisk.c.

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

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

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

Definition at line 1520 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01521 {
01522    if (argc != 2)
01523       return RESULT_SHOWUSAGE;
01524    quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
01525    return RESULT_SUCCESS;
01526 }

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

Definition at line 1512 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1528 of file asterisk.c.

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

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

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

Definition at line 1492 of file asterisk.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1482 of file asterisk.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

static void hup_handler ( int  num  )  [static]

Definition at line 1122 of file asterisk.c.

References sig_flags.

Referenced by main().

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

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

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

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

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

Definition at line 2541 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.

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

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

Definition at line 2521 of file asterisk.c.

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

Referenced by main().

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

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

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

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

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

Definition at line 892 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by ast_makesocket().

00893 {
00894    ast_network_puts_mutable(s);
00895 }

static void null_sig_handler ( int  signal  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 734 of file asterisk.c.

Referenced by ast_replace_sigchld().

00735 {
00736 
00737 }

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

Definition at line 1233 of file asterisk.c.

References ast_active_channels(), ast_begin_shutdown(), ast_cdr_engine_term(), ast_el_write_history(), ast_log(), 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().

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

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 425 of file asterisk.c.

Referenced by ast_mark().

00426 {
00427    return 0;
00428 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1410 of file asterisk.c.

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

Referenced by ast_remotecontrol().

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

static void set_icon ( char *  text  )  [static]

Definition at line 1180 of file asterisk.c.

Referenced by main().

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

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1174 of file asterisk.c.

Referenced by main().

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

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1151 of file asterisk.c.

References ast_log(), LOG_NOTICE, and LOG_WARNING.

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

static int show_cli_help ( void   )  [static]

Definition at line 2325 of file asterisk.c.

Referenced by main().

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

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

Definition at line 1629 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

01630 {
01631    int x;
01632 
01633    for (x = 0; x < sizeof(license_lines) / sizeof(license_lines[0]); x++)
01634       ast_cli(fd, (char *) license_lines[x]);
01635 
01636    return RESULT_SUCCESS;
01637 }

static int show_version ( void   )  [static]

Definition at line 2319 of file asterisk.c.

Referenced by main().

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

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

Definition at line 1600 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

01601 {
01602    int x;
01603 
01604    for (x = 0; x < sizeof(warranty_lines) / sizeof(warranty_lines[0]); x++)
01605       ast_cli(fd, (char *) warranty_lines[x]);
01606 
01607    return RESULT_SUCCESS;
01608 }

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

Referenced by main().

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


Variable Documentation

char* _argv[256] [static]

Definition at line 231 of file asterisk.c.

char abort_halt_help[] [static]

Initial value:

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

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

Referenced by launch_script().

char ast_config_AST_CONFIG_DIR[PATH_MAX]

Definition at line 202 of file asterisk.c.

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

char ast_config_AST_CONFIG_FILE[PATH_MAX]

Definition at line 203 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl"

Definition at line 221 of file asterisk.c.

char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0"

Definition at line 220 of file asterisk.c.

char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0"

Definition at line 219 of file asterisk.c.

char ast_config_AST_CTL_PERMISSIONS[PATH_MAX]

Definition at line 218 of file asterisk.c.

char ast_config_AST_DATA_DIR[PATH_MAX]

Definition at line 208 of file asterisk.c.

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

char ast_config_AST_DB[PATH_MAX]

Definition at line 211 of file asterisk.c.

Referenced by dbinit().

char ast_config_AST_KEY_DIR[PATH_MAX]

Definition at line 212 of file asterisk.c.

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

char ast_config_AST_LOG_DIR[PATH_MAX]

Definition at line 209 of file asterisk.c.

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

char ast_config_AST_MODULE_DIR[PATH_MAX]

Definition at line 204 of file asterisk.c.

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

char ast_config_AST_MONITOR_DIR[PATH_MAX]

Definition at line 206 of file asterisk.c.

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

char ast_config_AST_PID[PATH_MAX]

Definition at line 213 of file asterisk.c.

char ast_config_AST_RUN_DIR[PATH_MAX]

Definition at line 215 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_RUN_GROUP[PATH_MAX]

Definition at line 217 of file asterisk.c.

char ast_config_AST_RUN_USER[PATH_MAX]

Definition at line 216 of file asterisk.c.

char ast_config_AST_SOCKET[PATH_MAX]

Definition at line 214 of file asterisk.c.

char ast_config_AST_SPOOL_DIR[PATH_MAX]

Definition at line 205 of file asterisk.c.

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

char ast_config_AST_SYSTEM_NAME[20] = ""

Definition at line 222 of file asterisk.c.

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

char ast_config_AST_VAR_DIR[PATH_MAX]

Definition at line 207 of file asterisk.c.

Referenced by ael2_semantic_check(), and launch_script().

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

Definition at line 171 of file asterisk.c.

time_t ast_lastreloadtime

Definition at line 188 of file asterisk.c.

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

pid_t ast_mainpid

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

time_t ast_startuptime

Definition at line 187 of file asterisk.c.

Referenced by handle_showuptime(), and handle_showuptime_deprecated().

char bang_help[] [static]

Initial value:

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

Definition at line 1466 of file asterisk.c.

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 1665 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 1659 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 1654 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 1643 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 1649 of file asterisk.c.

struct console consoles[AST_MAX_CONNECTS]

Definition at line 194 of file asterisk.c.

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

pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 234 of file asterisk.c.

Referenced by show_console().

char debug_filename[AST_FILENAME_MAX] = ""

Definition at line 168 of file asterisk.c.

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

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 196 of file asterisk.c.

EditLine* el [static]

Definition at line 191 of file asterisk.c.

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

History* el_hist [static]

Definition at line 190 of file asterisk.c.

const char* license_lines[] [static]

Definition at line 1610 of file asterisk.c.

pthread_t lthread [static]

Definition at line 897 of file asterisk.c.

unsigned int need_quit

Definition at line 241 of file asterisk.c.

unsigned int need_reload

Definition at line 240 of file asterisk.c.

struct profile_data* prof_data [static]

Definition at line 364 of file asterisk.c.

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

char randompool[256] [static]

Definition at line 236 of file asterisk.c.

char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR

Definition at line 167 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 192 of file asterisk.c.

char restart_gracefully_help[] [static]

Initial value:

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

Definition at line 1457 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 1452 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 1462 of file asterisk.c.

int restartnow [static]

Definition at line 233 of file asterisk.c.

unsigned int safe_system_level = 0 [static]

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

Definition at line 742 of file asterisk.c.

void* safe_system_prev_handler [static]

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

char show_threads_help[] [static]

Initial value:

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

Definition at line 299 of file asterisk.c.

char show_version_files_help[] [static]

Initial value:

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

Definition at line 539 of file asterisk.c.

char show_warranty_help[] [static]

Initial value:

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

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

int shuttingdown [static]

Definition at line 232 of file asterisk.c.

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

Definition at line 238 of file asterisk.c.

struct { ... } sig_flags [static]

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

char version_help[] [static]

Initial value:

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

Definition at line 1478 of file asterisk.c.

const char* warranty_lines[] [static]

Definition at line 1575 of file asterisk.c.


Generated on Mon May 14 04:45:01 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1