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>

Include dependency graph for asterisk.c:

Go to the source code of this file.

Data Structures

struct  console
struct  ast_atexit

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.
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
struct 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]


Define Documentation

#define AST_MAX_CONNECTS   128

Definition at line 61 of file asterisk.c.

#define ASTERISK_PROMPT   "*CLI> "

Definition at line 859 of file asterisk.c.

#define ASTERISK_PROMPT2   "%s*CLI> "

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


Function Documentation

void ast_console_puts ( const char *  string  ) 

Definition at line 236 of file asterisk.c.

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

AST_MUTEX_DEFINE_STATIC ( atexitslock   ) 

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

Definition at line 133 of file asterisk.c.

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

int ast_safe_system ( const char *  s  ) 

Safely spawn an external program while closingn file descriptors.

Definition at line 181 of file asterisk.c.

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

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

Definition at line 151 of file asterisk.c.

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

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

Definition at line 1571 of file asterisk.c.

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


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.

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.

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.

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.

Definition at line 101 of file asterisk.c.

Definition at line 87 of file asterisk.c.

Definition at line 100 of file asterisk.c.

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.

Definition at line 79 of file asterisk.c.

int option_console = 0

Definition at line 72 of file asterisk.c.

int option_debug = 0

Definition at line 69 of file asterisk.c.

int option_dumpcore = 0

Definition at line 78 of file asterisk.c.

int option_exec = 0

Definition at line 75 of file asterisk.c.

Definition at line 73 of file asterisk.c.

Definition at line 76 of file asterisk.c.

Definition at line 77 of file asterisk.c.

int option_nofork = 0

Definition at line 70 of file asterisk.c.

Definition at line 80 of file asterisk.c.

int option_quiet = 0

Definition at line 71 of file asterisk.c.

Definition at line 81 of file asterisk.c.

int option_remote = 0

Definition at line 74 of file asterisk.c.

int option_verbose = 0

Definition at line 68 of file asterisk.c.

char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR

Definition at line 83 of file asterisk.c.


Generated on Wed Oct 28 17:00:49 2009 for Asterisk by  doxygen 1.5.6