/* Clear registered documents in a node in a node manager object. */ int nmgr_clear(NMGR *nmgr, const char *name, int options){ NODE *node; CBMAP *admins, *users, *links; const char *vbuf; char *label; if(!(vbuf = cbmapget(nmgr->nodes, name, -1, NULL))) return FALSE; node = (NODE *)vbuf; label = cbmemdup(node->label, -1); admins = cbmapdup(node->admins); users = cbmapdup(node->users); links = cbmapdup(node->links); if(!nmgr_out(nmgr, name) || !nmgr_put(nmgr, name, TRUE, options)){ cbmapclose(links); cbmapclose(users); cbmapclose(admins); free(label); return FALSE; } if(!(vbuf = cbmapget(nmgr->nodes, name, -1, NULL))) return FALSE; node = (NODE *)vbuf; cbmapclose(node->links); cbmapclose(node->users); cbmapclose(node->admins); free(node->label); node->label = label; node->admins = admins; node->users = users; node->links = links; return TRUE; }
/* Remove a node from a node manager object. */ int nmgr_out(NMGR *nmgr, const char *name){ NODE *node; const char *vbuf; char pbuf[URIBUFSIZ]; int err, ecode; assert(nmgr && name); log_print(LL_DEBUG, "nmgr_out: %s", name); if(!(vbuf = cbmapget(nmgr->nodes, name, -1, NULL))) return FALSE; err = FALSE; node = (NODE *)vbuf; pthread_mutex_destroy(&(node->mutex)); cbmapclose(node->links); cbmapclose(node->users); cbmapclose(node->admins); free(node->label); free(node->name); if(!est_mtdb_close(node->db, &ecode)){ log_print(LL_ERROR, "DB-ERROR: %s", est_err_msg(ecode)); err = TRUE; } sprintf(pbuf, "%s%c%s%c%s", nmgr->rootdir, ESTPATHCHR, NODEDIR, ESTPATHCHR, name); if(!est_rmdir_rec(pbuf)){ log_print(LL_ERROR, "could not remove a directory"); err = TRUE; } cbmapout(nmgr->nodes, name, -1); return TRUE; }
/* Get the value of a session variable of a user object. */ char *user_sess_val(USER *user, const char *name){ const char *value; char *rv; assert(user && name); if(pthread_mutex_lock(&(user->mutex)) != 0) return NULL; value = user->sess ? cbmapget(user->sess, name, -1, NULL) : NULL; rv = value ? cbmemdup(value, -1) : NULL; pthread_mutex_unlock(&(user->mutex)); return rv; }
/* Add a result document data to a result map object. */ void resmap_put(RESMAP *resmap, int score, ESTDOC *doc, CBMAP *attrs, char *body){ RESDOC resdoc; const char *uri, *vbuf; assert(resmap); uri = NULL; if(doc) uri = est_doc_attr(doc, ESTDATTRURI); if(attrs) uri = cbmapget(attrs, ESTDATTRURI, -1, NULL); if(!uri || pthread_mutex_lock(&(resmap->mutex)) != 0){ if(doc) est_doc_delete(doc); if(attrs) cbmapclose(attrs); if(body) free(body); return; } if((vbuf = cbmapget(resmap->uris, uri, -1, NULL)) != NULL){ if(((RESDOC *)vbuf)->score >= score){ if(doc) est_doc_delete(doc); if(attrs) cbmapclose(attrs); if(body) free(body); } else { if(((RESDOC *)vbuf)->doc) est_doc_delete(((RESDOC *)vbuf)->doc); if(((RESDOC *)vbuf)->attrs) cbmapclose(((RESDOC *)vbuf)->attrs); if(((RESDOC *)vbuf)->body) free(((RESDOC *)vbuf)->body); resdoc.score = score; resdoc.doc = doc; resdoc.attrs = attrs; resdoc.body = body; resdoc.value = NULL; cbmapput(resmap->uris, uri, -1, (char *)&resdoc, sizeof(RESDOC), TRUE); } } else { resdoc.score = score; resdoc.doc = doc; resdoc.attrs = attrs; resdoc.body = body; cbmapput(resmap->uris, uri, -1, (char *)&resdoc, sizeof(RESDOC), FALSE); } pthread_mutex_unlock(&(resmap->mutex)); }
/* Remove a user from a user manager object. */ int umgr_out(UMGR *umgr, const char *name){ USER *user; const char *vbuf; assert(umgr && name); log_print(LL_DEBUG, "umgr_out: %s", name); if(!(vbuf = cbmapget(umgr->users, name, -1, NULL))) return FALSE; user = (USER *)vbuf; pthread_mutex_destroy(&(user->mutex)); if(user->sess) cbmapclose(user->sess); free(user->misc); free(user->fname); free(user->flags); free(user->passwd); free(user->name); cbmapout(umgr->users, name, -1); return TRUE; }
/** Converts a CBMAP of char * strings into a Ruby Hash of Strings. */ VALUE CBMAP_2_hash(CBMAP *map) { int key_size = 0; int val_size = 0; const char *map_key = NULL; const char *map_val = NULL; VALUE hash = rb_hash_new(); VALUE key; VALUE val; cbmapiterinit(map); while((map_key = cbmapiternext(map, &key_size)) != NULL) { map_val = cbmapget(map, map_key, key_size, &val_size); key = rb_str_new(map_key, key_size); val = rb_str_new(map_val, val_size); rb_hash_aset(hash, key, val); } return hash; }
/* Add a user to a user manager object. */ int umgr_put(UMGR *umgr, const char *name, const char *passwd, const char *flags, const char *fname, const char *misc){ USER user; assert(umgr && name && passwd && flags && fname && misc); log_print(LL_DEBUG, "umgr_put: %s:%s:%s:%s:%s", name, passwd, flags, fname, misc); if(name[0] == '\0' || cbmapget(umgr->users, name, -1, NULL)){ log_print(LL_WARN, "duplicated or empty user name: %s", name); return FALSE; } if(!check_alnum_name(name)){ log_print(LL_WARN, "invalid user name: %s", name); return FALSE; } user.name = cbmemdup(name, -1); user.passwd = cbmemdup(passwd, -1); user.flags = cbmemdup(flags, -1); user.fname = cbmemdup(fname, -1); user.misc = cbmemdup(misc, -1); user.atime = 0; user.sess = NULL; pthread_mutex_init(&(user.mutex), NULL); cbmapput(umgr->users, name, -1, (char *)&user, sizeof(USER), FALSE); return TRUE; }
/* Get a node object in a node manager object. */ NODE *nmgr_get(NMGR *nmgr, const char *name){ const char *vbuf; assert(nmgr && name); if(!(vbuf = cbmapget(nmgr->nodes, name, -1, NULL))) return NULL; return (NODE *)vbuf; }
/* Add a node to a node manager object. */ int nmgr_put(NMGR *nmgr, const char *name, int wmode, int options){ NODE node; ESTMTDB *db; CBLIST *list; const char *cbuf, *pv; char pbuf[URIBUFSIZ], *vbuf; int i, ecode, csiz; assert(nmgr && name); log_print(LL_DEBUG, "nmgr_put: %s", name); if(name[0] == '\0' || cbmapget(nmgr->nodes, name, -1, NULL)){ log_print(LL_WARN, "duplicated or empty node name: %s", name); return FALSE; } if(strlen(name) >= NODENAMEMAX || !check_alnum_name(name)){ log_print(LL_WARN, "invalid node name: %s", name); return FALSE; } log_print(LL_INFO, "opening a node (%s): %s", wmode ? "WRITER" : "READER", name); sprintf(pbuf, "%s%c%s%c%s", nmgr->rootdir, ESTPATHCHR, NODEDIR, ESTPATHCHR, name); if(!(db = est_mtdb_open(pbuf, wmode ? ESTDBWRITER | ESTDBCREAT | options : ESTDBREADER, &ecode))){ log_print(LL_ERROR, "DB-ERROR: %s", est_err_msg(ecode)); return FALSE; } est_mtdb_set_informer(db, db_informer, NULL); cbmapiterinit(nmgr->aidxs); while((cbuf = cbmapiternext(nmgr->aidxs, NULL)) != NULL){ est_mtdb_add_attr_index(db, cbuf, *(int *)cbmapiterval(cbuf, NULL)); } node.db = db; est_mtdb_add_meta(db, NMKNAME, name); node.name = cbmemdup(name, -1); vbuf = est_mtdb_meta(db, NMKLABEL); node.label = vbuf ? vbuf : cbmemdup(name, -1); if((vbuf = est_mtdb_meta(db, NMKADMINS)) != NULL){ list = cbsplit(vbuf, -1, "\n"); node.admins = cbmapopenex(cblistnum(list) + MINIBNUM); for(i = 0; i < cblistnum(list); i++){ cbuf = cblistval(list, i, &csiz); if(csiz < 1) continue; cbmapput(node.admins, cbuf, csiz, "", 0, FALSE); } cblistclose(list); free(vbuf); } else { node.admins = cbmapopenex(MINIBNUM); } if((vbuf = est_mtdb_meta(db, NMKUSERS)) != NULL){ list = cbsplit(vbuf, -1, "\n"); node.users = cbmapopenex(cblistnum(list) + MINIBNUM); for(i = 0; i < cblistnum(list); i++){ cbuf = cblistval(list, i, &csiz); if(csiz < 1) continue; cbmapput(node.users, cbuf, csiz, "", 0, FALSE); } cblistclose(list); free(vbuf); } else { node.users = cbmapopenex(MINIBNUM); } if((vbuf = est_mtdb_meta(db, NMKLINKS)) != NULL){ list = cbsplit(vbuf, -1, "\n"); node.links = cbmapopenex(cblistnum(list) + MINIBNUM); for(i = 0; i < cblistnum(list); i++){ cbuf = cblistval(list, i, NULL); if(!(pv = strchr(cbuf, '\t'))) continue; cbmapput(node.links, cbuf, pv - cbuf, pv + 1, -1, FALSE); } cblistclose(list); free(vbuf); } else { node.links = cbmapopenex(MINIBNUM); } node.mtime = time(NULL); node.dirty = FALSE; pthread_mutex_init(&(node.mutex), NULL); cbmapput(nmgr->nodes, name, -1, (char *)&node, sizeof(NODE), FALSE); return TRUE; }
/* Get a user object in a user manager object. */ USER *umgr_get(UMGR *umgr, const char *name){ const char *vbuf; assert(umgr && name); if(!(vbuf = cbmapget(umgr->users, name, -1, NULL))) return NULL; return (USER *)vbuf; }