Пример #1
0
range* rangefunc_get_groups(range_request* rr, range** r)
{
    sqlite3* db;
    sqlite3_stmt* stmt;
    int err;
    range* ret = range_new(rr);
    apr_pool_t* pool = range_request_pool(rr);
    const char** tag_names = range_get_hostnames(pool, r[0]);

    const char* tag_name = tag_names[0];

    int warn_enabled = range_request_warn_enabled(rr);
    if (NULL == tag_name) {
        return ret;
    }

    db = _open_db(rr);
    err = sqlite3_prepare(db, GROUPS_SQL, strlen(GROUPS_SQL), &stmt, NULL);
    if (err != SQLITE_OK) {
        range_request_warn(rr, "?%s: cannot query sqlite db", tag_name );
        return ret;
    }
    assert(err == SQLITE_OK);

    sqlite3_bind_text(stmt, 1, tag_name, strlen(tag_name), SQLITE_STATIC);

    while(sqlite3_step(stmt) == SQLITE_ROW) {
        const char* answer = (const char*)sqlite3_column_text(stmt, 0);
        range_add(ret, answer);
    }
    sqlite3_finalize(stmt);
    return ret;
}
Пример #2
0
sqlite3* _open_db(range_request* rr)
{
    char * sqlite_db_path;
    sqlite3* db;
    sqlite3_stmt* stmt;
    libcrange* lr = range_request_lr(rr);
    int err;

    /* open the db */
    if (!(db = libcrange_get_cache(lr, "sqlite:nodes"))) {
        sqlite_db_path = libcrange_getcfg(lr, "sqlitedb");
        if (!sqlite_db_path) sqlite_db_path = DEFAULT_SQLITE_DB;

        err = sqlite3_open(sqlite_db_path, &db);
        if (err != SQLITE_OK) {
            return NULL;
        }
        assert(err == SQLITE_OK);
        /* set mmap pragma */
        err = sqlite3_prepare(db, MMAP_PRAGMA_SQL, strlen(MMAP_PRAGMA_SQL), &stmt, NULL);
        if (err != SQLITE_OK) {
            range_request_warn(rr, "allclusters(): cannot query sqlite db");
            return NULL;
        }
        assert(err == SQLITE_OK);
        while(sqlite3_step(stmt) == SQLITE_ROW) {
            // do nothing. Is this even necessary for the mmap_size pragma? docs are unclear
        }
        /* end mmap pragma setup */

        libcrange_set_cache(lr, "sqlite:nodes", db);
    }

    return db;
}
Пример #3
0
range* rangefunc_clusters(range_request* rr, range** r)
{
    sqlite3* db;
    sqlite3_stmt* stmt;
    int err;

    range* ret = range_new(rr);
    apr_pool_t* pool = range_request_pool(rr);
    const char** nodes = range_get_hostnames(pool, r[0]);
    const char** p_nodes = nodes;

    db = _open_db(rr);
    err = sqlite3_prepare(db, CLUSTERS_SQL, strlen(CLUSTERS_SQL), &stmt, NULL);
    if (err != SQLITE_OK) {
        range_request_warn(rr, "clusters(): cannot query sqlite db");
        return ret;
    }

    while (*p_nodes) {
        char * node_name = *p_nodes;
        sqlite3_bind_text(stmt, 1, node_name, strlen(node_name), SQLITE_STATIC);
        while(sqlite3_step(stmt) == SQLITE_ROW) {
            const char* answer = (const char*)sqlite3_column_text(stmt, 0);
            range_add(ret, answer);
        }
        sqlite3_reset(stmt);
        sqlite3_clear_bindings(stmt);
        ++p_nodes;
    }

    sqlite3_finalize(stmt);
    return ret;
}
Пример #4
0
range* do_range_expand(range_request* rr, const char* text)
{
    yyscan_t scanner;
    struct range_extras extra;
    int result;

    if (text == NULL) {
        range* r = range_new(rr);
        range_request_set(rr, r);
        return r;
    }
    current_rr = rr;
    extra.rr = rr;

    yylex_init(&scanner);
    yyset_extra(&extra, scanner);
    yy_scan_string(text, scanner);
    result = yyparse(scanner);
    yylex_destroy(scanner);
    current_rr = NULL;

    if (result != 0) {
        range* r = range_new(rr);
        range_request_warn(rr, "parsing [%s]", text);
        range_request_set(rr, r);
        return r;
    }

    range_request_set(rr, range_evaluate(rr, extra.theast));
    return range_request_results(rr);
}
Пример #5
0
range* range_from_match(range_request* rr,
                        const range* r, const char* regex)
{
    range* ret;
    int i;
    int err_offset;
    int ovector[30];
    int count;
    const char* error;
    const char** members;
    pcre* re;
    apr_pool_t* pool = range_request_pool(rr);
    
    members = range_get_hostnames(pool, r);
    ret = range_new(rr);

    re = pcre_compile(regex, 0, &error, &err_offset, NULL);
    if (!re) {
        range_request_warn(rr, "regex [%s] [%s]", regex, error);
        return ret;
    }

    for (i = 0; members[i]; i++) {
        count = pcre_exec(re, NULL, members[i],
                          strlen(members[i]), 0, 0, ovector, 30);
        if (count > 0) /* it matched */
            range_add(ret, members[i]);
    }
    pcre_free(re);

    return ret;
}
Пример #6
0
range* _do_has_mem(range_request* rr, range** r, char* sql_query)
{
    sqlite3* db;
    sqlite3_stmt* stmt;
    int err;
    range* ret = range_new(rr);
    apr_pool_t* pool = range_request_pool(rr);
    if (NULL == r[0]) {
        // don't attempt anything without arg #1 (key)
        return ret;
    }
    const char** tag_names = range_get_hostnames(pool, r[0]);
    const char* tag_name = tag_names[0];
    if (NULL == tag_name) {
        return ret;
    }

    const char** tag_values;
    const char* tag_value;
    if (NULL == r[1]) {
        // if we don't have arg #2 (val) then search for keys with empty string value
        tag_value = EMPTY_STRING;
    } else {
        tag_values = range_get_hostnames(pool, r[1]);
        tag_value = tag_values[0];
    }

    const char** all_clusters = _all_clusters(rr);
    const char** cluster = all_clusters;
    int warn_enabled = range_request_warn_enabled(rr);

    db = _open_db(rr);
    err = sqlite3_prepare(db, sql_query, strlen(sql_query), &stmt,
                          NULL);
    if (err != SQLITE_OK) {
        range_request_warn(rr, "has(%s,%s): cannot query sqlite db", tag_name, tag_value);
        return ret;
    }
    assert(err == SQLITE_OK);

    sqlite3_bind_text(stmt, 1, tag_name, strlen(tag_name), SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, tag_value, strlen(tag_value), SQLITE_STATIC);

    while(sqlite3_step(stmt) == SQLITE_ROW) {
        const char* answer = (const char*)sqlite3_column_text(stmt, 0);
        range_add(ret, answer);
    }

    sqlite3_finalize(stmt);
    return ret;
}
Пример #7
0
MDBM * _open_mdbm(range_request* rr)
{
  const char * mdbm_db_path;
  if (!mdbm_cache) {
    libcrange* lr = range_request_lr(rr);
    mdbm_db_path = libcrange_getcfg(lr, "mdbmdb");
    if (!mdbm_db_path) mdbm_db_path = DEFAULT_MDBM_DB;

    mdbm_cache = mdbm_open(mdbm_db_path, MDBM_O_RDONLY, 0, 0, 0);
    if (!mdbm_cache) { range_request_warn(rr, "cannot open mdbm"); }
    assert(mdbm_cache);
  }
  return mdbm_cache;
}
Пример #8
0
static set* _cluster_keys(range_request* rr, apr_pool_t* pool,
                          const char* cluster)
{
    set* sections;
    sqlite3* db;
    sqlite3_stmt* stmt;
    int err;
    db = _open_db(rr);

    /* our return set */
    sections = set_new(pool, 0);


    /* prepare our select */
    err = sqlite3_prepare(db, KEYVALUE_SQL, strlen(KEYVALUE_SQL),
                          &stmt, NULL);
    if (err != SQLITE_OK) {
        range_request_warn(rr, "%s: cannot query sqlite db", cluster);
        return sections;
    }
    assert(err == SQLITE_OK);

    /* for each key/value pair in cluster */
    sqlite3_bind_text(stmt, 1, cluster, strlen(cluster), SQLITE_STATIC);
    while(sqlite3_step(stmt) == SQLITE_ROW) {
        /* add it to the return */
        const char* key = (const char*)sqlite3_column_text(stmt, 0);
        const char* value = (const char*)sqlite3_column_text(stmt, 1);
        if (NULL == value) {
            value = EMPTY_STRING;
        }
        set_add(sections, key, apr_psprintf(pool, "%s",  _substitute_dollars(pool, cluster, value) ));
    }

    /* Add the magic "KEYS" index */
    set_add(sections, "KEYS", _join_elements(pool, ',', sections));

    sqlite3_finalize(stmt);
    return sections;
}
Пример #9
0
/* this is where the magic happens */
static set* _cluster_keys(range_request* rr, apr_pool_t* pool,
                          const char* cluster, const char* cluster_file)
{
    apr_array_header_t* working_range;
    set* sections;
    char* section;
    char* cur_section;
    apr_pool_t* req_pool = range_request_pool(rr);
    yaml_node_t *node;
    yaml_node_t *rootnode;
    yaml_node_t *keynode;
    yaml_node_t *valuenode;
    yaml_parser_t parser;
    yaml_node_item_t *item;
    yaml_node_pair_t *pair;
    
    yaml_document_t document;
    
    FILE* fp = fopen(cluster_file, "r");

    /* make sure we can open the file and parse it */
    if (!fp) {
        range_request_warn(rr, "%s: %s not readable", cluster, cluster_file);
        return set_new(pool, 0);
    }

    if (!yaml_parser_initialize(&parser)) {
        range_request_warn(rr, "%s: cannot initialize yaml parser", cluster);
        fclose(fp);
        return set_new(pool, 0);
    }

    yaml_parser_set_input_file(&parser, fp);
    if(!yaml_parser_load(&parser, &document)) {
        range_request_warn(rr, "%s: malformatted cluster definition %s",
                           cluster, cluster_file);
        fclose(fp);
        yaml_parser_delete(&parser);
        return set_new(pool, 0);
    }
    fclose(fp);
    
    rootnode = yaml_document_get_root_node(&document);
    /* make sure it's just a simple dictionary */
    if(rootnode->type != YAML_MAPPING_NODE) {
        range_request_warn(rr, "%s: malformatted cluster definition %s",
                           cluster, cluster_file);
        yaml_document_delete(&document);
        yaml_parser_delete(&parser);
        return set_new(pool, 0);
    }

    /* "sections" refers to cluster sections - %cluster:SECTION
       it's what we're going to return */
    sections = set_new(pool, 0);
    section = cur_section = NULL;

    for(pair = rootnode->data.mapping.pairs.start;
        pair < rootnode->data.mapping.pairs.top;
        pair++) { /* these are the keys */
        keynode = yaml_document_get_node(&document, pair->key);
        /* cur_section is the keyname - the WHATEVER in %cluster:WHATEVER */
        cur_section = apr_pstrdup(pool, (char *)(keynode->data.scalar.value));
        valuenode = yaml_document_get_node(&document, pair->value);
        /* if the value is a scalar, that's our answer */
        if(valuenode->type == YAML_SCALAR_NODE) {
            set_add(sections, cur_section,
                    apr_psprintf(pool, "%s", valuenode->data.scalar.value));
        } else if (valuenode->type == YAML_SEQUENCE_NODE) {
            /* otherwise, glue together all the values in the list */
            working_range = apr_array_make(req_pool, 1, sizeof(char*));
            for(item = valuenode->data.sequence.items.start;
                item < valuenode->data.sequence.items.top;
                item++) {
                node = yaml_document_get_node(&document, (int)*item);
                if(node->type != YAML_SCALAR_NODE) { /* only scalars allowed */
                    range_request_warn(rr,
                                       "%s: malformed cluster definition %s",
                                       cluster, cluster_file);
                    yaml_document_delete(&document);
                    yaml_parser_delete(&parser);
                    return set_new(pool, 0);
                } else { /* add to the working set */
                    /* include it in () because we're going to comma it
                       together later */
                    *(char**)apr_array_push(working_range) =
                        apr_psprintf(pool, "(%s)", _substitute_dollars(pool,
                          cluster, node->data.scalar.value));
                }
            }
            /* glue the list items together with commas */
            set_add(sections, cur_section,
                    apr_array_pstrcat(pool, working_range, ','));
        }
    }

    /* Add a "KEYS" toplevel key that lists all the other keys */
    /* TODO: make an error if somebody tries to specify KEYS manually? */
    set_add(sections, "KEYS", _join_elements(pool, ',', sections));
    yaml_document_delete(&document);
    yaml_parser_delete(&parser);
    return sections;
}
Пример #10
0
static set* _cluster_keys(range_request* rr, apr_pool_t* pool,
                          const char* cluster, const char* cluster_file)
{
    char line[32768];
    char* p;
    int ovector[30];
    apr_array_header_t* working_range;
    set* sections;
    char* section;
    char* cur_section;
    apr_pool_t* req_pool = range_request_pool(rr);
    int line_no;
    FILE* fp = fopen(cluster_file, "r");

    if (!fp) {
        range_request_warn(rr, "%s: %s not readable", cluster, cluster_file);
        return set_new(pool, 0);
    }

    if (!include_re) {
        const char* error;
        include_re = pcre_compile(INCLUDE_RE, 0, &error, ovector, NULL);
        assert(include_re);

        exclude_re = pcre_compile(EXCLUDE_RE, 0, &error, ovector, NULL);
        assert(exclude_re);
    }

    sections = set_new(pool, 0);
    section = cur_section = NULL;


    working_range = apr_array_make(req_pool, 1, sizeof(char*));
    line_no = 0;
    while (fgets(line, sizeof line, fp)) {
        int len;
        int count;
        line_no++;
        line[sizeof line - 1] = '\0';
        len = strlen(line);
        if (len+1 >= sizeof(line) && line[len - 1] != '\n') {
            /* incomplete line */
            fprintf(stderr, "%s:%d lines > 32767 chars not supported\n", cluster_file, line_no);
            exit(-1);
        }

        line[--len] = '\0'; /* get rid of the \n */
        for (p = line; *p; ++p)
            if (*p == '#') {
                *p = '\0';
                break;
            }

        len = strlen(line);
        if (len == 0) continue;

        for (p = &line[len - 1]; isspace(*p); --p) {
            *p = '\0';
            --len;
        }

        if (!*line) continue;

        if (!(isspace(*line))) {
            cur_section = apr_pstrdup(pool, line);
            continue;
        }

        if (section && strcmp(cur_section, section) != 0) {
            set_add(sections, section, 
                    apr_array_pstrcat(pool, working_range, ','));
            working_range = apr_array_make(req_pool, 1, sizeof(char*));
        }

        section = cur_section;
        count = pcre_exec(include_re, NULL, line, len,
                          0, 0, ovector, 30);
        if (count > 0) {
            line[ovector[3]] = '\0';
            *(char**)apr_array_push(working_range) =
                apr_psprintf(pool, "(%s)",
                             _substitute_dollars(pool, cluster, &line[ovector[2]]));
            continue;
        }

        count = pcre_exec(exclude_re, NULL, line, len,
                          0, 0, ovector, 30);
        if (count > 0) {
            line[ovector[3]] = '\0';
            *(char**)apr_array_push(working_range) =
                apr_psprintf(pool, "-(%s)",
                             _substitute_dollars(pool, cluster, &line[ovector[2]]));
        }

    }
    fclose(fp);

    if (cur_section)
        set_add(sections, cur_section,
                apr_array_pstrcat(pool, working_range, ','));

    set_add(sections, "KEYS", _join_elements(pool, ',', sections));
    set_add(sections, "UP", set_get_data(sections, "CLUSTER"));
    if (set_get(sections, "ALL") && set_get(sections, "CLUSTER"))
        set_add(sections, "DOWN",
                apr_psprintf(pool, "(%s)-(%s)",
                             (char*)set_get_data(sections, "ALL"),
                             (char*)set_get_data(sections, "CLUSTER")));
    return sections;
}
Пример #11
0
const char* do_range_compress(range_request* rr, const range* r)
{
    int i;
    #define MAX_NUM_GROUPS 65536
    const char* groups[MAX_NUM_GROUPS];
    int num_groups = 0;
    int count;
    char* result;
    char* presult;
    int result_size;
    const char** sorted_nodes;
    int n = r->nodes->members;
    apr_pool_t* pool = range_request_pool(rr);
    node_parts_int* prev = init_prev_parts(pool);
    int prev_num_str_len = -1;

    if (n == 0) return "";

    sorted_nodes = do_range_sort(rr, r);
    init_range_parts();

    count = 0;
    for (i=0; i<n; ++i) {
        node_parts_int* parts = node_to_parts(pool, sorted_nodes[i]);
        if (strcmp(parts->prefix, prev->prefix) == 0 &&
            strcmp(parts->domain,  prev->domain) == 0 &&
            (parts->num == prev->num + count + 1) &&
	    strlen(parts->num_str) == prev_num_str_len) count++;
        else {
            if (*prev->full_name) {
                if (count > 0)
                    groups[num_groups] = fmt_group(pool, prev, count);
                else
                    groups[num_groups] = prev->full_name;
                ++num_groups;
                if (num_groups == MAX_NUM_GROUPS) {
                    range_request_warn(rr, "%s\n", "too many compressed groups");
                    return "";
                }
            }
            prev = parts;
            if (prev->num_str)
                prev_num_str_len = strlen(prev->num_str);
            count = 0;
        }
    }
    if (count > 0)
        groups[num_groups] = fmt_group(pool, prev, count);
    else
        groups[num_groups] = prev->full_name;
    
    /* num_groups is 1 less than the # of groups */
    result_size = num_groups; /* commas */
    for (i=0; i<=num_groups; ++i) result_size += strlen(groups[i]);
    presult = result = apr_palloc(pool, result_size + 1);
    
    for (i=0; i<num_groups; ++i) {
        strcpy(presult, groups[i]);
        presult += strlen(groups[i]);
        *presult++ = ',';
    }
    
    /* add the last one */
    strcpy(presult, groups[num_groups]);
    return result;
}
Пример #12
0
void yyerror (YYLTYPE *locp, void * scanner, char const *msg)
{
    range_request_warn(current_rr, "%s", msg);
}