Mon Mar 31 07:38:59 2008

Asterisk developer's documentation


asterisk.c File Reference

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

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

Include dependency graph for asterisk.c:

Go to the source code of this file.

Data Structures

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

Defines

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

Functions

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

Variables

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

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 1653 of file asterisk.c.

Referenced by cli_prompt().

#define EL_BUF_SIZE   512

Referenced by ast_el_read_char().

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

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

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

#define NUM_MSGS   64

Definition at line 138 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

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

References sig_flags.

Referenced by main().

01353 {
01354    int a = 0;
01355    sig_flags.need_quit = 1;
01356    if (sig_alert_pipe[1] != -1)
01357       write(sig_alert_pipe[1], &a, sizeof(a));
01358    /* There is no need to restore the signal handler here, since the app
01359     * is going to exit */
01360 }

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

support for event profiling

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

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

01395 {
01396    while (*s) {
01397       if (*s > 32)
01398          return 0;
01399       s++;  
01400    }
01401    return 1;
01402 }

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

Definition at line 2018 of file asterisk.c.

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

Referenced by cli_complete().

02019 {
02020    int i, idx, limit, count;
02021    int screenwidth = 0;
02022    int numoutput = 0, numoutputline = 0;
02023 
02024    screenwidth = ast_get_termcols(STDOUT_FILENO);
02025 
02026    /* find out how many entries can be put on one line, with two spaces between strings */
02027    limit = screenwidth / (max + 2);
02028    if (limit == 0)
02029       limit = 1;
02030 
02031    /* how many lines of output */
02032    count = len / limit;
02033    if (count * limit < len)
02034       count++;
02035 
02036    idx = 1;
02037 
02038    qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
02039 
02040    for (; count > 0; count--) {
02041       numoutputline = 0;
02042       for (i=0; i < limit && matches[idx]; i++, idx++) {
02043 
02044          /* Don't print dupes */
02045          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
02046             i--;
02047             free(matches[idx]);
02048             matches[idx] = NULL;
02049             continue;
02050          }
02051 
02052          numoutput++;
02053          numoutputline++;
02054          fprintf(stdout, "%-*s  ", max, matches[idx]);
02055          free(matches[idx]);
02056          matches[idx] = NULL;
02057       }
02058       if (numoutputline > 0)
02059          fprintf(stdout, "\n");
02060    }
02061 
02062    return numoutput;
02063 }

void ast_console_puts ( const char *  string  ) 

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

Definition at line 894 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

00895 {
00896    fputs(string, stdout);
00897    fflush(stdout);
00898    ast_network_puts(string);
00899 }

void ast_console_puts_mutable ( const char *  string  ) 

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

Definition at line 871 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by ast_log().

00872 {
00873    fputs(string, stdout);
00874    fflush(stdout);
00875    ast_network_puts_mutable(string);
00876 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 834 of file asterisk.c.

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

Referenced by handle_logger_mute().

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

static int ast_el_add_history ( char *   )  [static]

Definition at line 2212 of file asterisk.c.

References ast_el_initialize().

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

02213 {
02214    HistEvent ev;
02215 
02216    if (el_hist == NULL || el == NULL)
02217       ast_el_initialize();
02218    if (strlen(buf) > 256)
02219       return 0;
02220    return (history(el_hist, &ev, H_ENTER, buf));
02221 }

static int ast_el_initialize ( void   )  [static]

Definition at line 2177 of file asterisk.c.

References cli_complete(), and cli_prompt().

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

02178 {
02179    HistEvent ev;
02180    char *editor = getenv("AST_EDITOR");
02181 
02182    if (el != NULL)
02183       el_end(el);
02184    if (el_hist != NULL)
02185       history_end(el_hist);
02186 
02187    el = el_init("asterisk", stdin, stdout, stderr);
02188    el_set(el, EL_PROMPT, cli_prompt);
02189 
02190    el_set(el, EL_EDITMODE, 1);      
02191    el_set(el, EL_EDITOR, editor ? editor : "emacs");     
02192    el_hist = history_init();
02193    if (!el || !el_hist)
02194       return -1;
02195 
02196    /* setup history with 100 entries */
02197    history(el_hist, &ev, H_SETSIZE, 100);
02198 
02199    el_set(el, EL_HIST, history, el_hist);
02200 
02201    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02202    /* Bind <tab> to command completion */
02203    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02204    /* Bind ? to command completion */
02205    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02206    /* Bind ^D to redisplay */
02207    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02208 
02209    return 0;
02210 }

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

Definition at line 1740 of file asterisk.c.

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

Referenced by ast_remotecontrol().

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

static int ast_el_read_history ( char *   )  [static]

Definition at line 2233 of file asterisk.c.

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

Referenced by ast_remotecontrol(), and main().

02234 {
02235    char buf[256];
02236    FILE *f;
02237    int ret = -1;
02238 
02239    if (el_hist == NULL || el == NULL)
02240       ast_el_initialize();
02241 
02242    if ((f = fopen(filename, "r")) == NULL)
02243       return ret;
02244 
02245    while (!feof(f)) {
02246       fgets(buf, sizeof(buf), f);
02247       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02248          continue;
02249       if (ast_all_zeros(buf))
02250          continue;
02251       if ((ret = ast_el_add_history(buf)) == -1)
02252          break;
02253    }
02254    fclose(f);
02255 
02256    return ret;
02257 }

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

Definition at line 2008 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02009 {
02010    char *s1, *s2;
02011 
02012    s1 = ((char **)i1)[0];
02013    s2 = ((char **)i2)[0];
02014 
02015    return strcasecmp(s1, s2);
02016 }

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

Definition at line 1973 of file asterisk.c.

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

Referenced by cli_complete().

01974 {
01975    char **match_list = NULL, *retstr;
01976    size_t match_list_len;
01977    int matches = 0;
01978 
01979    match_list_len = 1;
01980    while ( (retstr = strsep(&buf, " ")) != NULL) {
01981 
01982       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
01983          break;
01984       if (matches + 1 >= match_list_len) {
01985          match_list_len <<= 1;
01986          if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
01987             /* TODO: Handle memory allocation failure */
01988          }
01989       }
01990 
01991       match_list[matches++] = strdup(retstr);
01992    }
01993 
01994    if (!match_list)
01995       return (char **) NULL;
01996 
01997    if (matches >= match_list_len) {
01998       if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
01999          /* TODO: Handle memory allocation failure */
02000       }
02001    }
02002 
02003    match_list[matches] = (char *) NULL;
02004 
02005    return match_list;
02006 }

static int ast_el_write_history ( char *   )  [static]

Definition at line 2223 of file asterisk.c.

References ast_el_initialize().

Referenced by quit_handler().

02224 {
02225    HistEvent ev;
02226 
02227    if (el_hist == NULL || el == NULL)
02228       ast_el_initialize();
02229 
02230    return (history(el_hist, &ev, H_SAVE, filename));
02231 }

static AST_LIST_HEAD_STATIC ( thread_list  ,
thread_list_t   
) [static]

static AST_LIST_HEAD_STATIC ( file_versions  ,
file_version   
) [static]

static AST_LIST_HEAD_STATIC ( atexits  ,
ast_atexit   
) [static]

static int ast_makesocket ( void   )  [static]

Definition at line 1029 of file asterisk.c.

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

Referenced by main().

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

int64_t ast_mark ( int  i,
int  startstop 
)

Definition at line 431 of file asterisk.c.

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

Referenced by extension_match_core().

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

AST_MUTEX_DEFINE_STATIC ( safe_system_lock   ) 

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

write the string to all attached console clients

Definition at line 881 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

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

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

log the string to all attached console clients

Definition at line 856 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts_mutable(), and network_verboser().

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

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 399 of file asterisk.c.

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

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

static void ast_readconfig ( void   )  [static]

Definition at line 2384 of file asterisk.c.

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

Referenced by main().

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

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

Register a function to be executed before Asterisk exits.

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    struct ast_atexit *ae;
00702 
00703    if (!(ae = ast_calloc(1, sizeof(*ae))))
00704       return -1;
00705 
00706    ae->func = func;
00707 
00708    ast_unregister_atexit(func);  
00709 
00710    AST_LIST_LOCK(&atexits);
00711    AST_LIST_INSERT_HEAD(&atexits, ae, list);
00712    AST_LIST_UNLOCK(&atexits);
00713 
00714    return 0;
00715 }

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

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

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

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

Referenced by main().

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

void ast_replace_sigchld ( void   ) 

Replace the SIGCHLD handler.

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

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

Definition at line 752 of file asterisk.c.

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

Referenced by ast_safe_system().

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

static void ast_run_atexits ( void   )  [static]

Definition at line 1231 of file asterisk.c.

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

Referenced by quit_handler().

01232 {
01233    struct ast_atexit *ae;
01234    AST_LIST_LOCK(&atexits);
01235    AST_LIST_TRAVERSE(&atexits, ae, list) {
01236       if (ae->func) 
01237          ae->func();
01238    }
01239    AST_LIST_UNLOCK(&atexits);
01240 }

int ast_safe_system ( const char *  s  ) 

Safely spawn an external program while closing file descriptors

Note:
This replaces the system call in all Asterisk modules

Definition at line 780 of file asterisk.c.

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

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

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

int ast_set_priority ( int   ) 

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

Provided by asterisk.c

Definition at line 1197 of file asterisk.c.

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

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

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

static int ast_tryconnect ( void   )  [static]

Definition at line 1098 of file asterisk.c.

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

Referenced by ast_el_read_char(), and main().

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

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

Unregister a function registered with ast_register_atexit().

Parameters:
func The callback function to unregister.

Definition at line 717 of file asterisk.c.

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

Referenced by ast_register_atexit(), and do_reload().

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

void ast_unregister_file_version ( const char *  file  ) 

Unregister a source code file from the core.

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

References ast_mutex_lock(), and ast_mutex_unlock().

Referenced by agi_exec_full(), and ast_safe_system().

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

static void child_handler ( int  sig  )  [static]

Definition at line 1144 of file asterisk.c.

Referenced by main().

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

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

Definition at line 2066 of file asterisk.c.

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

Referenced by ast_el_initialize().

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

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

Definition at line 1824 of file asterisk.c.

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

Referenced by ast_el_initialize().

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

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

Definition at line 675 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.

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

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

Definition at line 653 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.

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

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

Definition at line 1373 of file asterisk.c.

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

Referenced by main().

01374 {
01375    char tmp[80];
01376    const char *c = NULL;
01377 
01378    if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
01379        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
01380        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
01381        (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) {
01382       fputs(tmp, stdout);
01383       fputs(c, stdout);
01384    } else
01385       fputs(s, stdout);
01386 
01387    fflush(stdout);
01388    
01389    /* Wake up a poll()ing console */
01390    if (ast_opt_console && consolethread != AST_PTHREADT_NULL)
01391       pthread_kill(consolethread, SIGURG);
01392 }

static void consolehandler ( char *  s  )  [static]

Definition at line 1404 of file asterisk.c.

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

Referenced by main().

01405 {
01406    printf(term_end());
01407    fflush(stdout);
01408 
01409    /* Called when readline data is available */
01410    if (!ast_all_zeros(s))
01411       ast_el_add_history(s);
01412    /* The real handler for bang */
01413    if (s[0] == '!') {
01414       if (s[1])
01415          ast_safe_system(s+1);
01416       else
01417          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
01418    } else 
01419       ast_cli_command(STDOUT_FILENO, s);
01420 }

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

Definition at line 735 of file asterisk.c.

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

00736 {
00737    return write(fd, s, strlen(s) + 1);
00738 }

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

Definition at line 1362 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01363 {
01364    const char *c;
01365    if (!strncmp(s, cmp, strlen(cmp))) {
01366       c = s + strlen(cmp);
01367       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01368       return c;
01369    }
01370    return NULL;
01371 }

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

Definition at line 1574 of file asterisk.c.

References ast_cancel_shutdown(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01575 {
01576    if (argc != 2)
01577       return RESULT_SHOWUSAGE;
01578    ast_cancel_shutdown();
01579    shuttingdown = 0;
01580    return RESULT_SUCCESS;
01581 }

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

Definition at line 1583 of file asterisk.c.

References RESULT_SUCCESS.

01584 {
01585    return RESULT_SUCCESS;
01586 }

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

Definition at line 1557 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01558 {
01559    if (argc != 2)
01560       return RESULT_SHOWUSAGE;
01561    quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
01562    return RESULT_SUCCESS;
01563 }

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

Definition at line 1549 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1565 of file asterisk.c.

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

01566 {
01567    if (argc != 3)
01568       return RESULT_SHOWUSAGE;
01569    ast_cli(fd, "Waiting for inactivity to perform restart\n");
01570    quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */);
01571    return RESULT_SUCCESS;
01572 }

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

Definition at line 493 of file asterisk.c.

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

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

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

Definition at line 447 of file asterisk.c.

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

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

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

Definition at line 335 of file asterisk.c.

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

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

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

Definition at line 599 of file asterisk.c.

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

00600 {
00601 #define FORMAT "%-25.25s %-40.40s\n"
00602    struct file_version *iterator;
00603    regex_t regexbuf;
00604    int havepattern = 0;
00605    int havename = 0;
00606    int count_files = 0;
00607 
00608    switch (argc) {
00609    case 6:
00610       if (!strcasecmp(argv[4], "like")) {
00611          if (regcomp(&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 1532 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01533 {
01534    if (argc != 2)
01535       return RESULT_SHOWUSAGE;
01536    quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
01537    return RESULT_SUCCESS;
01538 }

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

Definition at line 1524 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1540 of file asterisk.c.

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

01541 {
01542    if (argc != 3)
01543       return RESULT_SHOWUSAGE;
01544    ast_cli(fd, "Waiting for inactivity to perform halt\n");
01545    quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
01546    return RESULT_SUCCESS;
01547 }

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

Definition at line 1504 of file asterisk.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01505 {
01506    if (argc != 3)
01507       return RESULT_SHOWUSAGE;
01508    ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
01509       ASTERISK_VERSION, ast_build_user, ast_build_hostname,
01510       ast_build_machine, ast_build_os, ast_build_date);
01511    return RESULT_SUCCESS;
01512 }

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

Definition at line 1494 of file asterisk.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

static void hup_handler ( int  num  )  [static]

Definition at line 1131 of file asterisk.c.

References sig_flags.

Referenced by main().

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

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

Definition at line 963 of file asterisk.c.

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

Referenced by ast_makesocket().

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

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

Definition at line 2566 of file asterisk.c.

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

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

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

Definition at line 2546 of file asterisk.c.

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

Referenced by main().

02547 {
02548    for (;;) {
02549       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
02550       int a;
02551       poll(&p, 1, -1);
02552       if (sig_flags.need_reload) {
02553          sig_flags.need_reload = 0;
02554          ast_module_reload(NULL);
02555       }
02556       if (sig_flags.need_quit) {
02557          sig_flags.need_quit = 0;
02558          quit_handler(0, 0, 1, 0);
02559       }
02560       read(sig_alert_pipe[0], &a, sizeof(a));
02561    }
02562 
02563    return NULL;
02564 }

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

Definition at line 908 of file asterisk.c.

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

Referenced by listener().

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

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

Definition at line 901 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by ast_makesocket().

00902 {
00903    ast_network_puts_mutable(s);
00904 }

static void null_sig_handler ( int  signal  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 741 of file asterisk.c.

Referenced by ast_replace_sigchld().

00742 {
00743 
00744 }

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

Definition at line 1242 of file asterisk.c.

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

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

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

static __inline uint64_t rdtsc ( void   )  [static]

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

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

Referenced by ast_remotecontrol().

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

static void set_icon ( char *  text  )  [static]

Definition at line 1189 of file asterisk.c.

Referenced by main().

01190 {
01191    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
01192       fprintf(stdout, "\033]1;%s\007", text);
01193 }

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1183 of file asterisk.c.

Referenced by main().

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

static void set_ulimit ( int  value  )  [static]

Set maximum open files.

Definition at line 1160 of file asterisk.c.

References ast_log(), errno, LOG_NOTICE, and LOG_WARNING.

01161 {
01162    struct rlimit l = {0, 0};
01163    
01164    if (value <= 0) {
01165       ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
01166       return;
01167    }
01168    
01169    l.rlim_cur = value;
01170    l.rlim_max = value;
01171    
01172    if (setrlimit(RLIMIT_NOFILE, &l)) {
01173       ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
01174       return;
01175    }
01176    
01177    ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
01178    
01179    return;
01180 }

static int show_cli_help ( void   )  [static]

Definition at line 2348 of file asterisk.c.

Referenced by main().

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

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

Definition at line 1641 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

01642 {
01643    int x;
01644 
01645    for (x = 0; x < sizeof(license_lines) / sizeof(license_lines[0]); x++)
01646       ast_cli(fd, (char *) license_lines[x]);
01647 
01648    return RESULT_SUCCESS;
01649 }

static int show_version ( void   )  [static]

Definition at line 2342 of file asterisk.c.

Referenced by main().

02343 {
02344    printf("Asterisk " ASTERISK_VERSION "\n");
02345    return 0;
02346 }

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

Definition at line 1612 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

01613 {
01614    int x;
01615 
01616    for (x = 0; x < sizeof(warranty_lines) / sizeof(warranty_lines[0]); x++)
01617       ast_cli(fd, (char *) warranty_lines[x]);
01618 
01619    return RESULT_SUCCESS;
01620 }

static void urg_handler ( int  num  )  [static]

Urgent handler.

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

Definition at line 1125 of file asterisk.c.

Referenced by main().

01126 {
01127    signal(num, urg_handler);
01128    return;
01129 }


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

const char* ast_build_date

Definition at line 32 of file buildinfo.c.

const char* ast_build_hostname

Definition at line 28 of file buildinfo.c.

const char* ast_build_kernel

Definition at line 29 of file buildinfo.c.

const char* ast_build_machine

Definition at line 30 of file buildinfo.c.

const char* ast_build_os

Definition at line 31 of file buildinfo.c.

const char* ast_build_user

Definition at line 33 of file buildinfo.c.

char ast_config_AST_AGI_DIR[PATH_MAX]

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(), and realtime_update_peer().

char ast_config_AST_VAR_DIR[PATH_MAX]

Definition at line 207 of file asterisk.c.

Referenced by ael2_semantic_check(), and launch_script().

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

Definition at line 171 of file asterisk.c.

time_t ast_lastreloadtime

Definition at line 188 of file asterisk.c.

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

pid_t ast_mainpid

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

struct ast_cli_entry cli_asterisk[] [static]

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

struct ast_cli_entry cli_show_profile_deprecated [static]

Initial value:

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

Definition at line 1666 of file asterisk.c.

struct ast_cli_entry cli_show_version_deprecated [static]

Initial value:

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

Definition at line 1655 of file asterisk.c.

struct ast_cli_entry cli_show_version_files_deprecated [static]

Initial value:

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

Definition at line 1661 of file asterisk.c.

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

pthread_t lthread [static]

Definition at line 906 of file asterisk.c.

unsigned int need_quit

Definition at line 241 of file asterisk.c.

unsigned int need_reload

Definition at line 240 of file asterisk.c.

struct profile_data* prof_data [static]

Definition at line 364 of file asterisk.c.

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

char randompool[256] [static]

Definition at line 236 of file asterisk.c.

char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR

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

char restart_now_help[] [static]

Initial value:

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

Definition at line 1464 of file asterisk.c.

char restart_when_convenient_help[] [static]

Initial value:

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

Definition at line 1474 of file asterisk.c.

int restartnow [static]

Definition at line 233 of file asterisk.c.

unsigned int safe_system_level = 0 [static]

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

Definition at line 749 of file asterisk.c.

void* safe_system_prev_handler [static]

Definition at line 750 of file asterisk.c.

char show_license_help[] [static]

Initial value:

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

Definition at line 1486 of file asterisk.c.

char show_threads_help[] [static]

Initial value:

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

Definition at line 299 of file asterisk.c.

char show_version_files_help[] [static]

Initial value:

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

Definition at line 539 of file asterisk.c.

char show_warranty_help[] [static]

Initial value:

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

Definition at line 1482 of file asterisk.c.

char shutdown_gracefully_help[] [static]

Initial value:

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

Definition at line 1455 of file asterisk.c.

char shutdown_now_help[] [static]

Initial value:

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

Definition at line 1451 of file asterisk.c.

char shutdown_when_convenient_help[] [static]

Initial value:

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

Definition at line 1460 of file asterisk.c.

int shuttingdown [static]

Definition at line 232 of file asterisk.c.

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

Definition at line 238 of file asterisk.c.

struct { ... } sig_flags [static]

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

char version_help[] [static]

Initial value:

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

Definition at line 1490 of file asterisk.c.

const char* warranty_lines[] [static]

Definition at line 1587 of file asterisk.c.


Generated on Mon Mar 31 07:39:00 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1