boa阅读笔记2

拟墨画扇 提交于 2021-01-06 02:03:20
    fixup_server_root();
    read_config_files();
    open_logs();
    server_s = create_server_socket();
    init_signals();
    drop_privs();
    create_common_env();
    build_needs_escape();

上次我们讲到了处理命令行选项,接下来要分析一系列初始化函数,先介绍第一个函数。

static void fixup_server_root()
{
    char *dirbuf;
    
    if (!server_root) {//如果命令行选项中没有指定server_root,则设置server_root
#ifdef SERVER_ROOT
        //从头文件读取SERVER_ROOT的值
        server_root = strdup(SERVER_ROOT);
        if (!server_root) {
            perror("strdup (SERVER_ROOT)");
            exit(1);
        }
#else
        //如果没有定义SERVER_ROOT,则报错退出
        fputs("boa: don't know where server root is.  Please #define "
              "SERVER_ROOT in boa.h\n"
              "and recompile, or use the -c command line option to "
              "specify it.\n", stderr);
        exit(1);
#endif
    }
    //验证设置的server_root,注意,之前可能chroot和chdir了,所以server_root
    //的设置要考虑这点。
    if (chdir(server_root) == -1) {
        fprintf(stderr, "Could not chdir to \"%s\": aborting\n",
                server_root);
        exit(1);
    }
    //相对路径转绝对路径
    dirbuf = normalize_path(server_root);
    free(server_root);
    server_root = dirbuf;
}

fixup_server_root()函数从名字就可以以看出来,作用是修复server_root变量,如果server_root变量无法设置成功,则报错退出,否则转成绝对路径保存。

/*
 * Name: read_config_files
 *
 * Description: Reads config files via yyparse, then makes sure that
 * all required variables were set properly.
 */
void read_config_files(void)
{
    char *temp;
    //获取调用程序的用户ID
    current_uid = getuid();
    //供flex读取的文件指针
    yyin = fopen("boa.conf", "r");

    if (!yyin) {
        fputs("Could not open boa.conf for reading.\n", stderr);
        exit(1);
    }
    //对配置文件使用flex和bison进行解析
    if (yyparse()) {
        fputs("Error parsing config files, exiting\n", stderr);
        exit(1);
    }
    
    if (!server_name) {//如果没有定义server_name(暂时没有找到哪里赋值server_name)
        struct hostent *he;
        char temp_name[100];
        //获取主机名
        if (gethostname(temp_name, 100) == -1) {
            perror("gethostname:");
            exit(1);
        }
        //通过主机名获取主机结构体
        he = gethostbyname(temp_name);
        if (he == NULL) {
            perror("gethostbyname:");
            exit(1);
        }
        //从结构体里获得名字
        server_name = strdup(he->h_name);
        if (server_name == NULL) {
            perror("strdup:");
            exit(1);
        }
    }
    //获取临时文件夹
    tempdir = getenv("TMP");
    if (tempdir == NULL)
        tempdir = "/tmp";
    
    if (single_post_limit < 0) {//单线程post数小于零出错
        fprintf(stderr, "Invalid value for single_post_limit: %d\n",
                single_post_limit);
        exit(1);
    }
    //其他配置变量设置,统一转化成绝对路径
    if (document_root) {
        temp = normalize_path(document_root);
        free(document_root);
        document_root = temp;
    }

    if (error_log_name) {
        temp = normalize_path(error_log_name);
        free(error_log_name);
        error_log_name = temp;
    }

    if (access_log_name) {
        temp = normalize_path(access_log_name);
        free(access_log_name);
        access_log_name = temp;
    }

    if (cgi_log_name) {
        temp = normalize_path(cgi_log_name);
        free(cgi_log_name);
        cgi_log_name = temp;
    }

    if (dirmaker) {
        temp = normalize_path(dirmaker);
        free(dirmaker);
        dirmaker = temp;
    }

#if 0
    if (mime_types) {
        temp = normalize_path(mime_types);
        free(mime_types);
        mime_types = temp;
    }
#endif
}

read_config_files()函数用来读取配置信息,它使用了flex&bison的yyparse()来对文件进行词法和语法解析,flex和bison这对组合作为解析器提供了很高灵活性和可靠性。

flex和bison的使用方法笔者正在研究学习中,以后有心得了会发上来和大家分享。

今天就先到这里,下次继续分析下面的部分,欢迎大家讨论和批评。




易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!