Esempio n. 1
0
range* rangefunc_has(range_request* rr, range** r)
{
    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_values = range_get_hostnames(pool, r[1]);

    const char* tag_name = tag_names[0];
    const char* 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);

    if (!cluster) return ret;

    range_request_disable_warns(rr);
    while (*cluster) {
        range* vals = _expand_cluster(rr, *cluster, tag_name);
        if (set_get(vals->nodes, tag_value) != NULL) {
            range_add(ret, *cluster);
        }
        cluster++;
    }
    if (warn_enabled) range_request_enable_warns(rr);

    return ret;
}
Esempio n. 2
0
range* rangefunc_mem(range_request* rr, range** r)
{
    range* ret = range_new(rr);
    apr_pool_t* pool = range_request_pool(rr);
    const char** clusters = range_get_hostnames(pool, r[0]);
    const char* cluster = clusters[0];
    const char** wanted = range_get_hostnames(pool, r[1]);
    
    range* keys = _expand_cluster(rr, cluster, "KEYS");
    const char** all_sections = range_get_hostnames(pool, keys);
    const char** p_section = all_sections;

  SECTION:
    while (*p_section) {
        range* r_s = _expand_cluster(rr, cluster, *p_section);
        const char** p_wanted = wanted;
        while (*p_wanted) {
            if (set_get(r_s->nodes, *p_wanted) != NULL) {
                range_add(ret, *p_section++);
                goto SECTION;
            }
            ++p_wanted;
        }
        ++p_section;
    }

    return ret;
}
Esempio n. 3
0
static range* _expand_cluster(range_request* rr, const char* cluster, const char* section)
{
  set * ret_set;
  MDBM * db = _open_mdbm(rr);
  apr_pool_t* req_pool = range_request_pool(rr);
  // return a range * of the section
  // build the key:val
  strncpy(fetch_key, cluster, MAX_CLUSTER_STRING);
  strncat(fetch_key, ":", MAX_CLUSTER_STRING);
  strncat(fetch_key, section, MAX_CLUSTER_STRING);
  // first, query the data from mdbm
  datum val;
  datum key;
  key.dptr = fetch_key;
  key.dsize = strlen(fetch_key);
  val = mdbm_fetch(db, key);
  if (val.dsize) {
    ret_set = set_unpack(req_pool, val.dptr);
    return range_from_set(rr, ret_set);
  } else {
    /* FIXME warn -- ok fixed*/
    range_request_warn_type(rr, "NOCLUSTER", fetch_key);
    return range_new(rr);
  }
}
Esempio n. 4
0
static set* _get_clusters(range_request* rr)
{
    const char** all_clusters = _all_clusters(rr);
    const char** p_cl = all_clusters;
    apr_pool_t* pool = range_request_pool(rr);
    set* node_cluster = set_new(pool, 40000);

    if(p_cl == NULL) {
        return node_cluster;
    }

    while (*p_cl) {
        range* nodes_r = _expand_cluster(rr, *p_cl, "CLUSTER");
        const char** nodes = range_get_hostnames(pool, nodes_r);
        const char** p_nodes = nodes;

        while (*p_nodes) {
            apr_array_header_t* clusters = set_get_data(node_cluster, *p_nodes);

            if (!clusters) {
                clusters = apr_array_make(pool, 1, sizeof(char*));
                set_add(node_cluster, *p_nodes, clusters);
            }

            *(const char**)apr_array_push(clusters) = *p_cl;
            ++p_nodes;
        }
        ++p_cl;
    }

    return node_cluster;
}
Esempio n. 5
0
range* rangefunc_clusters(range_request* rr, range** r)
{
    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;
    set* node_cluster = _get_clusters(rr);
    
    while (*p_nodes) {
        apr_array_header_t* clusters = set_get_data(node_cluster, *p_nodes);
        if (!clusters)
            range_request_warn_type(rr, "NO_CLUSTER", *p_nodes);
        else {
            /* get all */
            int i;
            for (i=0; i<clusters->nelts; ++i) {
                const char* cluster = ((const char**)clusters->elts)[i];
                range_add(ret, cluster);
            }
        }
        ++p_nodes;
    }

    return ret;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
0
static vips* _empty_vips(range_request* rr)
{
    apr_pool_t* pool = range_request_pool(rr);
    vips* v = apr_palloc(pool, sizeof(*v));
    v->vips = v->viphosts = set_new(pool, 0);
    return v;
}
Esempio n. 10
0
range* range_from_set(range_request* rr, set* s)
{
    apr_pool_t* p = range_request_pool(rr);
    range* r = apr_palloc(p, sizeof(range));
    r->nodes = s;
    r->quoted = 0;
    return r;
}
Esempio n. 11
0
range* range_new(range_request* rr)
{
    apr_pool_t* pool = range_request_pool(rr);
    range* r = apr_palloc(pool, sizeof(range));
    r->nodes = set_new(pool, 0);
    r->quoted = 0;
    return r;
}
Esempio n. 12
0
static range* _expand_cluster(range_request* rr,
                              const char* cluster, const char* section)
{
    struct stat st;
    const char* res;
    libcrange* lr = range_request_lr(rr);
    set* cache = libcrange_get_cache(lr, "nodescf:cluster_keys");
    apr_pool_t* req_pool = range_request_pool(rr);
    apr_pool_t* lr_pool = range_request_lr_pool(rr);

    const char* cluster_file;
    cache_entry* e;

    if (strcmp(section, "VIPS") == 0)
        return _cluster_vips(rr, cluster);

    if (strcmp(section, "VIPHOSTS") == 0)
        return _cluster_viphosts(rr, cluster);
    
    cluster_file = apr_psprintf(req_pool, "%s/%s/nodes.cf", nodescf_path, cluster);
    if (!cache) {
        cache = set_new(lr_pool, 0);
        libcrange_set_cache(lr, "nodescf:cluster_keys", cache);
    }

    if (stat(cluster_file, &st) == -1) {
        range_request_warn_type(rr, "NOCLUSTERDEF", cluster);
        return range_new(rr);
    }
    
    e = set_get_data(cache, cluster_file);
    if (!e) {
        e = apr_palloc(lr_pool, sizeof(struct cache_entry));
        apr_pool_create(&e->pool, lr_pool);
        e->sections = _cluster_keys(rr, e->pool, cluster, cluster_file);
        e->mtime = st.st_mtime;
        set_add(cache, cluster_file, e);
    }
    else {
        time_t cached_mtime = e->mtime;
        if (cached_mtime != st.st_mtime) {
            apr_pool_clear(e->pool);
            e->sections = _cluster_keys(rr, e->pool, cluster, cluster_file);
            e->mtime = st.st_mtime;
        } 
    }

    res = set_get_data(e->sections, section);

    if (!res) {
        char* cluster_section = apr_psprintf(req_pool,
                                             "%s:%s", cluster, section);
        range_request_warn_type(rr, "NOCLUSTER", cluster_section);
        return range_new(rr);
    }

    return do_range_expand(rr, res);
}
Esempio n. 13
0
range* range_from_diff(range_request* rr,
                       const range* r1, const range* r2)
{
    range* r3 = range_new(rr);
    apr_pool_t* pool = range_request_pool(rr);
    
    r3->nodes = set_diff(pool, r1->nodes, r2->nodes);
    r3->quoted = r1->quoted || r2->quoted;
    return r3;
}
Esempio n. 14
0
range* rangefunc_group(range_request* rr, range** r)
{
    range* ret = range_new(rr);
    apr_pool_t* pool = range_request_pool(rr);
    const char** groups = range_get_hostnames(pool, r[0]);

    while (*groups) {
        range_union_inplace(rr, ret, _expand_cluster(rr, "GROUPS", *groups));
        ++groups;
    }
    return ret;
}
Esempio n. 15
0
range* range_from_braces(range_request* rr,
                         const range* r1, const range* r2, const range* r3)
{
    int i, j, k;
    set_element** m1;
    set_element** m2;
    set_element** m3;
    set* temp = NULL;
    range* bigrange;
    char* bundle;
    apr_pool_t* pool = range_request_pool(rr);
    
    if(r1->nodes->members == 0) {
        if(!temp) {
            temp = set_new(pool, 1);
            set_add(temp, "", NULL);
        }
        m1 = set_members(temp);
    } else m1 = set_members(r1->nodes);

    if(r2->nodes->members == 0) {
        if(!temp) {
            temp = set_new(pool, 1);
            set_add(temp, "", NULL);
        }
        m2 = set_members(temp);
    } else m2 = set_members(r2->nodes);

    if(r3->nodes->members == 0) {
        if(!temp) {
            temp = set_new(pool, 1);
            set_add(temp, "", NULL);
        }
        m3 = set_members(temp);
    } else m3 = set_members(r3->nodes);

    bigrange = range_new(rr);

    for(i = 0; m1[i]; i++)
        for(j = 0; m2[j]; j++)
            for(k = 0; m3[k]; k++) {
                bundle = apr_pstrcat(pool,
                                    m1[i]->name, m2[j]->name,
                                     m3[k]->name, NULL);
                range_add(bigrange, bundle);
            }

    if (temp) set_destroy(temp);
    bigrange->quoted = r1->quoted || r2->quoted || r3->quoted;
    return bigrange;
}
Esempio n. 16
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;
}
Esempio n. 17
0
rangeparts *rangeparts_from_hostname(range_request* rr,
                                     const char* hostname)
{
    pcre* re;
    const char* error;
    rangeparts* rangeparts;
    int offset, count;
    int offsets[128];
    static pcre* regex_node = NULL;
    apr_pool_t* pool = range_request_pool(rr);
    
    if (!regex_node) 
        regex_node = pcre_compile(NODE_RE, 0, &error, &offset, NULL);

    re = regex_node;
    count = pcre_exec(re, NULL, hostname, strlen(hostname),
                      0, 0, offsets, sizeof(offsets)/sizeof(int));
    if (count > 0) {
        /*
         * 1 == prefix
         * 2 == range start
         * 3 == domain, maybe
         * 4 == range specifier: - or ..
         * 5 == range end
         * 6 == domain, maybe
         */
        rangeparts = rangeparts_new(pool);

        rangeparts->prefix = libcrange_get_pcre_substring(pool, hostname, offsets, 1);
        rangeparts->first = libcrange_get_pcre_substring(pool, hostname, offsets, 2);
        rangeparts->last =  libcrange_get_pcre_substring(pool, hostname, offsets, 5);
        
        if ((offsets[7] - offsets[6]) > 0) {
            /* if we have a domain */
            rangeparts->domain = libcrange_get_pcre_substring(pool, hostname, offsets, 3);
        } else if ((offsets[13] - offsets[12]) > 0) {
            rangeparts->domain = libcrange_get_pcre_substring(pool, hostname, offsets, 6);
        } else {
            rangeparts->domain = "";
        }
        /*
        if (hostname[offsets[8]] == '-') {
            range_request_warn_type(rr, "DEPRECATED_SYNTAX", hostname);
        }
        */
        
        return rangeparts;
    }

    return NULL;
}
Esempio n. 18
0
range * rangefunc_group(range_request* rr, range** r)
{
    sqlite3* db;
    db = _open_db(rr);
    range* ret = range_new(rr), *expanded;
    apr_pool_t* pool = range_request_pool(rr);
    const char** groups = range_get_hostnames(pool, r[0]);
    while (*groups) {
        expanded = _expand_cluster(rr, "GROUPS", *groups);
        range_union_inplace(rr, ret, expanded);
        ++groups;
    }
    return ret;
}
static range* _python_function(range_request* rr,
                     const char* funcname, const range** r)
{
  range* result = range_new(rr);
  PyObject * pLibcrangeCallFunc;
  PyObject * pNodesReturned;
  PyObject * pMain = PyImport_AddModule("__main__");
  // printf("rr: %p, funcname=%s, range**r = %p\n", rr, funcname, r);
  pLibcrangeCallFunc = PyObject_GetAttrString(pMain, "libcrange_call_func");
  
  if (pLibcrangeCallFunc && PyCallable_Check(pLibcrangeCallFunc)) {
    PyObject * pRangeFuncName;
    PyObject * item;
    pRangeFuncName = PyString_FromString(funcname);
    PyObject * pFuncArgs;
    PyObject * pTempArgList = PyList_New(0);
    PyList_Append(pTempArgList, pRangeFuncName);
    Py_DECREF(pRangeFuncName);
    
    // build our range** into python function args
    const range** p_r = r;
    while (*p_r) {
      item = range_to_py_array(range_request_pool(rr), *p_r);
      PyList_Append(pTempArgList, item);
      Py_DECREF(item);
      p_r++;
    }
    pFuncArgs = PyList_AsTuple(pTempArgList);
    Py_DECREF(pTempArgList);
    
    // call the function
    pNodesReturned = PyObject_CallObject(pLibcrangeCallFunc, pFuncArgs);
    Py_DECREF(pFuncArgs);
    PyObject *iterator = PyObject_GetIter(pNodesReturned);
    if (iterator == NULL) {
      printf("ERROR: python function %s ran, but didn't return an iteratable object", funcname);
      return result;
    }
    // an iteratable object was returned, transform it into result
    while (item = PyIter_Next(iterator)) {
      // PyObject_Print(item, stdout, 0 );
      range_add(result, PyString_AsString(item));
      Py_DECREF(item);
    }
    Py_DECREF(pNodesReturned);
  }

  return result;
}
Esempio n. 20
0
range* rangefunc_get_groups(range_request* rr, range** r)
{
    range* ret = range_new(rr);
    if (!validate_range_args(rr, r, 1)) {
        return ret;
    }
    range* n = r[0];
    apr_pool_t* pool = range_request_pool(rr);
    const char** in_nodes = range_get_hostnames(pool, n);

    set* node_group = set_new(pool, 40000);
    range* groups_r = _expand_cluster(rr, "GROUPS", "KEYS");
    const char** groups = range_get_hostnames(pool, groups_r);
    const char** p_group = groups;

    while (*p_group) {
        range* nodes_r = _expand_cluster(rr, "GROUPS", *p_group);
        const char** nodes = range_get_hostnames(pool, nodes_r);
        const char** p_nodes = nodes;

        while (*p_nodes) {
            apr_array_header_t* my_groups = set_get_data(node_group, *p_nodes);
            if (!my_groups) {
                my_groups = apr_array_make(pool, 4, sizeof(char*));
                set_add(node_group, *p_nodes, my_groups);
            }
            *(const char**)apr_array_push(my_groups) = *p_group;
            ++p_nodes;
        }
        ++p_group;
    }

    while (*in_nodes) {
        apr_array_header_t* my_groups = set_get_data(node_group, *in_nodes);
        if (!my_groups) 
            range_request_warn_type(rr, "NO_GROUPS", *in_nodes);
        else {
            int i;
            for (i=0; i<my_groups->nelts; ++i)
                range_add(ret, ((const char**)my_groups->elts)[i]);
        }
        in_nodes++;
    }

    return ret;
}
Esempio n. 21
0
range* rangefunc_group(range_request* rr, range** r)
{
    range* ret = range_new(rr);
    if (!validate_range_args(rr, r, 1)) {
        return ret;
    }
    apr_pool_t* pool = range_request_pool(rr);
    const char** groups = range_get_hostnames(pool, r[0]);

    while (*groups) {
        if (islower(*groups[0]))
            range_union_inplace(rr, ret, _expand_cluster(rr, "HOSTS", *groups));
        else
            range_union_inplace(rr, ret, _expand_cluster(rr, "GROUPS", *groups));
        ++groups;
    }
    return ret;
}
Esempio n. 22
0
range* rangefunc_cluster(range_request* rr, range** r)
{
    range* ret = range_new(rr);
    if (!validate_range_args(rr, r, 1)) {
        return ret;
    }
    apr_pool_t* pool = range_request_pool(rr);
    const char** clusters = range_get_hostnames(pool, r[0]);
    const char** p = clusters;

    while (*p) {
        const char* colon = strchr(*p, ':');
        range* r1;
        if (colon) {
            int len = strlen(*p);
            int cluster_len = colon - *p;
            int section_len = len - cluster_len - 1;

            char* cl = apr_palloc(pool, cluster_len + 1);
            char* sec = apr_palloc(pool, section_len + 1);

            memcpy(cl, *p, cluster_len);
            cl[cluster_len] = '\0';
            memcpy(sec, colon + 1, section_len);
            sec[section_len] = '\0';

            r1 = _expand_cluster(rr, cl, sec);
        }
        else 
            r1 = _expand_cluster(rr, *p, "CLUSTER");

        if (range_members(r1) > range_members(ret)) {
            /* swap them */
            range* tmp = r1;
            r1 = ret;
            ret = tmp;
        }
        range_union_inplace(rr, ret, r1);
        range_destroy(r1);
        ++p;
    }
    return ret;
}
Esempio n. 23
0
static set* _get_ignore_set(range_request* rr)
{
    char line[32768];
    apr_pool_t* pool = range_request_pool(rr);
    const char* ignore_path = apr_psprintf(pool, "%s/all/IGNORE", nodescf_path);
    set* ret = set_new(pool, 0);
    FILE* fp = fopen(ignore_path, "r");
    if (!fp) return ret;

    while (fgets(line, sizeof line, fp) != NULL) {
        int len;
        char* p;
        line[sizeof line - 1] = '\0';
        len = strlen(line);

        if (!len) continue;
        if (line[len - 1] == '\n')
            line[--len] = '\0';

        for (p = line; *p; ++p)
            if (*p == '#') {
                *p = '\0';
                len = strlen(line);
                break;
            }

        if (!len) continue;

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

        set_add(ret, line, 0);
    }
    fclose(fp);

    return ret;
}
Esempio n. 24
0
range* range_from_rangeparts(range_request* rr,
                             const rangeparts* parts)
{
    int i;
    int f, l, firstlength, lastlength, length;
    range* r;
    char* pad1 = "";
    char* first;
    char* last;
    char* tmpstr;
    apr_pool_t* pool = range_request_pool(rr);
    
    r = range_new(rr);

    firstlength = strlen(parts->first);
    lastlength = strlen(parts->last);
    first = parts->first;
    last = parts->last;

    if (firstlength > lastlength) {
        pad1 = apr_palloc(pool, firstlength - lastlength + 1);
        for(i=0; i < (firstlength - lastlength); i++)
            pad1[i] = parts->first[i];
        pad1[i] = '\0';
        first = parts->first + i;
    }

    f = atoi(first);
    l = atoi(last);

    length = firstlength > lastlength ? lastlength : firstlength;

    for(i=f; i<=l; i++) {
        tmpstr = apr_psprintf(pool, "%s%s%0*d%s",
                             parts->prefix, pad1, length, i, parts->domain);
        range_add(r, tmpstr);
    }

    return r;
}
Esempio n. 25
0
range* rangefunc_get_admin(range_request* rr, range** r)
{
    range* ret = range_new(rr);
    if (!validate_range_args(rr, r, 1)) {
        return ret;
    }
    range* n = r[0];
    apr_pool_t* pool = range_request_pool(rr);
    const char** in_nodes = range_get_hostnames(pool, n);

    set* node_admin = set_new(pool, 40000);
    range* admins_r = _expand_cluster(rr, "HOSTS", "KEYS");
    const char** admins = range_get_hostnames(pool, admins_r);
    const char** p_admin = admins;

    while (*p_admin) {
        range* nodes_r = _expand_cluster(rr, "HOSTS", *p_admin);
        const char** nodes = range_get_hostnames(pool, nodes_r);
        const char** p_nodes = nodes;

        while (*p_nodes) {
            set_add(node_admin, *p_nodes, (void*)*p_admin);
            ++p_nodes;
        }
        ++p_admin;
    }

    while (*in_nodes) {
        const char* admin = set_get_data(node_admin, *in_nodes);
        if (!admin) {
            range_request_warn_type(rr, "NO_ADMIN", *in_nodes);
        }
        else {
            range_add(ret, admin);
        }
        in_nodes++;
    }

    return ret;
}
Esempio n. 26
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;
}
Esempio n. 27
0
static vips* _parse_cluster_vips(range_request* rr, const char* cluster)
{
    struct stat st;
    int ovector[30];
    char line[32768];
    int line_no;
    FILE* fp;
    apr_pool_t* req_pool = range_request_pool(rr);
    apr_pool_t* lr_pool = range_request_lr_pool(rr);
    libcrange* lr = range_request_lr(rr);
    set* cache = libcrange_get_cache(lr, "nodescf:cluster_vips");
    const char* vips_path = apr_psprintf(req_pool, "%s/%s/vips.cf",
                                         nodescf_path, cluster);
    vips* v;
    
    if (!cache) {
        cache = set_new(lr_pool, 0);
        libcrange_set_cache(lr, "nodescf:cluster_vips", cache);
    }

    if (stat(vips_path, &st) == -1) {
        range_request_warn_type(rr, "NOVIPS", cluster);
        return _empty_vips(rr);
    }

    v = set_get_data(cache, vips_path);
    if (!v) {
        v = apr_palloc(lr_pool, sizeof(struct vips));
        apr_pool_create(&v->pool, lr_pool);
        v->vips = set_new(v->pool, 0);
        v->viphosts = set_new(v->pool, 0);
        v->mtime = st.st_mtime;
        set_add(cache, vips_path, v);
    }
    else {
        time_t cached_mtime = v->mtime;
        if (cached_mtime != st.st_mtime) {
            apr_pool_clear(v->pool);
            v->vips = set_new(v->pool, 0);
            v->viphosts = set_new(v->pool, 0);
            v->mtime = st.st_mtime;
        }
        else /* current cached copy is good */
            return v;
    }

    /* create / update the current cached copy */
    fp = fopen(vips_path, "r");
    if (!fp) {
        range_request_warn_type(rr, "NOVIPS", cluster);
        return _empty_vips(rr);
    }

    if (!vips_re) {
        const char* error;
        vips_re = pcre_compile("^(\\S+)\\s+(\\S+)\\s+(\\S+)\\s*$", 0, &error,
                               ovector, NULL);
        assert(vips_re);
    }

    line_no = 0;
    while (fgets(line, sizeof line, fp)) {
        int len;
        int count;
        char* p;

        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", vips_path, 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;

        /* 68.142.248.161 as301000 eth0:1 */
        count = pcre_exec(vips_re, NULL, line, len, 0, 0, ovector, 30);
        if (count == 4) {
            line[ovector[3]] = '\0';
            line[ovector[5]] = '\0';
            line[ovector[7]] = '\0';

            set_add(v->vips, &line[ovector[2]], 0);
            set_add(v->viphosts, &line[ovector[4]], 0);
        }
    }

    fclose(fp);
    return v;
}
Esempio n. 28
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;
}
Esempio n. 29
0
range* rangefunc_group(range_request* rr, range** r)
{
    range* ret;
    const char** members;
    int i, err;
    sqlite3* db;
    sqlite3_stmt* tag_stmt;
    sqlite3_stmt* all_nodes_stmt;
    apr_pool_t* pool = range_request_pool(rr);
    libcrange* lr = range_request_lr(rr);
    
    ret = range_new(rr);
    members = range_get_hostnames(pool, r[0]);

    if (!(db = libcrange_get_cache(lr, "sqlite:nodes"))) {
	const char* 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) {
	    fprintf(stderr, "%s: %s\n", sqlite_db_path, sqlite3_errmsg(db));
	    return ret;
	}

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


    /* prepare our selects */
    err = sqlite3_prepare(db, ALL_NODES_SQL, strlen(ALL_NODES_SQL),
                          &all_nodes_stmt, NULL);
    if (err != SQLITE_OK) {
        fprintf(stderr, "%s: %s\n", ALL_NODES_SQL, sqlite3_errmsg(db));
        abort();
    }

    err = sqlite3_prepare(db, RANGE_FROM_TAGS, strlen(RANGE_FROM_TAGS),
                          &tag_stmt, NULL);
    assert(err == SQLITE_OK);

    /* for each group */
    for (i = 0; members[i]; ++i) {
        sqlite3_stmt* stmt;
        if (strcmp(members[i], "ALL") == 0) {
            stmt = all_nodes_stmt;
        } else {
            stmt = tag_stmt;
            /* bind the current group name */
            sqlite3_bind_text(tag_stmt, 1, members[i], strlen(members[i]), SQLITE_STATIC);
        }

        while (sqlite3_step(stmt) == SQLITE_ROW) {
            range* this_group;
            const char* result = (const char*)sqlite3_column_text(stmt, 0);
            if (stmt == all_nodes_stmt) {
                range_add(ret, result);
            } else {
                this_group = do_range_expand(rr, result);
                set_union_inplace(ret->nodes, this_group->nodes);
            }
        }
        sqlite3_reset(stmt);
    }
    sqlite3_finalize(all_nodes_stmt);
    sqlite3_finalize(tag_stmt);

    return ret;
}
Esempio n. 30
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;
}