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; }
range* range_from_function(range_request* rr, const char* funcname, const range** r) { range* returned_ret; range* passed_ret; range* (*f)(range_request*, const range**); const char* plugin_module; libcrange* lr = range_request_lr(rr); // is this a perl function? plugin_module = libcrange_get_perl_module(lr, funcname); if (plugin_module) { return perl_function(rr, funcname, r); } // or python? plugin_module = libcrange_get_python_module(lr, funcname); if (plugin_module) { returned_ret = python_function(rr, funcname, r, &passed_ret); return passed_ret; } // or C? f = libcrange_get_function(lr, funcname); if (!f) { range_request_warn_type(rr, "NO_FUNCTION", funcname); return range_new(rr); } return (*f)(rr, r); }
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); }
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; }
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; }
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; }