/*
* repo_solv.c
*
- * Read the binary dump of a Repo and create a Repo * from it
- *
- * See
- * Repo *pool_addrepo_solv(Pool *pool, FILE *fp)
- * below
+ * Add a repo in solv format
*
*/
#include "repopack.h"
#include "repopage.h"
+#include "poolid_private.h" /* WHATPROVIDES_BLOCK */
+
#define INTERESTED_START SOLVABLE_NAME
#define INTERESTED_END SOLVABLE_ENHANCES
#define SOLV_ERROR_OVERFLOW 5
#define SOLV_ERROR_CORRUPT 6
-static Pool *mypool; /* for pool_debug... */
-
/*******************************************************************************
c = getc(data->fp);
if (c == EOF)
{
- pool_debug(mypool, SOLV_ERROR, "unexpected EOF\n");
+ pool_debug(data->repo->pool, SOLV_ERROR, "unexpected EOF\n");
data->error = SOLV_ERROR_EOF;
return 0;
}
c = getc(data->fp);
if (c == EOF)
{
- pool_debug(mypool, SOLV_ERROR, "unexpected EOF\n");
+ pool_debug(data->repo->pool, SOLV_ERROR, "unexpected EOF\n");
data->error = SOLV_ERROR_EOF;
return 0;
}
c = getc(data->fp);
if (c == EOF)
{
- pool_debug(mypool, SOLV_ERROR, "unexpected EOF\n");
+ pool_debug(data->repo->pool, SOLV_ERROR, "unexpected EOF\n");
data->error = SOLV_ERROR_EOF;
return 0;
}
x = (x << 7) | c;
if (max && x >= max)
{
- pool_debug(mypool, SOLV_ERROR, "read_id: id too large (%u/%u)\n", x, max);
+ pool_debug(data->repo->pool, SOLV_ERROR, "read_id: id too large (%u/%u)\n", x, max);
data->error = SOLV_ERROR_ID_RANGE;
return 0;
}
}
x = (x << 7) ^ c ^ 128;
}
- pool_debug(mypool, SOLV_ERROR, "read_id: id too long\n");
+ pool_debug(data->repo->pool, SOLV_ERROR, "read_id: id too long\n");
data->error = SOLV_ERROR_CORRUPT;
return 0;
}
c = getc(data->fp);
if (c == EOF)
{
- pool_debug(mypool, SOLV_ERROR, "unexpected EOF\n");
+ pool_debug(data->repo->pool, SOLV_ERROR, "unexpected EOF\n");
data->error = SOLV_ERROR_EOF;
return 0;
}
x = (x << 6) | (c & 63);
if (max && x >= max)
{
- pool_debug(mypool, SOLV_ERROR, "read_idarray: id too large (%u/%u)\n", x, max);
+ pool_debug(data->repo->pool, SOLV_ERROR, "read_idarray: id too large (%u/%u)\n", x, max);
data->error = SOLV_ERROR_ID_RANGE;
return 0;
}
x = map[x];
if (store == end)
{
- pool_debug(mypool, SOLV_ERROR, "read_idarray: array overflow\n");
+ pool_debug(data->repo->pool, SOLV_ERROR, "read_idarray: array overflow\n");
return 0;
}
*store++ = x;
return store;
if (store == end)
{
- pool_debug(mypool, SOLV_ERROR, "read_idarray: array overflow\n");
+ pool_debug(data->repo->pool, SOLV_ERROR, "read_idarray: array overflow\n");
data->error = SOLV_ERROR_OVERFLOW;
return 0;
}
*/
static inline unsigned char *
-data_read_id_max(unsigned char *dp, Id *ret, Id *map, int max, int *error)
+data_read_id_max(unsigned char *dp, Id *ret, Id *map, int max, Repodata *data)
{
Id x;
dp = data_read_id(dp, &x);
if (x < 0 || (max && x >= max))
{
- pool_debug(mypool, SOLV_ERROR, "data_read_idarray: id too large (%u/%u)\n", x, max);
- *error = SOLV_ERROR_ID_RANGE;
+ pool_debug(data->repo->pool, SOLV_ERROR, "data_read_id_max: id too large (%u/%u)\n", x, max);
+ data->error = SOLV_ERROR_ID_RANGE;
x = 0;
}
*ret = map ? map[x] : x;
}
static unsigned char *
-data_read_idarray(unsigned char *dp, Id **storep, Id *map, int max, int *error)
+data_read_idarray(unsigned char *dp, Id **storep, Id *map, int max, Repodata *data)
{
Id *store = *storep;
unsigned int x = 0;
x = (x << 6) | (c & 63);
if (max && x >= max)
{
- pool_debug(mypool, SOLV_ERROR, "data_read_idarray: id too large (%u/%u)\n", x, max);
- *error = SOLV_ERROR_ID_RANGE;
+ pool_debug(data->repo->pool, SOLV_ERROR, "data_read_idarray: id too large (%u/%u)\n", x, max);
+ data->error = SOLV_ERROR_ID_RANGE;
break;
}
*store++ = x;
}
static unsigned char *
-data_read_rel_idarray(unsigned char *dp, Id **storep, Id *map, int max, int *error, Id marker)
+data_read_rel_idarray(unsigned char *dp, Id **storep, Id *map, int max, Repodata *data, Id marker)
{
Id *store = *storep;
Id old = 0;
old = x;
if (max && x >= max)
{
- pool_debug(mypool, SOLV_ERROR, "data_read_rel_idarray: id too large (%u/%u)\n", x, max);
- *error = SOLV_ERROR_ID_RANGE;
+ pool_debug(data->repo->pool, SOLV_ERROR, "data_read_rel_idarray: id too large (%u/%u)\n", x, max);
+ data->error = SOLV_ERROR_ID_RANGE;
break;
}
*store++ = map ? map[x] : x;
dp = data_read_ideof(dp, &id, &eof);
if (id < 0 || (max && id >= max))
{
- pool_debug(mypool, SOLV_ERROR, "incore_map_idarray: id too large (%u/%u)\n", id, max);
+ pool_debug(data->repo->pool, SOLV_ERROR, "incore_map_idarray: id too large (%u/%u)\n", id, max);
data->error = SOLV_ERROR_ID_RANGE;
break;
}
int keydepth;
int needchunk; /* need a new chunk of data */
unsigned int now;
+ int oldnstrings = pool->ss.nstrings;
+ int oldnrels = pool->nrels;
struct _Stringpool *spool;
data.fp = fp;
repopagestore_init(&data.store);
- mypool = pool;
-
if (read_u32(&data) != ('S' << 24 | 'O' << 16 | 'L' << 8 | 'V'))
{
pool_debug(pool, SOLV_ERROR, "not a SOLV file\n");
*/
if (!(flags & REPO_LOCALPOOL))
- {
- spool = &pool->ss;
- if (pool->whatprovides)
- pool_freewhatprovides(pool);
- }
+ spool = &pool->ss;
else
{
data.localpool = 1;
pool_shrink_rels(pool); /* vacuum */
}
+ /* if we added ids/rels, make room in our whatprovide arrays */
+ if (!(flags & REPO_LOCALPOOL))
+ {
+ if (pool->whatprovides && oldnstrings != pool->ss.nstrings)
+ {
+ int newlen = (pool->ss.nstrings + WHATPROVIDES_BLOCK) & ~WHATPROVIDES_BLOCK;
+ pool->whatprovides = solv_realloc2(pool->whatprovides, newlen, sizeof(Offset));
+ memset(pool->whatprovides + oldnstrings, 0, (newlen - oldnstrings) * sizeof(Offset));
+ }
+ if (pool->whatprovides_rel && oldnrels != pool->nrels)
+ {
+ int newlen = (pool->nrels + WHATPROVIDES_BLOCK) & ~WHATPROVIDES_BLOCK;
+ pool->whatprovides_rel = solv_realloc2(pool->whatprovides_rel, newlen, sizeof(Offset));
+ memset(pool->whatprovides_rel + oldnrels, 0, (newlen - oldnrels) * sizeof(Offset));
+ }
+ }
/******* Part 3: Dirs ***********************************************/
if (numdir)
l = allsize;
if (!l || fread(buf, l, 1, data.fp) != 1)
{
- pool_debug(mypool, SOLV_ERROR, "unexpected EOF\n");
+ pool_debug(pool, SOLV_ERROR, "unexpected EOF\n");
data.error = SOLV_ERROR_EOF;
id = 0;
}
{
bufend = buf + l;
allsize -= l;
- dp = data_read_id_max(dp, &id, 0, numschemata, &data.error);
+ dp = data_read_id_max(dp, &id, 0, numschemata, &data);
}
incore_add_id(&data, 0); /* XXX? */
break;
if (left < 0)
{
- pool_debug(mypool, SOLV_ERROR, "buffer overrun\n");
+ pool_debug(pool, SOLV_ERROR, "buffer overrun\n");
data.error = SOLV_ERROR_EOF;
break;
}
l = allsize;
if (l && fread(buf + left, l, 1, data.fp) != 1)
{
- pool_debug(mypool, SOLV_ERROR, "unexpected EOF\n");
+ pool_debug(pool, SOLV_ERROR, "unexpected EOF\n");
data.error = SOLV_ERROR_EOF;
break;
}
id = stack[keydepth - 1];
if (!id)
{
- dp = data_read_id_max(dp, &id, 0, numschemata, &data.error);
+ dp = data_read_id_max(dp, &id, 0, numschemata, &data);
incore_add_id(&data, id);
}
keyp = schemadata + schemata[id];
switch (keys[key].type)
{
case REPOKEY_TYPE_ID:
- dp = data_read_id_max(dp, &did, idmap, numid + numrel, &data.error);
+ dp = data_read_id_max(dp, &did, idmap, numid + numrel, &data);
if (s && id == SOLVABLE_NAME)
s->name = did;
else if (s && id == SOLVABLE_ARCH)
}
ido = idarraydatap - repo->idarraydata;
if (keys[key].type == REPOKEY_TYPE_IDARRAY)
- dp = data_read_idarray(dp, &idarraydatap, idmap, numid + numrel, &data.error);
+ dp = data_read_idarray(dp, &idarraydatap, idmap, numid + numrel, &data);
else if (id == SOLVABLE_REQUIRES)
- dp = data_read_rel_idarray(dp, &idarraydatap, idmap, numid + numrel, &data.error, SOLVABLE_PREREQMARKER);
+ dp = data_read_rel_idarray(dp, &idarraydatap, idmap, numid + numrel, &data, SOLVABLE_PREREQMARKER);
else if (id == SOLVABLE_PROVIDES)
- dp = data_read_rel_idarray(dp, &idarraydatap, idmap, numid + numrel, &data.error, SOLVABLE_FILEMARKER);
+ dp = data_read_rel_idarray(dp, &idarraydatap, idmap, numid + numrel, &data, SOLVABLE_FILEMARKER);
else
- dp = data_read_rel_idarray(dp, &idarraydatap, idmap, numid + numrel, &data.error, 0);
+ dp = data_read_rel_idarray(dp, &idarraydatap, idmap, numid + numrel, &data, 0);
if (idarraydatap > idarraydataend)
{
pool_debug(pool, SOLV_ERROR, "idarray overflow\n");
stack[keydepth++] = nentries;
stack[keydepth++] = keyp - schemadata;
stack[keydepth++] = 0;
- dp = data_read_id_max(dp, &nentries, 0, 0, &data.error);
+ dp = data_read_id_max(dp, &nentries, 0, 0, &data);
incore_add_id(&data, nentries);
if (!nentries)
{
data.incoreoffset[(s - pool->solvables) - data.start] = data.incoredatalen;
}
nentries--;
- dp = data_read_id_max(dp, &id, 0, numschemata, &data.error);
+ dp = data_read_id_max(dp, &id, 0, numschemata, &data);
incore_add_id(&data, id);
if (keys[key].type == REPOKEY_TYPE_FIXARRAY)
{
if (keys[key].type == REPOKEY_TYPE_U32)
dp = data_read_u32(dp, (unsigned int *)&id);
else
- dp = data_read_id_max(dp, &id, 0, 0, &data.error);
+ dp = data_read_id_max(dp, &id, 0, 0, &data);
if (!repo->rpmdbid)
repo->rpmdbid = repo_sidedata_create(repo, sizeof(Id));
repo->rpmdbid[(s - pool->solvables) - repo->start] = id;
{
if (dp > bufend)
{
- pool_debug(mypool, SOLV_ERROR, "buffer overrun\n");
+ pool_debug(pool, SOLV_ERROR, "buffer overrun\n");
data.error = SOLV_ERROR_EOF;
}
}
data.fp = 0;
}
solv_free(idmap);
- mypool = 0;
if (data.error)
{