options.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2018, CFWare, LLC
  5. *
  6. * Corey Farrell <git@cfware.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief Symbols related to asterisk.conf options and paths.
  21. *
  22. * \author Corey Farrell <git@cfware.com>
  23. */
  24. /*** MODULEINFO
  25. <support_level>core</support_level>
  26. ***/
  27. #include "asterisk.h"
  28. #include "asterisk/_private.h"
  29. #include "asterisk/app.h"
  30. #include "asterisk/config.h"
  31. #include "asterisk/logger.h"
  32. #include "asterisk/options.h"
  33. #include "asterisk/paths.h"
  34. #include "asterisk/pbx.h"
  35. #include "asterisk/rtp_engine.h"
  36. #include "asterisk/strings.h"
  37. #include "asterisk/utils.h"
  38. #include "asterisk/md5.h"
  39. #include "../defaults.h"
  40. #include <sys/time.h>
  41. #include <sys/resource.h>
  42. /*! Default minimum DTMF digit length - 80ms */
  43. #define AST_MIN_DTMF_DURATION 80
  44. #define DEFAULT_MONITOR_DIR DEFAULT_SPOOL_DIR "/monitor"
  45. #define DEFAULT_RECORDING_DIR DEFAULT_SPOOL_DIR "/recording"
  46. /*! \defgroup main_options Main Configuration Options
  47. * \brief Main configuration options from asterisk.conf or OS command line on starting Asterisk.
  48. * \arg \ref Config_ast "asterisk.conf"
  49. * \note Some of them can be changed in the CLI
  50. */
  51. /*! @{ */
  52. struct ast_flags ast_options = { AST_DEFAULT_OPTIONS };
  53. /*! Maximum active system verbosity level. */
  54. int ast_verb_sys_level;
  55. /*! Verbosity level */
  56. int option_verbose;
  57. /*! Debug level */
  58. int option_debug;
  59. /*! Default to -1 to know if we have read the level from pjproject yet. */
  60. int ast_pjproject_max_log_level = -1;
  61. int ast_option_pjproject_log_level;
  62. int ast_option_pjproject_cache_pools;
  63. /*! Max load avg on system */
  64. double ast_option_maxload;
  65. /*! Max number of active calls */
  66. int ast_option_maxcalls = 100; //by yu.ding
  67. /*! Max number of extensions */
  68. int ast_maxextensions = 300; //by dingyu
  69. /*! Max number of open file handles (files, sockets) */
  70. int ast_option_maxfiles;
  71. /*! Minimum duration of DTMF. */
  72. unsigned int option_dtmfminduration = AST_MIN_DTMF_DURATION;
  73. #if defined(HAVE_SYSINFO)
  74. /*! Minimum amount of free system memory - stop accepting calls if free memory falls below this watermark */
  75. long option_minmemfree;
  76. #endif
  77. unsigned int ast_option_rtpptdynamic = AST_RTP_PT_FIRST_DYNAMIC;
  78. /*! @} */
  79. struct ast_eid ast_eid_default;
  80. /* XXX tmpdir is a subdir of the spool directory, and no way to remap it */
  81. char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR;
  82. char ast_defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE;
  83. struct _cfg_paths {
  84. char config_dir[PATH_MAX];
  85. char module_dir[PATH_MAX];
  86. char spool_dir[PATH_MAX];
  87. char monitor_dir[PATH_MAX];
  88. char recording_dir[PATH_MAX];
  89. char var_dir[PATH_MAX];
  90. char data_dir[PATH_MAX];
  91. char log_dir[PATH_MAX];
  92. char agi_dir[PATH_MAX];
  93. char run_dir[PATH_MAX];
  94. char key_dir[PATH_MAX];
  95. char config_file[PATH_MAX];
  96. char db_path[PATH_MAX];
  97. char sbin_dir[PATH_MAX];
  98. char pid_path[PATH_MAX];
  99. char socket_path[PATH_MAX];
  100. char run_user[PATH_MAX];
  101. char run_group[PATH_MAX];
  102. char system_name[128];
  103. char ctl_perms[PATH_MAX];
  104. char ctl_owner[PATH_MAX];
  105. char ctl_group[PATH_MAX];
  106. char ctl_file[PATH_MAX];
  107. };
  108. static struct _cfg_paths cfg_paths = {
  109. .config_dir = DEFAULT_CONFIG_DIR,
  110. .module_dir = DEFAULT_MODULE_DIR,
  111. .spool_dir = DEFAULT_SPOOL_DIR,
  112. .monitor_dir = DEFAULT_MONITOR_DIR,
  113. .recording_dir = DEFAULT_RECORDING_DIR,
  114. .var_dir = DEFAULT_VAR_DIR,
  115. .data_dir = DEFAULT_DATA_DIR,
  116. .log_dir = DEFAULT_LOG_DIR,
  117. .agi_dir = DEFAULT_AGI_DIR,
  118. .run_dir = DEFAULT_RUN_DIR,
  119. .key_dir = DEFAULT_KEY_DIR,
  120. .config_file = DEFAULT_CONFIG_FILE,
  121. .db_path = DEFAULT_DB,
  122. .sbin_dir = DEFAULT_SBIN_DIR,
  123. .pid_path = DEFAULT_PID,
  124. .socket_path = DEFAULT_SOCKET,
  125. .ctl_file = "asterisk.ctl",
  126. };
  127. const char *ast_config_AST_CONFIG_DIR = cfg_paths.config_dir;
  128. const char *ast_config_AST_CONFIG_FILE = cfg_paths.config_file;
  129. const char *ast_config_AST_MODULE_DIR = cfg_paths.module_dir;
  130. const char *ast_config_AST_SPOOL_DIR = cfg_paths.spool_dir;
  131. const char *ast_config_AST_MONITOR_DIR = cfg_paths.monitor_dir;
  132. const char *ast_config_AST_RECORDING_DIR = cfg_paths.recording_dir;
  133. const char *ast_config_AST_VAR_DIR = cfg_paths.var_dir;
  134. const char *ast_config_AST_DATA_DIR = cfg_paths.data_dir;
  135. const char *ast_config_AST_LOG_DIR = cfg_paths.log_dir;
  136. const char *ast_config_AST_AGI_DIR = cfg_paths.agi_dir;
  137. const char *ast_config_AST_KEY_DIR = cfg_paths.key_dir;
  138. const char *ast_config_AST_RUN_DIR = cfg_paths.run_dir;
  139. const char *ast_config_AST_SBIN_DIR = cfg_paths.sbin_dir;
  140. const char *ast_config_AST_DB = cfg_paths.db_path;
  141. const char *ast_config_AST_PID = cfg_paths.pid_path;
  142. const char *ast_config_AST_SOCKET = cfg_paths.socket_path;
  143. const char *ast_config_AST_RUN_USER = cfg_paths.run_user;
  144. const char *ast_config_AST_RUN_GROUP = cfg_paths.run_group;
  145. const char *ast_config_AST_SYSTEM_NAME = cfg_paths.system_name;
  146. const char *ast_config_AST_CTL_PERMISSIONS = cfg_paths.ctl_perms;
  147. const char *ast_config_AST_CTL_OWNER = cfg_paths.ctl_owner;
  148. const char *ast_config_AST_CTL_GROUP = cfg_paths.ctl_group;
  149. const char *ast_config_AST_CTL = cfg_paths.ctl_file;
  150. /*! \brief Set maximum open files */
  151. static void set_ulimit(int value)
  152. {
  153. struct rlimit l = {0, 0};
  154. if (value <= 0) {
  155. ast_log(LOG_WARNING, "Unable to change max files open to invalid value %i\n",value);
  156. return;
  157. }
  158. l.rlim_cur = value;
  159. l.rlim_max = value;
  160. if (setrlimit(RLIMIT_NOFILE, &l)) {
  161. ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n",strerror(errno));
  162. return;
  163. }
  164. ast_log(LOG_NOTICE, "Setting max files open to %d\n",value);
  165. return;
  166. }
  167. void set_asterisk_conf_path(const char *path)
  168. {
  169. ast_copy_string(cfg_paths.config_file, path, sizeof(cfg_paths.config_file));
  170. }
  171. void set_socket_path(const char *path)
  172. {
  173. ast_copy_string(cfg_paths.socket_path, path, sizeof(cfg_paths.socket_path));
  174. }
  175. //通过配置文件判断模块状态 by dingyu
  176. static int check_module(char *module){
  177. FILE *fp; //文件指针
  178. int line=0;
  179. char file_str[1024];
  180. fp=fopen("/root/.pm2/dump.pm2","r");//创建的文件
  181. if(fp==NULL)
  182. {
  183. printf("open error\n");
  184. return 0;
  185. }
  186. while(fgets(file_str,sizeof(file_str),fp))//逐行循环读取文件,直到文件结束
  187. {
  188. line++;
  189. if(strstr(file_str,module)) //检查字符串是否在该行中,如果在,则输出该行
  190. {
  191. fclose(fp);
  192. return 1;
  193. }
  194. }
  195. fclose(fp);//关闭文件,结束
  196. return 0;
  197. }
  198. //修改分机容量 by dingyu
  199. static void change_extens(int numbers){
  200. FILE *fp;
  201. fp=fopen("/var/lib/asterisk/modeinfo.ini","w+");//指定配置文件
  202. if(fp==NULL)
  203. {
  204. printf("open error\n");
  205. return;
  206. }
  207. fprintf(fp, "[general]\n");
  208. fprintf(fp, "extennum = %d\n",numbers);
  209. fclose(fp);//关闭文件,结束
  210. }
  211. //对比license文件 by dingyu
  212. static int check_license(void)
  213. {
  214. FILE *fp; //文件1指针
  215. FILE *fp2; //文件2指针
  216. int line=0;
  217. int i;
  218. struct MD5Context md5;
  219. unsigned char sum[16];
  220. char file_str[1024];
  221. char file_str2[1024];
  222. char sumbuf[128];
  223. fp=fopen("/sys/block/mmcblk0/device/cid","r");//创建的文件
  224. if(fp==NULL)
  225. {
  226. printf("open error\n");
  227. return 0;
  228. }
  229. if(fgets(file_str,sizeof(file_str),fp))
  230. {
  231. file_str[strlen(file_str)-1] = 0;
  232. strcat(file_str,"e845116521d590069f285ddde46ee2cf");
  233. MD5Init(&md5);
  234. MD5Update(&md5, (unsigned char *) file_str, strlen(file_str));
  235. MD5Final(sum, &md5);
  236. char tmp[16];
  237. memset(tmp,0,sizeof(tmp));
  238. for(i=0;i<16;i++)
  239. {
  240. sprintf(tmp,"%02x",sum[i]);
  241. strcat(sumbuf,tmp);
  242. }
  243. fp2=fopen("/lib/modules/4.4.179/kernel/crypto/async_tx/astasync","r");//创建的文件
  244. if(fp2==NULL)
  245. {
  246. printf("open error\n");
  247. fclose(fp);
  248. return 0;
  249. }
  250. while(fgets(file_str2,sizeof(file_str2),fp2))//逐行循环读取文件,直到文件结束
  251. {
  252. line++;
  253. if(strstr(file_str2,sumbuf)) //检查字符串是否在该行中,如果在,则输出该行
  254. {
  255. fclose(fp);
  256. fclose(fp2);
  257. return 1;
  258. }
  259. }
  260. fclose(fp2);//关闭文件,结束
  261. }
  262. fclose(fp);//关闭文件,结束
  263. return 0;
  264. }
  265. void load_asterisk_conf(void)
  266. {
  267. //定义模块 by dingyu
  268. char *service_module = "/CC-System/sails/app.js";
  269. char *terminal_module = "/CC-System/gin/as-gin";
  270. char *api_module = "/CC-System/cc-api/zycooAPI";
  271. char *remote_module = "/CC-System/frp/frpc";
  272. char *knowledge_module = "/CC-System/k-peach/k-peach";
  273. struct ast_config *cfg;
  274. struct ast_variable *v;
  275. char *config = DEFAULT_CONFIG_FILE;
  276. char hostname[MAXHOSTNAMELEN] = "";
  277. struct ast_flags config_flags = { CONFIG_FLAG_NOREALTIME };
  278. struct {
  279. unsigned int dbdir:1;
  280. unsigned int keydir:1;
  281. } found = { 0, 0 };
  282. /* Default to false for security */
  283. int live_dangerously = 0;
  284. if (ast_opt_override_config) {
  285. cfg = ast_config_load2(ast_config_AST_CONFIG_FILE, "" /* core, can't reload */, config_flags);
  286. if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
  287. fprintf(stderr, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE);
  288. }
  289. } else {
  290. cfg = ast_config_load2(config, "" /* core, can't reload */, config_flags);
  291. }
  292. ast_set_default_eid(&ast_eid_default);
  293. /* no asterisk.conf? no problem, use buildtime config! */
  294. if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
  295. return;
  296. }
  297. for (v = ast_variable_browse(cfg, "files"); v; v = v->next) {
  298. if (!strcasecmp(v->name, "astctlpermissions")) {
  299. ast_copy_string(cfg_paths.ctl_perms, v->value, sizeof(cfg_paths.ctl_perms));
  300. } else if (!strcasecmp(v->name, "astctlowner")) {
  301. ast_copy_string(cfg_paths.ctl_owner, v->value, sizeof(cfg_paths.ctl_owner));
  302. } else if (!strcasecmp(v->name, "astctlgroup")) {
  303. ast_copy_string(cfg_paths.ctl_group, v->value, sizeof(cfg_paths.ctl_group));
  304. } else if (!strcasecmp(v->name, "astctl")) {
  305. ast_copy_string(cfg_paths.ctl_file, v->value, sizeof(cfg_paths.ctl_file));
  306. }
  307. }
  308. for (v = ast_variable_browse(cfg, "directories"); v; v = v->next) {
  309. if (!strcasecmp(v->name, "astetcdir")) {
  310. ast_copy_string(cfg_paths.config_dir, v->value, sizeof(cfg_paths.config_dir));
  311. } else if (!strcasecmp(v->name, "astspooldir")) {
  312. ast_copy_string(cfg_paths.spool_dir, v->value, sizeof(cfg_paths.spool_dir));
  313. snprintf(cfg_paths.monitor_dir, sizeof(cfg_paths.monitor_dir), "%s/monitor", v->value);
  314. snprintf(cfg_paths.recording_dir, sizeof(cfg_paths.recording_dir), "%s/recording", v->value);
  315. } else if (!strcasecmp(v->name, "astvarlibdir")) {
  316. ast_copy_string(cfg_paths.var_dir, v->value, sizeof(cfg_paths.var_dir));
  317. if (!found.dbdir) {
  318. snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
  319. }
  320. } else if (!strcasecmp(v->name, "astdbdir")) {
  321. snprintf(cfg_paths.db_path, sizeof(cfg_paths.db_path), "%s/astdb", v->value);
  322. found.dbdir = 1;
  323. } else if (!strcasecmp(v->name, "astdatadir")) {
  324. ast_copy_string(cfg_paths.data_dir, v->value, sizeof(cfg_paths.data_dir));
  325. if (!found.keydir) {
  326. snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
  327. }
  328. } else if (!strcasecmp(v->name, "astkeydir")) {
  329. snprintf(cfg_paths.key_dir, sizeof(cfg_paths.key_dir), "%s/keys", v->value);
  330. found.keydir = 1;
  331. } else if (!strcasecmp(v->name, "astlogdir")) {
  332. ast_copy_string(cfg_paths.log_dir, v->value, sizeof(cfg_paths.log_dir));
  333. } else if (!strcasecmp(v->name, "astagidir")) {
  334. ast_copy_string(cfg_paths.agi_dir, v->value, sizeof(cfg_paths.agi_dir));
  335. } else if (!strcasecmp(v->name, "astrundir")) {
  336. snprintf(cfg_paths.pid_path, sizeof(cfg_paths.pid_path), "%s/%s", v->value, "asterisk.pid");
  337. ast_copy_string(cfg_paths.run_dir, v->value, sizeof(cfg_paths.run_dir));
  338. } else if (!strcasecmp(v->name, "astmoddir")) {
  339. ast_copy_string(cfg_paths.module_dir, v->value, sizeof(cfg_paths.module_dir));
  340. } else if (!strcasecmp(v->name, "astsbindir")) {
  341. ast_copy_string(cfg_paths.sbin_dir, v->value, sizeof(cfg_paths.sbin_dir));
  342. }
  343. }
  344. /* Combine astrundir and astctl settings. */
  345. snprintf(cfg_paths.socket_path, sizeof(cfg_paths.socket_path), "%s/%s",
  346. ast_config_AST_RUN_DIR, ast_config_AST_CTL);
  347. for (v = ast_variable_browse(cfg, "options"); v; v = v->next) {
  348. /* verbose level (-v at startup) */
  349. if (!strcasecmp(v->name, "verbose")) {
  350. option_verbose = atoi(v->value);
  351. /* whether or not to force timestamping in CLI verbose output. (-T at startup) */
  352. } else if (!strcasecmp(v->name, "timestamp")) {
  353. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP);
  354. /* whether or not to support #exec in config files */
  355. } else if (!strcasecmp(v->name, "execincludes")) {
  356. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES);
  357. /* debug level (-d at startup) */
  358. } else if (!strcasecmp(v->name, "debug")) {
  359. option_debug = 0;
  360. if (sscanf(v->value, "%30d", &option_debug) != 1) {
  361. option_debug = ast_true(v->value) ? 1 : 0;
  362. }
  363. #if HAVE_WORKING_FORK
  364. /* Disable forking (-f at startup) */
  365. } else if (!strcasecmp(v->name, "nofork")) {
  366. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK);
  367. /* Always fork, even if verbose or debug are enabled (-F at startup) */
  368. } else if (!strcasecmp(v->name, "alwaysfork")) {
  369. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_ALWAYS_FORK);
  370. #endif
  371. /* Run quietly (-q at startup ) */
  372. } else if (!strcasecmp(v->name, "quiet")) {
  373. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET);
  374. /* Run as console (-c at startup, implies nofork) */
  375. } else if (!strcasecmp(v->name, "console")) {
  376. if (!ast_opt_remote) {
  377. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
  378. }
  379. /* Run with high priority if the O/S permits (-p at startup) */
  380. } else if (!strcasecmp(v->name, "highpriority")) {
  381. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY);
  382. /* Initialize RSA auth keys (IAX2) (-i at startup) */
  383. } else if (!strcasecmp(v->name, "initcrypto")) {
  384. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS);
  385. /* Disable ANSI colors for console (-c at startup) */
  386. } else if (!strcasecmp(v->name, "nocolor")) {
  387. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR);
  388. /* Disable some usage warnings for picky people :p */
  389. } else if (!strcasecmp(v->name, "dontwarn")) {
  390. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN);
  391. /* Dump core in case of crash (-g) */
  392. } else if (!strcasecmp(v->name, "dumpcore")) {
  393. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE);
  394. /* Cache recorded sound files to another directory during recording */
  395. } else if (!strcasecmp(v->name, "cache_record_files")) {
  396. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
  397. #if !defined(LOW_MEMORY)
  398. /* Cache media frames for performance */
  399. } else if (!strcasecmp(v->name, "cache_media_frames")) {
  400. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_MEDIA_FRAMES);
  401. #endif
  402. /* Specify cache directory */
  403. } else if (!strcasecmp(v->name, "record_cache_dir")) {
  404. ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
  405. /* Build transcode paths via SLINEAR, instead of directly */
  406. } else if (!strcasecmp(v->name, "transcode_via_sln")) {
  407. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN);
  408. /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */
  409. } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) {
  410. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
  411. /* Enable internal timing */
  412. } else if (!strcasecmp(v->name, "internal_timing")) {
  413. if (!ast_opt_remote) {
  414. fprintf(stderr,
  415. "NOTICE: The internal_timing option is no longer needed.\n"
  416. " It will always be enabled if you have a timing module loaded.\n");
  417. }
  418. } else if (!strcasecmp(v->name, "mindtmfduration")) {
  419. if (sscanf(v->value, "%30u", &option_dtmfminduration) != 1) {
  420. option_dtmfminduration = AST_MIN_DTMF_DURATION;
  421. }
  422. /* http://www.iana.org/assignments/rtp-parameters
  423. * RTP dynamic payload types start at 96 normally; extend down to 0 */
  424. } else if (!strcasecmp(v->name, "rtp_pt_dynamic")) {
  425. ast_parse_arg(v->value, PARSE_UINT32|PARSE_IN_RANGE|PARSE_DEFAULT,
  426. &ast_option_rtpptdynamic, AST_RTP_PT_FIRST_DYNAMIC,
  427. 0, AST_RTP_PT_LAST_REASSIGN);
  428. }
  429. /* by yu.ding
  430. else if (!strcasecmp(v->name, "maxcalls")) {
  431. if ((sscanf(v->value, "%30d", &ast_option_maxcalls) != 1) || (ast_option_maxcalls < 0)) {
  432. ast_option_maxcalls = 0;
  433. }
  434. }
  435. */
  436. else if (!strcasecmp(v->name, "maxload")) {
  437. double test[1];
  438. if (getloadavg(test, 1) == -1) {
  439. ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n");
  440. ast_option_maxload = 0.0;
  441. } else if ((sscanf(v->value, "%30lf", &ast_option_maxload) != 1) || (ast_option_maxload < 0.0)) {
  442. ast_option_maxload = 0.0;
  443. }
  444. /* Set the maximum amount of open files */
  445. } else if (!strcasecmp(v->name, "maxfiles")) {
  446. ast_option_maxfiles = atoi(v->value);
  447. if (!ast_opt_remote) {
  448. set_ulimit(ast_option_maxfiles);
  449. }
  450. /* What user to run as */
  451. } else if (!strcasecmp(v->name, "runuser")) {
  452. ast_copy_string(cfg_paths.run_user, v->value, sizeof(cfg_paths.run_user));
  453. /* What group to run as */
  454. } else if (!strcasecmp(v->name, "rungroup")) {
  455. ast_copy_string(cfg_paths.run_group, v->value, sizeof(cfg_paths.run_group));
  456. } else if (!strcasecmp(v->name, "systemname")) {
  457. ast_copy_string(cfg_paths.system_name, v->value, sizeof(cfg_paths.system_name));
  458. } else if (!strcasecmp(v->name, "autosystemname")) {
  459. if (ast_true(v->value)) {
  460. if (!gethostname(hostname, sizeof(hostname) - 1)) {
  461. ast_copy_string(cfg_paths.system_name, hostname, sizeof(cfg_paths.system_name));
  462. } else {
  463. if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)){
  464. ast_copy_string(cfg_paths.system_name, "localhost", sizeof(cfg_paths.system_name));
  465. }
  466. ast_log(LOG_ERROR, "Cannot obtain hostname for this system. Using '%s' instead.\n", ast_config_AST_SYSTEM_NAME);
  467. }
  468. }
  469. } else if (!strcasecmp(v->name, "languageprefix")) {
  470. ast_language_is_prefix = ast_true(v->value);
  471. } else if (!strcasecmp(v->name, "defaultlanguage")) {
  472. ast_copy_string(ast_defaultlanguage, v->value, MAX_LANGUAGE);
  473. } else if (!strcasecmp(v->name, "lockmode")) {
  474. if (!strcasecmp(v->value, "lockfile")) {
  475. ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
  476. } else if (!strcasecmp(v->value, "flock")) {
  477. ast_set_lock_type(AST_LOCK_TYPE_FLOCK);
  478. } else {
  479. ast_log(LOG_WARNING, "'%s' is not a valid setting for the lockmode option, "
  480. "defaulting to 'lockfile'\n", v->value);
  481. ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
  482. }
  483. #if defined(HAVE_SYSINFO)
  484. } else if (!strcasecmp(v->name, "minmemfree")) {
  485. /* specify the minimum amount of free memory to retain. Asterisk should stop accepting new calls
  486. * if the amount of free memory falls below this watermark */
  487. if ((sscanf(v->value, "%30ld", &option_minmemfree) != 1) || (option_minmemfree < 0)) {
  488. option_minmemfree = 0;
  489. }
  490. #endif
  491. } else if (!strcasecmp(v->name, "entityid")) {
  492. struct ast_eid tmp_eid;
  493. if (!ast_str_to_eid(&tmp_eid, v->value)) {
  494. ast_eid_default = tmp_eid;
  495. } else {
  496. ast_log(LOG_WARNING, "Invalid Entity ID '%s' provided\n", v->value);
  497. }
  498. } else if (!strcasecmp(v->name, "lightbackground")) {
  499. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LIGHT_BACKGROUND);
  500. } else if (!strcasecmp(v->name, "forceblackbackground")) {
  501. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
  502. } else if (!strcasecmp(v->name, "hideconnect")) {
  503. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT);
  504. } else if (!strcasecmp(v->name, "lockconfdir")) {
  505. ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LOCK_CONFIG_DIR);
  506. } else if (!strcasecmp(v->name, "stdexten")) {
  507. /* Choose how to invoke the extensions.conf stdexten */
  508. if (!strcasecmp(v->value, "gosub")) {
  509. ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
  510. } else if (!strcasecmp(v->value, "macro")) {
  511. ast_set_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
  512. } else {
  513. ast_log(LOG_WARNING,
  514. "'%s' is not a valid setting for the stdexten option, defaulting to 'gosub'\n",
  515. v->value);
  516. ast_clear_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO);
  517. }
  518. } else if (!strcasecmp(v->name, "live_dangerously")) {
  519. live_dangerously = ast_true(v->value);
  520. }
  521. }
  522. if (!ast_opt_remote) {
  523. pbx_live_dangerously(live_dangerously);
  524. }
  525. //校验license for CooCenter-S30
  526. if(check_license())
  527. {
  528. //通过模块状态控制并发数 by dingyu
  529. if(check_module(service_module))
  530. {
  531. ast_option_maxcalls -= 40;
  532. ast_maxextensions -= 100;
  533. }
  534. if(check_module(terminal_module))
  535. {
  536. ast_option_maxcalls -= 20;
  537. ast_maxextensions -= 80;
  538. }
  539. if(check_module(api_module))
  540. {
  541. ast_option_maxcalls -= 10;
  542. }
  543. if(check_module(remote_module))
  544. {
  545. ast_option_maxcalls -= 0;
  546. }
  547. if(check_module(knowledge_module))
  548. {
  549. ast_option_maxcalls -= 5;
  550. }
  551. change_extens(ast_maxextensions);
  552. }
  553. else
  554. {
  555. ast_option_maxcalls = 1;
  556. change_extens(10);
  557. }
  558. ast_config_destroy(cfg);
  559. }