int db_put_str(void *dbh, char *keystr, char *valstr) { if (valstr) return db_put(dbh, keystr, valstr, strlen(valstr) + 1, 0); else return db_put(dbh, keystr, NULL, 0, 0); }
int SLNSessionCreateUserInternal(SLNSessionRef const session, DB_txn *const txn, strarg_t const username, strarg_t const password, SLNMode const mode_unsafe) { if(!session) return DB_EINVAL; if(!txn) return DB_EINVAL; if(!username) return DB_EINVAL; if(!password) return DB_EINVAL; size_t const ulen = strlen(username); size_t const plen = strlen(password); if(ulen < USER_MIN || ulen > USER_MAX) return DB_EINVAL; if(plen < PASS_MIN || plen > PASS_MAX) return DB_EINVAL; SLNMode const mode = mode_unsafe & session->mode; if(!mode) return DB_EINVAL; uint64_t const parent = session->userID; uint64_t const time = uv_now(async_loop); // TODO: Appropriate timestamp? uint64_t const userID = db_next_id(SLNUserByID, txn); if(!userID) return DB_EACCES; str_t *passhash = pass_hash(password); if(!passhash) return DB_ENOMEM; DB_val username_key[1], userID_val[1]; SLNUserIDByNameKeyPack(username_key, txn, username); SLNUserIDByNameValPack(userID_val, txn, userID); int rc = db_put(txn, username_key, userID_val, DB_NOOVERWRITE); if(rc < 0) return rc; DB_val userID_key[1], user_val[1]; SLNUserByIDKeyPack(userID_key, txn, userID); SLNUserByIDValPack(user_val, txn, username, passhash, NULL, mode, parent, time); rc = db_put(txn, userID_key, user_val, DB_NOOVERWRITE); if(rc < 0) return rc; return 0; }
int SLNSubmissionStore(SLNSubmissionRef const sub, DB_txn *const txn) { assert(sub); assert(txn); assert(!sub->tmppath); // Session permissions were already checked when the sub was created. int64_t fileID = db_next_id(SLNFileByID, txn); int rc; DB_val dupFileID_val[1]; SLNFileIDByInfoValPack(dupFileID_val, txn, fileID); DB_val fileInfo_key[1]; SLNFileIDByInfoKeyPack(fileInfo_key, txn, sub->internalHash, sub->type); rc = db_put(txn, fileInfo_key, dupFileID_val, DB_NOOVERWRITE); if(rc >= 0) { DB_val fileID_key[1]; SLNFileByIDKeyPack(fileID_key, txn, fileID); DB_val file_val[1]; SLNFileByIDValPack(file_val, txn, sub->internalHash, sub->type, sub->size); rc = db_put(txn, fileID_key, file_val, DB_NOOVERWRITE_FAST); if(rc < 0) return rc; } else if(DB_KEYEXIST == rc) { fileID = db_read_uint64(dupFileID_val); } else return rc; for(size_t i = 0; sub->URIs[i]; ++i) { strarg_t const URI = sub->URIs[i]; DB_val null = { 0, NULL }; DB_val fwd[1]; SLNFileIDAndURIKeyPack(fwd, txn, fileID, URI); rc = db_put(txn, fwd, &null, DB_NOOVERWRITE_FAST); if(rc < 0 && DB_KEYEXIST != rc) return rc; DB_val rev[1]; SLNURIAndFileIDKeyPack(rev, txn, URI, fileID); rc = db_put(txn, rev, &null, DB_NOOVERWRITE_FAST); if(rc < 0 && DB_KEYEXIST != rc) return rc; } rc = SLNSubmissionParseMetaFile(sub, fileID, txn, &sub->metaFileID); if(rc < 0) { alogf("Submission meta-file error: %s\n", sln_strerror(rc)); return rc; } return 0; }
int db_schema_verify(DB_txn *const txn) { char const magic[] = "DBDB schema layer v1"; size_t const len = sizeof(magic)-1; DB_val key[1]; DB_VAL_STORAGE(key, DB_VARINT_MAX*2); db_bind_uint64(key, DBSchema); db_bind_uint64(key, 0); DB_val val[1]; DB_cursor *cur; int rc = db_txn_cursor(txn, &cur); if(rc < 0) return rc; rc = db_cursor_first(cur, NULL, NULL, +1); if(rc < 0 && DB_NOTFOUND != rc) return rc; // If the database is completely empty // we can assume it's ours to play with if(DB_NOTFOUND == rc) { *val = (DB_val){ len, (char *)magic }; rc = db_put(txn, key, val, 0); if(rc < 0) return rc; return 0; } rc = db_get(txn, key, val); if(DB_NOTFOUND == rc) return DB_VERSION_MISMATCH; if(rc < 0) return rc; if(len != val->size) return DB_VERSION_MISMATCH; if(0 != memcmp(val->data, magic, len)) return DB_VERSION_MISMATCH; return 0; }
/** * Using a single call to db_put(), write multiple zeroed records out, * all with u_id field set to ID_FREE. * This will zap all records from "start" to the end of this entry. * * Returns: * 0 on success (from db_put()) * non-zero on failure */ int db_zapper(struct db_i *dbip, struct directory *dp, size_t start) { union record *rp; size_t i; size_t todo; int ret; RT_CK_DBI(dbip); RT_CK_DIR(dp); if (RT_G_DEBUG&DEBUG_DB) bu_log("db_zapper(%s) %p, %p, start=%zu\n", dp->d_namep, (void *)dbip, (void *)dp, start); if (dp->d_flags & RT_DIR_INMEM) bu_bomb("db_zapper() called on RT_DIR_INMEM object\n"); if (dbip->dbi_read_only) return -1; BU_ASSERT_LONG(dbip->dbi_version, ==, 4); if (dp->d_len < start) return -1; if ((todo = dp->d_len - start) == 0) return 0; /* OK -- trivial */ rp = (union record *)bu_malloc(todo * sizeof(union record), "db_zapper buf"); memset((char *)rp, 0, todo * sizeof(union record)); for (i=0; i < todo; i++) rp[i].u_id = ID_FREE; ret = db_put(dbip, dp, rp, (off_t)start, todo); bu_free((char *)rp, "db_zapper buf"); return ret; }
static int test_db_put(T *db) { int r = 0, i, ks, vs; char *kdata, *vdata; TEST_START() for (i = 0; i < l_kvcnt; i++) { kdata = MY_Malloc(l_ksize + 32); vdata = MY_Malloc(l_vsize + 32); sprintf(kdata, "%s-%d", kpattern, i); sprintf(vdata, "%s-%d", vpattern, i); ks = strlen(kdata); vs = strlen(vdata); if (dbver == 1) { #if 0 r = db_put(db, kdata, ks, vdata, vs); #endif } else { r = HIDB2(db_put)(db, kdata, ks, vdata, vs); } if (r != 0) return r; } TEST_FIN() return 0; }
int main(int argc, char* argv[]) { void *db_test = db_init("test.db", DB_OMOD_WR); CP_ID id_test = 123; char test_str[] = "if you see this, then the db works."; BOOL res; if (NULL == db_test) { fprintf(stderr, "cannot open test.db!\n"); return 0; } res = db_put(db_test, &id_test, CP_ID_SZ, test_str, strlen(test_str) + 1); if (0 == res) fprintf(stderr, "db_put() fails.\n"); else fprintf(stderr, "db_put() successful.\n"); if (db_test) db_release(db_test); return 0; }
static void add_metadata(DB_txn *const txn, uint64_t const metaFileID, strarg_t const field, strarg_t const value) { assert(field); assert(value); if('\0' == value[0]) return; DB_val null = { 0, NULL }; int rc; DB_val fwd[1]; SLNMetaFileIDFieldAndValueKeyPack(fwd, txn, metaFileID, field, value); rc = db_put(txn, fwd, &null, DB_NOOVERWRITE_FAST); assertf(rc >= 0 || DB_KEYEXIST == rc, "Database error %s", sln_strerror(rc)); DB_val rev[1]; SLNFieldValueAndMetaFileIDKeyPack(rev, txn, field, value, metaFileID); rc = db_put(txn, rev, &null, DB_NOOVERWRITE_FAST); assertf(rc >= 0 || DB_KEYEXIST == rc, "Database error %s", sln_strerror(rc)); }
/* Handy function for keeping track of counts or sizes. Reads the old * value and adds in the new value. */ int db_update_long(void *dbh, char *keystr, long update) { long cur; if (db_get(dbh, keystr, &cur, sizeof(cur)) > 0) update += cur; return db_put(dbh, keystr, &update, sizeof(update), 0); }
int logi_put (logbase_t * base, long long rec, logrec_t * data) { int rc; /* count CRC */ data->crc = count_crc(data, sizeof(logrec_t)-sizeof(int)); /* write attempt */ rc = db_put(base->fd, rec, data, sizeof(logrec_t)); if (rc < 0) return rc; /* return success */ return SUCCESS; }
struct db *db_open(const char *path_db, int flags, duc_errno *e) { struct db *db; int compress = 0; uint32_t mode = KCOREADER; if(flags & DUC_OPEN_RW) mode |= KCOWRITER | KCOCREATE; if(flags & DUC_OPEN_COMPRESS) compress = 1; db = duc_malloc(sizeof *db); db->kdb = kcdbnew(); db->kdb = kcdbnew(); if(!db->kdb) { *e = DUC_E_DB_BACKEND; goto err1; } char fname[DUC_PATH_MAX]; snprintf(fname, sizeof(fname), "%s.kct#opts=c", path_db); int r = kcdbopen(db->kdb, fname, mode); if(r == 0) { perror(kcecodename(kcdbecode(db->kdb))); *e = tcdb_to_errno(db->kdb); goto err2; } size_t vall; char *version = db_get(db, "duc_db_version", 14, &vall); if(version) { if(strcmp(version, DUC_DB_VERSION) != 0) { *e = DUC_E_DB_VERSION_MISMATCH; goto err3; } free(version); } else { db_put(db, "duc_db_version", 14, DUC_DB_VERSION, strlen(DUC_DB_VERSION)); } return db; err3: kcdbclose(db->kdb); err2: kcdbdel(db->kdb); err1: free(db); return NULL; }
static uint64_t add_metafile(DB_txn *const txn, uint64_t const fileID, strarg_t const targetURI) { uint64_t const metaFileID = fileID; uint64_t const latestMetaFileID = db_next_id(SLNMetaFileByID, txn); if(metaFileID < latestMetaFileID) return 0; // If it's not a new file, then it's not a new meta-file. // Note that ordinary files can't be "promoted" to meta-files later // because that would break the ordering. DB_val null = { 0, NULL }; DB_cursor *cursor = NULL; int rc = db_txn_cursor(txn, &cursor); assert(rc >= 0); DB_val metaFileID_key[1]; SLNMetaFileByIDKeyPack(metaFileID_key, txn, metaFileID); DB_val metaFile_val[1]; SLNMetaFileByIDValPack(metaFile_val, txn, fileID, targetURI); rc = db_put(txn, metaFileID_key, metaFile_val, DB_NOOVERWRITE_FAST); assert(rc >= 0); DB_range alts[1]; SLNTargetURIAndMetaFileIDRange1(alts, txn, targetURI); rc = db_cursor_firstr(cursor, alts, NULL, NULL, +1); assert(rc >= 0 || DB_NOTFOUND == rc); if(DB_NOTFOUND == rc) { DB_val unique[1]; SLNFirstUniqueMetaFileIDKeyPack(unique, txn, metaFileID); rc = db_put(txn, unique, &null, DB_NOOVERWRITE_FAST); assert(rc >= 0); } DB_val targetURI_key[1]; SLNTargetURIAndMetaFileIDKeyPack(targetURI_key, txn, targetURI, metaFileID); rc = db_put(txn, targetURI_key, &null, DB_NOOVERWRITE_FAST); assert(rc >= 0); return metaFileID; }
int SLNSessionAddMetaMap(SLNSessionRef const session, strarg_t const metaURI, strarg_t const targetURI) { uint64_t const sessionID = SLNSessionGetID(session); DB_env *db = NULL; DB_txn *txn = NULL; int rc = SLNSessionDBOpen(session, SLN_RDWR, &db); if(rc < 0) goto cleanup; rc = db_txn_begin(db, NULL, DB_RDWR, &txn); if(rc < 0) goto cleanup; uint64_t nextID = SLNNextMetaMapID(txn, sessionID); if(!nextID) rc = DB_EIO; if(rc < 0) goto cleanup; DB_val mainkey[1], mainval[1]; SLNSessionIDAndMetaMapIDToMetaURIAndTargetURIKeyPack(mainkey, txn, sessionID, nextID); SLNSessionIDAndMetaMapIDToMetaURIAndTargetURIValPack(mainval, txn, metaURI, targetURI); rc = db_put(txn, mainkey, mainval, DB_NOOVERWRITE_FAST); if(rc < 0) goto cleanup; DB_val fwdkey[1], fwdval[1]; SLNMetaURIAndSessionIDToMetaMapIDKeyPack(fwdkey, txn, metaURI, sessionID); SLNMetaURIAndSessionIDToMetaMapIDValPack(fwdval, txn, nextID); rc = db_put(txn, fwdkey, fwdval, DB_NOOVERWRITE_FAST); if(rc < 0) goto cleanup; DB_val revkey[1], revval[1]; SLNTargetURISessionIDAndMetaMapIDKeyPack(revkey, txn, targetURI, sessionID, nextID); db_nullval(revval); rc = db_put(txn, revkey, revval, DB_NOOVERWRITE_FAST); if(rc < 0) goto cleanup; rc = db_txn_commit(txn); txn = NULL; cleanup: db_txn_abort(txn); txn = NULL; SLNSessionDBClose(session, &db); return rc; }
int SLNSessionCreateSession(SLNSessionRef const session, SLNSessionRef *const out) { assert(out); if(!session) return DB_EACCES; SLNSessionCacheRef const cache = session->cache; uint64_t const userID = session->userID; SLNMode const mode = session->mode; strarg_t const username = session->username; DB_env *db = NULL; DB_txn *txn = NULL; SLNSessionRef alt = NULL; byte_t key_raw[SESSION_KEY_LEN]; int rc = async_random(key_raw, sizeof(key_raw)); if(rc < 0) goto cleanup; byte_t key_enc[SHA256_DIGEST_LENGTH]; SHA256(key_raw, sizeof(key_raw), key_enc); str_t key_str[SESSION_KEY_HEX+1]; tohex(key_str, key_enc, SESSION_KEY_LEN); key_str[SESSION_KEY_HEX] = '\0'; rc = SLNSessionDBOpen(session, SLN_RDWR, &db); // TODO: Custom permission? if(rc < 0) goto cleanup; rc = db_txn_begin(db, NULL, DB_RDWR, &txn); if(rc < 0) goto cleanup; uint64_t const sessionID = db_next_id(SLNSessionByID, txn); DB_val key[1], val[1]; SLNSessionByIDKeyPack(key, txn, sessionID); SLNSessionByIDValPack(val, txn, userID, key_str); rc = db_put(txn, key, val, DB_NOOVERWRITE_FAST); if(rc < 0) goto cleanup; rc = db_txn_commit(txn); txn = NULL; SLNSessionDBClose(session, &db); if(rc < 0) goto cleanup; rc = SLNSessionCreateInternal(cache, sessionID, key_raw, key_enc, userID, mode, username, &alt); if(rc < 0) goto cleanup; *out = alt; alt = NULL; cleanup: db_txn_abort(txn); txn = NULL; SLNSessionDBClose(session, &db); SLNSessionRelease(&alt); return rc; }
BOOL index_formula(void *db_formula, CP_ID id_new, char *frml, char *url, CP_NBRW n_brw) { int n_vals; BOOL res = 0; /* id_new must be new */ n_vals = db_num_values(db_formula, &id_new, CP_ID_SZ); if (n_vals != 0) CP_FATAL; /* put n_brw */ res = db_put(db_formula, &id_new, CP_ID_SZ, &n_brw, sizeof(CP_NBRW)); if (0 == res) { trace(INDEX, "DB put call failed.\n", NULL); return 0; } /* put formula string */ res = db_put(db_formula, &id_new, CP_ID_SZ, frml, strlen(frml) + 1); if (0 == res) { trace(INDEX, "DB put call failed.\n", NULL); return 0; } /* put URL string */ res = db_put(db_formula, &id_new, CP_ID_SZ, url, strlen(url) + 1); if (0 == res) { trace(INDEX, "DB put call failed.\n", NULL); return 0; } return 1; }
void db_bind_string_len(DB_val *const val, char const *const str, size_t const len, int const nulterm, DB_txn *const txn) { assert(val); assert(len == strnlen(str, len) && "Embedded nuls"); unsigned char *const out = val->data; if(0 == len) { out[val->size++] = '\0'; out[val->size++] = str ? 0x01 : 0x00; return; } if(len < DB_INLINE_MAX) { memcpy(out+val->size, str, len); val->size += len; out[val->size++] = '\0'; if(DB_INLINE_TRUNC != len+1) return; out[val->size++] = '\0'; return; } memcpy(out+val->size, str, DB_INLINE_TRUNC-1); val->size += DB_INLINE_TRUNC-1; out[val->size++] = '\0'; SHA256_CTX algo[1]; int rc; rc = SHA256_Init(algo); db_assert(rc >= 0); rc = SHA256_Update(algo, str, len); db_assert(rc >= 0); rc = SHA256_Final(out+val->size, algo); db_assert(rc >= 0); if(0x00 == out[val->size]) out[val->size] = 0x01; val->size += SHA256_DIGEST_LENGTH; if(!txn) return; unsigned flags = 0; rc = db_txn_get_flags(txn, &flags); db_assertf(rc >= 0, "Database error %s", db_strerror(rc)); if(flags & DB_RDONLY) return; DB_val key = { DB_INLINE_MAX, out+val->size-DB_INLINE_MAX }; char *str2 = nulterm ? (char *)str : strndup(str, len); DB_val full = { len+1, str2 }; assert('\0' == str2[full.size-1]); rc = db_put(txn, &key, &full, 0); if(!nulterm) free(str2); str2 = NULL; db_assertf(rc >= 0, "Database error %s", db_strerror(rc)); }
void db_archive_add(DBArchive *b) { IOSBuf *key, *data; assert(b); key = ios_new(); if(!b->archive_id) b->archive_id = db_get_next_index(kArchive); ios_append_int32(key, b->archive_id); data = ios_new(); ios_append(data, &(b->version), sizeof(b->version)); ios_append_int16(data, ios_buffer_size(b->ios)); ios_append_ios(data, b->ios); db_put(kArchive, key, data); ios_free(key); ios_free(data); return; }
BOOL index_textree(char *db_textree, CP_ID id_new) { BOOL res; FILE *dev; char str_textree[MAX_TEXTREE_STR]; dev = dev_bind(str_textree, MAX_TEXTREE_STR); tex_tr_print(parser_root, dev); fclose(dev); printf("tree:\n%s\n", str_textree); res = db_put(db_textree, &id_new, CP_ID_SZ, str_textree, strlen(str_textree) + 1); if (0 == res) { trace(INDEX, "DB put call failed.\n", NULL); } return res; }
/* * vt_api_set_db_value - * return: * impl(): * index(): * dbval(): */ static int vt_api_set_db_value (void *impl, int index, DB_VALUE * dbval) { OBJECT_RESULTSET *or = (OBJECT_RESULTSET *) impl; DB_ATTRIBUTE *attr; int res; assert (or != NULL); attr = or->attr_index[index]; assert (attr != NULL); res = db_put (or->obj, attr->header.name, dbval); if (res != NO_ERROR) { return ER_INTERFACE_GENERIC; } return NO_ERROR; }
BOOL index_webpage(char *db_webpage, char *url, CP_ID id_new) { unsigned char hash_url[SHA1_BYTES_LEN]; BOOL res; int n_vals; cp_sha1(url, strlen(url), hash_url); printf("URL sha-1 = %s \n", sha1_str(hash_url)); n_vals = db_num_values(db_webpage, hash_url, SHA1_BYTES_LEN); if (n_vals != 0) /* just let us know */ printf("same URL exists.\n"); /* index a reverse look-up from URL */ res = db_put(db_webpage, hash_url, SHA1_BYTES_LEN, &id_new, CP_ID_SZ); if (0 == res) trace(INDEX, "DB put call failed.\n", NULL); return res; }
/** * Used to create a database record and get it written out to a granule. * In some cases, storage will need to be allocated. */ void color_putrec(struct ged *gedp, struct mater *mp) { struct directory dir; union record rec; /* we get here only if database is NOT read-only */ rec.md.md_id = ID_MATERIAL; rec.md.md_low = mp->mt_low; rec.md.md_hi = mp->mt_high; rec.md.md_r = mp->mt_r; rec.md.md_g = mp->mt_g; rec.md.md_b = mp->mt_b; /* Fake up a directory entry for db_* routines */ RT_DIR_SET_NAMEP(&dir, "color_putrec"); dir.d_magic = RT_DIR_MAGIC; dir.d_flags = 0; if (mp->mt_daddr == MATER_NO_ADDR) { /* Need to allocate new database space */ if (db_alloc(gedp->ged_wdbp->dbip, &dir, 1)) { bu_vls_printf(gedp->ged_result_str, "Database alloc error, aborting"); return; } mp->mt_daddr = dir.d_addr; } else { dir.d_addr = mp->mt_daddr; dir.d_len = 1; } if (db_put(gedp->ged_wdbp->dbip, &dir, &rec, 0, 1)) { bu_vls_printf(gedp->ged_result_str, "Database write error, aborting"); return; } }
int SLNSessionSetSubmittedFile(SLNSessionRef const session, DB_txn *const txn, strarg_t const URI) { uint64_t const sessionID = SLNSessionGetID(session); DB_cursor *cursor = NULL; int rc = db_txn_cursor(txn, &cursor); if(rc < 0) return rc; DB_range range[1]; DB_val filekey[1]; SLNURIAndFileIDRange1(range, txn, URI); rc = db_cursor_firstr(cursor, range, filekey, NULL, +1); if(rc < 0) return rc; strarg_t u; uint64_t fileID; SLNURIAndFileIDKeyUnpack(filekey, txn, &u, &fileID); DB_val sessionkey[1], null[1]; SLNFileIDAndSessionIDKeyPack(sessionkey, txn, fileID, sessionID); db_nullval(null); rc = db_put(txn, sessionkey, null, 0); if(rc < 0) return rc; return rc; }
DBKey *db_key_add(const char *key_val) { IOSBuf *key; IOSBuf *data; DBKey *dbk; key = ios_new(); data = ios_new(); ios_set_buffer(key, key_val, strlen(key_val)); dbk = db_key_new(0); dbk->version = 0; dbk->key_id = db_get_next_index(kKeys); dbk->key = (char *)key_val; ios_append_int16(data, dbk->version); ios_append_string(data, dbk->key); db_put(kKeys, key, data); ios_free(key); ios_free(data); return dbk; }
/** * make a copy of a v4 solid by adding it to our book-keeping list, * adding it to the db directory, and writing it out to disk. */ static void copy_v4_solid(struct db_i *_dbip, struct directory *proto, struct clone_state *state, int idx) { struct directory *dp = (struct directory *)NULL; union record *rp = (union record *)NULL; size_t i, j; /* make n copies */ for (i = 0; i < state->n_copies; i++) { struct bu_vls *name; if (i==0) name = get_name(_dbip, proto, state, i); else { dp = db_lookup(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i-1]), LOOKUP_QUIET); if (!dp) { continue; } name = get_name(_dbip, dp, state, i); } /* XXX: this can probably be optimized. */ bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(name)); bu_vls_free(name); /* add the object to the directory */ dp = db_diradd(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i]), RT_DIR_PHONY_ADDR, proto->d_len, proto->d_flags, &proto->d_minor_type); if ((dp == RT_DIR_NULL) || (db_alloc(_dbip, dp, proto->d_len) < 0)) { TCL_ALLOC_ERR; return; } /* get an in-memory reference to the object being copied */ if ((rp = db_getmrec(_dbip, proto)) == (union record *)0) { TCL_READ_ERR; return; } if (rp->u_id == ID_SOLID) { bu_strlcpy(rp->s.s_name, dp->d_namep, NAMESIZE); /* mirror */ if (state->miraxis != W) { /* XXX er, this seems rather wrong .. but it's v4 so punt */ rp->s.s_values[state->miraxis] += 2 * (state->mirpos - rp->s.s_values[state->miraxis]); for (j = 3+state->miraxis; j < 24; j++) rp->s.s_values[j] = -rp->s.s_values[j]; } /* translate */ if (state->trans[W] > SMALL_FASTF) /* assumes primitive's first parameter is its position */ VADD2(rp->s.s_values, rp->s.s_values, state->trans); /* rotate */ if (state->rot[W] > SMALL_FASTF) { mat_t r; vect_t vec, ovec; if (state->rpnt[W] > SMALL_FASTF) VSUB2(rp->s.s_values, rp->s.s_values, state->rpnt); MAT_IDN(r); bn_mat_angles(r, state->rot[X], state->rot[Y], state->rot[Z]); for (j = 0; j < 24; j+=3) { VMOVE(vec, rp->s.s_values+j); MAT4X3VEC(ovec, r, vec); VMOVE(rp->s.s_values+j, ovec); } if (state->rpnt[W] > SMALL_FASTF) VADD2(rp->s.s_values, rp->s.s_values, state->rpnt); } } else bu_log("mods not available on %s\n", proto->d_namep); /* write the object to disk */ if (db_put(_dbip, dp, rp, 0, dp->d_len) < 0) { bu_log("ERROR: clone internal error writing to the database\n"); return; } } if (rp) bu_free((char *)rp, "copy_solid record[]"); return; }
static void process_list(DNODEPTR l_list) { DNODEPTR trav; char child_buf[MAXHOST+1] = {0}; char dns_buf[MAXHOST+1] = {0}; int i; int pid; int nof_children = 0; fd_set rd_set; struct sigaction sigChildAction; sigChildAction.sa_handler = sigChild; sigChildAction.sa_flags = SA_NOCLDSTOP|SA_RESTART; sigemptyset(&sigChildAction.sa_mask); raiseSigChild = 0; sigaction(SIGCHLD, &sigChildAction, NULL); /* fire up our child processes */ for(i=0; i < dns_children; i++) { if(pipe(child[i].inpipe)) { if (verbose) fprintf(stderr,"INPIPE creation error"); return; /* exit(1) */ } if(pipe(child[i].outpipe)) { if (verbose) fprintf(stderr,"OUTPIPE creation error"); return; /* exit(1); */ } /* fork it off */ switch(pid=fork()) { case -1: { if (verbose) fprintf(stderr,"FORK error"); return; /* exit(1); */ } case 0: /* Child */ { int size; struct hostent *res_ent; close(child[i].inpipe[0]); close(child[i].outpipe[1]); /* get struct in_addr here */ while((size = read(child[i].outpipe[0], child_buf, MAXHOST))) { if(size < 0) { perror("read error"); exit(1); } else { if(debug_mode) printf("Child got work: %lx(%d)\n", *((unsigned long *)child_buf), size); if((res_ent = gethostbyaddr(child_buf, size, AF_INET))) { /* must be at least 4 chars */ if (strlen(res_ent->h_name)>3) { if(debug_mode) printf("Child got %s for %lx(%d), %d bytes\n", res_ent->h_name, *((unsigned long *)child_buf), size,strlen(res_ent->h_name)); /* If long hostname, take max domain name part */ if ((size = strlen(res_ent->h_name)) > MAXHOST) strcpy(child_buf,(res_ent->h_name+(size-MAXHOST))); else strcpy(child_buf, res_ent->h_name); size = strlen(child_buf); } else { if (debug_mode) printf("gethostbyaddr returned bad h_name!\n"); } } else { if(debug_mode) printf("gethostbyaddr returned NULL! (%d)\n",h_errno); } if (write(child[i].inpipe[1], child_buf, size) == -1) { perror("write error"); exit(1); } } } close(child[i].inpipe[1]); close(child[i].outpipe[0]); if(debug_mode) printf( "Child %d got closed input, shutting down\n", i); fflush(stdout); exit(0); } /* case 0 */ default: { child[i].pid = pid; child[i].flags = DNS_CHILD_READY|DNS_CHILD_RUNNING; nof_children++; close(child[i].inpipe[1]); close(child[i].outpipe[0]); set_fl(child[i].inpipe[0], O_NONBLOCK); } } } trav = l_list; while(nof_children) { static struct timeval selectTimeval; int res; int max_fd; FD_ZERO(&rd_set); max_fd = 0; if(raiseSigChild) { int pid; while((pid = waitpid(-1, NULL, WNOHANG)) > 0) { for(i=0;i<dns_children;i++) { if(child[i].pid == pid) { child[i].pid = 0; child[i].flags &= ~(DNS_CHILD_READY|DNS_CHILD_RUNNING); nof_children--; if(debug_mode) printf("Reaped Child %d\n", pid); break; } } } raiseSigChild--; continue; /* while, nof children has just changed */ } for(i=0;i<dns_children;i++) { if(child[i].flags & DNS_CHILD_RUNNING) /* Child is running */ { if(child[i].flags & DNS_CHILD_READY) { child[i].flags &= ~DNS_CHILD_READY; if(trav) /* something to resolve */ { if (write(child[i].outpipe[1], &(trav->addr.s_addr), sizeof(trav->addr.s_addr)) != -1) { /* We will watch this child */ child[i].cur = trav; FD_SET(child[i].inpipe[0], &rd_set); max_fd = MAX(max_fd, child[i].inpipe[0]); if(debug_mode) printf("Giving %s (%lx) to Child %d for resolving\n", child[i].cur->string, (unsigned long)child[i].cur->addr.s_addr, i); trav = trav->llist; } else /* write error */ { if(errno != EINTR) /* Could be a signal */ { perror("Could not write to pipe"); close(child[i].outpipe[1]); /* kill */ child[i].flags &= ~DNS_CHILD_RUNNING; /* child */ } } } else /* List is complete */ { close(child[i].outpipe[1]); /* Go away */ child[i].flags &= ~DNS_CHILD_RUNNING; /* Child is dead */ } } else { /* Look, the busy child... */ FD_SET(child[i].inpipe[0], &rd_set); max_fd = MAX(max_fd, child[i].inpipe[0]); } } } selectTimeval.tv_sec = 5; /* This stuff ticks in 5 second intervals */ selectTimeval.tv_usec = 0; switch(res = select(max_fd+1, &rd_set, NULL, NULL, &selectTimeval)) { case -1: { if(errno != EINTR) /* Could be a signal */ perror("Error in select"); break; } case 0: /* Timeout, just fall once through the child loop */ { if(debug_mode) printf("tick\n"); break; } default: { for(i=0; i< dns_children;i++) { if(!res) /* All file descriptors done */ break; if(FD_ISSET(child[i].inpipe[0], &rd_set)) { int size; res--; /* One less... */ if(debug_mode) printf("Work requested from Child %d\n", i); switch (size=read(child[i].inpipe[0], dns_buf, MAXHOST)) { case -1: { if(errno != EINTR) perror("Could not read from pipe"); break; } case 0: { /* EOF. Child has closed Pipe. It shouldn't have */ /* done that, could be an error or something. */ /* Reap it */ close(child[i].outpipe[1]); child[i].flags &= ~DNS_CHILD_RUNNING; if(debug_mode) printf("Child %d wants to be reaped\n", i); break; } default: { dns_buf[size] = '\0'; if(memcmp(dns_buf, &(child[i].cur->addr.s_addr), sizeof(child[i].cur->addr.s_addr))) { if(debug_mode) printf("Got a result (%d): %s -> %s\n", i, child[i].cur->string, dns_buf); db_put(child[i].cur->string, dns_buf, 0); } else { if(debug_mode) printf("Could not resolve (%d): %s\n", i, child[i].cur->string); /* db_put(child[i].cur->string,child[i].cur->string,1); */ } if(debug_mode) printf("Child %d back in task pool\n", i); /* Child is back in the task pool */ child[i].flags |= DNS_CHILD_READY; break; } } } } break; } } } return; }
int handle(const int fd, db_t *db, sbuf_t *in, sbuf_t *out) { ssize_t err; ssize_t len; char *key; uint32_t klen; uint32_t vlen; int argc; int arglen; char argv[ARGC_MAX][ARGV_MAX]; if ((err = sbuf_recv(fd, in, &len)) <= 0 && len == 0) { if (err == -1) { fprintf(stdout, "db-server: socket %d recv %s\n", fd, strerror(errno)); } return HANDLE_CLOSE; } arglen = argparse(in->buf, in->len, &argc, argv, ARGC_MAX); if (argc < 1 || arglen == -1) { fprintf(stderr, "db-server: socket %d malformed request\n", fd); return HANDLE_CLOSE; } if (strcmp(argv[0], "set") == 0 && argc >= 5) { key = argv[1]; klen = strlen(key); vlen = atoi(argv[4]); if (vlen + arglen > in->max) { fprintf(stderr, "db-server: socket %d too large value\n", fd); return HANDLE_CLOSE; } if (vlen + arglen > in->len) { return HANDLE_NEEDMOREIN; } if (db_put(db, key, klen, in->buf + arglen, vlen) == DB_OK) { out->len = sprintf(out->buf, "STORED\r\n"); } else { out->len = sprintf(out->buf, "ERROR\r\n"); } } else if (strcmp(argv[0], "get") == 0 && argc >= 2) { key = argv[1]; klen = strlen(key); if ((vlen = db_get(db, key, klen, valbuf, VALBUF_LEN)) != 0) { if (vlen > VALBUF_LEN) return HANDLE_CLOSE; out->len = snprintf(out->buf, out->max, "VALUE %.*s %d %d\r\n%.*s\r\nEND\r\n", klen, key, 0, vlen, vlen, valbuf); } else { out->len = sprintf(out->buf, "END\r\n"); } } else if (strcmp(argv[0], "delete") == 0 && argc >= 2) { key = argv[1]; klen = strlen(key); if ((db_del(db, key, klen)) != 0) { out->len = snprintf(out->buf, out->max, "DELETED\r\n"); } else { out->len = snprintf(out->buf, out->max, "NOT_FOUND\r\n"); } } else { return HANDLE_CLOSE; } if ((err = sbuf_send(fd, out, &len)) <= 0 && len == 0) { if (err == -1) { fprintf(stdout, "db-server: socket %d send %s\n", fd, strerror(errno)); } return HANDLE_CLOSE; } if (out->off < out->len) { return HANDLE_NEEDMOREOUT; } return HANDLE_FINISH; }
/** * make n copies of a v4 combination. */ static struct directory * copy_v4_comb(struct db_i *_dbip, struct directory *proto, struct clone_state *state, int idx) { struct directory *dp = (struct directory *)NULL; union record *rp = (union record *)NULL; size_t i; size_t j; /* make n copies */ for (i = 0; i < state->n_copies; i++) { /* get a v4 in-memory reference to the object being copied */ if ((rp = db_getmrec(_dbip, proto)) == (union record *)0) { TCL_READ_ERR; return NULL; } if (proto->d_flags & RT_DIR_REGION) { if (!is_in_list(obj_list, rp[1].M.m_instname)) { bu_log("ERROR: clone internal error looking up %s\n", rp[1].M.m_instname); return NULL; } bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(&obj_list.names[index_in_list(obj_list, rp[1].M.m_instname)].dest[i])); /* bleh, odd convention going on here.. prefix regions with an 'r' */ *bu_vls_addr(&obj_list.names[idx].dest[i]) = 'r'; } else { struct bu_vls *name; if (i==0) name = get_name(_dbip, proto, state, i); else { dp = db_lookup(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i-1]), LOOKUP_QUIET); if (!dp) { continue; } name = get_name(_dbip, dp, state, i); } bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(name)); bu_vls_free(name); } bu_strlcpy(rp[0].c.c_name, bu_vls_addr(&obj_list.names[idx].dest[i]), NAMESIZE); /* add the object to the directory */ dp = db_diradd(_dbip, rp->c.c_name, RT_DIR_PHONY_ADDR, proto->d_len, proto->d_flags, &proto->d_minor_type); if ((dp == NULL) || (db_alloc(_dbip, dp, proto->d_len) < 0)) { TCL_ALLOC_ERR; return NULL; } for (j = 1; j < proto->d_len; j++) { if (!is_in_list(obj_list, rp[j].M.m_instname)) { bu_log("ERROR: clone internal error looking up %s\n", rp[j].M.m_instname); return NULL; } snprintf(rp[j].M.m_instname, NAMESIZE, "%s", bu_vls_addr(&obj_list.names[index_in_list(obj_list, rp[j].M.m_instname)].dest[i])); } /* write the object to disk */ if (db_put(_dbip, dp, rp, 0, dp->d_len) < 0) { bu_log("ERROR: clone internal error writing to the database\n"); return NULL; } /* our responsibility to free the record */ bu_free((char *)rp, "deallocate copy_v4_comb() db_getmrec() record"); } return dp; }