Пример #1
0
static void XMLCALL
startElement(void *userData, const char *name, const char **atts)
{
  //fprintf(stderr,"+tag: %s\n", name);
  struct parsedata *pd = userData;
  Pool *pool = pd->common.pool;
  Solvable *s = pd->solvable;
  struct stateswitch *sw;
  const char *str;
  Id handle = pd->handle;

  // fprintf(stderr, "into %s, from %d, depth %d, statedepth %d\n", name, pd->state, pd->depth, pd->statedepth);

  if (pd->depth != pd->statedepth)
    {
      pd->depth++;
      return;
    }

  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++;
  if (!pd->swtab[pd->state])
    return;
  for (sw = pd->swtab[pd->state]; sw->from == pd->state; sw++)
    if (!strcmp(sw->ename, name))
      break;
  if (sw->from != pd->state)
    {
#if 0
      fprintf(stderr, "into unknown: %s\n", name);
#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_SOLVABLE:
      pd->kind = 0;
      if (name[2] == 't' && name[3] == 't')
        pd->kind = "pattern";
      else if (name[1] == 'r')
        pd->kind = "product";
      else if (name[2] == 't' && name[3] == 'c')
        pd->kind = "patch";

      /* to support extension metadata files like others.xml which
         have the following structure:

         <otherdata xmlns="http://linux.duke.edu/metadata/other"
                    packages="101">
           <package pkgid="b78f8664cd90efe42e09a345e272997ef1b53c18"
                    name="zaptel-kmp-default"
                    arch="i586"><version epoch="0"
                    ver="1.2.10_2.6.22_rc4_git6_2" rel="70"/>
              ...

         we need to check if the pkgid is there and if it matches
         an already seen package, that means we don't need to create
         a new solvable but just append the attributes to the existing
         one.
      */
      const char *pkgid;
      if ((pkgid = find_attr("pkgid", atts)) != NULL)
        {
          // look at the checksum cache
          Id index = stringpool_str2id(&pd->cspool, pkgid, 0);
          if (!index || index >= pd->ncscache || !pd->cscache[index])
	    {
              fprintf(stderr, "error, the repository specifies extra information about package with checksum '%s', which does not exist in the repository.\n", pkgid);
              exit(1);
	    }
	  pd->solvable = pool_id2solvable(pool, pd->cscache[index]);
        }
       else
        {
          /* this is a new package */
          pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->common.repo));
          pd->freshens = 0;
        }
      pd->handle = pd->solvable - pool->solvables;
#if 0
      fprintf(stderr, "package #%d\n", pd->solvable - pool->solvables);
#endif

      break;
    case STATE_VERSION:
      s->evr = makeevr_atts(pool, pd, atts);
      break;
    case STATE_PROVIDES:
      s->provides = 0;
      break;
    case STATE_PROVIDESENTRY:
      s->provides = adddep(pool, pd, s->provides, atts, 0);
      break;
    case STATE_REQUIRES:
      s->requires = 0;
      break;
    case STATE_REQUIRESENTRY:
      s->requires = adddep(pool, pd, s->requires, atts, 1);
      break;
    case STATE_OBSOLETES:
      s->obsoletes = 0;
      break;
    case STATE_OBSOLETESENTRY:
      s->obsoletes = adddep(pool, pd, s->obsoletes, atts, 0);
      break;
    case STATE_CONFLICTS:
      s->conflicts = 0;
      break;
    case STATE_CONFLICTSENTRY:
      s->conflicts = adddep(pool, pd, s->conflicts, atts, 0);
      break;
    case STATE_RECOMMENDS:
      s->recommends = 0;
      break;
    case STATE_RECOMMENDSENTRY:
      s->recommends = adddep(pool, pd, s->recommends, atts, 0);
      break;
    case STATE_SUPPLEMENTS:
      s->supplements= 0;
      break;
    case STATE_SUPPLEMENTSENTRY:
      s->supplements = adddep(pool, pd, s->supplements, atts, 0);
      break;
    case STATE_SUGGESTS:
      s->suggests = 0;
      break;
    case STATE_SUGGESTSENTRY:
      s->suggests = adddep(pool, pd, s->suggests, atts, 0);
      break;
    case STATE_ENHANCES:
      s->enhances = 0;
      break;
    case STATE_ENHANCESENTRY:
      s->enhances = adddep(pool, pd, s->enhances, atts, 0);
      break;
    case STATE_FRESHENS:
      pd->freshens = 0;
      break;
    case STATE_FRESHENSENTRY:
      pd->freshens = adddep(pool, pd, pd->freshens, atts, 0);
      break;
    case STATE_EULA:
    case STATE_SUMMARY:
    case STATE_CATEGORY:
    case STATE_DESCRIPTION:
      pd->tmplang = find_attr("lang", atts);
      break;
    case STATE_USERVISIBLE:
      repodata_set_void(pd->data, handle, SOLVABLE_ISVISIBLE );
      break;
    case STATE_INCLUDESENTRY:
      {
	const char *tmp = find_attr("pattern", atts);
	if (tmp)
	  repodata_add_poolstr_array(pd->data, pd->handle, SOLVABLE_INCLUDES, join2("pattern", ":", tmp));
      }
      break;
    case STATE_EXTENDSENTRY:
      {
	const char *tmp = find_attr("pattern", atts);
	if (tmp)
	  repodata_add_poolstr_array(pd->data, pd->handle, SOLVABLE_EXTENDS, join2("pattern", ":", tmp));
      }
      break;
    case STATE_LOCATION:
      str = find_attr("href", atts);
      if (str)
	repodata_set_location(pd->data, handle, 0, 0, str);
      break;
    case STATE_CHECKSUM:
      pd->tmpattr = find_attr("type", atts);
      break;
    case STATE_TIME:
      {
        unsigned int t;
        str = find_attr("build", atts);
        if (str && (t = atoi(str)) != 0)
          repodata_set_num(pd->data, handle, SOLVABLE_BUILDTIME, t);
	break;
      }
    case STATE_SIZE:
      {
        unsigned int k;
        str = find_attr("installed", atts);
	if (str && (k = atoi(str)) != 0)
	  repodata_set_num(pd->data, handle, SOLVABLE_INSTALLSIZE, (k + 1023) / 1024);
	/* XXX the "package" attribute gives the size of the rpm file,
	   i.e. the download size.  Except on packman, there it seems to be
	   something else entirely, it has a value near to the other two
	   values, as if the rpm is uncompressed.  */
        str = find_attr("package", atts);
	if (str && (k = atoi(str)) != 0)
	  repodata_set_num(pd->data, handle, SOLVABLE_DOWNLOADSIZE, (k + 1023) / 1024);
        break;
      }
    case STATE_HEADERRANGE:
      {
        unsigned int end;
        str = find_attr("end", atts);
	if (str && (end = atoi(str)) != 0)
	  repodata_set_num(pd->data, handle, SOLVABLE_HEADEREND, end);
      }
      /*
        <diskusage>
          <dirs>
            <dir name="/" size="56" count="11"/>
            <dir name="usr/" size="56" count="11"/>
            <dir name="usr/bin/" size="38" count="10"/>
            <dir name="usr/share/" size="18" count="1"/>
            <dir name="usr/share/doc/" size="18" count="1"/>
          </dirs>
        </diskusage>
      */
    case STATE_DISKUSAGE:
      {
        /* Really, do nothing, wat for <dir> tag */
        break;
      }
    case STATE_DIR:
      {
        long filesz = 0, filenum = 0;
        unsigned dirid;
        if ((str = find_attr("name", atts)) != 0)
          dirid = repodata_str2dir(pd->data, str, 1);
        else
          {
            fprintf( stderr, "<dir .../> tag without 'name' attribute, atts = %p, *atts = %p\n",
                    (void *)atts, *atts);
            break;
          }
        if ((str = find_attr("size", atts)) != 0)
          filesz = strtol(str, 0, 0);
        if ((str = find_attr("count", atts)) != 0)
          filenum = strtol(str, 0, 0);
        pd->dirs = sat_extend(pd->dirs, pd->ndirs, 1, sizeof(pd->dirs[0]), 31);
        pd->dirs[pd->ndirs][0] = dirid;
        pd->dirs[pd->ndirs][1] = filesz;
        pd->dirs[pd->ndirs][2] = filenum;
        pd->ndirs++;
        break;
      }
    default:
      break;
    }
}
Пример #2
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;
}
Пример #3
0
/* internal */
static Solvable *
get_solvable(HifPackage *pkg)
{
    HifPackagePrivate *priv = GET_PRIVATE(pkg);
    return pool_id2solvable(hif_package_get_pool(pkg), priv->id);
}
Пример #4
0
int
repo_add_debpackages(Repo *repo, FILE *fp, int flags)
{
  Pool *pool = repo->pool;
  Repodata *data;
  char *buf, *p;
  int bufl, l, ll;
  Solvable *s;

  data = repo_add_repodata(repo, flags);
  buf = solv_malloc(4096);
  bufl = 4096;
  l = 0;
  buf[l] = 0;
  p = buf;
  for (;;)
    {
      if (!(p = strchr(p, '\n')))
	{
	  int l3;
	  if (l + 1024 >= bufl)
	    {
	      buf = solv_realloc(buf, bufl + 4096);
	      bufl += 4096;
	      p = buf + l;
	      continue;
	    }
	  p = buf + l;
	  ll = fread(p, 1, bufl - l - 1, fp);
	  if (ll <= 0)
	    break;
	  p[ll] = 0;
	  while ((l3 = strlen(p)) < ll)
	    p[l3] = '\n';
	  l += ll;
	  continue;
	}
      p++;
      if (*p != '\n')
	continue;
      *p = 0;
      ll = p - buf + 1;
      s = pool_id2solvable(pool, repo_add_solvable(repo));
      control2solvable(s, data, buf);
      if (!s->name)
	repo_free_solvable(repo, s - pool->solvables, 1);
      if (l > ll)
        memmove(buf, p + 1, l - ll);
      l -= ll;
      p = buf;
      buf[l] = 0;
    }
  if (l)
    {
      s = pool_id2solvable(pool, repo_add_solvable(repo));
      control2solvable(s, data, buf);
      if (!s->name)
	repo_free_solvable(repo, s - pool->solvables, 1);
    }
  solv_free(buf);
  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  return 0;
}
Пример #5
0
Id
repo_add_deb(Repo *repo, const char *deb, int flags)
{
  Pool *pool = repo->pool;
  Repodata *data;
  unsigned char buf[4096], *bp;
  int l, l2, vlen, clen, ctarlen;
  unsigned char *ctgz;
  unsigned char pkgid[16];
  unsigned char *ctar;
  int gotpkgid;
  FILE *fp;
  Solvable *s;
  struct stat stb;

  data = repo_add_repodata(repo, flags);
  if ((fp = fopen(flags & REPO_USE_ROOTDIR ? pool_prepend_rootdir_tmp(pool, deb) : deb, "r")) == 0)
    {
      pool_error(pool, -1, "%s: %s", deb, strerror(errno));
      return 0;
    }
  if (fstat(fileno(fp), &stb))
    {
      pool_error(pool, -1, "fstat: %s", strerror(errno));
      fclose(fp);
      return 0;
    }
  l = fread(buf, 1, sizeof(buf), fp);
  if (l < 8 + 60 || strncmp((char *)buf, "!<arch>\ndebian-binary   ", 8 + 16) != 0)
    {
      pool_error(pool, -1, "%s: not a deb package", deb);
      fclose(fp);
      return 0;
    }
  vlen = atoi((char *)buf + 8 + 48);
  if (vlen < 0 || vlen > l)
    {
      pool_error(pool, -1, "%s: not a deb package", deb);
      fclose(fp);
      return 0;
    }
  vlen += vlen & 1;
  if (l < 8 + 60 + vlen + 60)
    {
      pool_error(pool, -1, "%s: unhandled deb package", deb);
      fclose(fp);
      return 0;
    }
  if (strncmp((char *)buf + 8 + 60 + vlen, "control.tar.gz  ", 16) != 0)
    {
      pool_error(pool, -1, "%s: control.tar.gz is not second entry", deb);
      fclose(fp);
      return 0;
    }
  clen = atoi((char *)buf + 8 + 60 + vlen + 48);
  if (clen <= 0 || clen >= 0x100000)
    {
      pool_error(pool, -1, "%s: control.tar.gz has illegal size", deb);
      fclose(fp);
      return 0;
    }
  ctgz = solv_calloc(1, clen + 4);
  bp = buf + 8 + 60 + vlen + 60;
  l -= 8 + 60 + vlen + 60;
  if (l > clen)
    l = clen;
  if (l)
    memcpy(ctgz, bp, l);
  if (l < clen)
    {
      if (fread(ctgz + l, clen - l, 1, fp) != 1)
	{
	  pool_error(pool, -1, "%s: unexpected EOF", deb);
	  solv_free(ctgz);
	  fclose(fp);
	  return 0;
	}
    }
  fclose(fp);
  gotpkgid = 0;
  if (flags & DEBS_ADD_WITH_PKGID)
    {
      Chksum *chk = solv_chksum_create(REPOKEY_TYPE_MD5);
      solv_chksum_add(chk, ctgz, clen);
      solv_chksum_free(chk, pkgid);
      gotpkgid = 1;
    }
  if (ctgz[0] != 0x1f || ctgz[1] != 0x8b)
    {
      pool_error(pool, -1, "%s: control.tar.gz is not gzipped", deb);
      solv_free(ctgz);
      return 0;
    }
  if (ctgz[2] != 8 || (ctgz[3] & 0xe0) != 0)
    {
      pool_error(pool, -1, "%s: control.tar.gz is compressed in a strange way", deb);
      solv_free(ctgz);
      return 0;
    }
  bp = ctgz + 4;
  bp += 6;	/* skip time, xflags and OS code */
  if (ctgz[3] & 0x04)
    {
      /* skip extra field */
      l = bp[0] | bp[1] << 8;
      bp += l + 2;
      if (bp >= ctgz + clen)
	{
          pool_error(pool, -1, "%s: control.tar.gz is corrupt", deb);
	  solv_free(ctgz);
	  return 0;
	}
    }
  if (ctgz[3] & 0x08)	/* orig filename */
    while (*bp)
      bp++;
  if (ctgz[3] & 0x10)	/* file comment */
    while (*bp)
      bp++;
  if (ctgz[3] & 0x02)	/* header crc */
    bp += 2;
  if (bp >= ctgz + clen)
    {
      pool_error(pool, -1, "%s: control.tar.gz is corrupt", deb);
      solv_free(ctgz);
      return 0;
    }
  ctar = decompress(bp, ctgz + clen - bp, &ctarlen);
  solv_free(ctgz);
  if (!ctar)
    {
      pool_error(pool, -1, "%s: control.tar.gz is corrupt", deb);
      return 0;
    }
  bp = ctar;
  l = ctarlen;
  while (l > 512)
    {
      int j;
      l2 = 0;
      for (j = 124; j < 124 + 12; j++)
	if (bp[j] >= '0' && bp[j] <= '7')
	  l2 = l2 * 8 + (bp[j] - '0');
      if (!strcmp((char *)bp, "./control") || !strcmp((char *)bp, "control"))
	break;
      l2 = 512 + ((l2 + 511) & ~511);
      l -= l2;
      bp += l2;
    }
  if (l <= 512 || l - 512 - l2 <= 0 || l2 <= 0)
    {
      pool_error(pool, -1, "%s: control.tar.gz contains no control file", deb);
      free(ctar);
      return 0;
    }
  memmove(ctar, bp + 512, l2);
  ctar = solv_realloc(ctar, l2 + 1);
  ctar[l2] = 0;
  s = pool_id2solvable(pool, repo_add_solvable(repo));
  control2solvable(s, data, (char *)ctar);
  if (!(flags & REPO_NO_LOCATION))
    repodata_set_location(data, s - pool->solvables, 0, 0, deb);
  if (S_ISREG(stb.st_mode))
    repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, (unsigned long long)stb.st_size);
  if (gotpkgid)
    repodata_set_bin_checksum(data, s - pool->solvables, SOLVABLE_PKGID, REPOKEY_TYPE_MD5, pkgid);
  solv_free(ctar);
  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  return s - pool->solvables;
}
Пример #6
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;
}
Пример #7
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;
}
Пример #8
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;

    /* 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 ("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)
                {
                    fprintf(stderr, "Unknown checksum type: %s: %s\n", value, checksumtype);
                    continue;
                }
                l = solv_chksum_len(type);
                if (strlen(checksum) != 2 * l)
                {
                    fprintf(stderr, "Invalid checksum length: %s: for %s\n", value, checksum);
                    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));
                repodata_extend(data, s - pool->solvables);
                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));
                repodata_extend(data, s - pool->solvables);
                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_str(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);
                    }
                }
            }

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

            if (code10 && istag ("DISTPRODUCT"))
                /* DISTPRODUCT is for registration and Yast, not for the solver. */
                repodata_set_str(data, s - pool->solvables, PRODUCT_DISTPRODUCT, value);
            else if (code10 && istag ("DISTVERSION"))
                /* DISTVERSION is for registration and Yast, not for the solver. */
                repodata_set_str(data, s - pool->solvables, PRODUCT_DISTVERSION, value);
            else if (code10 && 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 (code10 && istag ("PREREQUIRES"))
                s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER);
            else if (code10 && istag ("REQUIRES"))
                s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER);
            else if (code10 && istag ("PROVIDES"))
                s->provides = adddep(pool, &pd, s->provides, value, 0);
            else if (code10 && istag ("CONFLICTS"))
                s->conflicts = adddep(pool, &pd, s->conflicts, value, 0);
            else if (code10 && istag ("OBSOLETES"))
                s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0);
            else if (code10 && istag ("RECOMMENDS"))
                s->recommends = adddep(pool, &pd, s->recommends, value, 0);
            else if (code10 && istag ("SUGGESTS"))
                s->suggests = adddep(pool, &pd, s->suggests, value, 0);
            else if (code10 && istag ("SUPPLEMENTS"))
                s->supplements = adddep(pool, &pd, s->supplements, value, 0);
            else if (code10 && istag ("ENHANCES"))
                s->enhances = adddep(pool, &pd, s->enhances, value, 0);
            /* FRESHENS doesn't seem to exist.  */
            else if (code10 && 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_FATAL, "repo_content: 'content' incomplete, no product solvable created!\n");
        repo_free_solvable_block(repo, s - pool->solvables, 1, 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));
            repodata_extend(data, p - pool->solvables);
            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);
    join_freemem();
    if (!(flags & REPO_NO_INTERNALIZE))
        repodata_internalize(data);
    return 0;
}
Пример #9
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);
    }
}
Id
ModulePackage::createPlatformSolvable(DnfSack * sack, DnfSack * moduleSack,
        const std::vector<std::string> & osReleasePaths, const std::string install_root,
        const char *  platformModule)
{
    std::pair<std::string, std::string> parsedPlatform;
    std::string name;
    std::string stream;
    if (platformModule) {
        parsedPlatform = parsePlatform(platformModule);
        if (!parsedPlatform.first.empty() && !parsedPlatform.second.empty()) {
            name = parsedPlatform.first;
            stream = parsedPlatform.second;
        } else {
            throw std::runtime_error(
                tfm::format(_("Invalid format of Platform module: %s"), platformModule));
        }
    } else if (sack) {
        Query baseQuery(sack);
        baseQuery.addFilter(HY_PKG_PROVIDES, HY_EQ, "system-release");
        baseQuery.addFilter(HY_PKG_LATEST, HY_EQ, 1);
        baseQuery.apply();
        Query availableQuery(baseQuery);
        availableQuery.addFilter(HY_PKG_REPONAME, HY_NEQ, HY_SYSTEM_REPO_NAME);
        auto platform = availableQuery.getStringsFromProvide("base-module");
        auto platformSize = platform.size();
        if (platformSize == 1) {
            parsedPlatform = parsePlatform(*platform.begin());
        } else if (platformSize > 1) {
            auto logger(Log::getLogger());
            logger->debug(_("Multiple module platforms provided by available packages\n"));
        }
        if (!parsedPlatform.first.empty() && !parsedPlatform.second.empty()) {
            name = parsedPlatform.first;
            stream = parsedPlatform.second;
        } else {
            baseQuery.addFilter(HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
            platform = baseQuery.getStringsFromProvide("base-module");
            platformSize = platform.size();
            if (platformSize == 1) {
                parsedPlatform = parsePlatform(*platform.begin());
            } else if (platformSize > 1) {
                auto logger(Log::getLogger());
                logger->debug(_("Multiple module platforms provided by installed packages\n"));
            }
            if (!parsedPlatform.first.empty() && !parsedPlatform.second.empty()) {
                name = parsedPlatform.first;
                stream = parsedPlatform.second;
            }
        }
    }

    if (name.empty() || stream.empty()) {
        for (auto & osReleasePath: osReleasePaths) {
            std::string path;
            if (install_root == "/") {
                path = osReleasePath;
            } else {
                if (install_root.back() == '/') {
                    path = install_root.substr(0, install_root.size() -1);
                } else {
                    path = install_root;
                }
                path += osReleasePath;
            }
            std::pair<std::string, std::string> platform;
            try {
                platform = getPlatformStream(path);
            } catch (const std::exception & except) {
                auto logger(Log::getLogger());
                logger->debug(tfm::format(_("Detection of Platform Module in %s failed: %s"),
                                          osReleasePath, std::string(except.what())));
            }
            if (!platform.first.empty() && !platform.second.empty()) {
                name = platform.first;
                stream = platform.second;
                break;
            } else {
                auto logger(Log::getLogger());
                logger->debug(tfm::format(_("Missing PLATFORM_ID in %s"), osReleasePath));
            }
        }
    }
    if (name.empty() || stream.empty()) {
        throw std::runtime_error(_("No valid Platform ID detected"));
    }
    std::string version = "0";
    std::string context = "00000000";

    Pool * pool = dnf_sack_get_pool(moduleSack);
    HyRepo hrepo = hy_repo_create(HY_SYSTEM_REPO_NAME);
    auto repoImpl = libdnf::repoGetImpl(hrepo);
    LibsolvRepo *repo = repo_create(pool, HY_SYSTEM_REPO_NAME);
    repo->appdata = hrepo;
    repoImpl->libsolvRepo = repo;
    repoImpl->needs_internalizing = 1;
    Id id = repo_add_solvable(repo);
    Solvable *solvable = pool_id2solvable(pool, id);
    setSovable(pool, solvable, name, stream, version, context, "noarch");
    repoImpl->needs_internalizing = 1;
    dnf_sack_set_provides_not_ready(moduleSack);
    dnf_sack_set_considered_to_update(moduleSack);
    pool_set_installed(pool, repo);
    return id;
}
Пример #11
0
static void XMLCALL
startElement(void *userData, const char *name, const char **atts)
{
  Parsedata *pd = (Parsedata *)userData;
  struct stateswitch *sw;
  Pool *pool = pd->pool;
  Solvable *s = pd->solvable;

  if (pd->depth != pd->statedepth)
    {
      pd->depth++;
      return;
    }

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

  pd->depth++;

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

  /* check if we're at the right level */
  if (sw->from != pd->state)
    {
#if 0
      fprintf(stderr, "into unknown: %s\n", name);
#endif
      return;
    }
  
  /* set new state */
  pd->state = sw->to;

  pd->docontent = sw->docontent;
  pd->statedepth = pd->depth;

  /* start with empty content */
  /* (will collect data until end element) */
  pd->lcontent = 0;
  *pd->content = 0;

  switch (pd->state)
    {

    case STATE_NAME:
      if (pd->kind)		       /* if kind is set (non package) */
        {
          strcpy(pd->content, pd->kind);
          pd->lcontent = strlen(pd->content);
	  pd->content[pd->lcontent++] = ':';   /* prefix name with '<kind>:' */
	  pd->content[pd->lcontent] = 0;
	}
      break;

    case STATE_PACKAGE:		       /* solvable name */
      pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo));
      if (!strcmp(name, "selection"))
        pd->kind = "selection";
      else if (!strcmp(name, "pattern"))
        pd->kind = "pattern";
      else if (!strcmp(name, "atom"))
        pd->kind = "atom";
      else if (!strcmp(name, "product"))
        pd->kind = "product";
      else if (!strcmp(name, "patch"))
        pd->kind = "patch";
      else
        pd->kind = NULL;	       /* default is package */
      pd->levrspace = 1;
      pd->epoch = 0;
      pd->version = 0;
      pd->release = 0;
      pd->freshens = 0;
#if 0
      fprintf(stderr, "package #%d\n", s - pool->solvables);
#endif
      break;

    case STATE_UPDATE:
      pd->levrspace = 1;
      pd->epoch = 0;
      pd->version = 0;
      pd->release = 0;
      break;

    case STATE_PROVIDES:	       /* start of provides */
      s->provides = 0;
      break;
    case STATE_PROVIDESENTRY:	       /* entry within provides */
      s->provides = adddep(pool, pd, s->provides, atts, 0);
      break;
    case STATE_REQUIRESENTRY:
      s->requires = adddep(pool, pd, s->requires, atts, -SOLVABLE_PREREQMARKER);
      break;
    case STATE_PREREQUIRESENTRY:
      s->requires = adddep(pool, pd, s->requires, atts, SOLVABLE_PREREQMARKER);
      break;
    case STATE_OBSOLETES:
      s->obsoletes = 0;
      break;
    case STATE_OBSOLETESENTRY:
      s->obsoletes = adddep(pool, pd, s->obsoletes, atts, 0);
      break;
    case STATE_CONFLICTS:
      s->conflicts = 0;
      break;
    case STATE_CONFLICTSENTRY:
      s->conflicts = adddep(pool, pd, s->conflicts, atts, 0);
      break;
    case STATE_RECOMMENDS:
      s->recommends = 0;
      break;
    case STATE_RECOMMENDSENTRY:
      s->recommends = adddep(pool, pd, s->recommends, atts, 0);
      break;
    case STATE_SUPPLEMENTS:
      s->supplements= 0;
      break;
    case STATE_SUPPLEMENTSENTRY:
      s->supplements = adddep(pool, pd, s->supplements, atts, 0);
      break;
    case STATE_SUGGESTS:
      s->suggests = 0;
      break;
    case STATE_SUGGESTSENTRY:
      s->suggests = adddep(pool, pd, s->suggests, atts, 0);
      break;
    case STATE_ENHANCES:
      s->enhances = 0;
      break;
    case STATE_ENHANCESENTRY:
      s->enhances = adddep(pool, pd, s->enhances, atts, 0);
      break;
    case STATE_FRESHENS:
      pd->freshens = 0;
      break;
    case STATE_FRESHENSENTRY:
      pd->freshens = adddep(pool, pd, pd->freshens, atts, 0);
      break;
    default:
      break;
    }
}
Пример #12
0
int
main(int argc, char **argv)
{
  Pool *pool;
  Repo *commandlinerepo = 0;
  Id *commandlinepkgs = 0;
  Id p;
  struct repoinfo *repoinfos, installedrepoinfo;
  int nrepoinfos = 0;
  int mainmode = 0, mode = 0;
  int i, newpkgs;
  Queue job, checkq;
  Solver *solv = 0;
  Transaction *trans;
  FILE **newpkgsfps;
  Queue repofilter;
  Queue kindfilter;
  Queue archfilter;
  int archfilter_src = 0;
  int cleandeps = 0;
  int forcebest = 0;
  char *rootdir = 0;
  char *keyname = 0;
  int keyname_depstr = 0;
  int debuglevel = 0;
  int answer, acnt = 0;

  argc--;
  argv++;
  while (argc && !strcmp(argv[0], "-d"))
    {
      debuglevel++;
      argc--;
      argv++;
    }
  if (!argv[0])
    usage(1);
  if (!strcmp(argv[0], "install") || !strcmp(argv[0], "in"))
    {
      mainmode = MODE_INSTALL;
      mode = SOLVER_INSTALL;
    }
#if defined(SUSE) || defined(FEDORA)
  else if (!strcmp(argv[0], "patch"))
    {
      mainmode = MODE_PATCH;
      mode = SOLVER_INSTALL;
    }
#endif
  else if (!strcmp(argv[0], "erase") || !strcmp(argv[0], "rm"))
    {
      mainmode = MODE_ERASE;
      mode = SOLVER_ERASE;
    }
  else if (!strcmp(argv[0], "list") || !strcmp(argv[0], "ls"))
    {
      mainmode = MODE_LIST;
      mode = 0;
    }
  else if (!strcmp(argv[0], "info"))
    {
      mainmode = MODE_INFO;
      mode = 0;
    }
  else if (!strcmp(argv[0], "search") || !strcmp(argv[0], "se"))
    {
      mainmode = MODE_SEARCH;
      mode = 0;
    }
  else if (!strcmp(argv[0], "verify"))
    {
      mainmode = MODE_VERIFY;
      mode = SOLVER_VERIFY;
    }
  else if (!strcmp(argv[0], "update") || !strcmp(argv[0], "up"))
    {
      mainmode = MODE_UPDATE;
      mode = SOLVER_UPDATE;
    }
  else if (!strcmp(argv[0], "dist-upgrade") || !strcmp(argv[0], "dup"))
    {
      mainmode = MODE_DISTUPGRADE;
      mode = SOLVER_DISTUPGRADE;
    }
  else if (!strcmp(argv[0], "repos") || !strcmp(argv[0], "repolist") || !strcmp(argv[0], "lr"))
    {
      mainmode = MODE_REPOLIST;
      mode = 0;
    }
  else
    usage(1);

  for (;;)
    {
      if (argc > 2 && !strcmp(argv[1], "--root"))
	{
	  rootdir = argv[2];
	  argc -= 2;
	  argv += 2;
	}
      else if (argc > 1 && !strcmp(argv[1], "--clean"))
	{
	  cleandeps = 1;
	  argc--;
	  argv++;
	}
      else if (argc > 1 && !strcmp(argv[1], "--best"))
	{
	  forcebest = 1;
	  argc--;
	  argv++;
	}
      else if (argc > 1 && !strcmp(argv[1], "--depstr"))
	{
	  keyname_depstr = 1;
	  argc--;
	  argv++;
	}
      else if (argc > 2 && !strcmp(argv[1], "--keyname"))
	{
	  keyname = argv[2];
	  argc -= 2;
	  argv += 2;
	}
      else
	break;
    }

  set_userhome();
  pool = pool_create();
  pool_set_rootdir(pool, rootdir);

#if 0
  {
    const char *langs[] = {"de_DE", "de", "en"};
    pool_set_languages(pool, langs, sizeof(langs)/sizeof(*langs));
  }
#endif

  pool_setloadcallback(pool, load_stub, 0);
#ifdef SUSE
  pool->nscallback = nscallback;
#endif
  if (debuglevel)
    pool_setdebuglevel(pool, debuglevel);
  setarch(pool);
  pool_set_flag(pool, POOL_FLAG_ADDFILEPROVIDESFILTERED, 1);
  repoinfos = read_repoinfos(pool, &nrepoinfos);
  sort_repoinfos(repoinfos, nrepoinfos);

  if (mainmode == MODE_REPOLIST)
    {
      int j = 1;
      for (i = 0; i < nrepoinfos; i++)
	{
	  struct repoinfo *cinfo = repoinfos + i;
	  if (!cinfo->enabled)
	    continue;
	  printf("%d: %-20s %s (prio %d)\n", j++, cinfo->alias, cinfo->name, cinfo->priority);
	}
      exit(0);
    }
  memset(&installedrepoinfo, 0, sizeof(installedrepoinfo));
  if (!read_installed_repo(&installedrepoinfo, pool))
    exit(1);
  read_repos(pool, repoinfos, nrepoinfos);

  /* setup filters */
  queue_init(&repofilter);
  queue_init(&kindfilter);
  queue_init(&archfilter);
  while (argc > 1)
    {
      if (!strcmp(argv[1], "-i"))
	{
	  queue_push2(&repofilter, SOLVER_SOLVABLE_REPO | SOLVER_SETREPO, pool->installed->repoid);
	  argc--;
	  argv++;
	}
      else if (argc > 2 && (!strcmp(argv[1], "-r") || !strcmp(argv[1], "--repo")))
	{
	  Id repoid = find_repo(argv[2], pool, repoinfos, nrepoinfos);
	  if (!repoid)
	    {
	      fprintf(stderr, "%s: no such repo\n", argv[2]);
	      exit(1);
	    }
	  /* SETVENDOR is actually wrong but useful */
	  queue_push2(&repofilter, SOLVER_SOLVABLE_REPO | SOLVER_SETREPO | SOLVER_SETVENDOR, repoid);
	  argc -= 2;
	  argv += 2;
	}
      else if (argc > 2 && !strcmp(argv[1], "--arch"))
	{
	  if (!strcmp(argv[2], "src") || !strcmp(argv[2], "nosrc"))
	    archfilter_src = 1;
	  queue_push2(&archfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, pool_str2id(pool, argv[2], 1), REL_ARCH, 1));
	  argc -= 2;
	  argv += 2;
	}
      else if (argc > 2 && (!strcmp(argv[1], "-t") || !strcmp(argv[1], "--type")))
	{
	  const char *kind = argv[2];
	  if (!strcmp(kind, "srcpackage"))
	    {
	      /* hey! should use --arch! */
	      queue_push2(&archfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, ARCH_SRC, REL_ARCH, 1));
	      archfilter_src = 1;
	      argc -= 2;
	      argv += 2;
	      continue;
	    }
	  if (!strcmp(kind, "package"))
	    kind = "";
	  if (!strcmp(kind, "all"))
	    queue_push2(&kindfilter, SOLVER_SOLVABLE_ALL, 0);
	  else
	    queue_push2(&kindfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, pool_str2id(pool, kind, 1), REL_KIND, 1));
	  argc -= 2;
	  argv += 2;
	}
      else
	break;
    }

  if (mainmode == MODE_SEARCH)
    {
      Queue sel, q;
      Dataiterator di;
      if (argc != 2)
	usage(1);
      pool_createwhatprovides(pool);
      queue_init(&sel);
      dataiterator_init(&di, pool, 0, 0, 0, argv[1], SEARCH_SUBSTRING|SEARCH_NOCASE);
      dataiterator_set_keyname(&di, SOLVABLE_NAME);
      dataiterator_set_search(&di, 0, 0);
      while (dataiterator_step(&di))
	queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
      dataiterator_set_keyname(&di, SOLVABLE_SUMMARY);
      dataiterator_set_search(&di, 0, 0);
      while (dataiterator_step(&di))
	queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
      dataiterator_set_keyname(&di, SOLVABLE_DESCRIPTION);
      dataiterator_set_search(&di, 0, 0);
      while (dataiterator_step(&di))
	queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
      dataiterator_free(&di);
      if (repofilter.count)
	selection_filter(pool, &sel, &repofilter);
	
      queue_init(&q);
      selection_solvables(pool, &sel, &q);
      queue_free(&sel);
      for (i = 0; i < q.count; i++)
	{
	  Solvable *s = pool_id2solvable(pool, q.elements[i]);
	  printf("  - %s [%s]: %s\n", pool_solvable2str(pool, s), s->repo->name, solvable_lookup_str(s, SOLVABLE_SUMMARY));
	}
      queue_free(&q);
      exit(0);
    }

  /* process command line packages */
  if (mainmode == MODE_LIST || mainmode == MODE_INFO || mainmode == MODE_INSTALL)
    {
      for (i = 1; i < argc; i++)
	{
	  if (!is_cmdline_package((const char *)argv[i]))
	    continue;
	  if (access(argv[i], R_OK))
	    {
	      perror(argv[i]);
	      exit(1);
	    }
	  if (!commandlinepkgs)
	    commandlinepkgs = solv_calloc(argc, sizeof(Id));
	  if (!commandlinerepo)
	    commandlinerepo = repo_create(pool, "@commandline");
	  p = add_cmdline_package(commandlinerepo, (const char *)argv[i]);
	  if (!p)
	    {
	      fprintf(stderr, "could not add '%s'\n", argv[i]);
	      exit(1);
	    }
	  commandlinepkgs[i] = p;
	}
      if (commandlinerepo)
	repo_internalize(commandlinerepo);
    }

#if defined(ENABLE_RPMDB)
  if (pool->disttype == DISTTYPE_RPM)
    addfileprovides(pool);
#endif
#ifdef SUSE
  add_autopackages(pool);
#endif
  pool_createwhatprovides(pool);

  if (keyname)
    keyname = solv_dupjoin("solvable:", keyname, 0);
  queue_init(&job);
  for (i = 1; i < argc; i++)
    {
      Queue job2;
      int flags, rflags;

      if (commandlinepkgs && commandlinepkgs[i])
	{
	  queue_push2(&job, SOLVER_SOLVABLE, commandlinepkgs[i]);
	  continue;
	}
      queue_init(&job2);
      flags = SELECTION_NAME|SELECTION_PROVIDES|SELECTION_GLOB;
      flags |= SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL;
      if (kindfilter.count)
	flags |= SELECTION_SKIP_KIND;
      if (mode == MODE_LIST || archfilter_src)
	flags |= SELECTION_WITH_SOURCE;
      if (argv[i][0] == '/')
	flags |= SELECTION_FILELIST | (mode == MODE_ERASE ? SELECTION_INSTALLED_ONLY : 0);
      if (!keyname)
        rflags = selection_make(pool, &job2, argv[i], flags);
      else
	{
	  if (keyname_depstr)
	    flags |= SELECTION_MATCH_DEPSTR;
          rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
	}
      if (repofilter.count)
	selection_filter(pool, &job2, &repofilter);
      if (archfilter.count)
	selection_filter(pool, &job2, &archfilter);
      if (kindfilter.count)
	selection_filter(pool, &job2, &kindfilter);
      if (!job2.count)
	{
	  flags |= SELECTION_NOCASE;
	  if (!keyname)
            rflags = selection_make(pool, &job2, argv[i], flags);
	  else
	    rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
	  if (repofilter.count)
	    selection_filter(pool, &job2, &repofilter);
	  if (archfilter.count)
	    selection_filter(pool, &job2, &archfilter);
	  if (kindfilter.count)
	    selection_filter(pool, &job2, &kindfilter);
	  if (job2.count)
	    printf("[ignoring case for '%s']\n", argv[i]);
	}
      if (!job2.count)
	{
	  fprintf(stderr, "nothing matches '%s'\n", argv[i]);
	  exit(1);
	}
      if (rflags & SELECTION_FILELIST)
        printf("[using file list match for '%s']\n", argv[i]);
      if (rflags & SELECTION_PROVIDES)
	printf("[using capability match for '%s']\n", argv[i]);
      queue_insertn(&job, job.count, job2.count, job2.elements);
      queue_free(&job2);
    }
  keyname = solv_free(keyname);

  if (!job.count && (mainmode == MODE_UPDATE || mainmode == MODE_DISTUPGRADE || mainmode == MODE_VERIFY || repofilter.count || archfilter.count || kindfilter.count))
    {
      queue_push2(&job, SOLVER_SOLVABLE_ALL, 0);
      if (repofilter.count)
	selection_filter(pool, &job, &repofilter);
      if (archfilter.count)
	selection_filter(pool, &job, &archfilter);
      if (kindfilter.count)
	selection_filter(pool, &job, &kindfilter);
    }
  queue_free(&repofilter);
  queue_free(&archfilter);
  queue_free(&kindfilter);

  if (!job.count && mainmode != MODE_PATCH)
    {
      printf("no package matched\n");
      exit(1);
    }

  if (mainmode == MODE_LIST || mainmode == MODE_INFO)
    {
      /* list mode, no solver needed */
      Queue q;
      queue_init(&q);
      for (i = 0; i < job.count; i += 2)
	{
	  int j;
	  queue_empty(&q);
	  pool_job2solvables(pool, &q, job.elements[i], job.elements[i + 1]);
	  for (j = 0; j < q.count; j++)
	    {
	      Solvable *s = pool_id2solvable(pool, q.elements[j]);
	      if (mainmode == MODE_INFO)
		{
		  const char *str;
		  printf("Name:        %s\n", pool_solvable2str(pool, s));
		  printf("Repo:        %s\n", s->repo->name);
		  printf("Summary:     %s\n", solvable_lookup_str(s, SOLVABLE_SUMMARY));
		  str = solvable_lookup_str(s, SOLVABLE_URL);
		  if (str)
		    printf("Url:         %s\n", str);
		  str = solvable_lookup_str(s, SOLVABLE_LICENSE);
		  if (str)
		    printf("License:     %s\n", str);
		  printf("Description:\n%s\n", solvable_lookup_str(s, SOLVABLE_DESCRIPTION));
		  printf("\n");
		}
	      else
		{
#if 1
		  const char *sum = solvable_lookup_str_lang(s, SOLVABLE_SUMMARY, "de", 1);
#else
		  const char *sum = solvable_lookup_str_poollang(s, SOLVABLE_SUMMARY);
#endif
		  printf("  - %s [%s]\n", pool_solvable2str(pool, s), s->repo->name);
		  if (sum)
		    printf("    %s\n", sum);
		}
	    }
	}
      queue_free(&q);
      queue_free(&job);
      pool_free(pool);
      free_repoinfos(repoinfos, nrepoinfos);
      solv_free(commandlinepkgs);
      exit(0);
    }

#if defined(SUSE) || defined(FEDORA)
  if (mainmode == MODE_PATCH)
    add_patchjobs(pool, &job);
#endif

  // add mode
  for (i = 0; i < job.count; i += 2)
    {
      job.elements[i] |= mode;
      if (mode == SOLVER_UPDATE && pool_isemptyupdatejob(pool, job.elements[i], job.elements[i + 1]))
	job.elements[i] ^= SOLVER_UPDATE ^ SOLVER_INSTALL;
      if (cleandeps)
        job.elements[i] |= SOLVER_CLEANDEPS;
      if (forcebest)
        job.elements[i] |= SOLVER_FORCEBEST;
    }

  // multiversion test
  // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae", 1));
  // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae-base", 1));
  // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae-extra", 1));
#if 0
  queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, NAMESPACE_LANGUAGE, 0, REL_NAMESPACE, 1));
  queue_push2(&job, SOLVER_ERASE|SOLVER_CLEANDEPS|SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, NAMESPACE_LANGUAGE, 0, REL_NAMESPACE, 1));
#endif

rerunsolver:
  solv = solver_create(pool);
  solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1);
#ifdef FEDORA
  solver_set_flag(solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, 1);
#endif
  if (mainmode == MODE_ERASE)
    solver_set_flag(solv, SOLVER_FLAG_ALLOW_UNINSTALL, 1);	/* don't nag */
  solver_set_flag(solv, SOLVER_FLAG_BEST_OBEY_POLICY, 1);

  for (;;)
    {
      Id problem, solution;
      int pcnt, scnt;

      if (!solver_solve(solv, &job))
	break;
      pcnt = solver_problem_count(solv);
      printf("Found %d problems:\n", pcnt);
      for (problem = 1; problem <= pcnt; problem++)
	{
	  int take = 0;
	  printf("Problem %d/%d:\n", problem, pcnt);
	  solver_printprobleminfo(solv, problem);
	  printf("\n");
	  scnt = solver_solution_count(solv, problem);
	  for (solution = 1; solution <= scnt; solution++)
	    {
	      printf("Solution %d:\n", solution);
	      solver_printsolution(solv, problem, solution);
	      printf("\n");
	    }
	  for (;;)
	    {
	      char inbuf[128], *ip;
	      printf("Please choose a solution: ");
	      fflush(stdout);
	      *inbuf = 0;
	      if (!(ip = fgets(inbuf, sizeof(inbuf), stdin)))
		{
		  printf("Abort.\n");
		  exit(1);
		}
	      while (*ip == ' ' || *ip == '\t')
		ip++;
	      if (*ip >= '0' && *ip <= '9')
		{
		  take = atoi(ip);
		  if (take >= 1 && take <= scnt)
		    break;
		}
	      if (*ip == 's')
		{
		  take = 0;
		  break;
		}
	      if (*ip == 'q')
		{
		  printf("Abort.\n");
		  exit(1);
		}
	    }
	  if (!take)
	    continue;
	  solver_take_solution(solv, problem, take, &job);
	}
    }

  trans = solver_create_transaction(solv);
  if (!trans->steps.count)
    {
      printf("Nothing to do.\n");
      transaction_free(trans);
      solver_free(solv);
      queue_free(&job);
      pool_free(pool);
      free_repoinfos(repoinfos, nrepoinfos);
      solv_free(commandlinepkgs);
      exit(1);
    }

  /* display transaction to the user and ask for confirmation */
  printf("\n");
  printf("Transaction summary:\n\n");
  transaction_print(trans);
#if defined(SUSE)
  showdiskusagechanges(trans);
#endif
  printf("install size change: %d K\n", transaction_calc_installsizechange(trans));
  printf("\n");

  acnt = solver_alternatives_count(solv);
  if (acnt)
    {
      if (acnt == 1)
        printf("Have one alternative:\n");
      else
        printf("Have %d alternatives:\n", acnt);
      for (i = 1; i <= acnt; i++)
	{
	  Id id, from;
	  int atype = solver_get_alternative(solv, i, &id, &from, 0, 0, 0);
	  printf("  - %s\n", solver_alternative2str(solv, atype, id, from));
	}
      printf("\n");
      answer = yesno("OK to continue (y/n/a)? ", 'a');
    }
  else
    answer = yesno("OK to continue (y/n)? ", 0);
  if (answer == 'a')
    {
      Queue choicesq;
      Queue answerq;
      Id id, from, chosen;
      int j;

      queue_init(&choicesq);
      queue_init(&answerq);
      for (i = 1; i <= acnt; i++)
	{
	  int atype = solver_get_alternative(solv, i, &id, &from, &chosen, &choicesq, 0);
	  printf("\n%s\n", solver_alternative2str(solv, atype, id, from));
	  for (j = 0; j < choicesq.count; j++)
	    {
	      Id p = choicesq.elements[j];
	      if (p < 0)
		p = -p;
	      queue_push(&answerq, p);
	      printf("%6d: %s\n", answerq.count, pool_solvid2str(pool, p));
	    }
	}
      queue_free(&choicesq);
      printf("\n");
      for (;;)
	{
	  char inbuf[128], *ip;
	  int neg = 0;
	  printf("OK to continue (y/n), or number to change alternative: ");
	  fflush(stdout);
	  *inbuf = 0;
	  if (!(ip = fgets(inbuf, sizeof(inbuf), stdin)))
	    {
	      printf("Abort.\n");
	      exit(1);
	    }
	  while (*ip == ' ' || *ip == '\t')
	    ip++;
	  if (*ip == '-' && ip[1] >= '0' && ip[1] <= '9')
	    {
	      neg = 1;
	      ip++;
	    }
	  if (*ip >= '0' && *ip <= '9')
	    {
	      int take = atoi(ip);
	      if (take > 0 && take <= answerq.count)
		{
		  Id p = answerq.elements[take - 1];
		  queue_free(&answerq);
		  queue_push2(&job, (neg ? SOLVER_DISFAVOR : SOLVER_FAVOR) | SOLVER_SOLVABLE_NAME, pool->solvables[p].name);
		  solver_free(solv);
		  solv = 0;
		  goto rerunsolver;
		  break;
		}
	    }
	  if (*ip == 'n' || *ip == 'y')
	    {
	      answer = *ip == 'n' ? 0 : *ip;
	      break;
	    }
	}
      queue_free(&answerq);
    }
  if (!answer)
    {
      printf("Abort.\n");
      transaction_free(trans);
      solver_free(solv);
      queue_free(&job);
      pool_free(pool);
      free_repoinfos(repoinfos, nrepoinfos);
      solv_free(commandlinepkgs);
      exit(1);
    }

  /* download all new packages */
  queue_init(&checkq);
  newpkgs = transaction_installedresult(trans, &checkq);
  newpkgsfps = 0;
  if (newpkgs)
    {
      int downloadsize = 0;
      for (i = 0; i < newpkgs; i++)
	{
	  Solvable *s;

	  p = checkq.elements[i];
	  s = pool_id2solvable(pool, p);
	  downloadsize += solvable_lookup_sizek(s, SOLVABLE_DOWNLOADSIZE, 0);
	}
      printf("Downloading %d packages, %d K\n", newpkgs, downloadsize);
      newpkgsfps = solv_calloc(newpkgs, sizeof(*newpkgsfps));
      for (i = 0; i < newpkgs; i++)
	{
	  const char *loc;
	  Solvable *s;
	  struct repoinfo *cinfo;

	  p = checkq.elements[i];
	  s = pool_id2solvable(pool, p);
	  if (s->repo == commandlinerepo)
	    {
	      loc = solvable_lookup_location(s, 0);
	      if (!loc)
		continue;
	      if (!(newpkgsfps[i] = fopen(loc, "r")))
		{
		  perror(loc);
		  exit(1);
		}
	      putchar('.');
	      continue;
	    }
	  cinfo = s->repo->appdata;
	  if (!cinfo || cinfo->type == TYPE_INSTALLED)
	    {
	      printf("%s: no repository information\n", s->repo->name);
	      exit(1);
	    }
	  loc = solvable_lookup_location(s, 0);
	  if (!loc)
	     continue;	/* pseudo package? */
#if defined(ENABLE_RPMDB)
	  if (pool->installed && pool->installed->nsolvables)
	    {
	      if ((newpkgsfps[i] = trydeltadownload(s, loc)) != 0)
		{
		  putchar('d');
		  fflush(stdout);
		  continue;		/* delta worked! */
		}
	    }
#endif
	  if ((newpkgsfps[i] = downloadpackage(s, loc)) == 0)
	    {
	      printf("\n%s: %s not found in repository\n", s->repo->name, loc);
	      exit(1);
	    }
	  putchar('.');
	  fflush(stdout);
	}
      putchar('\n');
    }

#if defined(ENABLE_RPMDB) && (defined(SUSE) || defined(FEDORA) || defined(MANDRIVA) || defined(MAGEIA))
  /* check for file conflicts */
  if (newpkgs)
    {
      Queue conflicts;
      queue_init(&conflicts);
      if (checkfileconflicts(pool, &checkq, newpkgs, newpkgsfps, &conflicts))
	{
	  if (yesno("Re-run solver (y/n/q)? ", 0))
	    {
	      for (i = 0; i < newpkgs; i++)
		if (newpkgsfps[i])
		  fclose(newpkgsfps[i]);
	      newpkgsfps = solv_free(newpkgsfps);
	      solver_free(solv);
	      solv = 0;
	      pool_add_fileconflicts_deps(pool, &conflicts);
	      queue_free(&conflicts);
	      goto rerunsolver;
	    }
	}
      queue_free(&conflicts);
    }
#endif

  /* and finally commit the transaction */
  printf("Committing transaction:\n\n");
  transaction_order(trans, 0);
  for (i = 0; i < trans->steps.count; i++)
    {
      int j;
      FILE *fp;
      Id type;

      p = trans->steps.elements[i];
      type = transaction_type(trans, p, SOLVER_TRANSACTION_RPM_ONLY);
      switch(type)
	{
	case SOLVER_TRANSACTION_ERASE:
	  printf("erase %s\n", pool_solvid2str(pool, p));
	  commit_transactionelement(pool, type, p, 0);
	  break;
	case SOLVER_TRANSACTION_INSTALL:
	case SOLVER_TRANSACTION_MULTIINSTALL:
	  printf("install %s\n", pool_solvid2str(pool, p));
	  for (j = 0; j < newpkgs; j++)
	    if (checkq.elements[j] == p)
	      break;
	  fp = j < newpkgs ? newpkgsfps[j] : 0;
	  if (!fp)
	    continue;
	  commit_transactionelement(pool, type, p, fp);
	  fclose(fp);
	  newpkgsfps[j] = 0;
	  break;
	default:
	  break;
	}
    }

  for (i = 0; i < newpkgs; i++)
    if (newpkgsfps[i])
      fclose(newpkgsfps[i]);
  solv_free(newpkgsfps);
  queue_free(&checkq);
  transaction_free(trans);
  solver_free(solv);
  queue_free(&job);
  pool_free(pool);
  free_repoinfos(repoinfos, nrepoinfos);
  solv_free(commandlinepkgs);
  exit(0);
}
Пример #13
0
Id
repo_add_arch_pkg(Repo *repo, const char *fn, int flags)
{
  Pool *pool = repo->pool;
  Repodata *data;
  FILE *fp;
  struct tarhead th;
  char line[4096];
  int ignoreline;
  Solvable *s;
  int l, fd;
  struct stat stb;
  void *pkgidhandle = 0;

  data = repo_add_repodata(repo, flags);
  if ((fd = open(flags & REPO_USE_ROOTDIR ? pool_prepend_rootdir_tmp(pool, fn) : fn, O_RDONLY, 0)) < 0)
    {
      pool_error(pool, -1, "%s: %s", fn, strerror(errno));
      return 0;
    }
  if (fstat(fd, &stb))
    {
      pool_error(pool, -1, "%s: fstat: %s", fn, strerror(errno));
      close(fd);
      return 0;
    }
  if (!(fp = solv_xfopen_fd(fn, fd, "r")))
    {
      pool_error(pool, -1, "%s: fdopen failed", fn);
      close(fd);
      return 0;
    }
  s = 0;
  inittarhead(&th, fp);
  while (gettarhead(&th) > 0)
    {
      if (th.type != 1 || strcmp(th.path, ".PKGINFO") != 0)
	{
          skipentry(&th);
	  continue;
	}
      ignoreline = 0;
      s = pool_id2solvable(pool, repo_add_solvable(repo));
      if (flags & ARCH_ADD_WITH_PKGID)
	pkgidhandle = solv_chksum_create(REPOKEY_TYPE_MD5);
      while (getsentry(&th, line, sizeof(line)))
	{
	  l = strlen(line);
	  if (l == 0)
	    continue;
	  if (pkgidhandle)
	    solv_chksum_add(pkgidhandle, line, l);
	  if (line[l - 1] != '\n')
	    {
	      ignoreline = 1;
	      continue;
	    }
	  if (ignoreline)
	    {
	      ignoreline = 0;
	      continue;
	    }
	  line[--l] = 0;
	  if (l == 0 || line[0] == '#')
	    continue;
	  if (!strncmp(line, "pkgname = ", 10))
	    s->name = pool_str2id(pool, line + 10, 1);
	  else if (!strncmp(line, "pkgver = ", 9))
	    s->evr = pool_str2id(pool, line + 9, 1);
	  else if (!strncmp(line, "pkgdesc = ", 10))
	    {
	      repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, line + 10);
	      repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, line + 10);
	    }
	  else if (!strncmp(line, "url = ", 6))
	    repodata_set_str(data, s - pool->solvables, SOLVABLE_URL, line + 6);
	  else if (!strncmp(line, "builddate = ", 12))
	    repodata_set_num(data, s - pool->solvables, SOLVABLE_BUILDTIME, strtoull(line + 12, 0, 10));
	  else if (!strncmp(line, "packager = ", 11))
	    repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_PACKAGER, line + 11);
	  else if (!strncmp(line, "size = ", 7))
	    repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(line + 7, 0, 10));
	  else if (!strncmp(line, "arch = ", 7))
	    s->arch = pool_str2id(pool, line + 7, 1);
	  else if (!strncmp(line, "license = ", 10))
	    repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_LICENSE, line + 10);
	  else if (!strncmp(line, "replaces = ", 11))
	    s->obsoletes = adddep(repo, s->obsoletes, line + 11);
	  else if (!strncmp(line, "group = ", 8))
	    repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_GROUP, line + 8);
	  else if (!strncmp(line, "depend = ", 9))
	    s->requires = adddep(repo, s->requires, line + 9);
	  else if (!strncmp(line, "optdepend = ", 12))
	    {
	      char *p = strchr(line, ':');
	      if (p)
		*p = 0;
	      s->suggests = adddep(repo, s->suggests, line + 12);
	    }
	  else if (!strncmp(line, "conflict = ", 11))
	    s->conflicts = adddep(repo, s->conflicts, line + 11);
	  else if (!strncmp(line, "provides = ", 11))
	    s->provides = adddep(repo, s->provides, line + 11);
	}
      break;
    }
  freetarhead(&th);
  fclose(fp);
  if (!s)
    {
      pool_error(pool, -1, "%s: not an arch package", fn);
      if (pkgidhandle)
	solv_chksum_free(pkgidhandle, 0);
      return 0;
    }
  if (s && !s->name)
    {
      pool_error(pool, -1, "%s: package has no name", fn);
      repo_free_solvable(repo, s - pool->solvables, 1);
      s = 0;
    }
  if (s)
    {
      if (!s->arch)
	s->arch = ARCH_ANY;
      if (!s->evr)
	s->evr = ID_EMPTY;
      s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
      if (!(flags & REPO_NO_LOCATION))
	repodata_set_location(data, s - pool->solvables, 0, 0, fn);
      if (S_ISREG(stb.st_mode))
        repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, (unsigned long long)stb.st_size);
      if (pkgidhandle)
	{
	  unsigned char pkgid[16];
	  solv_chksum_free(pkgidhandle, pkgid);
	  repodata_set_bin_checksum(data, s - pool->solvables, SOLVABLE_PKGID, REPOKEY_TYPE_MD5, pkgid);
	  pkgidhandle = 0;
	}
    }
  if (pkgidhandle)
    solv_chksum_free(pkgidhandle, 0);
  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  return s ? s - pool->solvables : 0;
}
Пример #14
0
static void XMLCALL
startElement(void *userData, const char *name, const char **atts)
{
  struct parsedata *pd = userData;
  Pool *pool = pd->pool;
  Solvable *s = pd->solvable;
  struct stateswitch *sw;

#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])	/* no statetable -> no substates */
    {
#if 0
      fprintf(stderr, "into unknown: %s (from: %d)\n", name, pd->state);
#endif
      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);
#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_PRODUCT:
      /* parse 'schemeversion' and store in global variable */
      {
        const char * scheme = find_attr("schemeversion", atts);
        pd->productscheme = (scheme && *scheme) ? atoi(scheme) : -1;
      }
      if (!s)
	{
	  s = pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo));
	  pd->handle = s - pool->solvables;
	}
      break;

      /* <summary lang="xy">... */
    case STATE_SUMMARY:
    case STATE_DESCRIPTION:
      pd->tmplang = join_dup(&pd->jd, find_attr("lang", atts));
      break;
    case STATE_URL:
      pd->urltype = pool_str2id(pd->pool, find_attr("name", atts), 1);
      break;
    case STATE_REGUPDREPO:
      {
        const char *repoid = find_attr("repoid", atts);
	if (repoid && *repoid)
          repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_UPDATES_REPOID, repoid);
      }
    default:
      break;
    }
}
Пример #15
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;
}
Пример #16
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;
}
Пример #17
0
/* internal */
static Solvable *
get_solvable(HyPackage pkg)
{
    return pool_id2solvable(package_pool(pkg), pkg->id);
}
Пример #18
0
static void XMLCALL
startElement(void *userData, const char *name, const char **atts)
{
  struct parsedata *pd = userData;
  Pool *pool = pd->pool;
  Solvable *s = pd->solvable;
  struct stateswitch *sw;

#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])	/* no statetable -> no substates */
    {
#if 0
      fprintf(stderr, "into unknown: %s (from: %d)\n", name, pd->state);
#endif
      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);
#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_PRODUCT:
      {
	/* parse 'type' */
	const char *type = find_attr("type", atts, 0);
	s = pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo));
	repodata_extend(pd->data, s - pool->solvables);
	pd->handle = s - pool->solvables;
	if (type)
	  {
	    repodata_set_str(pd->data, pd->handle, PRODUCT_TYPE, type);
	  }
      }
      break;
    case STATE_VERSION:
      {
	const char *ver = find_attr("ver", atts, 0);
	const char *rel = find_attr("rel", atts, 0);
	/* const char *epoch = find_attr("epoch", atts, 1); ignored */
	s->evr = makeevr(pd->pool, join2(ver, "-", rel));
      }
      break;
      /* <summary lang="xy">... */
    case STATE_SUMMARY:
      pd->tmplang = find_attr("lang", atts, 1);
      break;
    default:
      break;
    }
}