-static int
-openpkgdb(struct rpmdbstate *state)
-{
- if (state->dbopened)
- return state->dbopened > 0 ? 1 : 0;
- state->dbopened = -1;
- if (!state->dbenv && !opendbenv(state))
- return 0;
- if (db_create(&state->db, state->dbenv, 0))
- {
- pool_error(state->pool, 0, "db_create: %s", strerror(errno));
- state->db = 0;
- closedbenv(state);
- return 0;
- }
- if (state->db->open(state->db, 0, "Packages", 0, DB_UNKNOWN, DB_RDONLY, 0664))
- {
- pool_error(state->pool, 0, "db->open Packages: %s", strerror(errno));
- state->db->close(state->db, 0);
- state->db = 0;
- closedbenv(state);
- return 0;
- }
- if (state->db->get_byteswapped(state->db, &state->byteswapped))
- {
- pool_error(state->pool, 0, "db->get_byteswapped: %s", strerror(errno));
- state->db->close(state->db, 0);
- state->db = 0;
- closedbenv(state);
- return 0;
- }
- state->dbopened = 1;
- return 1;
-}
-
-/* get the rpmdbids of all installed packages from the Name index database.
- * This is much faster then querying the big Packages database */
-static struct rpmdbentry *
-getinstalledrpmdbids(struct rpmdbstate *state, const char *index, const char *match, int *nentriesp, char **namedatap)
-{
- DB_ENV *dbenv = 0;
- DB *db = 0;
- DBC *dbc = 0;
- int byteswapped;
- DBT dbkey;
- DBT dbdata;
- unsigned char *dp;
- int dl;
- Id nameoff;
-
- char *namedata = 0;
- int namedatal = 0;
- struct rpmdbentry *entries = 0;
- int nentries = 0;
-
- *nentriesp = 0;
- if (namedatap)
- *namedatap = 0;
-
- if (!state->dbenv && !opendbenv(state))
- return 0;
- dbenv = state->dbenv;
- if (db_create(&db, dbenv, 0))
- {
- pool_error(state->pool, 0, "db_create: %s", strerror(errno));
- return 0;
- }
- if (db->open(db, 0, index, 0, DB_UNKNOWN, DB_RDONLY, 0664))
- {
- pool_error(state->pool, 0, "db->open %s: %s", index, strerror(errno));
- db->close(db, 0);
- return 0;
- }
- if (db->get_byteswapped(db, &byteswapped))
- {
- pool_error(state->pool, 0, "db->get_byteswapped: %s", strerror(errno));
- db->close(db, 0);
- return 0;
- }
- if (db->cursor(db, NULL, &dbc, 0))
- {
- pool_error(state->pool, 0, "db->cursor: %s", strerror(errno));
- db->close(db, 0);
- return 0;
- }
- memset(&dbkey, 0, sizeof(dbkey));
- memset(&dbdata, 0, sizeof(dbdata));
- if (match)
- {
- dbkey.data = (void *)match;
- dbkey.size = strlen(match);
- }
- while (dbc->c_get(dbc, &dbkey, &dbdata, match ? DB_SET : DB_NEXT) == 0)
- {
- if (!match && dbkey.size == 10 && !memcmp(dbkey.data, "gpg-pubkey", 10))
- continue;
- dl = dbdata.size;
- dp = dbdata.data;
- nameoff = namedatal;
- if (namedatap)
- {
- namedata = solv_extend(namedata, namedatal, dbkey.size + 1, 1, NAMEDATA_BLOCK);
- memcpy(namedata + namedatal, dbkey.data, dbkey.size);
- namedata[namedatal + dbkey.size] = 0;
- namedatal += dbkey.size + 1;
- }
- while(dl >= RPM_INDEX_SIZE)
- {
- entries = solv_extend(entries, nentries, 1, sizeof(*entries), ENTRIES_BLOCK);
- entries[nentries].rpmdbid = db2rpmdbid(dp, byteswapped);
- entries[nentries].nameoff = nameoff;
- nentries++;
- dp += RPM_INDEX_SIZE;
- dl -= RPM_INDEX_SIZE;
- }
- if (match)
- break;
- }
- dbc->c_close(dbc);
- db->close(db, 0);
- /* make sure that enteries is != 0 if there was no error */
- if (!entries)
- entries = solv_extend(entries, 1, 1, sizeof(*entries), ENTRIES_BLOCK);
- *nentriesp = nentries;
- if (namedatap)
- *namedatap = namedata;
- return entries;
-}
-
-/* common code, return dbid on success, -1 on error */
-static int
-getrpm_dbdata(struct rpmdbstate *state, DBT *dbdata, int dbid)
-{
- unsigned int dsize, cnt, l;
- RpmHead *rpmhead;
-
- 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)
- {
- 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, dbid, state->byteswapped);
- memset(&dbkey, 0, sizeof(dbkey));
- memset(&dbdata, 0, sizeof(dbdata));
- dbkey.data = buf;
- dbkey.size = 4;
- dbdata.data = 0;
- dbdata.size = 0;
- if (state->db->get(state->db, NULL, &dbkey, &dbdata, 0))
- return 0;
- return getrpm_dbdata(state, &dbdata, dbid);
-}
-
-/* retrive header by berkeleydb cursor, returns 0 on EOF, -1 on error */
-static Id
-getrpm_cursor(struct rpmdbstate *state, DBC *dbc)
-{
- DBT dbkey;
- DBT dbdata;
- Id dbid;
-
- memset(&dbkey, 0, sizeof(dbkey));
- memset(&dbdata, 0, sizeof(dbdata));
- while (dbc->c_get(dbc, &dbkey, &dbdata, DB_NEXT) == 0)
- {
- if (dbkey.size != 4)
- return pool_error(state->pool, -1, "corrupt Packages database (key size)");
- dbid = db2rpmdbid(dbkey.data, state->byteswapped);
- if (dbid) /* ignore join key */
- return getrpm_dbdata(state, &dbdata, dbid);
- }
- return 0;
-}
-
-static int
-count_headers(struct rpmdbstate *state)
-{
- Pool *pool = state->pool;
- char dbpath[PATH_MAX];
- struct stat statbuf;
- DB *db = 0;
- DBC *dbc = 0;
- int count = 0;
- DBT dbkey;
- DBT dbdata;
-
- snprintf(dbpath, PATH_MAX, "%s%s/Name", state->rootdir ? state->rootdir : "", state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm");
- if (stat(dbpath, &statbuf))
- return 0;
- memset(&dbkey, 0, sizeof(dbkey));
- memset(&dbdata, 0, sizeof(dbdata));
- if (db_create(&db, state->dbenv, 0))
- {
- pool_error(pool, 0, "db_create: %s", strerror(errno));
- return 0;
- }
- if (db->open(db, 0, "Name", 0, DB_UNKNOWN, DB_RDONLY, 0664))
- {
- pool_error(pool, 0, "db->open Name: %s", strerror(errno));
- db->close(db, 0);
- return 0;
- }
- if (db->cursor(db, NULL, &dbc, 0))
- {
- db->close(db, 0);
- pool_error(pool, 0, "db->cursor: %s", strerror(errno));
- return 0;
- }
- while (dbc->c_get(dbc, &dbkey, &dbdata, DB_NEXT) == 0)
- count += dbdata.size / RPM_INDEX_SIZE;
- dbc->c_close(dbc);
- db->close(db, 0);
- return count;
-}