⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 config.c

📁 boa 一个简小的web服务器 资源占用极少
💻 C
字号:
/*
 *  Boa, an http server
 *  Copyright (C) 1999 Larry Doolittle <ldoolitt@boa.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 1, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

/* $Id: config.c,v 1.31.2.3 2002/07/26 03:04:29 jnelson Exp $*/

#include "boa.h"
#include "y.tab.h"
#include "parse.h"

int yyparse(void);              /* Better match the output of lex */

#ifdef DEBUG
#define DBG(x) x
#else
#define DBG(x)
#endif

int server_port;
uid_t server_uid;
gid_t server_gid;
char *server_root;
char *server_name;
char *server_admin;
char *server_ip;
int virtualhost;
long int max_connections;

char *document_root;
char *user_dir;
char *directory_index;
char *default_type;
char *dirmaker;
char *cachedir;

char *tempdir;

char *cgi_path = NULL;
int single_post_limit = SINGLE_POST_LIMIT_DEFAULT;

int ka_timeout;
int ka_max;

/* These came from log.c */
char *error_log_name;
char *access_log_name;
char *cgi_log_name;

int use_localtime;

/* These are new */
static void c_set_user(char *v1, char *v2, void *t);
static void c_set_group(char *v1, char *v2, void *t);
static void c_set_string(char *v1, char *v2, void *t);
static void c_set_int(char *v1, char *v2, void *t);
static void c_set_unity(char *v1, char *v2, void *t);
static void c_add_type(char *v1, char *v2, void *t);
static void c_add_alias(char *v1, char *v2, void *t);

/* Fakery to keep the value passed to action() a void *,
   see usage in table and c_add_alias() below */
static int script_number = SCRIPTALIAS;
static int redirect_number = REDIRECT;
static int alias_number = ALIAS;
static uid_t current_uid=0;

/* Help keep the table below compact */
#define S0A STMT_NO_ARGS
#define S1A STMT_ONE_ARG
#define S2A STMT_TWO_ARGS

struct ccommand clist[] = {
    {"Port", S1A, c_set_int, &server_port},
    {"Listen", S1A, c_set_string, &server_ip},
    {"BackLog", S1A, c_set_int, &backlog},
    {"User", S1A, c_set_user, NULL},
    {"Group", S1A, c_set_group, NULL},
    {"ServerAdmin", S1A, c_set_string, &server_admin},
    {"ServerRoot", S1A, c_set_string, &server_root},
    {"ErrorLog", S1A, c_set_string, &error_log_name},
    {"AccessLog", S1A, c_set_string, &access_log_name},
    {"UseLocaltime", S0A, c_set_unity, &use_localtime},
    {"CgiLog", S1A, c_set_string, &cgi_log_name},
    {"VerboseCGILogs", S0A, c_set_unity, &verbose_cgi_logs},
    {"ServerName", S1A, c_set_string, &server_name},
    {"VirtualHost", S0A, c_set_unity, &virtualhost},
    {"DocumentRoot", S1A, c_set_string, &document_root},
    {"UserDir", S1A, c_set_string, &user_dir},
    {"DirectoryIndex", S1A, c_set_string, &directory_index},
    {"DirectoryMaker", S1A, c_set_string, &dirmaker},
    {"DirectoryCache", S1A, c_set_string, &cachedir},
    {"KeepAliveMax", S1A, c_set_int, &ka_max},
    {"KeepAliveTimeout", S1A, c_set_int, &ka_timeout},
    {"MimeTypes", S1A, c_set_string, &mime_types},
    {"DefaultType", S1A, c_set_string, &default_type},
    {"AddType", S2A, c_add_type, NULL},
    {"ScriptAlias", S2A, c_add_alias, &script_number},
    {"Redirect", S2A, c_add_alias, &redirect_number},
    {"Alias", S2A, c_add_alias, &alias_number},
    {"SinglePostLimit", S1A, c_set_int, &single_post_limit},
    {"CGIPath", S1A, c_set_string, &cgi_path},
    {"MaxConnections", S1A, c_set_int, &max_connections},
};

static void c_set_user(char *v1, char *v2, void *t)
{
    struct passwd *passwdbuf;
    char *endptr;
    int i;

    DBG(printf("User %s = ", v1);
        )
        i = strtol(v1, &endptr, 0);
    if (*v1 != '\0' && *endptr == '\0') {
        server_uid = i;
    } else {
        passwdbuf = getpwnam(v1);
        if (!passwdbuf) {
            if (current_uid)
                return;
            fprintf(stderr, "No such user: %s\n", v1);
            exit(1);
        }
        server_uid = passwdbuf->pw_uid;
    }
    DBG(printf("%d\n", server_uid);
        )
}

static void c_set_group(char *v1, char *v2, void *t)
{
    struct group *groupbuf;
    char *endptr;
    int i;
    DBG(printf("Group %s = ", v1);
        )
        i = strtol(v1, &endptr, 0);
    if (*v1 != '\0' && *endptr == '\0') {
        server_gid = i;
    } else {
        groupbuf = getgrnam(v1);
        if (!groupbuf) {
            if (current_uid)
                return;
            fprintf(stderr, "No such group: %s\n", v1);
            exit(1);
        }
        server_gid = groupbuf->gr_gid;
    }
    DBG(printf("%d\n", server_gid);
        )
}

static void c_set_string(char *v1, char *v2, void *t)
{
    char *s;
    DBG(printf("Setting pointer %p to string %s ..", t, v1);
        )
        if (t) {
        s = *(char **) t;
        if (s)
            free(s);
        *(char **) t = strdup(v1);
        if (!*(char **) t) {
            DIE("Unable to strdup in c_set_string");
        }
        DBG(printf("done.\n");
            )
    } else {
        DBG(printf("skipped.\n");
            )
    }
}

static void c_set_int(char *v1, char *v2, void *t)
{
    char *endptr;
    int i;
    DBG(printf("Setting pointer %p to integer string %s ..", t, v1);
        )
        if (t) {
        i = strtol(v1, &endptr, 0); /* Automatic base 10/16/8 switching */
        if (*v1 != '\0' && *endptr == '\0') {
            *(int *) t = i;
            DBG(printf(" Integer converted as %d, done\n", i);
                )
        } else {
            /* XXX should tell line number to user */
            fprintf(stderr, "Error: %s found where integer expected\n",
                    v1);
        }
    } else {
        DBG(printf("skipped.\n");
            )
    }
}

static void c_set_unity(char *v1, char *v2, void *t)
{
    DBG(printf("Setting pointer %p to unity\n", t);
        )
        if (t)
        *(int *) t = 1;
}

static void c_add_type(char *v1, char *v2, void *t)
{
    add_mime_type(v1, v2);
}

static void c_add_alias(char *v1, char *v2, void *t)
{
    add_alias(v2, v1, *(int *) t);
}

struct ccommand *lookup_keyword(char *c)
{
    struct ccommand *p;
    DBG(printf("Checking string '%s' against keyword list\n", c);
        )
        for (p = clist;
             p < clist + (sizeof (clist) / sizeof (struct ccommand)); p++) {
        if (strcmp(c, p->name) == 0)
            return p;
    }
    return NULL;
}

/*
 * 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;
    current_uid = getuid();
    yyin = fopen("boa.conf", "r");

    if (!yyin) {
        fputs("Could not open boa.conf for reading.\n", stderr);
        exit(1);
    }
    if (yyparse()) {
        fputs("Error parsing config files, exiting\n", stderr);
        exit(1);
    }

    if (!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) {
        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
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -