Пример #1
0
static Id
langtag(struct parsedata *pd, Id tag, const char *language)
{
  if (language && !language[0])
    language = 0;
  if (!language || tag >= ID_NUM_INTERNAL)
    return pool_id2langid(pd->repo->pool, tag, language, 1);
  if (!pd->langcache[tag])
    pd->langcache[tag] = pool_id2langid(pd->repo->pool, tag, language, 1);
  return pd->langcache[tag];
}
Пример #2
0
static Id
langtag(struct parsedata *pd, Id tag, const char *language)
{
  if (!language)	/* fall back to default if not specified */
    language = pd->language;
  if (language && (!language[0] || !strcmp(language, "en")))
    language = 0;
  if (!language || tag >= ID_NUM_INTERNAL)
    return pool_id2langid(pd->common.repo->pool, tag, language, 1);
  return pool_id2langid(pd->common.repo->pool, tag, language, 1);
  if (!pd->langcache[tag])
    pd->langcache[tag] = pool_id2langid(pd->common.repo->pool, tag, language, 1);
  return pd->langcache[tag];
}
Пример #3
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;
    }
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
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:
      /* product done, finish solvable */
      if (pd->ctime)
        repodata_set_num(pd->data, pd->handle, SOLVABLE_INSTALLTIME, pd->ctime);

      if (pd->basename)
        repodata_set_str(pd->data, pd->handle, PRODUCT_REFERENCEFILE, pd->basename);

      /* this is where <productsdir>/baseproduct points to */
      if (pd->currentproduct == pd->baseproduct)
	repodata_set_str(pd->data, pd->handle, PRODUCT_TYPE, "base");

      if (pd->tmprel)
	{
	  if (pd->tmpvers)
	    s->evr = makeevr(pd->pool, join2(&pd->jd, pd->tmpvers, "-", pd->tmprel));
	  else
	    {
	      fprintf(stderr, "Seen <release> but no <version>\n");
	    }
	}
      else if (pd->tmpvers)
	s->evr = makeevr(pd->pool, pd->tmpvers); /* just version, no release */
      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(pd->repo, s->provides, pool_rel2id(pd->pool, s->name, s->evr, REL_EQ, 1), 0);
      pd->solvable = 0;
      break;
    case STATE_VENDOR:
      s->vendor = pool_str2id(pd->pool, pd->content, 1);
      break;
    case STATE_NAME:
      s->name = pool_str2id(pd->pool, join2(&pd->jd, "product", ":", pd->content), 1);
      break;
    case STATE_VERSION:
      pd->tmpvers = solv_strdup(pd->content);
      break;
    case STATE_RELEASE:
      pd->tmprel = solv_strdup(pd->content);
      break;
    case STATE_ARCH:
      s->arch = pool_str2id(pd->pool, pd->content, 1);
      break;
    case STATE_PRODUCTLINE:
      repodata_set_str(pd->data, pd->handle, PRODUCT_PRODUCTLINE, pd->content);
    break;
    case STATE_UPDATEREPOKEY:
      /** obsolete **/
      break;
    case STATE_SUMMARY:
      repodata_set_str(pd->data, pd->handle, pool_id2langid(pd->pool, SOLVABLE_SUMMARY, pd->tmplang, 1), pd->content);
      break;
    case STATE_SHORTSUMMARY:
      repodata_set_str(pd->data, pd->handle, PRODUCT_SHORTLABEL, pd->content);
      break;
    case STATE_DESCRIPTION:
      repodata_set_str(pd->data, pd->handle, pool_id2langid(pd->pool, SOLVABLE_DESCRIPTION, pd->tmplang, 1), pd->content);
      break;
    case STATE_URL:
      if (pd->urltype)
        {
          repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
          repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, pd->urltype);
        }
      break;
    case STATE_TARGET:
      repodata_set_str(pd->data, pd->handle, PRODUCT_REGISTER_TARGET, pd->content);
      break;
    case STATE_REGRELEASE:
      repodata_set_str(pd->data, pd->handle, PRODUCT_REGISTER_RELEASE, pd->content);
      break;
    case STATE_CPEID:
      if (*pd->content)
        repodata_set_str(pd->data, pd->handle, SOLVABLE_CPEID, 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
}
Пример #7
0
int
repo_add_autopattern(Repo *repo, int flags)
{
  Pool *pool = repo->pool;
  Repodata *data = 0;
  Solvable *s, *s2;
  Queue patq, patq2;
  Queue prdq, prdq2;
  Id p;
  Id pattern_id, product_id;
  Id autopattern_id = 0, autoproduct_id = 0;
  int i, j;

  queue_init(&patq);
  queue_init(&patq2);
  queue_init(&prdq);
  queue_init(&prdq2);

  pattern_id = pool_str2id(pool, "pattern()", 9);
  product_id = pool_str2id(pool, "product()", 9);
  FOR_REPO_SOLVABLES(repo, p, s)
    {
      const char *n = pool_id2str(pool, s->name);
      if (*n == 'p')
	{
	  if (!strncmp("pattern:", n, 8))
	    {
	      queue_push(&patq, p);
	      continue;
	    }
	  else if (!strncmp("product:", n, 8))
	    {
	      queue_push(&prdq, p);
	      continue;
	    }
	}
      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->flags != REL_EQ)
		  continue;
		if (rd->name == pattern_id)
		  {
		    queue_push2(&patq2, p, rd->evr);
		    break;
		  }
		if (rd->name == product_id)
		  {
		    queue_push2(&prdq2, p, rd->evr);
		    break;
		  }
	      }
	}
    }
  for (i = 0; i < patq2.count; i += 2)
    {
      const char *pn = 0;
      char *newname;
      Id name, prv, *prvp;
      const char *str;
      unsigned long long num;

      s = pool->solvables + patq2.elements[i];
      /* construct new name */
      newname = pool_tmpjoin(pool, "pattern:", pool_id2str(pool, patq2.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 < patq.count; j++)
	    {
	      s2 = pool->solvables + patq.elements[j];
	      if (s2->name == name && s2->arch == s->arch && s2->evr == s->evr)
		break;
	    }
	  if (j < patq.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 + patq2.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);
	      if (newname[solv_validutf8(newname)] == 0)
	        repodata_set_str(data, s2 - pool->solvables, langtag, newname);
	      else
		{
		  char *ustr = solv_latin1toutf8(newname);
	          repodata_set_str(data, s2 - pool->solvables, langtag, ustr);
		  solv_free(ustr);
		}
	    }
	  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(&patq);
  queue_free(&patq2);

  if (repo == pool->installed)
    queue_empty(&prdq2);	/* no auto products for installed repos */

  for (i = 0; i < prdq2.count; i += 2)
    {
      const char *pn = 0;
      char *newname;
      Id name, evr = 0, prv, *prvp;
      const char *str;
      unsigned long long num;

      s = pool->solvables + prdq2.elements[i];
      /* construct new name */
      newname = pool_tmpjoin(pool, "product(", pool_id2str(pool, prdq2.elements[i + 1]), ")");
      unescape(newname);
      name = pool_str2id(pool, newname, 0);
      if (!name)
	continue;	/* must have it in provides! */
      prvp = repo->idarraydata + s->provides;
      while ((prv = *prvp++) != 0)            /* go through all provides */
	{
	  if (ISRELDEP(prv))
	    {
	      Reldep *rd = GETRELDEP(pool, prv);
	      if (rd->name == name && rd->flags == REL_EQ)
		{
		  evr = rd->evr;
		  break;
		}
	    }
	}
      if (!prv)
	continue;	/* not found in provides */
      newname = pool_tmpjoin(pool, "product:", pool_id2str(pool, prdq2.elements[i + 1]), 0);
      unescape(newname);
      name = pool_str2id(pool, newname, 0);
      if (name)
	{
	  /* check if we already have that product */
	  for (j = 0; j < prdq.count; j++)
	    {
	      s2 = pool->solvables + prdq.elements[j];
	      if (s2->name == name && s2->arch == s->arch && s2->evr == evr)
		break;
	    }
	  if (j < prdq.count)
	    continue;	/* yes, do not add again */
	}
      /* new product */
      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);
	}
      if ((num = solvable_lookup_num(s, SOLVABLE_INSTALLTIME, 0)) != 0)
	continue;		/* eek, not for installed packages, please! */
      s2 = pool_id2solvable(pool, repo_add_solvable(repo));
      s = pool->solvables + prdq2.elements[i];	/* re-calc pointer */
      s2->name = name;
      s2->arch = s->arch;
      s2->evr = evr;
      s2->vendor = s->vendor;
      /* add link requires */
      s2->requires = repo_addid_dep(repo, s2->requires, prv, 0);
      if (!autoproduct_id)
	autoproduct_id = pool_str2id(pool, "autoproduct()", 1);
      s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, autoproduct_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_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);
      if ((str = solvable_lookup_str(s, SOLVABLE_DISTRIBUTION)) != 0)
	repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DISTRIBUTION, 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("product-", pn, 8) != 0)
	    continue;
	  newname = 0;
	  if (evr)
	    {
	      newname = pool_tmpjoin(pool, pool_id2str(pool, evr), 0, 0);
	      unescape(newname);
	    }
	  if (!strcmp(pn, "product-label()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, PRODUCT_SHORTLABEL, newname);
	  else if (!strcmp(pn, "product-type()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, PRODUCT_TYPE, newname);
	  else if (!strcmp(pn, "product-cpeid()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, SOLVABLE_CPEID, newname);
	  else if (!strcmp(pn, "product-flags()") && evr)
	    repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_FLAGS, newname);
	  else if (!strcmp(pn, "product-updates-repoid()") && evr)
	    repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_UPDATES_REPOID, newname);
	  else if (!strncmp(pn, "product-url(", 12) && evr && pn[12] && pn[13] && strlen(pn + 12) < 32)
	    {
	      char type[34];
	      strcpy(type, pn + 12);
	      type[strlen(type) - 1] = 0;	/* closing ) */
	      repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_URL_TYPE, type);
	      repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_URL, newname);
	    }
	}
    }
  queue_free(&prdq);
  queue_free(&prdq2);

  if (data && !(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  else if (!data && !(flags & REPO_NO_INTERNALIZE))
    repo_internalize(repo);
  return 0;
}