您的位置:首页 > 其它

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

2012-12-03 10:47 344 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: