/* * Save the in-memory database mdb to the disk database dbname. * Return 0 if OK, -1 on error. */ int db_copy_out(DB *mdb, const char *dbname, const char *uname, BTREEINFO *bti) { DB *ddb; DBT key, data; int error, rv, version; if ((ddb = dbopen(dbname, O_RDWR|O_CREAT|O_TRUNC, 0644, DB_BTREE, bti)) == NULL) { warn("creating %s summary", uname); return (-1); } error = 0; for (rv = DB_SEQ(mdb, &key, &data, R_FIRST); rv == 0; rv = DB_SEQ(mdb, &key, &data, R_NEXT)) { if ((rv = DB_PUT(ddb, &key, &data, 0)) < 0) { warn("saving %s summary", uname); error = -1; goto out; } } if (rv < 0) { warn("retrieving %s stats", uname); error = -1; } out: /* Add a version record. */ key.data = (void*)&VERSION_KEY; key.size = sizeof(VERSION_KEY); version = 2; data.data = &version; data.size = sizeof(version); if ((rv = DB_PUT(ddb, &key, &data, 0)) < 0) { warn("add version record to %s stats", uname); error = -1; } else if (rv == 1) { warnx("duplicate version record in %s stats", uname); error = -1; } if (DB_SYNC(ddb, 0) < 0) { warn("syncing %s summary", uname); error = -1; } if (DB_CLOSE(ddb) < 0) { warn("closing %s summary", uname); error = -1; } return error; }
int usracct_update(void) { DB *saved_usracct_db; DBT key, data; BTREEINFO bti; int error, serr, nerr; memset(&bti, 0, sizeof(bti)); bti.compare = uid_compare; saved_usracct_db = dbopen(_PATH_USRACCT, O_RDWR|O_CREAT|O_TRUNC, 0644, DB_BTREE, &bti); if (saved_usracct_db == NULL) { warn("creating user accounting summary"); return (-1); } error = 0; serr = DB_SEQ(usracct_db, &key, &data, R_FIRST); if (serr < 0) { warn("retrieving user accounting stats"); error = -1; } while (serr == 0) { nerr = DB_PUT(saved_usracct_db, &key, &data, 0); if (nerr < 0) { warn("saving user accounting summary"); error = -1; break; } serr = DB_SEQ(usracct_db, &key, &data, R_NEXT); if (serr < 0) { warn("retrieving user accounting stats"); error = -1; break; } } if (DB_SYNC(saved_usracct_db, 0) < 0) { warn("syncing process accounting summary"); error = -1; } if (DB_CLOSE(saved_usracct_db) < 0) { warn("closing process accounting summary"); error = -1; } return error; }
/* * Create the in-memory database, *mdb. * If iflag is not set, fill-in mdb with the records of the disk-based * database dbname. * Upgrade old-version records by calling v1_to_v2. * Return 0 if OK, -1 on error. */ int db_copy_in(DB **mdb, const char *dbname, const char *uname, BTREEINFO *bti, int (*v1_to_v2)(DBT *key, DBT *data)) { DBT key, data; DB *ddb; int error, rv, version; if ((*mdb = dbopen(NULL, O_RDWR, 0, DB_BTREE, bti)) == NULL) return (-1); if (iflag) return (0); if ((ddb = dbopen(dbname, O_RDONLY, 0, DB_BTREE, bti)) == NULL) { if (errno == ENOENT) return (0); warn("retrieving %s summary", uname); db_destroy(*mdb, uname); return (-1); } error = 0; /* Obtain/set version. */ version = 1; key.data = (void*)&VERSION_KEY; key.size = sizeof(VERSION_KEY); rv = DB_GET(ddb, &key, &data, 0); if (rv < 0) { warn("get version key from %s stats", uname); error = -1; goto closeout; } else if (rv == 0) { /* It's there; verify version. */ if (data.size != sizeof(version)) { warnx("invalid version size %zd in %s", data.size, uname); error = -1; goto closeout; } memcpy(&version, data.data, data.size); if (version != 2) { warnx("unsupported version %d in %s", version, uname); error = -1; goto closeout; } } for (rv = DB_SEQ(ddb, &key, &data, R_FIRST); rv == 0; rv = DB_SEQ(ddb, &key, &data, R_NEXT)) { /* See if this is a version record. */ if (key.size == sizeof(VERSION_KEY) && memcmp(key.data, VERSION_KEY, sizeof(VERSION_KEY)) == 0) continue; /* Convert record from v1, if needed. */ if (version == 1 && v1_to_v2(&key, &data) < 0) { warn("converting %s stats", uname); error = -1; goto closeout; } /* Copy record to the in-memory database. */ if ((rv = DB_PUT(*mdb, &key, &data, 0)) < 0) { warn("initializing %s stats", uname); error = -1; goto closeout; } } if (rv < 0) { warn("retrieving %s summary", uname); error = -1; } closeout: if (DB_CLOSE(ddb) < 0) { warn("closing %s summary", uname); error = -1; } if (error) db_destroy(*mdb, uname); return (error); }
void db_destroy(DB *db, const char *uname) { if (DB_CLOSE(db) < 0) warn("destroying %s stats", uname); }
int main(int argc, char* argv[]) { // Parse the command line. if (argc != 3) usage(argv[0]); std::string outputFile = argv[2]; // Open the input file. std::cout << "Processing: " << argv[1] << std::endl; std::ifstream file(argv[1], std::ios_base::in | std::ios_base::binary); if (! file) { std::cerr << "ERROR: Could not open input file: " << argv[1] << std::endl; std::exit(1); } ::boost::iostreams::filtering_istream in; if (file.peek() == 0x1f) in.push(::boost::iostreams::gzip_decompressor()); in.push(file); // Initialise the database. #ifdef QDBM_AS_TOKYOCABINET VILLA* db; if (! (db = vlopen(outputFile.c_str(), VL_OWRITER | VL_OCREAT | VL_OTRUNC | VL_OZCOMP, VL_CMPLEX))) { std::cerr << "ERROR: Could not open QDBM database: " << outputFile << std::endl; std::exit(1); } #else TCBDB* db = tcbdbnew(); if (! tcbdbopen(db, outputFile.c_str(), BDBOWRITER | BDBOCREAT | BDBOTRUNC)) { std::cerr << "ERROR: Could not open Tokyo Cabinet database: " << outputFile << std::endl; std::exit(1); } #endif // Fill the database with the user-supplied key-value pairs. std::string sig, name; const char* pos; unsigned long tot = 0; while (true) { in >> sig; if (in.eof()) break; std::getline(in, name); if (in.eof()) { std::cerr << "ERROR: Signature " << sig << " is missing a corresponding name.\n\n"; DB_CLOSE(db); usage(argv[0]); } // Skip initial whitespace in the manifold name (which will // always be present, since the previous in >> sig // does not eat the separating whitespace). pos = name.c_str(); while (*pos && std::isspace(*pos)) ++pos; if (! *pos) { std::cerr << "ERROR: Signature " << sig << " has an empty name.\n\n"; DB_CLOSE(db); usage(argv[0]); } #ifdef QDBM_AS_TOKYOCABINET if (! vlput(db, sig.c_str(), sig.length(), pos, -1 /* strlen */, VL_DDUP)) { #else if (! tcbdbputdup2(db, sig.c_str(), pos)) { #endif std::cerr << "ERROR: Could not store the record for " << sig << " in the database." << std::endl; DB_CLOSE(db); std::exit(1); } ++tot; } // Close and tidy up. #ifdef QDBM_AS_TOKYOCABINET if (! vloptimize(db)) { std::cerr << "ERROR: Could not optimise QDBM database: " << outputFile << std::endl; DB_CLOSE(db); std::exit(1); } if (! vlclose(db)) { std::cerr << "ERROR: Could not close QDBM database: " << outputFile << std::endl; std::exit(1); } #else // The following call to tcbdboptimise() does not change any options // other than the bitwise compression option given in the final argument. if (! tcbdboptimize(db, 0, 0, 0, -1, -1, BDBTBZIP)) { std::cerr << "ERROR: Could not optimise Tokyo Cabinet database: " << outputFile << std::endl; std::cerr << "Tokyo cabinet error: " << tcerrmsg(tcbdbecode(db)) << std::endl; DB_CLOSE(db); std::exit(1); } if (! tcbdbclose(db)) { std::cerr << "ERROR: Could not close Tokyo Cabinet database: " << outputFile << std::endl; tcbdbdel(db); std::exit(1); } tcbdbdel(db); #endif std::cout << "Success: " << tot << " records." << std::endl; return 0; }
int usracct_init(void) { DB *saved_usracct_db; BTREEINFO bti; int error; int ndups = 0; memset(&bti, 0, sizeof(bti)); bti.compare = uid_compare; usracct_db = dbopen(NULL, O_RDWR|O_CREAT|O_TRUNC, 0644, DB_BTREE, &bti); if (usracct_db == NULL) return (-1); error = 0; if (!iflag) { DBT key, data; int serr, nerr; saved_usracct_db = dbopen(_PATH_USRACCT, O_RDONLY, 0, DB_BTREE, &bti); if (saved_usracct_db == NULL) { error = (errno == ENOENT) ? 0 : -1; if (error) warn("retrieving user accounting summary"); goto out; } serr = DB_SEQ(saved_usracct_db, &key, &data, R_FIRST); if (serr < 0) { warn("retrieving user accounting summary"); error = -1; goto closeout; } while (serr == 0) { nerr = DB_PUT(usracct_db, &key, &data, R_NOOVERWRITE); if (nerr < 0) { warn("initializing user accounting stats"); error = -1; break; } if (nerr == 1) { warnx("duplicate key in `%s': %s", _PATH_USRACCT, fmt(&key)); if (ndups++ == 5) { warnx("too many duplicate keys;" " `%s' possibly corrupted.", _PATH_USRACCT); error = -1; break; } } serr = DB_SEQ(saved_usracct_db, &key, &data, R_NEXT); if (serr < 0) { warn("retrieving user accounting summary"); error = -1; break; } } closeout: if (DB_CLOSE(saved_usracct_db) < 0) { warn("closing user accounting summary"); error = -1; } } out: if (error != 0) usracct_destroy(); return (error); }
void usracct_destroy(void) { if (DB_CLOSE(usracct_db) < 0) warn("destroying user accounting stats"); }