size_t getstringlistfield(lua_State *L, int table, const char *fieldname, std::vector<std::string> *result) { lua_getfield(L, table, fieldname); size_t num_strings_read = read_stringlist(L, -1, result); lua_pop(L, 1); return num_strings_read; }
bool read_stringset(SerialIn &in, StringSet &list) { #if 1 StringList lst; if (!read_stringlist(in, lst)) return false; list.~StringSet(); new (&list) StringSet(lst.begin(), lst.end()); #else // "HINTS"... yeah right :P uint32_t len; in >= len; StringSet::iterator hint = list.end(); for (uint32_t i = 0; i != len; ++i) { string str; in >= str; hint = list.emplace_hint(hint, move(str)); } #endif return in.in_; }
static bool db_load(DB *db, const string& filename) { bool gzip = ends_with_gz(filename); uniq<SerialIn> sin(SerialIn::Open(db, filename, gzip)); if (gzip) db->config_.Log(Message, "reading compressed database\n"); else db->config_.Log(Message, "reading database\n"); SerialIn &in(*sin); if (!sin || !in.in_) { //log(Error, "failed to open file %s for reading\n", filename.c_str()); return true; // might not exist... } Header hdr; in >= hdr; if (memcmp(hdr.magic, depdb_magic, sizeof(hdr.magic)) != 0) { db->config_.Log(Error, "not a valid database file: %s\n", filename.c_str()); return false; } in.version_ = hdr.version; db->loaded_version_ = hdr.version; // supported versions: if (hdr.version > DB::CURRENT) { db->config_.Log(Error, "cannot read depdb version %u files, (known up to %u)\n", (unsigned)hdr.version, (unsigned)DB::CURRENT); return false; } if (hdr.version >= 8) in.ver8_refs_ = true; if (hdr.version >= 3) db->contains_package_depends_ = true; if (hdr.version >= 5) db->contains_groups_ = true; if (hdr.flags & DBFlags::FileLists) db->contains_filelists_ = true; if (hdr.version >= 10) db->contains_make_depends_ = true; if (hdr.version >= 12) db->contains_check_depends_ = true; if (hdr.version >= 13) db->contains_pkgbase_ = true; in >= db->name_; if (!read_stringlist(in, db->library_path_)) { db->config_.Log(Error, "failed reading library paths\n"); return false; } uint32_t len; in >= len; db->packages_.resize(len); for (uint32_t i = 0; i != len; ++i) { if (!read_pkg(in, db->packages_[i], hdr.version, hdr.flags, db->config_)) { db->config_.Log(Error, "failed reading packages\n"); return false; } } if (!read_objlist(in, db->objects_, db->config_)) { db->config_.Log(Error, "failed reading object list\n"); return false; } in >= len; rptr<Elf> obj; for (uint32_t i = 0; i != len; ++i) { if (!read_obj(in, obj, db->config_) || !read_objset(in, obj->req_found_, db->config_)) { db->config_.Log(Error, "failed reading map of found dependencies\n"); return false; } } in >= len; for (uint32_t i = 0; i != len; ++i) { if (!read_obj(in, obj, db->config_) || !read_stringset(in, obj->req_missing_)) { db->config_.Log(Error, "failed reading map of missing dependencies\n"); return false; } } if (hdr.version < 2) return true; if (hdr.flags & DBFlags::IgnoreRules) { if (!read_stringset(in, db->ignore_file_rules_)) return false; } if (hdr.flags & DBFlags::AssumeFound) { if (!read_stringset(in, db->assume_found_rules_)) return false; } if (hdr.flags & DBFlags::PackageLDPath) { in >= len; for (uint32_t i = 0; i != len; ++i) { string pkg; in >= pkg; if (!read_stringlist(in, db->package_library_path_[pkg])) return false; } } if (hdr.flags & DBFlags::BasePackages) { if (!read_stringset(in, db->base_packages_)) return false; } return true; }
static bool read_pkg(SerialIn &in, Package *&pkg, unsigned hdrver, HdrFlags flags, const Config& config) { ObjRef r; in >= r; size_t ref; if (r == ObjRef::PKGREF) { in >= ref; if (in.ver8_refs_) { if (ref >= in.pkgref_.size()) { config.Log(Error, "db error: pkgref out of range [%zu/%zu]\n", ref, in.pkgref_.size()); return false; } pkg = in.pkgref_[ref]; } else { auto existing = in.old_pkgref_.find(ref); if (existing == in.old_pkgref_.end()) { config.Log(Error, "db error: failed to find deserialized package\n"); return false; } pkg = existing->second; } return true; } if (r != ObjRef::PKG) { config.Log(Error, "package expected, object-ref value: %u\n", (unsigned)r); return false; } // Remember the one we're constructing now: pkg = new Package; if (in.ver8_refs_) in.pkgref_.push_back(pkg); else { ref = in.in_.TellG(); in.old_pkgref_[ref] = pkg; } // Now serialize the actual package data: in >= pkg->name_ >= pkg->version_; if (hdrver >= 13) in >= pkg->pkgbase_; if (!read_objlist(in, pkg->objects_, config)) return false; for (auto &o : pkg->objects_) o->owner_ = pkg; if (hdrver >= 10) { if (!read_dependlist(in, pkg->depends_) || !read_dependlist(in, pkg->makedepends_) || (hdrver >= 12 && !read_dependlist(in, pkg->checkdepends_)) || !read_dependlist(in, pkg->optdepends_) || !read_dependlist(in, pkg->provides_) || !read_dependlist(in, pkg->conflicts_) || !read_dependlist(in, pkg->replaces_)) { return false; } } else if (hdrver >= 3) { if (!read_olddependlist(in, pkg->depends_) || !read_olddependlist(in, pkg->optdepends_)) { return false; } if (hdrver >= 4) { if (!read_olddependlist(in, pkg->provides_) || !read_olddependlist(in, pkg->conflicts_) || !read_olddependlist(in, pkg->replaces_)) { return false; } } } if (hdrver >= 5 && !read_stringset(in, pkg->groups_)) return false; if (flags & DBFlags::FileLists && !read_stringlist(in, pkg->filelist_)) return false; return true; }
static bool read_obj(SerialIn &in, rptr<Elf> &obj, const Config& config) { ObjRef r; in >= r; size_t ref; if (r == ObjRef::OBJREF) { in >= ref; if (in.ver8_refs_) { if (ref >= in.objref_.size()) { config.Log(Error, "db error: objref out of range [%zu/%zu]\n", ref, in.objref_.size()); return false; } obj = in.objref_[ref]; } else { auto existing = in.old_objref_.find(ref); if (existing == in.old_objref_.end()) { config.Log(Error, "db error: failed to find deserialized object\n"); return false; } obj = existing->second; } return true; } if (r != ObjRef::OBJ) { config.Log(Error, "object expected, object-ref value: %u\n", (unsigned)r); return false; } // Remember the one we're constructing now: obj = new Elf; if (in.ver8_refs_) in.objref_.push_back(obj.get()); else { ref = in.in_.TellG(); in.old_objref_[ref] = obj.get(); } // Read out the object data // Serialize the actual object data uint8_t rpset, runpset, interpset = 0; in >= obj->dirname_ >= obj->basename_ >= obj->ei_class_ >= obj->ei_data_ >= obj->ei_osabi_ >= rpset >= runpset >= obj->rpath_ >= obj->runpath_; if (in.version_ >= 9) in >= interpset >= obj->interpreter_; obj->rpath_set_ = rpset; obj->runpath_set_ = runpset; obj->interpreter_set_ = interpset; if (!read_stringlist(in, obj->needed_)) return false; return true; }