Example #1
0
/**
 * 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;
}
Example #2
0
/**
 * 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;
}