summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorMichael Schroeder <mls@suse.de>2009-06-29 12:35:50 +0200
committerMichael Schroeder <mls@suse.de>2009-06-29 12:35:50 +0200
commit5ed9867b973d98b8405926f9ba11134a01337b32 (patch)
treef1d880637c06c8c7929884a3818b99c102f0ac1b /ext
parent8d207e96e526e4670c65d4f22d575f2203612247 (diff)
downloadlibsolv-5ed9867b973d98b8405926f9ba11134a01337b32.tar.gz
libsolv-5ed9867b973d98b8405926f9ba11134a01337b32.tar.bz2
libsolv-5ed9867b973d98b8405926f9ba11134a01337b32.zip
- add some comments, move code around
- add support for RPM_ADD_WITH_PKGID, RPM_ADD_NO_FILELIST, RPM_ADD_NO_RPMLIBREQS
Diffstat (limited to 'ext')
-rw-r--r--ext/repo_rpmdb.c222
-rw-r--r--ext/repo_rpmdb.h5
2 files changed, 133 insertions, 94 deletions
diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c
index 826fa13..5de20b0 100644
--- a/ext/repo_rpmdb.c
+++ b/ext/repo_rpmdb.c
@@ -88,6 +88,11 @@
#define TAG_ENHANCESVERSION 1160
#define TAG_ENHANCESFLAGS 1161
+#define SIGTAG_SIZE 1000
+#define SIGTAG_PGP 1002 /* RSA signature */
+#define SIGTAG_MD5 1004 /* header+payload md5 checksum */
+#define SIGTAG_GPG 1005 /* DSA signature */
+
#define DEP_LESS (1 << 1)
#define DEP_GREATER (1 << 2)
#define DEP_EQUAL (1 << 3)
@@ -107,12 +112,12 @@ typedef struct rpmhead {
unsigned char data[1];
} RpmHead;
-static int
-headexists(RpmHead *h, int tag)
+
+static inline unsigned char *
+headfindtag(RpmHead *h, int tag)
{
unsigned int i;
unsigned char *d, taga[4];
-
d = h->dp - 16;
taga[0] = tag >> 24;
taga[1] = tag >> 16;
@@ -120,27 +125,23 @@ headexists(RpmHead *h, int tag)
taga[3] = tag;
for (i = 0; i < h->cnt; i++, d -= 16)
if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
- return 1;
+ return d;
return 0;
}
+static int
+headexists(RpmHead *h, int tag)
+{
+ return headfindtag(h, tag) ? 1 : 0;
+}
+
static unsigned int *
headint32array(RpmHead *h, int tag, int *cnt)
{
unsigned int i, o, *r;
- unsigned char *d, taga[4];
+ unsigned char *d = headfindtag(h, tag);
- d = h->dp - 16;
- taga[0] = tag >> 24;
- taga[1] = tag >> 16;
- taga[2] = tag >> 8;
- taga[3] = tag;
- for (i = 0; i < h->cnt; i++, d -= 16)
- if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
- break;
- if (i >= h->cnt)
- return 0;
- if (d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 4)
+ if (!d || d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 4)
return 0;
o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
i = d[12] << 24 | d[13] << 16 | d[14] << 8 | d[15];
@@ -155,23 +156,14 @@ headint32array(RpmHead *h, int tag, int *cnt)
return r;
}
+/* returns the first entry of an integer array */
static unsigned int
headint32(RpmHead *h, int tag)
{
unsigned int i, o;
- unsigned char *d, taga[4];
+ unsigned char *d = headfindtag(h, tag);
- d = h->dp - 16;
- taga[0] = tag >> 24;
- taga[1] = tag >> 16;
- taga[2] = tag >> 8;
- taga[3] = tag;
- for (i = 0; i < h->cnt; i++, d -= 16)
- if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
- break;
- if (i >= h->cnt)
- return 0;
- if (d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 4)
+ if (!d || d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 4)
return 0;
o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
i = d[12] << 24 | d[13] << 16 | d[14] << 8 | d[15];
@@ -185,19 +177,9 @@ static unsigned int *
headint16array(RpmHead *h, int tag, int *cnt)
{
unsigned int i, o, *r;
- unsigned char *d, taga[4];
+ unsigned char *d = headfindtag(h, tag);
- d = h->dp - 16;
- taga[0] = tag >> 24;
- taga[1] = tag >> 16;
- taga[2] = tag >> 8;
- taga[3] = tag;
- for (i = 0; i < h->cnt; i++, d -= 16)
- if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
- break;
- if (i >= h->cnt)
- return 0;
- if (d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 3)
+ if (!d || d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 3)
return 0;
o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
i = d[12] << 24 | d[13] << 16 | d[14] << 8 | d[15];
@@ -215,22 +197,14 @@ headint16array(RpmHead *h, int tag, int *cnt)
static char *
headstring(RpmHead *h, int tag)
{
- unsigned int i, o;
- unsigned char *d, taga[4];
- d = h->dp - 16;
- taga[0] = tag >> 24;
- taga[1] = tag >> 16;
- taga[2] = tag >> 8;
- taga[3] = tag;
- for (i = 0; i < h->cnt; i++, d -= 16)
- if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
- break;
- if (i >= h->cnt)
- return 0;
+ unsigned int o;
+ unsigned char *d = headfindtag(h, tag);
/* 6: STRING, 9: I18NSTRING */
- if (d[4] != 0 || d[5] != 0 || d[6] != 0 || (d[7] != 6 && d[7] != 9))
+ if (!d || d[4] != 0 || d[5] != 0 || d[6] != 0 || (d[7] != 6 && d[7] != 9))
return 0;
o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
+ if (o >= h->dcnt)
+ return 0;
return (char *)h->dp + o;
}
@@ -238,20 +212,10 @@ static char **
headstringarray(RpmHead *h, int tag, int *cnt)
{
unsigned int i, o;
- unsigned char *d, taga[4];
+ unsigned char *d = headfindtag(h, tag);
char **r;
- d = h->dp - 16;
- taga[0] = tag >> 24;
- taga[1] = tag >> 16;
- taga[2] = tag >> 8;
- taga[3] = tag;
- for (i = 0; i < h->cnt; i++, d -= 16)
- if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
- break;
- if (i >= h->cnt)
- return 0;
- if (d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 8)
+ if (!d || d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 8)
return 0;
o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
i = d[12] << 24 | d[13] << 16 | d[14] << 8 | d[15];
@@ -273,6 +237,22 @@ headstringarray(RpmHead *h, int tag, int *cnt)
return r;
}
+static unsigned char *
+headbinary(RpmHead *h, int tag, unsigned int *sizep)
+{
+ unsigned int i, o;
+ unsigned char *d = headfindtag(h, tag);
+ if (!d || d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 7)
+ return 0;
+ o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
+ i = d[12] << 24 | d[13] << 16 | d[14] << 8 | d[15];
+ if (o > h->dcnt || o + i < o || o + i > h->dcnt)
+ return 0;
+ if (sizep)
+ *sizep = i;
+ return h->dp + o;
+}
+
static char *headtoevr(RpmHead *h)
{
unsigned int epoch;
@@ -381,16 +361,28 @@ setutf8string(Repodata *repodata, Id handle, Id tag, const char *str)
sat_free(buf);
}
+
+#define MAKEDEPS_FILTER_WEAK (1 << 0)
+#define MAKEDEPS_FILTER_STRONG (1 << 1)
+#define MAKEDEPS_NO_RPMLIB (1 << 2)
+
+/*
+ * strong: 0: ignore strongness
+ * 1: filter to strong
+ * 2: filter to weak
+ */
static unsigned int
-makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, int strong)
+makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, int flags)
{
char **n, **v;
unsigned int *f;
int i, cc, nc, vc, fc;
- int haspre = 0;
+ int haspre;
unsigned int olddeps;
Id *ida;
+ int strong;
+ strong = flags & (MAKEDEPS_FILTER_STRONG|MAKEDEPS_FILTER_WEAK);
n = headstringarray(rpmhead, tagn, &nc);
if (!n)
return 0;
@@ -414,19 +406,26 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf,
}
cc = nc;
- if (strong)
+ haspre = 0; /* add no prereq marker */
+ if (flags)
{
+ /* we do filtering */
cc = 0;
for (i = 0; i < nc; i++)
- if ((f[i] & DEP_STRONG) == (strong == 1 ? 0 : DEP_STRONG))
- {
- cc++;
- if ((f[i] & DEP_PRE) != 0)
- haspre = 1;
- }
+ {
+ if (strong && (f[i] & DEP_STRONG) != (strong == MAKEDEPS_FILTER_WEAK ? 0 : DEP_STRONG))
+ continue;
+ if ((flags & MAKEDEPS_NO_RPMLIB) != 0)
+ if (!strncmp(n[i], "rpmlib(", 7))
+ continue;
+ if ((f[i] & DEP_PRE) != 0)
+ haspre = 1;
+ cc++;
+ }
}
- else
+ else if (tagn == TAG_REQUIRENAME)
{
+ /* no filtering, just look for the first prereq */
for (i = 0; i < nc; i++)
if ((f[i] & DEP_PRE) != 0)
{
@@ -434,8 +433,6 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf,
break;
}
}
- if (tagn != TAG_REQUIRENAME)
- haspre = 0;
if (cc == 0)
{
sat_free(n);
@@ -452,16 +449,19 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf,
{
if (haspre != 1)
break;
- haspre = 2;
+ haspre = 2; /* pass two: prereqs */
i = 0;
*ida++ = SOLVABLE_PREREQMARKER;
}
- if (strong && (f[i] & DEP_STRONG) != (strong == 1 ? 0 : DEP_STRONG))
+ if (strong && (f[i] & DEP_STRONG) != (strong == MAKEDEPS_FILTER_WEAK ? 0 : DEP_STRONG))
continue;
if (haspre == 1 && (f[i] & DEP_PRE) != 0)
continue;
if (haspre == 2 && (f[i] & DEP_PRE) == 0)
continue;
+ if ((flags & MAKEDEPS_NO_RPMLIB) != 0)
+ if (!strncmp(n[i], "rpmlib(", 7))
+ continue;
if (f[i] & (DEP_LESS|DEP_GREATER|DEP_EQUAL))
{
Id name, evr;
@@ -796,7 +796,7 @@ addsourcerpm(Pool *pool, Repodata *data, Id handle, char *sourcerpm, char *name,
}
static int
-rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead)
+rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead, int flags)
{
char *name;
char *evr;
@@ -828,17 +828,18 @@ rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead)
s->vendor = str2id(pool, headstring(rpmhead, TAG_VENDOR), 1);
s->provides = makedeps(pool, repo, rpmhead, TAG_PROVIDENAME, TAG_PROVIDEVERSION, TAG_PROVIDEFLAGS, 0);
- s->provides = addfileprovides(pool, repo, data, s, rpmhead, s->provides);
+ if ((flags & RPM_ADD_NO_FILELIST) == 0)
+ s->provides = addfileprovides(pool, repo, data, s, rpmhead, s->provides);
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->requires = makedeps(pool, repo, rpmhead, TAG_REQUIRENAME, TAG_REQUIREVERSION, TAG_REQUIREFLAGS, 0);
+ s->requires = makedeps(pool, repo, rpmhead, TAG_REQUIRENAME, TAG_REQUIREVERSION, TAG_REQUIREFLAGS, (flags & RPM_ADD_NO_RPMLIBREQS) ? MAKEDEPS_NO_RPMLIB : 0);
s->conflicts = makedeps(pool, repo, rpmhead, TAG_CONFLICTNAME, TAG_CONFLICTVERSION, TAG_CONFLICTFLAGS, 0);
s->obsoletes = makedeps(pool, repo, rpmhead, TAG_OBSOLETENAME, TAG_OBSOLETEVERSION, TAG_OBSOLETEFLAGS, 0);
- s->recommends = makedeps(pool, repo, rpmhead, TAG_SUGGESTSNAME, TAG_SUGGESTSVERSION, TAG_SUGGESTSFLAGS, 2);
- s->suggests = makedeps(pool, repo, rpmhead, TAG_SUGGESTSNAME, TAG_SUGGESTSVERSION, TAG_SUGGESTSFLAGS, 1);
- s->supplements = makedeps(pool, repo, rpmhead, TAG_ENHANCESNAME, TAG_ENHANCESVERSION, TAG_ENHANCESFLAGS, 2);
- s->enhances = makedeps(pool, repo, rpmhead, TAG_ENHANCESNAME, TAG_ENHANCESVERSION, TAG_ENHANCESFLAGS, 1);
+ s->recommends = makedeps(pool, repo, rpmhead, TAG_SUGGESTSNAME, TAG_SUGGESTSVERSION, TAG_SUGGESTSFLAGS, MAKEDEPS_FILTER_STRONG);
+ s->suggests = makedeps(pool, repo, rpmhead, TAG_SUGGESTSNAME, TAG_SUGGESTSVERSION, TAG_SUGGESTSFLAGS, MAKEDEPS_FILTER_WEAK);
+ s->supplements = makedeps(pool, repo, rpmhead, TAG_ENHANCESNAME, TAG_ENHANCESVERSION, TAG_ENHANCESFLAGS, MAKEDEPS_FILTER_STRONG);
+ s->enhances = makedeps(pool, repo, rpmhead, TAG_ENHANCESNAME, TAG_ENHANCESVERSION, TAG_ENHANCESFLAGS, MAKEDEPS_FILTER_WEAK);
s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
s->conflicts = repo_fix_conflicts(repo, s->conflicts);
@@ -1378,7 +1379,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, const char *rootdir, int flags)
memcpy(rpmhead->data, (unsigned char *)dbdata.data + 8, rpmhead->cnt * 16 + rpmhead->dcnt);
rpmhead->dp = rpmhead->data + rpmhead->cnt * 16;
repo->rpmdbid[(s - pool->solvables) - repo->start] = dbid;
- if (rpm2solv(pool, repo, data, s, rpmhead))
+ if (rpm2solv(pool, repo, data, s, rpmhead, flags))
{
i++;
s = 0;
@@ -1613,7 +1614,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, const char *rootdir, int flags)
memcpy(rpmhead->data, (unsigned char *)dbdata.data + 8, rpmhead->cnt * 16 + rpmhead->dcnt);
rpmhead->dp = rpmhead->data + rpmhead->cnt * 16;
- rpm2solv(pool, repo, data, s, rpmhead);
+ rpm2solv(pool, repo, data, s, rpmhead, flags);
if ((flags & RPMDB_REPORT_PROGRESS) != 0)
{
if (done < count)
@@ -1668,6 +1669,8 @@ repo_add_rpms(Repo *repo, const char **rpms, int nrpms, int flags)
int headerstart, headerend;
struct stat stb;
Repodata *data;
+ unsigned char pkgid[16];
+ int gotpkgid;
if (!(flags & REPO_REUSE_REPODATA))
data = repo_add_repodata(repo, 0);
@@ -1718,16 +1721,47 @@ repo_add_rpms(Repo *repo, const char **rpms, int nrpms, int flags)
sigdsize += sigcnt * 16;
sigdsize = (sigdsize + 7) & ~7;
headerstart = 96 + 16 + sigdsize;
- while (sigdsize)
+ gotpkgid = 0;
+ if ((flags & RPM_ADD_WITH_PKGID) != 0)
{
- l = sigdsize > 4096 ? 4096 : sigdsize;
- if (fread(lead, l, 1, fp) != 1)
+ unsigned char *chksum;
+ unsigned int chksumsize;
+ /* extract pkgid from the signature header */
+ if (sigdsize > rpmheadsize)
+ {
+ rpmheadsize = sigdsize + 128;
+ rpmhead = sat_realloc(rpmhead, sizeof(*rpmhead) + rpmheadsize);
+ }
+ if (fread(rpmhead->data, sigdsize, 1, fp) != 1)
{
fprintf(stderr, "%s: unexpected EOF\n", rpms[i]);
fclose(fp);
continue;
}
- sigdsize -= l;
+ rpmhead->cnt = sigcnt;
+ rpmhead->dcnt = sigdsize - sigcnt * 16;
+ rpmhead->dp = rpmhead->data + rpmhead->cnt * 16;
+ chksum = headbinary(rpmhead, SIGTAG_MD5, &chksumsize);
+ if (chksum && chksumsize == 16)
+ {
+ gotpkgid = 1;
+ memcpy(pkgid, chksum, 16);
+ }
+ }
+ else
+ {
+ /* just skip the signature header */
+ while (sigdsize)
+ {
+ l = sigdsize > 4096 ? 4096 : sigdsize;
+ if (fread(lead, l, 1, fp) != 1)
+ {
+ fprintf(stderr, "%s: unexpected EOF\n", rpms[i]);
+ fclose(fp);
+ continue;
+ }
+ sigdsize -= l;
+ }
}
if (fread(lead, 16, 1, fp) != 1)
{
@@ -1780,13 +1814,15 @@ repo_add_rpms(Repo *repo, const char **rpms, int nrpms, int flags)
}
fclose(fp);
s = pool_id2solvable(pool, repo_add_solvable(repo));
- rpm2solv(pool, repo, data, s, rpmhead);
+ rpm2solv(pool, repo, data, s, rpmhead, flags);
if (data)
{
Id handle = s - pool->solvables;
repodata_set_location(data, handle, 0, 0, rpms[i]);
repodata_set_num(data, handle, SOLVABLE_DOWNLOADSIZE, (unsigned int)((stb.st_size + 1023) / 1024));
repodata_set_num(data, handle, SOLVABLE_HEADEREND, headerend);
+ if (gotpkgid)
+ repodata_set_bin_checksum(data, handle, SOLVABLE_PKGID, REPOKEY_TYPE_MD5, pkgid);
}
}
if (rpmhead)
diff --git a/ext/repo_rpmdb.h b/ext/repo_rpmdb.h
index 3e80302..abd7364 100644
--- a/ext/repo_rpmdb.h
+++ b/ext/repo_rpmdb.h
@@ -10,7 +10,10 @@
extern void repo_add_rpmdb(Repo *repo, Repo *ref, const char *rootdir, int flags);
extern void repo_add_rpms(Repo *repo, const char **rpms, int nrpms, int flags);
-#define RPMDB_REPORT_PROGRESS (1 << 8)
+#define RPMDB_REPORT_PROGRESS (1 << 8)
+#define RPM_ADD_WITH_PKGID (1 << 9)
+#define RPM_ADD_NO_FILELIST (1 << 10)
+#define RPM_ADD_NO_RPMLIBREQS (1 << 11)
#define RPM_ITERATE_FILELIST_ONLYDIRS (1 << 0)
#define RPM_ITERATE_FILELIST_WITHMD5 (1 << 1)