mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +00:00 
			
		
		
		
	Merge "core: Create main/options.c."
This commit is contained in:
		| @@ -15,6 +15,11 @@ | |||||||
| #ifndef _ASTERISK__PRIVATE_H | #ifndef _ASTERISK__PRIVATE_H | ||||||
| #define _ASTERISK__PRIVATE_H | #define _ASTERISK__PRIVATE_H | ||||||
|  |  | ||||||
|  | /* Load settings from asterisk.conf, provided by options.c */ | ||||||
|  | void load_asterisk_conf(void); | ||||||
|  | void set_asterisk_conf_path(const char *path); | ||||||
|  | void set_socket_path(const char *path); | ||||||
|  |  | ||||||
| int load_modules(unsigned int);		/*!< Provided by loader.c */ | int load_modules(unsigned int);		/*!< Provided by loader.c */ | ||||||
| int modules_shutdown(void);		/*!< Provided by loader.c */ | int modules_shutdown(void);		/*!< Provided by loader.c */ | ||||||
| int load_pbx(void);			/*!< Provided by pbx.c */ | int load_pbx(void);			/*!< Provided by pbx.c */ | ||||||
|   | |||||||
| @@ -37,5 +37,9 @@ extern const char *ast_config_AST_RUN_GROUP; | |||||||
| extern const char *ast_config_AST_RUN_USER; | extern const char *ast_config_AST_RUN_USER; | ||||||
| extern const char *ast_config_AST_SYSTEM_NAME; | extern const char *ast_config_AST_SYSTEM_NAME; | ||||||
| extern const char *ast_config_AST_SBIN_DIR; | extern const char *ast_config_AST_SBIN_DIR; | ||||||
|  | extern const char *ast_config_AST_CTL_PERMISSIONS; | ||||||
|  | extern const char *ast_config_AST_CTL_OWNER; | ||||||
|  | extern const char *ast_config_AST_CTL_GROUP; | ||||||
|  | extern const char *ast_config_AST_CTL; | ||||||
|  |  | ||||||
| #endif /* _ASTERISK_PATHS_H */ | #endif /* _ASTERISK_PATHS_H */ | ||||||
|   | |||||||
							
								
								
									
										418
									
								
								main/asterisk.c
									
									
									
									
									
								
							
							
						
						
									
										418
									
								
								main/asterisk.c
									
									
									
									
									
								
							| @@ -294,10 +294,6 @@ int daemon(int, int);  /* defined in libresolv of all places */ | |||||||
| #define AST_MAX_CONNECTS 128 | #define AST_MAX_CONNECTS 128 | ||||||
| #define NUM_MSGS 64 | #define NUM_MSGS 64 | ||||||
|  |  | ||||||
| /*! Default minimum DTMF digit length - 80ms */ |  | ||||||
| #define AST_MIN_DTMF_DURATION 80 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /*! \brief Welcome message when starting a CLI interface */ | /*! \brief Welcome message when starting a CLI interface */ | ||||||
| #define WELCOME_MESSAGE \ | #define WELCOME_MESSAGE \ | ||||||
|     ast_verbose("Asterisk %s, Copyright (C) 1999 - 2016, Digium, Inc. and others.\n" \ |     ast_verbose("Asterisk %s, Copyright (C) 1999 - 2016, Digium, Inc. and others.\n" \ | ||||||
| @@ -308,40 +304,6 @@ int daemon(int, int);  /* defined in libresolv of all places */ | |||||||
|                 "certain conditions. Type 'core show license' for details.\n" \ |                 "certain conditions. Type 'core show license' for details.\n" \ | ||||||
|                 "=========================================================================\n", ast_get_version()) \ |                 "=========================================================================\n", ast_get_version()) \ | ||||||
|  |  | ||||||
| /*! \defgroup main_options Main Configuration Options |  | ||||||
|  * \brief Main configuration options from asterisk.conf or OS command line on starting Asterisk. |  | ||||||
|  * \arg \ref Config_ast "asterisk.conf" |  | ||||||
|  * \note Some of them can be changed in the CLI |  | ||||||
|  */ |  | ||||||
| /*! @{ */ |  | ||||||
|  |  | ||||||
| struct ast_flags ast_options = { AST_DEFAULT_OPTIONS }; |  | ||||||
|  |  | ||||||
| /*! Maximum active system verbosity level. */ |  | ||||||
| int ast_verb_sys_level; |  | ||||||
|  |  | ||||||
| int option_verbose;				/*!< Verbosity level */ |  | ||||||
| int option_debug;				/*!< Debug level */ |  | ||||||
| int ast_pjproject_max_log_level = -1;/* Default to -1 to know if we have read the level from pjproject yet. */ |  | ||||||
| int ast_option_pjproject_log_level; |  | ||||||
| int ast_option_pjproject_cache_pools; |  | ||||||
| double ast_option_maxload;			/*!< Max load avg on system */ |  | ||||||
| int ast_option_maxcalls;			/*!< Max number of active calls */ |  | ||||||
| int ast_option_maxfiles;			/*!< Max number of open file handles (files, sockets) */ |  | ||||||
| unsigned int option_dtmfminduration;		/*!< Minimum duration of DTMF. */ |  | ||||||
| #if defined(HAVE_SYSINFO) |  | ||||||
| long option_minmemfree;				/*!< Minimum amount of free system memory - stop accepting calls if free memory falls below this watermark */ |  | ||||||
| #endif |  | ||||||
| int ast_option_rtpusedynamic; |  | ||||||
| unsigned int ast_option_rtpptdynamic; |  | ||||||
|  |  | ||||||
| /*! @} */ |  | ||||||
|  |  | ||||||
| struct ast_eid ast_eid_default; |  | ||||||
|  |  | ||||||
| /* XXX tmpdir is a subdir of the spool directory, and no way to remap it */ |  | ||||||
| char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR; |  | ||||||
|  |  | ||||||
| static int ast_socket = -1;		/*!< UNIX Socket for allowing remote control */ | static int ast_socket = -1;		/*!< UNIX Socket for allowing remote control */ | ||||||
| static int ast_socket_is_sd = 0; /*!< Is socket activation responsible for ast_socket? */ | static int ast_socket_is_sd = 0; /*!< Is socket activation responsible for ast_socket? */ | ||||||
| static int ast_consock = -1;		/*!< UNIX Socket for controlling another asterisk */ | static int ast_consock = -1;		/*!< UNIX Socket for controlling another asterisk */ | ||||||
| @@ -375,8 +337,6 @@ static char *remotehostname; | |||||||
|  |  | ||||||
| struct console consoles[AST_MAX_CONNECTS]; | struct console consoles[AST_MAX_CONNECTS]; | ||||||
|  |  | ||||||
| char ast_defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE; |  | ||||||
|  |  | ||||||
| static int ast_el_add_history(const char *); | static int ast_el_add_history(const char *); | ||||||
| static int ast_el_read_history(const char *); | static int ast_el_read_history(const char *); | ||||||
| static int ast_el_write_history(const char *); | static int ast_el_write_history(const char *); | ||||||
| @@ -386,62 +346,6 @@ static void ast_el_write_default_histfile(void); | |||||||
|  |  | ||||||
| static void asterisk_daemon(int isroot, const char *runuser, const char *rungroup); | static void asterisk_daemon(int isroot, const char *runuser, const char *rungroup); | ||||||
|  |  | ||||||
| #define DEFAULT_MONITOR_DIR DEFAULT_SPOOL_DIR "/monitor" |  | ||||||
| #define DEFAULT_RECORDING_DIR DEFAULT_SPOOL_DIR "/recording" |  | ||||||
|  |  | ||||||
| struct _cfg_paths { |  | ||||||
| 	char config_dir[PATH_MAX]; |  | ||||||
| 	char module_dir[PATH_MAX]; |  | ||||||
| 	char spool_dir[PATH_MAX]; |  | ||||||
| 	char monitor_dir[PATH_MAX]; |  | ||||||
| 	char recording_dir[PATH_MAX]; |  | ||||||
| 	char var_dir[PATH_MAX]; |  | ||||||
| 	char data_dir[PATH_MAX]; |  | ||||||
| 	char log_dir[PATH_MAX]; |  | ||||||
| 	char agi_dir[PATH_MAX]; |  | ||||||
| 	char run_dir[PATH_MAX]; |  | ||||||
| 	char key_dir[PATH_MAX]; |  | ||||||
|  |  | ||||||
| 	char config_file[PATH_MAX]; |  | ||||||
| 	char db_path[PATH_MAX]; |  | ||||||
| 	char sbin_dir[PATH_MAX]; |  | ||||||
| 	char pid_path[PATH_MAX]; |  | ||||||
| 	char socket_path[PATH_MAX]; |  | ||||||
| 	char run_user[PATH_MAX]; |  | ||||||
| 	char run_group[PATH_MAX]; |  | ||||||
| 	char system_name[128]; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static struct _cfg_paths cfg_paths; |  | ||||||
|  |  | ||||||
| const char *ast_config_AST_CONFIG_DIR	= cfg_paths.config_dir; |  | ||||||
| const char *ast_config_AST_CONFIG_FILE	= cfg_paths.config_file; |  | ||||||
| const char *ast_config_AST_MODULE_DIR	= cfg_paths.module_dir; |  | ||||||
| const char *ast_config_AST_SPOOL_DIR	= cfg_paths.spool_dir; |  | ||||||
| const char *ast_config_AST_MONITOR_DIR	= cfg_paths.monitor_dir; |  | ||||||
| const char *ast_config_AST_RECORDING_DIR	= cfg_paths.recording_dir; |  | ||||||
| const char *ast_config_AST_VAR_DIR	= cfg_paths.var_dir; |  | ||||||
| const char *ast_config_AST_DATA_DIR	= cfg_paths.data_dir; |  | ||||||
| const char *ast_config_AST_LOG_DIR	= cfg_paths.log_dir; |  | ||||||
| const char *ast_config_AST_AGI_DIR	= cfg_paths.agi_dir; |  | ||||||
| const char *ast_config_AST_KEY_DIR	= cfg_paths.key_dir; |  | ||||||
| const char *ast_config_AST_RUN_DIR	= cfg_paths.run_dir; |  | ||||||
| const char *ast_config_AST_SBIN_DIR = cfg_paths.sbin_dir; |  | ||||||
|  |  | ||||||
| const char *ast_config_AST_DB		= cfg_paths.db_path; |  | ||||||
| const char *ast_config_AST_PID		= cfg_paths.pid_path; |  | ||||||
| const char *ast_config_AST_SOCKET	= cfg_paths.socket_path; |  | ||||||
| const char *ast_config_AST_RUN_USER	= cfg_paths.run_user; |  | ||||||
| const char *ast_config_AST_RUN_GROUP	= cfg_paths.run_group; |  | ||||||
| const char *ast_config_AST_SYSTEM_NAME	= cfg_paths.system_name; |  | ||||||
|  |  | ||||||
| static char ast_config_AST_CTL_PERMISSIONS[PATH_MAX]; |  | ||||||
| static char ast_config_AST_CTL_OWNER[PATH_MAX] = "\0"; |  | ||||||
| static char ast_config_AST_CTL_GROUP[PATH_MAX] = "\0"; |  | ||||||
| static char ast_config_AST_CTL[PATH_MAX] = "asterisk.ctl"; |  | ||||||
|  |  | ||||||
| extern unsigned int ast_FD_SETSIZE; |  | ||||||
|  |  | ||||||
| static char *_argv[256]; | static char *_argv[256]; | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
| @@ -1803,29 +1707,6 @@ static struct sigaction child_handler = { | |||||||
| 	.sa_flags = SA_RESTART, | 	.sa_flags = SA_RESTART, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /*! \brief Set maximum open files */ |  | ||||||
| static void set_ulimit(int value) |  | ||||||
| { |  | ||||||
| 	struct rlimit l = {0, 0}; |  | ||||||
|  |  | ||||||
| 	if (value <= 0) { |  | ||||||
| 		ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	l.rlim_cur = value; |  | ||||||
| 	l.rlim_max = value; |  | ||||||
|  |  | ||||||
| 	if (setrlimit(RLIMIT_NOFILE, &l)) { |  | ||||||
| 		ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno)); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ast_log(LOG_NOTICE, "Setting max files open to %d\n",value); |  | ||||||
|  |  | ||||||
| 	return; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /*! \brief Set an X-term or screen title */ | /*! \brief Set an X-term or screen title */ | ||||||
| static void set_title(char *text) | static void set_title(char *text) | ||||||
| { | { | ||||||
| @@ -3441,296 +3322,6 @@ static int show_cli_help(void) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void ast_readconfig(void) |  | ||||||
| { |  | ||||||
| 	struct ast_config *cfg; |  | ||||||
| 	struct ast_variable *v; |  | ||||||
| 	char hostname[MAXHOSTNAMELEN] = ""; |  | ||||||
| 	struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME }; |  | ||||||
| 	struct { |  | ||||||
| 		unsigned int dbdir:1; |  | ||||||
| 		unsigned int keydir:1; |  | ||||||
| 	} found = { 0, 0 }; |  | ||||||
| 	/* Default to false for security */ |  | ||||||
| 	int live_dangerously = 0; |  | ||||||
| 	int option_debug_new = 0; |  | ||||||
| 	int option_verbose_new = 0; |  | ||||||
|  |  | ||||||
| 	/* Set default value */ |  | ||||||
| 	option_dtmfminduration = AST_MIN_DTMF_DURATION; |  | ||||||
| 	ast_option_rtpusedynamic = 1; |  | ||||||
| 	ast_option_rtpptdynamic = 35; |  | ||||||
|  |  | ||||||
| 	/* init with buildtime config */ |  | ||||||
| 	ast_copy_string(cfg_paths.config_dir, DEFAULT_CONFIG_DIR, sizeof(cfg_paths.config_dir)); |  | ||||||
| 	ast_copy_string(cfg_paths.spool_dir, DEFAULT_SPOOL_DIR, sizeof(cfg_paths.spool_dir)); |  | ||||||
| 	ast_copy_string(cfg_paths.module_dir, DEFAULT_MODULE_DIR, sizeof(cfg_paths.module_dir)); |  | ||||||
| 	ast_copy_string(cfg_paths.monitor_dir, DEFAULT_MONITOR_DIR, sizeof(cfg_paths.monitor_dir)); |  | ||||||
| 	ast_copy_string(cfg_paths.recording_dir, DEFAULT_RECORDING_DIR, sizeof(cfg_paths.recording_dir)); |  | ||||||
| 	ast_copy_string(cfg_paths.var_dir, DEFAULT_VAR_DIR, sizeof(cfg_paths.var_dir)); |  | ||||||
| 	ast_copy_string(cfg_paths.data_dir, DEFAULT_DATA_DIR, sizeof(cfg_paths.data_dir)); |  | ||||||
| 	ast_copy_string(cfg_paths.log_dir, DEFAULT_LOG_DIR, sizeof(cfg_paths.log_dir)); |  | ||||||
| 	ast_copy_string(cfg_paths.agi_dir, DEFAULT_AGI_DIR, sizeof(cfg_paths.agi_dir)); |  | ||||||
| 	ast_copy_string(cfg_paths.db_path, DEFAULT_DB, sizeof(cfg_paths.db_path)); |  | ||||||
| 	ast_copy_string(cfg_paths.sbin_dir, DEFAULT_SBIN_DIR, sizeof(cfg_paths.sbin_dir)); |  | ||||||
| 	ast_copy_string(cfg_paths.key_dir, DEFAULT_KEY_DIR, sizeof(cfg_paths.key_dir)); |  | ||||||
| 	ast_copy_string(cfg_paths.pid_path, DEFAULT_PID, sizeof(cfg_paths.pid_path)); |  | ||||||
| 	ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path)); |  | ||||||
| 	ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir)); |  | ||||||
|  |  | ||||||
| #ifdef REF_DEBUG |  | ||||||
| 	/* The REF_DEBUG compiler flag is now only used to enable refdebug by default. |  | ||||||
| 	 * Support for debugging reference counts is always compiled in. */ |  | ||||||
| 	ast_set2_flag(&ast_options, 1, AST_OPT_FLAG_REF_DEBUG); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| 	ast_set_default_eid(&ast_eid_default); |  | ||||||
|  |  | ||||||
| 	cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags); |  | ||||||
|  |  | ||||||
| 	/* If AST_OPT_FLAG_EXEC_INCLUDES was previously enabled with -X turn it off now. |  | ||||||
| 	 * Using #exec from other configs requires that it be enabled from asterisk.conf. */ |  | ||||||
| 	ast_clear_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES); |  | ||||||
|  |  | ||||||
| 	/* no asterisk.conf? no problem, use buildtime config! */ |  | ||||||
| 	if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) { |  | ||||||
| 		fprintf(stderr, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for (v = ast_variable_browse(cfg, "files"); v; v = v->next) { |  | ||||||
| 		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)); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) { |  | ||||||
| 		if (!strcasecmp(v->name, "astetcdir")) { |  | ||||||
| 			ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir)); |  | ||||||
| 		} else if (!strcasecmp(v->name, "astspooldir")) { |  | ||||||
| 			ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir)); |  | ||||||
| 			snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value); |  | ||||||
| 			snprintf(cfg_paths.recording_dir, sizeof(cfg_paths.recording_dir), "%s/recording", v->value); |  | ||||||
| 		} else if (!strcasecmp(v->name, "astvarlibdir")) { |  | ||||||
| 			ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir)); |  | ||||||
| 			if (!found.dbdir) |  | ||||||
| 				snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value); |  | ||||||
| 		} else if (!strcasecmp(v->name, "astdbdir")) { |  | ||||||
| 			snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value); |  | ||||||
| 			found.dbdir = 1; |  | ||||||
| 		} else if (!strcasecmp(v->name, "astdatadir")) { |  | ||||||
| 			ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir)); |  | ||||||
| 			if (!found.keydir) |  | ||||||
| 				snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value); |  | ||||||
| 		} else if (!strcasecmp(v->name, "astkeydir")) { |  | ||||||
| 			snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value); |  | ||||||
| 			found.keydir = 1; |  | ||||||
| 		} else if (!strcasecmp(v->name, "astlogdir")) { |  | ||||||
| 			ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir)); |  | ||||||
| 		} else if (!strcasecmp(v->name, "astagidir")) { |  | ||||||
| 			ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir)); |  | ||||||
| 		} else if (!strcasecmp(v->name, "astrundir")) { |  | ||||||
| 			snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid"); |  | ||||||
| 			ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir)); |  | ||||||
| 		} else if (!strcasecmp(v->name, "astmoddir")) { |  | ||||||
| 			ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir)); |  | ||||||
| 		} else if (!strcasecmp(v->name, "astsbindir")) { |  | ||||||
| 			ast_copy_string(cfg_paths.sbin_dir, v->value, sizeof(cfg_paths.sbin_dir)); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* Combine astrundir and astctl settings. */ |  | ||||||
| 	snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", |  | ||||||
| 		ast_config_AST_RUN_DIR, ast_config_AST_CTL); |  | ||||||
|  |  | ||||||
| 	for (v = ast_variable_browse(cfg, "options"); v; v = v->next) { |  | ||||||
| 		/* verbose level (-v at startup) */ |  | ||||||
| 		if (!strcasecmp(v->name, "verbose")) { |  | ||||||
| 			option_verbose_new = atoi(v->value); |  | ||||||
| 		/* whether or not to force timestamping in CLI verbose output. (-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); |  | ||||||
| 		/* debug level (-d at startup) */ |  | ||||||
| 		} else if (!strcasecmp(v->name, "debug")) { |  | ||||||
| 			option_debug_new = 0; |  | ||||||
| 			if (sscanf(v->value, "%30d", &option_debug_new) != 1) { |  | ||||||
| 				option_debug_new = ast_true(v->value) ? 1 : 0; |  | ||||||
| 			} |  | ||||||
| 		} else if (!strcasecmp(v->name, "refdebug")) { |  | ||||||
| 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_REF_DEBUG); |  | ||||||
| #if HAVE_WORKING_FORK |  | ||||||
| 		/* 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); |  | ||||||
| #endif |  | ||||||
| 		/* 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_NO_FORK | 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); |  | ||||||
| #if !defined(LOW_MEMORY) |  | ||||||
| 		/* Cache media frames for performance */ |  | ||||||
| 		} else if (!strcasecmp(v->name, "cache_media_frames")) { |  | ||||||
| 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_MEDIA_FRAMES); |  | ||||||
| #endif |  | ||||||
| 		/* 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 or DTMF is being generated on a channel */ |  | ||||||
| 		} else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) { |  | ||||||
| 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE); |  | ||||||
| 		/* Enable internal timing */ |  | ||||||
| 		} else if (!strcasecmp(v->name, "internal_timing")) { |  | ||||||
| 			if (!ast_opt_remote) { |  | ||||||
| 				fprintf(stderr, |  | ||||||
| 					"NOTICE: The internal_timing option is no longer needed.\n" |  | ||||||
| 					"  It will always be enabled if you have a timing module loaded.\n"); |  | ||||||
| 			} |  | ||||||
| 		} else if (!strcasecmp(v->name, "mindtmfduration")) { |  | ||||||
| 			if (sscanf(v->value, "%30u", &option_dtmfminduration) != 1) { |  | ||||||
| 				option_dtmfminduration = AST_MIN_DTMF_DURATION; |  | ||||||
| 			} |  | ||||||
| 		} else if (!strcasecmp(v->name, "rtp_use_dynamic")) { |  | ||||||
| 			ast_option_rtpusedynamic = ast_true(v->value); |  | ||||||
| 		/* http://www.iana.org/assignments/rtp-parameters |  | ||||||
| 		 * RTP dynamic payload types start at 96 normally; extend down to 0 */ |  | ||||||
| 		} else if (!strcasecmp(v->name, "rtp_pt_dynamic")) { |  | ||||||
| 			ast_parse_arg(v->value, PARSE_UINT32|PARSE_IN_RANGE, |  | ||||||
| 			              &ast_option_rtpptdynamic, 0, AST_RTP_PT_FIRST_DYNAMIC); |  | ||||||
| 		} else if (!strcasecmp(v->name, "maxcalls")) { |  | ||||||
| 			if ((sscanf(v->value, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) { |  | ||||||
| 				ast_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"); |  | ||||||
| 				ast_option_maxload = 0.0; |  | ||||||
| 			} else if ((sscanf(v->value, "%30lf", &ast_option_maxload) != 1) || (ast_option_maxload < 0.0)) { |  | ||||||
| 				ast_option_maxload = 0.0; |  | ||||||
| 			} |  | ||||||
| 		/* Set the maximum amount of open files */ |  | ||||||
| 		} else if (!strcasecmp(v->name, "maxfiles")) { |  | ||||||
| 			ast_option_maxfiles = atoi(v->value); |  | ||||||
| 			if (!ast_opt_remote) { |  | ||||||
| 				set_ulimit(ast_option_maxfiles); |  | ||||||
| 			} |  | ||||||
| 		/* What user to run as */ |  | ||||||
| 		} else if (!strcasecmp(v->name, "runuser")) { |  | ||||||
| 			ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user)); |  | ||||||
| 		/* What group to run as */ |  | ||||||
| 		} else if (!strcasecmp(v->name, "rungroup")) { |  | ||||||
| 			ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group)); |  | ||||||
| 		} else if (!strcasecmp(v->name, "systemname")) { |  | ||||||
| 			ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name)); |  | ||||||
| 		} else if (!strcasecmp(v->name, "autosystemname")) { |  | ||||||
| 			if (ast_true(v->value)) { |  | ||||||
| 				if (!gethostname(hostname, sizeof(hostname) - 1)) |  | ||||||
| 					ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name)); |  | ||||||
| 				else { |  | ||||||
| 					if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){ |  | ||||||
| 						ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name)); |  | ||||||
| 					} |  | ||||||
| 					ast_log(LOG_ERROR, "Cannot obtain hostname for this system.  Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} else if (!strcasecmp(v->name, "languageprefix")) { |  | ||||||
| 			ast_language_is_prefix = ast_true(v->value); |  | ||||||
| 		} else if (!strcasecmp(v->name, "defaultlanguage")) { |  | ||||||
| 			ast_copy_string(ast_defaultlanguage, v->value, MAX_LANGUAGE); |  | ||||||
| 		} else if (!strcasecmp(v->name, "lockmode")) { |  | ||||||
| 			if (!strcasecmp(v->value, "lockfile")) { |  | ||||||
| 				ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE); |  | ||||||
| 			} else if (!strcasecmp(v->value, "flock")) { |  | ||||||
| 				ast_set_lock_type(AST_LOCK_TYPE_FLOCK); |  | ||||||
| 			} else { |  | ||||||
| 				ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, " |  | ||||||
| 					"defaulting to 'lockfile'\n", v->value); |  | ||||||
| 				ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE); |  | ||||||
| 			} |  | ||||||
| #if defined(HAVE_SYSINFO) |  | ||||||
| 		} else if (!strcasecmp(v->name, "minmemfree")) { |  | ||||||
| 			/* specify the minimum amount of free memory to retain.  Asterisk should stop accepting new calls |  | ||||||
| 			 * if the amount of free memory falls below this watermark */ |  | ||||||
| 			if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) { |  | ||||||
| 				option_minmemfree = 0; |  | ||||||
| 			} |  | ||||||
| #endif |  | ||||||
| 		} else if (!strcasecmp(v->name, "entityid")) { |  | ||||||
| 			struct ast_eid tmp_eid; |  | ||||||
| 			if (!ast_str_to_eid(&tmp_eid, v->value)) { |  | ||||||
| 				ast_eid_default = tmp_eid; |  | ||||||
| 			} else { |  | ||||||
| 				ast_log(LOG_WARNING, "Invalid Entity ID '%s' provided\n", v->value); |  | ||||||
| 			} |  | ||||||
| 		} else if (!strcasecmp(v->name, "lightbackground")) { |  | ||||||
| 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND); |  | ||||||
| 		} else if (!strcasecmp(v->name, "forceblackbackground")) { |  | ||||||
| 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND); |  | ||||||
| 		} else if (!strcasecmp(v->name, "hideconnect")) { |  | ||||||
| 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT); |  | ||||||
| 		} else if (!strcasecmp(v->name, "lockconfdir")) { |  | ||||||
| 			ast_set2_flag(&ast_options, ast_true(v->value),	AST_OPT_FLAG_LOCK_CONFIG_DIR); |  | ||||||
| 		} else if (!strcasecmp(v->name, "stdexten")) { |  | ||||||
| 			/* Choose how to invoke the extensions.conf stdexten */ |  | ||||||
| 			if (!strcasecmp(v->value, "gosub")) { |  | ||||||
| 				ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO); |  | ||||||
| 			} else if (!strcasecmp(v->value, "macro")) { |  | ||||||
| 				ast_set_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO); |  | ||||||
| 			} else { |  | ||||||
| 				ast_log(LOG_WARNING, |  | ||||||
| 					"'%s' is not a valid setting for the stdexten option, defaulting to 'gosub'\n", |  | ||||||
| 					v->value); |  | ||||||
| 				ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO); |  | ||||||
| 			} |  | ||||||
| 		} else if (!strcasecmp(v->name, "live_dangerously")) { |  | ||||||
| 			live_dangerously = ast_true(v->value); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if (!ast_opt_remote) { |  | ||||||
| 		pbx_live_dangerously(live_dangerously); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	option_debug += option_debug_new; |  | ||||||
| 	option_verbose += option_verbose_new; |  | ||||||
|  |  | ||||||
| 	ast_config_destroy(cfg); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void read_pjproject_startup_options(void) | static void read_pjproject_startup_options(void) | ||||||
| { | { | ||||||
| 	struct ast_config *cfg; | 	struct ast_config *cfg; | ||||||
| @@ -3915,9 +3506,6 @@ int main(int argc, char *argv[]) | |||||||
| 	} | 	} | ||||||
| 	ast_mainpid = getpid(); | 	ast_mainpid = getpid(); | ||||||
|  |  | ||||||
| 	/* Set config file to default before checking arguments for override. */ |  | ||||||
| 	ast_copy_string(cfg_paths.config_file, DEFAULT_CONFIG_FILE, sizeof(cfg_paths.config_file)); |  | ||||||
|  |  | ||||||
| 	/* Process command-line options that effect asterisk.conf load. */ | 	/* Process command-line options that effect asterisk.conf load. */ | ||||||
| 	while ((c = getopt(argc, argv, getopt_settings)) != -1) { | 	while ((c = getopt(argc, argv, getopt_settings)) != -1) { | ||||||
| 		switch (c) { | 		switch (c) { | ||||||
| @@ -3925,7 +3513,7 @@ int main(int argc, char *argv[]) | |||||||
| 			ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES); | 			ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES); | ||||||
| 			break; | 			break; | ||||||
| 		case 'C': | 		case 'C': | ||||||
| 			ast_copy_string(cfg_paths.config_file, optarg, sizeof(cfg_paths.config_file)); | 			set_asterisk_conf_path(optarg); | ||||||
| 			break; | 			break; | ||||||
| 		case 'd': | 		case 'd': | ||||||
| 			option_debug++; | 			option_debug++; | ||||||
| @@ -3954,7 +3542,7 @@ int main(int argc, char *argv[]) | |||||||
| 	/* Initialize env so it is available if #exec is used in asterisk.conf. */ | 	/* Initialize env so it is available if #exec is used in asterisk.conf. */ | ||||||
| 	env_init(); | 	env_init(); | ||||||
|  |  | ||||||
| 	ast_readconfig(); | 	load_asterisk_conf(); | ||||||
|  |  | ||||||
| 	/* Update env to include any systemname that was set. */ | 	/* Update env to include any systemname that was set. */ | ||||||
| 	env_init(); | 	env_init(); | ||||||
| @@ -4047,7 +3635,7 @@ int main(int argc, char *argv[]) | |||||||
| 			break; | 			break; | ||||||
| 		case 's': | 		case 's': | ||||||
| 			if (ast_opt_remote) { | 			if (ast_opt_remote) { | ||||||
| 				ast_copy_string((char *) cfg_paths.socket_path, optarg, sizeof(cfg_paths.socket_path)); | 				set_socket_path(optarg); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		case 'T': | 		case 'T': | ||||||
|   | |||||||
							
								
								
									
										475
									
								
								main/options.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										475
									
								
								main/options.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,475 @@ | |||||||
|  | /* | ||||||
|  |  * Asterisk -- An open source telephony toolkit. | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2018, CFWare, LLC | ||||||
|  |  * | ||||||
|  |  * Corey Farrell <git@cfware.com> | ||||||
|  |  * | ||||||
|  |  * See http://www.asterisk.org for more information about | ||||||
|  |  * the Asterisk project. Please do not directly contact | ||||||
|  |  * any of the maintainers of this project for assistance; | ||||||
|  |  * the project provides a web site, mailing lists and IRC | ||||||
|  |  * channels for your use. | ||||||
|  |  * | ||||||
|  |  * This program is free software, distributed under the terms of | ||||||
|  |  * the GNU General Public License Version 2. See the LICENSE file | ||||||
|  |  * at the top of the source tree. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /*! \file | ||||||
|  |  * | ||||||
|  |  * \brief Symbols related to asterisk.conf options and paths. | ||||||
|  |  * | ||||||
|  |  * \author Corey Farrell <git@cfware.com> | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /*** MODULEINFO | ||||||
|  | 	<support_level>core</support_level> | ||||||
|  |  ***/ | ||||||
|  |  | ||||||
|  | #include "asterisk.h" | ||||||
|  | #include "asterisk/_private.h" | ||||||
|  | #include "asterisk/app.h" | ||||||
|  | #include "asterisk/config.h" | ||||||
|  | #include "asterisk/logger.h" | ||||||
|  | #include "asterisk/options.h" | ||||||
|  | #include "asterisk/paths.h" | ||||||
|  | #include "asterisk/pbx.h" | ||||||
|  | #include "asterisk/rtp_engine.h" | ||||||
|  | #include "asterisk/strings.h" | ||||||
|  | #include "asterisk/utils.h" | ||||||
|  |  | ||||||
|  | #include "../defaults.h" | ||||||
|  |  | ||||||
|  | #include <sys/time.h> | ||||||
|  | #include <sys/resource.h> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /*! Default minimum DTMF digit length - 80ms */ | ||||||
|  | #define AST_MIN_DTMF_DURATION 80 | ||||||
|  |  | ||||||
|  | #define DEFAULT_MONITOR_DIR DEFAULT_SPOOL_DIR "/monitor" | ||||||
|  | #define DEFAULT_RECORDING_DIR DEFAULT_SPOOL_DIR "/recording" | ||||||
|  |  | ||||||
|  | /*! \defgroup main_options Main Configuration Options | ||||||
|  |  * \brief Main configuration options from asterisk.conf or OS command line on starting Asterisk. | ||||||
|  |  * \arg \ref Config_ast "asterisk.conf" | ||||||
|  |  * \note Some of them can be changed in the CLI | ||||||
|  |  */ | ||||||
|  | /*! @{ */ | ||||||
|  |  | ||||||
|  | struct ast_flags ast_options = { AST_DEFAULT_OPTIONS }; | ||||||
|  |  | ||||||
|  | /*! Maximum active system verbosity level. */ | ||||||
|  | int ast_verb_sys_level; | ||||||
|  |  | ||||||
|  | /*! Verbosity level */ | ||||||
|  | int option_verbose; | ||||||
|  | /*! Debug level */ | ||||||
|  | int option_debug; | ||||||
|  | /*! Default to -1 to know if we have read the level from pjproject yet. */ | ||||||
|  | int ast_pjproject_max_log_level = -1; | ||||||
|  | int ast_option_pjproject_log_level; | ||||||
|  | int ast_option_pjproject_cache_pools; | ||||||
|  | /*! Max load avg on system */ | ||||||
|  | double ast_option_maxload; | ||||||
|  | /*! Max number of active calls */ | ||||||
|  | int ast_option_maxcalls; | ||||||
|  | /*! Max number of open file handles (files, sockets) */ | ||||||
|  | int ast_option_maxfiles; | ||||||
|  | /*! Minimum duration of DTMF. */ | ||||||
|  | unsigned int option_dtmfminduration = AST_MIN_DTMF_DURATION; | ||||||
|  | #if defined(HAVE_SYSINFO) | ||||||
|  | /*! Minimum amount of free system memory - stop accepting calls if free memory falls below this watermark */ | ||||||
|  | long option_minmemfree; | ||||||
|  | #endif | ||||||
|  | int ast_option_rtpusedynamic = 1; | ||||||
|  | unsigned int ast_option_rtpptdynamic = 35; | ||||||
|  |  | ||||||
|  | /*! @} */ | ||||||
|  |  | ||||||
|  | struct ast_eid ast_eid_default; | ||||||
|  |  | ||||||
|  | /* XXX tmpdir is a subdir of the spool directory, and no way to remap it */ | ||||||
|  | char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR; | ||||||
|  |  | ||||||
|  | char ast_defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE; | ||||||
|  |  | ||||||
|  | struct _cfg_paths { | ||||||
|  | 	char config_dir[PATH_MAX]; | ||||||
|  | 	char module_dir[PATH_MAX]; | ||||||
|  | 	char spool_dir[PATH_MAX]; | ||||||
|  | 	char monitor_dir[PATH_MAX]; | ||||||
|  | 	char recording_dir[PATH_MAX]; | ||||||
|  | 	char var_dir[PATH_MAX]; | ||||||
|  | 	char data_dir[PATH_MAX]; | ||||||
|  | 	char log_dir[PATH_MAX]; | ||||||
|  | 	char agi_dir[PATH_MAX]; | ||||||
|  | 	char run_dir[PATH_MAX]; | ||||||
|  | 	char key_dir[PATH_MAX]; | ||||||
|  |  | ||||||
|  | 	char config_file[PATH_MAX]; | ||||||
|  | 	char db_path[PATH_MAX]; | ||||||
|  | 	char sbin_dir[PATH_MAX]; | ||||||
|  | 	char pid_path[PATH_MAX]; | ||||||
|  | 	char socket_path[PATH_MAX]; | ||||||
|  | 	char run_user[PATH_MAX]; | ||||||
|  | 	char run_group[PATH_MAX]; | ||||||
|  | 	char system_name[128]; | ||||||
|  | 	char ctl_perms[PATH_MAX]; | ||||||
|  | 	char ctl_owner[PATH_MAX]; | ||||||
|  | 	char ctl_group[PATH_MAX]; | ||||||
|  | 	char ctl_file[PATH_MAX]; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static struct _cfg_paths cfg_paths = { | ||||||
|  | 	.config_dir = DEFAULT_CONFIG_DIR, | ||||||
|  | 	.module_dir = DEFAULT_MODULE_DIR, | ||||||
|  | 	.spool_dir = DEFAULT_SPOOL_DIR, | ||||||
|  | 	.monitor_dir = DEFAULT_MONITOR_DIR, | ||||||
|  | 	.recording_dir = DEFAULT_RECORDING_DIR, | ||||||
|  | 	.var_dir = DEFAULT_VAR_DIR, | ||||||
|  | 	.data_dir = DEFAULT_DATA_DIR, | ||||||
|  | 	.log_dir = DEFAULT_LOG_DIR, | ||||||
|  | 	.agi_dir = DEFAULT_AGI_DIR, | ||||||
|  | 	.run_dir = DEFAULT_RUN_DIR, | ||||||
|  | 	.key_dir = DEFAULT_KEY_DIR, | ||||||
|  |  | ||||||
|  | 	.config_file = DEFAULT_CONFIG_FILE, | ||||||
|  | 	.db_path = DEFAULT_DB, | ||||||
|  | 	.sbin_dir = DEFAULT_SBIN_DIR, | ||||||
|  | 	.pid_path = DEFAULT_PID, | ||||||
|  | 	.socket_path = DEFAULT_SOCKET, | ||||||
|  | 	.ctl_file = "asterisk.ctl", | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const char *ast_config_AST_CONFIG_DIR	= cfg_paths.config_dir; | ||||||
|  | const char *ast_config_AST_CONFIG_FILE	= cfg_paths.config_file; | ||||||
|  | const char *ast_config_AST_MODULE_DIR	= cfg_paths.module_dir; | ||||||
|  | const char *ast_config_AST_SPOOL_DIR	= cfg_paths.spool_dir; | ||||||
|  | const char *ast_config_AST_MONITOR_DIR	= cfg_paths.monitor_dir; | ||||||
|  | const char *ast_config_AST_RECORDING_DIR	= cfg_paths.recording_dir; | ||||||
|  | const char *ast_config_AST_VAR_DIR	= cfg_paths.var_dir; | ||||||
|  | const char *ast_config_AST_DATA_DIR	= cfg_paths.data_dir; | ||||||
|  | const char *ast_config_AST_LOG_DIR	= cfg_paths.log_dir; | ||||||
|  | const char *ast_config_AST_AGI_DIR	= cfg_paths.agi_dir; | ||||||
|  | const char *ast_config_AST_KEY_DIR	= cfg_paths.key_dir; | ||||||
|  | const char *ast_config_AST_RUN_DIR	= cfg_paths.run_dir; | ||||||
|  | const char *ast_config_AST_SBIN_DIR = cfg_paths.sbin_dir; | ||||||
|  |  | ||||||
|  | const char *ast_config_AST_DB		= cfg_paths.db_path; | ||||||
|  | const char *ast_config_AST_PID		= cfg_paths.pid_path; | ||||||
|  | const char *ast_config_AST_SOCKET	= cfg_paths.socket_path; | ||||||
|  | const char *ast_config_AST_RUN_USER	= cfg_paths.run_user; | ||||||
|  | const char *ast_config_AST_RUN_GROUP	= cfg_paths.run_group; | ||||||
|  | const char *ast_config_AST_SYSTEM_NAME	= cfg_paths.system_name; | ||||||
|  |  | ||||||
|  | const char *ast_config_AST_CTL_PERMISSIONS = cfg_paths.ctl_perms; | ||||||
|  | const char *ast_config_AST_CTL_OWNER = cfg_paths.ctl_owner; | ||||||
|  | const char *ast_config_AST_CTL_GROUP = cfg_paths.ctl_group; | ||||||
|  | const char *ast_config_AST_CTL = cfg_paths.ctl_file; | ||||||
|  |  | ||||||
|  | /*! \brief Set maximum open files */ | ||||||
|  | static void set_ulimit(int value) | ||||||
|  | { | ||||||
|  | 	struct rlimit l = {0, 0}; | ||||||
|  |  | ||||||
|  | 	if (value <= 0) { | ||||||
|  | 		ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	l.rlim_cur = value; | ||||||
|  | 	l.rlim_max = value; | ||||||
|  |  | ||||||
|  | 	if (setrlimit(RLIMIT_NOFILE, &l)) { | ||||||
|  | 		ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno)); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ast_log(LOG_NOTICE, "Setting max files open to %d\n",value); | ||||||
|  |  | ||||||
|  | 	return; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void set_asterisk_conf_path(const char *path) | ||||||
|  | { | ||||||
|  | 	ast_copy_string(cfg_paths.config_file, path, sizeof(cfg_paths.config_file)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void set_socket_path(const char *path) | ||||||
|  | { | ||||||
|  | 	ast_copy_string(cfg_paths.socket_path, path, sizeof(cfg_paths.socket_path)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void load_asterisk_conf(void) | ||||||
|  | { | ||||||
|  | 	struct ast_config *cfg; | ||||||
|  | 	struct ast_variable *v; | ||||||
|  | 	char hostname[MAXHOSTNAMELEN] = ""; | ||||||
|  | 	struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME }; | ||||||
|  | 	struct { | ||||||
|  | 		unsigned int dbdir:1; | ||||||
|  | 		unsigned int keydir:1; | ||||||
|  | 	} found = { 0, 0 }; | ||||||
|  | 	/* Default to false for security */ | ||||||
|  | 	int live_dangerously = 0; | ||||||
|  | 	int option_debug_new = 0; | ||||||
|  | 	int option_verbose_new = 0; | ||||||
|  |  | ||||||
|  | 	/* init with buildtime config */ | ||||||
|  | #ifdef REF_DEBUG | ||||||
|  | 	/* The REF_DEBUG compiler flag is now only used to enable refdebug by default. | ||||||
|  | 	 * Support for debugging reference counts is always compiled in. */ | ||||||
|  | 	ast_set2_flag(&ast_options, 1, AST_OPT_FLAG_REF_DEBUG); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	ast_set_default_eid(&ast_eid_default); | ||||||
|  |  | ||||||
|  | 	cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags); | ||||||
|  |  | ||||||
|  | 	/* If AST_OPT_FLAG_EXEC_INCLUDES was previously enabled with -X turn it off now. | ||||||
|  | 	 * Using #exec from other configs requires that it be enabled from asterisk.conf. */ | ||||||
|  | 	ast_clear_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES); | ||||||
|  |  | ||||||
|  | 	/* no asterisk.conf? no problem, use buildtime config! */ | ||||||
|  | 	if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) { | ||||||
|  | 		fprintf(stderr, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for (v = ast_variable_browse(cfg, "files"); v; v = v->next) { | ||||||
|  | 		if (!strcasecmp(v->name, "astctlpermissions")) { | ||||||
|  | 			ast_copy_string(cfg_paths.ctl_perms, v->value, sizeof(cfg_paths.ctl_perms)); | ||||||
|  | 		} else if (!strcasecmp(v->name, "astctlowner")) { | ||||||
|  | 			ast_copy_string(cfg_paths.ctl_owner, v->value, sizeof(cfg_paths.ctl_owner)); | ||||||
|  | 		} else if (!strcasecmp(v->name, "astctlgroup")) { | ||||||
|  | 			ast_copy_string(cfg_paths.ctl_group, v->value, sizeof(cfg_paths.ctl_group)); | ||||||
|  | 		} else if (!strcasecmp(v->name, "astctl")) { | ||||||
|  | 			ast_copy_string(cfg_paths.ctl_file, v->value, sizeof(cfg_paths.ctl_file)); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) { | ||||||
|  | 		if (!strcasecmp(v->name, "astetcdir")) { | ||||||
|  | 			ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir)); | ||||||
|  | 		} else if (!strcasecmp(v->name, "astspooldir")) { | ||||||
|  | 			ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir)); | ||||||
|  | 			snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value); | ||||||
|  | 			snprintf(cfg_paths.recording_dir, sizeof(cfg_paths.recording_dir), "%s/recording", v->value); | ||||||
|  | 		} else if (!strcasecmp(v->name, "astvarlibdir")) { | ||||||
|  | 			ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir)); | ||||||
|  | 			if (!found.dbdir) { | ||||||
|  | 				snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value); | ||||||
|  | 			} | ||||||
|  | 		} else if (!strcasecmp(v->name, "astdbdir")) { | ||||||
|  | 			snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value); | ||||||
|  | 			found.dbdir = 1; | ||||||
|  | 		} else if (!strcasecmp(v->name, "astdatadir")) { | ||||||
|  | 			ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir)); | ||||||
|  | 			if (!found.keydir) { | ||||||
|  | 				snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value); | ||||||
|  | 			} | ||||||
|  | 		} else if (!strcasecmp(v->name, "astkeydir")) { | ||||||
|  | 			snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value); | ||||||
|  | 			found.keydir = 1; | ||||||
|  | 		} else if (!strcasecmp(v->name, "astlogdir")) { | ||||||
|  | 			ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir)); | ||||||
|  | 		} else if (!strcasecmp(v->name, "astagidir")) { | ||||||
|  | 			ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir)); | ||||||
|  | 		} else if (!strcasecmp(v->name, "astrundir")) { | ||||||
|  | 			snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid"); | ||||||
|  | 			ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir)); | ||||||
|  | 		} else if (!strcasecmp(v->name, "astmoddir")) { | ||||||
|  | 			ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir)); | ||||||
|  | 		} else if (!strcasecmp(v->name, "astsbindir")) { | ||||||
|  | 			ast_copy_string(cfg_paths.sbin_dir, v->value, sizeof(cfg_paths.sbin_dir)); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* Combine astrundir and astctl settings. */ | ||||||
|  | 	snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s", | ||||||
|  | 		ast_config_AST_RUN_DIR, ast_config_AST_CTL); | ||||||
|  |  | ||||||
|  | 	for (v = ast_variable_browse(cfg, "options"); v; v = v->next) { | ||||||
|  | 		/* verbose level (-v at startup) */ | ||||||
|  | 		if (!strcasecmp(v->name, "verbose")) { | ||||||
|  | 			option_verbose_new = atoi(v->value); | ||||||
|  | 		/* whether or not to force timestamping in CLI verbose output. (-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); | ||||||
|  | 		/* debug level (-d at startup) */ | ||||||
|  | 		} else if (!strcasecmp(v->name, "debug")) { | ||||||
|  | 			option_debug_new = 0; | ||||||
|  | 			if (sscanf(v->value, "%30d", &option_debug_new) != 1) { | ||||||
|  | 				option_debug_new = ast_true(v->value) ? 1 : 0; | ||||||
|  | 			} | ||||||
|  | 		} else if (!strcasecmp(v->name, "refdebug")) { | ||||||
|  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_REF_DEBUG); | ||||||
|  | #if HAVE_WORKING_FORK | ||||||
|  | 		/* 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); | ||||||
|  | #endif | ||||||
|  | 		/* 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_NO_FORK | 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); | ||||||
|  | #if !defined(LOW_MEMORY) | ||||||
|  | 		/* Cache media frames for performance */ | ||||||
|  | 		} else if (!strcasecmp(v->name, "cache_media_frames")) { | ||||||
|  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_MEDIA_FRAMES); | ||||||
|  | #endif | ||||||
|  | 		/* 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 or DTMF is being generated on a channel */ | ||||||
|  | 		} else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) { | ||||||
|  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE); | ||||||
|  | 		/* Enable internal timing */ | ||||||
|  | 		} else if (!strcasecmp(v->name, "internal_timing")) { | ||||||
|  | 			if (!ast_opt_remote) { | ||||||
|  | 				fprintf(stderr, | ||||||
|  | 					"NOTICE: The internal_timing option is no longer needed.\n" | ||||||
|  | 					"  It will always be enabled if you have a timing module loaded.\n"); | ||||||
|  | 			} | ||||||
|  | 		} else if (!strcasecmp(v->name, "mindtmfduration")) { | ||||||
|  | 			if (sscanf(v->value, "%30u", &option_dtmfminduration) != 1) { | ||||||
|  | 				option_dtmfminduration = AST_MIN_DTMF_DURATION; | ||||||
|  | 			} | ||||||
|  | 		} else if (!strcasecmp(v->name, "rtp_use_dynamic")) { | ||||||
|  | 			ast_option_rtpusedynamic = ast_true(v->value); | ||||||
|  | 		/* http://www.iana.org/assignments/rtp-parameters | ||||||
|  | 		 * RTP dynamic payload types start at 96 normally; extend down to 0 */ | ||||||
|  | 		} else if (!strcasecmp(v->name, "rtp_pt_dynamic")) { | ||||||
|  | 			ast_parse_arg(v->value, PARSE_UINT32|PARSE_IN_RANGE, | ||||||
|  | 			              &ast_option_rtpptdynamic, 0, AST_RTP_PT_FIRST_DYNAMIC); | ||||||
|  | 		} else if (!strcasecmp(v->name, "maxcalls")) { | ||||||
|  | 			if ((sscanf(v->value, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) { | ||||||
|  | 				ast_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"); | ||||||
|  | 				ast_option_maxload = 0.0; | ||||||
|  | 			} else if ((sscanf(v->value, "%30lf", &ast_option_maxload) != 1) || (ast_option_maxload < 0.0)) { | ||||||
|  | 				ast_option_maxload = 0.0; | ||||||
|  | 			} | ||||||
|  | 		/* Set the maximum amount of open files */ | ||||||
|  | 		} else if (!strcasecmp(v->name, "maxfiles")) { | ||||||
|  | 			ast_option_maxfiles = atoi(v->value); | ||||||
|  | 			if (!ast_opt_remote) { | ||||||
|  | 				set_ulimit(ast_option_maxfiles); | ||||||
|  | 			} | ||||||
|  | 		/* What user to run as */ | ||||||
|  | 		} else if (!strcasecmp(v->name, "runuser")) { | ||||||
|  | 			ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user)); | ||||||
|  | 		/* What group to run as */ | ||||||
|  | 		} else if (!strcasecmp(v->name, "rungroup")) { | ||||||
|  | 			ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group)); | ||||||
|  | 		} else if (!strcasecmp(v->name, "systemname")) { | ||||||
|  | 			ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name)); | ||||||
|  | 		} else if (!strcasecmp(v->name, "autosystemname")) { | ||||||
|  | 			if (ast_true(v->value)) { | ||||||
|  | 				if (!gethostname(hostname, sizeof(hostname) - 1)) { | ||||||
|  | 					ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name)); | ||||||
|  | 				} else { | ||||||
|  | 					if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){ | ||||||
|  | 						ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name)); | ||||||
|  | 					} | ||||||
|  | 					ast_log(LOG_ERROR, "Cannot obtain hostname for this system.  Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} else if (!strcasecmp(v->name, "languageprefix")) { | ||||||
|  | 			ast_language_is_prefix = ast_true(v->value); | ||||||
|  | 		} else if (!strcasecmp(v->name, "defaultlanguage")) { | ||||||
|  | 			ast_copy_string(ast_defaultlanguage, v->value, MAX_LANGUAGE); | ||||||
|  | 		} else if (!strcasecmp(v->name, "lockmode")) { | ||||||
|  | 			if (!strcasecmp(v->value, "lockfile")) { | ||||||
|  | 				ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE); | ||||||
|  | 			} else if (!strcasecmp(v->value, "flock")) { | ||||||
|  | 				ast_set_lock_type(AST_LOCK_TYPE_FLOCK); | ||||||
|  | 			} else { | ||||||
|  | 				ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, " | ||||||
|  | 					"defaulting to 'lockfile'\n", v->value); | ||||||
|  | 				ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE); | ||||||
|  | 			} | ||||||
|  | #if defined(HAVE_SYSINFO) | ||||||
|  | 		} else if (!strcasecmp(v->name, "minmemfree")) { | ||||||
|  | 			/* specify the minimum amount of free memory to retain.  Asterisk should stop accepting new calls | ||||||
|  | 			 * if the amount of free memory falls below this watermark */ | ||||||
|  | 			if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) { | ||||||
|  | 				option_minmemfree = 0; | ||||||
|  | 			} | ||||||
|  | #endif | ||||||
|  | 		} else if (!strcasecmp(v->name, "entityid")) { | ||||||
|  | 			struct ast_eid tmp_eid; | ||||||
|  | 			if (!ast_str_to_eid(&tmp_eid, v->value)) { | ||||||
|  | 				ast_eid_default = tmp_eid; | ||||||
|  | 			} else { | ||||||
|  | 				ast_log(LOG_WARNING, "Invalid Entity ID '%s' provided\n", v->value); | ||||||
|  | 			} | ||||||
|  | 		} else if (!strcasecmp(v->name, "lightbackground")) { | ||||||
|  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND); | ||||||
|  | 		} else if (!strcasecmp(v->name, "forceblackbackground")) { | ||||||
|  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND); | ||||||
|  | 		} else if (!strcasecmp(v->name, "hideconnect")) { | ||||||
|  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT); | ||||||
|  | 		} else if (!strcasecmp(v->name, "lockconfdir")) { | ||||||
|  | 			ast_set2_flag(&ast_options, ast_true(v->value),	AST_OPT_FLAG_LOCK_CONFIG_DIR); | ||||||
|  | 		} else if (!strcasecmp(v->name, "stdexten")) { | ||||||
|  | 			/* Choose how to invoke the extensions.conf stdexten */ | ||||||
|  | 			if (!strcasecmp(v->value, "gosub")) { | ||||||
|  | 				ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO); | ||||||
|  | 			} else if (!strcasecmp(v->value, "macro")) { | ||||||
|  | 				ast_set_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO); | ||||||
|  | 			} else { | ||||||
|  | 				ast_log(LOG_WARNING, | ||||||
|  | 					"'%s' is not a valid setting for the stdexten option, defaulting to 'gosub'\n", | ||||||
|  | 					v->value); | ||||||
|  | 				ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO); | ||||||
|  | 			} | ||||||
|  | 		} else if (!strcasecmp(v->name, "live_dangerously")) { | ||||||
|  | 			live_dangerously = ast_true(v->value); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if (!ast_opt_remote) { | ||||||
|  | 		pbx_live_dangerously(live_dangerously); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	option_debug += option_debug_new; | ||||||
|  | 	option_verbose += option_verbose_new; | ||||||
|  |  | ||||||
|  | 	ast_config_destroy(cfg); | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user