Skip to content
Snippets Groups Projects
asterisk.c 74.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • Mark Spencer's avatar
    Mark Spencer committed
    	if (!version)
    		version = "<Version Unknown>";
    
    Mark Spencer's avatar
    Mark Spencer committed
    	strsep(&stringp, ".");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (cpid)
    		pid = atoi(cpid);
    	else
    		pid = -1;
    
    	snprintf(tmp, sizeof(tmp), "set verbose atleast %d", option_verbose);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	fdprint(ast_consock, tmp);
    
    	snprintf(tmp, sizeof(tmp), "set debug atleast %d", option_debug);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	remotehostname = hostname;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (getenv("HOME")) 
    		snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (el_hist == NULL || el == NULL)
    		ast_el_initialize();
    
    	el_set(el, EL_GETCFN, ast_el_read_char);
    
    
    	if (!ast_strlen_zero(filename))
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_el_read_history(filename);
    
    
    	if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */
    
    Mark Spencer's avatar
    Mark Spencer committed
    		char tempchar;
    
    		struct pollfd fds[0];
    		fds[0].fd = ast_consock;
    		fds[0].events = POLLIN;
    		fds[0].revents = 0;
    		while(poll(fds, 1, 100) > 0) {
    			ast_el_read_char(el, &tempchar);
    		}
    
    Mark Spencer's avatar
    Mark Spencer committed
    		return;
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ebuf = (char *)el_gets(el, &num);
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    			if (ebuf[strlen(ebuf)-1] == '\n')
    				ebuf[strlen(ebuf)-1] = '\0';
    			if (!remoteconsolehandler(ebuf)) {
    				res = write(ast_consock, ebuf, strlen(ebuf) + 1);
    
    Mark Spencer's avatar
    Mark Spencer committed
    				if (res < 1) {
    					ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno));
    					break;
    				}
    			}
    		}
    	}
    	printf("\nDisconnected from Asterisk server\n");
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    static int show_version(void)
    {
    	printf("Asterisk " ASTERISK_VERSION "\n");
    	return 0;
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    static int show_cli_help(void) {
    
    	printf("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2006, Digium, Inc. and others.\n");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	printf("Usage: asterisk [OPTIONS]\n");
    	printf("Valid Options:\n");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	printf("   -V              Display version number and exit\n");
    
    	printf("   -C <configfile> Use an alternate configuration file\n");
    
    	printf("   -G <group>      Run as a group other than the caller\n");
    	printf("   -U <user>       Run as a user other than the caller\n");
    
    	printf("   -c              Provide console CLI\n");
    	printf("   -d              Enable extra debugging\n");
    	printf("   -f              Do not fork\n");
    	printf("   -g              Dump core in case of a crash\n");
    	printf("   -h              This help screen\n");
    
    	printf("   -i              Initialize crypto keys at startup\n");
    
    	printf("   -I              Enable internal timing if Zaptel timer is available\n");
    	printf("   -L <load>       Limit the maximum load average before rejecting new calls\n");
    	printf("   -M <value>      Limit the maximum number of calls to the specified value\n");
    
    	printf("   -n              Disable console colorization\n");
    	printf("   -p              Run as pseudo-realtime thread\n");
    
    	printf("   -q              Quiet mode (suppress output)\n");
    
    	printf("   -r              Connect to Asterisk on this machine\n");
    
    	printf("   -R              Connect to Asterisk, and attempt to reconnect if disconnected\n");
    
    	printf("   -t              Record soundfiles in /var/tmp and move them where they belong after they are done.\n");
    
    	printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line of output to the CLI.\n");
    
    	printf("   -v              Increase verbosity (multiple v's = more verbose)\n");
    	printf("   -x <cmd>        Execute command <cmd> (only valid with -r)\n");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	printf("\n");
    	return 0;
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    	struct ast_config *cfg;
    	struct ast_variable *v;
    
    		cfg = ast_config_load(ast_config_AST_CONFIG_FILE);
    
    			ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	} else {
    
    		cfg = ast_config_load(config);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	}
    
    	/* init with buildtime config */
    
    	ast_copy_string(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR, sizeof(ast_config_AST_CONFIG_DIR));
    	ast_copy_string(ast_config_AST_SPOOL_DIR, AST_SPOOL_DIR, sizeof(ast_config_AST_SPOOL_DIR));
    
    	ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_MODULE_DIR));
    
     	snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR);
    	ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR));
    
    	ast_copy_string(ast_config_AST_DATA_DIR, AST_DATA_DIR, sizeof(ast_config_AST_DATA_DIR));
    
    	ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR));
    	ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR));
    	ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB));
    	ast_copy_string(ast_config_AST_KEY_DIR, AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR));
    	ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID));
    	ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET));
    	ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR));
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    	/* no asterisk.conf? no problem, use buildtime config! */
    	if (!cfg) {
    
    James Golovich's avatar
    James Golovich committed
    		return;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	}
    
    	v = ast_variable_browse(cfg, "files");
    	while (v) {
    		if (!strcasecmp(v->name, "astctlpermissions")) {
    			ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS));
    		} else if (!strcasecmp(v->name, "astctlowner")) {
    			ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER));
    		} else if (!strcasecmp(v->name, "astctlgroup")) {
    			ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP));
    		} else if (!strcasecmp(v->name, "astctl")) {
    			ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL));
    		}
    		v = v->next;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	v = ast_variable_browse(cfg, "directories");
    	while(v) {
    		if (!strcasecmp(v->name, "astetcdir")) {
    
    			ast_copy_string(ast_config_AST_CONFIG_DIR, v->value, sizeof(ast_config_AST_CONFIG_DIR));
    
    Mark Spencer's avatar
    Mark Spencer committed
    		} else if (!strcasecmp(v->name, "astspooldir")) {
    
    			ast_copy_string(ast_config_AST_SPOOL_DIR, v->value, sizeof(ast_config_AST_SPOOL_DIR));
    			snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", v->value);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		} else if (!strcasecmp(v->name, "astvarlibdir")) {
    
    			ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR));
    
    			snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/astdb", v->value);
    
    		} else if (!strcasecmp(v->name, "astdatadir")) {
    			ast_copy_string(ast_config_AST_DATA_DIR, v->value, sizeof(ast_config_AST_DATA_DIR));
    
    			snprintf(ast_config_AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR), "%s/keys", v->value);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		} else if (!strcasecmp(v->name, "astlogdir")) {
    
    			ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR));
    
    Mark Spencer's avatar
    Mark Spencer committed
    		} else if (!strcasecmp(v->name, "astagidir")) {
    
    			ast_copy_string(ast_config_AST_AGI_DIR, v->value, sizeof(ast_config_AST_AGI_DIR));
    
    Mark Spencer's avatar
    Mark Spencer committed
    		} else if (!strcasecmp(v->name, "astrundir")) {
    
    			snprintf(ast_config_AST_PID, sizeof(ast_config_AST_PID), "%s/%s", v->value, "asterisk.pid");
    			snprintf(ast_config_AST_SOCKET, sizeof(ast_config_AST_SOCKET), "%s/%s", v->value, ast_config_AST_CTL);
    			ast_copy_string(ast_config_AST_RUN_DIR, v->value, sizeof(ast_config_AST_RUN_DIR));
    
    Mark Spencer's avatar
    Mark Spencer committed
    		} else if (!strcasecmp(v->name, "astmoddir")) {
    
    			ast_copy_string(ast_config_AST_MODULE_DIR, v->value, sizeof(ast_config_AST_MODULE_DIR));
    
    		} else if (!strcasecmp(v->name, "languageprefix")) {
    			ast_language_is_prefix = ast_true(v->value);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		}
    		v = v->next;
    	}
    
    	v = ast_variable_browse(cfg, "options");
    	while(v) {
    
    		/* verbose level (-v at startup) */
    
    		if (!strcasecmp(v->name, "verbose")) {
    
    		/* whether or not to force timestamping. (-T at startup) */
    		} else if (!strcasecmp(v->name, "timestamp")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
    
    		/* whether or not to support #exec in config files */
    
    		} else if (!strcasecmp(v->name, "execincludes")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		/* debug level (-d at startup) */
    
    		} else if (!strcasecmp(v->name, "debug")) {
    
    			option_debug = 0;
    			if (sscanf(v->value, "%d", &option_debug) != 1) {
    				option_debug = ast_true(v->value);
    			}
    		/* Disable forking (-f at startup) */
    
    		} else if (!strcasecmp(v->name, "nofork")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
    
    		/* Always fork, even if verbose or debug are enabled (-F at startup) */
    		} else if (!strcasecmp(v->name, "alwaysfork")) {
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
    
    		/* Run quietly (-q at startup ) */
    
    		} else if (!strcasecmp(v->name, "quiet")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
    
    		/* Run as console (-c at startup, implies nofork) */
    
    		} else if (!strcasecmp(v->name, "console")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CONSOLE);
    
    		/* Run with high priority if the O/S permits (-p at startup) */
    
    		} else if (!strcasecmp(v->name, "highpriority")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
    
    		/* Initialize RSA auth keys (IAX2) (-i at startup) */
    
    		} else if (!strcasecmp(v->name, "initcrypto")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
    
    		/* Disable ANSI colors for console (-c at startup) */
    
    		} else if (!strcasecmp(v->name, "nocolor")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
    
    		/* Disable some usage warnings for picky people :p */
    		} else if (!strcasecmp(v->name, "dontwarn")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
    
    		/* Dump core in case of crash (-g) */
    
    		} else if (!strcasecmp(v->name, "dumpcore")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
    
    		/* Cache recorded sound files to another directory during recording */
    
    		} else if (!strcasecmp(v->name, "cache_record_files")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
    
    		/* Specify cache directory */
    
    		}  else if (!strcasecmp(v->name, "record_cache_dir")) {
    
    			ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
    
    		/* Build transcode paths via SLINEAR, instead of directly */
    		} else if (!strcasecmp(v->name, "transcode_via_sln")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
    
    		/* Transmit SLINEAR silence while a channel is being recorded */
    		} else if (!strcasecmp(v->name, "transmit_silence_during_record")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
    
    		/* Enable internal timing */
    		} else if (!strcasecmp(v->name, "internal_timing")) {
    
    			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		} else if (!strcasecmp(v->name, "maxcalls")) {
    
    			if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    				option_maxcalls = 0;
    			}
    
    		} else if (!strcasecmp(v->name, "maxload")) {
    
    			double test[1];
    
    			if (getloadavg(test, 1) == -1) {
    				ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
    				option_maxload = 0.0;
    			} else if ((sscanf(v->value, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
    
    Kevin P. Fleming's avatar
    Kevin P. Fleming committed
    		/* What user to run as */
    		} else if (!strcasecmp(v->name, "runuser")) {
    			ast_copy_string(ast_config_AST_RUN_USER, v->value, sizeof(ast_config_AST_RUN_USER));
    		/* What group to run as */
    		} else if (!strcasecmp(v->name, "rungroup")) {
    			ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP));
    
    		} else if (!strcasecmp(v->name, "systemname")) {
    			ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME));
    
    	ast_config_destroy(cfg);
    
    Mark Spencer's avatar
    Mark Spencer committed
    int main(int argc, char *argv[])
    {
    
    Mark Spencer's avatar
    Mark Spencer committed
    	char filename[80] = "";
    
    Mark Spencer's avatar
    Mark Spencer committed
    	char tmp[80];
    
    Mark Spencer's avatar
    Mark Spencer committed
    	char * xarg = NULL;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	int x;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	FILE *f;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	sigset_t sigs;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	int num;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	char *buf;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	/* 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);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		argc = sizeof(_argv) / sizeof(_argv[0]) - 1;
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    		_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) {
    
    		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's avatar
    Mark Spencer committed
    	ast_ulaw_init();
    
    Mark Spencer's avatar
    Mark Spencer committed
    	ast_alaw_init();
    
    Mark Spencer's avatar
    Mark Spencer committed
    	callerid_init();
    
    Mark Spencer's avatar
    Mark Spencer committed
    	ast_utils_init();
    
    Mark Spencer's avatar
    Mark Spencer committed
    	tdd_init();
    
    	/* 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;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (getenv("HOME")) 
    		snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
    
    Mark Spencer's avatar
    Mark Spencer committed
    	/* Check for options */
    
    	while ((c = getopt(argc, argv, "tThfdvVqprRgciInx:U:G:C:L:M:")) != -1) {
    		switch (c) {
    
    		case 'F':
    			ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'd':
    			option_debug++;
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'c':
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'f':
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'n':
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'r':
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'p':
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    		case 'v':
    			option_verbose++;
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		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;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'q':
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'x':
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			xarg = optarg;
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'C':
    
    			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);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'i':
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    			ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'h':
    			show_cli_help();
    			exit(0);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'V':
    			show_version();
    			exit(0);
    
    		case 'U':
    			runuser = optarg;
    			break;
    		case 'G':
    			rungroup = optarg;
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case '?':
    			exit(1);
    		}
    	}
    
    	if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
    		ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
    		ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
    	}
    
    
    	/* 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). */
    
    		strcpy(argv[0], "rasterisk");
    		for (x = 1; x < argc; x++) {
    			argv[x] = argv[0] + 10;
    		}
    	}
    
    
    	if (ast_opt_console && !option_verbose) 
    		ast_verbose("[ Reading Master Configuration ]");
    	ast_readconfig();
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    		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));
    		}
    	}
    
    
    Kevin P. Fleming's avatar
    Kevin P. Fleming committed
    	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;
    
    Kevin P. Fleming's avatar
    Kevin P. Fleming committed
    #ifndef __CYGWIN__
    
    
    Kevin P. Fleming's avatar
    Kevin P. Fleming committed
    	if (!is_child_of_nonroot) 
    
    		ast_set_priority(ast_opt_high_priority);
    
    		struct group *gr;
    		gr = getgrnam(rungroup);
    		if (!gr) {
    			ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
    			exit(1);
    		}
    
    Mark Spencer's avatar
    Mark Spencer committed
    		if (setgid(gr->gr_gid)) {
    
    			ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
    
    Kevin P. Fleming's avatar
    Kevin P. Fleming committed
    		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);
    	}
    
    
    		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", (int)pw->pw_gid);
    
    			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", (int)pw->pw_uid, runuser);
    
    		setenv("ASTERISK_ALREADY_NONROOT", "yes", 1);
    
    		if (option_verbose)
    			ast_verbose("Running as user '%s'\n", runuser);
    	}
    
    
    Kevin P. Fleming's avatar
    Kevin P. Fleming committed
    #endif /* __CYGWIN__ */
    
    
    	if (geteuid() && ast_opt_dump_core) {
    		if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
    			ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
    		}	
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	term_init();
    	printf(term_end());
    	fflush(stdout);
    
    		ast_verbose("[ Initializing Custom Configuration Options ]");
    
    	/* custom config setup */
    	register_config_cli();
    
    	read_config_maps();
    
    		if (el_hist == NULL || el == NULL)
    			ast_el_initialize();
    
    		if (!ast_strlen_zero(filename))
    			ast_el_read_history(filename);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (ast_tryconnect()) {
    		/* One is already running */
    
    Mark Spencer's avatar
    Mark Spencer committed
    				ast_remotecontrol(xarg);
    
    Mark Spencer's avatar
    Mark Spencer committed
    				quit_handler(0, 0, 0, 0);
    
    Mark Spencer's avatar
    Mark Spencer committed
    				exit(0);
    			}
    
    Mark Spencer's avatar
    Mark Spencer committed
    			printf(term_quit());
    
    Mark Spencer's avatar
    Mark Spencer committed
    			ast_register_verbose(console_verboser);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			WELCOME_MESSAGE;
    
    Mark Spencer's avatar
    Mark Spencer committed
    			ast_remotecontrol(NULL);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			quit_handler(0, 0, 0, 0);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			exit(0);
    		} else {
    
    			ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			printf(term_quit());
    
    Mark Spencer's avatar
    Mark Spencer committed
    			exit(1);
    		}
    
    	} 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);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		printf(term_quit());
    
    Mark Spencer's avatar
    Mark Spencer committed
    		exit(1);
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	/* Blindly write pid file since we couldn't connect */
    
    	unlink(ast_config_AST_PID);
    	f = fopen(ast_config_AST_PID, "w");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (f) {
    
    		fprintf(f, "%ld\n", (long)getpid());
    
    Mark Spencer's avatar
    Mark Spencer committed
    		fclose(f);
    	} else
    
    		ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
    
    	if (ast_opt_always_fork || !ast_opt_no_fork) {
    
    		/* Blindly re-write pid file since we are forking */
    
    		unlink(ast_config_AST_PID);
    		f = fopen(ast_config_AST_PID, "w");
    
    		if (f) {
    
    			fprintf(f, "%ld\n", (long)ast_mainpid);
    
    			fclose(f);
    		} else
    
    			ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno));
    
    Mark Spencer's avatar
    Mark Spencer committed
    	}
    
    	/* Test recursive mutex locking. */
    	if (test_for_thread_safety())
    		ast_verbose("Warning! Asterisk is not thread safe.\n");
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    	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);
    
    	if (ast_opt_console || option_verbose || ast_opt_remote)
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_register_verbose(console_verboser);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	/* Print a welcome message if desired */
    
    	if (option_verbose || ast_opt_console) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    		WELCOME_MESSAGE;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_verbose("[ Booting...");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	signal(SIGURG, urg_handler);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	signal(SIGINT, __quit_handler);
    	signal(SIGTERM, __quit_handler);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	signal(SIGHUP, hup_handler);
    
    	signal(SIGCHLD, child_handler);
    	signal(SIGPIPE, SIG_IGN);
    
    
    	/* 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));
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (init_logger()) {
    		printf(term_quit());
    
    Mark Spencer's avatar
    Mark Spencer committed
    		exit(1);
    
    	if (dnsmgr_init()) {
    		printf(term_quit());
    		exit(1);
    	}
    
    	/* load 'preload' modules, required for access to Realtime-mapped configuration files */
    	if (load_modules(1)) {
    		printf(term_quit());
    		exit(1);
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (init_manager()) {
    		printf(term_quit());
    		exit(1);
    	}
    
    	if (ast_cdr_engine_init()) {
    		printf(term_quit());
    		exit(1);
    	}
    
    	if (ast_device_state_engine_init()) {
    		printf(term_quit());
    		exit(1);
    	}
    
    	ast_rtp_init();
    
    	ast_udptl_init();
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (ast_image_init()) {
    		printf(term_quit());
    
    Mark Spencer's avatar
    Mark Spencer committed
    		exit(1);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (load_pbx()) {
    		printf(term_quit());
    
    Mark Spencer's avatar
    Mark Spencer committed
    		exit(1);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		printf(term_quit());
    
    Mark Spencer's avatar
    Mark Spencer committed
    		exit(1);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	}
    	if (init_framer()) {
    		printf(term_quit());
    
    Mark Spencer's avatar
    Mark Spencer committed
    		exit(1);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (astdb_init()) {
    		printf(term_quit());
    		exit(1);
    	}
    
    	if (ast_enum_init()) {
    		printf(term_quit());
    		exit(1);
    	}
    
    Kevin P. Fleming's avatar
    Kevin P. Fleming committed
    
    	dnsmgr_start_refresh();
    
    
    #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_logger(0);
    
    James Golovich's avatar
    James Golovich committed
    	reload_manager();
    	ast_enum_reload();
    	ast_rtp_reload();
    
    Mark Spencer's avatar
    Mark Spencer committed
    	/* We might have the option of showing a console, but for now just
    	   do nothing... */
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_verbose(" ]\n");
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
    
    James Golovich's avatar
    James Golovich committed
    		consolethread = pthread_self();
    
    	ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	time(&ast_startuptime);
    
    	ast_cli_register_multiple(core_cli, sizeof(core_cli) / sizeof(core_cli[0]));
    
    Mark Spencer's avatar
    Mark Spencer committed
    		/* Console stuff now... */
    		/* Register our quit function */
    
    Mark Spencer's avatar
    Mark Spencer committed
    		char title[256];
    		set_icon("Asterisk");
    
    		snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		set_title(title);
    
    		for (;;) {
    			buf = (char *)el_gets(el, &num);
    			if (buf) {
    				if (buf[strlen(buf)-1] == '\n')
    					buf[strlen(buf)-1] = '\0';
    
    				consolehandler((char *)buf);
    
    				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");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	}
    
    	for(;;)  {	/* apparently needed for the MACos */
    		struct pollfd p = { -1 /* no descriptor */, 0, 0 };
    		poll(&p, 0, -1);
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	return 0;
    }