예제 #1
0
파일: advisory.c 프로젝트: Xake/hawkey
// deprecated in 0.4.18, eligible for dropping after 2014-10-15 AND no sooner
// than in 0.4.21, use hy_advisorypkg_get_string instead
HyStringArray
hy_advisory_get_filenames(HyAdvisory advisory)
{
    HyAdvisoryPkg advisorypkg;
    char *filename;
    int len = 0;
    HyStringArray strs = solv_extend(0, 0, 1, sizeof(char*), FILENAME_BLOCK);
    HyAdvisoryPkgList pkglist = hy_advisory_get_packages(advisory);

    for (int i = 0; i < hy_advisorypkglist_count(pkglist); i++) {
	advisorypkg = hy_advisorypkglist_get_clone(pkglist, i);
	filename = solv_strdup(
		hy_advisorypkg_get_string(advisorypkg, HY_ADVISORYPKG_FILENAME));
	hy_advisorypkg_free(advisorypkg);
	if (!filename)
	    continue;

	strs[len++] = filename;
	strs = solv_extend(strs, len, 1, sizeof(char*), FILENAME_BLOCK);
    }

    strs[len++] = NULL;
    hy_advisorypkglist_free(pkglist);
    return strs;
}
예제 #2
0
파일: dirpool.c 프로젝트: openSUSE/libsolv
Id
dirpool_add_dir(Dirpool *dp, Id parent, Id comp, int create)
{
  Id did, d, ds;

  if (!dp->ndirs)
    {
      if (!create)
	return 0;
      dp->ndirs = 2;
      dp->dirs = solv_extend_resize(dp->dirs, dp->ndirs, sizeof(Id), DIR_BLOCK);
      dp->dirs[0] = 0;
      dp->dirs[1] = 1;	/* "" */
    }
  if (comp <= 0)
    return 0;
  if (parent == 0 && comp == 1)
    return 1;
  if (!dp->dirtraverse)
    dirpool_make_dirtraverse(dp);
  /* check all entries with this parent if we
   * already have this component */
  ds = dp->dirtraverse[parent];
  while (ds)
    {
      /* ds: first component in this block
       * ds-1: parent link */
      for (d = ds--; d < dp->ndirs; d++)
	{
	  if (dp->dirs[d] == comp)
	    return d;
	  if (dp->dirs[d] <= 0)	/* reached end of this block */
	    break;
	}
      if (ds)
        ds = dp->dirtraverse[ds];
    }
  if (!create)
    return 0;
  /* a new one, find last parent */
  for (did = dp->ndirs - 1; did > 0; did--)
    if (dp->dirs[did] <= 0)
      break;
  if (dp->dirs[did] != -parent)
    {
      /* make room for parent entry */
      dp->dirs = solv_extend(dp->dirs, dp->ndirs, 1, sizeof(Id), DIR_BLOCK);
      dp->dirtraverse = solv_extend(dp->dirtraverse, dp->ndirs, 1, sizeof(Id), DIR_BLOCK);
      /* new parent block, link in */
      dp->dirs[dp->ndirs] = -parent;
      dp->dirtraverse[dp->ndirs] = dp->dirtraverse[parent];
      dp->dirtraverse[parent] = ++dp->ndirs;
    }
  /* make room for new entry */
  dp->dirs = solv_extend(dp->dirs, dp->ndirs, 1, sizeof(Id), DIR_BLOCK);
  dp->dirtraverse = solv_extend(dp->dirtraverse, dp->ndirs, 1, sizeof(Id), DIR_BLOCK);
  dp->dirs[dp->ndirs] = comp;
  dp->dirtraverse[dp->ndirs] = 0;
  return dp->ndirs++;
}
예제 #3
0
Offset
repo_reserve_ids(Repo *repo, Offset olddeps, int num)
{
  num++;	/* room for trailing ID_NULL */

  if (!repo->idarraysize)	       /* ensure buffer space */
    {
      repo->idarraysize = 1;
      repo->idarraydata = solv_extend_resize(0, 1 + num, sizeof(Id), IDARRAY_BLOCK);
      repo->idarraydata[0] = 0;
      repo->lastoff = 1;
      return 1;
    }

  if (olddeps && olddeps != repo->lastoff)   /* if not appending */
    {
      /* can't insert into idarray, this would invalidate all 'larger' offsets
       * so create new space at end and move existing deps there.
       * Leaving 'hole' at old position.
       */

      Id *idstart, *idend;
      int count;

      for (idstart = idend = repo->idarraydata + olddeps; *idend++; )   /* find end */
	;
      count = idend - idstart - 1 + num;	       /* new size */

      repo->idarraydata = solv_extend(repo->idarraydata, repo->idarraysize, count, sizeof(Id), IDARRAY_BLOCK);
      /* move old deps to end */
      olddeps = repo->lastoff = repo->idarraysize;
      memcpy(repo->idarraydata + olddeps, idstart, count - num);
      repo->idarraysize = olddeps + count - num;

      return olddeps;
    }

  if (olddeps)			       /* appending */
    repo->idarraysize--;

  /* make room*/
  repo->idarraydata = solv_extend(repo->idarraydata, repo->idarraysize, num, sizeof(Id), IDARRAY_BLOCK);

  /* appending or new */
  repo->lastoff = olddeps ? olddeps : repo->idarraysize;

  return repo->lastoff;
}
예제 #4
0
FILE *
solv_xfopen_buf(const char *fn, char **bufp, size_t *buflp, const char *mode)
{
  struct bufcookie *bc;
  FILE *fp;
  if (*mode != 'r' && *mode != 'w')
    return 0;
  bc = solv_calloc(1, sizeof(*bc));
  bc->freemem = 0;
  bc->bufp = bufp;
  if (!buflp)
    {
      bc->bufl_int = *mode == 'w' ? 0 : strlen(*bufp);
      buflp = &bc->bufl_int;
    }
  bc->buflp = buflp;
  if (*mode == 'w')
    {
      *bc->bufp = solv_extend(0, 0, 1, 1, 4095);	/* always zero-terminate */
      (*bc->bufp)[0] = 0;
      *bc->buflp = 0;
    }
  fp = cookieopen(bc, mode, cookie_bufread, cookie_bufwrite, cookie_bufclose);
  if (!strcmp(mode, "rf"))	/* auto-free */
    bc->freemem = *bufp;
  if (!fp)
    {
      if (*mode == 'w')
	*bc->bufp = solv_free(*bc->bufp);
      cookie_bufclose(bc);
    }
  return fp;
}
예제 #5
0
Offset
repo_addid(Repo *repo, Offset olddeps, Id id)
{
  Id *idarray;
  int idarraysize;
  int i;

  idarray = repo->idarraydata;
  idarraysize = repo->idarraysize;

  if (!idarray)			       /* alloc idarray if not done yet */
    {
      idarraysize = 1;
      idarray = solv_extend_resize(0, 1, sizeof(Id), IDARRAY_BLOCK);
      idarray[0] = 0;
      repo->lastoff = 0;
    }

  if (!olddeps)				/* no deps yet */
    {
      olddeps = idarraysize;
      idarray = solv_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK);
    }
  else if (olddeps == repo->lastoff)	/* extend at end */
    idarraysize--;
  else					/* can't extend, copy old */
    {
      i = olddeps;
      olddeps = idarraysize;
      for (; idarray[i]; i++)
        {
	  idarray = solv_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK);
          idarray[idarraysize++] = idarray[i];
        }
      idarray = solv_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK);
    }

  idarray[idarraysize++] = id;		/* insert Id into array */
  idarray = solv_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK);
  idarray[idarraysize++] = 0;		/* ensure NULL termination */

  repo->idarraydata = idarray;
  repo->idarraysize = idarraysize;
  repo->lastoff = olddeps;

  return olddeps;
}
예제 #6
0
static inline Id
addfilesspace(struct cbdata *cbdata, int len)
{
  unsigned int off = cbdata->filesspacen;
  cbdata->filesspace = solv_extend(cbdata->filesspace, cbdata->filesspacen, len, 1, FILESSPACE_BLOCK);
  cbdata->filesspacen += len;
  return off;
}
예제 #7
0
char *
findmetalinkurl(FILE *fp, unsigned char *chksump, Id *chksumtypep)
{
  char buf[4096], *bp, *ep;
  char **urls = 0;
  int nurls = 0;
  int i;

  if (chksumtypep)
    *chksumtypep = 0;
  while((bp = fgets(buf, sizeof(buf), fp)) != 0)
    {
      while (*bp == ' ' || *bp == '\t')
	bp++;
      if (chksumtypep && !*chksumtypep && !strncmp(bp, "<hash type=\"sha256\">", 20))
	{
	  bp += 20;
	  if (solv_hex2bin((const char **)&bp, chksump, 32) == 32)
	    *chksumtypep = REPOKEY_TYPE_SHA256;
	  continue;
	}
      if (strncmp(bp, "<url", 4))
	continue;
      bp = strchr(bp, '>');
      if (!bp)
	continue;
      bp++;
      ep = strstr(bp, "repodata/repomd.xml</url>");
      if (!ep)
	continue;
      *ep = 0;
      if (strncmp(bp, "http", 4))
	continue;
      urls = solv_extend(urls, nurls, 1, sizeof(*urls), 15);
      urls[nurls++] = strdup(bp);
    }
  if (nurls)
    {
      if (nurls > 1)
        findfastest(urls, nurls > 5 ? 5 : nurls);
      bp = urls[0];
      urls[0] = 0;
      for (i = 0; i < nurls; i++)
        solv_free(urls[i]);
      solv_free(urls);
      ep = strchr(bp, '/');
      if ((ep = strchr(ep + 2, '/')) != 0)
	{
	  *ep = 0;
	  printf("[using mirror %s]\n", bp);
	  *ep = '/';
	}
      return bp;
    }
  return 0;
}
예제 #8
0
파일: subject-py.c 프로젝트: gbraad/libhif
static HyForm *
forms_from_list(PyObject *list)
{
    HyForm *forms = NULL;
    int i = 0;
    const int BLOCK_SIZE = 6;
    while (i < PyList_Size(list)) {
        PyObject *form = PyList_GetItem(list, i);
        if (!PyInt_Check(form)) {
            g_free(forms);
            return NULL;
        }
        forms = solv_extend(forms, i, 1, sizeof(HyForm), BLOCK_SIZE);
        forms[i++] = PyLong_AsLong(form);
    }
    forms = solv_extend(forms, i, 1, sizeof(HyForm), BLOCK_SIZE);
    forms[i] = _HY_FORM_STOP_;
    return forms;
}
예제 #9
0
void *
repo_sidedata_extend(Repo *repo, void *b, size_t size, Id p, int count)
{
  int n = repo->end - repo->start;
  if (p < repo->start)
    {
      int d = repo->start - p;
      b = solv_extend(b, n, d, size, REPO_SIDEDATA_BLOCK);
      memmove((char *)b + d * size, b, n * size);
      memset(b, 0, d * size);
      n += d;
    }
  if (p + count > repo->end)
    {
      int d = p + count - repo->end;
      b = solv_extend(b, n, d, size, REPO_SIDEDATA_BLOCK);
      memset((char *)b + n * size, 0, d * size);
    }
  return b;
}
예제 #10
0
HyStringArray
hy_package_get_files(HyPackage pkg)
{
    Pool *pool = package_pool(pkg);
    Solvable *s = get_solvable(pkg);
    Dataiterator di;
    int len = 0;
    HyStringArray strs = solv_extend(0, 0, 1, sizeof(char*), BLOCK_SIZE);

    repo_internalize_trigger(s->repo);
    dataiterator_init(&di, pool, s->repo, pkg->id, SOLVABLE_FILELIST, NULL,
		      SEARCH_FILES | SEARCH_COMPLETE_FILELIST);
    while (dataiterator_step(&di)) {
	strs[len++] = solv_strdup(di.kv.str);
	strs = solv_extend(strs, len, 1, sizeof(char*), BLOCK_SIZE);
    }
    dataiterator_free(&di);
    strs[len++] = NULL;
    return strs;
}
예제 #11
0
static ssize_t cookie_bufwrite(void *cookie, const char *buf, size_t nbytes)
{
  struct bufcookie *bc = cookie;
  int n = nbytes > 0x40000000 ? 0x40000000 : nbytes;
  if (n)
    {
      *bc->bufp = solv_extend(*bc->bufp, *bc->buflp, n + 1, 1, 4095);
      memcpy(*bc->bufp, buf, n);
      (*bc->bufp)[n] = 0;	/* zero-terminate */
      *bc->buflp += n;
    }
  return n;
}
예제 #12
0
static HyForm *
forms_dup(HyForm *forms)
{
    if (forms == NULL)
        return NULL;
    HyForm *res = NULL;
    const int BLOCK_SIZE = 6;
    HyForm form;
    int i = 0;
    do {
        res = solv_extend(res, i, 1, sizeof(HyForm), BLOCK_SIZE);
        form = forms[i];
        res[i++] = form;
    } while (form != _HY_FORM_STOP_);
    return res;
}
예제 #13
0
char *
findmirrorlisturl(FILE *fp)
{
  char buf[4096], *bp, *ep;
  int i, l;
  char **urls = 0;
  int nurls = 0;

  while((bp = fgets(buf, sizeof(buf), fp)) != 0)
    {
      while (*bp == ' ' || *bp == '\t')
	bp++;
      if (!*bp || *bp == '#')
	continue;
      l = strlen(bp);
      while (l > 0 && (bp[l - 1] == ' ' || bp[l - 1] == '\t' || bp[l - 1] == '\n'))
	bp[--l] = 0;
      if ((ep = strstr(bp, "url=")) != 0)
	bp = ep + 4;
      urls = solv_extend(urls, nurls, 1, sizeof(*urls), 15);
      urls[nurls++] = strdup(bp);
    }
  if (nurls)
    {
      if (nurls > 1)
        findfastest(urls, nurls > 5 ? 5 : nurls);
      bp = urls[0];
      urls[0] = 0;
      for (i = 0; i < nurls; i++)
        solv_free(urls[i]);
      solv_free(urls);
      ep = strchr(bp, '/');
      if ((ep = strchr(ep + 2, '/')) != 0)
	{
	  *ep = 0;
	  printf("[using mirror %s]\n", bp);
	  *ep = '/';
	}
      return bp;
    }
  return 0;
}
예제 #14
0
파일: rpms2solv.c 프로젝트: zde/libsolv
int
main(int argc, char **argv)
{
    const char **rpms = 0;
    char *manifest = 0;
    int manifest0 = 0;
    int c, i, res, nrpms = 0;
    Pool *pool = pool_create();
    Repo *repo;
    FILE *fp;
    char buf[4096], *p;
    const char *basefile = 0;
#ifdef ENABLE_PUBKEY
    int pubkeys = 0;
#endif

    while ((c = getopt(argc, argv, "0kKb:m:")) >= 0)
    {
        switch(c)
        {
        case 'b':
            basefile = optarg;
            break;
        case 'm':
            manifest = optarg;
            break;
        case '0':
            manifest0 = 1;
            break;
#ifdef ENABLE_PUBKEY
        case 'k':
            pubkeys = 1;
            break;
        case 'K':
            pubkeys = 2;
            break;
#endif
        default:
            exit(1);
        }
    }
    if (manifest)
    {
        if (!strcmp(manifest, "-"))
            fp = stdin;
        else if ((fp = fopen(manifest, "r")) == 0)
        {
            perror(manifest);
            exit(1);
        }
        for (;;)
        {
            if (manifest0)
            {
                if (!fgets0(buf, sizeof(buf), fp))
                    break;
            }
            else
            {
                if (!fgets(buf, sizeof(buf), fp))
                    break;
                if ((p = strchr(buf, '\n')) != 0)
                    *p = 0;
            }
            rpms = solv_extend(rpms, nrpms, 1, sizeof(char *), 15);
            rpms[nrpms++] = strdup(buf);
        }
        if (fp != stdin)
            fclose(fp);
    }
    while (optind < argc)
    {
        rpms = solv_extend(rpms, nrpms, 1, sizeof(char *), 15);
        rpms[nrpms++] = strdup(argv[optind++]);
    }
    repo = repo_create(pool, "rpms2solv");
    repo_add_repodata(repo, 0);
    res = 0;
    for (i = 0; i < nrpms; i++)
    {
#ifdef ENABLE_PUBKEY
        if (pubkeys == 2)
        {
            FILE *fp = solv_xfopen(rpms[i], "r");
            if (!fp)
            {
                perror(rpms[i]);
                res = 1;
                continue;
            }
            if (repo_add_keyring(repo, fp, REPO_REUSE_REPODATA|REPO_NO_INTERNALIZE|ADD_WITH_KEYSIGNATURES))
            {
                fprintf(stderr, "rpms2solv: %s\n", pool_errstr(pool));
                res = 1;
            }
            fclose(fp);
            continue;
        }
        if (pubkeys)
        {
            if (repo_add_pubkey(repo, rpms[i], REPO_REUSE_REPODATA|REPO_NO_INTERNALIZE|ADD_WITH_KEYSIGNATURES) == 0)
            {
                fprintf(stderr, "rpms2solv: %s\n", pool_errstr(pool));
                res = 1;
            }
            continue;
        }
#endif
        if (repo_add_rpm(repo, rpms[i], REPO_REUSE_REPODATA|REPO_NO_INTERNALIZE) == 0)
        {
            fprintf(stderr, "rpms2solv: %s\n", pool_errstr(pool));
            res = 1;
        }
    }
    repo_internalize(repo);
    tool_write(repo, basefile, 0);
    pool_free(pool);
    for (c = 0; c < nrpms; c++)
        free((char *)rpms[c]);
    solv_free(rpms);
    exit(res);
}
예제 #15
0
int
main(int argc, char **argv)
{
  const char **debs = 0;
  char *manifest = 0;
  int manifest0 = 0;
  int c, i, res, ndebs = 0;
  Pool *pool = pool_create();
  Repo *repo;
  FILE *fp;
  char buf[4096], *p;
  const char *basefile = 0;
  int is_repo = 0;

  while ((c = getopt(argc, argv, "0b:m:r")) >= 0)
    {
      switch(c)
	{
	case 'b':
	  basefile = optarg;
	  break;
	case 'm':
	  manifest = optarg;
	  break;
	case 'r':
	  is_repo = 1;
	  break;
	case '0':
	  manifest0 = 1;
	  break;
	default:
	  exit(1);
	}
    }
  if (manifest)
    {
      if (!strcmp(manifest, "-"))
        fp = stdin;
      else if ((fp = fopen(manifest, "r")) == 0)
	{
	  perror(manifest);
	  exit(1);
	}
      for (;;)
	{
	  if (manifest0)
	    {
	      if (!fgets0(buf, sizeof(buf), fp))
		break;
	    }
	  else
	    {
	      if (!fgets(buf, sizeof(buf), fp))
		break;
	      if ((p = strchr(buf, '\n')) != 0)
		*p = 0;
	    }
          debs = solv_extend(debs, ndebs, 1, sizeof(char *), 15);
	  debs[ndebs++] = strdup(buf);
	}
      if (fp != stdin)
        fclose(fp);
    }
  while (optind < argc)
    {
      debs = solv_extend(debs, ndebs, 1, sizeof(char *), 15);
      debs[ndebs++] = strdup(argv[optind++]);
    }
  repo = repo_create(pool, "deb2solv");
  repo_add_repodata(repo, 0);
  res = 0;
  if (!ndebs && !manifest && is_repo)
    {
      if (repo_add_debpackages(repo, stdin, REPO_REUSE_REPODATA|REPO_NO_INTERNALIZE))
	{
	  fprintf(stderr, "deb2solv: %s\n", pool_errstr(pool));
	  res = 1;
	}
    }
  for (i = 0; i < ndebs; i++)
    {
      if (is_repo)
	{
	  if ((fp = fopen(debs[i], "r")) == 0)
	    {
	      perror(debs[i]);
	      res = 1;
	      continue;
	    }
	  if (repo_add_debpackages(repo, fp, REPO_REUSE_REPODATA|REPO_NO_INTERNALIZE))
	    {
	      fprintf(stderr, "deb2solv: %s\n", pool_errstr(pool));
	      res = 1;
	    }
	  fclose(fp);
	  continue;
	}
      if (repo_add_deb(repo, debs[i], REPO_REUSE_REPODATA|REPO_NO_INTERNALIZE) == 0)
	{
	  fprintf(stderr, "deb2solv: %s\n", pool_errstr(pool));
	  res = 1;
	}
    }
  repo_internalize(repo);
  tool_write(repo, basefile, 0);
  pool_free(pool);
  for (c = 0; c < ndebs; c++)
    free((char *)debs[c]);
  solv_free(debs);
  exit(res);
}
예제 #16
0
파일: poolid.c 프로젝트: korli/libsolv
Id
pool_rel2id(Pool *pool, Id name, Id evr, int flags, int create)
{
  Hashval h, hh, hashmask;
  int i;
  Id id;
  Hashtable hashtbl;
  Reldep *ran;

  hashmask = pool->relhashmask;
  hashtbl = pool->relhashtbl;
  ran = pool->rels;
  
  /* extend hashtable if needed */
  if (pool->nrels * 2 > hashmask)
    {
      solv_free(pool->relhashtbl);
      pool->relhashmask = hashmask = mkmask(pool->nrels + REL_BLOCK);
      pool->relhashtbl = hashtbl = solv_calloc(hashmask + 1, sizeof(Id));
      /* rehash all rels into new hashtable */
      for (i = 1; i < pool->nrels; i++)
	{
	  h = relhash(ran[i].name, ran[i].evr, ran[i].flags) & hashmask;
	  hh = HASHCHAIN_START;
	  while (hashtbl[h])
	    h = HASHCHAIN_NEXT(h, hh, hashmask);
	  hashtbl[h] = i;
	}
    }
  
  /* compute hash and check for match */
  h = relhash(name, evr, flags) & hashmask;
  hh = HASHCHAIN_START;
  while ((id = hashtbl[h]) != 0)
    {
      if (ran[id].name == name && ran[id].evr == evr && ran[id].flags == flags)
	break;
      h = HASHCHAIN_NEXT(h, hh, hashmask);
    }
  if (id)
    return MAKERELDEP(id);

  if (!create)
    return ID_NULL;

  id = pool->nrels++;
  /* extend rel space if needed */
  pool->rels = solv_extend(pool->rels, id, 1, sizeof(Reldep), REL_BLOCK);
  hashtbl[h] = id;
  ran = pool->rels + id;
  ran->name = name;
  ran->evr = evr;
  ran->flags = flags;

  /* extend whatprovides_rel if needed */
  if (pool->whatprovides_rel && (id & WHATPROVIDES_BLOCK) == 0)
    {
      pool->whatprovides_rel = solv_realloc2(pool->whatprovides_rel, id + (WHATPROVIDES_BLOCK + 1), sizeof(Offset));
      memset(pool->whatprovides_rel + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset));
    }
  return MAKERELDEP(id);
}
예제 #17
0
파일: packagelist.c 프로젝트: Xake/hawkey
/**
 * Adds pkg at the end of plist.
 *
 * Assumes ownership of pkg and will free it during hy_packagelist_free().
 */
void hy_packagelist_push(HyPackageList plist, HyPackage pkg)
{
    plist->elements = solv_extend(plist->elements, plist->count, 1,
				  sizeof(pkg), BLOCK_SIZE);
    plist->elements[plist->count++] = pkg;
}
예제 #18
0
static void
pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct searchfiles *isf)
{
  Id dep, sid;
  const char *s;
  struct searchfiles *csf;

  while ((dep = *ida++) != 0)
    {
      csf = sf;
      while (ISRELDEP(dep))
	{
	  Reldep *rd;
	  sid = pool->ss.nstrings + GETRELID(dep);
	  if (MAPTST(&csf->seen, sid))
	    {
	      dep = 0;
	      break;
	    }
	  MAPSET(&csf->seen, sid);
	  rd = GETRELDEP(pool, dep);
	  if (rd->flags < 8)
	    dep = rd->name;
	  else if (rd->flags == REL_NAMESPACE)
	    {
	      if (rd->name == NAMESPACE_SPLITPROVIDES)
		{
		  csf = isf;
		  if (!csf || MAPTST(&csf->seen, sid))
		    {
		      dep = 0;
		      break;
		    }
		  MAPSET(&csf->seen, sid);
		}
	      dep = rd->evr;
	    }
	  else if (rd->flags == REL_FILECONFLICT)
	    {
	      dep = 0;
	      break;
	    }
	  else
	    {
	      Id ids[2];
	      ids[0] = rd->name;
	      ids[1] = 0;
	      pool_addfileprovides_dep(pool, ids, csf, isf);
	      dep = rd->evr;
	    }
	}
      if (!dep)
	continue;
      if (MAPTST(&csf->seen, dep))
	continue;
      MAPSET(&csf->seen, dep);
      s = pool_id2str(pool, dep);
      if (*s != '/')
	continue;
      if (csf != isf && pool->addedfileprovides == 1 && !repodata_filelistfilter_matches(0, s))
	continue;	/* skip non-standard locations csf == isf: installed case */
      csf->ids = solv_extend(csf->ids, csf->nfiles, 1, sizeof(Id), SEARCHFILES_BLOCK);
      csf->ids[csf->nfiles++] = dep;
    }
}
예제 #19
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;
}
예제 #20
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;
  const char *pkgid;

  // 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.
      */
      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 = solv_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;
    }
}