Exemple #1
0
static int
init_test_globals(struct TestGlobals_s *tg, const char *repo_dir)
{
    int const len = strlen(repo_dir);
    if (repo_dir[len -1] != '/')
	tg->repo_dir = solv_dupjoin(repo_dir, "/", NULL);
    else
	tg->repo_dir = solv_strdup(repo_dir);
    tg->tmpdir = solv_strdup(UNITTEST_DIR);
    if (mkdtemp(tg->tmpdir) == NULL)
	return 1;
    tg->sack = NULL;
    return 0;
}
Exemple #2
0
// 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;
}
Exemple #3
0
int
hy_detect_arch(char **arch)
{
    struct utsname un;

    if (uname(&un))
	return HY_E_FAILED;

    if (!strcmp(un.machine, "armv6l")) {
	int flags = 0;
	int ret = parse_cpu_flags(&flags, "Features");
	if (ret)
	    return ret;
	if (flags & ARM_VFP)
	    strcpy(un.machine, "armv6hl");
    }
    if (!strcmp(un.machine, "armv7l")) {
	int flags = 0;
	int ret = parse_cpu_flags(&flags, "Features");
	if (ret)
	    return ret;
	if (flags & (ARM_NEON | ARM_VFP3))
	    strcpy(un.machine, "armv7hnl");
	else if (flags & ARM_VFP3)
	    strcpy(un.machine, "armv7hl");
    }
#ifdef __MIPSEL__
    if (!strcmp(un.machine, "mips"))
	strcpy(un.machine, "mipsel");
    else if (!strcmp(un.machine, "mips64"))
	strcpy(un.machine, "mips64el");
#endif
    *arch = solv_strdup(un.machine);
    return 0;
}
Exemple #4
0
static int
glob_for_cachedir(char *path)
{
    int ret = 1;
    if (!str_endswith(path, "XXXXXX"))
	return ret;

    wordexp_t word_vector;
    char *p = solv_strdup(path);
    const int len = strlen(p);
    struct stat s;

    ret = 2;
    p[len-6] = '*';
    p[len-5] = '\0';
    if (wordexp(p, &word_vector, 0)) {
	solv_free(p);
	return ret;
    }
    for (int i = 0; i < word_vector.we_wordc; ++i) {
	char *entry = word_vector.we_wordv[i];
	if (stat(entry, &s))
	    continue;
	if (S_ISDIR(s.st_mode) &&
	    s.st_uid == getuid()) {
	    assert(strlen(path) == strlen(entry));
	    strcpy(path, entry);
	    ret = 0;
	    break;
	}
    }
    wordfree(&word_vector);
    solv_free(p);
    return ret;
}
Exemple #5
0
/**
 * Recursively create directory.
 *
 * If it is in the format accepted by mkdtemp() the function globs for a
 * matching name and if not found it uses mkdtemp() to create the path. 'path'
 * is modified in those two cases.
 */
int
mkcachedir(char *path)
{
    int ret = 1;

    if (!glob_for_cachedir(path))
	return 0;

    const int len = strlen(path);
    if (len < 1 || path[0] != '/')
	return 1; // only absolute pathnames are accepted

    char *p = solv_strdup(path);

    if (p[len-1] == '/')
	p[len-1] = '\0';

    if (access(p, X_OK)) {
	*(strrchr(p, '/')) = '\0';
	ret = mkcachedir(p);
	if (str_endswith(path, "XXXXXX")) {
	    char *retptr = mkdtemp(path);
	    if (retptr == NULL)
		ret |= 1;
	} else
	    ret |= mkdir(path, CACHEDIR_PERMISSIONS);
    } else {
	ret = 0;
    }

    solv_free(p);
    return ret;
}
Exemple #6
0
char *
hy_package_get_location(HyPackage pkg)
{
    Solvable *s = get_solvable(pkg);
    repo_internalize_trigger(s->repo);
    return solv_strdup(solvable_get_location(s, NULL));
}
Exemple #7
0
char *
hy_package_get_version(HyPackage pkg)
{
    char *e, *v, *r;

    pool_split_evr(package_pool(pkg), hy_package_get_evr(pkg), &e, &v, &r);
    return solv_strdup(v);
}
Exemple #8
0
char *
hy_package_get_release(HyPackage pkg)
{
    char *e, *v, *r;

    pool_split_evr(package_pool(pkg), hy_package_get_evr(pkg), &e, &v, &r);
    return solv_strdup(r);
}
Exemple #9
0
static inline const char *
find_attr(const char *txt, const char **atts, int dup)
{
  for (; *atts; atts += 2)
    {
      if (!strcmp(*atts, txt))
        return dup ? solv_strdup(atts[1]) : atts[1];
    }
  return 0;
}
Exemple #10
0
HyPackageDelta
hy_package_get_delta_from_evr(HyPackage pkg, const char *from_evr)
{
    Pool *pool = package_pool(pkg);
    Solvable *s = get_solvable(pkg);
    HyPackageDelta delta = NULL;
    Dataiterator di;
    Id checksum_type;
    const unsigned char *checksum;
    const char *name = hy_package_get_name(pkg);

    dataiterator_init(&di, pool, s->repo, SOLVID_META, DELTA_PACKAGE_NAME, name,
		      SEARCH_STRING);
    dataiterator_prepend_keyname(&di, REPOSITORY_DELTAINFO);
    while (dataiterator_step(&di)) {
	dataiterator_setpos_parent(&di);
	if (pool_lookup_id(pool, SOLVID_POS, DELTA_PACKAGE_EVR) != s->evr ||
	    pool_lookup_id(pool, SOLVID_POS, DELTA_PACKAGE_ARCH) != s->arch)
	    continue;
	const char * base_evr = pool_id2str(pool, pool_lookup_id(pool, SOLVID_POS,
								 DELTA_BASE_EVR));
	if (strcmp(base_evr, from_evr))
	    continue;

	// we have the right delta info, set up HyPackageDelta and break out:
	delta = delta_create();
	delta->location = solv_strdup(pool_lookup_deltalocation(pool, SOLVID_POS, 0));
	delta->baseurl = solv_strdup(pool_lookup_str(pool, SOLVID_POS, DELTA_LOCATION_BASE));
	delta->downloadsize = pool_lookup_num(pool, SOLVID_POS, DELTA_DOWNLOADSIZE, 0);
	checksum = pool_lookup_bin_checksum(pool, SOLVID_POS, DELTA_CHECKSUM, &checksum_type);
	if (checksum) {
	    delta->checksum_type = checksumt_l2h(checksum_type);
	    delta->checksum = solv_memdup((void*)checksum, checksum_type2length(delta->checksum_type));
	}

	break;
    }
    dataiterator_free(&di);

    return delta;
}
Exemple #11
0
void
hy_repo_set_string(HyRepo repo, int which, const char *str_val)
{
    switch (which) {
    case HY_REPO_NAME:
	solv_free(repo->name);
	repo->name = solv_strdup(str_val);
	break;
    case HY_REPO_MD_FN:
	solv_free(repo->repomd_fn);
	repo->repomd_fn = solv_strdup(str_val);
	break;
    case HY_REPO_PRIMARY_FN:
	solv_free(repo->primary_fn);
	repo->primary_fn = solv_strdup(str_val);
	break;
    case HY_REPO_FILELISTS_FN:
	solv_free(repo->filelists_fn);
	repo->filelists_fn = solv_strdup(str_val);
	break;
    case HY_REPO_PRESTO_FN:
	solv_free(repo->presto_fn);
	repo->presto_fn = solv_strdup(str_val);
	break;
    case HY_REPO_UPDATEINFO_FN:
	solv_free(repo->updateinfo_fn);
	repo->updateinfo_fn = solv_strdup(str_val);
	break;
    default:
	assert(0);
    }
}
Exemple #12
0
/* split filelist dep into basename and dirname */
static void
create_dirs_names_array(struct addfileprovides_cbdata *cbd, Pool *pool)
{
  int i;
  cbd->dirs = solv_malloc2(cbd->nfiles, sizeof(char *));
  cbd->names = solv_malloc2(cbd->nfiles, sizeof(char *));
  for (i = 0; i < cbd->nfiles; i++)
    {
      char *s = solv_strdup(pool_id2str(pool, cbd->ids[i]));
      cbd->dirs[i] = s;
      s = strrchr(s, '/');
      *s = 0;
      cbd->names[i] = s + 1;
    }
}
Exemple #13
0
int
hy_split_nevra(const char *nevra, char **name, long int *epoch,
	       char **version, char **release, char **arch)
{
    const int len = strlen(nevra);
    if (len <= 0)
	return HY_E_OP;

    const char *m1 = NULL, *m2 = NULL, *m3 = NULL;
    const char *c;
    for (c = nevra + len - 1; c > nevra; --c)
	if (*c == '.') {
	    m3 = c;
	    break;
	}
    if (c == nevra)
	return HY_E_OP;

    for (; c > nevra; --c)
	if (*c == '-') {
	    if (m2 == NULL)
		m2 = c;
	    else if (m1 == NULL) {
		m1 = c;
		break;
	    }
	}
    if (c == nevra)
	return HY_E_OP;

    *arch = solv_strdup(m3+1);
    *name = hy_strndup(nevra, (m1 - nevra));
    *release = hy_strndup(m2 + 1, (m3 - m2 - 1));

    char *endptr;
    long int converted;
    errno = 0;
    converted = strtol(m1 + 1, &endptr, 10);
    if (!errno && *endptr == ':') {
	*epoch = converted;
	*version = hy_strndup(endptr + 1, (m2 - endptr - 1));
    } else {
	*epoch = 0;
	*version = hy_strndup(m1 + 1, (m2 - m1 - 1));
    }

    return 0;
}
Exemple #14
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;
}
Exemple #15
0
char *
abspath(const char *path)
{
    const int len = strlen(path);
    if (len <= 1) {
	hy_errno = HY_E_OP;
	return NULL;
    }

    if (path[0] == '/')
	return solv_strdup(path);

    char cwd[PATH_MAX];
    if (!getcwd(cwd, PATH_MAX)) {
	hy_errno = HY_E_FAILED;
	return NULL;
    }

    return solv_dupjoin(cwd, "/", path);
}
Exemple #16
0
/* add all files ending in .appdata.xml */
int
repo_add_appdata_dir(Repo *repo, const char *appdatadir, int flags)
{
  DIR *dir;
  char *dirpath;
  Repodata *data;

  data = repo_add_repodata(repo, flags);
  if (flags & REPO_USE_ROOTDIR)
    dirpath = pool_prepend_rootdir(repo->pool, appdatadir);
  else
    dirpath = solv_strdup(appdatadir);
  if ((dir = opendir(dirpath)) != 0)
    {
      struct dirent *entry;
      while ((entry = readdir(dir)))
	{
	  const char *n;
	  FILE *fp;
	  int len = strlen(entry->d_name);
	  if (len <= 12 || strcmp(entry->d_name + len - 12, ".appdata.xml") != 0)
	    continue;
	  if (entry->d_name[0] == '.')
	    continue;
          n = pool_tmpjoin(repo->pool, dirpath, "/", entry->d_name);
	  fp = fopen(n, "r");
	  if (!fp)
	    {
	      pool_error(repo->pool, 0, "%s: %s", n, strerror(errno));
	      continue;
	    }
	  repo_add_appdata(repo, fp, flags | REPO_NO_INTERNALIZE | REPO_REUSE_REPODATA);
	  fclose(fp);
	}
    }
  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  return 0;
}
Exemple #17
0
void
pool_setvendorclasses(Pool *pool, const char **vendorclasses)
{
  int i;
  const char **v;

  if (pool->vendorclasses)
    {
      for (v = pool->vendorclasses; v[0] || v[1]; v++)
	solv_free((void *)*v);
      pool->vendorclasses = solv_free((void *)pool->vendorclasses);
    }
  if (!vendorclasses || !vendorclasses[0])
    return;
  for (v = vendorclasses; v[0] || v[1]; v++)
    ;
  pool->vendorclasses = solv_calloc(v - vendorclasses + 2, sizeof(const char *));
  for (v = vendorclasses, i = 0; v[0] || v[1]; v++, i++)
    pool->vendorclasses[i] = *v ? solv_strdup(*v) : 0;
  pool->vendorclasses[i++] = 0;
  pool->vendorclasses[i] = 0;
  queue_empty(&pool->vendormap);
}
Exemple #18
0
void
pool_addvendorclass(Pool *pool, const char **vendorclass)
{
  int i, j;

  if (!vendorclass || !vendorclass[0])
    return;
  for (j = 1; vendorclass[j]; j++)
    ;
  i = 0;
  if (pool->vendorclasses)
    {
      for (i = 0; pool->vendorclasses[i] || pool->vendorclasses[i + 1]; i++)
	;
      if (i)
        i++;
    }
  pool->vendorclasses = solv_realloc2((void *)pool->vendorclasses, i + j + 2, sizeof(const char *));
  for (j = 0; vendorclass[j]; j++)
    pool->vendorclasses[i++] = solv_strdup(vendorclass[j]);
  pool->vendorclasses[i++] = 0;
  pool->vendorclasses[i] = 0;
  queue_empty(&pool->vendormap);
}
Exemple #19
0
Repo *
repo_create(Pool *pool, const char *name)
{
  Repo *repo;

  pool_freewhatprovides(pool);
  repo = (Repo *)solv_calloc(1, sizeof(*repo));
  if (!pool->nrepos)
    {
      pool->nrepos = 1;	/* start with repoid 1 */
      pool->repos = (Repo **)solv_calloc(2, sizeof(Repo *));
    }
  else
    pool->repos = (Repo **)solv_realloc2(pool->repos, pool->nrepos + 1, sizeof(Repo *));
  pool->repos[pool->nrepos] = repo;
  pool->urepos++;
  repo->repoid = pool->nrepos++;
  repo->name = name ? solv_strdup(name) : 0;
  repo->pool = pool;
  repo->start = pool->nsolvables;
  repo->end = pool->nsolvables;
  repo->nsolvables = 0;
  return repo;
}
Exemple #20
0
char *
hy_package_get_sourcerpm(HyPackage pkg)
{
    Solvable *s = get_solvable(pkg);
    return solv_strdup(solvable_lookup_sourcepkg(s));
}
Exemple #21
0
char *
hy_package_get_nevra(HyPackage pkg)
{
    Solvable *s = get_solvable(pkg);
    return solv_strdup(pool_solvable2str(package_pool(pkg), s));
}
Exemple #22
0
static void XMLCALL
endElement(void *userData, const char *name)
{
  Parsedata *pd = (Parsedata *)userData;
  Pool *pool = pd->pool;
  Solvable *s = pd->solvable;
  Id evr;
  unsigned int t = 0;
  const char *flavor;

  if (pd->depth != pd->statedepth)
    {
      pd->depth--;
      /* printf("back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth); */
      return;
    }

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

  pd->depth--;
  pd->statedepth--;
  switch (pd->state)
    {

    case STATE_PACKAGE:		       /* package complete */
      if (name[0] == 's' && name[1] == 'r' && name[2] == 'c' && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
	s->arch = ARCH_SRC;
      if (!s->arch)                    /* default to "noarch" */
	s->arch = ARCH_NOARCH;

      if (!s->evr && pd->version)      /* set solvable evr */
        s->evr = evr2id(pool, pd,
                        pd->epoch   ? pd->evrspace + pd->epoch   : 0,
                        pd->version ? pd->evrspace + pd->version : 0,
                        pd->release ? pd->evrspace + pd->release : "");
      /* ensure self-provides */
      if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
        s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
      s->supplements = repo_fix_supplements(pd->repo, s->provides, s->supplements, pd->freshens);
      s->conflicts = repo_fix_conflicts(pd->repo, s->conflicts);
      pd->freshens = 0;

      /* see bugzilla bnc#190163 */
      flavor = findKernelFlavor(pd, s);
      if (flavor) 
	{
	  char *cflavor = solv_strdup(flavor);	/* make pointer safe */

	  Id npr;
	  Id pid;

	  /* this is either a kernel package or a kmp */
	  if (s->provides)
	    {
	      Offset prov = s->provides;
	      npr = 0;
	      while ((pid = pd->repo->idarraydata[prov++]) != 0)
		{
		  const char *depname = 0;
		  Reldep *prd = 0;

		  if (ISRELDEP(pid))
		    {
		      prd = GETRELDEP(pool, pid);
		      depname = pool_id2str(pool, prd->name);
		    }
		  else
		    {
		      depname = pool_id2str(pool, pid);
		    }


		  if (!strncmp(depname, "kernel(", 7) && !strchr(depname, ':'))
		    {
		      char newdep[100];
		      snprintf(newdep, sizeof(newdep), "kernel(%s:%s", cflavor, depname + 7);
		      pid = pool_str2id(pool, newdep, 1);
		      if (prd)
			pid = pool_rel2id(pool, pid, prd->evr, prd->flags, 1);
		    }

		  npr = repo_addid_dep(pd->repo, npr, pid, 0);
		}
	      s->provides = npr;
	    }
#if 1

	  if (s->requires)
	    {
	      Offset reqs = s->requires;
	      npr = 0;
	      while ((pid = pd->repo->idarraydata[reqs++]) != 0)
		{
		  const char *depname = 0;
		  Reldep *prd = 0;

		  if (ISRELDEP(pid))
		    {
		      prd = GETRELDEP(pool, pid);
		      depname = pool_id2str(pool, prd->name);
		    }
		  else
		    {
		      depname = pool_id2str(pool, pid);
		    }

		  if (!strncmp(depname, "kernel(", 7) && !strchr(depname, ':'))
		    {
		      char newdep[100];
		      snprintf(newdep, sizeof(newdep), "kernel(%s:%s", cflavor, depname + 7);
		      pid = pool_str2id(pool, newdep, 1);
		      if (prd)
			pid = pool_rel2id(pool, pid, prd->evr, prd->flags, 1);
		    }
		  npr = repo_addid_dep(pd->repo, npr, pid, 0);
		}
	      s->requires = npr;
	    }
#endif
	  free(cflavor);
	}
      break;
    case STATE_NAME:
      s->name = pool_str2id(pool, pd->content, 1);
      break;
    case STATE_VENDOR:
      s->vendor = pool_str2id(pool, pd->content, 1);
      break;
    case STATE_BUILDTIME:
      t = atoi (pd->content);
      if (t)
	repodata_set_num(pd->data, s - pool->solvables, SOLVABLE_BUILDTIME, t);
      break;	
    case STATE_UPDATE:		       /* new version, keeping all other metadata */
      evr = evr2id(pool, pd,
                   pd->epoch   ? pd->evrspace + pd->epoch   : 0,
                   pd->version ? pd->evrspace + pd->version : 0,
                   pd->release ? pd->evrspace + pd->release : 0);
      pd->levrspace = 1;
      pd->epoch = 0;
      pd->version = 0;
      pd->release = 0;
      /* use highest evr */
      if (!s->evr || pool_evrcmp(pool, s->evr, evr, EVRCMP_COMPARE) <= 0)
	s->evr = evr;
      break;
    case STATE_EPOCH:
    case STATE_VERSION:
    case STATE_RELEASE:
    case STATE_PEPOCH:
    case STATE_PVERSION:
    case STATE_PRELEASE:
      /* ensure buffer space */
      if (pd->lcontent + 1 + pd->levrspace > pd->aevrspace)
	{
	  pd->evrspace = (char *)realloc(pd->evrspace, pd->lcontent + 1 + pd->levrspace + 256);
	  pd->aevrspace = pd->lcontent + 1 + pd->levrspace + 256;
	}
      memcpy(pd->evrspace + pd->levrspace, pd->content, pd->lcontent + 1);
      if (pd->state == STATE_EPOCH || pd->state == STATE_PEPOCH)
	pd->epoch = pd->levrspace;
      else if (pd->state == STATE_VERSION || pd->state == STATE_PVERSION)
	pd->version = pd->levrspace;
      else
	pd->release = pd->levrspace;
      pd->levrspace += pd->lcontent + 1;
      break;
    case STATE_ARCH:
    case STATE_PARCH:
      s->arch = pool_str2id(pool, pd->content, 1);
      break;
    default:
      break;
    }
  pd->state = pd->sbtab[pd->state];
  pd->docontent = 0;
  /* printf("back from known %d %d %d\n", pd->state, pd->depth, pd->statedepth); */
}
Exemple #23
0
char
*hy_reldep_str(HyReldep reldep)
{
    const char *str = pool_dep2str(reldep->pool, reldep->r_id);
    return solv_strdup(str);
}
Exemple #24
0
static void XMLCALL
endElement(void *userData, const char *name)
{
  struct parsedata *pd = userData;
  Solvable *s = pd->solvable;

#if 0
  fprintf(stderr, "end: [%d]%s\n", pd->state, name);
#endif
  if (pd->depth != pd->statedepth)
    {
      pd->depth--;
#if 0
      fprintf(stderr, "back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth);
#endif
      return;
    }

  pd->depth--;
  pd->statedepth--;

  switch (pd->state)
    {
    case STATE_PRODUCT:
      /* product done, finish solvable */
      if (pd->ctime)
        repodata_set_num(pd->data, pd->handle, SOLVABLE_INSTALLTIME, pd->ctime);

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

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

      if (pd->tmprel)
	{
	  if (pd->tmpvers)
	    s->evr = makeevr(pd->pool, join2(&pd->jd, pd->tmpvers, "-", pd->tmprel));
	  else
	    {
	      fprintf(stderr, "Seen <release> but no <version>\n");
	    }
	}
      else if (pd->tmpvers)
	s->evr = makeevr(pd->pool, pd->tmpvers); /* just version, no release */
      pd->tmpvers = solv_free((void *)pd->tmpvers);
      pd->tmprel = solv_free((void *)pd->tmprel);
      if (!s->arch)
	s->arch = ARCH_NOARCH;
      if (!s->evr)
	s->evr = ID_EMPTY;
      if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
	s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pd->pool, s->name, s->evr, REL_EQ, 1), 0);
      pd->solvable = 0;
      break;
    case STATE_VENDOR:
      s->vendor = pool_str2id(pd->pool, pd->content, 1);
      break;
    case STATE_NAME:
      s->name = pool_str2id(pd->pool, join2(&pd->jd, "product", ":", pd->content), 1);
      break;
    case STATE_VERSION:
      pd->tmpvers = solv_strdup(pd->content);
      break;
    case STATE_RELEASE:
      pd->tmprel = solv_strdup(pd->content);
      break;
    case STATE_ARCH:
      s->arch = pool_str2id(pd->pool, pd->content, 1);
      break;
    case STATE_PRODUCTLINE:
      repodata_set_str(pd->data, pd->handle, PRODUCT_PRODUCTLINE, pd->content);
    break;
    case STATE_UPDATEREPOKEY:
      /** obsolete **/
      break;
    case STATE_SUMMARY:
      repodata_set_str(pd->data, pd->handle, pool_id2langid(pd->pool, SOLVABLE_SUMMARY, pd->tmplang, 1), pd->content);
      break;
    case STATE_SHORTSUMMARY:
      repodata_set_str(pd->data, pd->handle, PRODUCT_SHORTLABEL, pd->content);
      break;
    case STATE_DESCRIPTION:
      repodata_set_str(pd->data, pd->handle, pool_id2langid(pd->pool, SOLVABLE_DESCRIPTION, pd->tmplang, 1), pd->content);
      break;
    case STATE_URL:
      if (pd->urltype)
        {
          repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content);
          repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, pd->urltype);
        }
      break;
    case STATE_TARGET:
      repodata_set_str(pd->data, pd->handle, PRODUCT_REGISTER_TARGET, pd->content);
      break;
    case STATE_REGRELEASE:
      repodata_set_str(pd->data, pd->handle, PRODUCT_REGISTER_RELEASE, pd->content);
      break;
    case STATE_CPEID:
      if (*pd->content)
        repodata_set_str(pd->data, pd->handle, SOLVABLE_CPEID, pd->content);
    default:
      break;
    }

  pd->state = pd->sbtab[pd->state];
  pd->docontent = 0;

#if 0
      fprintf(stderr, "end: [%s] -> %d\n", name, pd->state);
#endif
}
Exemple #25
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 #26
0
static int gettarhead(struct tarhead *th)
{
  int l, type;
  long long length;

  th->path = solv_free(th->path);
  th->ispax = 0;
  th->type = 0;
  th->length = 0;
  th->off = 0;
  th->end = 0;
  if (th->eof)
    return 0;
  for (;;)
    {
      int r = readblock(th->fp, th->blk);
      if (r)
	{
	  if (feof(th->fp))
	    {
	      th->eof = 1;
	      return 0;
	    }
	  return -1;
	}
      if (th->blk[0] == 0)
	{
          th->eof = 1;
	  return 0;
	}
      length = parsenum(th->blk + 124, 12);
      if (length < 0)
	return -1;
      type = 0;
      switch (th->blk[156])
	{
	case 'S': case '0':
	  type = 1;	/* file */
	  break;
	case '1':
	  /* hard link, special length magic... */
	  if (!th->ispax)
	    length = 0;
	  break;
	case '5':
	  type = 2;	/* dir */
	  break;
	case '2': case '3': case '4': case '6':
	  length = 0;
	  break;
	case 'X': case 'x': case 'L':
	  {
	    char *data, *pp;
	    if (length < 1 || length >= 1024 * 1024)
	      return -1;
	    l = length;
	    data = pp = solv_malloc(l + 512);
	    for (; l > 0; l -= 512, pp += 512)
	      if (readblock(th->fp, (unsigned char *)pp))
	        {
		  solv_free(data);
		  return -1;
	        }
	    type = 3;		/* extension */
	    if (th->blk[156] == 'L')
	      {
	        solv_free(th->path);
	        th->path = data;
	        length = 0;
		break;
	      }
	    pp = data;
	    while (length > 0)
	      {
		int ll = 0;
		int l;
		for (l = 0; l < length && pp[l] >= '0' && pp[l] <= '9'; l++)
		  ll = ll * 10 + (pp[l] - '0');
		if (l == length || pp[l] != ' ' || ll < 1 || ll > length || pp[ll - 1] != '\n')
		  {
		    solv_free(data);
		    return -1;
		  }
		length -= ll;
		pp += l + 1;
		ll -= l + 1;
		pp[ll - 1] = 0;
		if (!strncmp(pp, "path=", 5))
		  {
		    solv_free(th->path);
		    th->path = solv_strdup(pp + 5);
		  }
		pp += ll;
	      }
	    solv_free(data);
	    th->ispax = 1;
	    length = 0;
	    break;
	  }
	default:
	  type = 3;	/* extension */
	  break;
	}
      if ((type == 1 || type == 2) && !th->path)
	{
	  char path[157];
	  memcpy(path, th->blk, 156);
	  path[156] = 0;
	  if (!memcmp(th->blk + 257, "ustar\0\060\060", 8) && !th->path && th->blk[345])
	    {
	      /* POSIX ustar with prefix */
	      char prefix[156];
	      memcpy(prefix, th->blk + 345, 155);
	      prefix[155] = 0;
	      l = strlen(prefix);
	      if (l && prefix[l - 1] == '/')
		prefix[l - 1] = 0;
	      th->path = solv_dupjoin(prefix, "/", path);
	    }
	  else
	    th->path = solv_dupjoin(path, 0, 0);
	}
      if (type == 1 || type == 2)
	{
	  l = strlen(th->path);
	  if (l && th->path[l - 1] == '/')
	    {
	      if (l > 1)
		th->path[l - 1] = 0;
	      type = 2;
	    }
	}
      if (type != 3)
	break;
      while (length > 0)
	{
	  r = readblock(th->fp, th->blk);
	  if (r)
	    return r;
	  length -= 512;
	}
    }
  th->type = type;
  th->length = length;
  return 1;
}