}
static int
-rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead, int flags)
+rpmhead2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead, int flags)
{
char *name;
char *evr;
#define ENTRIES_BLOCK 255
#define NAMEDATA_BLOCK 1023
+static inline unsigned int
+getu32(const unsigned char *dp)
+{
+ return dp[0] << 24 | dp[1] << 16 | dp[2] << 8 | dp[3];
+}
-static inline Id db2rpmdbid(unsigned char *db, int byteswapped)
+static inline Id
+db2rpmdbid(unsigned char *db, int byteswapped)
{
#ifdef RPM5
return db[0] << 24 | db[1] << 16 | db[2] << 8 | db[3];
#endif
}
-static inline void rpmdbid2db(unsigned char *db, Id id, int byteswapped)
+static inline void
+rpmdbid2db(unsigned char *db, Id id, int byteswapped)
{
#ifdef RPM5
db[0] = id >> 24, db[1] = id >> 16, db[2] = id >> 8, db[3] = id;
return entries;
}
-/* retrive header by rpmdbid */
+/* common code, return dbid on success, -1 on error */
static int
-getrpmdbid(struct rpmdbstate *state, Id rpmdbid)
+getrpm_dbdata(struct rpmdbstate *state, DBT *dbdata, int dbid)
{
- unsigned char buf[16];
- DBT dbkey;
- DBT dbdata;
+ unsigned int dsize, cnt, l;
RpmHead *rpmhead;
- if (!rpmdbid)
+ if (dbdata->size < 8)
+ return pool_error(state->pool, -1, "corrupt rpm database (size)");
+ cnt = getu32((const unsigned char *)dbdata->data);
+ dsize = getu32((const unsigned char *)dbdata->data + 4);
+ if (cnt >= MAX_HDR_CNT || dsize >= MAX_HDR_DSIZE)
+ return pool_error(state->pool, -1, "corrupt rpm database (cnt/dcnt)");
+ l = cnt * 16 + dsize;
+ if (8 + l > dbdata->size)
+ return pool_error(state->pool, -1, "corrupt rpm database (data size)");
+ if (l + 1 > state->rpmheadsize)
{
- pool_error(state->pool, 0, "illegal rpmdbid");
- return -1;
+ state->rpmheadsize = l + 128;
+ state->rpmhead = solv_realloc(state->rpmhead, sizeof(*rpmhead) + state->rpmheadsize);
}
+ rpmhead = state->rpmhead;
+ rpmhead->forcebinary = 1;
+ rpmhead->cnt = cnt;
+ rpmhead->dcnt = dsize;
+ memcpy(rpmhead->data, (unsigned char *)dbdata->data + 8, l);
+ rpmhead->data[l] = 0;
+ rpmhead->dp = rpmhead->data + cnt * 16;
+ return dbid;
+}
+
+/* retrive header by rpmdbid, returns 0 if not found, -1 on error */
+static int
+getrpm_dbid(struct rpmdbstate *state, Id dbid)
+{
+ unsigned char buf[4];
+ DBT dbkey;
+ DBT dbdata;
+
+ if (dbid <= 0)
+ return pool_error(state->pool, -1, "illegal rpmdbid %d", dbid);
if (state->dbopened != 1 && !openpkgdb(state))
return -1;
- rpmdbid2db(buf, rpmdbid, state->byteswapped);
+ rpmdbid2db(buf, dbid, state->byteswapped);
memset(&dbkey, 0, sizeof(dbkey));
memset(&dbdata, 0, sizeof(dbdata));
dbkey.data = buf;
dbdata.size = 0;
if (state->db->get(state->db, NULL, &dbkey, &dbdata, 0))
return 0;
- if (dbdata.size < 8)
- {
- pool_error(state->pool, 0, "corrupt rpm database (size)");
- return -1;
- }
- if (dbdata.size > state->rpmheadsize)
- {
- state->rpmheadsize = dbdata.size + 128;
- state->rpmhead = solv_realloc(state->rpmhead, sizeof(*rpmhead) + state->rpmheadsize);
- }
- rpmhead = state->rpmhead;
- memcpy(buf, dbdata.data, 8);
- rpmhead->forcebinary = 1;
- rpmhead->cnt = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
- rpmhead->dcnt = buf[4] << 24 | buf[5] << 16 | buf[6] << 8 | buf[7];
- if (8 + rpmhead->cnt * 16 + rpmhead->dcnt > dbdata.size)
- {
- pool_error(state->pool, 0, "corrupt rpm database (data size)");
- return -1;
- }
- memcpy(rpmhead->data, (unsigned char *)dbdata.data + 8, rpmhead->cnt * 16 + rpmhead->dcnt);
- rpmhead->dp = rpmhead->data + rpmhead->cnt * 16;
- return 1;
+ return getrpm_dbdata(state, &dbdata, dbid);
}
-/* retrive header by berkeleydb cursor */
+/* retrive header by berkeleydb cursor, returns 0 on EOF, -1 on error */
static Id
-getrpmcursor(struct rpmdbstate *state, DBC *dbc)
+getrpm_cursor(struct rpmdbstate *state, DBC *dbc)
{
- unsigned char buf[16];
DBT dbkey;
DBT dbdata;
- RpmHead *rpmhead;
Id dbid;
memset(&dbkey, 0, sizeof(dbkey));
if (dbkey.size != 4)
return pool_error(state->pool, -1, "corrupt Packages database (key size)");
dbid = db2rpmdbid(dbkey.data, state->byteswapped);
- if (dbid == 0) /* the join key */
- continue;
- if (dbdata.size < 8)
- return pool_error(state->pool, -1, "corrupt rpm database (size %u)\n", dbdata.size);
- if (dbdata.size > state->rpmheadsize)
- {
- state->rpmheadsize = dbdata.size + 128;
- state->rpmhead = solv_realloc(state->rpmhead, sizeof(*state->rpmhead) + state->rpmheadsize);
- }
- rpmhead = state->rpmhead;
- memcpy(buf, dbdata.data, 8);
- rpmhead->forcebinary = 1;
- rpmhead->cnt = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
- rpmhead->dcnt = buf[4] << 24 | buf[5] << 16 | buf[6] << 8 | buf[7];
- if (8 + rpmhead->cnt * 16 + rpmhead->dcnt > dbdata.size)
- return pool_error(state->pool, -1, "corrupt rpm database (data size)\n");
- memcpy(rpmhead->data, (unsigned char *)dbdata.data + 8, rpmhead->cnt * 16 + rpmhead->dcnt);
- rpmhead->dp = rpmhead->data + rpmhead->cnt * 16;
- return dbid;
+ if (dbid) /* ignore join key */
+ return getrpm_dbdata(state, &dbdata, dbid);
}
return 0;
}
}
i = 0;
s = 0;
- while ((dbid = getrpmcursor(&state, dbc)) != 0)
+ while ((dbid = getrpm_cursor(&state, dbc)) != 0)
{
if (dbid == -1)
{
if (!repo->rpmdbid)
repo->rpmdbid = repo_sidedata_create(repo, sizeof(Id));
repo->rpmdbid[(s - pool->solvables) - repo->start] = dbid;
- if (rpm2solv(pool, repo, data, s, state.rpmhead, flags | RPM_ADD_TRIGGERS))
+ if (rpmhead2solv(pool, repo, data, s, state.rpmhead, flags | RPM_ADD_TRIGGERS))
{
i++;
s = 0;
}
}
}
- res = getrpmdbid(&state, dbid);
+ res = getrpm_dbid(&state, dbid);
if (res <= 0)
{
if (!res)
solv_free(refhash);
return -1;
}
- rpm2solv(pool, repo, data, s, state.rpmhead, flags | RPM_ADD_TRIGGERS);
+ rpmhead2solv(pool, repo, data, s, state.rpmhead, flags | RPM_ADD_TRIGGERS);
if ((flags & RPMDB_REPORT_PROGRESS) != 0)
{
if (done < count)
return res;
}
-static inline unsigned int
-getu32(const unsigned char *dp)
-{
- return dp[0] << 24 | dp[1] << 16 | dp[2] << 8 | dp[3];
-}
-
-
Id
repo_add_rpm(Repo *repo, const char *rpm, int flags)
{
if ((flags & (RPM_ADD_WITH_PKGID | RPM_ADD_WITH_HDRID)) != 0)
{
/* extract pkgid or hdrid from the signature header */
- if (sigdsize > rpmheadsize)
+ if (sigdsize + 1 > rpmheadsize)
{
rpmheadsize = sigdsize + 128;
rpmhead = solv_realloc(rpmhead, sizeof(*rpmhead) + rpmheadsize);
fclose(fp);
return 0;
}
+ rpmhead->data[sigdsize] = 0;
if (chksumh)
solv_chksum_add(chksumh, rpmhead->data, sigdsize);
if (leadsigchksumh)
}
l = sigdsize + sigcnt * 16;
headerend = headerstart + 16 + l;
- if (l > rpmheadsize)
+ if (l + 1 > rpmheadsize)
{
rpmheadsize = l + 128;
rpmhead = solv_realloc(rpmhead, sizeof(*rpmhead) + rpmheadsize);
fclose(fp);
return 0;
}
+ rpmhead->data[l] = 0;
if (chksumh)
solv_chksum_add(chksumh, rpmhead->data, l);
rpmhead->forcebinary = forcebinary;
solv_chksum_add(chksumh, lead, l);
fclose(fp);
s = pool_id2solvable(pool, repo_add_solvable(repo));
- if (!rpm2solv(pool, repo, data, s, rpmhead, flags & ~(RPM_ADD_WITH_HDRID | RPM_ADD_WITH_PKGID)))
+ if (!rpmhead2solv(pool, repo, data, s, rpmhead, flags & ~(RPM_ADD_WITH_HDRID | RPM_ADD_WITH_PKGID)))
{
repo_free_solvable(repo, s - pool->solvables, 1);
solv_chksum_free(chksumh, 0);
return 0;
}
s = pool_id2solvable(pool, repo_add_solvable(repo));
- if (!rpm2solv(pool, repo, data, s, rpmhead, flags))
+ if (!rpmhead2solv(pool, repo, data, s, rpmhead, flags))
{
repo_free_solvable(repo, s - pool->solvables, 1);
return 0;
struct rpmdbstate *state = rpmstate;
int r;
- r = getrpmdbid(state, rpmdbid);
+ r = getrpm_dbid(state, rpmdbid);
if (!r)
pool_error(state->pool, 0, "header #%d not in database", rpmdbid);
return r <= 0 ? 0 : state->rpmhead;
}
l = sigdsize + sigcnt * 16;
/* headerend = headerstart + 16 + l; */
- if (l > state->rpmheadsize)
+ if (l + 1 > state->rpmheadsize)
{
state->rpmheadsize = l + 128;
state->rpmhead = solv_realloc(state->rpmhead, sizeof(*state->rpmhead) + state->rpmheadsize);
pool_error(state->pool, 0, "%s: unexpected EOF", name);
return 0;
}
+ rpmhead->data[l] = 0;
rpmhead->forcebinary = forcebinary;
rpmhead->cnt = sigcnt;
rpmhead->dcnt = sigdsize;
if (sigcnt >= MAX_HDR_CNT || sigdsize >= MAX_HDR_DSIZE)
return 0;
l = sigdsize + sigcnt * 16;
- if (l > state->rpmheadsize)
+ if (l + 1 > state->rpmheadsize)
{
state->rpmheadsize = l + 128;
state->rpmhead = solv_realloc(state->rpmhead, sizeof(*state->rpmhead) + state->rpmheadsize);
}
rpmhead = state->rpmhead;
- memcpy(rpmhead->data, uh + 8, l - 8);
+ memcpy(rpmhead->data, uh + 8, l);
+ rpmhead->data[l] = 0;
free((void *)uh);
rpmhead->forcebinary = 0;
rpmhead->cnt = sigcnt;
rpmhead->dcnt = sigdsize;
- rpmhead->dp = rpmhead->data + rpmhead->cnt * 16;
+ rpmhead->dp = rpmhead->data + sigcnt * 16;
return rpmhead;
}