Newer
Older
/* Remember original args for restart */
if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) {
fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1);
argc = sizeof(_argv) / sizeof(_argv[0]) - 1;
}
for (x=0;x<argc;x++)
_argv[x] = argv[x];
_argv[x] = NULL;
/* if the progname is rasterisk consider it a remote console */
if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
}
if (gethostname(hostname, sizeof(hostname)-1))
ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
Mark Spencer
committed
ast_mainpid = getpid();
Kevin P. Fleming
committed
/* When Asterisk restarts after it has dropped the root privileges,
* it can't issue setuid(), setgid(), setgroups() or set_priority()
* */
if (getenv("ASTERISK_ALREADY_NONROOT"))
is_child_of_nonroot=1;
if (getenv("HOME"))
snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
if (geteuid()) {
ast_log(LOG_ERROR, "Must be run as root\n");
exit(1);
}
while((c=getopt(argc, argv, "tThfdvVqprRgcinx:U:G:C:L:M:")) != -1) {
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
case 'R':
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
break;
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
case 'M':
if ((sscanf(optarg, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0))
option_maxcalls = 0;
break;
case 'L':
if ((sscanf(optarg, "%lf", &option_maxload) != 1) || (option_maxload < 0.0))
option_maxload = 0.0;
break;
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC);
Russell Bryant
committed
ast_copy_string(ast_config_AST_CONFIG_FILE, optarg, sizeof(ast_config_AST_CONFIG_FILE));
ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
case 'U':
runuser = optarg;
break;
case 'G':
rungroup = optarg;
break;
Kevin P. Fleming
committed
/* For remote connections, change the name of the remote connection.
* We do this for the benefit of init scripts (which need to know if/when
* the main asterisk process has died yet). */
Russell Bryant
committed
if (ast_opt_remote) {
Kevin P. Fleming
committed
strcpy(argv[0], "rasterisk");
for (x = 1; x < argc; x++) {
argv[x] = argv[0] + 10;
}
}
Kevin P. Fleming
committed
if (ast_opt_console && !option_verbose)
ast_verbose("[ Reading Master Configuration ]");
ast_readconfig();
Russell Bryant
committed
if (ast_opt_dump_core) {
struct rlimit l;
memset(&l, 0, sizeof(l));
l.rlim_cur = RLIM_INFINITY;
l.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_CORE, &l)) {
ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
}
}
if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
rungroup = ast_config_AST_RUN_GROUP;
if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
runuser = ast_config_AST_RUN_USER;
Russell Bryant
committed
ast_set_priority(ast_opt_high_priority);
Kevin P. Fleming
committed
if (!is_child_of_nonroot && rungroup) {
struct group *gr;
gr = getgrnam(rungroup);
if (!gr) {
ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
exit(1);
}
ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", gr->gr_gid, rungroup);
exit(1);
}
if (setgroups(0, NULL)) {
ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
exit(1);
}
if (option_verbose)
ast_verbose("Running as group '%s'\n", rungroup);
}
Kevin P. Fleming
committed
if (!is_child_of_nonroot && runuser) {
struct passwd *pw;
pw = getpwnam(runuser);
if (!pw) {
ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
exit(1);
}
if (!rungroup) {
if (setgid(pw->pw_gid)) {
ast_log(LOG_WARNING, "Unable to setgid to %d!\n", pw->pw_gid);
exit(1);
}
if (initgroups(pw->pw_name, pw->pw_gid)) {
ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser);
exit(1);
}
if (setuid(pw->pw_uid)) {
ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", pw->pw_uid, runuser);
exit(1);
}
Kevin P. Fleming
committed
setenv("ASTERISK_ALREADY_NONROOT","yes",1);
if (option_verbose)
ast_verbose("Running as user '%s'\n", runuser);
}
term_init();
printf(term_end());
fflush(stdout);
Mark Spencer
committed
Russell Bryant
committed
if (ast_opt_console && !option_verbose)
ast_verbose("[ Initializing Custom Configuration Options ]");
/* custom config setup */
register_config_cli();
Russell Bryant
committed
if (ast_opt_console) {
if (el_hist == NULL || el == NULL)
ast_el_initialize();
if (!ast_strlen_zero(filename))
ast_el_read_history(filename);
if (ast_tryconnect()) {
/* One is already running */
Russell Bryant
committed
if (ast_opt_remote) {
if (ast_opt_exec) {
Russell Bryant
committed
ast_log(LOG_ERROR, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
Russell Bryant
committed
} else if (ast_opt_remote || ast_opt_exec) {
ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n",ast_config_AST_SOCKET);
/* Blindly write pid file since we couldn't connect */
Russell Bryant
committed
unlink(ast_config_AST_PID);
f = fopen(ast_config_AST_PID, "w");
if (f) {
fprintf(f, "%d\n", getpid());
fclose(f);
} else
Russell Bryant
committed
ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
Russell Bryant
committed
if (!option_verbose && !option_debug && !ast_opt_no_fork && !ast_opt_console) {
/* Blindly re-write pid file since we are forking */
Russell Bryant
committed
unlink(ast_config_AST_PID);
f = fopen(ast_config_AST_PID, "w");
if (f) {
fprintf(f, "%d\n", getpid());
fclose(f);
} else
Russell Bryant
committed
ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
/* Test recursive mutex locking. */
if (test_for_thread_safety())
ast_verbose("Warning! Asterisk is not thread safe.\n");
ast_makesocket();
sigemptyset(&sigs);
sigaddset(&sigs, SIGHUP);
sigaddset(&sigs, SIGTERM);
sigaddset(&sigs, SIGINT);
sigaddset(&sigs, SIGPIPE);
sigaddset(&sigs, SIGWINCH);
pthread_sigmask(SIG_BLOCK, &sigs, NULL);
Russell Bryant
committed
if (ast_opt_console || option_verbose || ast_opt_remote)
Russell Bryant
committed
if (option_verbose || ast_opt_console) {
Russell Bryant
committed
if (ast_opt_console && !option_verbose)
signal(SIGINT, __quit_handler);
signal(SIGTERM, __quit_handler);
signal(SIGCHLD, child_handler);
signal(SIGPIPE, SIG_IGN);
Kevin P. Fleming
committed
/* ensure that the random number generators are seeded with a different value every time
Asterisk is started
*/
srand((unsigned int) getpid() + (unsigned int) time(NULL));
initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool));
Kevin P. Fleming
committed
if (dnsmgr_init()) {
printf(term_quit());
exit(1);
}
Kevin P. Fleming
committed
/* load 'preload' modules, required for access to Realtime-mapped configuration files */
if (load_modules(1)) {
printf(term_quit());
exit(1);
}
ast_channels_init();
if (init_manager()) {
printf(term_quit());
exit(1);
}
if (ast_cdr_engine_init()) {
printf(term_quit());
exit(1);
}
Kevin P. Fleming
committed
if (ast_device_state_engine_init()) {
printf(term_quit());
exit(1);
}
#if defined(T38_SUPPORT)
ast_udptl_init();
#endif
if (ast_image_init()) {
printf(term_quit());
Mark Spencer
committed
if (ast_file_init()) {
printf(term_quit());
exit(1);
}
Kevin P. Fleming
committed
if (load_modules(0)) {
}
if (init_framer()) {
printf(term_quit());
if (astdb_init()) {
printf(term_quit());
exit(1);
}
if (ast_enum_init()) {
printf(term_quit());
exit(1);
}
#if 0
/* This should no longer be necessary */
/* sync cust config and reload some internals in case a custom config handler binded to them */
read_ast_cust_config();
reload_manager();
ast_enum_reload();
ast_rtp_reload();
#endif
Anthony Minessale II
committed
/* We might have the option of showing a console, but for now just
do nothing... */
Russell Bryant
committed
if (ast_opt_console && !option_verbose)
Russell Bryant
committed
if (option_verbose || ast_opt_console)
ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
Russell Bryant
committed
if (ast_opt_no_fork)
Russell Bryant
committed
ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
Mark Spencer
committed
#ifdef __AST_DEBUG_MALLOC
__ast_mm_init();
#endif
Kevin P. Fleming
committed
ast_cli_register_multiple(core_cli, sizeof(core_cli) / sizeof(core_cli[0]));
Russell Bryant
committed
if (ast_opt_console) {
/* Console stuff now... */
/* Register our quit function */
Mark Spencer
committed
snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, ast_mainpid);
for (;;) {
buf = (char *)el_gets(el, &num);
if (buf) {
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
consolehandler((char *)buf);
} else {
if (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n",
strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0) {
/* Whoa, stdout disappeared from under us... Make /dev/null's */
int fd;
fd = open("/dev/null", O_RDWR);
if (fd > -1) {
dup2(fd, STDOUT_FILENO);
dup2(fd, STDIN_FILENO);
} else
ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n");
break;
}
for(;;) { /* apparently needed for the MACos */
struct pollfd p = { -1 /* no descriptor */, 0, 0 };
poll(&p, 0, -1);
}