Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:21 2009

## 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 <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.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/module.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/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/compat.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

## Defines

#define | AF_LOCAL AF_UNIX
#define | AST_MAX_CONNECTS 128
#define | ASTERISK_PROMPT "*CLI> "
#define | ASTERISK_PROMPT2 "%s*CLI> "
#define | FORMAT "%-25.25s %-40.40s\n"
#define | 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)
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)
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 (file_versions, file_version)
static int | ast_makesocket (void)
| AST_MUTEX_DEFINE_STATIC (safe_system_lock)
| AST_MUTEX_DEFINE_STATIC (atexitslock)
static void | ast_network_puts (const char *string)
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.
static void | ast_remotecontrol (char *data)
static void | ast_run_atexits (void)
int | ast_safe_system (const char *s)
int | ast_set_priority (int pri)
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.
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 (char *line, char *word, int pos, int state)
static void | console_verboser (const char *s, int pos, int replace, int complete)
static void | consolehandler (char *s)
static int | fdprint (int fd, const char *s)
static const char * | fix_header (char *outbuf, int maxout, const char *s, char *cmp)
static int | handle_abort_halt (int fd, int argc, char *argv[])
static int | handle_bang (int fd, int argc, char *argv[])
static int | handle_restart_gracefully (int fd, int argc, char *argv[])
static int | handle_restart_now (int fd, int argc, char *argv[])
static int | handle_restart_when_convenient (int fd, int argc, char *argv[])
static int | handle_show_version_files (int fd, int argc, char *argv[])
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 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, int pos, int replace, int complete)
static void | null_sig_handler (int signal)
static void | quit_handler (int num, int nice, int safeshutdown, int restart)
static int | remoteconsolehandler (char *s)
static void | set_icon (char *text)
static void | set_title (char *text)
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)

## Variables

static char * | _argv [256]
static char | abort_halt_help []
char | ast_config_AST_AGI_DIR [AST_CONFIG_MAX_PATH]
char | ast_config_AST_CONFIG_DIR [AST_CONFIG_MAX_PATH]
char | ast_config_AST_CONFIG_FILE [AST_CONFIG_MAX_PATH]
char | ast_config_AST_CTL [AST_CONFIG_MAX_PATH] = "asterisk.ctl"
char | ast_config_AST_CTL_GROUP [AST_CONFIG_MAX_PATH] = "\0"
char | ast_config_AST_CTL_OWNER [AST_CONFIG_MAX_PATH] = "\0"
char | ast_config_AST_CTL_PERMISSIONS [AST_CONFIG_MAX_PATH]
char | ast_config_AST_DB [AST_CONFIG_MAX_PATH]
char | ast_config_AST_KEY_DIR [AST_CONFIG_MAX_PATH]
char | ast_config_AST_LOG_DIR [AST_CONFIG_MAX_PATH]
char | ast_config_AST_MODULE_DIR [AST_CONFIG_MAX_PATH]
char | ast_config_AST_MONITOR_DIR [AST_CONFIG_MAX_PATH]
char | ast_config_AST_PID [AST_CONFIG_MAX_PATH]
char | ast_config_AST_RUN_DIR [AST_CONFIG_MAX_PATH]
char | ast_config_AST_RUN_GROUP [AST_CONFIG_MAX_PATH]
char | ast_config_AST_RUN_USER [AST_CONFIG_MAX_PATH]
char | ast_config_AST_SOCKET [AST_CONFIG_MAX_PATH]
char | ast_config_AST_SPOOL_DIR [AST_CONFIG_MAX_PATH]
char | ast_config_AST_VAR_DIR [AST_CONFIG_MAX_PATH]
static int | ast_consock = -1
time_t | ast_lastreloadtime
int | ast_mainpid
static int | ast_socket = -1
time_t | ast_startuptime
static struct ast_atexit * | atexits
static char | bang_help []
struct console | consoles [AST_MAX_CONNECTS]
static pthread_t | consolethread = AST_PTHREADT_NULL
static struct ast_cli_entry | core_cli []
char | debug_filename [AST_FILENAME_MAX] = ""
char | defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE
static EditLine * | el = NULL
static History * | el_hist = NULL
int | fully_booted = 0
static const char * | license_lines []
static pthread_t | lthread
int | option_cache_record_files = 0
int | option_console = 0
int | option_debug = 0
int | option_dontwarn = 0
int | option_dumpcore = 0
int | option_exec = 0
int | option_exec_includes = 0
int | option_highpriority = 0
int | option_initcrypto = 0
int | option_maxcalls = 0
double | option_maxload = 0.0
int | option_nocolor
int | option_nofork = 0
int | option_overrideconfig = 0
int | option_priority_jumping = 1
int | option_quiet = 0
int | option_reconnect = 0
int | option_remote = 0
int | option_timestamp = 0
int | option_transcode_slin = 1
int | option_transmit_silence_during_record = 0
int | option_verbose = 0
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 = 0
static unsigned int | safe_system_level = 0
static void * | safe_system_prev_handler
static char | show_license_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 = 0
static int | sig_alert_pipe [2] = { -1, -1 }
struct {
unsigned int need_quit:1
unsigned int need_reload:1
} | sig_flags
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 129 of file asterisk.c.

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

#define AST_MAX_CONNECTS 128

Definition at line 133 of file asterisk.c.

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

#define ASTERISK_PROMPT "*CLI> "

Definition at line 1225 of file asterisk.c.

Referenced by cli_prompt().

#define ASTERISK_PROMPT2 "%s*CLI> "

Definition at line 1227 of file asterisk.c.

Referenced by cli_prompt().

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

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

#define NUM_MSGS 64

Definition at line 134 of file asterisk.c.

#define PF_LOCAL PF_UNIX

Definition at line 130 of file asterisk.c.

Referenced by ast_makesocket(), and ast_tryconnect().

#define WELCOME_MESSAGE

Welcome message when starting a CLI interface.

Definition at line 137 of file asterisk.c.

Referenced by ast_el_read_char(), and main().

## Function Documentation

static void __quit_handler | ( | int | num | ) | `[static]`

Definition at line 948 of file asterisk.c.

References sig_flags.

Referenced by main().

    00949 {
    00950    int a = 0;
    00951    sig_flags.need_quit = 1;
    00952    if (sig_alert_pipe[1] != -1)
    00953       write(sig_alert_pipe[1], &a, sizeof(a));
    00954    /* There is no need to restore the signal handler here, since the app
    00955     * is going to exit */
    00956 }

static int ast_all_zeros | ( | char * | s | ) | `[static]`

Definition at line 994 of file asterisk.c.

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

    00995 {
    00996    while(*s) {
    00997       if (*s > 32)
    00998          return 0;
    00999       s++;
    01000    }
    01001    return 1;
    01002 }

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

Definition at line 1520 of file asterisk.c.

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

Referenced by cli_complete().

    01521 {
    01522    int i, idx, limit, count;
    01523    int screenwidth = 0;
    01524    int numoutput = 0, numoutputline = 0;
    01525
    01526    screenwidth = ast_get_termcols(STDOUT_FILENO);
    01527
    01528    /* find out how many entries can be put on one line, with two spaces between strings */
    01529    limit = screenwidth / (max + 2);
    01530    if (limit == 0)
    01531       limit = 1;
    01532
    01533    /* how many lines of output */
    01534    count = len / limit;
    01535    if (count * limit < len)
    01536       count++;
    01537
    01538    idx = 1;
    01539
    01540    qsort(&matches[0], (size_t)(len + 1), sizeof(char *), ast_el_sort_compare);
    01541
    01542    for (; count > 0; count--) {
    01543       numoutputline = 0;
    01544       for (i=0; i < limit && matches[idx]; i++, idx++) {
    01545
    01546          /* Don't print dupes */
    01547          if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) {
    01548             i--;
    01549             free(matches[idx]);
    01550             matches[idx] = NULL;
    01551             continue;
    01552          }
    01553
    01554          numoutput++;
    01555          numoutputline++;
    01556          fprintf(stdout, "%-*s  ", max, matches[idx]);
    01557          free(matches[idx]);
    01558          matches[idx] = NULL;
    01559       }
    01560       if (numoutputline > 0)
    01561          fprintf(stdout, "\n");
    01562    }
    01563
    01564    return numoutput;
    01565 }

void ast_console_puts | ( | const char * | string | ) |

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

Definition at line 501 of file asterisk.c.

References ast_network_puts().

Referenced by ast_log(), and chan_misdn_log().

    00502 {
    00503    fputs(string, stdout);
    00504    fflush(stdout);
    00505    ast_network_puts(string);
    00506 }

static int ast_el_add_history | ( | char * | buf | ) | `[static]`

Definition at line 1713 of file asterisk.c.

References ast_el_initialize().

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

    01714 {
    01715    HistEvent ev;
    01716
    01717    if (el_hist == NULL || el == NULL)
    01718       ast_el_initialize();
    01719    if (strlen(buf) > 256)
    01720       return 0;
    01721    return (history(el_hist, &ev, H_ENTER, buf));
    01722 }

static int ast_el_initialize | ( | void |  | ) | `[static]`

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

    01679 {
    01680    HistEvent ev;
    01681    char *editor = getenv("AST_EDITOR");
    01682
    01683    if (el != NULL)
    01684       el_end(el);
    01685    if (el_hist != NULL)
    01686       history_end(el_hist);
    01687
    01688    el = el_init("asterisk", stdin, stdout, stderr);
    01689    el_set(el, EL_PROMPT, cli_prompt);
    01690
    01691    el_set(el, EL_EDITMODE, 1);
    01692    el_set(el, EL_EDITOR, editor ? editor : "emacs");
    01693    el_hist = history_init();
    01694    if (!el || !el_hist)
    01695       return -1;
    01696
    01697    /* setup history with 100 entries */
    01698    history(el_hist, &ev, H_SETSIZE, 100);
    01699
    01700    el_set(el, EL_HIST, history, el_hist);
    01701
    01702    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
    01703    /* Bind <tab> to command completion */
    01704    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
    01705    /* Bind ? to command completion */
    01706    el_set(el, EL_BIND, "?", "ed-complete", NULL);
    01707    /* Bind ^D to redisplay */
    01708    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
    01709
    01710    return 0;
    01711 }

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

Definition at line 1256 of file asterisk.c.

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

Referenced by ast_remotecontrol().

    01257 {
    01258    int num_read=0;
    01259    int lastpos=0;
    01260    struct pollfd fds[2];
    01261    int res;
    01262    int max;
    01263    char buf[512];
    01264
    01265    for (;;) {
    01266       max = 1;
    01267       fds[0].fd = ast_consock;
    01268       fds[0].events = POLLIN;
    01269       if (!option_exec) {
    01270          fds[1].fd = STDIN_FILENO;
    01271          fds[1].events = POLLIN;
    01272          max++;
    01273       }
    01274       res = poll(fds, max, -1);
    01275       if (res < 0) {
    01276          if (errno == EINTR)
    01277             continue;
    01278          ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno));
    01279          break;
    01280       }
    01281
    01282       if (!option_exec && fds[1].revents) {
    01283          num_read = read(STDIN_FILENO, cp, 1);
    01284          if (num_read < 1) {
    01285             break;
    01286          } else
    01287             return (num_read);
    01288       }
    01289       if (fds[0].revents) {
    01290          res = read(ast_consock, buf, sizeof(buf) - 1);
    01291          /* if the remote side disappears exit */
    01292          if (res < 1) {
    01293             fprintf(stderr, "\nDisconnected from Asterisk server\n");
    01294             if (!option_reconnect) {
    01295                quit_handler(0, 0, 0, 0);
    01296             } else {
    01297                int tries;
    01298                int reconnects_per_second = 20;
    01299                fprintf(stderr, "Attempting to reconnect for 30 seconds\n");
    01300                for (tries=0;tries<30 * reconnects_per_second;tries++) {
    01301                   if (ast_tryconnect()) {
    01302                      fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries);
    01303                      printf(term_quit());
    01304                      WELCOME_MESSAGE;
    01305                      break;
    01306                   } else {
    01307                      usleep(1000000 / reconnects_per_second);
    01308                   }
    01309                }
    01310                if (tries >= 30 * reconnects_per_second) {
    01311                   fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n");
    01312                   quit_handler(0, 0, 0, 0);
    01313                }
    01314             }
    01315          }
    01316
    01317          buf[res] = '\0';
    01318
    01319          if (!option_exec && !lastpos)
    01320             write(STDOUT_FILENO, "\r", 1);
    01321          write(STDOUT_FILENO, buf, res);
    01322          if ((buf[res-1] == '\n') || (buf[res-2] == '\n')) {
    01323             *cp = CC_REFRESH;
    01324             return(1);
    01325          } else {
    01326             lastpos = 1;
    01327          }
    01328       }
    01329    }
    01330
    01331    *cp = '\0';
    01332    return (0);
    01333 }

static int ast_el_read_history | ( | char * | filename | ) | `[static]`

Definition at line 1734 of file asterisk.c.

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

Referenced by ast_remotecontrol(), and main().

    01735 {
    01736    char buf[256];
    01737    FILE *f;
    01738    int ret = -1;
    01739
    01740    if (el_hist == NULL || el == NULL)
    01741       ast_el_initialize();
    01742
    01743    if ((f = fopen(filename, "r")) == NULL)
    01744       return ret;
    01745
    01746    while (!feof(f)) {
    01747       fgets(buf, sizeof(buf), f);
    01748       if (!strcmp(buf, "_HiStOrY_V2_\n"))
    01749          continue;
    01750       if (ast_all_zeros(buf))
    01751          continue;
    01752       if ((ret = ast_el_add_history(buf)) == -1)
    01753          break;
    01754    }
    01755    fclose(f);
    01756
    01757    return ret;
    01758 }

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

Definition at line 1510 of file asterisk.c.

Referenced by ast_cli_display_match_list().

    01511 {
    01512    char *s1, *s2;
    01513
    01514    s1 = ((char **)i1)[0];
    01515    s2 = ((char **)i2)[0];
    01516
    01517    return strcasecmp(s1, s2);
    01518 }

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

Definition at line 1480 of file asterisk.c.

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

Referenced by cli_complete().

    01481 {
    01482    char **match_list = NULL, *retstr;
    01483    size_t match_list_len;
    01484    int matches = 0;
    01485
    01486    match_list_len = 1;
    01487    while ( (retstr = strsep(&buf, " ")) != NULL) {
    01488
    01489       if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
    01490          break;
    01491       if (matches + 1 >= match_list_len) {
    01492          match_list_len <<= 1;
    01493          match_list = realloc(match_list, match_list_len * sizeof(char *));
    01494       }
    01495
    01496       match_list[matches++] = strdup(retstr);
    01497    }
    01498
    01499    if (!match_list)
    01500       return (char **) NULL;
    01501
    01502    if (matches>= match_list_len)
    01503       match_list = realloc(match_list, (match_list_len + 1) * sizeof(char *));
    01504
    01505    match_list[matches] = (char *) NULL;
    01506
    01507    return match_list;
    01508 }

static int ast_el_write_history | ( | char * | filename | ) | `[static]`

Definition at line 1724 of file asterisk.c.

References ast_el_initialize().

Referenced by quit_handler().

    01725 {
    01726    HistEvent ev;
    01727
    01728    if (el_hist == NULL || el == NULL)
    01729       ast_el_initialize();
    01730
    01731    return (history(el_hist, &ev, H_SAVE, filename));
    01732 }

static AST_LIST_HEAD_STATIC | ( | file_versions | ,
|  | file_version |  |
| ) |  |  | `[static]`

static int ast_makesocket | ( | void |  | ) | `[static]`

Definition at line 649 of file asterisk.c.

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

Referenced by main().

    00650 {
    00651    struct sockaddr_un sunaddr;
    00652    int res;
    00653    int x;
    00654    uid_t uid = -1;
    00655    gid_t gid = -1;
    00656
    00657    for (x = 0; x < AST_MAX_CONNECTS; x++)
    00658       consoles[x].fd = -1;
    00659    unlink(ast_config_AST_SOCKET);
    00660    ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0);
    00661    if (ast_socket < 0) {
    00662       ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno));
    00663       return -1;
    00664    }
    00665    memset(&sunaddr, 0, sizeof(sunaddr));
    00666    sunaddr.sun_family = AF_LOCAL;
    00667    ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
    00668    res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
    00669    if (res) {
    00670       ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
    00671       close(ast_socket);
    00672       ast_socket = -1;
    00673       return -1;
    00674    }
    00675    res = listen(ast_socket, 2);
    00676    if (res < 0) {
    00677       ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
    00678       close(ast_socket);
    00679       ast_socket = -1;
    00680       return -1;
    00681    }
    00682    ast_register_verbose(network_verboser);
    00683    ast_pthread_create(&lthread, NULL, listener, NULL);
    00684
    00685    if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
    00686       struct passwd *pw;
    00687       if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL) {
    00688          ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER);
    00689       } else {
    00690          uid = pw->pw_uid;
    00691       }
    00692    }
    00693
    00694    if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) {
    00695       struct group *grp;
    00696       if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL) {
    00697          ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP);
    00698       } else {
    00699          gid = grp->gr_gid;
    00700       }
    00701    }
    00702
    00703    if (chown(ast_config_AST_SOCKET, uid, gid) < 0)
    00704       ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
    00705
    00706    if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) {
    00707       int p1;
    00708       mode_t p;
    00709       sscanf(ast_config_AST_CTL_PERMISSIONS, "%30o", &p1);
    00710       p = p1;
    00711       if ((chmod(ast_config_AST_SOCKET, p)) < 0)
    00712          ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno));
    00713    }
    00714
    00715    return 0;
    00716 }

AST_MUTEX_DEFINE_STATIC | ( | safe_system_lock |  | ) |

AST_MUTEX_DEFINE_STATIC | ( | atexitslock |  | ) |

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

write the string to all attached console clients

Definition at line 488 of file asterisk.c.

References AST_MAX_CONNECTS, consoles, and fdprint().

Referenced by ast_console_puts(), and network_verboser().

    00489 {
    00490    int x;
    00491    for (x=0;x<AST_MAX_CONNECTS; x++) {
    00492       if (consoles[x].fd > -1)
    00493          fdprint(consoles[x].p[1], string);
    00494    }
    00495 }

static void ast_readconfig | ( | void |  | ) | `[static]`

Definition at line 1870 of file asterisk.c.

References AST_CACHE_DIR_LEN, ast_config_destroy(), ast_config_load(), ast_log(), ast_true(), ast_variable_browse(), cfg, config, getloadavg(), LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by main().

    01870                                  {
    01871    struct ast_config *cfg;
    01872    struct ast_variable *v;
    01873    char *config = AST_CONFIG_FILE;
    01874
    01875    if (option_overrideconfig == 1) {
    01876       cfg = ast_config_load(ast_config_AST_CONFIG_FILE);
    01877       if (!cfg)
    01878          ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
    01879    } else {
    01880       cfg = ast_config_load(config);
    01881    }
    01882
    01883    /* init with buildtime config */
    01884    ast_copy_string(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR, sizeof(ast_config_AST_CONFIG_DIR));
    01885    ast_copy_string(ast_config_AST_SPOOL_DIR, AST_SPOOL_DIR, sizeof(ast_config_AST_SPOOL_DIR));
    01886    ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_MODULE_DIR));
    01887    snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR);
    01888    ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR));
    01889    ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR));
    01890    ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR));
    01891    ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB));
    01892    ast_copy_string(ast_config_AST_KEY_DIR, AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR));
    01893    ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID));
    01894    ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET));
    01895    ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR));
    01896
    01897    /* no asterisk.conf? no problem, use buildtime config! */
    01898    if (!cfg) {
    01899       return;
    01900    }
    01901    v = ast_variable_browse(cfg, "files");
    01902    while (v) {
    01903       if (!strcasecmp(v->name, "astctlpermissions")) {
    01904          ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
    01905       } else if (!strcasecmp(v->name, "astctlowner")) {
    01906          ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
    01907       } else if (!strcasecmp(v->name, "astctlgroup")) {
    01908          ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
    01909       } else if (!strcasecmp(v->name, "astctl")) {
    01910          ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
    01911       }
    01912       v = v->next;
    01913    }
    01914    v = ast_variable_browse(cfg, "directories");
    01915    while(v) {
    01916       if (!strcasecmp(v->name, "astetcdir")) {
    01917          ast_copy_string(ast_config_AST_CONFIG_DIR, v->value, sizeof(ast_config_AST_CONFIG_DIR));
    01918       } else if (!strcasecmp(v->name, "astspooldir")) {
    01919          ast_copy_string(ast_config_AST_SPOOL_DIR, v->value, sizeof(ast_config_AST_SPOOL_DIR));
    01920          snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", v->value);
    01921       } else if (!strcasecmp(v->name, "astvarlibdir")) {
    01922          ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR));
    01923          snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/astdb", v->value);
    01924          snprintf(ast_config_AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR), "%s/keys", v->value);
    01925       } else if (!strcasecmp(v->name, "astlogdir")) {
    01926          ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR));
    01927       } else if (!strcasecmp(v->name, "astagidir")) {
    01928          ast_copy_string(ast_config_AST_AGI_DIR, v->value, sizeof(ast_config_AST_AGI_DIR));
    01929       } else if (!strcasecmp(v->name, "astrundir")) {
    01930          snprintf(ast_config_AST_PID, sizeof(ast_config_AST_PID), "%s/%s", v->value, "asterisk.pid");
    01931          snprintf(ast_config_AST_SOCKET, sizeof(ast_config_AST_SOCKET), "%s/%s", v->value, ast_config_AST_CTL);
    01932          ast_copy_string(ast_config_AST_RUN_DIR, v->value, sizeof(ast_config_AST_RUN_DIR));
    01933       } else if (!strcasecmp(v->name, "astmoddir")) {
    01934          ast_copy_string(ast_config_AST_MODULE_DIR, v->value, sizeof(ast_config_AST_MODULE_DIR));
    01935       }
    01936       v = v->next;
    01937    }
    01938    v = ast_variable_browse(cfg, "options");
    01939    while(v) {
    01940       /* verbose level (-v at startup) */
    01941       if (!strcasecmp(v->name, "verbose")) {
    01942          option_verbose = atoi(v->value);
    01943       /* whether or not to force timestamping. (-T at startup) */
    01944       } else if (!strcasecmp(v->name, "timestamp")) {
    01945          option_timestamp = ast_true(v->value);
    01946       /* whether or not to support #exec in config files */
    01947       } else if (!strcasecmp(v->name, "execincludes")) {
    01948          option_exec_includes = ast_true(v->value);
    01949       /* debug level (-d at startup) */
    01950       } else if (!strcasecmp(v->name, "debug")) {
    01951          option_debug = 0;
    01952          if (sscanf(v->value, "%30d", &option_debug) != 1) {
    01953             option_debug = ast_true(v->value);
    01954          }
    01955       /* Disable forking (-f at startup) */
    01956       } else if (!strcasecmp(v->name, "nofork")) {
    01957          option_nofork = ast_true(v->value);
    01958       /* Run quietly (-q at startup ) */
    01959       } else if (!strcasecmp(v->name, "quiet")) {
    01960          option_quiet = ast_true(v->value);
    01961       /* Run as console (-c at startup, implies nofork) */
    01962       } else if (!strcasecmp(v->name, "console")) {
    01963          option_console = ast_true(v->value);
    01964       /* Run with highg priority if the O/S permits (-p at startup) */
    01965       } else if (!strcasecmp(v->name, "highpriority")) {
    01966          option_highpriority = ast_true(v->value);
    01967       /* Initialize RSA auth keys (IAX2) (-i at startup) */
    01968       } else if (!strcasecmp(v->name, "initcrypto")) {
    01969          option_initcrypto = ast_true(v->value);
    01970       /* Disable ANSI colors for console (-c at startup) */
    01971       } else if (!strcasecmp(v->name, "nocolor")) {
    01972          option_nocolor = ast_true(v->value);
    01973       /* Disable some usage warnings for picky people :p */
    01974       } else if (!strcasecmp(v->name, "dontwarn")) {
    01975          option_dontwarn = ast_true(v->value);
    01976       /* Dump core in case of crash (-g) */
    01977       } else if (!strcasecmp(v->name, "dumpcore")) {
    01978          option_dumpcore = ast_true(v->value);
    01979       /* Cache recorded sound files to another directory during recording */
    01980       } else if (!strcasecmp(v->name, "cache_record_files")) {
    01981          option_cache_record_files = ast_true(v->value);
    01982       /* Specify cache directory */
    01983       }  else if (!strcasecmp(v->name, "record_cache_dir")) {
    01984          ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
    01985       /* Build transcode paths via SLINEAR, instead of directly */
    01986       } else if (!strcasecmp(v->name, "transcode_via_sln")) {
    01987          option_transcode_slin = ast_true(v->value);
    01988       /* Transmit SLINEAR silence while a channel is being recorded */
    01989       } else if (!strcasecmp(v->name, "transmit_silence_during_record")) {
    01990          option_transmit_silence_during_record = ast_true(v->value);
    01991       } else if (!strcasecmp(v->name, "maxcalls")) {
    01992          if ((sscanf(v->value, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
    01993             option_maxcalls = 0;
    01994          }
    01995       } else if (!strcasecmp(v->name, "maxload")) {
    01996          double test[1];
    01997
    01998          if (getloadavg(test, 1) == -1) {
    01999             ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
    02000             option_maxload = 0.0;
    02001          } else if ((sscanf(v->value, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
    02002             option_maxload = 0.0;
    02003          }
    02004       /* What user to run as */
    02005       } else if (!strcasecmp(v->name, "runuser")) {
    02006          ast_copy_string(ast_config_AST_RUN_USER, v->value, sizeof(ast_config_AST_RUN_USER));
    02007       /* What group to run as */
    02008       } else if (!strcasecmp(v->name, "rungroup")) {
    02009          ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP));
    02010       }
    02011       v = v->next;
    02012    }
    02013    ast_config_destroy(cfg);
    02014 }

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

References ast_mutex_lock(), ast_mutex_unlock(), ast_unregister_atexit(), atexits, ast_atexit::func, malloc, and ast_atexit::next.

Referenced by do_reload(), and load_module().

    00377 {
    00378    int res = -1;
    00379    struct ast_atexit *ae;
    00380    ast_unregister_atexit(func);
    00381    ae = malloc(sizeof(struct ast_atexit));
    00382    ast_mutex_lock(&atexitslock);
    00383    if (ae) {
    00384       memset(ae, 0, sizeof(struct ast_atexit));
    00385       ae->next = atexits;
    00386       ae->func = func;
    00387       atexits = ae;
    00388       res = 0;
    00389    }
    00390    ast_mutex_unlock(&atexitslock);
    00391    return res;
    00392 }

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

References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_strdupa, ast_strip_quoted(), calloc, and list.

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

static void ast_remotecontrol | ( | char * | data | ) | `[static]`

Definition at line 1760 of file asterisk.c.

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

Referenced by main().

    01761 {
    01762    char buf[80];
    01763    int res;
    01764    char filename[80] = "";
    01765    char *hostname;
    01766    char *cpid;
    01767    char *version;
    01768    int pid;
    01769    char tmp[80];
    01770    char *stringp=NULL;
    01771
    01772    char *ebuf;
    01773    int num = 0;
    01774
    01775    read(ast_consock, buf, sizeof(buf));
    01776    if (data)
    01777       write(ast_consock, data, strlen(data) + 1);
    01778    stringp=buf;
    01779    hostname = strsep(&stringp, "/");
    01780    cpid = strsep(&stringp, "/");
    01781    version = strsep(&stringp, "\n");
    01782    if (!version)
    01783       version = "<Version Unknown>";
    01784    stringp=hostname;
    01785    strsep(&stringp, ".");
    01786    if (cpid)
    01787       pid = atoi(cpid);
    01788    else
    01789       pid = -1;
    01790    snprintf(tmp, sizeof(tmp), "set verbose atleast %d", option_verbose);
    01791    fdprint(ast_consock, tmp);
    01792    snprintf(tmp, sizeof(tmp), "set debug atleast %d", option_debug);
    01793    fdprint(ast_consock, tmp);
    01794    ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
    01795    remotehostname = hostname;
    01796    if (getenv("HOME"))
    01797       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
    01798    if (el_hist == NULL || el == NULL)
    01799       ast_el_initialize();
    01800
    01801    el_set(el, EL_GETCFN, ast_el_read_char);
    01802
    01803    if (!ast_strlen_zero(filename))
    01804       ast_el_read_history(filename);
    01805
    01806    if (option_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
    01807       char tempchar;
    01808       struct pollfd fds;
    01809       fds.fd = ast_consock;
    01810       fds.events = POLLIN;
    01811       fds.revents = 0;
    01812       while (poll(&fds, 1, 100) > 0)
    01813          ast_el_read_char(el, &tempchar);
    01814       return;
    01815    }
    01816    for(;;) {
    01817       ebuf = (char *)el_gets(el, &num);
    01818
    01819       if (!ebuf && write(1, "", 1) < 0)
    01820          break;
    01821
    01822       if (!ast_strlen_zero(ebuf)) {
    01823          if (ebuf[strlen(ebuf)-1] == '\n')
    01824             ebuf[strlen(ebuf)-1] = '\0';
    01825          if (!remoteconsolehandler(ebuf)) {
    01826             res = write(ast_consock, ebuf, strlen(ebuf) + 1);
    01827             if (res < 1) {
    01828                ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
    01829                break;
    01830             }
    01831          }
    01832       }
    01833    }
    01834    printf("\nDisconnected from Asterisk server\n");
    01835 }

static void ast_run_atexits | ( | void |  | ) | `[static]`

Definition at line 829 of file asterisk.c.

References ast_mutex_lock(), ast_mutex_unlock(), atexits, ast_atexit::func, and ast_atexit::next.

Referenced by quit_handler().

    00830 {
    00831    struct ast_atexit *ae;
    00832    ast_mutex_lock(&atexitslock);
    00833    ae = atexits;
    00834    while(ae) {
    00835       if (ae->func)
    00836          ae->func();
    00837       ae = ae->next;
    00838    }
    00839    ast_mutex_unlock(&atexitslock);
    00840 }

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

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_priority(), LOG_WARNING, and null_sig_handler().

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

    00429 {
    00430    pid_t pid;
    00431    int x;
    00432    int res;
    00433    struct rusage rusage;
    00434    int status;
    00435    unsigned int level;
    00436
    00437    /* keep track of how many ast_safe_system() functions
    00438       are running at this moment
    00439    */
    00440    ast_mutex_lock(&safe_system_lock);
    00441    level = safe_system_level++;
    00442
    00443    /* only replace the handler if it has not already been done */
    00444    if (level == 0)
    00445       safe_system_prev_handler = signal(SIGCHLD, null_sig_handler);
    00446
    00447    ast_mutex_unlock(&safe_system_lock);
    00448
    00449    pid = fork();
    00450
    00451    if (pid == 0) {
    00452       if (option_highpriority)
    00453          ast_set_priority(0);
    00454       /* Close file descriptors and launch system command */
    00455       for (x = STDERR_FILENO + 1; x < 4096; x++)
    00456          close(x);
    00457       execl("/bin/sh", "/bin/sh", "-c", s, NULL);
    00458       _exit(1);
    00459    } else if (pid > 0) {
    00460       for(;;) {
    00461          res = wait4(pid, &status, 0, &rusage);
    00462          if (res > -1) {
    00463             res = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
    00464             break;
    00465          } else if (errno != EINTR)
    00466             break;
    00467       }
    00468    } else {
    00469       ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
    00470       res = -1;
    00471    }
    00472
    00473    ast_mutex_lock(&safe_system_lock);
    00474    level = --safe_system_level;
    00475
    00476    /* only restore the handler if we are the last one */
    00477    if (level == 0)
    00478       signal(SIGCHLD, safe_system_prev_handler);
    00479
    00480    ast_mutex_unlock(&safe_system_lock);
    00481
    00482    return res;
    00483 }

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.

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

    00794 {
    00795    struct sched_param sched;
    00796    memset(&sched, 0, sizeof(sched));
    00797 #ifdef __linux__
    00798 #undef sched_setscheduler
    00799    if (pri) {
    00800       sched.sched_priority = 10;
    00801       if (sched_setscheduler(0, SCHED_RR, &sched)) {
    00802          ast_log(LOG_WARNING, "Unable to set high priority\n");
    00803          return -1;
    00804       } else
    00805          if (option_verbose)
    00806             ast_verbose("Set to realtime thread\n");
    00807    } else {
    00808       sched.sched_priority = 0;
    00809       /* According to the manpage, this can never fail, with these parameters. */
    00810       sched_setscheduler(0, SCHED_OTHER, &sched);
    00811    }
    00812 #else
    00813 #undef setpriority
    00814    if (pri) {
    00815       if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
    00816          ast_log(LOG_WARNING, "Unable to set high priority\n");
    00817          return -1;
    00818       } else
    00819          if (option_verbose)
    00820             ast_verbose("Set to high priority\n");
    00821    } else {
    00822       /* According to the manpage, this can never fail, with these parameters. */
    00823       setpriority(PRIO_PROCESS, 0, 0);
    00824    }
    00825 #endif
    00826    return 0;
    00827 }

static int ast_tryconnect | ( | void |  | ) | `[static]`

Definition at line 718 of file asterisk.c.

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

Referenced by ast_el_read_char(), and main().

    00719 {
    00720    struct sockaddr_un sunaddr;
    00721    int res;
    00722    ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
    00723    if (ast_consock < 0) {
    00724       ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
    00725       return 0;
    00726    }
    00727    memset(&sunaddr, 0, sizeof(sunaddr));
    00728    sunaddr.sun_family = AF_LOCAL;
    00729    ast_copy_string(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path));
    00730    res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
    00731    if (res) {
    00732       close(ast_consock);
    00733       ast_consock = -1;
    00734       return 0;
    00735    } else
    00736       return 1;
    00737 }

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

References ast_mutex_lock(), ast_mutex_unlock(), atexits, ast_atexit::func, and ast_atexit::next.

Referenced by ast_register_atexit(), and do_reload().

    00395 {
    00396    struct ast_atexit *ae, *prev = NULL;
    00397    ast_mutex_lock(&atexitslock);
    00398    ae = atexits;
    00399    while(ae) {
    00400       if (ae->func == func) {
    00401          if (prev)
    00402             prev->next = ae->next;
    00403          else
    00404             atexits = ae->next;
    00405          break;
    00406       }
    00407       prev = ae;
    00408       ae = ae->next;
    00409    }
    00410    ast_mutex_unlock(&atexitslock);
    00411 }

void ast_unregister_file_version | ( | const char * | file | ) |

Unregister a source code file from the core.

Parameters:

  | file | the source file name

Returns:
  nothing

This function should not be called directly, but instead the ASTERISK_FILE_VERSION macro should be used to automatically unregister the file when the module is unloaded.

Definition at line 274 of file asterisk.c.

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

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

static void child_handler | ( | int | sig | ) | `[static]`

Definition at line 763 of file asterisk.c.

References n.

Referenced by main().

    00764 {
    00765    /* Must not ever ast_log or ast_verbose within signal handler */
    00766    int n, status;
    00767
    00768    /*
    00769     * Reap all dead children -- not just one
    00770     */
    00771    for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++)
    00772       ;
    00773    if (n == 0 && option_debug)
    00774       printf("Huh?  Child handler, but nobody there?\n");
    00775    signal(sig, child_handler);
    00776 }

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

Definition at line 1568 of file asterisk.c.

References AST_CLI_COMPLETE_EOF, ast_cli_completion_matches(), ast_cli_display_match_list(), ast_cli_generatornummatches(), ast_el_strtoarr(), fdprint(), free, malloc, and realloc.

Referenced by ast_el_initialize().

    01569 {
    01570    int len=0;
    01571    char *ptr;
    01572    int nummatches = 0;
    01573    char **matches;
    01574    int retval = CC_ERROR;
    01575    char buf[2048];
    01576    int res;
    01577
    01578    LineInfo *lf = (LineInfo *)el_line(el);
    01579
    01580    *(char *)lf->cursor = '\0';
    01581    ptr = (char *)lf->cursor;
    01582    if (ptr) {
    01583       while (ptr > lf->buffer) {
    01584          if (isspace(*ptr)) {
    01585             ptr++;
    01586             break;
    01587          }
    01588          ptr--;
    01589       }
    01590    }
    01591
    01592    len = lf->cursor - ptr;
    01593
    01594    if (option_remote) {
    01595       snprintf(buf, sizeof(buf),"_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);
    01596       fdprint(ast_consock, buf);
    01597       res = read(ast_consock, buf, sizeof(buf));
    01598       buf[res] = '\0';
    01599       nummatches = atoi(buf);
    01600
    01601       if (nummatches > 0) {
    01602          char *mbuf;
    01603          int mlen = 0, maxmbuf = 2048;
    01604          /* Start with a 2048 byte buffer */
    01605          mbuf = malloc(maxmbuf);
    01606          if (!mbuf)
    01607             return (char *)(CC_ERROR);
    01608          snprintf(buf, sizeof(buf),"_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);
    01609          fdprint(ast_consock, buf);
    01610          res = 0;
    01611          mbuf[0] = '\0';
    01612          while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
    01613             if (mlen + 1024 > maxmbuf) {
    01614                /* Every step increment buffer 1024 bytes */
    01615                maxmbuf += 1024;
    01616                mbuf = realloc(mbuf, maxmbuf);
    01617                if (!mbuf)
    01618                   return (char *)(CC_ERROR);
    01619             }
    01620             /* Only read 1024 bytes at a time */
    01621             res = read(ast_consock, mbuf + mlen, 1024);
    01622             if (res > 0)
    01623                mlen += res;
    01624          }
    01625          mbuf[mlen] = '\0';
    01626
    01627          matches = ast_el_strtoarr(mbuf);
    01628          free(mbuf);
    01629       } else
    01630          matches = (char **) NULL;
    01631
    01632
    01633    } else {
    01634
    01635       nummatches = ast_cli_generatornummatches((char *)lf->buffer,ptr);
    01636       matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
    01637    }
    01638
    01639    if (matches) {
    01640       int i;
    01641       int matches_num, maxlen, match_len;
    01642
    01643       if (matches[0][0] != '\0') {
    01644          el_deletestr(el, (int) len);
    01645          el_insertstr(el, matches[0]);
    01646          retval = CC_REFRESH;
    01647       }
    01648
    01649       if (nummatches == 1) {
    01650          /* Found an exact match */
    01651          el_insertstr(el, " ");
    01652          retval = CC_REFRESH;
    01653       } else {
    01654          /* Must be more than one match */
    01655          for (i=1, maxlen=0; matches[i]; i++) {
    01656             match_len = strlen(matches[i]);
    01657             if (match_len > maxlen)
    01658                maxlen = match_len;
    01659          }
    01660          matches_num = i - 1;
    01661          if (matches_num >1) {
    01662             fprintf(stdout, "\n");
    01663             ast_cli_display_match_list(matches, nummatches, maxlen);
    01664             retval = CC_REDISPLAY;
    01665          } else {
    01666             el_insertstr(el," ");
    01667             retval = CC_REFRESH;
    01668          }
    01669       }
    01670       for (i=0; matches[i]; i++)
    01671          free(matches[i]);
    01672       free(matches);
    01673    }
    01674
    01675    return (char *)(long)retval;
    01676 }

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

Definition at line 1335 of file asterisk.c.

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

Referenced by ast_el_initialize().

    01336 {
    01337    static char prompt[200];
    01338    char *pfmt;
    01339    int color_used=0;
    01340    char term_code[20];
    01341
    01342    if ((pfmt = getenv("ASTERISK_PROMPT"))) {
    01343       char *t = pfmt, *p = prompt;
    01344       memset(prompt, 0, sizeof(prompt));
    01345       while (*t != '\0' && *p < sizeof(prompt)) {
    01346          if (*t == '%') {
    01347             char hostname[MAXHOSTNAMELEN]="";
    01348             int i;
    01349             time_t ts;
    01350             struct tm tm;
    01351 #ifdef linux
    01352             FILE *LOADAVG;
    01353 #endif
    01354             int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
    01355
    01356             t++;
    01357             switch (*t) {
    01358                case 'C': /* color */
    01359                   t++;
    01360                   if (sscanf(t, "%30d;%30d%n", &fgcolor, &bgcolor, &i) == 2) {
    01361                      strncat(p, term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
    01362                      t += i - 1;
    01363                   } else if (sscanf(t, "%30d%n", &fgcolor, &i) == 1) {
    01364                      strncat(p, term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
    01365                      t += i - 1;
    01366                   }
    01367
    01368                   /* If the color has been reset correctly, then there's no need to reset it later */
    01369                   if ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) {
    01370                      color_used = 0;
    01371                   } else {
    01372                      color_used = 1;
    01373                   }
    01374                   break;
    01375                case 'd': /* date */
    01376                   memset(&tm, 0, sizeof(struct tm));
    01377                   time(&ts);
    01378                   if (localtime_r(&ts, &tm)) {
    01379                      strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm);
    01380                   }
    01381                   break;
    01382                case 'h': /* hostname */
    01383                   if (!gethostname(hostname, sizeof(hostname) - 1)) {
    01384                      strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
    01385                   } else {
    01386                      strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
    01387                   }
    01388                   break;
    01389                case 'H': /* short hostname */
    01390                   if (!gethostname(hostname, sizeof(hostname) - 1)) {
    01391                      for (i=0;i<sizeof(hostname);i++) {
    01392                         if (hostname[i] == '.') {
    01393                            hostname[i] = '\0';
    01394                            break;
    01395                         }
    01396                      }
    01397                      strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
    01398                   } else {
    01399                      strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
    01400                   }
    01401                   break;
    01402 #ifdef linux
    01403                case 'l': /* load avg */
    01404                   t++;
    01405                   if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
    01406                      float avg1, avg2, avg3;
    01407                      int actproc, totproc, npid, which;
    01408                      fscanf(LOADAVG, "%30f %30f %30f %30d/%30d %30d",
    01409                         &avg1, &avg2, &avg3, &actproc, &totproc, &npid);
    01410                      if (sscanf(t, "%30d", &which) == 1) {
    01411                         switch (which) {
    01412                            case 1:
    01413                               snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1);
    01414                               break;
    01415                            case 2:
    01416                               snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2);
    01417                               break;
    01418                            case 3:
    01419                               snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3);
    01420                               break;
    01421                            case 4:
    01422                               snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc);
    01423                               break;
    01424                            case 5:
    01425                               snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid);
    01426                               break;
    01427                         }
    01428                      }
    01429                   }
    01430                   break;
    01431 #endif
    01432                case 't': /* time */
    01433                   memset(&tm, 0, sizeof(struct tm));
    01434                   time(&ts);
    01435                   if (localtime_r(&ts, &tm)) {
    01436                      strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm);
    01437                   }
    01438                   break;
    01439                case '#': /* process console or remote? */
    01440                   if (! option_remote) {
    01441                      strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1);
    01442                   } else {
    01443                      strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1);
    01444                   }
    01445                   break;
    01446                case '%': /* literal % */
    01447                   strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1);
    01448                   break;
    01449                case '\0': /* % is last character - prevent bug */
    01450                   t--;
    01451                   break;
    01452             }
    01453             while (*p != '\0') {
    01454                p++;
    01455             }
    01456             t++;
    01457          } else {
    01458             *p = *t;
    01459             p++;
    01460             t++;
    01461          }
    01462       }
    01463       if (color_used) {
    01464          /* Force colors back to normal at end */
    01465          term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code));
    01466          if (strlen(term_code) > sizeof(prompt) - strlen(prompt)) {
    01467             strncat(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code));
    01468          } else {
    01469             strncat(p, term_code, sizeof(term_code));
    01470          }
    01471       }
    01472    } else if (remotehostname)
    01473       snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT2, remotehostname);
    01474    else
    01475       snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT);
    01476
    01477    return(prompt);
    01478 }

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

Definition at line 351 of file asterisk.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, list, and strdup.

    00352 {
    00353    struct file_version *find;
    00354    int which = 0;
    00355    char *ret = NULL;
    00356    int matchlen = strlen(word);
    00357
    00358    if (pos != 3)
    00359       return NULL;
    00360
    00361    AST_LIST_LOCK(&file_versions);
    00362    AST_LIST_TRAVERSE(&file_versions, find, list) {
    00363       if (!strncasecmp(word, find->file, matchlen)) {
    00364          if (++which > state) {
    00365             ret = strdup(find->file);
    00366             break;
    00367          }
    00368       }
    00369    }
    00370    AST_LIST_UNLOCK(&file_versions);
    00371
    00372    return ret;
    00373 }

static void console_verboser | ( | const char * | s,
|  | int | pos,
|  | int | replace,
|  | int | complete |
| ) |  |  | `[static]`

Definition at line 969 of file asterisk.c.

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

Referenced by main().

    00970 {
    00971    char tmp[80];
    00972    const char *c=NULL;
    00973    /* Return to the beginning of the line */
    00974    if (!pos) {
    00975       fprintf(stdout, "\r");
    00976       if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) ||
    00977          (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) ||
    00978          (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) ||
    00979          (c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1)))
    00980          fputs(tmp, stdout);
    00981    }
    00982    if (c)
    00983       fputs(c + pos,stdout);
    00984    else
    00985       fputs(s + pos,stdout);
    00986    fflush(stdout);
    00987    if (complete) {
    00988       /* Wake up a poll()ing console */
    00989       if (option_console && consolethread != AST_PTHREADT_NULL)
    00990          pthread_kill(consolethread, SIGURG);
    00991    }
    00992 }

static void consolehandler | ( | char * | s | ) | `[static]`

Definition at line 1004 of file asterisk.c.

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

Referenced by main().

    01005 {
    01006    printf(term_end());
    01007    fflush(stdout);
    01008
    01009    /* Called when readline data is available */
    01010    if (!ast_all_zeros(s))
    01011       ast_el_add_history(s);
    01012    /* The real handler for bang */
    01013    if (s[0] == '!') {
    01014       if (s[1])
    01015          ast_safe_system(s+1);
    01016       else
    01017          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
    01018    } else
    01019       ast_cli_command(STDOUT_FILENO, s);
    01020 }

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

Definition at line 413 of file asterisk.c.

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

    00414 {
    00415    return write(fd, s, strlen(s) + 1);
    00416 }

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

Definition at line 958 of file asterisk.c.

References COLOR_GRAY, and term_color().

Referenced by console_verboser().

    00959 {
    00960    const char *c;
    00961    if (!strncmp(s, cmp, strlen(cmp))) {
    00962       c = s + strlen(cmp);
    00963       term_color(outbuf, cmp, COLOR_GRAY, 0, maxout);
    00964       return c;
    00965    }
    00966    return NULL;
    00967 }

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

Definition at line 1148 of file asterisk.c.

References ast_cancel_shutdown(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    01149 {
    01150    if (argc != 2)
    01151       return RESULT_SHOWUSAGE;
    01152    ast_cancel_shutdown();
    01153    shuttingdown = 0;
    01154    return RESULT_SUCCESS;
    01155 }

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

Definition at line 1157 of file asterisk.c.

References RESULT_SUCCESS.

    01158 {
    01159    return RESULT_SUCCESS;
    01160 }

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

Definition at line 1132 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    01133 {
    01134    if (argc != 2)
    01135       return RESULT_SHOWUSAGE;
    01136    quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
    01137    return RESULT_SUCCESS;
    01138 }

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

Definition at line 1124 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    01125 {
    01126    if (argc != 2)
    01127       return RESULT_SHOWUSAGE;
    01128    quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */);
    01129    return RESULT_SUCCESS;
    01130 }

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

Definition at line 1140 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    01141 {
    01142    if (argc != 3)
    01143       return RESULT_SHOWUSAGE;
    01144    quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */);
    01145    return RESULT_SUCCESS;
    01146 }

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

CLI command to list module versions

Definition at line 297 of file asterisk.c.

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

    00298 {
    00299 #define FORMAT "%-25.25s %-40.40s\n"
    00300    struct file_version *iterator;
    00301    regex_t regexbuf;
    00302    int havepattern = 0;
    00303    int havename = 0;
    00304    int count_files = 0;
    00305
    00306    switch (argc) {
    00307    case 5:
    00308       if (!strcasecmp(argv[3], "like")) {
    00309          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
    00310             return RESULT_SHOWUSAGE;
    00311          havepattern = 1;
    00312       } else
    00313          return RESULT_SHOWUSAGE;
    00314       break;
    00315    case 4:
    00316       havename = 1;
    00317       break;
    00318    case 3:
    00319       break;
    00320    default:
    00321       return RESULT_SHOWUSAGE;
    00322    }
    00323
    00324    ast_cli(fd, FORMAT, "File", "Revision");
    00325    ast_cli(fd, FORMAT, "----", "--------");
    00326    AST_LIST_LOCK(&file_versions);
    00327    AST_LIST_TRAVERSE(&file_versions, iterator, list) {
    00328       if (havename && strcasecmp(iterator->file, argv[3]))
    00329          continue;
    00330
    00331       if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
    00332          continue;
    00333
    00334       ast_cli(fd, FORMAT, iterator->file, iterator->version);
    00335       count_files++;
    00336       if (havename)
    00337          break;
    00338    }
    00339    AST_LIST_UNLOCK(&file_versions);
    00340    if (!havename) {
    00341       ast_cli(fd, "%d files listed.\n", count_files);
    00342    }
    00343
    00344    if (havepattern)
    00345       regfree(&regexbuf);
    00346
    00347    return RESULT_SUCCESS;
    00348 #undef FORMAT
    00349 }

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

Definition at line 1108 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    01109 {
    01110    if (argc != 2)
    01111       return RESULT_SHOWUSAGE;
    01112    quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
    01113    return RESULT_SUCCESS;
    01114 }

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

Definition at line 1100 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    01101 {
    01102    if (argc != 2)
    01103       return RESULT_SHOWUSAGE;
    01104    quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */);
    01105    return RESULT_SUCCESS;
    01106 }

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

Definition at line 1116 of file asterisk.c.

References quit_handler(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    01117 {
    01118    if (argc != 3)
    01119       return RESULT_SHOWUSAGE;
    01120    quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
    01121    return RESULT_SUCCESS;
    01122 }

static void hup_handler | ( | int | num | ) | `[static]`

Definition at line 750 of file asterisk.c.

References sig_flags.

Referenced by main().

    00751 {
    00752    int a = 0;
    00753    if (option_verbose > 1)
    00754       printf("Received HUP signal -- Reloading configs\n");
    00755    if (restartnow)
    00756       execvp(_argv[0], _argv);
    00757    sig_flags.need_reload = 1;
    00758    if (sig_alert_pipe[1] != -1)
    00759       write(sig_alert_pipe[1], &a, sizeof(a));
    00760    signal(num, hup_handler);
    00761 }

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

Definition at line 584 of file asterisk.c.

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

Referenced by ast_makesocket().

    00585 {
    00586    struct sockaddr_un sunaddr;
    00587    int s;
    00588    socklen_t len;
    00589    int x;
    00590    int flags;
    00591    struct pollfd fds[1];
    00592    pthread_attr_t attr;
    00593    pthread_attr_init(&attr);
    00594    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    00595    for(;;) {
    00596       if (ast_socket < 0)
    00597          return NULL;
    00598       fds[0].fd = ast_socket;
    00599       fds[0].events= POLLIN;
    00600       s = poll(fds, 1, -1);
    00601       pthread_testcancel();
    00602       if (s < 0) {
    00603          if (errno != EINTR)
    00604             ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno));
    00605          continue;
    00606       }
    00607       len = sizeof(sunaddr);
    00608       s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
    00609       if (s < 0) {
    00610          if (errno != EINTR)
    00611             ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
    00612       } else {
    00613          for (x=0;x<AST_MAX_CONNECTS;x++) {
    00614             if (consoles[x].fd < 0) {
    00615                if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) {
    00616                   ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno));
    00617                   consoles[x].fd = -1;
    00618                   fdprint(s, "Server failed to create pipe\n");
    00619                   close(s);
    00620                   break;
    00621                }
    00622                flags = fcntl(consoles[x].p[1], F_GETFL);
    00623                fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
    00624                consoles[x].fd = s;
    00625                if (ast_pthread_create(&consoles[x].t, &attr, netconsole, &consoles[x])) {
    00626                   ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno));
    00627                   close(consoles[x].p[0]);
    00628                   close(consoles[x].p[1]);
    00629                   consoles[x].fd = -1;
    00630                   fdprint(s, "Server failed to spawn thread\n");
    00631                   close(s);
    00632                }
    00633                break;
    00634             }
    00635          }
    00636          if (x >= AST_MAX_CONNECTS) {
    00637             fdprint(s, "No more connections allowed\n");
    00638             ast_log(LOG_WARNING, "No more connections allowed\n");
    00639             close(s);
    00640          } else if (consoles[x].fd > -1) {
    00641             if (option_verbose > 2)
    00642                ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection\n");
    00643          }
    00644       }
    00645    }
    00646    return NULL;
    00647 }

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

Definition at line 2036 of file asterisk.c.

References __ast_mm_init(), __quit_handler(), ast_alaw_init(), ast_cdr_engine_init(), ast_channels_init(), ast_cli_register_multiple(), ast_device_state_engine_init(), ast_el_initialize(), ast_el_read_history(), ast_enum_init(), ast_enum_reload(), ast_file_init(), ast_image_init(), ast_log(), ast_makesocket(), ast_pthread_create, ast_readconfig(), ast_register_verbose(), ast_remotecontrol(), ast_rtp_init(), ast_rtp_reload(), ast_set_priority(), ast_strlen_zero(), ast_tryconnect(), ast_ulaw_init(), ast_utils_init(), ast_verbose(), astdb_init(), callerid_init(), child_handler(), COLOR_BLACK, COLOR_BRWHITE, console_verboser(), consolehandler(), dnsmgr_init(), dnsmgr_start_refresh(), 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(), reload_logger(), reload_manager(), set_icon(), set_title(), setenv(), show_cli_help(), show_version(), tdd_init(), term_color(), term_end(), term_init(), term_quit(), test_for_thread_safety(), urg_handler(), and WELCOME_MESSAGE.

    02037 {
    02038    int c;
    02039    char filename[80] = "";
    02040    char hostname[MAXHOSTNAMELEN]="";
    02041    char tmp[80];
    02042    char * xarg = NULL;
    02043    int x;
    02044    FILE *f;
    02045    sigset_t sigs;
    02046    int num;
    02047    int is_child_of_nonroot=0;
    02048    char *buf;
    02049    char *runuser=NULL, *rungroup=NULL;
    02050
    02051    /* Remember original args for restart */
    02052    if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) {
    02053       fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1);
    02054       argc = sizeof(_argv) / sizeof(_argv[0]) - 1;
    02055    }
    02056    for (x=0;x<argc;x++)
    02057       _argv[x] = argv[x];
    02058    _argv[x] = NULL;
    02059
    02060    /* if the progname is rasterisk consider it a remote console */
    02061    if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
    02062       option_remote++;
    02063       option_nofork++;
    02064    }
    02065    if (gethostname(hostname, sizeof(hostname)-1))
    02066       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
    02067    ast_mainpid = getpid();
    02068    ast_ulaw_init();
    02069    ast_alaw_init();
    02070    callerid_init();
    02071    ast_utils_init();
    02072    tdd_init();
    02073    /* When Asterisk restarts after it has dropped the root privileges,
    02074     * it can't issue setuid(), setgid(), setgroups() or set_priority()
    02075     * */
    02076    if (getenv("ASTERISK_ALREADY_NONROOT"))
    02077       is_child_of_nonroot=1;
    02078    if (getenv("HOME"))
    02079       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
    02080    /* Check if we're root */
    02081    /*
    02082    if (geteuid()) {
    02083       ast_log(LOG_ERROR, "Must be run as root\n");
    02084       exit(1);
    02085    }
    02086    */
    02087    /* Check for options */
    02088    while((c=getopt(argc, argv, "tThfdvVqprRgcinx:U:G:C:L:M:")) != -1) {
    02089       switch(c) {
    02090       case 'd':
    02091          option_debug++;
    02092          option_nofork++;
    02093          break;
    02094       case 'c':
    02095          option_console++;
    02096          option_nofork++;
    02097          break;
    02098       case 'f':
    02099          option_nofork++;
    02100          break;
    02101       case 'n':
    02102          option_nocolor++;
    02103          break;
    02104       case 'r':
    02105          option_remote++;
    02106          option_nofork++;
    02107          break;
    02108       case 'R':
    02109          option_remote++;
    02110          option_nofork++;
    02111          option_reconnect++;
    02112          break;
    02113       case 'p':
    02114          option_highpriority++;
    02115          break;
    02116       case 'v':
    02117          option_verbose++;
    02118          option_nofork++;
    02119          break;
    02120       case 'M':
    02121          if ((sscanf(optarg, "%30d", &option_maxcalls) != 1) || (option_maxcalls < 0))
    02122             option_maxcalls = 0;
    02123          break;
    02124       case 'L':
    02125          if ((sscanf(optarg, "%30lf", &option_maxload) != 1) || (option_maxload < 0.0))
    02126             option_maxload = 0.0;
    02127          break;
    02128       case 'q':
    02129          option_quiet++;
    02130          break;
    02131       case 't':
    02132          option_cache_record_files++;
    02133          break;
    02134       case 'T':
    02135          option_timestamp++;
    02136          break;
    02137       case 'x':
    02138          option_exec++;
    02139          xarg = optarg;
    02140          break;
    02141       case 'C':
    02142          ast_copy_string((char *)ast_config_AST_CONFIG_FILE,optarg,sizeof(ast_config_AST_CONFIG_FILE));
    02143          option_overrideconfig++;
    02144          break;
    02145       case 'i':
    02146          option_initcrypto++;
    02147          break;
    02148       case'g':
    02149          option_dumpcore++;
    02150          break;
    02151       case 'h':
    02152          show_cli_help();
    02153          exit(0);
    02154       case 'V':
    02155          show_version();
    02156          exit(0);
    02157       case 'U':
    02158          runuser = optarg;
    02159          break;
    02160       case 'G':
    02161          rungroup = optarg;
    02162          break;
    02163       case '?':
    02164          exit(1);
    02165       }
    02166    }
    02167
    02168    /* For remote connections, change the name of the remote connection.
    02169     * We do this for the benefit of init scripts (which need to know if/when
    02170     * the main asterisk process has died yet). */
    02171    if (option_remote) {
    02172       strcpy(argv[0], "rasterisk");
    02173       for (x = 1; x < argc; x++) {
    02174          argv[x] = argv[0] + 10;
    02175       }
    02176    }
    02177
    02178    if (option_console && !option_verbose)
    02179       ast_verbose("[ Reading Master Configuration ]");
    02180    ast_readconfig();
    02181
    02182    if (option_dumpcore) {
    02183       struct rlimit l;
    02184       memset(&l, 0, sizeof(l));
    02185       l.rlim_cur = RLIM_INFINITY;
    02186       l.rlim_max = RLIM_INFINITY;
    02187       if (setrlimit(RLIMIT_CORE, &l)) {
    02188          ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
    02189       }
    02190    }
    02191
    02192    if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
    02193       rungroup = ast_config_AST_RUN_GROUP;
    02194    if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
    02195       runuser = ast_config_AST_RUN_USER;
    02196 #ifndef __CYGWIN__
    02197
    02198    if (!is_child_of_nonroot)
    02199       ast_set_priority(option_highpriority);
    02200
    02201    if (!is_child_of_nonroot && rungroup) {
    02202       struct group *gr;
    02203       gr = getgrnam(rungroup);
    02204       if (!gr) {
    02205          ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
    02206          exit(1);
    02207       }
    02208       if (setgid(gr->gr_gid)) {
    02209          ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
    02210          exit(1);
    02211       }
    02212       if (setgroups(0, NULL)) {
    02213          ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
    02214          exit(1);
    02215       }
    02216       if (option_verbose)
    02217          ast_verbose("Running as group '%s'\n", rungroup);
    02218    }
    02219
    02220    if (!is_child_of_nonroot && runuser) {
    02221       struct passwd *pw;
    02222       pw = getpwnam(runuser);
    02223       if (!pw) {
    02224          ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
    02225          exit(1);
    02226       }
    02227       if (!rungroup) {
    02228          if (setgid(pw->pw_gid)) {
    02229             ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
    02230             exit(1);
    02231          }
    02232          if (initgroups(pw->pw_name, pw->pw_gid)) {
    02233             ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser);
    02234             exit(1);
    02235          }
    02236       }
    02237       if (setuid(pw->pw_uid)) {
    02238          ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
    02239          exit(1);
    02240       }
    02241       setenv("ASTERISK_ALREADY_NONROOT","yes",1);
    02242       if (option_verbose)
    02243          ast_verbose("Running as user '%s'\n", runuser);
    02244    }
    02245
    02246 #endif /* __CYGWIN__ */
    02247
    02248 #ifdef linux
    02249
    02250    if (geteuid() && option_dumpcore) {
    02251       if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
    02252          ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
    02253       }
    02254    }
    02255
    02256 #endif
    02257
    02258    term_init();
    02259    printf(term_end());
    02260    fflush(stdout);
    02261
    02262    if (option_console && !option_verbose)
    02263       ast_verbose("[ Initializing Custom Configuration Options ]");
    02264    /* custom config setup */
    02265    register_config_cli();
    02266    read_config_maps();
    02267
    02268
    02269    if (option_console) {
    02270       if (el_hist == NULL || el == NULL)
    02271          ast_el_initialize();
    02272
    02273       if (!ast_strlen_zero(filename))
    02274          ast_el_read_history(filename);
    02275    }
    02276
    02277    if (ast_tryconnect()) {
    02278       /* One is already running */
    02279       if (option_remote) {
    02280          if (option_exec) {
    02281             ast_remotecontrol(xarg);
    02282             quit_handler(0, 0, 0, 0);
    02283             exit(0);
    02284          }
    02285          printf(term_quit());
    02286          ast_register_verbose(console_verboser);
    02287          WELCOME_MESSAGE;
    02288          ast_remotecontrol(NULL);
    02289          quit_handler(0, 0, 0, 0);
    02290          exit(0);
    02291       } else {
    02292          ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", (char *)ast_config_AST_SOCKET);
    02293          printf(term_quit());
    02294          exit(1);
    02295       }
    02296    } else if (option_remote || option_exec) {
    02297       ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n",ast_config_AST_SOCKET);
    02298       printf(term_quit());
    02299       exit(1);
    02300    }
    02301    /* Blindly write pid file since we couldn't connect */
    02302    unlink((char *)ast_config_AST_PID);
    02303    f = fopen((char *)ast_config_AST_PID, "w");
    02304    if (f) {
    02305       fprintf(f, "%d\n", (int)getpid());
    02306       fclose(f);
    02307    } else
    02308       ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", (char *)ast_config_AST_PID, strerror(errno));
    02309
    02310    if (!option_verbose && !option_debug && !option_nofork && !option_console) {
    02311       daemon(0,0);
    02312       /* Blindly re-write pid file since we are forking */
    02313       unlink((char *)ast_config_AST_PID);
    02314       f = fopen((char *)ast_config_AST_PID, "w");
    02315       if (f) {
    02316          fprintf(f, "%d\n", (int)getpid());
    02317          fclose(f);
    02318       } else
    02319          ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", (char *)ast_config_AST_PID, strerror(errno));
    02320       ast_mainpid = getpid();
    02321    }
    02322
    02323    /* Test recursive mutex locking. */
    02324    if (test_for_thread_safety())
    02325       ast_verbose("Warning! Asterisk is not thread safe.\n");
    02326
    02327    ast_makesocket();
    02328    sigemptyset(&sigs);
    02329    sigaddset(&sigs, SIGHUP);
    02330    sigaddset(&sigs, SIGTERM);
    02331    sigaddset(&sigs, SIGINT);
    02332    sigaddset(&sigs, SIGPIPE);
    02333    sigaddset(&sigs, SIGWINCH);
    02334    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
    02335    if (option_console || option_verbose || option_remote)
    02336       ast_register_verbose(console_verboser);
    02337    /* Print a welcome message if desired */
    02338    if (option_verbose || option_console) {
    02339       WELCOME_MESSAGE;
    02340    }
    02341    if (option_console && !option_verbose)
    02342       ast_verbose("[ Booting...");
    02343
    02344    signal(SIGURG, urg_handler);
    02345    signal(SIGINT, __quit_handler);
    02346    signal(SIGTERM, __quit_handler);
    02347    signal(SIGHUP, hup_handler);
    02348    signal(SIGCHLD, child_handler);
    02349    signal(SIGPIPE, SIG_IGN);
    02350
    02351    /* ensure that the random number generators are seeded with a different value every time
    02352       Asterisk is started
    02353    */
    02354    srand((unsigned int) getpid() + (unsigned int) time(NULL));
    02355    srandom((unsigned int) getpid() + (unsigned int) time(NULL));
    02356
    02357    if (init_logger()) {
    02358       printf(term_quit());
    02359       exit(1);
    02360    }
    02361    if (dnsmgr_init()) {
    02362       printf(term_quit());
    02363       exit(1);
    02364    }
    02365    /* load 'preload' modules, required for access to Realtime-mapped configuration files */
    02366    if (load_modules(1)) {
    02367       printf(term_quit());
    02368       exit(1);
    02369    }
    02370    ast_channels_init();
    02371    if (init_manager()) {
    02372       printf(term_quit());
    02373       exit(1);
    02374    }
    02375    if (ast_cdr_engine_init()) {
    02376       printf(term_quit());
    02377       exit(1);
    02378    }
    02379    if (ast_device_state_engine_init()) {
    02380       printf(term_quit());
    02381       exit(1);
    02382    }
    02383    ast_rtp_init();
    02384    if (ast_image_init()) {
    02385       printf(term_quit());
    02386       exit(1);
    02387    }
    02388    if (ast_file_init()) {
    02389       printf(term_quit());
    02390       exit(1);
    02391    }
    02392    if (load_pbx()) {
    02393       printf(term_quit());
    02394       exit(1);
    02395    }
    02396    if (init_framer()) {
    02397       printf(term_quit());
    02398       exit(1);
    02399    }
    02400    if (astdb_init()) {
    02401       printf(term_quit());
    02402       exit(1);
    02403    }
    02404    if (ast_enum_init()) {
    02405       printf(term_quit());
    02406       exit(1);
    02407    }
    02408    if (load_modules(0)) {
    02409       printf(term_quit());
    02410       exit(1);
    02411    }
    02412
    02413    dnsmgr_start_refresh();
    02414
    02415 #if 0
    02416    /* This should no longer be necessary */
    02417    /* sync cust config and reload some internals in case a custom config handler binded to them */
    02418    read_ast_cust_config();
    02419    reload_logger(0);
    02420    reload_manager();
    02421    ast_enum_reload();
    02422    ast_rtp_reload();
    02423 #endif
    02424
    02425
    02426    /* We might have the option of showing a console, but for now just
    02427       do nothing... */
    02428    if (option_console && !option_verbose)
    02429       ast_verbose(" ]\n");
    02430    if (option_verbose || option_console)
    02431       ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
    02432    if (option_nofork)
    02433       consolethread = pthread_self();
    02434
    02435    if (pipe(sig_alert_pipe))
    02436       sig_alert_pipe[0] = sig_alert_pipe[1] = -1;
    02437
    02438    fully_booted = 1;
    02439    pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
    02440 #ifdef __AST_DEBUG_MALLOC
    02441    __ast_mm_init();
    02442 #endif
    02443    time(&ast_startuptime);
    02444    ast_cli_register_multiple(core_cli, sizeof(core_cli) / sizeof(core_cli[0]));
    02445    if (option_console) {
    02446       /* Console stuff now... */
    02447       /* Register our quit function */
    02448       char title[256];
    02449       pthread_attr_t attr;
    02450       pthread_t dont_care;
    02451
    02452       pthread_attr_init(&attr);
    02453       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    02454       ast_pthread_create(&dont_care, &attr, monitor_sig_flags, NULL);
    02455       pthread_attr_destroy(&attr);
    02456
    02457       set_icon("Asterisk");
    02458       snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, ast_mainpid);
    02459       set_title(title);
    02460
    02461       for (;;) {
    02462          buf = (char *)el_gets(el, &num);
    02463
    02464          if (!buf && write(1, "", 1) < 0)
    02465             goto lostterm;
    02466
    02467          if (buf) {
    02468             if (buf[strlen(buf)-1] == '\n')
    02469                buf[strlen(buf)-1] = '\0';
    02470
    02471             consolehandler((char *)buf);
    02472          } else if (option_remote) {
    02473             if (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
    02474                  strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0) {
    02475                /* Whoa, stdout disappeared from under us... Make /dev/null's */
    02476                int fd;
    02477                fd = open("/dev/null", O_RDWR);
    02478                if (fd > -1) {
    02479                   dup2(fd, STDOUT_FILENO);
    02480                   dup2(fd, STDIN_FILENO);
    02481                } else
    02482                   ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console.  Bad things will happen!\n");
    02483                break;
    02484             }
    02485          }
    02486       }
    02487    }
    02488
    02489    monitor_sig_flags(NULL);
    02490
    02491 lostterm:
    02492    return 0;
    02493 }

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

Definition at line 2016 of file asterisk.c.

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

Referenced by main().

    02017 {
    02018    for (;;) {
    02019       struct pollfd p = { sig_alert_pipe[0], POLLIN, 0 };
    02020       int a;
    02021       poll(&p, 1, -1);
    02022       if (sig_flags.need_reload) {
    02023          sig_flags.need_reload = 0;
    02024          ast_module_reload(NULL);
    02025       }
    02026       if (sig_flags.need_quit) {
    02027          sig_flags.need_quit = 0;
    02028          quit_handler(0, 0, 1, 0);
    02029       }
    02030       read(sig_alert_pipe[0], &a, sizeof(a));
    02031    }
    02032
    02033    return NULL;
    02034 }

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

Definition at line 529 of file asterisk.c.

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

Referenced by listener().

    00530 {
    00531    struct console *con = vconsole;
    00532    char hostname[MAXHOSTNAMELEN]="";
    00533    char tmp[512];
    00534    int res;
    00535    struct pollfd fds[2];
    00536
    00537    if (gethostname(hostname, sizeof(hostname)-1))
    00538       ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
    00539    snprintf(tmp, sizeof(tmp), "%s/%d/%s\n", hostname, ast_mainpid, ASTERISK_VERSION);
    00540    fdprint(con->fd, tmp);
    00541    for(;;) {
    00542       fds[0].fd = con->fd;
    00543       fds[0].events = POLLIN;
    00544       fds[0].revents = 0;
    00545       fds[1].fd = con->p[0];
    00546       fds[1].events = POLLIN;
    00547       fds[1].revents = 0;
    00548
    00549       res = poll(fds, 2, -1);
    00550       if (res < 0) {
    00551          if (errno != EINTR)
    00552             ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno));
    00553          continue;
    00554       }
    00555       if (fds[0].revents) {
    00556          res = read(con->fd, tmp, sizeof(tmp));
    00557          if (res < 1) {
    00558             break;
    00559          }
    00560          tmp[res] = 0;
    00561          ast_cli_command(con->fd, tmp);
    00562       }
    00563       if (fds[1].revents) {
    00564          res = read(con->p[0], tmp, sizeof(tmp));
    00565          if (res < 1) {
    00566             ast_log(LOG_ERROR, "read returned %d\n", res);
    00567             break;
    00568          }
    00569          res = write(con->fd, tmp, res);
    00570          if (res < 1)
    00571             break;
    00572       }
    00573    }
    00574    if (option_verbose > 2)
    00575       ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection disconnected\n");
    00576    close(con->fd);
    00577    close(con->p[0]);
    00578    close(con->p[1]);
    00579    con->fd = -1;
    00580
    00581    return NULL;
    00582 }

static void network_verboser | ( | const char * | s,
|  | int | pos,
|  | int | replace,
|  | int | complete |
| ) |  |  | `[static]`

Definition at line 508 of file asterisk.c.

References ast_log(), ast_network_puts(), LOG_ERROR, and t.

Referenced by ast_makesocket().

    00510 {
    00511    if (replace) {
    00512       char *t = alloca(strlen(s) + 2);
    00513       if (t) {
    00514          sprintf(t, "\r%s", s);
    00515          if (complete)
    00516             ast_network_puts(t);
    00517       } else {
    00518          ast_log(LOG_ERROR, "Out of memory\n");
    00519          ast_network_puts(s);
    00520       }
    00521    } else {
    00522       if (complete)
    00523          ast_network_puts(s);
    00524    }
    00525 }

static void null_sig_handler | ( | int | signal | ) | `[static]`

NULL handler so we can collect the child exit status

Definition at line 419 of file asterisk.c.

Referenced by ast_safe_system().

    00420 {
    00421
    00422 }

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

Definition at line 842 of file asterisk.c.

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

    00843 {
    00844    char filename[80] = "";
    00845    time_t s,e;
    00846    int x;
    00847    /* Try to get as many CDRs as possible submitted to the backend engines (if in batch mode) */
    00848    ast_cdr_engine_term();
    00849    if (safeshutdown) {
    00850       shuttingdown = 1;
    00851       if (!nice) {
    00852          /* Begin shutdown routine, hanging up active channels */
    00853          ast_begin_shutdown(1);
    00854          if (option_verbose && option_console)
    00855             ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown");
    00856          time(&s);
    00857          for(;;) {
    00858             time(&e);
    00859             /* Wait up to 15 seconds for all channels to go away */
    00860             if ((e - s) > 15)
    00861                break;
    00862             if (!ast_active_channels())
    00863                break;
    00864             if (!shuttingdown)
    00865                break;
    00866             /* Sleep 1/10 of a second */
    00867             usleep(100000);
    00868          }
    00869       } else {
    00870          if (nice < 2)
    00871             ast_begin_shutdown(0);
    00872          if (option_verbose && option_console)
    00873             ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
    00874          for(;;) {
    00875             if (!ast_active_channels())
    00876                break;
    00877             if (!shuttingdown)
    00878                break;
    00879             sleep(1);
    00880          }
    00881       }
    00882
    00883       if (!shuttingdown) {
    00884          if (option_verbose && option_console)
    00885             ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown");
    00886          return;
    00887       }
    00888    }
    00889    if (option_console || option_remote) {
    00890       if (getenv("HOME"))
    00891          snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
    00892       if (!ast_strlen_zero(filename))
    00893          ast_el_write_history(filename);
    00894       if (el != NULL)
    00895          el_end(el);
    00896       if (el_hist != NULL)
    00897          history_end(el_hist);
    00898    }
    00899    if (option_verbose)
    00900       ast_verbose("Executing last minute cleanups\n");
    00901    ast_run_atexits();
    00902    /* Called on exit */
    00903    if (option_verbose && option_console)
    00904       ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num);
    00905    if (option_debug)
    00906       ast_log(LOG_DEBUG, "Asterisk ending (%d).\n", num);
    00907    manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
    00908    if (ast_socket > -1) {
    00909       pthread_cancel(lthread);
    00910       close(ast_socket);
    00911       ast_socket = -1;
    00912       unlink(ast_config_AST_SOCKET);
    00913    }
    00914    if (ast_consock > -1)
    00915       close(ast_consock);
    00916    if (!option_remote) unlink((char *)ast_config_AST_PID);
    00917    printf(term_quit());
    00918    if (restart) {
    00919       if (option_verbose || option_console)
    00920          ast_verbose("Preparing for Asterisk restart...\n");
    00921       /* Mark all FD's for closing on exec */
    00922       for (x=3;x<32768;x++) {
    00923          fcntl(x, F_SETFD, FD_CLOEXEC);
    00924       }
    00925       if (option_verbose || option_console)
    00926          ast_verbose("Restarting Asterisk NOW...\n");
    00927       restartnow = 1;
    00928
    00929       /* close logger */
    00930       close_logger();
    00931
    00932       /* If there is a consolethread running send it a SIGHUP
    00933          so it can execvp, otherwise we can do it ourselves */
    00934       if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) {
    00935          pthread_kill(consolethread, SIGHUP);
    00936          /* Give the signal handler some time to complete */
    00937          sleep(2);
    00938       } else
    00939          execvp(_argv[0], _argv);
    00940
    00941    } else {
    00942       /* close logger */
    00943       close_logger();
    00944    }
    00945    exit(0);
    00946 }

static int remoteconsolehandler | ( | char * | s | ) | `[static]`

Definition at line 1022 of file asterisk.c.

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

Referenced by ast_remotecontrol().

    01023 {
    01024    int ret = 0;
    01025
    01026    /* Called when readline data is available */
    01027    if (!ast_all_zeros(s))
    01028       ast_el_add_history(s);
    01029    /* The real handler for bang */
    01030    if (s[0] == '!') {
    01031       if (s[1])
    01032          ast_safe_system(s+1);
    01033       else
    01034          ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
    01035       ret = 1;
    01036    }
    01037    if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
    01038        (s[4] == '\0' || isspace(s[4]))) {
    01039       quit_handler(0, 0, 0, 0);
    01040       ret = 1;
    01041    }
    01042
    01043    return ret;
    01044 }

static void set_icon | ( | char * | text | ) | `[static]`

Definition at line 785 of file asterisk.c.

Referenced by main().

    00786 {
    00787    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
    00788       fprintf(stdout, "\033]1;%s\007", text);
    00789 }

static void set_title | ( | char * | text | ) | `[static]`

Set an X-term or screen title

Definition at line 779 of file asterisk.c.

Referenced by main().

    00780 {
    00781    if (getenv("TERM") && strstr(getenv("TERM"), "xterm"))
    00782       fprintf(stdout, "\033]2;%s\007", text);
    00783 }

static int show_cli_help | ( | void |  | ) | `[static]`

Definition at line 1843 of file asterisk.c.

Referenced by main().

    01843                                {
    01844    printf("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2005, Digium, Inc. and others.\n");
    01845    printf("Usage: asterisk [OPTIONS]\n");
    01846    printf("Valid Options:\n");
    01847    printf("   -V              Display version number and exit\n");
    01848    printf("   -C <configfile> Use an alternate configuration file\n");
    01849    printf("   -G <group>      Run as a group other than the caller\n");
    01850    printf("   -U <user>       Run as a user other than the caller\n");
    01851    printf("   -c              Provide console CLI\n");
    01852    printf("   -d              Enable extra debugging\n");
    01853    printf("   -f              Do not fork\n");
    01854    printf("   -g              Dump core in case of a crash\n");
    01855    printf("   -h              This help screen\n");
    01856    printf("   -i              Initialize crypto keys at startup\n");
    01857    printf("   -n              Disable console colorization\n");
    01858    printf("   -p              Run as pseudo-realtime thread\n");
    01859    printf("   -q              Quiet mode (suppress output)\n");
    01860    printf("   -r              Connect to Asterisk on this machine\n");
    01861    printf("   -R              Connect to Asterisk, and attempt to reconnect if disconnected\n");
    01862    printf("   -t              Record soundfiles in /var/tmp and move them where they belong after they are done.\n");
    01863    printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line of output to the CLI.\n");
    01864    printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
    01865    printf("   -x <cmd>        Execute command <cmd> (only valid with -r)\n");
    01866    printf("\n");
    01867    return 0;
    01868 }

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

Definition at line 1215 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

    01216 {
    01217    int x;
    01218
    01219    for (x = 0; x < sizeof(license_lines) / sizeof(license_lines[0]); x++)
    01220       ast_cli(fd, (char *) license_lines[x]);
    01221
    01222    return RESULT_SUCCESS;
    01223 }

static int show_version | ( | void |  | ) | `[static]`

Definition at line 1837 of file asterisk.c.

Referenced by main().

    01838 {
    01839    printf("Asterisk " ASTERISK_VERSION "\n");
    01840    return 0;
    01841 }

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

Definition at line 1186 of file asterisk.c.

References ast_cli(), and RESULT_SUCCESS.

    01187 {
    01188    int x;
    01189
    01190    for (x = 0; x < sizeof(warranty_lines) / sizeof(warranty_lines[0]); x++)
    01191       ast_cli(fd, (char *) warranty_lines[x]);
    01192
    01193    return RESULT_SUCCESS;
    01194 }

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

Referenced by main().

    00745 {
    00746    signal(num, urg_handler);
    00747    return;
    00748 }

## Variable Documentation

char* _argv[256]`[static]`

Definition at line 232 of file asterisk.c.

char abort_halt_help[]`[static]`

Initial value:

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

Definition at line 1046 of file asterisk.c.

char ast_config_AST_AGI_DIR[AST_CONFIG_MAX_PATH]

Definition at line 219 of file asterisk.c.

Referenced by launch_script().

char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH]

Definition at line 212 of file asterisk.c.

Referenced by ast_ael_compile(), compile_script(), config_text_file_load(), config_text_file_save(), handle_save_dialplan(), ices_exec(), and vm_change_password().

char ast_config_AST_CONFIG_FILE[AST_CONFIG_MAX_PATH]

Definition at line 213 of file asterisk.c.

char ast_config_AST_CTL[AST_CONFIG_MAX_PATH] = "asterisk.ctl"

Definition at line 230 of file asterisk.c.

char ast_config_AST_CTL_GROUP[AST_CONFIG_MAX_PATH] = "\0"

Definition at line 229 of file asterisk.c.

char ast_config_AST_CTL_OWNER[AST_CONFIG_MAX_PATH] = "\0"

Definition at line 228 of file asterisk.c.

char ast_config_AST_CTL_PERMISSIONS[AST_CONFIG_MAX_PATH]

Definition at line 227 of file asterisk.c.

char ast_config_AST_DB[AST_CONFIG_MAX_PATH]

Definition at line 220 of file asterisk.c.

Referenced by dbinit().

char ast_config_AST_KEY_DIR[AST_CONFIG_MAX_PATH]

Definition at line 221 of file asterisk.c.

Referenced by crypto_load(), init_keys(), and osp_build().

char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH]

Definition at line 218 of file asterisk.c.

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

char ast_config_AST_MODULE_DIR[AST_CONFIG_MAX_PATH]

Definition at line 214 of file asterisk.c.

Referenced by __load_resource(), add_module(), complete_fn(), file_ok_sel(), and load_modules().

char ast_config_AST_MONITOR_DIR[AST_CONFIG_MAX_PATH]

Definition at line 216 of file asterisk.c.

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

char ast_config_AST_PID[AST_CONFIG_MAX_PATH]

Definition at line 222 of file asterisk.c.

char ast_config_AST_RUN_DIR[AST_CONFIG_MAX_PATH]

Definition at line 224 of file asterisk.c.

char ast_config_AST_RUN_GROUP[AST_CONFIG_MAX_PATH]

Definition at line 226 of file asterisk.c.

char ast_config_AST_RUN_USER[AST_CONFIG_MAX_PATH]

Definition at line 225 of file asterisk.c.

char ast_config_AST_SOCKET[AST_CONFIG_MAX_PATH]

Definition at line 223 of file asterisk.c.

char ast_config_AST_SPOOL_DIR[AST_CONFIG_MAX_PATH]

Definition at line 215 of file asterisk.c.

Referenced by conf_run(), dictate_exec(), hasvoicemail_internal(), load_module(), and play_mailbox_owner().

char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH]

Definition at line 217 of file asterisk.c.

Referenced by ast_linear_stream(), build_filename(), dial_exec_full(), make_filename(), and reload_firmware().

int ast_consock = -1`[static]`

UNIX Socket for controlling another asterisk

Definition at line 182 of file asterisk.c.

time_t ast_lastreloadtime

Definition at line 198 of file asterisk.c.

Referenced by ast_module_reload(), and handle_showuptime().

int ast_mainpid

Definition at line 183 of file asterisk.c.

Referenced by safe_append(), and scan_service().

int ast_socket = -1`[static]`

UNIX Socket for allowing remote control

Definition at line 181 of file asterisk.c.

time_t ast_startuptime

Definition at line 197 of file asterisk.c.

Referenced by handle_showuptime().

struct ast_atexit * atexits`[static]`

Referenced by ast_register_atexit(), ast_run_atexits(), and ast_unregister_atexit().

char bang_help[]`[static]`

Initial value:

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

Definition at line 1078 of file asterisk.c.

struct console consoles[AST_MAX_CONNECTS]

Definition at line 204 of file asterisk.c.

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

pthread_t consolethread = AST_PTHREADT_NULL`[static]`

Definition at line 235 of file asterisk.c.

Referenced by show_console().

struct ast_cli_entry core_cli[]`[static]`

Definition at line 1229 of file asterisk.c.

char debug_filename[AST_FILENAME_MAX] = ""

Definition at line 179 of file asterisk.c.

Referenced by ast_log(), and handle_debuglevel().

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE

Definition at line 206 of file asterisk.c.

Referenced by ast_channel_alloc().

EditLine* el = NULL`[static]`

Definition at line 201 of file asterisk.c.

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

History* el_hist = NULL`[static]`

Definition at line 200 of file asterisk.c.

int fully_booted = 0

Definition at line 177 of file asterisk.c.

Referenced by __load_resource().

const char* license_lines[]`[static]`

Definition at line 1196 of file asterisk.c.

pthread_t lthread`[static]`

Definition at line 527 of file asterisk.c.

unsigned int need_quit

Definition at line 240 of file asterisk.c.

unsigned int need_reload

Definition at line 239 of file asterisk.c.

char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR

Definition at line 178 of file asterisk.c.

Referenced by ast_writefile().

char* remotehostname`[static]`

Definition at line 202 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 1069 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 1064 of file asterisk.c.

char restart_when_convenient_help[]`[static]`

Initial value:

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

Definition at line 1074 of file asterisk.c.

int restartnow = 0`[static]`

Definition at line 234 of file asterisk.c.

unsigned int safe_system_level = 0`[static]`

Definition at line 425 of file asterisk.c.

void* safe_system_prev_handler`[static]`

Definition at line 426 of file asterisk.c.

char show_license_help[]`[static]`

Initial value:

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

Definition at line 1086 of file asterisk.c.

char show_version_files_help[]`[static]`

Initial value:

    "Usage: show version files [like <pattern>]\n"
    "       Shows 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 291 of file asterisk.c.

char show_warranty_help[]`[static]`

Initial value:

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

Definition at line 1082 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 1055 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 1051 of file asterisk.c.

char shutdown_when_convenient_help[]`[static]`

Initial value:

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

Definition at line 1060 of file asterisk.c.

int shuttingdown = 0`[static]`

Definition at line 233 of file asterisk.c.

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

Definition at line 237 of file asterisk.c.

struct { ... } sig_flags`[static]`

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

const char* warranty_lines[]`[static]`

Definition at line 1161 of file asterisk.c.