Sun Jun 12 16:37:51 2011

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

Variables

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

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

#define AST_MAX_CONNECTS   128

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 1654 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2   "%s*CLI> "

Definition at line 1656 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"

#define NUM_MSGS   64

Definition at line 144 of file asterisk.c.

#define PF_LOCAL   PF_UNIX

Definition at line 140 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 147 of file asterisk.c.

Referenced by ast_el_read_char(), and main().


Function Documentation

static void __quit_handler ( int  num  )  [static]

Definition at line 1345 of file asterisk.c.

References sig_flags.

Referenced by main().

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

int ast_add_profile ( const char *  name,
uint64_t  scale 
)

allocates a counter with a given name and scale.

support for event profiling

Returns:
Returns the identifier of the counter.

Definition at line 378 of file asterisk.c.

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

Referenced by extension_match_core().

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

static int ast_all_zeros ( char *  s  )  [static]

Definition at line 1397 of file asterisk.c.

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

01398 {
01399    while (*s) {
01400       if (*s > 32)
01401          return 0;
01402       s++;  
01403    }
01404    return 1;
01405 }

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

Definition at line 2031 of file asterisk.c.

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

Referenced by cli_complete().

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

void ast_console_puts ( const char *  string  ) 

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

Definition at line 910 of file asterisk.c.

References ast_network_puts().

Referenced by chan_misdn_log().

00911 {
00912    fputs(string, stdout);
00913    fflush(stdout);
00914    ast_network_puts(string);
00915 }

void ast_console_puts_mutable ( const char *  string  ) 

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

Definition at line 887 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by ast_log().

00888 {
00889    fputs(string, stdout);
00890    fflush(stdout);
00891    ast_network_puts_mutable(string);
00892 }

void ast_console_toggle_mute ( int  fd,
int  silent 
)

mute or unmute a console from logging

Definition at line 850 of file asterisk.c.

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

Referenced by handle_logger_mute().

00850                                                  {
00851    int x;
00852    for (x = 0;x < AST_MAX_CONNECTS; x++) {
00853       if (fd == consoles[x].fd) {
00854          if (consoles[x].mute) {
00855             consoles[x].mute = 0;
00856             if (!silent)
00857                ast_cli(fd, "Console is not muted anymore.\n");
00858          } else {
00859             consoles[x].mute = 1;
00860             if (!silent)
00861                ast_cli(fd, "Console is muted.\n");
00862          }
00863          return;
00864       }
00865    }
00866    ast_cli(fd, "Couldn't find remote console.\n");
00867 }

static int ast_el_add_history ( char *  buf  )  [static]

Definition at line 2225 of file asterisk.c.

References ast_el_initialize().

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

02226 {
02227    HistEvent ev;
02228 
02229    if (el_hist == NULL || el == NULL)
02230       ast_el_initialize();
02231    if (strlen(buf) > 256)
02232       return 0;
02233    return (history(el_hist, &ev, H_ENTER, buf));
02234 }

static int ast_el_initialize ( void   )  [static]

Definition at line 2190 of file asterisk.c.

References cli_complete(), and cli_prompt().

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

02191 {
02192    HistEvent ev;
02193    char *editor = getenv("AST_EDITOR");
02194 
02195    if (el != NULL)
02196       el_end(el);
02197    if (el_hist != NULL)
02198       history_end(el_hist);
02199 
02200    el = el_init("asterisk", stdin, stdout, stderr);
02201    el_set(el, EL_PROMPT, cli_prompt);
02202 
02203    el_set(el, EL_EDITMODE, 1);      
02204    el_set(el, EL_EDITOR, editor ? editor : "emacs");     
02205    el_hist = history_init();
02206    if (!el || !el_hist)
02207       return -1;
02208 
02209    /* setup history with 100 entries */
02210    history(el_hist, &ev, H_SETSIZE, 100);
02211 
02212    el_set(el, EL_HIST, history, el_hist);
02213 
02214    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
02215    /* Bind <tab> to command completion */
02216    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
02217    /* Bind ? to command completion */
02218    el_set(el, EL_BIND, "?", "ed-complete", NULL);
02219    /* Bind ^D to redisplay */
02220    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
02221 
02222    return 0;
02223 }

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

Definition at line 1743 of file asterisk.c.

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

Referenced by ast_remotecontrol().

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

static int ast_el_read_history ( char *  filename  )  [static]

Definition at line 2246 of file asterisk.c.

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

Referenced by ast_remotecontrol(), and main().

02247 {
02248    char buf[256];
02249    FILE *f;
02250    int ret = -1;
02251 
02252    if (el_hist == NULL || el == NULL)
02253       ast_el_initialize();
02254 
02255    if ((f = fopen(filename, "r")) == NULL)
02256       return ret;
02257 
02258    while (!feof(f)) {
02259       fgets(buf, sizeof(buf), f);
02260       if (!strcmp(buf, "_HiStOrY_V2_\n"))
02261          continue;
02262       if (ast_all_zeros(buf))
02263          continue;
02264       if ((ret = ast_el_add_history(buf)) == -1)
02265          break;
02266    }
02267    fclose(f);
02268 
02269    return ret;
02270 }

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

Definition at line 2021 of file asterisk.c.

Referenced by ast_cli_display_match_list().

02022 {
02023    char *s1, *s2;
02024 
02025    s1 = ((char **)i1)[0];
02026    s2 = ((char **)i2)[0];
02027 
02028    return strcasecmp(s1, s2);
02029 }

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

Definition at line 1986 of file asterisk.c.

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

Referenced by cli_complete().

01987 {
01988    char **match_list = NULL, *retstr;
01989    size_t match_list_len;
01990    int matches = 0;
01991 
01992    match_list_len = 1;
01993    while ( (retstr = strsep(&buf, " ")) != NULL) {
01994 
01995       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
01996          break;
01997       if (matches + 1 >= match_list_len) {
01998          match_list_len <<= 1;
01999          if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
02000             /* TODO: Handle memory allocation failure */
02001          }
02002       }
02003 
02004       match_list[matches++] = strdup(retstr);
02005    }
02006 
02007    if (!match_list)
02008       return (char **) NULL;
02009 
02010    if (matches >= match_list_len) {
02011       if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
02012          /* TODO: Handle memory allocation failure */
02013       }
02014    }
02015 
02016    match_list[matches] = (char *) NULL;
02017 
02018    return match_list;
02019 }

static int ast_el_write_history ( char *  filename  )  [static]

Definition at line 2236 of file asterisk.c.

References ast_el_initialize().

Referenced by quit_handler().

02237 {
02238    HistEvent ev;
02239 
02240    if (el_hist == NULL || el == NULL)
02241       ast_el_initialize();
02242 
02243    return (history(el_hist, &ev, H_SAVE, filename));
02244 }

static AST_LIST_HEAD_STATIC ( thread_list  ,
thread_list_t   
) [static]

static AST_LIST_HEAD_STATIC ( file_versions  ,
file_version   
) [static]

static AST_LIST_HEAD_STATIC ( atexits  ,
ast_atexit   
) [static]

static int ast_makesocket ( void   )  [static]

Definition at line 1045 of file asterisk.c.

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

Referenced by main().

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

int64_t ast_mark ( int  i,
int  startstop 
)

Definition at line 440 of file asterisk.c.

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

Referenced by extension_match_core().

00441 {
00442    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00443       return 0;
00444    if (startstop == 1)
00445       prof_data->e[i].mark = rdtsc();
00446    else {
00447       prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
00448       if (prof_data->e[i].scale > 1)
00449          prof_data->e[i].mark /= prof_data->e[i].scale;
00450       prof_data->e[i].value += prof_data->e[i].mark;
00451       prof_data->e[i].events++;
00452    }
00453    return prof_data->e[i].mark;
00454 }

AST_MUTEX_DEFINE_STATIC ( safe_system_lock   ) 

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

write the string to all attached console clients

Definition at line 897 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts().

00898 {
00899    int x;
00900    for (x=0; x < AST_MAX_CONNECTS; x++) {
00901       if (consoles[x].fd > -1) 
00902          fdprint(consoles[x].p[1], string);
00903    }
00904 }

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

log the string to all attached console clients

Definition at line 872 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts_mutable(), and network_verboser().

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

int64_t ast_profile ( int  i,
int64_t  delta 
)

Definition at line 408 of file asterisk.c.

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

00409 {
00410    if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
00411       return 0;
00412    if (prof_data->e[i].scale > 1)
00413       delta /= prof_data->e[i].scale;
00414    prof_data->e[i].value += delta;
00415    prof_data->e[i].events++;
00416    return prof_data->e[i].value;
00417 }

static void ast_readconfig ( void   )  [static]

Definition at line 2430 of file asterisk.c.

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

Referenced by main().

02431 {
02432    struct ast_config *cfg;
02433    struct ast_variable *v;
02434    char *config = AST_CONFIG_FILE;
02435 
02436    if (ast_opt_override_config) {
02437       cfg = ast_config_load(ast_config_AST_CONFIG_FILE);
02438       if (!cfg)
02439          ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
02440    } else {
02441       cfg = ast_config_load(config);
02442    }
02443 
02444    /* init with buildtime config */
02445    ast_copy_string(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR, sizeof(ast_config_AST_CONFIG_DIR));
02446    ast_copy_string(ast_config_AST_SPOOL_DIR, AST_SPOOL_DIR, sizeof(ast_config_AST_SPOOL_DIR));
02447    ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_MODULE_DIR));
02448    snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR);
02449    ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR));
02450    ast_copy_string(ast_config_AST_DATA_DIR, AST_DATA_DIR, sizeof(ast_config_AST_DATA_DIR));
02451    ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR));
02452    ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR));
02453    ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB));
02454    ast_copy_string(ast_config_AST_KEY_DIR, AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR));
02455    ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID));
02456    ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET));
02457    ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR));
02458    ast_copy_string(ast_config_AST_SYSTEM_NAME, AST_SYSTEM_NAME, sizeof(ast_config_AST_SYSTEM_NAME));
02459 
02460    /* no asterisk.conf? no problem, use buildtime config! */
02461    if (!cfg) {
02462       return;
02463    }
02464 
02465    for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
02466       if (!strcasecmp(v->name, "astctlpermissions")) {
02467          ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
02468       } else if (!strcasecmp(v->name, "astctlowner")) {
02469          ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
02470       } else if (!strcasecmp(v->name, "astctlgroup")) {
02471          ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
02472       } else if (!strcasecmp(v->name, "astctl")) {
02473          ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
02474       }
02475    }
02476 
02477    for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
02478       if (!strcasecmp(v->name, "astetcdir")) {
02479          ast_copy_string(ast_config_AST_CONFIG_DIR, v->value, sizeof(ast_config_AST_CONFIG_DIR));
02480       } else if (!strcasecmp(v->name, "astspooldir")) {
02481          ast_copy_string(ast_config_AST_SPOOL_DIR, v->value, sizeof(ast_config_AST_SPOOL_DIR));
02482          snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", v->value);
02483       } else if (!strcasecmp(v->name, "astvarlibdir")) {
02484          ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR));
02485          snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/astdb", v->value);
02486       } else if (!strcasecmp(v->name, "astdatadir")) {
02487          ast_copy_string(ast_config_AST_DATA_DIR, v->value, sizeof(ast_config_AST_DATA_DIR));
02488          snprintf(ast_config_AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR), "%s/keys", v->value);
02489       } else if (!strcasecmp(v->name, "astlogdir")) {
02490          ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR));
02491       } else if (!strcasecmp(v->name, "astagidir")) {
02492          ast_copy_string(ast_config_AST_AGI_DIR, v->value, sizeof(ast_config_AST_AGI_DIR));
02493       } else if (!strcasecmp(v->name, "astrundir")) {
02494          snprintf(ast_config_AST_PID, sizeof(ast_config_AST_PID), "%s/%s", v->value, "asterisk.pid");
02495          snprintf(ast_config_AST_SOCKET, sizeof(ast_config_AST_SOCKET), "%s/%s", v->value, ast_config_AST_CTL);
02496          ast_copy_string(ast_config_AST_RUN_DIR, v->value, sizeof(ast_config_AST_RUN_DIR));
02497       } else if (!strcasecmp(v->name, "astmoddir")) {
02498          ast_copy_string(ast_config_AST_MODULE_DIR, v->value, sizeof(ast_config_AST_MODULE_DIR));
02499       }
02500    }
02501 
02502    for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
02503       /* verbose level (-v at startup) */
02504       if (!strcasecmp(v->name, "verbose")) {
02505          option_verbose = atoi(v->value);
02506       /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
02507       } else if (!strcasecmp(v->name, "timestamp")) {
02508          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
02509       /* whether or not to support #exec in config files */
02510       } else if (!strcasecmp(v->name, "execincludes")) {
02511          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
02512       /* debug level (-d at startup) */
02513       } else if (!strcasecmp(v->name, "debug")) {
02514          option_debug = 0;
02515          if (sscanf(v->value, "%d", &option_debug) != 1) {
02516             option_debug = ast_true(v->value);
02517          }
02518 #if HAVE_WORKING_FORK
02519       /* Disable forking (-f at startup) */
02520       } else if (!strcasecmp(v->name, "nofork")) {
02521          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
02522       /* Always fork, even if verbose or debug are enabled (-F at startup) */
02523       } else if (!strcasecmp(v->name, "alwaysfork")) {
02524          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
02525 #endif
02526       /* Run quietly (-q at startup ) */
02527       } else if (!strcasecmp(v->name, "quiet")) {
02528          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
02529       /* Run as console (-c at startup, implies nofork) */
02530       } else if (!strcasecmp(v->name, "console")) {
02531          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CONSOLE);
02532       /* Run with high priority if the O/S permits (-p at startup) */
02533       } else if (!strcasecmp(v->name, "highpriority")) {
02534          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
02535       /* Initialize RSA auth keys (IAX2) (-i at startup) */
02536       } else if (!strcasecmp(v->name, "initcrypto")) {
02537          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
02538       /* Disable ANSI colors for console (-c at startup) */
02539       } else if (!strcasecmp(v->name, "nocolor")) {
02540          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
02541       /* Disable some usage warnings for picky people :p */
02542       } else if (!strcasecmp(v->name, "dontwarn")) {
02543          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
02544       /* Dump core in case of crash (-g) */
02545       } else if (!strcasecmp(v->name, "dumpcore")) {
02546          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
02547       /* Cache recorded sound files to another directory during recording */
02548       } else if (!strcasecmp(v->name, "cache_record_files")) {
02549          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
02550       /* Specify cache directory */
02551       }  else if (!strcasecmp(v->name, "record_cache_dir")) {
02552          ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
02553       /* Build transcode paths via SLINEAR, instead of directly */
02554       } else if (!strcasecmp(v->name, "transcode_via_sln")) {
02555          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
02556       /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
02557       } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
02558          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
02559       /* Enable internal timing */
02560       } else if (!strcasecmp(v->name, "internal_timing")) {
02561          ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING);
02562       } else if (!strcasecmp(v->name, "maxcalls")) {
02563          if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
02564             option_maxcalls = 0;
02565          }
02566       } else if (!strcasecmp(v->name, "maxload")) {
02567          double test[1];
02568 
02569          if (getloadavg(test, 1) == -1) {
02570             ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
02571             option_maxload = 0.0;
02572          } else if ((sscanf(v->value, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
02573             option_maxload = 0.0;
02574          }
02575       /* What user to run as */
02576       } else if (!strcasecmp(v->name, "runuser")) {
02577          ast_copy_string(ast_config_AST_RUN_USER, v->value, sizeof(ast_config_AST_RUN_USER));
02578       /* What group to run as */
02579       } else if (!strcasecmp(v->name, "rungroup")) {
02580          ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP));
02581       } else if (!strcasecmp(v->name, "systemname")) {
02582          ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME));
02583       } else if (!strcasecmp(v->name, "uniquename")) {
02584          ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME));
02585       } else if (!strcasecmp(v->name, "languageprefix")) {
02586          ast_language_is_prefix = ast_true(v->value);
02587       }
02588    }
02589    ast_config_destroy(cfg);
02590 }

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

Register a function to be executed before Asterisk exits.

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

Definition at line 708 of file asterisk.c.

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

Referenced by do_reload(), and load_module().

00709 {
00710    struct ast_atexit *ae;
00711 
00712    if (!(ae = ast_calloc(1, sizeof(*ae))))
00713       return -1;
00714 
00715    ae->func = func;
00716 
00717    ast_unregister_atexit(func);  
00718 
00719    AST_LIST_LOCK(&atexits);
00720    AST_LIST_INSERT_HEAD(&atexits, ae, list);
00721    AST_LIST_UNLOCK(&atexits);
00722 
00723    return 0;
00724 }

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

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

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

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

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

void ast_register_thread ( char *  name  ) 

Definition at line 312 of file asterisk.c.

References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, and AST_LIST_UNLOCK.

Referenced by dummy_start().

00313 { 
00314    struct thread_list_t *new = ast_calloc(1, sizeof(*new));
00315 
00316    if (!new)
00317       return;
00318    new->id = pthread_self();
00319    new->name = name; /* steal the allocated memory for the thread name */
00320    AST_LIST_LOCK(&thread_list);
00321    AST_LIST_INSERT_HEAD(&thread_list, new, list);
00322    AST_LIST_UNLOCK(&thread_list);
00323 }

static void ast_remotecontrol ( char *  data  )  [static]

Definition at line 2272 of file asterisk.c.

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

Referenced by main().

02273 {
02274    char buf[80];
02275    int res;
02276    char filename[80] = "";
02277    char *hostname;
02278    char *cpid;
02279    char *version;
02280    int pid;
02281    char tmp[80];
02282    char *stringp = NULL;
02283 
02284    char *ebuf;
02285    int num = 0;
02286 
02287    read(ast_consock, buf, sizeof(buf));
02288    if (data)
02289       write(ast_consock, data, strlen(data) + 1);
02290    stringp = buf;
02291    hostname = strsep(&stringp, "/");
02292    cpid = strsep(&stringp, "/");
02293    version = strsep(&stringp, "\n");
02294    if (!version)
02295       version = "<Version Unknown>";
02296    stringp = hostname;
02297    strsep(&stringp, ".");
02298    if (cpid)
02299       pid = atoi(cpid);
02300    else
02301       pid = -1;
02302    if (!data) {
02303       snprintf(tmp, sizeof(tmp), "core set verbose atleast %d", option_verbose);
02304       fdsend(ast_consock, tmp);
02305       snprintf(tmp, sizeof(tmp), "core set debug atleast %d", option_debug);
02306       fdsend(ast_consock, tmp);
02307       if (!ast_opt_mute)
02308          fdsend(ast_consock, "logger mute silent");
02309       else 
02310          printf("log and verbose output currently muted ('logger mute' to unmute)\n");
02311    }
02312    ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
02313    remotehostname = hostname;
02314    if (getenv("HOME")) 
02315       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
02316    if (el_hist == NULL || el == NULL)
02317       ast_el_initialize();
02318 
02319    el_set(el, EL_GETCFN, ast_el_read_char);
02320 
02321    if (!ast_strlen_zero(filename))
02322       ast_el_read_history(filename);
02323 
02324    if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
02325       struct pollfd fds;
02326       fds.fd = ast_consock;
02327       fds.events = POLLIN;
02328       fds.revents = 0;
02329       while (poll(&fds, 1, 500) > 0) {
02330          char buf[512] = "", *curline = buf, *nextline;
02331          int not_written = 1;
02332 
02333          if (read(ast_consock, buf, sizeof(buf) - 1) <= 0) {
02334             break;
02335          }
02336 
02337          do {
02338             if ((nextline = strchr(curline, '\n'))) {
02339                nextline++;
02340             } else {
02341                nextline = strchr(curline, '\0');
02342             }
02343 
02344             /* Skip verbose lines */
02345             if (*curline != 127) {
02346                not_written = 0;
02347                write(STDOUT_FILENO, curline, nextline - curline);
02348             }
02349             curline = nextline;
02350          } while (!ast_strlen_zero(curline));
02351 
02352          /* No non-verbose output in 500ms */
02353          if (not_written) {
02354             break;
02355          }
02356       }
02357       return;
02358    }
02359    for (;;) {
02360       ebuf = (char *)el_gets(el, &num);
02361 
02362       if (!ebuf && write(1, "", 1) < 0)
02363          break;
02364 
02365       if (!ast_strlen_zero(ebuf)) {
02366          if (ebuf[strlen(ebuf)-1] == '\n')
02367             ebuf[strlen(ebuf)-1] = '\0';
02368          if (!remoteconsolehandler(ebuf)) {
02369             /* Strip preamble from output */
02370             char *tmp;
02371             for (tmp = ebuf; *tmp; tmp++) {
02372                if (*tmp == 127) {
02373                   memmove(tmp, tmp + 1, strlen(tmp));
02374                   tmp--;
02375                }
02376             }
02377             res = write(ast_consock, ebuf, strlen(ebuf) + 1);
02378             if (res < 1) {
02379                ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
02380                break;
02381             }
02382          }
02383       }
02384    }
02385    printf("\nDisconnected from Asterisk server\n");
02386 }

void ast_replace_sigchld ( void   ) 

Replace the SIGCHLD handler.

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

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

Definition at line 768 of file asterisk.c.

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

Referenced by agi_exec_full(), and ast_safe_system().

00769 {
00770    unsigned int level;
00771 
00772    ast_mutex_lock(&safe_system_lock);
00773    level = safe_system_level++;
00774 
00775    /* only replace the handler if it has not already been done */
00776    if (level == 0)
00777       safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
00778 
00779    ast_mutex_unlock(&safe_system_lock);
00780 }

static void ast_run_atexits ( void   )  [static]

Definition at line 1224 of file asterisk.c.

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

Referenced by quit_handler().

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

int ast_safe_system ( const char *  s  ) 

Safely spawn an external program while closing file descriptors

Note:
This replaces the system call in all Asterisk modules

Definition at line 796 of file asterisk.c.

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

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

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

int ast_set_priority ( int   ) 

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

Provided by asterisk.c

Definition at line 1190 of file asterisk.c.

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

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

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

static int ast_tryconnect ( void   )  [static]

Definition at line 1114 of file asterisk.c.

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

Referenced by ast_el_read_char(), and main().

01115 {
01116    struct sockaddr_un sunaddr;
01117    int res;
01118    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
01119    if (ast_consock < 0) {
01120       ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
01121       return 0;
01122    }
01123    memset(&sunaddr, 0, sizeof(sunaddr));
01124    sunaddr.sun_family = AF_LOCAL;
01125    ast_copy_string(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
01126    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
01127    if (res) {
01128       close(ast_consock);
01129       ast_consock = -1;
01130       return 0;
01131    } else
01132       return 1;
01133 }

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

Unregister a function registered with ast_register_atexit().

Parameters:
func The callback function to unregister.

Definition at line 726 of file asterisk.c.

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

Referenced by ast_register_atexit(), and do_reload().

00727 {
00728    struct ast_atexit *ae = NULL;
00729 
00730    AST_LIST_LOCK(&atexits);
00731    AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
00732       if (ae->func == func) {
00733          AST_LIST_REMOVE_CURRENT(&atexits, list);
00734          break;
00735       }
00736    }
00737    AST_LIST_TRAVERSE_SAFE_END
00738    AST_LIST_UNLOCK(&atexits);
00739 
00740    if (ae)
00741       free(ae);
00742 }

void ast_unregister_file_version ( const char *  file  ) 

Unregister a source code file from the core.

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

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

00284 {
00285    struct file_version *find;
00286 
00287    AST_LIST_LOCK(&file_versions);
00288    AST_LIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) {
00289       if (!strcasecmp(find->file, file)) {
00290          AST_LIST_REMOVE_CURRENT(&file_versions, list);
00291          break;
00292       }
00293    }
00294    AST_LIST_TRAVERSE_SAFE_END;
00295    AST_LIST_UNLOCK(&file_versions);
00296    if (find)
00297       free(find);
00298 }

void ast_unregister_thread ( void *  id  ) 

Definition at line 325 of file asterisk.c.

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

Referenced by dummy_start().

00326 {
00327    struct thread_list_t *x;
00328 
00329    AST_LIST_LOCK(&thread_list);
00330    AST_LIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
00331       if ((void *) x->id == id) {
00332          AST_LIST_REMOVE_CURRENT(&thread_list, list);
00333          break;
00334       }
00335    }
00336    AST_LIST_TRAVERSE_SAFE_END;
00337    AST_LIST_UNLOCK(&thread_list);
00338    if (x) {
00339       free(x->name);
00340       free(x);
00341    }
00342 }

void ast_unreplace_sigchld ( void   ) 

Restore the SIGCHLD handler.

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

Definition at line 782 of file asterisk.c.

References ast_mutex_lock(), and ast_mutex_unlock().

Referenced by agi_exec_full(), and ast_safe_system().

00783 {
00784    unsigned int level;
00785 
00786    ast_mutex_lock(&safe_system_lock);
00787    level = --safe_system_level;
00788 
00789    /* only restore the handler if we are the last one */
00790    if (level == 0)
00791       signal(SIGCHLD, safe_system_prev_handler);
00792 
00793    ast_mutex_unlock(&safe_system_lock);
00794 }

static void child_handler ( int  sig  )  [static]

Definition at line 1160 of file asterisk.c.

Referenced by main().

01161 {
01162    /* Must not ever ast_log or ast_verbose within signal handler */
01163    int n, status;
01164 
01165    /*
01166     * Reap all dead children -- not just one
01167     */
01168    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
01169       ;
01170    if (n == 0 && option_debug)   
01171       printf("Huh?  Child handler, but nobody there?\n");
01172    signal(sig, child_handler);
01173 }

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

Definition at line 2079 of file asterisk.c.

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

Referenced by ast_el_initialize().

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

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

Definition at line 1837 of file asterisk.c.

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

Referenced by ast_el_initialize().

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

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

Definition at line 684 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.

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

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

Definition at line 662 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.

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

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

Definition at line 1372 of file asterisk.c.

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

Referenced by main().

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

static void consolehandler ( char *  s  )  [static]

Definition at line 1407 of file asterisk.c.

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

Referenced by main().

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

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

Definition at line 751 of file asterisk.c.

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

00752 {
00753    return write(fd, s, strlen(s));
00754 }

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

Definition at line 745 of file asterisk.c.

Referenced by ast_el_read_char(), ast_remotecontrol(), and cli_complete().

00746 {
00747    return write(fd, s, strlen(s) + 1);
00748 }

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

Definition at line 1355 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

01356 {
01357    const char *c;
01358 
01359    /* Check for verboser preamble */
01360    if (*s == 127) {
01361       s++;
01362    }
01363 
01364    if (!strncmp(s, cmp, strlen(cmp))) {
01365       c = s + strlen(cmp);
01366       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
01367       return c;
01368    }
01369    return NULL;
01370 }

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

Definition at line 1577 of file asterisk.c.

References ast_cancel_shutdown(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01578 {
01579    if (argc != 2)
01580       return RESULT_SHOWUSAGE;
01581    ast_cancel_shutdown();
01582    shuttingdown = 0;
01583    return RESULT_SUCCESS;
01584 }

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

Definition at line 1586 of file asterisk.c.

References RESULT_SUCCESS.

01587 {
01588    return RESULT_SUCCESS;
01589 }

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

Definition at line 1560 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1552 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1568 of file asterisk.c.

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

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

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

Definition at line 502 of file asterisk.c.

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

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

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

Definition at line 456 of file asterisk.c.

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

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

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

Definition at line 344 of file asterisk.c.

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

00345 {
00346    int count = 0;
00347    struct thread_list_t *cur;
00348 
00349    AST_LIST_LOCK(&thread_list);
00350    AST_LIST_TRAVERSE(&thread_list, cur, list) {
00351       ast_cli(fd, "%p %s\n", (void *)cur->id, cur->name);
00352       count++;
00353    }
00354         AST_LIST_UNLOCK(&thread_list);
00355    ast_cli(fd, "%d threads listed.\n", count);
00356    return 0;
00357 }

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

Definition at line 608 of file asterisk.c.

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

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

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

CLI command to list module versions.

Definition at line 554 of file asterisk.c.

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

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

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

Definition at line 1535 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1527 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1543 of file asterisk.c.

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

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

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

Definition at line 1507 of file asterisk.c.

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

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

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

Definition at line 1497 of file asterisk.c.

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

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

static void hup_handler ( int  num  )  [static]

Definition at line 1147 of file asterisk.c.

References sig_flags.

Referenced by main().

01148 {
01149    int a = 0;
01150    if (option_verbose > 1) 
01151       printf("Received HUP signal -- Reloading configs\n");
01152    if (restartnow)
01153       execvp(_argv[0], _argv);
01154    sig_flags.need_reload = 1;
01155    if (sig_alert_pipe[1] != -1)
01156       write(sig_alert_pipe[1], &a, sizeof(a));
01157    signal(num, hup_handler);
01158 }

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

Definition at line 979 of file asterisk.c.

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

Referenced by ast_makesocket().

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

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

Definition at line 2612 of file asterisk.c.

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

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

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

Definition at line 2592 of file asterisk.c.

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

Referenced by main().

02593 {
02594    for (;;) {
02595       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
02596       int a;
02597       poll(&p, 1, -1);
02598       if (sig_flags.need_reload) {
02599          sig_flags.need_reload = 0;
02600          ast_module_reload(NULL);
02601       }
02602       if (sig_flags.need_quit) {
02603          sig_flags.need_quit = 0;
02604          quit_handler(0, 0, 1, 0);
02605       }
02606       read(sig_alert_pipe[0], &a, sizeof(a));
02607    }
02608 
02609    return NULL;
02610 }

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

Definition at line 924 of file asterisk.c.

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

Referenced by listener().

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

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

Definition at line 917 of file asterisk.c.

References ast_network_puts_mutable().

Referenced by ast_makesocket().

00918 {
00919    ast_network_puts_mutable(s);
00920 }

static void null_sig_handler ( int  signal  )  [static]

NULL handler so we can collect the child exit status.

Definition at line 757 of file asterisk.c.

Referenced by ast_replace_sigchld().

00758 {
00759 
00760 }

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

Definition at line 1235 of file asterisk.c.

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

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

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

static __inline uint64_t rdtsc ( void   )  [static]

Definition at line 434 of file asterisk.c.

Referenced by ast_mark().

00435 {
00436    return 0;
00437 }

static int remoteconsolehandler ( char *  s  )  [static]

Definition at line 1425 of file asterisk.c.

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

Referenced by ast_remotecontrol().

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

static void set_icon ( char *  text  )  [static]

Definition at line 1182 of file asterisk.c.

Referenced by main().

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

static void set_title ( char *  text  )  [static]

Set an X-term or screen title.

Definition at line 1176 of file asterisk.c.

Referenced by main().

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

static int show_cli_help ( void   )  [static]

Definition at line 2394 of file asterisk.c.

References ASTERISK_VERSION.

Referenced by main().

02394                                {
02395    printf("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2008, Digium, Inc. and others.\n");
02396    printf("Usage: asterisk [OPTIONS]\n");
02397    printf("Valid Options:\n");
02398    printf("   -V              Display version number and exit\n");
02399    printf("   -C <configfile> Use an alternate configuration file\n");
02400    printf("   -G <group>      Run as a group other than the caller\n");
02401    printf("   -U <user>       Run as a user other than the caller\n");
02402    printf("   -c              Provide console CLI\n");
02403    printf("   -d              Enable extra debugging\n");
02404 #if HAVE_WORKING_FORK
02405    printf("   -f              Do not fork\n");
02406    printf("   -F              Always fork\n");
02407 #endif
02408    printf("   -g              Dump core in case of a crash\n");
02409    printf("   -h              This help screen\n");
02410    printf("   -i              Initialize crypto keys at startup\n");
02411    printf("   -I              Enable internal timing if Zaptel timer is available\n");
02412    printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
02413    printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
02414    printf("   -m              Mute debugging and console output on the console\n");
02415    printf("   -n              Disable console colorization\n");
02416    printf("   -p              Run as pseudo-realtime thread\n");
02417    printf("   -q              Quiet mode (suppress output)\n");
02418    printf("   -r              Connect to Asterisk on this machine\n");
02419    printf("   -R              Same as -r, except attempt to reconnect if disconnected\n");
02420    printf("   -t              Record soundfiles in /var/tmp and move them where they\n");
02421    printf("                   belong after they are done\n");
02422    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line\n");
02423    printf("                   of output to the CLI\n");
02424    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
02425    printf("   -x <cmd>        Execute command <cmd> (only valid with -r)\n");
02426    printf("\n");
02427    return 0;
02428 }

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

Definition at line 1644 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

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

static int show_version ( void   )  [static]

Definition at line 2388 of file asterisk.c.

References ASTERISK_VERSION.

Referenced by main().

02389 {
02390    printf("Asterisk " ASTERISK_VERSION "\n");
02391    return 0;
02392 }

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

Definition at line 1615 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

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

static void urg_handler ( int  num  )  [static]

Urgent handler.

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

Definition at line 1141 of file asterisk.c.

Referenced by main().

01142 {
01143    signal(num, urg_handler);
01144    return;
01145 }


Variable Documentation

char* _argv[256] [static]

Definition at line 240 of file asterisk.c.

char abort_halt_help[] [static]

Initial value:

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

Definition at line 1449 of file asterisk.c.

const char* ast_build_date

Definition at line 32 of file buildinfo.c.

const char* ast_build_hostname

Definition at line 28 of file buildinfo.c.

const char* ast_build_kernel

Definition at line 29 of file buildinfo.c.

const char* ast_build_machine

Definition at line 30 of file buildinfo.c.

const char* ast_build_os

Definition at line 31 of file buildinfo.c.

const char* ast_build_user

Definition at line 33 of file buildinfo.c.

char ast_config_AST_AGI_DIR[PATH_MAX]

Definition at line 219 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_CONFIG_DIR[PATH_MAX]

Definition at line 212 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl"

Definition at line 230 of file asterisk.c.

char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0"

Definition at line 229 of file asterisk.c.

char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0"

Definition at line 228 of file asterisk.c.

Definition at line 227 of file asterisk.c.

char ast_config_AST_DATA_DIR[PATH_MAX]

char ast_config_AST_DB[PATH_MAX]

Definition at line 220 of file asterisk.c.

Referenced by dbinit().

char ast_config_AST_KEY_DIR[PATH_MAX]

Definition at line 221 of file asterisk.c.

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

char ast_config_AST_LOG_DIR[PATH_MAX]

char ast_config_AST_MODULE_DIR[PATH_MAX]

char ast_config_AST_PID[PATH_MAX]

Definition at line 222 of file asterisk.c.

char ast_config_AST_RUN_DIR[PATH_MAX]

Definition at line 224 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_RUN_GROUP[PATH_MAX]

Definition at line 226 of file asterisk.c.

char ast_config_AST_RUN_USER[PATH_MAX]

Definition at line 225 of file asterisk.c.

char ast_config_AST_SOCKET[PATH_MAX]

Definition at line 223 of file asterisk.c.

char ast_config_AST_SPOOL_DIR[PATH_MAX]

char ast_config_AST_VAR_DIR[PATH_MAX]

Definition at line 216 of file asterisk.c.

Referenced by ael2_semantic_check(), and launch_script().

int ast_consock = -1 [static]

UNIX Socket for controlling another asterisk

Definition at line 180 of file asterisk.c.

Definition at line 197 of file asterisk.c.

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

pid_t ast_mainpid

Definition at line 181 of file asterisk.c.

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

int ast_socket = -1 [static]

UNIX Socket for allowing remote control

Definition at line 179 of file asterisk.c.

Definition at line 196 of file asterisk.c.

Referenced by handle_showuptime(), and handle_showuptime_deprecated().

char bang_help[] [static]

Initial value:

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

Definition at line 1481 of file asterisk.c.

struct ast_cli_entry cli_asterisk[] [static]

Definition at line 1680 of file asterisk.c.

Initial value:

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

Definition at line 1674 of file asterisk.c.

Initial value:

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

Definition at line 1669 of file asterisk.c.

Initial value:

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

Definition at line 1658 of file asterisk.c.

Initial value:

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

Definition at line 1664 of file asterisk.c.

struct console consoles[AST_MAX_CONNECTS]

pthread_t consolethread = AST_PTHREADT_NULL [static]

Definition at line 243 of file asterisk.c.

Referenced by show_console().

char debug_filename[AST_FILENAME_MAX] = ""

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 205 of file asterisk.c.

Referenced by ast_channel_alloc().

EditLine* el [static]

History* el_hist [static]

Definition at line 199 of file asterisk.c.

const char* license_lines[] [static]

Definition at line 1625 of file asterisk.c.

pthread_t lthread [static]

Definition at line 922 of file asterisk.c.

unsigned int need_quit

Definition at line 250 of file asterisk.c.

unsigned int need_reload

Definition at line 249 of file asterisk.c.

struct profile_data* prof_data [static]

Definition at line 373 of file asterisk.c.

char randompool[256] [static]

Definition at line 245 of file asterisk.c.

char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR

Definition at line 176 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname [static]

Definition at line 201 of file asterisk.c.

char restart_gracefully_help[] [static]

Initial value:

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

Definition at line 1472 of file asterisk.c.

char restart_now_help[] [static]

Initial value:

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

Definition at line 1467 of file asterisk.c.

Initial value:

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

Definition at line 1477 of file asterisk.c.

int restartnow [static]

Definition at line 242 of file asterisk.c.

unsigned int safe_system_level = 0 [static]

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

Definition at line 765 of file asterisk.c.

void* safe_system_prev_handler [static]

Definition at line 766 of file asterisk.c.

char show_license_help[] [static]

Initial value:

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

Definition at line 1489 of file asterisk.c.

char show_threads_help[] [static]

Initial value:

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

Definition at line 308 of file asterisk.c.

char show_version_files_help[] [static]

Initial value:

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

Definition at line 548 of file asterisk.c.

char show_warranty_help[] [static]

Initial value:

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

Definition at line 1485 of file asterisk.c.

char shutdown_gracefully_help[] [static]

Initial value:

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

Definition at line 1458 of file asterisk.c.

char shutdown_now_help[] [static]

Initial value:

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

Definition at line 1454 of file asterisk.c.

Initial value:

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

Definition at line 1463 of file asterisk.c.

int shuttingdown [static]

Definition at line 241 of file asterisk.c.

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

Definition at line 247 of file asterisk.c.

struct { ... } sig_flags [static]

char version_help[] [static]

Initial value:

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

Definition at line 1493 of file asterisk.c.

const char* warranty_lines[] [static]

Definition at line 1590 of file asterisk.c.


Generated on Sun Jun 12 16:37:51 2011 for Asterisk - the Open Source PBX by  doxygen 1.5.6