/** * Return the package set with the given name. * * If the package already exists in the internal database, then it returns * the existing structure. Otherwise it allocates a new one and will return * it. The actual name associated to the package set is a lowercase version * of the name given in parameter. * * A package set (struct pkgset) can be composed of multiple package instances * (struct pkginfo) where each instance is distinguished by its architecture * (as recorded in pkg.installed.arch and pkg.available.arch). * * @param inname Name of the package set. * * @return The package set. */ struct pkgset * pkg_hash_find_set(const char *inname) { struct pkgset **setp, *new_set; char *name = m_strdup(inname), *p; p= name; while (*p) { *p = c_tolower(*p); p++; } setp = bins + (str_fnv_hash(name) % (BINS)); while (*setp && strcasecmp((*setp)->name, name)) setp = &(*setp)->next; if (*setp) { free(name); return *setp; } new_set = nfmalloc(sizeof(*new_set)); pkgset_blank(new_set); new_set->name = nfstrsave(name); new_set->next = NULL; *setp = new_set; nset++; npkg++; free(name); return new_set; }
/** * Parse an RFC-822 style file. * * donep may be NULL. * If donep is not NULL only one package's information is expected. */ int parsedb(const char *filename, enum parsedbflags flags, struct pkginfo **donep) { struct pkgset tmp_set; struct pkginfo *new_pkg, *db_pkg; struct pkgbin *new_pkgbin, *db_pkgbin; struct pkg_parse_object pkg_obj; int fieldencountered[array_count(fieldinfos)]; int pdone; struct parsedb_state ps; struct field_state fs; memset(&fs, 0, sizeof(fs)); fs.fieldencountered = fieldencountered; parse_open(&ps, filename, flags); new_pkg = &tmp_set.pkg; if (flags & pdb_recordavailable) new_pkgbin = &new_pkg->available; else new_pkgbin = &new_pkg->installed; ps.pkg = new_pkg; ps.pkgbin = new_pkgbin; pkg_obj.pkg = new_pkg; pkg_obj.pkgbin = new_pkgbin; pdone= 0; /* Loop per package. */ for (;;) { memset(fieldencountered, 0, sizeof(fieldencountered)); pkgset_blank(&tmp_set); if (!parse_stanza(&ps, &fs, pkg_parse_field, &pkg_obj)) break; if (pdone && donep) parse_error(&ps, _("several package info entries found, only one allowed")); pkg_parse_verify(&ps, new_pkg, new_pkgbin); db_pkg = pkg_db_find_pkg(new_pkg->set->name, new_pkgbin->arch); if (flags & pdb_recordavailable) db_pkgbin = &db_pkg->available; else db_pkgbin = &db_pkg->installed; if ((flags & pdb_ignoreolder) && versioncompare(&new_pkgbin->version, &db_pkgbin->version) < 0) continue; pkg_parse_copy(&ps, db_pkg, db_pkgbin, new_pkg, new_pkgbin); if (donep) *donep = db_pkg; pdone++; if (parse_EOF(&ps)) break; } parse_close(&ps); varbuf_destroy(&fs.value); if (donep && !pdone) ohshit(_("no package information in `%.255s'"),filename); return pdone; }