* repo_content.c
*
* Parses 'content' file into .solv
+ * A 'content' file is the repomd.xml of the susetags format
+ *
* See http://en.opensuse.org/Standards/YaST2_Repository_Metadata/content for a description
* of the syntax
*
*/
#include <sys/types.h>
-#include <limits.h>
-#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pool.h"
#include "repo.h"
#include "util.h"
+#include "chksum.h"
#include "repo_content.h"
#define DISABLE_SPLIT
+#define DISABLE_JOIN2
#include "tools_util.h"
/* split off a word, return null terminated pointer to it.
if (l > pd->tmpl)
{
pd->tmpl = l + 256;
- pd->tmp = sat_realloc(pd->tmp, pd->tmpl);
+ pd->tmp = solv_realloc(pd->tmp, pd->tmpl);
}
p = pd->tmp;
if (s1)
strcpy(p, s3);
p += strlen(s3);
}
+ *p = 0;
return pd->tmp;
}
dependencies sometimes. */
if (!strncmp (name, "package:", 8))
name += 8;
- id = str2id(pool, name, 1);
+ id = pool_str2id(pool, name, 1);
if (*line == '<' || *line == '>' || *line == '=') /* rel follows */
{
char *rel = splitword(&line);
if (!rel || !evr)
{
- pool_debug(pool, SAT_FATAL, "repo_content: bad relation '%s %s'\n", name, rel);
- exit(1);
+ pool_debug(pool, SOLV_ERROR, "repo_content: bad relation '%s %s'\n", name, rel);
+ continue;
}
for (flags = 0; flags < 6; flags++)
if (!strcmp(rel, flagtab[flags]))
break;
if (flags == 6)
{
- pool_debug(pool, SAT_FATAL, "repo_content: unknown relation '%s'\n", rel);
- exit(1);
+ pool_debug(pool, SOLV_ERROR, "repo_content: unknown relation '%s'\n", rel);
+ continue;
}
- id = rel2id(pool, id, str2id(pool, evr, 1), flags + 1, 1);
+ id = pool_rel2id(pool, id, pool_str2id(pool, evr, 1), flags + 1, 1);
}
olddeps = repo_addid_dep(pd->repo, olddeps, id, marker);
}
*
*/
-void
+int
repo_add_content(Repo *repo, FILE *fp, int flags)
{
Pool *pool = repo->pool;
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
unsigned int numotherarchs = 0;
Id *otherarchs = 0;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
-
memset(&pd, 0, sizeof(pd));
- line = sat_malloc(1024);
+ line = solv_malloc(1024);
aline = 1024;
- if (repo->nrepodata)
- /* use last repodata */
- data = repo->repodata + repo->nrepodata - 1;
- else
- data = repo_add_repodata(repo, 0);
-
pd.repo = repo;
linep = line;
s = 0;
+ data = repo_add_repodata(repo, flags);
+
for (;;)
{
char *key, *value;
if (linep - line + 16 > aline)
{
aline = linep - line;
- line = sat_realloc(line, aline + 512);
+ line = solv_realloc(line, aline + 512);
linep = line + aline;
aline += 512;
}
#define code10 (contentstyle == 10)
#define code11 (contentstyle == 11)
- if (contentstyle == 0)
+
+ 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"))
{
- if (istag ("CONTENTSTYLE"))
+ Id dh = repodata_new_handle(data);
+ char *p;
+ /* like with createrepo --distro */
+ if ((p = strchr(value, ',')) != 0)
{
- contentstyle = atoi(value);
- continue;
+ *p++ = 0;
+ if (*value)
+ repodata_set_poolstr(data, dh, REPOSITORY_PRODUCT_CPEID, value);
}
else
- contentstyle = 10;
+ 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")))
{
{
/* this solvable was created without seeing a
PRODUCT entry, just set the name and continue */
- s->name = str2id(pool, join(&pd, "product", ":", value), 1);
+ 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->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
- s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+ 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);
+ repo_rewrite_suse_deps(s, 0);
}
/* create new solvable */
s = pool_id2solvable(pool, repo_add_solvable(repo));
- repodata_extend(data, s - pool->solvables);
handle = s - pool->solvables;
- s->name = str2id(pool, join(&pd, "product", ":", value), 1);
+ 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;
}
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 = strdup(value);
+ pd.tmpvers = solv_strdup(value);
else if (istag ("RELEASE"))
- pd.tmprel = strdup(value);
+ pd.tmprel = solv_strdup(value);
else if (code11 && istag ("DISTRIBUTION"))
- repo_set_str(repo, s - pool->solvables, SOLVABLE_DISTRIBUTION, value);
- else if (istag ("DATADIR"))
- repo_set_str(repo, s - pool->solvables, SUSETAGS_DATADIR, value);
+ repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_DISTRIBUTION, value);
else if (istag ("UPDATEURLS"))
- add_multiple_urls(data, handle, value, str2id(pool, "update", 1));
+ add_multiple_urls(data, handle, value, pool_str2id(pool, "update", 1));
else if (istag ("EXTRAURLS"))
- add_multiple_urls(data, handle, value, str2id(pool, "extra", 1));
+ add_multiple_urls(data, handle, value, pool_str2id(pool, "extra", 1));
else if (istag ("OPTIONALURLS"))
- add_multiple_urls(data, handle, value, str2id(pool, "optional", 1));
+ add_multiple_urls(data, handle, value, pool_str2id(pool, "optional", 1));
else if (istag ("RELNOTESURL"))
- add_multiple_urls(data, handle, value, str2id(pool, "releasenotes", 1));
+ add_multiple_urls(data, handle, value, pool_str2id(pool, "releasenotes", 1));
else if (istag ("SHORTLABEL"))
- repo_set_str(repo, s - pool->solvables, PRODUCT_SHORTLABEL, value);
+ repodata_set_str(data, s - pool->solvables, PRODUCT_SHORTLABEL, value);
else if (istag ("LABEL")) /* LABEL is the products SUMMARY. */
- repo_set_str(repo, s - pool->solvables, SOLVABLE_SUMMARY, value);
+ repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, value);
else if (!strncmp (key, "LABEL.", 6))
- repo_set_str(repo, s - pool->solvables, pool_id2langid(pool, SOLVABLE_SUMMARY, key + 6, 1), value);
+ 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"))
- s->vendor = str2id(pool, value, 1);
+ 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 = str2id(pool, arch, 1);
+ s->arch = pool_str2id(pool, arch, 1);
while ((arch = splitword(&value)) != 0)
{
- otherarchs = sat_extend(otherarchs, numotherarchs, 1, sizeof(Id), 7);
- otherarchs[numotherarchs++] = str2id(pool, arch, 1);
+ 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
*
*/
- else if (code10 && istag ("CONTENTSTYLE"))
- /* CONTENTSTYLE must be first line */
- pool_debug(pool, SAT_ERROR, "repo_content: 'CONTENTSTYLE' must be first line of 'content'\n");
- else if (code10 && istag ("DISTPRODUCT"))
- /* DISTPRODUCT is for registration and Yast, not for the solver. */
- repo_set_str(repo, s - pool->solvables, PRODUCT_DISTPRODUCT, value);
- else if (code10 && istag ("DISTVERSION"))
- /* DISTVERSION is for registration and Yast, not for the solver. */
- repo_set_str(repo, s - pool->solvables, PRODUCT_DISTVERSION, value);
- else if (code10 && istag ("ARCH"))
+ 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 (code10 && istag ("PREREQUIRES"))
+ else if (istag ("PREREQUIRES"))
s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER);
- else if (code10 && istag ("REQUIRES"))
+ else if (istag ("REQUIRES"))
s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER);
- else if (code10 && istag ("PROVIDES"))
+ else if (istag ("PROVIDES"))
s->provides = adddep(pool, &pd, s->provides, value, 0);
- else if (code10 && istag ("CONFLICTS"))
+ else if (istag ("CONFLICTS"))
s->conflicts = adddep(pool, &pd, s->conflicts, value, 0);
- else if (code10 && istag ("OBSOLETES"))
+ else if (istag ("OBSOLETES"))
s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0);
- else if (code10 && istag ("RECOMMENDS"))
+ else if (istag ("RECOMMENDS"))
s->recommends = adddep(pool, &pd, s->recommends, value, 0);
- else if (code10 && istag ("SUGGESTS"))
+ else if (istag ("SUGGESTS"))
s->suggests = adddep(pool, &pd, s->suggests, value, 0);
- else if (code10 && istag ("SUPPLEMENTS"))
+ else if (istag ("SUPPLEMENTS"))
s->supplements = adddep(pool, &pd, s->supplements, value, 0);
- else if (code10 && istag ("ENHANCES"))
+ else if (istag ("ENHANCES"))
s->enhances = adddep(pool, &pd, s->enhances, value, 0);
/* FRESHENS doesn't seem to exist. */
- else if (code10 && istag ("TYPE"))
- repo_set_str(repo, s - pool->solvables, PRODUCT_TYPE, value);
+ 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, SAT_ERROR, "repo_content: malformed line: %s\n", line);
+ pool_debug(pool, SOLV_ERROR, "repo_content: malformed line: %s\n", line);
}
- if (!s || !s->name)
+ if (datadir)
+ free(datadir);
+ if (descrdir)
+ free(descrdir);
+ if (defvendor)
+ free(defvendor);
+
+ if (s && !s->name)
{
- pool_debug(pool, SAT_FATAL, "repo_content: 'content' incomplete, no product solvable created !\n");
- exit(1);
+ pool_debug(pool, SOLV_ERROR, "repo_content: 'content' incomplete, no product solvable created!\n");
+ s = solvable_free(s, 1);
}
-
- if (pd.tmpvers)
+ if (s)
{
if (pd.tmprel)
- s->evr = makeevr(pool, join2(pd.tmpvers, "-", pd.tmprel));
+ s->evr = makeevr(pool, join(&pd, pd.tmpvers, "-", pd.tmprel));
else
- s->evr = makeevr(pool, pd.tmpvers);
- }
- else if (pd.tmprel)
- {
- s->evr = makeevr(pool, join2("", "-", pd.tmprel));
- }
- pd.tmpvers = sat_free((void *)pd.tmpvers);
- pd.tmprel = sat_free((void *)pd.tmprel);
-
- if (!s->arch)
- s->arch = ARCH_NOARCH;
- if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
- {
- s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
+ 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);
- }
+ repo_rewrite_suse_deps(s, 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 (p->arch != ARCH_SRC && p->arch != ARCH_NOSRC)
- p->provides = repo_addid_dep(repo, p->provides, rel2id(pool, p->name, p->evr, REL_EQ, 1), 0);
-
- /* now merge the attributes */
- repodata_merge_attrs(data, p - pool->solvables, s - pool->solvables);
+ /* 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)
- sat_free(pd.tmp);
- sat_free(line);
- sat_free(otherarchs);
+ solv_free(pd.tmp);
+ solv_free(line);
+ solv_free(otherarchs);
if (!(flags & REPO_NO_INTERNALIZE))
repodata_internalize(data);
+ return res;
}