Asterisk内核框架(2)--启动过程

 asterisk启动过程
主要就main函数讲解asterisk的启动过程:
int main(int argc, char *argv[])
{
       int c;
       char filename[80] = "";
       char hostname[MAXHOSTNAMELEN] = "";
       char tmp[80];
       char * xarg = NULL;
       int x;
       FILE *f;
       sigset_t sigs;
       int num;
       int isroot = 1;
       char *buf;
       char *runuser = NULL, *rungroup = NULL;
/*保存命令行参数(argv[]->_argv[]),以便程序重启时使用*/
       /* Remember original args for restart */
       if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) {
              fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1);
              argc = sizeof(_argv) / sizeof(_argv[0]) - 1;
       }
       for (x=0; x<argc; x++)
              _argv[x] = argv[x];
       _argv[x] = NULL;
       if (geteuid() != 0)
              isroot = 0;
/*命令如果是rasterisk,设置AST_OPT_FLAG_NO_FORK和AST_OPT_FLAG_REMOTE标志位*/
       /* if the progname is rasterisk consider it a remote console */
       if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
              ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
       }
/*得到当前主机名,在启动时打印出来*/
       if (gethostname(hostname, sizeof(hostname)-1))
              ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
/*获取当前的进程标识*/
       ast_mainpid = getpid();
/*建立mu-law和a-law转换表*/
       ast_ulaw_init();
       ast_alaw_init();
/*为FFT逆变换(傅立叶逆变换)做一些初始化,用于在zaptel里进行callerid的DTMF检测*/
       callerid_init();
/*初始化内置命令的_full_cmd字符串,并注册常用命令,ast_builtins_init() -> ast_cli_register_multiple() -> ast_cli_register() -> __ast_cli_register() */
       ast_builtins_init();
/*初始化base64转换*/
       ast_utils_init();
/* tty/tdd初始化*/
       tdd_init();
/*设置用户历史命令的保存路径*/
       if (getenv("HOME"))
              snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
       /* Check for options */
/*检查命令行的输入参数,匹配参数范围是“mtThfFdvVqprRgciInx:U:G:C:L:M:”,不同的参数输入走到不同的case分支处理。有几个v,verbose级别就增加几*/
       while ((c = getopt(argc, argv, "mtThfFdvVqprRgciInx:U:G:C:L:M:")) != -1) {
              switch (c) {
#if HAVE_WORKING_FORK
              case 'F':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
                     break;
              case 'f':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
                     break;
#endif
              case 'd':
                     option_debug++;
                     ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
                     break;
              case 'c':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE);
                     break;
              case 'n':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR);
                     break;
              case 'r':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE);
                     break;
              case 'R':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT);
                     break;
              case 'p':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY);
                     break;
              case 'v':
                     option_verbose++;
                     ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK);
                     break;
              case 'm':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_MUTE);
                     break;
              case 'M':
                     if ((sscanf(optarg, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0))
                            option_maxcalls = 0;
                     break;
              case 'L':
                     if ((sscanf(optarg, "%lf", &option_maxload) != 1) || (option_maxload < 0.0))
                            option_maxload = 0.0;
                     break;
              case 'q':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
                     break;
              case 't':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
                     break;
              case 'T':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP);
                     break;
              case 'x':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC);
                     xarg = ast_strdupa(optarg);
                     break;
              case 'C':
                     ast_copy_string(ast_config_AST_CONFIG_FILE, optarg, sizeof(ast_config_AST_CONFIG_FILE));
                     ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
                     break;
              case 'I':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING);
                     break;
              case 'i':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
                     break;
              case 'g':
                     ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE);
                     break;
              case 'h':
                     show_cli_help();
                     exit(0);
              case 'V':
                     show_version();
                     exit(0);
              case 'U':
                     runuser = ast_strdupa(optarg);
                     break;
              case 'G':
                     rungroup = ast_strdupa(optarg);
                     break;
              case '?':
                     exit(1);
              }
       }
/*如果用了-c或者-v或者-r并且没有-x cmd参数,则打印欢迎信息*/
       if (ast_opt_console || option_verbose || (ast_opt_remote && !ast_opt_exec)) {
              ast_register_verbose(console_verboser);
              WELCOME_MESSAGE;
       }
/*如果没有开调试则简单打印Booting... */
       if (ast_opt_console && !option_verbose)
              ast_verbose("[ Booting...\n");
/*显示控制台时,不论是本地还是远程,都不能使用-F参数,否则无效*/
       if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
              ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
              ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
       }
       /* For remote connections, change the name of the remote connection.
        * We do this for the benefit of init scripts (which need to know if/when
        * the main asterisk process has died yet). */
       if (ast_opt_remote) {
              strcpy(argv[0], "rasterisk");
              for (x = 1; x < argc; x++) {
                     argv[x] = argv[0] + 10;
              }
       }
/*读取主配置文件,主配置文件是由make menuselect配置的*/
       if (ast_opt_console && !option_verbose)
              ast_verbose("[ Reading Master Configuration ]\n");
       ast_readconfig();
/*如果启动加了-g,取消core dump文件的大小限制*/
       if (ast_opt_dump_core) {
              struct rlimit l;
              memset(&l, 0, sizeof(l));
              l.rlim_cur = RLIM_INFINITY;
              l.rlim_max = RLIM_INFINITY;
              if (setrlimit(RLIMIT_CORE, &l)) {
                     ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
              }
       }
/*修改用户和组权限*/
       if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP))
              rungroup = ast_config_AST_RUN_GROUP;
       if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER))
              runuser = ast_config_AST_RUN_USER;
#ifndef __CYGWIN__
       if (isroot)
              ast_set_priority(ast_opt_high_priority);
       if (isroot && rungroup) {
              struct group *gr;
              gr = getgrnam(rungroup);
              if (!gr) {
                     ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
                     exit(1);
              }
              if (setgid(gr->gr_gid)) {
                     ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup);
                     exit(1);
              }
              if (setgroups(0, NULL)) {
                     ast_log(LOG_WARNING, "Unable to drop unneeded groups\n");
                     exit(1);
              }
              if (option_verbose)
                     ast_verbose("Running as group '%s'\n", rungroup);
       }
       if (runuser && !ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)) {
#ifdef HAVE_CAP
              int has_cap = 1;
#endif /* HAVE_CAP */
              struct passwd *pw;
              pw = getpwnam(runuser);
              if (!pw) {
                     ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
                     exit(1);
              }
#ifdef HAVE_CAP
              if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
                     ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
                     has_cap = 0;
              }
#endif /* HAVE_CAP */
              if (!isroot && pw->pw_uid != geteuid()) {
                     ast_log(LOG_ERROR, "Asterisk started as nonroot, but runuser '%s' requested.\n", runuser);
                     exit(1);
              }
              if (!rungroup) {
                     if (setgid(pw->pw_gid)) {
                            ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
                            exit(1);
                     }
                     if (isroot && initgroups(pw->pw_name, pw->pw_gid)) {
                            ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser);
                            exit(1);
                     }
              }
              if (setuid(pw->pw_uid)) {
                     ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser);
                     exit(1);
              }
              if (option_verbose)
                     ast_verbose("Running as user '%s'\n", runuser);
#ifdef HAVE_CAP
              if (has_cap) {
                     cap_t cap;
                     cap = cap_from_text("cap_net_admin=ep");
                     if (cap_set_proc(cap))
                            ast_log(LOG_WARNING, "Unable to install capabilities.\n");
                     if (cap_free(cap))
                            ast_log(LOG_WARNING, "Unable to drop capabilities.\n");
              }
#endif /* HAVE_CAP */
       }
#endif /* __CYGWIN__ */
#ifdef linux
       if (geteuid() && ast_opt_dump_core) {
              if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
                     ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno));
              }   
       }
#endif
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值