static void
susetags_add_ext(Repo *repo, Repodata *data)
{
  Pool *pool = repo->pool;
  Dataiterator di;
  char ext[3];
  Id handle, filechksumtype;
  const unsigned char *filechksum;

  dataiterator_init(&di, pool, repo, SOLVID_META, SUSETAGS_FILE_NAME, 0, 0);
  dataiterator_prepend_keyname(&di, SUSETAGS_FILE);
  while (dataiterator_step(&di))
    {
      if (strncmp(di.kv.str, "packages.", 9) != 0)
	continue;
      if (!strcmp(di.kv.str + 9, "gz"))
	continue;
      if (!di.kv.str[9] || !di.kv.str[10] || (di.kv.str[11] && di.kv.str[11] != '.'))
	continue;
      ext[0] = di.kv.str[9];
      ext[1] = di.kv.str[10];
      ext[2] = 0;
      if (!strcmp(ext, "en"))
	continue;
      if (!susetags_find(repo, di.kv.str, &filechksum, &filechksumtype))
	continue;
      handle = repodata_new_handle(data);
      repodata_set_str(data, handle, SUSETAGS_FILE_NAME, di.kv.str);
      if (filechksumtype)
	repodata_set_bin_checksum(data, handle, SUSETAGS_FILE_CHECKSUM, filechksumtype, filechksum);
      add_ext_keys(data, handle, ext);
      repodata_add_flexarray(data, SOLVID_META, REPOSITORY_EXTERNAL, handle);
    }
  dataiterator_free(&di);
}
Example #2
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;
}
Example #3
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;
}