static void setSovable(Pool * pool, Solvable *solvable, std::string name,
    std::string stream, std::string version, std::string context, const char * arch)
{
    std::ostringstream ss;
    // create solvable with:
    //   Name: $name:$stream:$version:$context
    //   Version: 0
    //   Arch: $arch
    ss << name << ":" << stream << ":" << version << ":" << context;
    solvable_set_str(solvable, SOLVABLE_NAME, ss.str().c_str());
    solvable_set_str(solvable, SOLVABLE_EVR, "0");
    // TODO Test can be remove when modules will be always with arch
    solvable_set_str(solvable, SOLVABLE_ARCH, arch ? arch : "noarch");
    // create Provide: module($name)
    ss.str(std::string());
    ss << "module(" << name << ")";
    auto depId = pool_str2id(pool, ss.str().c_str(), 1);
    solvable_add_deparray(solvable, SOLVABLE_PROVIDES, depId, -1);

    // create Provide: module($name:$stream)
    ss.str(std::string());
    ss << "module(" << name << ":" << stream << ")";
    depId = pool_str2id(pool, ss.str().c_str(), 1);
    solvable_add_deparray(solvable, SOLVABLE_PROVIDES, depId, -1);

    // create Provide: module($name:$stream:$version)
    ss.str(std::string());
    ss << "module(" << name << ":" << stream << ":" << version << ")";
    depId = pool_str2id(pool, ss.str().c_str(), 1);
    solvable_add_deparray(solvable, SOLVABLE_PROVIDES, depId, -1);
}
Beispiel #2
0
static void
endElement(struct solv_xmlparser *xmlp, int state, char *content)
{
  struct parsedata *pd = xmlp->userdata;
  Solvable *s = pd->solvable;

  switch (state)
    {
    case STATE_PRODUCT:
      if (!s->arch)
	s->arch = ARCH_NOARCH;
      if (!s->evr)
	s->evr = ID_EMPTY;
      if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
	s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pd->pool, s->name, s->evr, REL_EQ, 1), 0);
      pd->solvable = 0;
      break;
    case STATE_NAME:
      s->name = pool_str2id(pd->pool, join2(&pd->jd, "product", ":", content), 1);
      break;
    case STATE_ARCH:
      s->arch = pool_str2id(pd->pool, content, 1);
      break;
    case STATE_SUMMARY:
      repodata_set_str(pd->data, pd->handle, pool_id2langid(pd->pool, SOLVABLE_SUMMARY, pd->tmplang, 1), content);
      break;
    case STATE_VENDOR:
      s->vendor = pool_str2id(pd->pool, content, 1);
      break;
    case STATE_INSTALLTIME:
      repodata_set_num(pd->data, pd->handle, SOLVABLE_INSTALLTIME, atol(content));
    default:
      break;
    }
}
Beispiel #3
0
static void XMLCALL
endElement(void *userData, const char *name)
{
  struct parsedata *pd = userData;
  Solvable *s = pd->solvable;

#if 0
  fprintf(stderr, "end: [%d]%s\n", pd->state, name);
#endif
  if (pd->depth != pd->statedepth)
    {
      pd->depth--;
#if 0
      fprintf(stderr, "back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth);
#endif
      return;
    }

  pd->depth--;
  pd->statedepth--;

  switch (pd->state)
    {
    case STATE_PRODUCT:
      if (!s->arch)
	s->arch = ARCH_NOARCH;
      if (!s->evr)
	s->evr = ID_EMPTY;
      if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
	s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pd->pool, s->name, s->evr, REL_EQ, 1), 0);
      pd->solvable = 0;
      break;
    case STATE_NAME:
      s->name = pool_str2id(pd->pool, join2("product", ":", pd->content), 1);
      break;
    case STATE_ARCH:
      s->arch = pool_str2id(pd->pool, pd->content, 1);
      break;
    case STATE_SUMMARY:
      repodata_set_str(pd->data, pd->handle, langtag(pd, SOLVABLE_SUMMARY, pd->tmplang), pd->content);
      pd->tmplang = solv_free((void *)pd->tmplang);
      break;
    case STATE_VENDOR:
      s->vendor = pool_str2id(pd->pool, pd->content, 1);
      break;
    case STATE_INSTALLTIME:
      repodata_set_num(pd->data, pd->handle, SOLVABLE_INSTALLTIME, atol(pd->content));
    default:
      break;
    }

  pd->state = pd->sbtab[pd->state];
  pd->docontent = 0;

#if 0
  fprintf(stderr, "end: [%s] -> %d\n", name, pd->state);
#endif
}
static unsigned int
adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, char *line, Id marker, char *kind)
{
  int i, flags;
  Id id, evrid;
  char *sp[4];

  if (line[6] == '/')
    {
      /* A file dependency. Do not try to parse it */
      id = pool_str2id(pool, line + 6, 1);
    }
#ifdef ENABLE_COMPLEX_DEPS
  else if (line[6] == '(')
    {
      id = pool_parserpmrichdep(pool, line + 6);
      if (!id)
	{
	  pd->ret = pool_error(pool, -1, "susetags: line %d: bad dependency: '%s'\n", pd->lineno, line);
          return olddeps;
	}
    }
#endif
  else
    {
      i = split(line + 6, sp, 4); /* name, <op>, evr, ? */
      if (i != 1 && i != 3) /* expect either 'name' or 'name' <op> 'evr' */
        {
	  pd->ret = pool_error(pool, -1, "susetags: line %d: bad dependency: '%s'\n", pd->lineno, line);
          return olddeps;
        }
      if (kind)
        id = pool_str2id(pool, join2(&pd->jd, kind, ":", sp[0]), 1);
      else
        id = pool_str2id(pool, sp[0], 1);
      if (i == 3)
        {
          evrid = makeevr(pool, sp[2]);
          for (flags = 0; flags < 6; flags++)
            if (!strcmp(sp[1], flagtab[flags]))
              break;
          if (flags == 6)
            {
	      if (!strcmp(sp[1], "<>"))
		flags = 4;
	      else
		{
		  pd->ret = pool_error(pool, -1, "susetags: line %d: unknown relation: '%s'\n", pd->lineno, sp[1]);
		  return olddeps;
		}
            }
          id = pool_rel2id(pool, id, evrid, flags + 1, 1);
        }
    }
  return repo_addid_dep(pd->repo, olddeps, id, marker);
}
Beispiel #5
0
static unsigned int
adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, const char **atts, int isreq)
{
  Id id, name, marker;
  const char *n, *f, *k;
  const char **a;

  n = f = k = 0;
  marker = isreq ? -SOLVABLE_PREREQMARKER : 0;
  for (a = atts; *a; a += 2)
    {
      if (!strcmp(*a, "name"))
	n = a[1];
      else if (!strcmp(*a, "flags"))
	f = a[1];
      else if (!strcmp(*a, "kind"))
	k = a[1];
      else if (isreq && !strcmp(*a, "pre") && a[1][0] == '1')
	marker = SOLVABLE_PREREQMARKER;
    }
  if (!n)
    return olddeps;
  if (k && !strcmp(k, "package"))
    k = 0;
  if (k)
    {
      int l = strlen(k) + 1 + strlen(n) + 1;
      if (l > pd->acontent)
	{
	  pd->content = solv_realloc(pd->content, l + 256);
	  pd->acontent = l + 256;
	}
      sprintf(pd->content, "%s:%s", k, n);
      name = pool_str2id(pool, pd->content, 1);
    }
  else
    name = pool_str2id(pool, (char *)n, 1);
  if (f)
    {
      Id evr = makeevr_atts(pool, pd, atts);
      int flags;
      for (flags = 0; flags < 6; flags++)
	if (!strcmp(f, flagtab[flags]))
	  break;
      flags = flags < 6 ? flags + 1 : 0;
      id = pool_rel2id(pool, name, evr, flags, 1);
    }
  else
    id = name;
#if 0
  fprintf(stderr, "new dep %s%s%s\n", pool_id2str(pool, d), id2rel(pool, d), id2evr(pool, d));
#endif
  return repo_addid_dep(pd->common.repo, olddeps, id, marker);
}
Beispiel #6
0
Offset
repo_fix_conflicts(Repo *repo, Offset conflicts)
{
  char buf[1024], *p, *dep;
  Pool *pool = repo->pool;
  Id id;
  int i;

  if (!conflicts)
    return conflicts;
  for (i = conflicts; repo->idarraydata[i]; i++)
    {
      id = repo->idarraydata[i];
      if (ISRELDEP(id))
	continue;
      dep = (char *)pool_id2str(pool, id);
      if (!strncmp(dep, "otherproviders(", 15) && strlen(dep) < sizeof(buf) - 2)
	{
	  strcpy(buf, dep + 15);
	  if ((p = strchr(buf, ')')) != 0)
	    *p = 0;
	  id = pool_str2id(pool, buf, 1);
	  id = pool_rel2id(pool, NAMESPACE_OTHERPROVIDERS, id, REL_NAMESPACE, 1);
	  repo->idarraydata[i] = id;
	}
    }
  return conflicts;
}
/**
 * @brief Create stream dependencies based on modulemd metadata.
 */
void ModulePackage::createDependencies(Solvable *solvable) const
{
    Id depId;
    Pool * pool = dnf_sack_get_pool(moduleSack);

    for (const auto &dependency : getModuleDependencies()) {
        for (const auto &requires : dependency.getRequires()) {
            for (const auto &singleRequires : requires) {
                auto moduleName = singleRequires.first;
                std::vector<std::string> requiresStream;
                for (const auto &moduleStream : singleRequires.second) {
                    if (moduleStream.find('-', 0) != std::string::npos) {
                        std::ostringstream ss;
                        ss << "module(" << moduleName << ":" << moduleStream.substr(1) << ")";
                        depId = pool_str2id(pool, ss.str().c_str(), 1);
                        solvable_add_deparray(solvable, SOLVABLE_CONFLICTS, depId, 0);
                    } else {
                        std::string reqFormated = "module(" + moduleName + ":" + moduleStream + ")";
                        requiresStream.push_back(std::move(reqFormated));
                    }
                }
                if (requiresStream.empty()) {
                    std::ostringstream ss;
                    ss << "module(" << moduleName << ")";
                    depId = pool_str2id(pool, ss.str().c_str(), 1);
                    solvable_add_deparray(solvable, SOLVABLE_REQUIRES, depId, -1);
                } else if (requiresStream.size() == 1) {
                    auto & requireFormated = requiresStream[0];
                    depId = pool_str2id(pool, requireFormated.c_str(), 1);
                    solvable_add_deparray(solvable, SOLVABLE_REQUIRES, depId, -1);
                } else {
                    std::ostringstream ss;
                    ss << "(";
                    ss << std::accumulate(std::next(requiresStream.begin()),
                                            requiresStream.end(), requiresStream[0],
                                            [](std::string & a, std::string & b)
                                            { return a + " or " + b; });
                    ss << ")";
                    depId = pool_parserpmrichdep(pool, ss.str().c_str());
                    if (!depId)
                        throw std::runtime_error("Cannot parse module requires");
                    solvable_add_deparray(solvable, SOLVABLE_REQUIRES, depId, -1);
                }
            }
        }
    }
}
Beispiel #8
0
HyReldep
hy_reldep_create(HySack sack, const char *name, int cmp_type, const char *evr)
{
    Pool *pool = sack_pool(sack);
    Id id = pool_str2id(pool, name, 0);

    if (id == STRID_NULL || id == STRID_EMPTY)
	// stop right there, this will never match anything.
	return NULL;

    if (evr) {
	assert(cmp_type);
        Id ievr = pool_str2id(pool, evr, 1);
        int flags = cmptype2relflags(cmp_type);
        id = pool_rel2id(pool, id, ievr, flags, 1);
    }
    return reldep_create(pool, id);
}
/**
 * @brief Add conflict with a module stream represented as a ModulePackage.
 */
void ModulePackage::addStreamConflict(const ModulePackage * package)
{
    Pool * pool = dnf_sack_get_pool(moduleSack);
    std::ostringstream ss;
    Solvable *solvable = pool_id2solvable(pool, id);

    ss << "module(" + package->getNameStream() + ")";
    auto depId = pool_str2id(pool, ss.str().c_str(), 1);
    solvable_add_deparray(solvable, SOLVABLE_CONFLICTS, depId, 0);
}
Beispiel #10
0
static int
str2archid(Pool *pool, const char *arch)
{
  Id id;
  if (!*arch)
    return 0;
  id = pool_str2id(pool, arch, 0);
  if (!id || id == ARCH_SRC || id == ARCH_NOSRC || id == ARCH_NOARCH)
    return id;
  if (pool->id2arch && (id > pool->lastarch || !pool->id2arch[id]))
    return 0;
  return id;
}
Beispiel #11
0
static unsigned int
adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, char *line, Id marker)
{
  char *name;
  Id id;

  while ((name = splitword(&line)) != 0)
    {
      /* Hack, as the content file adds 'package:' for package
         dependencies sometimes.  */
      if (!strncmp (name, "package:", 8))
        name += 8;
      id = pool_str2id(pool, name, 1);
      if (*line == '<' || *line == '>' || *line == '=')	/* rel follows */
	{
	  char *rel = splitword(&line);
          char *evr = splitword(&line);
	  int flags;

	  if (!rel || !evr)
	    {
	      pool_debug(pool, SOLV_ERROR, "repo_content: bad relation '%s %s'\n", name, rel);
	      continue;
	    }
	  for (flags = 0; flags < 6; flags++)
	    if (!strcmp(rel, flagtab[flags]))
	      break;
	  if (flags == 6)
	    {
	      pool_debug(pool, SOLV_ERROR, "repo_content: unknown relation '%s'\n", rel);
	      continue;
	    }
	  id = pool_rel2id(pool, id, pool_str2id(pool, evr, 1), flags + 1, 1);
	}
      olddeps = repo_addid_dep(pd->repo, olddeps, id, marker);
    }
  return olddeps;
}
static void
add_source(struct parsedata *pd, char *line, Solvable *s, Id handle)
{
  Pool *pool = s->repo->pool;
  char *sp[5];
  Id name;
  Id arch;
  const char *evr, *sevr;

  if (split(line, sp, 5) != 4)
    {
      pd->ret = pool_error(pool, -1, "susetags: line %d: bad source line '%s'\n", pd->lineno, line);
      return;
    }

  name = pool_str2id(pool, sp[0], 1);
  arch = pool_str2id(pool, sp[3], 1);	/* do this before id2str */
  evr = join2(&pd->jd, sp[1], "-", sp[2]);
  sevr = pool_id2str(pool, s->evr);
  if (sevr)
    {
      /* strip epoch */
      const char *p;
      for (p = sevr; *p >= '0' && *p <= '9'; p++)
	;
      if (p != sevr && *p == ':' && p[1])
	sevr = p;
    }
  if (name == s->name)
    repodata_set_void(pd->data, handle, SOLVABLE_SOURCENAME);
  else
    repodata_set_id(pd->data, handle, SOLVABLE_SOURCENAME, name);
  if (sevr && !strcmp(sevr, evr))
    repodata_set_void(pd->data, handle, SOLVABLE_SOURCEEVR);
  else
    repodata_set_id(pd->data, handle, SOLVABLE_SOURCEEVR, pool_str2id(pool, evr, 1));
  repodata_set_constantid(pd->data, handle, SOLVABLE_SOURCEARCH, arch);
}
Beispiel #13
0
static void
queue_pkg_name(HySack sack, Queue *queue, const char *provide, int flags)
{
    Pool *pool = sack_pool(sack);
    if (!flags) {
	Id id = pool_str2id(pool, provide, 0);
	if (id == 0)
	    return;
	Id p, pp;
	FOR_PKG_PROVIDES(p, pp, id) {
	    Solvable *s = pool_id2solvable(pool, p);
	    if (s->name == id)
		queue_push(queue, p);
	}
Beispiel #14
0
/* content file query */
static void
doquery(Pool *pool, Repo *repo, const char *arg)
{
  char qbuf[256];
  const char *str;
  Id id;

  snprintf(qbuf, sizeof(qbuf), "susetags:%s", arg);
  id = pool_str2id(pool, qbuf, 0);
  if (!id)
    return;
  str = repo_lookup_str(repo, SOLVID_META, id);
  if (str)
    printf("%s\n", str);
}
Beispiel #15
0
void
repo_set_poolstr(Repo *repo, Id p, Id keyname, const char *str)
{
  Repodata *data;
  if (p >= 0)
    {
      switch (keyname)
	{
	case SOLVABLE_NAME:
	case SOLVABLE_ARCH:
	case SOLVABLE_EVR:
	case SOLVABLE_VENDOR:
	  repo_set_id(repo, p, keyname, pool_str2id(repo->pool, str, 1));
	  return;
	}
    }
  data = repo_last_repodata(repo);
  repodata_set_poolstr(data, p, keyname, str);
}
Beispiel #16
0
static void XMLCALL
endElement(void *userData, const char *name)
{
  struct parsedata *pd = userData;
  Pool *pool = pd->pool;
  Solvable *s = pd->solvable;
  Repo *repo = pd->repo;

#if 0
      fprintf(stderr, "end: %s\n", name);
#endif
  if (pd->depth != pd->statedepth)
    {
      pd->depth--;
#if 0
      fprintf(stderr, "back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth);
#endif
      return;
    }

  pd->depth--;
  pd->statedepth--;
  switch (pd->state)
    {
    case STATE_START:
      break;
    case STATE_UPDATES:
      break;
    case STATE_UPDATE:
      s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
      if (pd->buildtime)
	{
	  repodata_set_num(pd->data, pd->datanum, SOLVABLE_BUILDTIME, pd->buildtime);
	  pd->buildtime = (time_t)0;
	}
      break;
    case STATE_ID:
      s->name = pool_str2id(pool, join2(&pd->jd, "patch", ":", pd->content), 1);
      break;
      /* <title>imlib-1.9.15-6.fc8</title> */
    case STATE_TITLE:
      while (pd->lcontent > 0 && pd->content[pd->lcontent - 1] == '\n')
        pd->content[--pd->lcontent] = 0;
      repodata_set_str(pd->data, pd->datanum, SOLVABLE_SUMMARY, pd->content);
      break;
    case STATE_SEVERITY:
      repodata_set_poolstr(pd->data, pd->datanum, UPDATE_SEVERITY, pd->content);
      break;
    case STATE_RIGHTS:
      repodata_set_poolstr(pd->data, pd->datanum, UPDATE_RIGHTS, pd->content);
      break;
      /*
       * <release>Fedora 8</release>
       */
    case STATE_RELEASE:
      break;
    case STATE_ISSUED:
      break;
    case STATE_REFERENCES:
      break;
    case STATE_REFERENCE:
      break;
      /*
       * <description>This update ...</description>
       */
    case STATE_DESCRIPTION:
      repodata_set_str(pd->data, pd->datanum, SOLVABLE_DESCRIPTION, pd->content);
      break;
      /*
       * <message>Warning! ...</message>
       */
    case STATE_MESSAGE:
      repodata_set_str(pd->data, pd->datanum, UPDATE_MESSAGE, pd->content);
      break;
    case STATE_PKGLIST:
      break;
    case STATE_COLLECTION:
      break;
    case STATE_NAME:
      break;
    case STATE_PACKAGE:
      repodata_add_flexarray(pd->data, pd->datanum, UPDATE_COLLECTION, pd->collhandle);
      pd->collhandle = 0;
      break;
      /* <filename>libntlm-0.4.2-1.fc8.x86_64.rpm</filename> */
      /* <filename>libntlm-0.4.2-1.fc8.x86_64.rpm</filename> */
    case STATE_FILENAME:
      repodata_set_str(pd->data, pd->collhandle, UPDATE_COLLECTION_FILENAME, pd->content);
      break;
      /* <reboot_suggested>True</reboot_suggested> */
    case STATE_REBOOT:
      if (pd->content[0] == 'T' || pd->content[0] == 't'|| pd->content[0] == '1')
	{
	  /* FIXME: this is per-package, the global flag should be computed at runtime */
	  repodata_set_void(pd->data, pd->datanum, UPDATE_REBOOT);
	  repodata_set_void(pd->data, pd->collhandle, UPDATE_REBOOT);
	}
      break;
      /* <restart_suggested>True</restart_suggested> */
    case STATE_RESTART:
      if (pd->content[0] == 'T' || pd->content[0] == 't'|| pd->content[0] == '1')
	{
	  /* FIXME: this is per-package, the global flag should be computed at runtime */
	  repodata_set_void(pd->data, pd->datanum, UPDATE_RESTART);
	  repodata_set_void(pd->data, pd->collhandle, UPDATE_RESTART);
	}
      break;
      /* <relogin_suggested>True</relogin_suggested> */
    case STATE_RELOGIN:
      if (pd->content[0] == 'T' || pd->content[0] == 't'|| pd->content[0] == '1')
	{
	  /* FIXME: this is per-package, the global flag should be computed at runtime */
	  repodata_set_void(pd->data, pd->datanum, UPDATE_RELOGIN);
	  repodata_set_void(pd->data, pd->collhandle, UPDATE_RELOGIN);
	}
      break;
    default:
      break;
    }

  pd->state = pd->sbtab[pd->state];
  pd->docontent = 0;
}
Beispiel #17
0
static void XMLCALL
startElement(void *userData, const char *name, const char **atts)
{
  struct parsedata *pd = userData;
  Pool *pool = pd->pool;
  Solvable *solvable = pd->solvable;
  struct stateswitch *sw;
  /*const char *str; */

#if 0
  fprintf(stderr, "start: [%d]%s\n", pd->state, name);
#endif
  if (pd->depth != pd->statedepth)
    {
      pd->depth++;
      return;
    }

  pd->depth++;
  if (!pd->swtab[pd->state])
    return;
  for (sw = pd->swtab[pd->state]; sw->from == pd->state; sw++)  /* find name in statetable */
    if (!strcmp(sw->ename, name))
      break;

  if (sw->from != pd->state)
    {
#if 0
      fprintf(stderr, "into unknown: %s (from: %d)\n", name, pd->state);
      exit( 1 );
#endif
      return;
    }
  pd->state = sw->to;
  pd->docontent = sw->docontent;
  pd->statedepth = pd->depth;
  pd->lcontent = 0;
  *pd->content = 0;

  switch(pd->state)
    {
    case STATE_START:
      break;
    case STATE_UPDATES:
      break;
      /*
       * <update from="*****@*****.**"
       *         status="stable"
       *         type="bugfix" (enhancement, security)
       *         version="1.4">
       */
    case STATE_UPDATE:
      {
	const char *from = 0, *type = 0, *version = 0;
	for (; *atts; atts += 2)
	  {
	    if (!strcmp(*atts, "from"))
	      from = atts[1];
	    else if (!strcmp(*atts, "type"))
	      type = atts[1];
	    else if (!strcmp(*atts, "version"))
	      version = atts[1];
	  }


	solvable = pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo));
	pd->datanum = pd->solvable - pool->solvables;

	solvable->vendor = pool_str2id(pool, from, 1);
	solvable->evr = pool_str2id(pool, version, 1);
	solvable->arch = ARCH_NOARCH;
	if (type)
	  repodata_set_str(pd->data, pd->datanum, SOLVABLE_PATCHCATEGORY, type);
        pd->buildtime = (time_t)0;
      }
      break;
      /* <id>FEDORA-2007-4594</id> */
    case STATE_ID:
      break;
      /* <title>imlib-1.9.15-6.fc8</title> */
    case STATE_TITLE:
      break;
      /* <release>Fedora 8</release> */
    case STATE_RELEASE:
      break;
      /*  <issued date="2008-03-21 21:36:55"/>
      */
    case STATE_ISSUED:
    case STATE_UPDATED:
      {
	const char *date = 0;
	for (; *atts; atts += 2)
	  {
	    if (!strcmp(*atts, "date"))
	      date = atts[1];
	  }
	if (date)
	  {
	    time_t t = datestr2timestamp(date);
	    if (t && t > pd->buildtime)
              pd->buildtime = t;
	  }
      }
      break;
    case STATE_REFERENCES:
      break;
      /*  <reference href="https://bugzilla.redhat.com/show_bug.cgi?id=330471"
       *             id="330471"
       *             title="LDAP schema file missing for dhcpd"
       *             type="bugzilla"/>
       */
    case STATE_REFERENCE:
      {
        const char *href = 0, *id = 0, *title = 0, *type = 0;
	Id handle;
	for (; *atts; atts += 2)
	  {
	    if (!strcmp(*atts, "href"))
	      href = atts[1];
	    else if (!strcmp(*atts, "id"))
	      id = atts[1];
	    else if (!strcmp(*atts, "title"))
	      title = atts[1];
	    else if (!strcmp(*atts, "type"))
	      type = atts[1];
	  }
	handle = repodata_new_handle(pd->data);
	if (href)
	  repodata_set_str(pd->data, handle, UPDATE_REFERENCE_HREF, href);
	if (id)
	  repodata_set_str(pd->data, handle, UPDATE_REFERENCE_ID, id);
	if (title)
	  repodata_set_str(pd->data, handle, UPDATE_REFERENCE_TITLE, title);
	if (type)
	  repodata_set_poolstr(pd->data, handle, UPDATE_REFERENCE_TYPE, type);
	repodata_add_flexarray(pd->data, pd->datanum, UPDATE_REFERENCE, handle);
      }
      break;
      /* <description>This update ...</description> */
    case STATE_DESCRIPTION:
      break;
      /* <message type="confirm">This update ...</message> */
    case STATE_MESSAGE:
      break;
    case STATE_PKGLIST:
      break;
      /* <collection short="F8" */
    case STATE_COLLECTION:
      break;
      /* <name>Fedora 8</name> */
    case STATE_NAME:
      break;
      /*   <package arch="ppc64" name="imlib-debuginfo" release="6.fc8"
       *            src="http://download.fedoraproject.org/pub/fedora/linux/updates/8/ppc64/imlib-debuginfo-1.9.15-6.fc8.ppc64.rpm"
       *            version="1.9.15">
       *
       *
       * -> patch.conflicts: {name} < {version}.{release}
       */
    case STATE_PACKAGE:
      {
	const char *arch = 0, *name = 0;
	Id evr = makeevr_atts(pool, pd, atts); /* parse "epoch", "version", "release" */
	Id n, a = 0;
	Id rel_id;

	for (; *atts; atts += 2)
	  {
	    if (!strcmp(*atts, "arch"))
	      arch = atts[1];
	    else if (!strcmp(*atts, "name"))
	      name = atts[1];
	  }
	/* generated Id for name */
	n = pool_str2id(pool, name, 1);
	rel_id = n;
	if (arch)
	  {
	    /*  generate Id for arch and combine with name */
	    a = pool_str2id(pool, arch, 1);
	    rel_id = pool_rel2id(pool, n, a, REL_ARCH, 1);
	  }
	rel_id = pool_rel2id(pool, rel_id, evr, REL_LT, 1);

	solvable->conflicts = repo_addid_dep(pd->repo, solvable->conflicts, rel_id, 0);

        /* who needs the collection anyway? */
        pd->collhandle = repodata_new_handle(pd->data);
	repodata_set_id(pd->data, pd->collhandle, UPDATE_COLLECTION_NAME, n);
	repodata_set_id(pd->data, pd->collhandle, UPDATE_COLLECTION_EVR, evr);
	repodata_set_id(pd->data, pd->collhandle, UPDATE_COLLECTION_ARCH, a);
        break;
      }
      /* <filename>libntlm-0.4.2-1.fc8.x86_64.rpm</filename> */
      /* <filename>libntlm-0.4.2-1.fc8.x86_64.rpm</filename> */
    case STATE_FILENAME:
      break;
      /* <reboot_suggested>True</reboot_suggested> */
    case STATE_REBOOT:
      break;
      /* <restart_suggested>True</restart_suggested> */
    case STATE_RESTART:
      break;
      /* <relogin_suggested>True</relogin_suggested> */
    case STATE_RELOGIN:
      break;
    default:
      break;
    }
  return;
}
Beispiel #18
0
static Id
makeevr_atts(Pool *pool, struct parsedata *pd, const char **atts)
{
  const char *e, *v, *r, *v2;
  char *c;
  int l;

  e = v = r = 0;
  for (; *atts; atts += 2)
    {
      if (!strcmp(*atts, "epoch"))
	e = atts[1];
      else if (!strcmp(*atts, "version"))
	v = atts[1];
      else if (!strcmp(*atts, "release"))
	r = atts[1];
    }
  if (e && !strcmp(e, "0"))
    e = 0;
  if (v && !e)
    {
      for (v2 = v; *v2 >= '0' && *v2 <= '9'; v2++)
        ;
      if (v2 > v && *v2 == ':')
	e = "0";
    }
  l = 1;
  if (e)
    l += strlen(e) + 1;
  if (v)
    l += strlen(v);
  if (r)
    l += strlen(r) + 1;
  if (l > pd->acontent)
    {
      pd->content = realloc(pd->content, l + 256);
      pd->acontent = l + 256;
    }
  c = pd->content;
  if (e)
    {
      strcpy(c, e);
      c += strlen(c);
      *c++ = ':';
    }
  if (v)
    {
      strcpy(c, v);
      c += strlen(c);
    }
  if (r)
    {
      *c++ = '-';
      strcpy(c, r);
      c += strlen(c);
    }
  *c = 0;
  if (!*pd->content)
    return 0;
#if 0
  fprintf(stderr, "evr: %s\n", pd->content);
#endif
  return pool_str2id(pool, pd->content, 1);
}
Beispiel #19
0
static void XMLCALL
endElement(void *userData, const char *name)
{
  struct parsedata *pd = userData;
  Pool *pool = pd->pool;
  Solvable *s = pd->solvable;
  Id id;

#if 0
  fprintf(stderr, "end: [%d]%s\n", pd->state, name);
#endif
  if (pd->depth != pd->statedepth)
    {
      pd->depth--;
#if 0
      fprintf(stderr, "back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth);
#endif
      return;
    }

  pd->depth--;
  pd->statedepth--;

  switch (pd->state)
    {
    case STATE_APPLICATION:
      if (!s->arch)
	s->arch = ARCH_NOARCH;
      if (!s->evr)
	s->evr = ID_EMPTY;
      if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
	s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pd->pool, s->name, s->evr, REL_EQ, 1), 0);
      pd->solvable = 0;
      break;
    case STATE_ID:
      if (pd->lcontent > 8 && !strcmp(".desktop", pd->content + pd->lcontent - 8))
	pd->content[pd->lcontent - 8] = 0;
      id = pool_str2id(pd->pool, pool_tmpjoin(pool, "appdata(", pd->content, ")"), 1);
      s->requires = repo_addid_dep(pd->repo, s->requires, id, 0);
      id = pool_str2id(pd->pool, pool_tmpjoin(pool, "application-appdata(", pd->content, ")"), 1);
      s->provides = repo_addid_dep(pd->repo, s->provides, id, 0);
      break;
    case STATE_NAME:
      s->name = pool_str2id(pd->pool, pool_tmpjoin(pool, "application:", pd->content, 0), 1);
      break;
    case STATE_LICENCE:
      repodata_add_poolstr_array(pd->data, pd->handle, SOLVABLE_LICENSE, pd->content);
      break;
    case STATE_SUMMARY:
      repodata_set_str(pd->data, pd->handle, SOLVABLE_SUMMARY, pd->content);
      break;
    case STATE_URL:
      repodata_set_str(pd->data, pd->handle, SOLVABLE_URL, pd->content);
      break;
    case STATE_GROUP:
      repodata_add_poolstr_array(pd->data, pd->handle, SOLVABLE_GROUP, pd->content);
      break;
    case STATE_DESCRIPTION:
      if (pd->description)
	{
	  /* strip trailing newlines */
	  int l = strlen(pd->description);
	  while (l && pd->description[l - 1] == '\n')
	    pd->description[--l] = 0;
          repodata_set_str(pd->data, pd->handle, SOLVABLE_DESCRIPTION, pd->description);
	}
      break;
    case STATE_P:
      wsstrip(pd);
      pd->description = solv_dupappend(pd->description, pd->content, "\n\n");
      break;
    case STATE_UL_LI:
      wsstrip(pd);
      indent(pd, 4);
      pd->content[2] = '-';
      pd->description = solv_dupappend(pd->description, pd->content, "\n");
      break;
    case STATE_OL_LI:
      wsstrip(pd);
      indent(pd, 4);
      if (++pd->licnt >= 10)
	pd->content[0] = '0' + (pd->licnt / 10) % 10;
      pd->content[1] = '0' + pd->licnt  % 10;
      pd->content[2] = '.';
      pd->description = solv_dupappend(pd->description, pd->content, "\n");
      break;
    case STATE_UL:
    case STATE_OL:
      pd->description = solv_dupappend(pd->description, "\n", 0);
      break;
    default:
      break;
    }

  pd->state = pd->sbtab[pd->state];
  pd->docontent = 0;

#if 0
  fprintf(stderr, "end: [%s] -> %d\n", name, pd->state);
#endif
}
Beispiel #20
0
static Id
parseonedep(Pool *pool, char *p)
{
  char *n, *ne, *e, *ee;
  Id name, evr;
  int flags;

  while (*p == ' ' || *p == '\t' || *p == '\n')
    p++;
  if (!*p)
    return 0;
  if (!strcmp(p, "!true"))
    return 0;
  if (!strcmp(p, "!false"))
    return pool_str2id(pool, p, 1);
  n = p;
  /* find end of name */
  while (*p && *p != ' ' && *p != '\t' && *p != '\n' && *p != '|')
    p++;
  ne = p;
  while (*p == ' ' || *p == '\t' || *p == '\n')
    p++;
  evr = 0;
  flags = 0;
  e = ee = 0;
  if (*p == '>' || *p == '<' || *p == '=' || *p == '!')
    {
      if (*p == '>')
	flags |= REL_GT;
      else if (*p == '=')
	flags |= REL_EQ;
      else if (*p == '<')
	flags |= REL_LT;
      else if (*p == '!')
	flags |= REL_LT | REL_GT | REL_EQ;
      p++;
      if (flags && *p == '=')
	{
	  if (p[-1] != '=')
	    flags ^= REL_EQ;
	  p++;
	}
      while (*p == ' ' || *p == '\t' || *p == '\n')
	p++;
      e = p;
      while (*p && *p != ' ' && *p != '\t' && *p != '\n' && *p != '|')
	p++;
      ee = p;
      while (*p == ' ' || *p == '\t' || *p == '\n')
	p++;
    }
  name = pool_strn2id(pool, n, ne - n, 1);
  if (e)
    {
      evr = pool_strn2id(pool, e, ee - e, 1);
      name = pool_rel2id(pool, name, evr, flags, 1);
    }
  if (*p == '|')
    {
      Id id = parseonedep(pool, p + 1);
      if (id)
	name = pool_rel2id(pool, name, id, REL_OR, 1);
    }
  return name;
}
Beispiel #21
0
static void XMLCALL
endElement(void *userData, const char *name)
{
  Parsedata *pd = (Parsedata *)userData;
  Pool *pool = pd->pool;
  Solvable *s = pd->solvable;
  Id evr;
  unsigned int t = 0;
  const char *flavor;

  if (pd->depth != pd->statedepth)
    {
      pd->depth--;
      /* printf("back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth); */
      return;
    }

  /* ignore deps element */
  if (pd->state == STATE_PACKAGE && !strcmp(name, "deps"))
    return;

  pd->depth--;
  pd->statedepth--;
  switch (pd->state)
    {

    case STATE_PACKAGE:		       /* package complete */
      if (name[0] == 's' && name[1] == 'r' && name[2] == 'c' && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
	s->arch = ARCH_SRC;
      if (!s->arch)                    /* default to "noarch" */
	s->arch = ARCH_NOARCH;

      if (!s->evr && pd->version)      /* set solvable evr */
        s->evr = evr2id(pool, pd,
                        pd->epoch   ? pd->evrspace + pd->epoch   : 0,
                        pd->version ? pd->evrspace + pd->version : 0,
                        pd->release ? pd->evrspace + pd->release : "");
      /* ensure self-provides */
      if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
        s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
      s->supplements = repo_fix_supplements(pd->repo, s->provides, s->supplements, pd->freshens);
      s->conflicts = repo_fix_conflicts(pd->repo, s->conflicts);
      pd->freshens = 0;

      /* see bugzilla bnc#190163 */
      flavor = findKernelFlavor(pd, s);
      if (flavor) 
	{
	  char *cflavor = solv_strdup(flavor);	/* make pointer safe */

	  Id npr;
	  Id pid;

	  /* this is either a kernel package or a kmp */
	  if (s->provides)
	    {
	      Offset prov = s->provides;
	      npr = 0;
	      while ((pid = pd->repo->idarraydata[prov++]) != 0)
		{
		  const char *depname = 0;
		  Reldep *prd = 0;

		  if (ISRELDEP(pid))
		    {
		      prd = GETRELDEP(pool, pid);
		      depname = pool_id2str(pool, prd->name);
		    }
		  else
		    {
		      depname = pool_id2str(pool, pid);
		    }


		  if (!strncmp(depname, "kernel(", 7) && !strchr(depname, ':'))
		    {
		      char newdep[100];
		      snprintf(newdep, sizeof(newdep), "kernel(%s:%s", cflavor, depname + 7);
		      pid = pool_str2id(pool, newdep, 1);
		      if (prd)
			pid = pool_rel2id(pool, pid, prd->evr, prd->flags, 1);
		    }

		  npr = repo_addid_dep(pd->repo, npr, pid, 0);
		}
	      s->provides = npr;
	    }
#if 1

	  if (s->requires)
	    {
	      Offset reqs = s->requires;
	      npr = 0;
	      while ((pid = pd->repo->idarraydata[reqs++]) != 0)
		{
		  const char *depname = 0;
		  Reldep *prd = 0;

		  if (ISRELDEP(pid))
		    {
		      prd = GETRELDEP(pool, pid);
		      depname = pool_id2str(pool, prd->name);
		    }
		  else
		    {
		      depname = pool_id2str(pool, pid);
		    }

		  if (!strncmp(depname, "kernel(", 7) && !strchr(depname, ':'))
		    {
		      char newdep[100];
		      snprintf(newdep, sizeof(newdep), "kernel(%s:%s", cflavor, depname + 7);
		      pid = pool_str2id(pool, newdep, 1);
		      if (prd)
			pid = pool_rel2id(pool, pid, prd->evr, prd->flags, 1);
		    }
		  npr = repo_addid_dep(pd->repo, npr, pid, 0);
		}
	      s->requires = npr;
	    }
#endif
	  free(cflavor);
	}
      break;
    case STATE_NAME:
      s->name = pool_str2id(pool, pd->content, 1);
      break;
    case STATE_VENDOR:
      s->vendor = pool_str2id(pool, pd->content, 1);
      break;
    case STATE_BUILDTIME:
      t = atoi (pd->content);
      if (t)
	repodata_set_num(pd->data, s - pool->solvables, SOLVABLE_BUILDTIME, t);
      break;	
    case STATE_UPDATE:		       /* new version, keeping all other metadata */
      evr = evr2id(pool, pd,
                   pd->epoch   ? pd->evrspace + pd->epoch   : 0,
                   pd->version ? pd->evrspace + pd->version : 0,
                   pd->release ? pd->evrspace + pd->release : 0);
      pd->levrspace = 1;
      pd->epoch = 0;
      pd->version = 0;
      pd->release = 0;
      /* use highest evr */
      if (!s->evr || pool_evrcmp(pool, s->evr, evr, EVRCMP_COMPARE) <= 0)
	s->evr = evr;
      break;
    case STATE_EPOCH:
    case STATE_VERSION:
    case STATE_RELEASE:
    case STATE_PEPOCH:
    case STATE_PVERSION:
    case STATE_PRELEASE:
      /* ensure buffer space */
      if (pd->lcontent + 1 + pd->levrspace > pd->aevrspace)
	{
	  pd->evrspace = (char *)realloc(pd->evrspace, pd->lcontent + 1 + pd->levrspace + 256);
	  pd->aevrspace = pd->lcontent + 1 + pd->levrspace + 256;
	}
      memcpy(pd->evrspace + pd->levrspace, pd->content, pd->lcontent + 1);
      if (pd->state == STATE_EPOCH || pd->state == STATE_PEPOCH)
	pd->epoch = pd->levrspace;
      else if (pd->state == STATE_VERSION || pd->state == STATE_PVERSION)
	pd->version = pd->levrspace;
      else
	pd->release = pd->levrspace;
      pd->levrspace += pd->lcontent + 1;
      break;
    case STATE_ARCH:
    case STATE_PARCH:
      s->arch = pool_str2id(pool, pd->content, 1);
      break;
    default:
      break;
    }
  pd->state = pd->sbtab[pd->state];
  pd->docontent = 0;
  /* printf("back from known %d %d %d\n", pd->state, pd->depth, pd->statedepth); */
}
Beispiel #22
0
int
repo_add_autopattern(Repo *repo, int flags)
{
  Pool *pool = repo->pool;
  Repodata *data = 0;
  Solvable *s, *s2;
  Queue q, q2;
  Id p;
  Id pattern_id;
  Id autopattern_id = 0;
  int i, j;

  queue_init(&q);
  queue_init(&q2);

  pattern_id = pool_str2id(pool, "pattern()", 9);
  FOR_REPO_SOLVABLES(repo, p, s)
    {
      const char *n = pool_id2str(pool, s->name);
      if (!strncmp("pattern:", n, 8))
	queue_push(&q, p);
      else if (s->provides)
	{
	  Id prv, *prvp = repo->idarraydata + s->provides;
	  while ((prv = *prvp++) != 0)            /* go through all provides */
	    if (ISRELDEP(prv))
	      {
	        Reldep *rd = GETRELDEP(pool, prv);
		if (rd->name == pattern_id && rd->flags == REL_EQ)
		  {
		    queue_push2(&q2, p, rd->evr);
		    break;
		  }
	      }
	}
    }
  for (i = 0; i < q2.count; i += 2)
    {
      const char *pn = 0;
      char *newname;
      Id name, prv, *prvp;
      const char *str;
      unsigned long long num;

      s = pool->solvables + q2.elements[i];
      /* construct new name */
      newname = pool_tmpjoin(pool, "pattern:", pool_id2str(pool, q2.elements[i + 1]), 0);
      unescape(newname);
      name = pool_str2id(pool, newname, 0);
      if (name)
	{
	  /* check if we already have that pattern */
	  for (j = 0; j < q.count; j++)
	    {
	      s2 = pool->solvables + q.elements[j];
	      if (s2->name == name && s2->arch == s->arch && s2->evr == s->evr)
		break;
	    }
	  if (j < q.count)
	    continue;	/* yes, do not add again */
	}
      /* new pattern */
      if (!name)
        name = pool_str2id(pool, newname, 1);
      if (!data)
	{
	  repo_internalize(repo);	/* to make that the lookups work */
	  data = repo_add_repodata(repo, flags);
	}
      s2 = pool_id2solvable(pool, repo_add_solvable(repo));
      s = pool->solvables + q2.elements[i];	/* re-calc pointer */
      s2->name = name;
      s2->arch = s->arch;
      s2->evr = s->evr;
      s2->vendor = s->vendor;
      /* add link requires */
      s2->requires = repo_addid_dep(repo, s2->requires, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1) , 0);
      /* add autopattern provides */
      if (!autopattern_id)
	autopattern_id = pool_str2id(pool, "autopattern()", 1);
      s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, autopattern_id, s->name, REL_EQ, 1), 0);
      /* add self provides */
      s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, s2->name, s2->evr, REL_EQ, 1), 0);
      if ((num = solvable_lookup_num(s, SOLVABLE_INSTALLTIME, 0)) != 0)
	repodata_set_num(data, s2 - pool->solvables, SOLVABLE_INSTALLTIME, num);
      if ((num = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0)) != 0)
	repodata_set_num(data, s2 - pool->solvables, SOLVABLE_BUILDTIME, num);
      if ((str = solvable_lookup_str(s, SOLVABLE_SUMMARY)) != 0)
	repodata_set_str(data, s2 - pool->solvables, SOLVABLE_SUMMARY, str);
      if ((str = solvable_lookup_str(s, SOLVABLE_DESCRIPTION)) != 0)
	repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DESCRIPTION, str);
      /* fill in stuff from provides */
      prvp = repo->idarraydata + s->provides;
      while ((prv = *prvp++) != 0)            /* go through all provides */
	{
	  Id evr = 0;
	  if (ISRELDEP(prv))
	    {
	      Reldep *rd = GETRELDEP(pool, prv);
	      if (rd->flags != REL_EQ)
	        continue;
	      prv = rd->name;
	      evr = rd->evr;
	    }
	  pn = pool_id2str(pool, prv);
	  if (strncmp("pattern-", pn, 8) != 0)
	    continue;
	  newname = 0;
	  if (evr)
	    {
	      newname = pool_tmpjoin(pool, pool_id2str(pool, evr), 0, 0);
	      unescape(newname);
	    }
	  if (!strncmp(pn, "pattern-category(", 17) && evr)
	    {
	      char lang[9];
	      int l = strlen(pn);
	      Id langtag;
	      if (l > 17 + 9 || pn[l - 1] != ')')
		continue;
              strncpy(lang, pn + 17, l - 17 - 1);
	      lang[l - 17 - 1] = 0;
	      langtag = SOLVABLE_CATEGORY;
	      if (*lang && strcmp(lang, "en") != 0)
		langtag = pool_id2langid(pool, SOLVABLE_CATEGORY, lang, 1);
	      repodata_set_str(data, s2 - pool->solvables, langtag, newname);
	    }
	  else if (!strcmp(pn, "pattern-includes()") && evr)
	    repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_INCLUDES, pool_tmpjoin(pool, "pattern:", newname, 0));
	  else if (!strcmp(pn, "pattern-extends()") && evr)
	    repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_EXTENDS, pool_tmpjoin(pool, "pattern:", newname, 0));
	  else if (!strcmp(pn, "pattern-icon()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ICON, newname);
	  else if (!strcmp(pn, "pattern-order()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ORDER, newname);
	  else if (!strcmp(pn, "pattern-visible()") && !evr)
	    repodata_set_void(data, s2 - pool->solvables, SOLVABLE_ISVISIBLE);
	}
    }
  queue_free(&q);
  queue_free(&q2);
  if (data && !(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  else if (!data && !(flags & REPO_NO_INTERNALIZE))
    repo_internalize(repo);
  return 0;
}
Beispiel #23
0
int
repo_add_mdk(Repo *repo, FILE *fp, int flags)
{
  Pool *pool = repo->pool;
  Repodata *data;
  Solvable *s;
  char *buf;
  int bufa, bufl;

  data = repo_add_repodata(repo, flags);
  bufa = 4096;
  buf = solv_malloc(bufa);
  bufl = 0;
  s = 0;
  while (fgets(buf + bufl, bufa - bufl, fp) > 0)
    {
      bufl += strlen(buf + bufl);
      if (bufl && buf[bufl - 1] != '\n')
	{
	  if (bufa - bufl < 256)
	    {
	      bufa += 4096;
	      buf = solv_realloc(buf, bufa);
	    }
	  continue;
	}
      buf[--bufl] = 0;
      bufl = 0;
      if (buf[0] != '@')
	{
	  pool_debug(pool, SOLV_ERROR, "bad line <%s>\n", buf);
	  continue;
	}
      if (!s)
	s = pool_id2solvable(pool, repo_add_solvable(repo));
      if (!strncmp(buf + 1, "filesize@", 9))
	repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, strtoull(buf + 10, 0, 10));
      else if (!strncmp(buf + 1, "summary@", 8))
	repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, buf + 9);
      else if (!strncmp(buf + 1, "provides@", 9))
	s->provides = parse_deps(s, buf + 10, 0);
      else if (!strncmp(buf + 1, "requires@", 9))
	s->requires = parse_deps(s, buf + 10, SOLVABLE_PREREQMARKER);
      else if (!strncmp(buf + 1, "suggests@", 9))
	s->suggests = parse_deps(s, buf + 10, 0);
      else if (!strncmp(buf + 1, "obsoletes@", 10))
	s->obsoletes = parse_deps(s, buf + 11, 0);
      else if (!strncmp(buf + 1, "conflicts@", 10))
	s->conflicts = parse_deps(s, buf + 11, 0);
      else if (!strncmp(buf + 1, "info@", 5))
	{
	  char *nvra = buf + 6;
	  char *epochstr;
	  char *arch;
	  char *version;
	  char *filename;
	  if ((epochstr = strchr(nvra, '@')) != 0)
	    {
	      char *sizestr;
	      *epochstr++ = 0;
	      if ((sizestr = strchr(epochstr, '@')) != 0)
		{
		  char *groupstr;
		  *sizestr++ = 0;
		  if ((groupstr = strchr(sizestr, '@')) != 0)
		    {
		      char *n;
		      *groupstr++ = 0;
		      if ((n = strchr(groupstr, '@')) != 0)
			*n = 0;
		      if (*groupstr)
			repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_GROUP, groupstr);
		    }
		  repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(sizestr, 0, 10));
		}
	    }
          filename = pool_tmpjoin(pool, nvra, ".rpm", 0);
	  arch = strrchr(nvra, '.');
	  if (arch)
	    {
	      *arch++ = 0;
	      s->arch = pool_str2id(pool, arch, 1);
	    }
	  /* argh, do we have a distepoch or not, check self-provides */
	  if (s->provides)
	    {
	      Id id, lastid, *idp = s->repo->idarraydata + s->provides;
	      lastid = 0;
	      for (idp = s->repo->idarraydata + s->provides; (id = *idp) != 0; idp++)
		{
		  const char *evr, *name;
		  int namel;
		  Reldep *rd;
		  if (!ISRELDEP(id))
		    continue;
		  rd = GETRELDEP(pool, id);
		  if (rd->flags != REL_EQ)
		    continue;
		  name = pool_id2str(pool, rd->name);
		  namel = strlen(name);
		  if (strncmp(name, nvra, namel) != 0 || nvra[namel] != '-')
		    continue;
		  evr = pool_id2str(pool, rd->evr);
		  evr = strrchr(evr, '-');
		  if (evr && strchr(evr, ':') != 0)
		    lastid = id;
		}
	      if (lastid)
		{
		  /* self provides found, and it contains a distepoch */
		  /* replace with self-provides distepoch to get rid of the disttag */
		  char *nvradistepoch = strrchr(nvra, '-');
		  if (nvradistepoch)
		    {
		      Reldep *rd = GETRELDEP(pool, lastid);
		      const char *evr = pool_id2str(pool, rd->evr);
		      evr = strrchr(evr, '-');
		      if (evr && (evr = strchr(evr, ':')) != 0)
			{
			  if (strlen(evr) < strlen(nvradistepoch))
			    strcpy(nvradistepoch, evr);
			}
		    }
		}
	    }
	  version = strrchr(nvra, '-');
	  if (version)
	    {
	      char *release = version;
	      *release = 0;
	      version = strrchr(nvra, '-');
	      *release = '-';
	      if (!version)
		version = release;
	      *version++ = 0;
	    }
	  else
	    version = "";
	  s->name = pool_str2id(pool, nvra, 1);
	  if (epochstr && *epochstr && strcmp(epochstr, "0") != 0)
	    {
	      char *evr = pool_tmpjoin(pool, epochstr, ":", version);
	      s->evr = pool_str2id(pool, evr, 1);
	    }
	  else
	    s->evr = pool_str2id(pool, version, 1);
	  repodata_set_location(data, s - pool->solvables, 0, 0, filename);
	  if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
	    s->provides = repo_addid_dep(s->repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
          s = 0;
	}
      else
	{
	  char *tagend = strchr(buf + 1, '@');
	  if (tagend)
	    *tagend = 0;
	  pool_debug(pool, SOLV_ERROR, "unknown tag <%s>\n", buf + 1);
	  continue;
	}
    }
  if (s)
    {
      pool_debug(pool, SOLV_ERROR, "unclosed package at EOF\n");
      repo_free_solvable(s->repo, s - pool->solvables, 1);
    }
  solv_free(buf);
  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  return 0;
}
static void
add_releasefile_product(Repo *repo, FILE *fp)
{
  Pool *pool = repo->pool;
  char buf[BUFF_SIZE];
  Id name = 0;
  Id arch = 0;
  Id version = 0;
  int lnum = 0; /* line number */
  char *ptr, *ptr1;

  /* parse /etc/<xyz>-release file */
  while (fgets(buf, sizeof(buf), fp))
    {
      /* remove trailing \n */
      int l = strlen(buf);
      if (l && buf[l - 1] == '\n')
	buf[--l] = 0;
      ++lnum;

      if (lnum == 1)
	{
	  /* 1st line, <name> [(<arch>)] */
	  ptr = strchr(buf, '(');
	  if (ptr)
	    {
	      ptr1 = ptr - 1;
	      *ptr++ = 0;
	    }
	  else
	    ptr1 = buf + l - 1;

	  /* track back until non-blank, non-digit */
	  while (ptr1 > buf
		 && (*ptr1 == ' ' || isdigit(*ptr1) || *ptr1 == '.'))
	    --ptr1;
	  *(++ptr1) = 0;
	  name = pool_str2id(pool, join2("product", ":", buf), 1);

	  if (ptr)
	    {
	      /* have arch */
	      char *ptr1 = strchr(ptr, ')');
	      if (ptr1)
		{
		  *ptr1 = 0;
		  /* downcase arch */
		  ptr1 = ptr;
		  while (*ptr1)
		    {
		      if (isupper(*ptr1))
			 *ptr1 = tolower(*ptr1);
		      ++ptr1;
		    }
		  arch = pool_str2id(pool, ptr, 1);
		}
	    }
	}
      else if (strncmp(buf, "VERSION", 7) == 0)
	{
	  ptr = strchr(buf + 7, '=');
	  if (ptr)
	    {
	      while (*++ptr == ' ')
		;
	      version = makeevr(pool, ptr);
	    }
	}
    }
  if (name)
    {
      Solvable *s = pool_id2solvable(pool, repo_add_solvable(repo));
      s->name = name;
      s->evr = version ? version : ID_EMPTY;
      s->arch = arch ? arch : ARCH_NOARCH;
      if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
	s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
    }
}
Beispiel #25
0
static unsigned int
adddep(Pool *pool, Parsedata *pd, unsigned int olddeps, const char **atts, Id marker)
{
  Id id, name;
  const char *n, *f, *k;
  const char **a;

  n = f = k = NULL;

  /* loop over name,value pairs */
  for (a = atts; *a; a += 2)
    {
      if (!strcmp(*a, "name"))
	n = a[1];
      if (!strcmp(*a, "kind"))
	k = a[1];
      else if (!strcmp(*a, "op"))
	f = a[1];
      else if (marker && !strcmp(*a, "pre") && a[1][0] == '1')
        marker = SOLVABLE_PREREQMARKER;
    }
  if (!n)			       /* quit if no name found */
    return olddeps;

  /* kind, name */
  if (k && !strcmp(k, "package"))
    k = NULL;			       /* package is default */

  if (k)			       /* if kind!=package, intern <kind>:<name> */
    {
      int l = strlen(k) + 1 + strlen(n) + 1;
      if (l > pd->acontent)	       /* extend buffer if needed */
	{
	  pd->content = (char *)realloc(pd->content, l + 256);
	  pd->acontent = l + 256;
	}
      sprintf(pd->content, "%s:%s", k, n);
      name = pool_str2id(pool, pd->content, 1);
    }
  else
    {
      name = pool_str2id(pool, n, 1);       /* package: just intern <name> */
    }

  if (f)			       /* operator ? */
    {
      /* intern e:v-r */
      Id evr = evr_atts2id(pool, pd, atts);
      /* parser operator to flags */
      int flags;
      for (flags = 0; flags < sizeof(flagtab)/sizeof(*flagtab); flags++)
	if (!strcmp(f, flagtab[flags].from))
	  {
	    flags = flagtab[flags].to;
	    break;
	  }
      if (flags > 7)
	flags = 0;
      /* intern rel */
      id = pool_rel2id(pool, name, evr, flags, 1);
    }
  else
    id = name;			       /* no operator */

  /* add new dependency to repo */
  return repo_addid_dep(pd->repo, olddeps, id, marker);
}
Beispiel #26
0
static void XMLCALL
endElement(void *userData, const char *name)
{
  //fprintf(stderr,"-tag: %s\n", name);
  struct parsedata *pd = userData;
  Pool *pool = pd->common.pool;
  Solvable *s = pd->solvable;
  Repo *repo = pd->common.repo;
  Id handle = pd->handle;
  Id id;
  char *p;

  if (pd->depth != pd->statedepth)
    {
      pd->depth--;
      // printf("back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth);
      return;
    }

  /* ignore patterns & metadata */
  if (pd->state == STATE_START && !strcmp(name, "patterns"))
    return;
  if (pd->state == STATE_START && !strcmp(name, "products"))
    return;
  //if (pd->state == STATE_START && !strcmp(name, "metadata"))
  //  return;
  if (pd->state == STATE_SOLVABLE && !strcmp(name, "format"))
    return;

  pd->depth--;
  pd->statedepth--;
  switch (pd->state)
    {
    case STATE_SOLVABLE:
      if (pd->kind && !s->name) /* add namespace in case of NULL name */
        s->name = pool_str2id(pool, join2(pd->kind, ":", ""), 1);
      if (!s->arch)
        s->arch = ARCH_NOARCH;
      if (!s->evr)
        s->evr = ID_EMPTY;	/* some patterns have this */
      if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
        s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
      s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, pd->freshens);
      s->conflicts = repo_fix_conflicts(repo, s->conflicts);
      pd->freshens = 0;
      pd->kind = 0;
      break;
    case STATE_NAME:
      if (pd->kind)
        s->name = pool_str2id(pool, join2(pd->kind, ":", pd->content), 1);
      else
        s->name = pool_str2id(pool, pd->content, 1);
      break;
    case STATE_ARCH:
      s->arch = pool_str2id(pool, pd->content, 1);
      break;
    case STATE_VENDOR:
      s->vendor = pool_str2id(pool, pd->content, 1);
      break;
    case STATE_RPM_GROUP:
      repodata_set_poolstr(pd->data, handle, SOLVABLE_GROUP, pd->content);
      break;
    case STATE_RPM_LICENSE:
      repodata_set_poolstr(pd->data, handle, SOLVABLE_LICENSE, pd->content);
      break;
    case STATE_CHECKSUM:
      {
        Id type, index;
	type = solv_chksum_str2type(pd->tmpattr);
	if (!type)
	  {
            fprintf(stderr, "Unknown checksum type: %d: %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr);
            exit(1);
	  }
        if (strlen(pd->content) != 2 * solv_chksum_len(type))
          {
            fprintf(stderr, "Invalid checksum length: %d: for %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr);
            exit(1);
          }
        repodata_set_checksum(pd->data, handle, SOLVABLE_CHECKSUM, type, pd->content);
        /* we save the checksum to solvable id relationship for extended
           metadata */
        index = stringpool_str2id(&pd->cspool, pd->content, 1 /* create it */);
        if (index >= pd->ncscache)
          {
            pd->cscache = solv_zextend(pd->cscache, pd->ncscache, index + 1 - pd->ncscache, sizeof(Id), 255);
            pd->ncscache = index + 1;
          }
        /* add the checksum to the cache */
        pd->cscache[index] = s - pool->solvables;
        break;
      }
    case STATE_FILE:
#if 0
      id = pool_str2id(pool, pd->content, 1);
      s->provides = repo_addid_dep(repo, s->provides, id, SOLVABLE_FILEMARKER);
#endif
      if ((p = strrchr(pd->content, '/')) != 0)
	{
	  *p++ = 0;
	  if (pd->lastdir && !strcmp(pd->lastdirstr, pd->content))
	    {
	      id = pd->lastdir;
	    }
	  else
	    {
	      int l;
	      id = repodata_str2dir(pd->data, pd->content, 1);
	      l = strlen(pd->content) + 1;
	      if (l > pd->lastdirstrl)
		{
		  pd->lastdirstrl = l + 128;
		  pd->lastdirstr = solv_realloc(pd->lastdirstr, pd->lastdirstrl);
		}
	      strcpy(pd->lastdirstr, pd->content);
	      pd->lastdir = id;
	    }
	}
      else
	{
	  p = pd->content;
	  id = 0;
	}
      if (!id)
	id = repodata_str2dir(pd->data, "/", 1);
      repodata_add_dirstr(pd->data, handle, SOLVABLE_FILELIST, id, p);
      break;
    case STATE_SUMMARY:
      repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_SUMMARY, pd->tmplang), pd->content);
      break;
    case STATE_DESCRIPTION:
      set_description_author(pd->data, handle, pd->content, pd);
      break;
    case STATE_CATEGORY:
      repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_CATEGORY, pd->tmplang), pd->content);
      break;
    case STATE_DISTRIBUTION:
        repodata_set_poolstr(pd->data, handle, SOLVABLE_DISTRIBUTION, pd->content);
        break;
    case STATE_URL:
      if (pd->content[0])
	repodata_set_str(pd->data, handle, SOLVABLE_URL, pd->content);
      break;
    case STATE_PACKAGER:
      if (pd->content[0])
	repodata_set_poolstr(pd->data, handle, SOLVABLE_PACKAGER, pd->content);
      break;
    case STATE_SOURCERPM:
      set_sourcerpm(pd->data, s, handle, pd->content);
      break;
    case STATE_RELNOTESURL:
      if (pd->content[0])
        {
          repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
          repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, pool_str2id(pool, "releasenotes", 1));
        }
      break;
    case STATE_UPDATEURL:
      if (pd->content[0])
        {
          repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
          repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, pool_str2id(pool, "update", 1));
        }
      break;
    case STATE_OPTIONALURL:
      if (pd->content[0])
        {
          repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
          repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, pool_str2id(pool, "optional", 1));
        }
      break;
    case STATE_FLAG:
      if (pd->content[0])
          repodata_set_poolstr(pd->data, handle, PRODUCT_FLAGS, pd->content);
      break;
    case STATE_EULA:
      if (pd->content[0])
	repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_EULA, pd->tmplang), pd->content);
      break;
    case STATE_KEYWORD:
      if (pd->content[0])
        repodata_add_poolstr_array(pd->data, pd->handle, SOLVABLE_KEYWORDS, pd->content);
      break;
    case STATE_DISKUSAGE:
      if (pd->ndirs)
        commit_diskusage(pd, pd->handle);
      break;
    case STATE_ORDER:
      if (pd->content[0])
        repodata_set_str(pd->data, pd->handle, SOLVABLE_ORDER, pd->content);
    default:
      break;
    }
  pd->state = pd->sbtab[pd->state];
  pd->docontent = 0;
  // fprintf(stderr, "back from known %d %d %d\n", pd->state, pd->depth, pd->statedepth);
}
Beispiel #27
0
/* warning: does inplace changes */
static void
control2solvable(Solvable *s, Repodata *data, char *control)
{
  Repo *repo = s->repo;
  Pool *pool = repo->pool;
  char *p, *q, *end, *tag;
  int x, l;
  int havesource = 0;
  char checksum[32 * 2 + 1];
  Id checksumtype = 0;
  Id newtype;

  p = control;
  while (*p)
    {
      p = strchr(p, '\n');
      if (!p)
	break;
      if (p[1] == ' ' || p[1] == '\t')
	{
	  char *q;
	  /* continuation line */
	  q = p - 1;
	  while (q >= control && *q == ' ' && *q == '\t')
	    q--;
	  l = q + 1 - control;
	  if (l)
	    memmove(p + 1 - l, control, l);
	  control = p + 1 - l;
	  p[1] = '\n';
	  p += 2;
	  continue;
	}
      end = p - 1;
      if (*p)
        *p++ = 0;
      /* strip trailing space */
      while (end >= control && (*end == ' ' || *end == '\t'))
	*end-- = 0;
      tag = control;
      control = p;
      q = strchr(tag, ':');
      if (!q || q - tag < 4)
	continue;
      *q++ = 0;
      while (*q == ' ' || *q == '\t')
	q++;
      x = '@' + (tag[0] & 0x1f);
      x = (x << 8) + '@' + (tag[1] & 0x1f);
      switch(x)
	{
	case 'A' << 8 | 'R':
	  if (!strcasecmp(tag, "architecture"))
	    s->arch = pool_str2id(pool, q, 1);
	  break;
	case 'B' << 8 | 'R':
	  if (!strcasecmp(tag, "breaks"))
	    s->conflicts = makedeps(repo, q, s->conflicts, 0);
	  break;
	case 'C' << 8 | 'O':
	  if (!strcasecmp(tag, "conflicts"))
	    s->conflicts = makedeps(repo, q, s->conflicts, 0);
	  break;
	case 'D' << 8 | 'E':
	  if (!strcasecmp(tag, "depends"))
	    s->requires = makedeps(repo, q, s->requires, -SOLVABLE_PREREQMARKER);
	  else if (!strcasecmp(tag, "description"))
	    {
	      char *ld = strchr(q, '\n');
	      if (ld)
		{
		  *ld++ = 0;
	          repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, ld);
		}
	      else
	        repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, q);
	      repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, q);
	    }
	  break;
	case 'E' << 8 | 'N':
	  if (!strcasecmp(tag, "enhances"))
	    s->enhances = makedeps(repo, q, s->enhances, 0);
	  break;
	case 'F' << 8 | 'I':
	  if (!strcasecmp(tag, "filename"))
	    repodata_set_location(data, s - pool->solvables, 0, 0, q);
	  break;
	case 'H' << 8 | 'O':
	  if (!strcasecmp(tag, "homepage"))
	    repodata_set_str(data, s - pool->solvables, SOLVABLE_URL, q);
	  break;
	case 'I' << 8 | 'N':
	  if (!strcasecmp(tag, "installed-size"))
	    repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(q, 0, 10) << 10);
	  break;
	case 'M' << 8 | 'D':
	  if (!strcasecmp(tag, "md5sum") && !checksumtype && strlen(q) == 16 * 2)
	    {
	      strcpy(checksum, q);
	      checksumtype = REPOKEY_TYPE_MD5;
	    }
	  break;
	case 'P' << 8 | 'A':
	  if (!strcasecmp(tag, "package"))
	    s->name = pool_str2id(pool, q, 1);
	  break;
	case 'P' << 8 | 'R':
	  if (!strcasecmp(tag, "pre-depends"))
	    s->requires = makedeps(repo, q, s->requires, SOLVABLE_PREREQMARKER);
	  else if (!strcasecmp(tag, "provides"))
	    s->provides = makedeps(repo, q, s->provides, 0);
	  break;
	case 'R' << 8 | 'E':
	  if (!strcasecmp(tag, "replaces"))
	    s->obsoletes = makedeps(repo, q, s->obsoletes, 0);
	  else if (!strcasecmp(tag, "recommends"))
	    s->recommends = makedeps(repo, q, s->recommends, 0);
	  break;
	case 'S' << 8 | 'H':
	  newtype = solv_chksum_str2type(tag);
	  if (!newtype || solv_chksum_len(newtype) * 2 != strlen(q))
	    break;
	  if (!checksumtype || (newtype == REPOKEY_TYPE_SHA1 && checksumtype != REPOKEY_TYPE_SHA256) || newtype == REPOKEY_TYPE_SHA256)
	    {
	      strcpy(checksum, q);
	      checksumtype = newtype;
	    }
	  break;
	case 'S' << 8 | 'O':
	  if (!strcasecmp(tag, "source"))
	    {
	      char *q2;
	      /* ignore version for now */
	      for (q2 = q; *q2; q2++)
		if (*q2 == ' ' || *q2 == '\t')
		  {
		    *q2 = 0;
		    break;
		  }
	      if (s->name && !strcmp(q, pool_id2str(pool, s->name)))
		repodata_set_void(data, s - pool->solvables, SOLVABLE_SOURCENAME);
	      else
		repodata_set_id(data, s - pool->solvables, SOLVABLE_SOURCENAME, pool_str2id(pool, q, 1));
	      havesource = 1;
	    }
	  break;
	case 'S' << 8 | 'T':
	  if (!strcasecmp(tag, "status"))
	    repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_INSTALLSTATUS, q);
	  break;
	case 'S' << 8 | 'U':
	  if (!strcasecmp(tag, "suggests"))
	    s->suggests = makedeps(repo, q, s->suggests, 0);
	  break;
	case 'V' << 8 | 'E':
	  if (!strcasecmp(tag, "version"))
	    s->evr = pool_str2id(pool, q, 1);
	  break;
	}
    }
  if (checksumtype)
    repodata_set_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, checksumtype, checksum);
  if (!s->arch)
    s->arch = ARCH_ALL;
  if (!s->evr)
    s->evr = ID_EMPTY;
  if (s->name)
    s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
  if (s->name && !havesource)
    repodata_set_void(data, s - pool->solvables, SOLVABLE_SOURCENAME);
  if (s->obsoletes)
    {
      /* obsoletes only count when the packages also conflict */
      /* XXX: should not transcode here */
      int i, j, k;
      Id d, cid;
      for (i = j = s->obsoletes; (d = repo->idarraydata[i]) != 0; i++)
	{
	  if (!s->conflicts)
	    continue;
	  for (k = s->conflicts; (cid = repo->idarraydata[k]) != 0; k++)
	    {
	      if (repo->idarraydata[k] == cid)
		break;
	      if (ISRELDEP(cid))
		{
		  Reldep *rd = GETRELDEP(pool, cid);
		  if (rd->flags < 8 && rd->name == d)
		    break;	/* specialize obsoletes */
		}
	    }
	  if (cid)
	    repo->idarraydata[j++] = cid;
	}
      repo->idarraydata[j] = 0;
      if (j == s->obsoletes)
	s->obsoletes = 0;
    }
}
Beispiel #28
0
Offset
repo_fix_supplements(Repo *repo, Offset provides, Offset supplements, Offset freshens)
{
  Pool *pool = repo->pool;
  Id id, idp, idl;
  char buf[1024], *p, *dep;
  int i, l;

  if (provides)
    {
      for (i = provides; repo->idarraydata[i]; i++)
	{
	  id = repo->idarraydata[i];
	  if (ISRELDEP(id))
	    continue;
	  dep = (char *)pool_id2str(pool, id);
	  if (!strncmp(dep, "locale(", 7) && strlen(dep) < sizeof(buf) - 2)
	    {
	      idp = 0;
	      strcpy(buf + 2, dep);
	      dep = buf + 2 + 7;
	      if ((p = strchr(dep, ':')) != 0 && p != dep)
		{
		  *p++ = 0;
		  idp = pool_str2id(pool, dep, 1);
		  dep = p;
		}
	      id = 0;
	      while ((p = strchr(dep, ';')) != 0)
		{
		  if (p == dep)
		    {
		      dep = p + 1;
		      continue;
		    }
		  *p++ = 0;
		  idl = pool_str2id(pool, dep, 1);
		  idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
		  if (id)
		    id = pool_rel2id(pool, id, idl, REL_OR, 1);
		  else
		    id = idl;
		  dep = p;
		}
	      if (dep[0] && dep[1])
		{
	 	  for (p = dep; *p && *p != ')'; p++)
		    ;
		  *p = 0;
		  idl = pool_str2id(pool, dep, 1);
		  idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
		  if (id)
		    id = pool_rel2id(pool, id, idl, REL_OR, 1);
		  else
		    id = idl;
		}
	      if (idp)
		id = pool_rel2id(pool, idp, id, REL_AND, 1);
	      if (id)
		supplements = repo_addid_dep(repo, supplements, id, 0);
	    }
	  else if ((p = strchr(dep, ':')) != 0 && p != dep && p[1] == '/' && strlen(dep) < sizeof(buf))
	    {
	      strcpy(buf, dep);
	      p = buf + (p - dep);
	      *p++ = 0;
	      idp = pool_str2id(pool, buf, 1);
	      /* strip trailing slashes */
	      l = strlen(p);
	      while (l > 1 && p[l - 1] == '/')
		p[--l] = 0;
	      id = pool_str2id(pool, p, 1);
	      id = pool_rel2id(pool, idp, id, REL_WITH, 1);
	      id = pool_rel2id(pool, NAMESPACE_SPLITPROVIDES, id, REL_NAMESPACE, 1);
	      supplements = repo_addid_dep(repo, supplements, id, 0);
	    }
	}
    }
  if (supplements)
    {
      for (i = supplements; repo->idarraydata[i]; i++)
	{
	  id = repo->idarraydata[i];
	  if (ISRELDEP(id))
	    continue;
	  dep = (char *)pool_id2str(pool, id);
	  if (!strncmp(dep, "system:modalias(", 16))
	    dep += 7;
	  if (!strncmp(dep, "modalias(", 9) && dep[9] && dep[10] && strlen(dep) < sizeof(buf))
	    {
	      strcpy(buf, dep);
	      p = strchr(buf + 9, ':');
	      if (p && p != buf + 9 && strchr(p + 1, ':'))
		{
		  *p++ = 0;
		  idp = pool_str2id(pool, buf + 9, 1);
		  p[strlen(p) - 1] = 0;
		  id = pool_str2id(pool, p, 1);
		  id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
		  id = pool_rel2id(pool, idp, id, REL_AND, 1);
		}
	      else
		{
		  p = buf + 9;
		  p[strlen(p) - 1] = 0;
		  id = pool_str2id(pool, p, 1);
		  id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
		}
	      if (id)
		repo->idarraydata[i] = id;
	    }
	  else if (!strncmp(dep, "packageand(", 11) && strlen(dep) < sizeof(buf))
	    {
	      strcpy(buf, dep);
	      id = 0;
	      dep = buf + 11;
	      while ((p = strchr(dep, ':')) != 0)
		{
		  if (p == dep)
		    {
		      dep = p + 1;
		      continue;
		    }
		  *p++ = 0;
		  idp = pool_str2id(pool, dep, 1);
		  if (id)
		    id = pool_rel2id(pool, id, idp, REL_AND, 1);
		  else
		    id = idp;
		  dep = p;
		}
	      if (dep[0] && dep[1])
		{
		  dep[strlen(dep) - 1] = 0;
		  idp = pool_str2id(pool, dep, 1);
		  if (id)
		    id = pool_rel2id(pool, id, idp, REL_AND, 1);
		  else
		    id = idp;
		}
	      if (id)
		repo->idarraydata[i] = id;
	    }
	  else if (!strncmp(dep, "filesystem(", 11) && strlen(dep) < sizeof(buf))
	    {
	      strcpy(buf, dep + 11);
	      if ((p = strrchr(buf, ')')) != 0)
		*p = 0;
	      id = pool_str2id(pool, buf, 1);
	      id = pool_rel2id(pool, NAMESPACE_FILESYSTEM, id, REL_NAMESPACE, 1);
	      repo->idarraydata[i] = id;
	    }
	}
    }
  if (freshens && repo->idarraydata[freshens])
    {
      Id idsupp = 0, idfresh = 0;
      if (!supplements || !repo->idarraydata[supplements])
	return freshens;
      for (i = supplements; repo->idarraydata[i]; i++)
        {
	  if (!idsupp)
	    idsupp = repo->idarraydata[i];
	  else
	    idsupp = pool_rel2id(pool, idsupp, repo->idarraydata[i], REL_OR, 1);
        }
      for (i = freshens; repo->idarraydata[i]; i++)
        {
	  if (!idfresh)
	    idfresh = repo->idarraydata[i];
	  else
	    idfresh = pool_rel2id(pool, idfresh, repo->idarraydata[i], REL_OR, 1);
        }
      if (!idsupp)
        idsupp = idfresh;
      else
	idsupp = pool_rel2id(pool, idsupp, idfresh, REL_AND, 1);
      supplements = repo_addid_dep(repo, 0, idsupp, 0);
    }
  return supplements;
}
Beispiel #29
0
int
repo_add_content(Repo *repo, FILE *fp, int flags)
{
  Pool *pool = repo->pool;
  char *line, *linep;
  int aline;
  Solvable *s;
  struct parsedata pd;
  Repodata *data;
  Id handle = 0;
  int contentstyle = 0;
  char *descrdir = 0;
  char *datadir = 0;
  char *defvendor = 0;

  int i = 0;
  int res = 0;

  /* architectures
     we use the first architecture in BASEARCHS or noarch
     for the product. At the end we create (clone) the product
     for each one of the remaining architectures
     we allow max 4 archs
  */
  unsigned int numotherarchs = 0;
  Id *otherarchs = 0;

  memset(&pd, 0, sizeof(pd));
  line = solv_malloc(1024);
  aline = 1024;

  pd.repo = repo;
  linep = line;
  s = 0;

  data = repo_add_repodata(repo, flags);

  for (;;)
    {
      char *key, *value;

      /* read line into big-enough buffer */
      if (linep - line + 16 > aline)
	{
	  aline = linep - line;
	  line = solv_realloc(line, aline + 512);
	  linep = line + aline;
	  aline += 512;
	}
      if (!fgets(linep, aline - (linep - line), fp))
	break;
      linep += strlen(linep);
      if (linep == line || linep[-1] != '\n')
        continue;
      while ( --linep > line && ( linep[-1] == ' ' ||  linep[-1] == '\t' ) )
        ; /* skip trailing ws */
      *linep = 0;
      linep = line;

      /* expect "key value" lines */
      value = line;
      key = splitword(&value);

      if (key)
        {
#if 0
	  fprintf (stderr, "key %s, value %s\n", key, value);
#endif

#define istag(x) (!strcmp (key, x))
#define code10 (contentstyle == 10)
#define code11 (contentstyle == 11)


	  if (istag ("CONTENTSTYLE"))
	    {
	      if (contentstyle)
	        pool_debug(pool, SOLV_ERROR, "repo_content: 'CONTENTSTYLE' must be first line of 'content'\n");
	      contentstyle = atoi(value);
	      continue;
	    }
	  if (!contentstyle)
	    contentstyle = 10;

	  /* repository tags */
          /* we also replicate some of them into the product solvables
           * to be backward compatible */

	  if (istag ("REPOID"))
	    {
	      repodata_add_poolstr_array(data, SOLVID_META, REPOSITORY_REPOID, value);
	      continue;
	    }
	  if (istag ("REPOKEYWORDS"))
	    {
	      add_multiple_strings(data, SOLVID_META, REPOSITORY_KEYWORDS, value);
	      continue;
	    }
	  if (istag ("DISTRO"))
	    {
	      Id dh = repodata_new_handle(data);
	      char *p;
	      /* like with createrepo --distro */
	      if ((p = strchr(value, ',')) != 0)
		{
		  *p++ = 0;
		  if (*value)
		    repodata_set_poolstr(data, dh, REPOSITORY_PRODUCT_CPEID, value);
		}
	      else
	        p = value;
	      if (*p)
		repodata_set_str(data, dh, REPOSITORY_PRODUCT_LABEL, p);
	      repodata_add_flexarray(data, SOLVID_META, REPOSITORY_DISTROS, dh);
	      continue;
	    }

	  if (istag ("DESCRDIR"))
	    {
	      if (descrdir)
		free(descrdir);
	      else
	        repodata_set_str(data, SOLVID_META, SUSETAGS_DESCRDIR, value);
	      if (s)
	        repodata_set_str(data, s - pool->solvables, SUSETAGS_DESCRDIR, value);
	      descrdir = solv_strdup(value);
	      continue;
	    }
	  if (istag ("DATADIR"))
	    {
	      if (datadir)
		free(datadir);
	      else
	        repodata_set_str(data, SOLVID_META, SUSETAGS_DATADIR, value);
	      if (s)
	        repodata_set_str(data, s - pool->solvables, SUSETAGS_DATADIR, value);
	      datadir = solv_strdup(value);
	      continue;
	    }
	  if (istag ("VENDOR"))
	    {
	      if (defvendor)
		free(defvendor);
	      else
	        repodata_set_poolstr(data, SOLVID_META, SUSETAGS_DEFAULTVENDOR, value);
	      if (s)
		s->vendor = pool_str2id(pool, value, 1);
	      defvendor = solv_strdup(value);
	      continue;
	    }

	  if (istag ("META") || istag ("HASH") || istag ("KEY"))
	    {
	      char *checksumtype, *checksum;
	      Id fh, type;
	      int l;

	      if ((checksumtype = splitword(&value)) == 0)
		continue;
	      if ((checksum = splitword(&value)) == 0)
		continue;
	      if (!*value)
		continue;
	      type = solv_chksum_str2type(checksumtype);
	      if (!type)
		{
		  pool_error(pool, -1, "%s: unknown checksum type '%s'", value, checksumtype);
		  res = 1;
		  continue;
		}
              l = solv_chksum_len(type);
	      if (strlen(checksum) != 2 * l)
	        {
		  pool_error(pool, -1, "%s: invalid checksum length for %s", value, checksumtype);
		  res = 1;
		  continue;
	        }
	      fh = repodata_new_handle(data);
	      repodata_set_poolstr(data, fh, SUSETAGS_FILE_TYPE, key);
	      repodata_set_str(data, fh, SUSETAGS_FILE_NAME, value);
	      repodata_set_checksum(data, fh, SUSETAGS_FILE_CHECKSUM, type, checksum);
	      repodata_add_flexarray(data, SOLVID_META, SUSETAGS_FILE, fh);
	      continue;
	    }

	  /* product tags */

	  if ((code10 && istag ("PRODUCT"))
	      || (code11 && istag ("NAME")))
	    {
	      if (s && !s->name)
		{
		  /* this solvable was created without seeing a
		     PRODUCT entry, just set the name and continue */
		  s->name = pool_str2id(pool, join(&pd, "product", ":", value), 1);
		  continue;
		}
	      if (s)
		{
		  /* finish old solvable */
		  if (!s->arch)
		    s->arch = ARCH_NOARCH;
		  if (!s->evr)
		    s->evr = ID_EMPTY;
		  if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
		    s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
		  if (code10)
		    s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
		}
	      /* create new solvable */
	      s = pool_id2solvable(pool, repo_add_solvable(repo));
	      handle = s - pool->solvables;
	      s->name = pool_str2id(pool, join(&pd, "product", ":", value), 1);
	      if (datadir)
	        repodata_set_str(data, s - pool->solvables, SUSETAGS_DATADIR, datadir);
	      if (descrdir)
	        repodata_set_str(data, s - pool->solvables, SUSETAGS_DESCRDIR, descrdir);
	      if (defvendor)
		s->vendor = pool_str2id(pool, defvendor, 1);
	      continue;
	    }

	  /* Sometimes PRODUCT/NAME is not the first entry, but we need a solvable
	     from here on.  */
	  if (!s)
	    {
	      s = pool_id2solvable(pool, repo_add_solvable(repo));
	      handle = s - pool->solvables;
	    }

	  if (istag ("VERSION"))
            pd.tmpvers = solv_strdup(value);
          else if (istag ("RELEASE"))
            pd.tmprel = solv_strdup(value);
	  else if (code11 && istag ("DISTRIBUTION"))
	    repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_DISTRIBUTION, value);
	  else if (istag ("UPDATEURLS"))
	    add_multiple_urls(data, handle, value, pool_str2id(pool, "update", 1));
	  else if (istag ("EXTRAURLS"))
	    add_multiple_urls(data, handle, value, pool_str2id(pool, "extra", 1));
	  else if (istag ("OPTIONALURLS"))
	    add_multiple_urls(data, handle, value, pool_str2id(pool, "optional", 1));
	  else if (istag ("RELNOTESURL"))
	    add_multiple_urls(data, handle, value, pool_str2id(pool, "releasenotes", 1));
	  else if (istag ("SHORTLABEL"))
	    repodata_set_str(data, s - pool->solvables, PRODUCT_SHORTLABEL, value);
	  else if (istag ("LABEL")) /* LABEL is the products SUMMARY. */
	    repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, value);
	  else if (!strncmp (key, "LABEL.", 6))
	    repodata_set_str(data, s - pool->solvables, pool_id2langid(pool, SOLVABLE_SUMMARY, key + 6, 1), value);
	  else if (istag ("FLAGS"))
	    add_multiple_strings(data, handle, PRODUCT_FLAGS, value);
	  else if (istag ("VENDOR"))	/* actually already handled above */
	    s->vendor = pool_str2id(pool, value, 1);
          else if (istag ("BASEARCHS"))
            {
              char *arch;

	      if ((arch = splitword(&value)) != 0)
		{
		  s->arch = pool_str2id(pool, arch, 1);
		  while ((arch = splitword(&value)) != 0)
		    {
		       otherarchs = solv_extend(otherarchs, numotherarchs, 1, sizeof(Id), 7);
		       otherarchs[numotherarchs++] = pool_str2id(pool, arch, 1);
		    }
		}
            }
	  if (!code10)
	    continue;

	  /*
	   * Every tag below is Code10 only
	   *
	   */

	  if (istag ("ARCH"))
	    /* Theoretically we want to have the best arch of the given
	       modifiers which still is compatible with the system
	       arch.  We don't know the latter here, though.  */
	    s->arch = ARCH_NOARCH;
	  else if (istag ("PREREQUIRES"))
	    s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER);
	  else if (istag ("REQUIRES"))
	    s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER);
	  else if (istag ("PROVIDES"))
	    s->provides = adddep(pool, &pd, s->provides, value, 0);
	  else if (istag ("CONFLICTS"))
	    s->conflicts = adddep(pool, &pd, s->conflicts, value, 0);
	  else if (istag ("OBSOLETES"))
	    s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0);
	  else if (istag ("RECOMMENDS"))
	    s->recommends = adddep(pool, &pd, s->recommends, value, 0);
	  else if (istag ("SUGGESTS"))
	    s->suggests = adddep(pool, &pd, s->suggests, value, 0);
	  else if (istag ("SUPPLEMENTS"))
	    s->supplements = adddep(pool, &pd, s->supplements, value, 0);
	  else if (istag ("ENHANCES"))
	    s->enhances = adddep(pool, &pd, s->enhances, value, 0);
	  /* FRESHENS doesn't seem to exist.  */
	  else if (istag ("TYPE"))
	    repodata_set_str(data, s - pool->solvables, PRODUCT_TYPE, value);

	  /* XXX do something about LINGUAS and ARCH?
          * <ma>: Don't think so. zypp does not use or propagate them.
          */
#undef istag
	}
      else
	pool_debug(pool, SOLV_ERROR, "repo_content: malformed line: %s\n", line);
    }

  if (datadir)
    free(datadir);
  if (descrdir)
    free(descrdir);
  if (defvendor)
    free(defvendor);

  if (s && !s->name)
    {
      pool_debug(pool, SOLV_ERROR, "repo_content: 'content' incomplete, no product solvable created!\n");
      repo_free_solvable(repo, s - pool->solvables, 1);
      s = 0;
    }
  if (s)
    {
      if (pd.tmprel)
	s->evr = makeevr(pool, join(&pd, pd.tmpvers, "-", pd.tmprel));
      else
	s->evr = makeevr(pool, pd.tmpvers);
      pd.tmpvers = solv_free((void *)pd.tmpvers);
      pd.tmprel = solv_free((void *)pd.tmprel);

      if (!s->arch)
	s->arch = ARCH_NOARCH;
      if (!s->evr)
	s->evr = ID_EMPTY;
      if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
        s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
      if (code10)
	s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);

      /* now for every other arch, clone the product except the architecture */
      for (i = 0; i < numotherarchs; ++i)
	{
	  Solvable *p = pool_id2solvable(pool, repo_add_solvable(repo));
	  p->name = s->name;
	  p->evr = s->evr;
	  p->vendor = s->vendor;
	  p->arch = otherarchs[i];

	  /* self provides */
	  if (s->name && p->arch != ARCH_SRC && p->arch != ARCH_NOSRC)
	      p->provides = repo_addid_dep(repo, p->provides, pool_rel2id(pool, p->name, p->evr, REL_EQ, 1), 0);

	  /* now merge the attributes */
	  repodata_merge_attrs(data, p - pool->solvables, s - pool->solvables);
	}
    }

  if (pd.tmp)
    solv_free(pd.tmp);
  solv_free(line);
  solv_free(otherarchs);
  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  return res;
}
Beispiel #30
0
int
repo_add_cudf(Repo *repo, Repo *installedrepo, FILE *fp, Queue *job, int flags)
{
  Pool *pool = repo->pool;
  char *buf, *p;
  int bufa, bufl, c;
  Solvable *s;
  int instanza = 0;
  int inrequest = 0;
  int isinstalled = 0;
  int keep = 0;
  Repo *xrepo;

  xrepo = repo ? repo : installedrepo;
  if (!xrepo)
    return -1;

  buf = solv_malloc(4096);
  bufa = 4096;
  bufl = 0;
  s = 0;

  while (fgets(buf + bufl, bufa - bufl, fp) > 0)
    {
      bufl += strlen(buf + bufl);
      if (bufl && buf[bufl - 1] != '\n')
	{
	  if (bufa - bufl < 256)
	    {
	      bufa += 4096;
	      buf = solv_realloc(buf, bufa);
	    }
	  continue;
	}
      buf[--bufl] = 0;
      c = getc(fp);
      if (c == ' ' || c == '\t')
	{
	  /* continuation line */
	  buf[bufl++] = ' ';
	  continue;
	}
      if (c != EOF)
	ungetc(c, fp);
      bufl = 0;
      if (*buf == '#')
	continue;
      if (!*buf)
	{
	  if (s && !repo && !isinstalled)
	    {
	      repo_free_solvable(repo, s - pool->solvables, 1);
	      s = 0;
	    }
	  if (s)
	    finishpackage(pool, s, keep, job);
	  s = 0;
	  keep = 0;
	  instanza = 0;
	  inrequest = 0;
	  continue;
	}
      p = strchr(buf, ':');
      if (!p)
	continue;	/* hmm */
      *p++ = 0;
      while (*p == ' ' || *p == '\t')
	p++;
      if (!instanza)
	{
	  instanza = 1;
	  inrequest = 0;
	  if (!strcmp(buf, "request"))
	    {
	      inrequest = 1;
	      continue;
	    }
	  if (!strcmp(buf, "package"))
	    {
	      s = pool_id2solvable(pool, repo_add_solvable(xrepo));
	      isinstalled = 0;
	      keep = 0;
	    }
	}
      if (inrequest)
	{
	  if (!job)
	    continue;
	  if (!strcmp(buf, "install"))
	    {
	      Id id, *idp;
	      Offset off = makedeps(xrepo, p, 0, 0);
	      for (idp = xrepo->idarraydata + off; (id = *idp) != 0; idp++)
		queue_push2(job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES, id);
	    }
	  else if (!strcmp(buf, "remove"))
	    {
	      Id id, *idp;
	      Offset off = makedeps(xrepo, p, 0, 0);
	      for (idp = xrepo->idarraydata + off; (id = *idp) != 0; idp++)
		queue_push2(job, SOLVER_ERASE|SOLVER_SOLVABLE_PROVIDES, id);
	    }
	  else if (!strcmp(buf, "upgrade"))
	    {
	      Id id, *idp;
	      Offset off = makedeps(xrepo, p, 0, 0);
	      for (idp = xrepo->idarraydata + off; (id = *idp) != 0; idp++)
		queue_push2(job, SOLVER_INSTALL|SOLVER_ORUPDATE|SOLVER_SOLVABLE_PROVIDES, id);
	    }
	  continue;
	}
      if (!s)
	continue;	/* we ignore the preamble for now */
      switch (buf[0])
	{
	case 'c':
	  if (!strcmp(buf, "conflicts"))
	    {
	      s->conflicts = makedeps(s->repo, p, s->conflicts, 0);
	      continue;
	    }
	case 'd':
	  if (!strcmp(buf, "depends"))
	    {
	      s->requires = makedeps(s->repo, p, s->requires, 0);
	      continue;
	    }
	  break;
	case 'k':
	  if (!strcmp(buf, "keep"))
	    {
	      if (!job)
		continue;
	      if (!strcmp(p, "version"))
		keep = KEEP_VERSION;
	      else if (!strcmp(p, "package"))
		keep = KEEP_PACKAGE;
	      else if (!strcmp(p, "feature"))
		keep = KEEP_FEATURE;
	      continue;
	    }
	  break;
	case 'i':
	  if (!strcmp(buf, "installed"))
	    {
	      if (!strcmp(p, "true"))
		{
		  isinstalled = 1;
		  if (!installedrepo)
		    {
		      repo_free_solvable(repo, s - pool->solvables, 1);
		      s = 0;
		    }
		  else if (s->repo != installedrepo)
		    {
		      copysolvabledata(pool, s, installedrepo);
		      s->repo->nsolvables--;
		      s->repo = installedrepo;
		      if (s - pool->solvables < s->repo->start)
			s->repo->start = s - pool->solvables;
		      if (s - pool->solvables >= s->repo->end)
			s->repo->end = s - pool->solvables + 1;
		      s->repo->nsolvables++;
		    }
		}
	      continue;
	    }
	  break;
	case 'p':
	  if (!strcmp(buf, "package"))
	    {
	      s->name = pool_str2id(pool, p, 1);
	      continue;
	    }
	  if (!strcmp(buf, "provides"))
	    {
	      s->provides = makedeps(s->repo, p, s->provides, 0);
	      continue;
	    }
	  break;
	case 'r':
	  if (!strcmp(buf, "depends"))
	    {
	      s->recommends = makedeps(s->repo, p, s->recommends, 0);
	      continue;
	    }
	  break;
	case 'v':
	  if (!strcmp(buf, "version"))
	    {
	      s->evr = pool_str2id(pool, p, 1);
	      continue;
	    }
	  break;
	}
    }
  if (s && !repo && !isinstalled)
    {
      repo_free_solvable(repo, s - pool->solvables, 1);
      s = 0;
    }
  if (s)
    finishpackage(pool, s, keep, job);
  solv_free(buf);
  return 0;
}