コード例 #1
0
ファイル: lwan.c プロジェクト: LegendZhu/lwan
static const lwan_module_t *lwan_module_find(lwan_t *l, const char *name)
{
    lwan_module_t *module = hash_find(l->module_registry, name);
    if (!module) {
        lwan_module_t *(*module_fn)(void);
        char module_symbol[128];
        int r;

        for (const char *p = name; *p; p++) {
            if (isalnum(*p) || *p == '_')
                continue;

            lwan_status_error("Module name (%s) contains invalid character: %c",
                name, *p);
            return NULL;
        }

        r = snprintf(module_symbol, sizeof(module_symbol),
            "lwan_module_%s", name);
        if (r < 0 || r >= (int)sizeof(module_symbol)) {
            lwan_status_error("Module name too long: %s", name);
            return NULL;
        }

        module_fn = find_handler_symbol(module_symbol);
        if (!module_fn) {
            lwan_status_error("Module \"%s\" does not exist", name);
            return NULL;
        }

        module = module_fn();
        if (!module) {
            lwan_status_error("Function \"%s()\" didn't return a module",
                module_symbol);
            return NULL;
        }

        lwan_status_debug("Module \"%s\" registered", name);
        hash_add(l->module_registry, module->name, module);
    }

    return module;
}
コード例 #2
0
ファイル: lwan-straitjacket.c プロジェクト: 0x003e/lwan
static bool get_user_uid_gid(const char *user, uid_t *uid, gid_t *gid)
{
    struct passwd pwd = { };
    struct passwd *result;
    char *buf;
    long pw_size_max = sysconf(_SC_GETPW_R_SIZE_MAX);
    int r;

    if (!user || !*user) {
        lwan_status_error("Username should be provided");
        return false;
    }

    if (pw_size_max < 0)
        pw_size_max = 16384;

    buf = malloc((size_t)pw_size_max);
    if (!buf) {
        lwan_status_error("Could not allocate buffer for passwd struct");
        return false;
    }

    r = getpwnam_r(user, &pwd, buf, (size_t)pw_size_max, &result);
    *uid = pwd.pw_uid;
    *gid = pwd.pw_gid;
    free(buf);

    if (result)
        return true;

    if (!r) {
        lwan_status_error("Username not found: %s", user);
    } else {
        errno = r;
        lwan_status_perror("Could not obtain uid/gid for user %s", user);
    }

    return false;
}
コード例 #3
0
ファイル: lwan-thread.c プロジェクト: pokey909/lwan
void
lwan_thread_shutdown(lwan_t *l)
{
    lwan_status_debug("Shutting down threads");

    for (int i = l->thread.count - 1; i >= 0; i--) {
        lwan_thread_t *t = &l->thread.threads[i];
        char less_than_int = 0;
        ssize_t r;

        lwan_status_debug("Closing epoll for thread %d (fd=%d)", i,
            t->epoll_fd);

        /* Close the epoll_fd and write less than an int to signal the
         * thread to gracefully finish.  */
        close(t->epoll_fd);

        while (true) {
            r = write(t->pipe_fd[1], &less_than_int, sizeof(less_than_int));

            if (r >= 0)
                break;

            if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
                continue;

            lwan_status_error("Could not write to I/O thread (%d) pipe to shutdown", i);
            break;
        }
    }

    for (int i = l->thread.count - 1; i >= 0; i--) {
        lwan_thread_t *t = &l->thread.threads[i];

        lwan_status_debug("Waiting for thread %d to finish", i);
        pthread_join(l->thread.threads[i].self, NULL);

        lwan_status_debug("Closing pipe (%d, %d)", t->pipe_fd[0],
            t->pipe_fd[1]);
        close(t->pipe_fd[0]);
        close(t->pipe_fd[1]);
    }

    free(l->thread.threads);
}
コード例 #4
0
ファイル: lwan-config.c プロジェクト: ktsaou/lwan
static void *parse_config(struct parser *parser)
{
    struct lexeme *lexeme;

    while (lex_next(&parser->lexer, &lexeme)) {
        switch (lexeme->type) {
        case LEXEME_EQUAL:
            return parse_key_value;

        case LEXEME_OPEN_BRACKET:
            return parse_section;

        case LEXEME_LINEFEED:
            if (parser->buffer.population)
                return parse_section_shorthand;

            return parse_config;

        case LEXEME_STRING:
            lexeme_buffer_emit(&parser->buffer, lexeme);
            break;

        case LEXEME_CLOSE_BRACKET: {
            struct config_line line = { .type = CONFIG_LINE_TYPE_SECTION_END };

            config_buffer_emit(&parser->items, &line);

            return parse_config;
        }

        case LEXEME_EOF:
            return NULL;

        default:
            lwan_status_error("Unexpected lexeme type: %s",
                lexeme_type_str[lexeme->type]);
            return NULL;
        }
    }

    return NULL;
}
コード例 #5
0
ファイル: lwan-config.c プロジェクト: ktsaou/lwan
static void *parse_key_value(struct parser *parser)
{
    struct config_line line = { .type = CONFIG_LINE_TYPE_LINE };
    struct lexeme *lexeme;
    size_t key_size;

    while (lexeme_buffer_consume(&parser->buffer, &lexeme)) {
        strbuf_append_str(&parser->strbuf, lexeme->value.value, lexeme->value.len);

        if (parser->buffer.population >= 1)
            strbuf_append_char(&parser->strbuf, '_');
    }
    key_size = strbuf_get_length(&parser->strbuf);
    strbuf_append_char(&parser->strbuf, '\0');

    while (lex_next(&parser->lexer, &lexeme)) {
        switch (lexeme->type) {
        case LEXEME_VARIABLE: {
            const char *value;

            value = secure_getenv_len(lexeme->value.value, lexeme->value.len);
            if (!value) {
                lwan_status_error("Variable '$%.*s' not defined in environment",
                    (int)lexeme->value.len, lexeme->value.value);
                return NULL;
            }

            strbuf_append_str(&parser->strbuf, value, 0);
            break;
        }

        case LEXEME_EQUAL:
            strbuf_append_char(&parser->strbuf, '=');
            break;

        case LEXEME_STRING:
            strbuf_append_str(&parser->strbuf, lexeme->value.value, lexeme->value.len);
            break;

        case LEXEME_CLOSE_BRACKET:
            backup(&parser->lexer);
            /* fallthrough */

        case LEXEME_LINEFEED:
            line.key = strbuf_get_buffer(&parser->strbuf);
            line.value = line.key + key_size + 1;
            if (!config_buffer_emit(&parser->items, &line))
                return NULL;

            return parse_config;

        default:
            lwan_status_error("Unexpected token while parsing key-value: %s",
                lexeme_type_str[lexeme->type]);
            return NULL;
        }
    }

    lwan_status_error("EOF while parsing key-value");
    return NULL;
}