Exemple #1
0
static void
add_code11_product(struct parsedata *pd, FILE *fp)
{
  char buf[BUFF_SIZE];
  int l;
  struct stat st;
  XML_Parser parser;

  if (!fstat(fileno(fp), &st))
    {
      pd->currentproduct = st.st_ino;
      pd->ctime = (unsigned int)st.st_ctime;
    }
  else
    {
      pd->currentproduct = pd->baseproduct + 1; /* make it != baseproduct if stat fails */
      pool_error(pd->pool, 0, "fstat: %s", strerror(errno));
      pd->ctime = 0;
    }

  parser = XML_ParserCreate(NULL);
  XML_SetUserData(parser, pd);
  XML_SetElementHandler(parser, startElement, endElement);
  XML_SetCharacterDataHandler(parser, characterData);

  for (;;)
    {
      l = fread(buf, 1, sizeof(buf), fp);
      if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR)
	{
	  pool_debug(pd->pool, SOLV_ERROR, "%s: %s at line %u:%u\n", pd->filename, XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser), (unsigned int)XML_GetCurrentColumnNumber(parser));
	  XML_ParserFree(parser);
	  if (pd->solvable)
	    {
	      repo_free_solvable(pd->repo, pd->solvable - pd->pool->solvables, 1);
	      pd->solvable = 0;
	    }
	  return;
	}
      if (l == 0)
	break;
    }
  XML_ParserFree(parser);
}
Exemple #2
0
int
repo_add_content(Repo *repo, FILE *fp, int flags)
{
  Pool *pool = repo->pool;
  char *line, *linep;
  int aline;
  Solvable *s;
  struct parsedata pd;
  Repodata *data;
  Id handle = 0;
  int contentstyle = 0;
  char *descrdir = 0;
  char *datadir = 0;
  char *defvendor = 0;

  int i = 0;
  int res = 0;

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

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

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

  data = repo_add_repodata(repo, flags);

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

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

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

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

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


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

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

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

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

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

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

	  /* product tags */

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

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

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

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

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

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

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

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

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

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

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

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

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

  if (pd.tmp)
    solv_free(pd.tmp);
  solv_free(line);
  solv_free(otherarchs);
  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  return res;
}
Exemple #3
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;
}
Exemple #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;
}
Exemple #5
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;
}
Exemple #6
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;
}