Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

asterisk.c File Reference

#include <unistd.h>
#include <stdlib.h>
#include <sys/poll.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/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 <sys/resource.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <sched.h>
#include <asterisk/io.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "editline/histedit.h"
#include "asterisk.h"
#include <asterisk/config.h>
#include <asterisk/config_pvt.h>
#include <grp.h>
#include <pwd.h>

Go to the source code of this file.

Data Structures

struct  ast_atexit
struct  console

Defines

#define AST_MAX_CONNECTS   128
#define NUM_MSGS   64
#define WELCOME_MESSAGE
#define ASTERISK_PROMPT   "*CLI> "
#define ASTERISK_PROMPT2   "%s*CLI> "

Functions

 AST_MUTEX_DEFINE_STATIC (atexitslock)
int ast_register_atexit (void(*func)(void))
void ast_unregister_atexit (void(*func)(void))
int ast_safe_system (const char *s)
 Safely spawn an external program while closingn file descriptors. More...

void ast_console_puts (const char *string)
int main (int argc, char *argv[])

Variables

int option_verbose = 0
int option_debug = 0
int option_nofork = 0
int option_quiet = 0
int option_console = 0
int option_highpriority = 0
int option_remote = 0
int option_exec = 0
int option_initcrypto = 0
int option_nocolor
int option_dumpcore = 0
int option_cache_record_files = 0
int option_overrideconfig = 0
int option_reconnect = 0
int fully_booted = 0
char record_cache_dir [AST_CACHE_DIR_LEN] = AST_TMP_DIR
int ast_mainpid
time_t ast_startuptime
time_t ast_lastreloadtime
console consoles [AST_MAX_CONNECTS]
char defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE
char ast_config_AST_CONFIG_DIR [AST_CONFIG_MAX_PATH]
char ast_config_AST_CONFIG_FILE [AST_CONFIG_MAX_PATH]
char ast_config_AST_MODULE_DIR [AST_CONFIG_MAX_PATH]
char ast_config_AST_SPOOL_DIR [AST_CONFIG_MAX_PATH]
char ast_config_AST_VAR_DIR [AST_CONFIG_MAX_PATH]
char ast_config_AST_LOG_DIR [AST_CONFIG_MAX_PATH]
char ast_config_AST_AGI_DIR [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_PID [AST_CONFIG_MAX_PATH]
char ast_config_AST_SOCKET [AST_CONFIG_MAX_PATH]
char ast_config_AST_RUN_DIR [AST_CONFIG_MAX_PATH]
char ast_config_AST_DATA_DIR [AST_CONFIG_MAX_PATH]


Define Documentation

#define AST_MAX_CONNECTS   128
 

Definition at line 61 of file asterisk.c.

#define ASTERISK_PROMPT   "*CLI> "
 

Definition at line 858 of file asterisk.c.

#define ASTERISK_PROMPT2   "%s*CLI> "
 

Definition at line 860 of file asterisk.c.

#define NUM_MSGS   64
 

Definition at line 62 of file asterisk.c.

#define WELCOME_MESSAGE
 

Value:

ast_verbose( "Asterisk " ASTERISK_VERSION ", Copyright (C) 1999-2004 Digium.\n"); \
      ast_verbose( "Written by Mark Spencer <markster@digium.com>\n"); \
      ast_verbose( "=========================================================================\n")

Definition at line 64 of file asterisk.c.

Referenced by main().


Function Documentation

void ast_console_puts const char *    string
 

Definition at line 237 of file asterisk.c.

References string.

Referenced by ast_log().

00238 {
00239    fputs(string, stdout);
00240    fflush(stdout);
00241    ast_network_puts(string);
00242 }

AST_MUTEX_DEFINE_STATIC atexitslock   
 

int ast_register_atexit void(*    func)(void)
 

Definition at line 134 of file asterisk.c.

References ast_mutex_lock, ast_mutex_unlock, ast_unregister_atexit(), and malloc.

00135 {
00136    int res = -1;
00137    struct ast_atexit *ae;
00138    ast_unregister_atexit(func);
00139    ae = malloc(sizeof(struct ast_atexit));
00140    ast_mutex_lock(&atexitslock);
00141    if (ae) {
00142       memset(ae, 0, sizeof(struct ast_atexit));
00143       ae->next = atexits;
00144       ae->func = func;
00145       atexits = ae;
00146       res = 0;
00147    }
00148    ast_mutex_unlock(&atexitslock);
00149    return res;
00150 }

int ast_safe_system const char *    s
 

Safely spawn an external program while closingn file descriptors.

Definition at line 182 of file asterisk.c.

References ast_log(), LOG_WARNING, and s.

Referenced by ast_closestream().

00183 {
00184    /* XXX This function needs some optimization work XXX */
00185    pid_t pid;
00186    int x;
00187    int res;
00188    struct rusage rusage;
00189    int status;
00190    void (*prev_handler) = signal(SIGCHLD, null_sig_handler);
00191    pid = fork();
00192    if (pid == 0) {
00193       /* Close file descriptors and launch system command */
00194       for (x=STDERR_FILENO + 1; x<4096;x++) {
00195          close(x);
00196       }
00197       res = execl("/bin/sh", "/bin/sh", "-c", s, NULL);
00198       exit(1);
00199    } else if (pid > 0) {
00200       for(;;) {
00201          res = wait4(pid, &status, 0, &rusage);
00202          if (res > -1) {
00203             if (WIFEXITED(status))
00204                res = WEXITSTATUS(status);
00205             else
00206                res = -1;
00207             break;
00208          } else {
00209             if (errno != EINTR) 
00210                break;
00211          }
00212       }
00213    } else {
00214       ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
00215       res = -1;
00216    }
00217    signal(SIGCHLD, prev_handler);
00218    return res;
00219 }

void ast_unregister_atexit void(*    func)(void)
 

Definition at line 152 of file asterisk.c.

References ast_mutex_lock, and ast_mutex_unlock.

Referenced by ast_register_atexit().

00153 {
00154    struct ast_atexit *ae, *prev = NULL;
00155    ast_mutex_lock(&atexitslock);
00156    ae = atexits;
00157    while(ae) {
00158       if (ae->func == func) {
00159          if (prev)
00160             prev->next = ae->next;
00161          else
00162             atexits = ae->next;
00163          break;
00164       }
00165       prev = ae;
00166       ae = ae->next;
00167    }
00168    ast_mutex_unlock(&atexitslock);
00169 }

int main int    argc,
char *    argv[]
 

Definition at line 1571 of file asterisk.c.

References __ast_mm_init(), ast_alaw_init(), ast_cli(), ast_cli_register(), ast_config_AST_CONFIG_FILE, ast_config_AST_PID, ast_config_AST_SOCKET, ast_enum_init(), ast_enum_reload(), ast_file_init(), ast_image_init(), ast_log(), ast_mainpid, ast_register_verbose(), ast_rtp_init(), ast_rtp_reload(), ast_startuptime, ast_ulaw_init(), ast_utils_init(), ast_verbose(), astdb_init(), callerid_init(), COLOR_BLACK, COLOR_BRWHITE, fully_booted, init_framer(), init_logger(), init_manager(), load_modules(), load_pbx(), LOG_ERROR, LOG_WARNING, option_cache_record_files, option_console, option_debug, option_dumpcore, option_exec, option_highpriority, option_initcrypto, option_nocolor, option_nofork, option_overrideconfig, option_quiet, option_reconnect, option_remote, option_verbose, poll(), read_ast_cust_config(), register_config_cli(), reload_logger(), reload_manager(), tdd_init(), term_color(), term_end(), term_init(), term_quit(), test_for_thread_safety(), and WELCOME_MESSAGE.

01572 {
01573    int c;
01574    char filename[80] = "";
01575    char hostname[256];
01576    char tmp[80];
01577    char * xarg = NULL;
01578    int x;
01579    FILE *f;
01580    sigset_t sigs;
01581    int num;
01582    char *buf;
01583    char *runuser=NULL, *rungroup=NULL;
01584 
01585    /* Remember original args for restart */
01586    if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) {
01587       fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1);
01588       argc = sizeof(_argv) / sizeof(_argv[0]) - 1;
01589    }
01590    for (x=0;x<argc;x++)
01591       _argv[x] = argv[x];
01592    _argv[x] = NULL;
01593 
01594    /* if the progname is rasterisk consider it a remote console */
01595    if ( argv[0] && (strstr(argv[0], "rasterisk")) != NULL)  {
01596       option_remote++;
01597       option_nofork++;
01598    }
01599    if (gethostname(hostname, sizeof(hostname)))
01600       strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
01601    ast_mainpid = getpid();
01602    ast_ulaw_init();
01603    ast_alaw_init();
01604    callerid_init();
01605    ast_utils_init();
01606    tdd_init();
01607    if (getenv("HOME")) 
01608       snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
01609    /* Check for options */
01610    while((c=getopt(argc, argv, "thfdvVqprRgcinx:U:G:C:")) != -1) {
01611       switch(c) {
01612       case 'd':
01613          option_debug++;
01614          option_nofork++;
01615          break;
01616       case 'c':
01617          option_console++;
01618          option_nofork++;
01619          break;
01620       case 'f':
01621          option_nofork++;
01622          break;
01623       case 'n':
01624          option_nocolor++;
01625          break;
01626       case 'r':
01627          option_remote++;
01628          option_nofork++;
01629          break;
01630       case 'R':
01631          option_remote++;
01632          option_nofork++;
01633          option_reconnect++;
01634          break;
01635       case 'p':
01636          option_highpriority++;
01637          break;
01638       case 'v':
01639          option_verbose++;
01640          option_nofork++;
01641          break;
01642       case 'q':
01643          option_quiet++;
01644          break;
01645       case 't':
01646          option_cache_record_files++;
01647          break;
01648       case 'x':
01649          option_exec++;
01650          xarg = optarg;
01651          break;
01652       case 'C':
01653          strncpy((char *)ast_config_AST_CONFIG_FILE,optarg,sizeof(ast_config_AST_CONFIG_FILE) - 1);
01654          option_overrideconfig++;
01655          break;
01656       case 'i':
01657          option_initcrypto++;
01658          break;
01659       case'g':
01660          option_dumpcore++;
01661          break;
01662       case 'h':
01663          show_cli_help();
01664          exit(0);
01665       case 'V':
01666          show_version();
01667          exit(0);
01668       case 'U':
01669          runuser = optarg;
01670          break;
01671       case 'G':
01672          rungroup = optarg;
01673          break;
01674       case '?':
01675          exit(1);
01676       }
01677    }
01678 
01679    if (option_dumpcore) {
01680       struct rlimit l;
01681       memset(&l, 0, sizeof(l));
01682       l.rlim_cur = RLIM_INFINITY;
01683       l.rlim_max = RLIM_INFINITY;
01684       if (setrlimit(RLIMIT_CORE, &l)) {
01685          ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
01686       }
01687    }
01688 
01689    if (rungroup) {
01690       struct group *gr;
01691       gr = getgrnam(rungroup);
01692       if (!gr) {
01693          ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
01694          exit(1);
01695       }
01696       if (setgid(gr->gr_gid)) {
01697          ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", gr->gr_gid, rungroup);
01698          exit(1);
01699       }
01700       if (option_verbose)
01701          ast_verbose("Running as group '%s'\n", rungroup);
01702    }
01703 
01704    if (set_priority(option_highpriority)) {
01705       exit(1);
01706    }
01707    if (runuser) {
01708       struct passwd *pw;
01709       pw = getpwnam(runuser);
01710       if (!pw) {
01711          ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
01712          exit(1);
01713       }
01714       if (setuid(pw->pw_uid)) {
01715          ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", pw->pw_uid, runuser);
01716          exit(1);
01717       }
01718       if (option_verbose)
01719          ast_verbose("Running as user '%s'\n", runuser);
01720    }
01721 
01722    term_init();
01723    printf(term_end());
01724    fflush(stdout);
01725 
01726    if (option_console && !option_verbose) 
01727       ast_verbose("[ Reading Master Configuration ]");
01728    ast_readconfig();
01729 
01730    if (option_console && !option_verbose) 
01731       ast_verbose("[ Initializing Custom Configuration Options]");
01732    /* custom config setup */
01733    register_config_cli();
01734    read_ast_cust_config();
01735    
01736 
01737    if (option_console) {
01738       if (el_hist == NULL || el == NULL)
01739          ast_el_initialize();
01740 
01741       if (!ast_strlen_zero(filename))
01742          ast_el_read_history(filename);
01743    }
01744 
01745    if (ast_tryconnect()) {
01746       /* One is already running */
01747       if (option_remote) {
01748          if (option_exec) {
01749             ast_remotecontrol(xarg);
01750             quit_handler(0, 0, 0, 0);
01751             exit(0);
01752          }
01753          printf(term_quit());
01754          ast_register_verbose(console_verboser);
01755          WELCOME_MESSAGE;
01756          ast_remotecontrol(NULL);
01757          quit_handler(0, 0, 0, 0);
01758          exit(0);
01759       } else {
01760          ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", (char *)ast_config_AST_SOCKET);
01761          printf(term_quit());
01762          exit(1);
01763       }
01764    } else if (option_remote || option_exec) {
01765       ast_log(LOG_ERROR, "Unable to connect to remote asterisk\n");
01766       printf(term_quit());
01767       exit(1);
01768    }
01769    /* Blindly write pid file since we couldn't connect */
01770    unlink((char *)ast_config_AST_PID);
01771    f = fopen((char *)ast_config_AST_PID, "w");
01772    if (f) {
01773       fprintf(f, "%d\n", getpid());
01774       fclose(f);
01775    } else
01776       ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", (char *)ast_config_AST_PID, strerror(errno));
01777 
01778    if (!option_verbose && !option_debug && !option_nofork && !option_console) {
01779       daemon(0,0);
01780       /* Blindly re-write pid file since we are forking */
01781       unlink((char *)ast_config_AST_PID);
01782       f = fopen((char *)ast_config_AST_PID, "w");
01783       if (f) {
01784          fprintf(f, "%d\n", getpid());
01785          fclose(f);
01786       } else
01787          ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", (char *)ast_config_AST_PID, strerror(errno));
01788    }
01789 
01790    /* Test recursive mutex locking. */
01791    if (test_for_thread_safety())
01792       ast_verbose("Warning! Asterisk is not thread safe.\n");
01793 
01794    ast_makesocket();
01795    sigemptyset(&sigs);
01796    sigaddset(&sigs, SIGHUP);
01797    sigaddset(&sigs, SIGTERM);
01798    sigaddset(&sigs, SIGINT);
01799    sigaddset(&sigs, SIGPIPE);
01800    sigaddset(&sigs, SIGWINCH);
01801    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
01802    if (option_console || option_verbose || option_remote)
01803       ast_register_verbose(console_verboser);
01804    /* Print a welcome message if desired */
01805    if (option_verbose || option_console) {
01806       WELCOME_MESSAGE;
01807    }
01808    if (option_console && !option_verbose) 
01809       ast_verbose("[ Booting...");
01810 
01811    signal(SIGURG, urg_handler);
01812    signal(SIGINT, __quit_handler);
01813    signal(SIGTERM, __quit_handler);
01814    signal(SIGHUP, hup_handler);
01815    signal(SIGCHLD, child_handler);
01816    signal(SIGPIPE, SIG_IGN);
01817 
01818    if (init_logger()) {
01819       printf(term_quit());
01820       exit(1);
01821    }
01822    if (init_manager()) {
01823       printf(term_quit());
01824       exit(1);
01825    }
01826    ast_rtp_init();
01827    if (ast_image_init()) {
01828       printf(term_quit());
01829       exit(1);
01830    }
01831    if (ast_file_init()) {
01832       printf(term_quit());
01833       exit(1);
01834    }
01835    if (load_pbx()) {
01836       printf(term_quit());
01837       exit(1);
01838    }
01839    if (load_modules()) {
01840       printf(term_quit());
01841       exit(1);
01842    }
01843    if (init_framer()) {
01844       printf(term_quit());
01845       exit(1);
01846    }
01847    if (astdb_init()) {
01848       printf(term_quit());
01849       exit(1);
01850    }
01851    if (ast_enum_init()) {
01852       printf(term_quit());
01853       exit(1);
01854    }
01855    /* sync cust config and reload some internals in case a custom config handler binded to them */
01856    read_ast_cust_config();
01857    reload_logger(0);
01858    reload_manager();
01859    ast_enum_reload();
01860    ast_rtp_reload();
01861 
01862 
01863    /* We might have the option of showing a console, but for now just
01864       do nothing... */
01865    if (option_console && !option_verbose)
01866       ast_verbose(" ]\n");
01867    if (option_verbose || option_console)
01868       ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
01869    if (option_nofork)
01870       consolethread = pthread_self();
01871    fully_booted = 1;
01872    pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
01873 #ifdef __AST_DEBUG_MALLOC
01874    __ast_mm_init();
01875 #endif   
01876    time(&ast_startuptime);
01877    ast_cli_register(&astshutdownnow);
01878    ast_cli_register(&astshutdowngracefully);
01879    ast_cli_register(&astrestartnow);
01880    ast_cli_register(&astrestartgracefully);
01881    ast_cli_register(&astrestartwhenconvenient);
01882    ast_cli_register(&astshutdownwhenconvenient);
01883    ast_cli_register(&aborthalt);
01884    ast_cli_register(&astbang);
01885    if (option_console) {
01886       /* Console stuff now... */
01887       /* Register our quit function */
01888       char title[256];
01889       set_icon("Asterisk");
01890       snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, ast_mainpid);
01891       set_title(title);
01892        ast_cli_register(&quit);
01893        ast_cli_register(&astexit);
01894 
01895       for (;;) {
01896          buf = (char *)el_gets(el, &num);
01897          if (buf) {
01898             if (buf[strlen(buf)-1] == '\n')
01899                buf[strlen(buf)-1] = '\0';
01900 
01901             consolehandler((char *)buf);
01902          } else {
01903             if (option_remote)
01904                ast_cli(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n");
01905          }
01906       }
01907 
01908    } else {
01909       /* Do nothing */
01910       for(;;) 
01911          poll(NULL,0, -1);
01912    }
01913    return 0;
01914 }


Variable Documentation

char ast_config_AST_AGI_DIR[AST_CONFIG_MAX_PATH]
 

Definition at line 121 of file asterisk.c.

char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH]
 

Definition at line 115 of file asterisk.c.

char ast_config_AST_CONFIG_FILE[AST_CONFIG_MAX_PATH]
 

Definition at line 116 of file asterisk.c.

Referenced by main().

char ast_config_AST_DATA_DIR[AST_CONFIG_MAX_PATH]
 

Definition at line 127 of file asterisk.c.

char ast_config_AST_DB[AST_CONFIG_MAX_PATH]
 

Definition at line 122 of file asterisk.c.

char ast_config_AST_KEY_DIR[AST_CONFIG_MAX_PATH]
 

Definition at line 123 of file asterisk.c.

char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH]
 

Definition at line 120 of file asterisk.c.

char ast_config_AST_MODULE_DIR[AST_CONFIG_MAX_PATH]
 

Definition at line 117 of file asterisk.c.

char ast_config_AST_PID[AST_CONFIG_MAX_PATH]
 

Definition at line 124 of file asterisk.c.

Referenced by main().

char ast_config_AST_RUN_DIR[AST_CONFIG_MAX_PATH]
 

Definition at line 126 of file asterisk.c.

char ast_config_AST_SOCKET[AST_CONFIG_MAX_PATH]
 

Definition at line 125 of file asterisk.c.

Referenced by main().

char ast_config_AST_SPOOL_DIR[AST_CONFIG_MAX_PATH]
 

Definition at line 118 of file asterisk.c.

char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH]
 

Definition at line 119 of file asterisk.c.

time_t ast_lastreloadtime
 

Definition at line 101 of file asterisk.c.

int ast_mainpid
 

Definition at line 87 of file asterisk.c.

Referenced by main().

time_t ast_startuptime
 

Definition at line 100 of file asterisk.c.

Referenced by main().

struct console consoles[AST_MAX_CONNECTS]
 

Definition at line 107 of file asterisk.c.

char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE
 

Definition at line 109 of file asterisk.c.

int fully_booted = 0
 

Definition at line 82 of file asterisk.c.

Referenced by main().

int option_cache_record_files = 0
 

Definition at line 79 of file asterisk.c.

Referenced by main().

int option_console = 0
 

Definition at line 72 of file asterisk.c.

Referenced by main().

int option_debug = 0
 

Definition at line 69 of file asterisk.c.

Referenced by main().

int option_dumpcore = 0
 

Definition at line 78 of file asterisk.c.

Referenced by main().

int option_exec = 0
 

Definition at line 75 of file asterisk.c.

Referenced by main().

int option_highpriority = 0
 

Definition at line 73 of file asterisk.c.

Referenced by main().

int option_initcrypto = 0
 

Definition at line 76 of file asterisk.c.

Referenced by main().

int option_nocolor
 

Definition at line 77 of file asterisk.c.

Referenced by main().

int option_nofork = 0
 

Definition at line 70 of file asterisk.c.

Referenced by main().

int option_overrideconfig = 0
 

Definition at line 80 of file asterisk.c.

Referenced by main().

int option_quiet = 0
 

Definition at line 71 of file asterisk.c.

Referenced by main().

int option_reconnect = 0
 

Definition at line 81 of file asterisk.c.

Referenced by main().

int option_remote = 0
 

Definition at line 74 of file asterisk.c.

Referenced by main().

int option_verbose = 0
 

Definition at line 68 of file asterisk.c.

Referenced by main().

char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR
 

Definition at line 83 of file asterisk.c.


Generated on Thu Oct 28 11:32:59 2004 for Asterisk by doxygen1.2.15