Skip to content
Snippets Groups Projects
asterisk.c 34.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • Mark Spencer's avatar
    Mark Spencer committed
    					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_cli_help(void) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    	printf("Asterisk " ASTERISK_VERSION ", Copyright (C) 2000-2002, Digium.\n");
    	printf("Usage: asterisk [OPTIONS]\n");
    	printf("Valid Options:\n");
    	printf("   -h           This help screen\n");
    	printf("   -r           Connect to Asterisk on this machine\n");
    	printf("   -f           Do not fork\n");
    	printf("   -n           Disable console colorization\n");
    	printf("   -p           Run as pseudo-realtime thread\n");
    	printf("   -v           Increase verbosity (multiple v's = more verbose)\n");
    	printf("   -q           Quiet mode (supress output)\n");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	printf("   -g           Dump core in case of a crash\n");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	printf("   -x <cmd>     Execute command <cmd> (only valid with -r)\n");
    	printf("   -i           Initializie crypto keys at startup\n");
    	printf("   -c           Provide console CLI\n");
    	printf("   -d           Enable extra debugging\n");
    	printf("\n");
    	return 0;
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    static void ast_readconfig() {
    	struct ast_config *cfg;
    	struct ast_variable *v;
    	char *config = ASTCONFPATH;
    
    	if (option_overrideconfig == 1) {
    	    cfg = ast_load((char *)ast_config_AST_CONFIG_FILE);
    	} else {
    	    cfg = ast_load(config);
    	}
    
    	/* init with buildtime config */
    	strncpy((char *)ast_config_AST_CONFIG_DIR,AST_CONFIG_DIR,sizeof(ast_config_AST_CONFIG_DIR)-1);
    	strncpy((char *)ast_config_AST_SPOOL_DIR,AST_SPOOL_DIR,sizeof(ast_config_AST_SPOOL_DIR)-1);
    	strncpy((char *)ast_config_AST_MODULE_DIR,AST_MODULE_DIR,sizeof(ast_config_AST_VAR_DIR)-1);
    	strncpy((char *)ast_config_AST_VAR_DIR,AST_VAR_DIR,sizeof(ast_config_AST_VAR_DIR)-1);
    	strncpy((char *)ast_config_AST_LOG_DIR,AST_LOG_DIR,sizeof(ast_config_AST_LOG_DIR)-1);
    	strncpy((char *)ast_config_AST_AGI_DIR,AST_AGI_DIR,sizeof(ast_config_AST_AGI_DIR)-1);
    	strncpy((char *)ast_config_AST_DB,AST_DB,sizeof(ast_config_AST_DB)-1);
    	strncpy((char *)ast_config_AST_KEY_DIR,AST_KEY_DIR,sizeof(ast_config_AST_KEY_DIR)-1);
    	strncpy((char *)ast_config_AST_PID,AST_PID,sizeof(ast_config_AST_PID)-1);
    	strncpy((char *)ast_config_AST_SOCKET,AST_SOCKET,sizeof(ast_config_AST_SOCKET)-1);
    	strncpy((char *)ast_config_AST_RUN_DIR,AST_RUN_DIR,sizeof(ast_config_AST_RUN_DIR)-1);
    	
    	/* no asterisk.conf? no problem, use buildtime config! */
    	if (!cfg) {
    	    return;
    	}
    	v = ast_variable_browse(cfg, "directories");
    	while(v) {
    		if (!strcasecmp(v->name, "astetcdir")) {
    		    strncpy((char *)ast_config_AST_CONFIG_DIR,v->value,sizeof(ast_config_AST_CONFIG_DIR)-1);
    		} else if (!strcasecmp(v->name, "astspooldir")) {
    		    strncpy((char *)ast_config_AST_SPOOL_DIR,v->value,sizeof(ast_config_AST_SPOOL_DIR)-1);
    		} else if (!strcasecmp(v->name, "astvarlibdir")) {
    		    strncpy((char *)ast_config_AST_VAR_DIR,v->value,sizeof(ast_config_AST_VAR_DIR)-1);
    		    snprintf((char *)ast_config_AST_DB,sizeof(ast_config_AST_DB)-1,"%s/%s",v->value,"astdb");    
    		} else if (!strcasecmp(v->name, "astlogdir")) {
    		    strncpy((char *)ast_config_AST_LOG_DIR,v->value,sizeof(ast_config_AST_LOG_DIR)-1);
    		} else if (!strcasecmp(v->name, "astagidir")) {
    		    strncpy((char *)ast_config_AST_AGI_DIR,v->value,sizeof(ast_config_AST_AGI_DIR)-1);
    		} else if (!strcasecmp(v->name, "astrundir")) {
    		    snprintf((char *)ast_config_AST_PID,sizeof(ast_config_AST_PID)-1,"%s/%s",v->value,"asterisk.pid");    
    		    snprintf((char *)ast_config_AST_SOCKET,sizeof(ast_config_AST_SOCKET)-1,"%s/%s",v->value,"asterisk.ctl");    
    		    strncpy((char *)ast_config_AST_RUN_DIR,v->value,sizeof(ast_config_AST_RUN_DIR)-1);
    		} else if (!strcasecmp(v->name, "astmoddir")) {
    		    strncpy((char *)ast_config_AST_MODULE_DIR,v->value,sizeof(ast_config_AST_MODULE_DIR)-1);
    		}
    		v = v->next;
    	}
    	ast_destroy(cfg);
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    int main(int argc, char *argv[])
    {
    	char c;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	char filename[80] = "";
    
    Mark Spencer's avatar
    Mark Spencer committed
    	char hostname[256];
    
    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;
    	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", 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;
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (gethostname(hostname, sizeof(hostname)))
    
    Mark Spencer's avatar
    Mark Spencer committed
    		strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	mainpid = getpid();
    
    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
    	tdd_init();
    
    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 if we're root */
    
    Mark Spencer's avatar
    Mark Spencer committed
    	/*
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (geteuid()) {
    		ast_log(LOG_ERROR, "Must be run as root\n");
    		exit(1);
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	*/
    
    Mark Spencer's avatar
    Mark Spencer committed
    	/* Check for options */
    
    Mark Spencer's avatar
    Mark Spencer committed
    	while((c=getopt(argc, argv, "hfdvqprgcinx:C:")) != EOF) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    		switch(c) {
    		case 'd':
    			option_debug++;
    			option_nofork++;
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'c':
    			option_console++;
    			option_nofork++;
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'f':
    			option_nofork++;
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'n':
    			option_nocolor++;
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'r':
    			option_remote++;
    			option_nofork++;
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'p':
    			option_highpriority++;
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    		case 'v':
    			option_verbose++;
    
    Mark Spencer's avatar
    Mark Spencer committed
    			option_nofork++;
    
    Mark Spencer's avatar
    Mark Spencer committed
    			break;
    		case 'q':
    			option_quiet++;
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'x':
    			option_exec++;
    			xarg = optarg;
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'C':
    			strncpy((char *)ast_config_AST_CONFIG_FILE,optarg,sizeof(ast_config_AST_CONFIG_FILE));
    			option_overrideconfig++;
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'i':
    			option_initcrypto++;
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case'g':
    			option_dumpcore++;
    			break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case 'h':
    			show_cli_help();
    			exit(0);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		case '?':
    			exit(1);
    		}
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (option_dumpcore) {
    		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));
    		}
    	}
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    	term_init();
    	printf(term_end());
    	fflush(stdout);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (option_console && !option_verbose) 
    		ast_verbose("[ Reading Master Configuration ]");
    	ast_readconfig();
    
    	if (el_hist == NULL || el == NULL)
    		ast_el_initialize();
    
    	if (strlen(filename))
    		ast_el_read_history(filename);
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (ast_tryconnect()) {
    		/* One is already running */
    		if (option_remote) {
    			if (option_exec) {
    				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);
    			ast_verbose( "Asterisk " ASTERISK_VERSION ", Copyright (C) 1999-2001 Linux Support Services, Inc.\n");
    			ast_verbose( "Written by Mark Spencer <markster@linux-support.net>\n");
    			ast_verbose( "=========================================================================\n");
    			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 {
    
    Mark Spencer's avatar
    Mark Spencer committed
    			ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", (char *)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 (option_remote || option_exec) {
    		ast_log(LOG_ERROR, "Unable to connect to remote asterisk\n");
    
    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 */
    
    Mark Spencer's avatar
    Mark Spencer committed
    	unlink((char *)ast_config_AST_PID);
    	f = fopen((char *)ast_config_AST_PID, "w");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (f) {
    		fprintf(f, "%d\n", getpid());
    		fclose(f);
    	} else
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", (char *)ast_config_AST_PID, strerror(errno));
    
    Mark Spencer's avatar
    Mark Spencer committed
    
    	if (!option_verbose && !option_debug && !option_nofork && !option_console) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    #if 1
    		daemon(0,0);
    #else	
    
    Mark Spencer's avatar
    Mark Spencer committed
    		pid = fork();
    		if (pid < 0) {
    			ast_log(LOG_ERROR, "Unable to fork(): %s\n", strerror(errno));
    
    Mark Spencer's avatar
    Mark Spencer committed
    			printf(term_quit());
    
    Mark Spencer's avatar
    Mark Spencer committed
    			exit(1);
    		}
    		if (pid) 
    			exit(0);
    
    Mark Spencer's avatar
    Mark Spencer committed
    #endif			
    
    Mark Spencer's avatar
    Mark Spencer committed
    	}
    
    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 (option_console || option_verbose || option_remote)
    		ast_register_verbose(console_verboser);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	/* Print a welcome message if desired */
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (option_verbose || option_console) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_verbose( "Asterisk " ASTERISK_VERSION ", Copyright (C) 1999-2001 Linux Support Services, Inc.\n");
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_verbose( "Written by Mark Spencer <markster@linux-support.net>\n");
    		ast_verbose( "=========================================================================\n");
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (option_console && !option_verbose) 
    		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(SIGPIPE, pipe_handler);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (set_priority(option_highpriority)) {
    		printf(term_quit());
    
    Mark Spencer's avatar
    Mark Spencer committed
    		exit(1);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	}
    	if (init_logger()) {
    		printf(term_quit());
    
    Mark Spencer's avatar
    Mark Spencer committed
    		exit(1);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (init_manager()) {
    		printf(term_quit());
    		exit(1);
    	}
    
    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
    	}
    	if (load_modules()) {
    		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);
    	}
    
    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
    	if (option_console && !option_verbose)
    		ast_verbose(" ]\n");
    	if (option_verbose || option_console)
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
    
    Mark Spencer's avatar
    Mark Spencer committed
    	fully_booted = 1;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	ast_cli_register(&astshutdownnow);
    	ast_cli_register(&astshutdowngracefully);
    	ast_cli_register(&astrestartnow);
    	ast_cli_register(&astrestartgracefully);
    	ast_cli_register(&astrestartwhenconvenient);
    	ast_cli_register(&aborthalt);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (option_console) {
    		/* Console stuff now... */
    		/* Register our quit function */
    
    Mark Spencer's avatar
    Mark Spencer committed
    		char title[256];
    		set_icon("Asterisk");
    
    Mark Spencer's avatar
    Mark Spencer committed
    		snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, mainpid);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		set_title(title);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	    ast_cli_register(&quit);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	    ast_cli_register(&astexit);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		consolethread = pthread_self();
    
    Mark Spencer's avatar
    Mark Spencer committed
    
    		while ( (buf = (char *)el_gets(el, &num) ) != NULL && num != 0) {
    
    			if (buf[strlen(buf)-1] == '\n')
    				buf[strlen(buf)-1] = '\0';
    
    			consolehandler((char *)buf);
    		}
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    	} else {
    
    Mark Spencer's avatar
    Mark Spencer committed
     		/* Do nothing */
    
    Mark Spencer's avatar
    Mark Spencer committed
    		select(0,NULL,NULL,NULL,NULL);
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	return 0;
    }