#include "util.h"
#include "repo_rpmdb.h"
+#define RPMDB_COOKIE_VERSION 1
#define TAG_NAME 1000
#define TAG_VERSION 1001
}
}
+static void
+mkrpmdbcookie(struct stat *st, unsigned char *cookie)
+{
+ memset(cookie, 0, 32);
+ cookie[3] = RPMDB_COOKIE_VERSION;
+ memcpy(cookie + 16, &st->st_ino, sizeof(st->st_ino));
+ memcpy(cookie + 24, &st->st_dev, sizeof(st->st_dev));
+}
+
/*
* read rpm db as repo
*
DB_ENV *dbenv = 0;
DBT dbkey;
DBT dbdata;
+ struct stat packagesstat;
memset(&dbkey, 0, sizeof(dbkey));
memset(&dbdata, 0, sizeof(dbdata));
exit(1);
}
- if (!ref)
+ /* XXX: should get ro lock of Packages database! */
+ snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm/Packages", rootdir);
+ if (stat(dbpath, &packagesstat))
+ {
+ perror(dbpath);
+ exit(1);
+ }
+ mkrpmdbcookie(&packagesstat, repo->rpmdbcookie);
+
+ if (!ref || memcmp(repo->rpmdbcookie, ref->rpmdbcookie, 32) != 0)
{
Id *pkgids;
- snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm/Packages", rootdir);
if (db->open(db, 0, dbpath, 0, DB_HASH, DB_RDONLY, 0664))
{
perror("db->open var/lib/rpm/Packages");
}
}
+
+static Id subfilekeys[] = {
+ REPODATA_INFO, REPOKEY_TYPE_VOID,
+ REPODATA_EXTERNAL, REPOKEY_TYPE_VOID,
+ REPODATA_KEYS, REPOKEY_TYPE_IDARRAY,
+ REPODATA_LOCATION, REPOKEY_TYPE_STR,
+ REPODATA_ADDEDFILEPROVIDES, REPOKEY_TYPE_REL_IDARRAY,
+ REPODATA_RPMDBCOOKIE, REPOKEY_TYPE_SHA256,
+ 0,
+};
+
/*
* Repo
*/
/* If we store subfile info, generate the necessary keys. */
if (nsubfiles)
{
- key = cbdata.mykeys + cbdata.nmykeys;
- key->name = REPODATA_INFO;
- key->type = REPOKEY_TYPE_VOID;
- key->size = 0;
- key->storage = KEY_STORAGE_SOLVABLE;
- cbdata.keymap[key->name] = cbdata.nmykeys++;
-
- key = cbdata.mykeys + cbdata.nmykeys;
- key->name = REPODATA_EXTERNAL;
- key->type = REPOKEY_TYPE_VOID;
- key->size = 0;
- key->storage = KEY_STORAGE_SOLVABLE;
- cbdata.keymap[key->name] = cbdata.nmykeys++;
-
- key = cbdata.mykeys + cbdata.nmykeys;
- key->name = REPODATA_KEYS;
- key->type = REPOKEY_TYPE_IDARRAY;
- key->size = 0;
- key->storage = KEY_STORAGE_SOLVABLE;
- cbdata.keymap[key->name] = cbdata.nmykeys++;
-
- key = cbdata.mykeys + cbdata.nmykeys;
- key->name = REPODATA_LOCATION;
- key->type = REPOKEY_TYPE_STR;
- key->size = 0;
- key->storage = KEY_STORAGE_SOLVABLE;
- cbdata.keymap[key->name] = cbdata.nmykeys++;
-
- key = cbdata.mykeys + cbdata.nmykeys;
- key->name = REPODATA_ADDEDFILEPROVIDES;
- key->type = REPOKEY_TYPE_REL_IDARRAY;
- key->size = 0;
- key->storage = KEY_STORAGE_SOLVABLE;
- cbdata.keymap[key->name] = cbdata.nmykeys++;
+ for (i = 0; subfilekeys[i]; i += 2)
+ {
+ key = cbdata.mykeys + cbdata.nmykeys;
+ key->name = subfilekeys[i];
+ key->type = subfilekeys[i + 1];
+ key->size = 0;
+ key->storage = KEY_STORAGE_SOLVABLE;
+ cbdata.keymap[key->name] = cbdata.nmykeys++;
+ }
}
dirpoolusage = 0;
Id schema[4], *sp;
sp = schema;
- if (fileinfo[i].addedfileprovides)
+ if (fileinfo[i].addedfileprovides || fileinfo[i].rpmdbcookie)
{
/* extra info about this file */
*sp++ = cbdata.keymap[REPODATA_INFO];
- *sp++ = cbdata.keymap[REPODATA_ADDEDFILEPROVIDES];
- for (j = 0; fileinfo[i].addedfileprovides[j]; j++)
- ;
- cbdata.mykeys[cbdata.keymap[REPODATA_ADDEDFILEPROVIDES]].size += j + 1;
+ if (fileinfo[i].addedfileprovides)
+ {
+ *sp++ = cbdata.keymap[REPODATA_ADDEDFILEPROVIDES];
+ for (j = 0; fileinfo[i].addedfileprovides[j]; j++)
+ ;
+ cbdata.mykeys[cbdata.keymap[REPODATA_ADDEDFILEPROVIDES]].size += j + 1;
+ }
+ if (fileinfo[i].rpmdbcookie)
+ *sp++ = cbdata.keymap[REPODATA_RPMDBCOOKIE];
}
else
{
cur = xd.len;
data_addid(&xd, repodataschemata[i]);
- if (fileinfo[i].addedfileprovides)
+ if (fileinfo[i].addedfileprovides || fileinfo[i].rpmdbcookie)
{
- data_addidarray_sort(&xd, pool, needid, fileinfo[i].addedfileprovides, 0);
+ if (fileinfo[i].addedfileprovides)
+ data_addidarray_sort(&xd, pool, needid, fileinfo[i].addedfileprovides, 0);
+ if (fileinfo[i].rpmdbcookie)
+ data_addblob(&xd, fileinfo[i].rpmdbcookie, 32);
}
else
{