Exemple #1
0
void
repo_add_products(Repo *repo, const char *proddir, const char *root, int flags)
{
  const char *fullpath;
  DIR *dir;

  dir = opendir(proddir);
  if (dir)
    {
      /* assume code11 stype products */
      closedir(dir);
      repo_add_code11_products(repo, proddir, flags);
      return;
    }

  /* code11 didn't work, try old zyppdb */
  fullpath = root ? join2(root, "", "/var/lib/zypp/db/products") : "/var/lib/zypp/db/products";
  dir = opendir(fullpath);
  if (dir)
    {
      closedir(dir);
      /* assume code10 style products */
      repo_add_zyppdb_products(repo, fullpath, flags);
      join_freemem();
      return;
    }

  /* code11 didn't work, try -release files parsing */
  fullpath = root ? join2(root, "", "/etc") : "/etc";
  dir = opendir(fullpath);
  if (dir)
    {
      closedir(dir);
      repo_add_releasefile_products(repo, fullpath, flags);
      join_freemem();
      return;
    }

  /* no luck. print an error message in case the root argument is wrong */
  perror(fullpath);
  join_freemem();

  /* the least we can do... */
  if (!(flags & REPO_NO_INTERNALIZE) && (flags & REPO_REUSE_REPODATA) != 0)
    repodata_internalize(repo_last_repodata(repo));
}
Exemple #2
0
void
repo_add_zyppdb_products(Repo *repo, const char *dirpath, int flags)
{
  int i;
  struct parsedata pd;
  struct stateswitch *sw;
  struct dirent *entry;
  char *fullpath;
  DIR *dir;
  FILE *fp;
  Repodata *data;
  
  data = repo_add_repodata(repo, flags);
  memset(&pd, 0, sizeof(pd));
  pd.repo = repo;
  pd.pool = repo->pool;
  pd.data = data;

  pd.content = malloc(256);
  pd.acontent = 256;

  for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
    {
      if (!pd.swtab[sw->from])
        pd.swtab[sw->from] = sw;
      pd.sbtab[sw->to] = sw->from;
    }

  dir = opendir(dirpath);
  if (dir)
    {
      while ((entry = readdir(dir)))
	{
	  if (strlen(entry->d_name) < 3)
	    continue;	/* skip '.' and '..' */
	  fullpath = join2(dirpath, "/", entry->d_name);
	  if ((fp = fopen(fullpath, "r")) == 0)
	    {
	      perror(fullpath);
	      continue;
	    }
	  add_zyppdb_product(&pd, fp);
	  fclose(fp);
	}
    }
  closedir(dir);

  solv_free((void *)pd.tmplang);
  free(pd.content);
  join_freemem();
  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
}
Exemple #3
0
int
repo_add_zyppdb_products(Repo *repo, const char *dirpath, int flags)
{
  struct parsedata pd;
  struct dirent *entry;
  char *fullpath;
  DIR *dir;
  FILE *fp;
  Repodata *data;

  data = repo_add_repodata(repo, flags);
  memset(&pd, 0, sizeof(pd));
  pd.repo = repo;
  pd.pool = repo->pool;
  pd.data = data;
  solv_xmlparser_init(&pd.xmlp, stateswitches, &pd, startElement, endElement);

  if (flags & REPO_USE_ROOTDIR)
    dirpath = pool_prepend_rootdir(repo->pool, dirpath);
  dir = opendir(dirpath);
  if (dir)
    {
      while ((entry = readdir(dir)))
	{
	  if (entry->d_name[0] == '.')
	    continue;	/* skip dot files */
	  fullpath = join2(&pd.jd, dirpath, "/", entry->d_name);
	  if ((fp = fopen(fullpath, "r")) == 0)
	    {
	      pool_error(repo->pool, 0, "%s: %s", fullpath, strerror(errno));
	      continue;
	    }
          pd.filename = entry->d_name;
	  if (solv_xmlparser_parse(&pd.xmlp, fp) != SOLV_XMLPARSER_OK)
	    {
	      pool_debug(pd.pool, SOLV_ERROR, "repo_zyppdb: %s: %s at line %u:%u\n", pd.filename, pd.xmlp.errstr, pd.xmlp.line, pd.xmlp.column);
	      pd.solvable = solvable_free(pd.solvable, 1);
	    }
	  fclose(fp);
	}
    }
  closedir(dir);

  solv_xmlparser_free(&pd.xmlp);
  join_freemem(&pd.jd);
  if (flags & REPO_USE_ROOTDIR)
    solv_free((char *)dirpath);
  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  return 0;
}
Exemple #4
0
int
repo_add_updateinfoxml(Repo *repo, FILE *fp, int flags)
{
  Pool *pool = repo->pool;
  struct parsedata pd;
  char buf[BUFF_SIZE];
  int i, l;
  struct stateswitch *sw;
  Repodata *data;
  XML_Parser parser;

  data = repo_add_repodata(repo, flags);

  memset(&pd, 0, sizeof(pd));
  for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
    {
      if (!pd.swtab[sw->from])
        pd.swtab[sw->from] = sw;
      pd.sbtab[sw->to] = sw->from;
    }
  pd.pool = pool;
  pd.repo = repo;
  pd.data = data;

  pd.content = malloc(256);
  pd.acontent = 256;
  pd.lcontent = 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(pool, SOLV_FATAL, "repo_updateinfoxml: %s at line %u:%u\n", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser), (unsigned int)XML_GetCurrentColumnNumber(parser));
	  exit(1);
	}
      if (l == 0)
	break;
    }
  XML_ParserFree(parser);
  free(pd.content);
  join_freemem(&pd.jd);

  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  return 0;
}
int
repo_add_releasefile_products(Repo *repo, const char *dirpath, int flags)
{
  DIR *dir;
  struct dirent *entry;
  FILE *fp;
  char *fullpath;
  struct parsedata pd;

  if (!dirpath)
    dirpath = "/etc";
  if (flags & REPO_USE_ROOTDIR)
    dirpath = pool_prepend_rootdir(repo->pool, dirpath);
  dir = opendir(dirpath);
  if (!dir)
    {
      if (flags & REPO_USE_ROOTDIR)
        solv_free((char *)dirpath);
      return 0;
    }

  memset(&pd, 0, sizeof(pd));
  pd.repo = repo;
  while ((entry = readdir(dir)))
    {
      int len = strlen(entry->d_name);
      if (len > 8 && !strcmp(entry->d_name + len - 8, "-release"))
        {
	  /* skip /etc/lsb-release, thats not a product per-se */
	  if (strcmp(entry->d_name, "lsb-release") == 0)
	    continue;
	  fullpath = join2(&pd.jd, dirpath, "/", entry->d_name);
	  if ((fp = fopen(fullpath, "r")) == 0)
	    {
	      pool_error(repo->pool, 0, "%s: %s", fullpath, strerror(errno));
	      continue;
	    }
	  add_releasefile_product(&pd, fp);
	  fclose(fp);
	}
    }
  closedir(dir);
  join_freemem(&pd.jd);
  if (flags & REPO_USE_ROOTDIR)
    solv_free((char *)dirpath);

  if (!(flags & REPO_NO_INTERNALIZE) && (flags & REPO_REUSE_REPODATA) != 0)
    repodata_internalize(repo_last_repodata(repo));
  return 0;
}
int
repo_add_releasefile_products(Repo *repo, const char *dirpath, int flags)
{
  DIR *dir;
  struct dirent *entry;
  FILE *fp;
  char *fullpath;

  dir = opendir(dirpath);
  if (!dir)
    return 0;

  while ((entry = readdir(dir)))
    {
      int len = strlen(entry->d_name);
      if (len > 8 && !strcmp(entry->d_name + len - 8, "-release"))
        {
	  /* skip /etc/lsb-release, thats not a product per-se */
	  if (strcmp(entry->d_name, "lsb-release") == 0)
	    continue;
	  fullpath = join2(dirpath, "/", entry->d_name);
	  if ((fp = fopen(fullpath, "r")) == 0)
	    {
	      perror(fullpath);
	      continue;
	    }
	  add_releasefile_product(repo, fp);
	  fclose(fp);
	}
    }
  closedir(dir);
  join_freemem();

  if (!(flags & REPO_NO_INTERNALIZE) && (flags & REPO_REUSE_REPODATA) != 0)
    repodata_internalize(repo_last_repodata(repo));
  return 0;
}
Exemple #7
0
void
repo_add_rpmmd(Repo *repo, FILE *fp, const char *language, int flags)
{
  Pool *pool = repo->pool;
  struct parsedata pd;
  char buf[BUFF_SIZE];
  int i, l;
  struct stateswitch *sw;
  Repodata *data;
  unsigned int now;

  now = sat_timems(0);
  data = repo_add_repodata(repo, flags);

  memset(&pd, 0, sizeof(pd));
  for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
    {
      if (!pd.swtab[sw->from])
        pd.swtab[sw->from] = sw;
      pd.sbtab[sw->to] = sw->from;
    }
  pd.common.pool = pool;
  pd.common.repo = repo;

  pd.data = data;

  pd.content = sat_malloc(256);
  pd.acontent = 256;
  pd.lcontent = 0;
  pd.common.tmp = 0;
  pd.common.tmpl = 0;
  pd.kind = 0;
  pd.language = language;

  /* initialize the string pool where we will store
     the package checksums we know about, to get an Id
     we can use in a cache */
  stringpool_init_empty(&pd.cspool);
  if ((flags & REPO_EXTEND_SOLVABLES) != 0)
    {
      /* setup join data */
      Dataiterator di;
      dataiterator_init(&di, pool, repo, 0, SOLVABLE_CHECKSUM, 0, 0);
      while (dataiterator_step(&di))
	{
	  const char *str;
	  int index;

	  if (!sat_chksum_len(di.key->type))
	    continue;
	  str = repodata_chk2str(di.data, di.key->type, (const unsigned char *)di.kv.str);
          index = stringpool_str2id(&pd.cspool, str, 1);
	  if (index >= pd.ncscache)
	    {
	      pd.cscache = sat_zextend(pd.cscache, pd.ncscache, index + 1 - pd.ncscache, sizeof(Id), 255);
	      pd.ncscache = index + 1;
	    }
          pd.cscache[index] = di.solvid;
	}
      dataiterator_free(&di);
    }

  XML_Parser parser = XML_ParserCreate(NULL);
  XML_SetUserData(parser, &pd);
  pd.parser = &parser;
  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(pool, SAT_FATAL, "repo_rpmmd: %s at line %u:%u\n", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser), (unsigned int)XML_GetCurrentColumnNumber(parser));
	  exit(1);
	}
      if (l == 0)
	break;
    }
  XML_ParserFree(parser);
  sat_free(pd.content);
  sat_free(pd.lastdirstr);
  join_freemem();
  stringpool_free(&pd.cspool);
  sat_free(pd.cscache);

  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  POOL_DEBUG(SAT_DEBUG_STATS, "repo_add_rpmmd took %d ms\n", sat_timems(now));
  POOL_DEBUG(SAT_DEBUG_STATS, "repo size: %d solvables\n", repo->nsolvables);
  POOL_DEBUG(SAT_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", data->incoredatalen/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
}
Exemple #8
0
int
repo_add_content(Repo *repo, FILE *fp, int flags)
{
    Pool *pool = repo->pool;
    char *line, *linep;
    int aline;
    Solvable *s;
    struct parsedata pd;
    Repodata *data;
    Id handle = 0;
    int contentstyle = 0;
    char *descrdir = 0;
    char *datadir = 0;
    char *defvendor = 0;

    int i = 0;

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

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

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

    data = repo_add_repodata(repo, flags);

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

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

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

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

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


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

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

            if (istag ("REPOID"))
            {
                repodata_add_poolstr_array(data, SOLVID_META, REPOSITORY_REPOID, value);
                continue;
            }

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

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

                if ((checksumtype = splitword(&value)) == 0)
                    continue;
                if ((checksum = splitword(&value)) == 0)
                    continue;
                if (!*value)
                    continue;
                type = solv_chksum_str2type(checksumtype);
                if (!type)
                {
                    fprintf(stderr, "Unknown checksum type: %s: %s\n", value, checksumtype);
                    continue;
                }
                l = solv_chksum_len(type);
                if (strlen(checksum) != 2 * l)
                {
                    fprintf(stderr, "Invalid checksum length: %s: for %s\n", value, checksum);
                    continue;
                }
                fh = repodata_new_handle(data);
                repodata_set_poolstr(data, fh, SUSETAGS_FILE_TYPE, key);
                repodata_set_str(data, fh, SUSETAGS_FILE_NAME, value);
                repodata_set_checksum(data, fh, SUSETAGS_FILE_CHECKSUM, type, checksum);
                repodata_add_flexarray(data, SOLVID_META, SUSETAGS_FILE, fh);
                continue;
            }

            /* product tags */

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

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

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

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

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

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

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

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

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

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

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

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

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

    if (pd.tmp)
        solv_free(pd.tmp);
    solv_free(line);
    solv_free(otherarchs);
    join_freemem();
    if (!(flags & REPO_NO_INTERNALIZE))
        repodata_internalize(data);
    return 0;
}
Exemple #9
0
int
repo_add_code11_products(Repo *repo, const char *dirpath, int flags)
{
  Repodata *data;
  struct parsedata pd;
  struct stateswitch *sw;
  DIR *dir;
  int i;

  data = repo_add_repodata(repo, flags);

  memset(&pd, 0, sizeof(pd));
  pd.repo = repo;
  pd.pool = repo->pool;
  pd.data = data;

  pd.content = solv_malloc(256);
  pd.acontent = 256;

  for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
    {
      if (!pd.swtab[sw->from])
        pd.swtab[sw->from] = sw;
      pd.sbtab[sw->to] = sw->from;
    }

  if (flags & REPO_USE_ROOTDIR)
    dirpath = pool_prepend_rootdir(repo->pool, dirpath);
  dir = opendir(dirpath);
  if (dir)
    {
      struct dirent *entry;
      struct stat st;
      char *fullpath;

      /* check for <productsdir>/baseproduct on code11 and remember its target inode */
      if (stat(join2(&pd.jd, dirpath, "/", "baseproduct"), &st) == 0) /* follow symlink */
	pd.baseproduct = st.st_ino;
      else
	pd.baseproduct = 0;

      while ((entry = readdir(dir)))
	{
	  int len = strlen(entry->d_name);
	  FILE *fp;
	  if (len <= 5 || strcmp(entry->d_name + len - 5, ".prod") != 0)
	    continue;
	  fullpath = join2(&pd.jd, dirpath, "/", entry->d_name);
	  fp = fopen(fullpath, "r");
	  if (!fp)
	    {
	      pool_error(repo->pool, 0, "%s: %s", fullpath, strerror(errno));
	      continue;
	    }
	  pd.filename = fullpath;
	  pd.basename = entry->d_name;
	  add_code11_product(&pd, fp);
	  fclose(fp);
	}
      closedir(dir);
    }
  solv_free(pd.content);
  join_freemem(&pd.jd);
  if (flags & REPO_USE_ROOTDIR)
    solv_free((char *)dirpath);

  if (!(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  return 0;
}