17 #define _RPMEVR_INTERNAL
20 #define _RPMDB_INTERNAL
21 #define _MIRE_INTERNAL
45 #define _DB_TAGGED_FILE_INDICES 1
50 #define _DBI_PERMS 0644
57 #define __PBM_NBITS (8 * sizeof (__pbm_bits))
58 #define __PBM_IX(d) ((d) / __PBM_NBITS)
59 #define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS))
65 #define __PBM_BITS(set) ((set)->bits)
67 #define PBM_FREE(s) _free(s);
68 #define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d))
69 #define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d))
70 #define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0)
72 #define PBM_ALLOC(d) xcalloc(__PBM_IX (d) + 1, sizeof(__pbm_bits))
93 for (i =
__PBM_IX(*odp) + 1; i < nb; i++)
108 static inline unsigned char nibble(
char c)
111 if (c >=
'0' && c <=
'9')
113 if (c >=
'A' && c <=
'F')
114 return (c -
'A') + 10;
115 if (c >=
'a' && c <=
'f')
116 return (c -
'a') + 10;
127 static int printable(
const void * ptr,
size_t len)
129 const char * s = ptr;
131 for (i = 0; i < len; i++, s++)
132 if (!(*s >=
' ' && *s <=
'~'))
return 0;
148 if (db->db_tagn != NULL)
149 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
151 if (rpmtag != db->db_tagn[dbix])
168 static const char *
const _dbiTagStr_default =
169 "Packages:Name:Basenames:Group:Requirename:Providename:Conflictname:Triggername:Dirnames:Requireversion:Provideversion:Installtid:Sigmd5:Sha1header:Filemd5s:Depends:Pubkeys";
170 int * dbiTags = NULL;
172 char * dbiTagStr = NULL;
174 int dbix, rpmtag, bingo;
176 dbiTagStr =
rpmExpand(
"%{?_dbi_tags}", NULL);
177 if (!(dbiTagStr && *dbiTagStr)) {
178 dbiTagStr =
_free(dbiTagStr);
179 dbiTagStr =
xstrdup(_dbiTagStr_default);
183 dbiTags =
xcalloc(1,
sizeof(*dbiTags));
186 for (o = dbiTagStr; o && *o; o = oe) {
191 for (oe = o; oe && *oe; oe++) {
194 if (oe[0] ==
':' && !(oe[1] ==
'/' && oe[2] ==
'/'))
202 _(
"dbiTagsInit: unrecognized tag name: \"%s\" ignored\n"), o);
208 for (dbix = 0; dbix < dbiTagsMax; dbix++) {
210 if (rpmtag == dbiTags[dbix]) {
219 dbiTags =
xrealloc(dbiTags, (dbiTagsMax + 1) *
sizeof(*dbiTags));
220 dbiTags[dbiTagsMax++] = rpmtag;
223 if (dbiTagsMaxP != NULL)
224 *dbiTagsMaxP = dbiTagsMax;
226 if (dbiTagsP != NULL)
229 dbiTags =
_free(dbiTags);
231 dbiTagStr =
_free(dbiTagStr);
242 extern struct _dbiVec
db3vec;
244 #define DB3vec &db3vec
250 #ifdef HAVE_SQLITE3_H
254 extern struct _dbiVec sqlitevec;
256 #define SQLITEvec &sqlitevec
259 #define SQLITEvec NULL
278 const char * s =
tagName(value);
281 else if (!strcmp(s,
"Filedigests"))
290 int _dbapi, _dbapi_rebuild, _dbapi_wanted;
295 fprintf(stderr,
"==> %s(%p, %s, 0x%x)\n", __FUNCTION__, db,
mapTagName(rpmtag), flags);
302 if (dbix < 0 || dbix >= db->db_ndbi)
307 if (db->_dbi != NULL && (dbi = db->_dbi[dbix]) != NULL)
312 if (_dbapi_rebuild < 1 || _dbapi_rebuild > 4)
317 switch (_dbapi_wanted) {
319 _dbapi = _dbapi_wanted;
320 if (_dbapi < 0 || _dbapi >= 5 || mydbvecs[_dbapi] == NULL) {
326 rc = (*mydbvecs[_dbapi]->open) (db, rpmtag, &dbi);
328 static int _printed[32];
329 if (!_printed[dbix & 0x1f]++)
331 _(
"cannot open %s index using db%d - %s (%d)\n"),
333 (rc > 0 ? strerror(rc) :
""), rc);
339 while (_dbapi-- > 1) {
340 if (mydbvecs[_dbapi] == NULL)
344 rc = (*mydbvecs[_dbapi]->open) (db, rpmtag, &dbi);
349 static int _printed[32];
350 if (!_printed[dbix & 0x1f]++)
356 if (db->db_api == -1 && _dbapi > 0)
362 if (dbi != NULL && rc == 0) {
363 if (db->_dbi != NULL)
364 db->_dbi[dbix] = dbi;
368 if (!dbiStat(dbi, DB_FAST_STAT)) {
369 DB_HASH_STAT * hash = (DB_HASH_STAT *)dbi->dbi_stats;
371 db->db_nbits += hash->hash_nkeys;
397 rec->hdrNum = hdrNum;
398 rec->tagNum = tagNum;
407 #define _DBSWAP(_a) \
409 { unsigned char _b, *_c = (_a).uc; \
410 _b = _c[3]; _c[3] = _c[0]; _c[0] = _b; \
411 _b = _c[2]; _c[2] = _c[1]; _c[1] = _b; \
430 if (dbi == NULL || data == NULL || setp == NULL)
432 _dbbyteswapped = dbiByteSwapped(dbi);
434 if ((sdbir = data->data) == NULL) {
440 set->count = data->size / dbi->dbi_jlen;
441 set->recs =
xmalloc(set->count *
sizeof(*(set->recs)));
444 switch (dbi->dbi_jlen) {
447 for (i = 0; i <
set->count; i++) {
450 memcpy(&hdrNum.
ui, sdbir,
sizeof(hdrNum.
ui));
451 sdbir +=
sizeof(hdrNum.
ui);
452 memcpy(&tagNum.
ui, sdbir,
sizeof(tagNum.
ui));
453 sdbir +=
sizeof(tagNum.
ui);
454 if (_dbbyteswapped) {
458 set->recs[i].hdrNum = hdrNum.
ui;
459 set->recs[i].tagNum = tagNum.
ui;
460 set->recs[i].fpNum = 0;
464 for (i = 0; i <
set->count; i++) {
467 memcpy(&hdrNum.
ui, sdbir,
sizeof(hdrNum.
ui));
468 sdbir +=
sizeof(hdrNum.
ui);
469 if (_dbbyteswapped) {
472 set->recs[i].hdrNum = hdrNum.
ui;
473 set->recs[i].tagNum = 0;
474 set->recs[i].fpNum = 0;
499 if (dbi == NULL || data == NULL ||
set == NULL)
501 _dbbyteswapped = dbiByteSwapped(dbi);
503 data->size =
set->count * (dbi->dbi_jlen);
504 if (data->size == 0) {
508 tdbir = data->data =
xmalloc(data->size);
511 switch (dbi->dbi_jlen) {
514 for (i = 0; i <
set->count; i++) {
517 memset(&hdrNum, 0,
sizeof(hdrNum));
518 memset(&tagNum, 0,
sizeof(tagNum));
519 hdrNum.
ui =
set->recs[i].hdrNum;
520 tagNum.
ui =
set->recs[i].tagNum;
521 if (_dbbyteswapped) {
525 memcpy(tdbir, &hdrNum.
ui,
sizeof(hdrNum.
ui));
526 tdbir +=
sizeof(hdrNum.
ui);
527 memcpy(tdbir, &tagNum.
ui,
sizeof(tagNum.
ui));
528 tdbir +=
sizeof(tagNum.
ui);
532 for (i = 0; i <
set->count; i++) {
535 memset(&hdrNum, 0,
sizeof(hdrNum));
536 hdrNum.
ui =
set->recs[i].hdrNum;
537 if (_dbbyteswapped) {
540 memcpy(tdbir, &hdrNum.
ui,
sizeof(hdrNum.
ui));
541 tdbir +=
sizeof(hdrNum.
ui);
553 static int hdrNumCmp(
const void * one,
const void * two)
556 const int * a = one, * b = two;
570 int nrecs,
size_t recsize,
int sortset)
573 const char * rptr =
recs;
574 size_t rlen = (recsize <
sizeof(*(
set->recs)))
575 ? recsize :
sizeof(*(set->recs));
577 if (
set == NULL || recs == NULL || nrecs <= 0 || recsize == 0)
581 (set->count + nrecs) *
sizeof(*(set->recs)));
583 memset(set->recs + set->count, 0, nrecs *
sizeof(*(set->recs)));
585 while (nrecs-- > 0) {
587 memcpy(set->recs + set->count, rptr, rlen);
593 if (sortset && set->count > 1)
594 qsort(set->recs, set->count,
sizeof(*(set->recs)),
hdrNumCmp);
609 size_t recsize,
int sorted)
614 int num =
set->count;
617 assert(set->count > 0);
618 if (nrecs > 1 && !sorted)
621 for (from = 0; from < num; from++) {
622 if (bsearch(&set->recs[from], recs, nrecs, recsize,
hdrNumCmp)) {
627 set->recs[to] =
set->recs[from];
631 return (numCopied == num);
641 return set->recs[recno].hdrNum;
646 return set->recs[recno].tagNum;
652 set->recs =
_free(set->recs);
701 sigset_t newMask, oldMask;
702 static int terminating = 0;
704 if (terminating)
return 1;
706 (void) sigfillset(&newMask);
707 (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask);
722 while ((mi = rpmmiRock) != NULL) {
730 while ((db = rpmdbRock) != NULL) {
731 rpmdbRock = db->db_next;
737 (void) sigprocmask(SIG_SETMASK, &oldMask, NULL);
768 (void) sigfillset(&newMask);
769 (void) sigprocmask(SIG_BLOCK, &newMask, oldMask);
770 (void) sigdelset(&newMask, SIGINT);
771 (void) sigdelset(&newMask, SIGQUIT);
772 (void) sigdelset(&newMask, SIGHUP);
773 (void) sigdelset(&newMask, SIGTERM);
774 (void) sigdelset(&newMask, SIGPIPE);
775 return sigprocmask(SIG_BLOCK, &newMask, NULL);
790 return sigprocmask(SIG_SETMASK, oldMask, NULL);
804 const char * errstr =
"(unkown error)";
828 const char * fn = NULL;
832 {
const char * fnfmt =
rpmGetPath(
"%{?_hrmib_path}", NULL);
835 fnfmt =
_free(fnfmt);
850 struct utimbuf stamp;
851 stamp.actime = *iidp;
852 stamp.modtime = *iidp;
853 if (!
Utime(fn, &stamp))
868 #define _DB_HOME "%{?_dbpath}"
871 #define _DB_PERMS 0644
874 #define _DB_ERRPFX "rpmdb"
889 if (db == NULL)
return -2;
891 if (db->db_tagn != NULL && db->_dbi != NULL)
892 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
893 if (db->db_tagn[dbix] < 0)
895 if (db->_dbi[dbix] != NULL)
897 switch ((db->db_tagn[dbix])) {
907 (void)
dbiOpen(db, db->db_tagn[dbix], db->db_flags);
914 int tagn = (rpmtag >= 0 ? rpmtag : -rpmtag);
917 if (db == NULL || db->_dbi == NULL)
920 if (db->db_tagn != NULL)
921 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
922 if (db->db_tagn[dbix] != tagn)
924 db->db_tagn[dbix] = rpmtag;
935 if (db == NULL || db->_dbi == NULL)
938 if (db->db_tagn != NULL)
939 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
940 if (db->db_tagn[dbix] != rpmtag)
943 if (db->_dbi[dbix] != NULL) {
946 xx = dbiClose(db->_dbi[dbix], 0);
947 if (xx && rc == 0) rc = xx;
948 db->_dbi[dbix] = NULL;
977 for (dbix = db->db_ndbi; --dbix >= 0; ) {
979 if (db->_dbi[dbix] == NULL)
982 xx = dbiClose(db->_dbi[dbix], 0);
983 if (xx && rc == 0) rc = xx;
984 db->_dbi[dbix] = NULL;
987 db->db_errpfx =
_free(db->db_errpfx);
988 db->db_root =
_free(db->db_root);
989 db->db_home =
_free(db->db_home);
990 db->db_bits =
PBM_FREE(db->db_bits);
991 db->db_tagn =
_free(db->db_tagn);
992 db->_dbi =
_free(db->_dbi);
997 while ((next = *prev) != NULL && next != db)
998 prev = &next->db_next;
1000 *prev = next->db_next;
1001 next->db_next = NULL;
1023 if (db == NULL)
return 0;
1024 if (db->_dbi != NULL)
1025 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
1027 if (db->_dbi[dbix] == NULL)
1029 if (db->_dbi[dbix]->dbi_no_dbsync)
1031 xx = dbiSync(db->_dbi[dbix], 0);
1032 if (xx && rc == 0) rc = xx;
1047 const char * fn = NULL;
1071 if (fn && *fn && *fn !=
'/') {
1075 if ((t =
realpath(
".", dn)) != NULL) {
1077 if (t > dn && t[-1] !=
'/')
1079 t =
stpncpy(t, fn, (
sizeof(dn) - (t - dn)));
1096 int mode,
int perms,
int flags)
1102 static int oneshot = 0;
1106 fprintf(stderr,
"==> %s(%s, %s, 0x%x, 0%o, 0x%x) db %p\n", __FUNCTION__, root, home, mode, perms, flags, db);
1122 if (!(perms & 0600)) perms = 0644;
1124 if (mode >= 0) db->db_mode = mode;
1125 if (perms >= 0) db->db_perms = perms;
1126 if (flags >= 0) db->db_flags = flags;
1131 if (!(db->db_home && db->db_home[0])) {
1133 db->db_root =
_free(db->db_root);
1134 db->db_home =
_free(db->db_home);
1140 {
const char * dbpath =
rpmGetPath(
"%{?_dbpath}", NULL);
1141 const char * rootpath = NULL;
1142 const char * homepath = NULL;
1144 (void)
urlPath(db->db_root, &rootpath);
1145 (void)
urlPath(db->db_home, &homepath);
1146 #define _VARLIBRPM "/var/lib/rpm"
1147 if (!strcmp(rootpath,
"/")
1150 dbpath =
_free(dbpath);
1155 db->db_remove_env = 0;
1158 db->_dbi =
xcalloc(db->db_ndbi,
sizeof(*db->_dbi));
1169 const char * dbpath,
1170 int _dbapi,
rpmdb *dbp,
1171 int mode,
int perms,
int flags)
1184 if (_dbapi < -1 || _dbapi > 4)
1191 if (mode & O_WRONLY)
1194 db =
rpmdbNew(prefix, dbpath, mode, perms, flags);
1204 db->db_api = _dbapi;
1209 if (db->db_tagn != NULL)
1210 for (dbix = 0; rc == 0 && dbix < db->db_ndbi; dbix++) {
1215 switch ((rpmtag = db->db_tagn[dbix])) {
1234 if (dbi == NULL) rc |= 1;
1237 if (db->db_api == 3)
1242 if (dbi == NULL) rc |= 1;
1253 if (rc || justCheck || dbp == NULL)
1271 fprintf(stderr,
"--> db %p -- %d %s at %s:%u\n", db, db->nrefs, msg, fn, ln);
1282 fprintf(stderr,
"--> db %p ++ %d %s at %s:%u\n", db, db->nrefs, msg, fn, ln);
1309 if (xx && rc == 0) rc = xx;
1311 if (xx && rc == 0) rc = xx;
1326 if (db->_dbi != NULL)
1327 for (dbix = db->db_ndbi; --dbix >= 0; ) {
1328 if (db->_dbi[dbix] == NULL)
1331 xx = dbiVerify(db->_dbi[dbix], 0);
1332 if (xx && rc == 0) rc = xx;
1333 db->_dbi[dbix] = NULL;
1340 if (xx && rc == 0) rc = xx;
1352 if (!rc && db != NULL)
1366 while ((c = *(
const unsigned char *)s++) != 0) {
1371 return ((r & 0x7fff) | 0x8000) << 16;
1393 const char * baseName;
1406 if (filespec == NULL)
return -2;
1409 if ((baseName = strrchr(filespec,
'/')) != NULL) {
1413 len = baseName - filespec + 1;
1415 t = strncpy(
alloca(len + 1), filespec, len);
1422 baseName = filespec;
1425 if (baseName == NULL)
1429 fp1 =
fpLookup(fpc, dirName, baseName, 1);
1435 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
1438 key->data = (
void *) baseName;
1440 key->size = strlen(baseName);
1441 if (key->size == 0) key->size++;
1443 rc = dbiGet(dbi, dbcursor, key, data, DB_SET);
1446 _(
"error(%d) getting \"%s\" records from %s index\n"),
1451 (void)
dbt2set(dbi, data, &allMatches);
1455 for (i = 0; i < allMatches->count; i++) {
1456 if (allMatches->recs[i].tagNum & 0x80000000)
1457 allMatches->recs[i].tagNum &= 0x0000ffff;
1460 xx = dbiCclose(dbi, dbcursor, 0);
1472 *matches =
xcalloc(1,
sizeof(**matches));
1475 if (allMatches != NULL)
1476 while (i < allMatches->count) {
1477 const char ** baseNames, ** dirNames;
1480 unsigned int prevoff;
1504 fp2 =
fpLookup(fpc, dirNames[dirIndexes[num]], baseNames[num], 1);
1515 if (i < allMatches->count)
1517 }
while (i < allMatches->count && offset == prevoff);
1519 baseNames = hfd(baseNames, bnt);
1520 dirNames = hfd(dirNames, dnt);
1529 if ((*matches)->count == 0) {
1539 DBC * dbcursor = NULL;
1540 DBT * key =
alloca(
sizeof(*key));
1541 DBT * data =
alloca(
sizeof(*data));
1546 if (db == NULL || keyp == NULL)
1549 memset(key, 0,
sizeof(*key));
1550 memset(data, 0,
sizeof(*data));
1557 keylen = strlen(keyp);
1560 key->data = (
void *) keyp;
1562 key->size = (u_int32_t) keylen;
1564 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
1565 rc = dbiGet(dbi, dbcursor, key, data, DB_SET);
1567 xx = dbiCclose(dbi, dbcursor, 0);
1575 (void)
dbt2set(dbi, data, &matches);
1582 if (rc == DB_NOTFOUND) {
1586 _(
"error(%d) getting \"%s\" records from %s index\n"),
1592 xx = dbiCclose(dbi, dbcursor, 0);
1618 DBT * key, DBT * data,
1620 const char * version,
1621 const char * release,
1633 key->data = (
void *) name;
1635 key->size = strlen(name);
1637 rc = dbiGet(dbi, dbcursor, key, data, DB_SET);
1640 (void)
dbt2set(dbi, data, matches);
1641 if (version == NULL && release == NULL)
1644 if (rc == DB_NOTFOUND) {
1648 _(
"error(%d) getting \"%s\" records from %s index\n"),
1683 (*matches)->recs[gotMatches++] = (*matches)->recs[i];
1685 (*matches)->recs[i].hdrNum = 0;
1692 (*matches)->count = gotMatches;
1699 if (rc && matches && *matches)
1724 const char * release;
1734 rc =
dbiFindMatches(dbi, dbcursor, key, data, arg, NULL, NULL, matches);
1742 localarg =
alloca(strlen(arg) + 1);
1743 s =
stpcpy(localarg, arg);
1747 for (s -= 1; s > localarg; s--) {
1753 if (c !=
'[') brackets = 0;
1757 if (!brackets && *s ==
'-')
1767 rc =
dbiFindMatches(dbi, dbcursor, key, data, localarg, s + 1, NULL, matches);
1781 for (; s > localarg; s--) {
1787 if (c !=
'[') brackets = 0;
1791 if (!brackets && *s ==
'-')
1801 return dbiFindMatches(dbi, dbcursor, key, data, localarg, s + 1, release, matches);
1810 sw = &dbi->dbi_rpmdb->db_getops;
1813 sw = &dbi->dbi_rpmdb->db_putops;
1817 sw = &dbi->dbi_rpmdb->db_delops;
1837 if (mi == NULL || mi->
mi_h == NULL)
1843 sigset_t signalMask;
1854 const char * msg = NULL;
1857 rpmrc = (*mi->
mi_hdrchk) (mi->
mi_ts, data->data, data->size, &msg);
1860 (rpmrc ==
RPMRC_FAIL ?
_(
"miFreeHeader: skipping") :
"write"),
1865 if (data->data != NULL && rpmrc !=
RPMRC_FAIL) {
1867 rc = dbiPut(dbi, mi->
mi_dbc, key, data, DB_KEYLAST);
1870 _(
"error(%d) storing record #%d into %s\n"),
1873 xx = dbiSync(dbi, 0);
1876 data->data =
_free(data->data);
1900 while ((next = *prev) != NULL && next != mi)
1914 xx = dbiCclose(dbi, mi->
mi_dbc, 0);
1917 if (mi->
mi_re != NULL)
1918 for (i = 0; i < mi->
mi_nre; i++)
1919 xx = mireClean(mi->
mi_re + i);
1951 static int mireCmp(
const void * a,
const void * b)
1953 const miRE mireA = (
const miRE) a;
1954 const miRE mireB = (
const miRE) b;
1955 return (mireA->tag - mireB->tag);
1966 const char * pattern)
1980 case RPMMIRE_DEFAULT:
1982 *modep = RPMMIRE_GLOB;
1987 nb = strlen(pattern) +
sizeof(
"^$");
1993 for (s = pattern; *s !=
'\0'; s++) {
1998 if (!brackets) nb++;
2007 if (c !=
'[') brackets = 0;
2015 if (pattern[0] !=
'^') *t++ =
'^';
2020 for (s = pattern; *s !=
'\0'; s++, t++) {
2024 if (!brackets) *t++ =
'\\';
2027 if (!brackets) *t++ =
'.';
2036 if (c !=
'[') brackets = 0;
2042 if (s > pattern && s[-1] !=
'$') *t++ =
'$';
2044 *modep = RPMMIRE_REGEX;
2046 case RPMMIRE_STRCMP:
2058 rpmMireMode mode,
const char * pattern)
2060 static rpmMireMode defmode = (rpmMireMode)-1;
2063 const char * allpat = NULL;
2068 if (defmode == (rpmMireMode)-1) {
2069 const char *t =
rpmExpand(
"%{?_query_selector_match}", NULL);
2071 if (*t ==
'\0' || !strcmp(t,
"default"))
2072 defmode = RPMMIRE_DEFAULT;
2073 else if (!strcmp(t,
"strcmp"))
2074 defmode = RPMMIRE_STRCMP;
2075 else if (!strcmp(t,
"regex"))
2076 defmode = RPMMIRE_REGEX;
2077 else if (!strcmp(t,
"glob"))
2078 defmode = RPMMIRE_GLOB;
2080 defmode = RPMMIRE_DEFAULT;
2084 if (mi == NULL || pattern == NULL)
2088 if (*pattern ==
'!') {
2094 nmire = mireNew(mode, tag);
2096 allpat =
mireDup(nmire->tag, &nmire->mode, pattern);
2099 if (nmire->mode == RPMMIRE_DEFAULT)
2100 nmire->mode = defmode;
2102 rc = mireRegcomp(nmire, allpat);
2110 mire->mode = nmire->mode;
2111 mire->pattern = nmire->pattern; nmire->pattern = NULL;
2112 mire->preg = nmire->preg; nmire->preg = NULL;
2113 mire->cflags = nmire->cflags;
2114 mire->eflags = nmire->eflags;
2115 mire->fnflags = nmire->fnflags;
2116 mire->tag = nmire->tag;
2117 mire->notmatch = notmatch;
2125 allpat =
_free(allpat);
2126 nmire = mireFree(nmire);
2158 if (mi->
mi_h == NULL)
2166 if ((mire = mi->
mi_re) == NULL)
2169 for (i = 0; i < mi->
mi_nre; i++, mire++) {
2172 if (!hge(mi->
mi_h, mire->tag, &t, (
void **)&u, &c)) {
2187 sprintf(numbuf,
"%d", (
int) *u.i8p);
2188 rc = mireRegexec(mire, numbuf);
2189 if ((!rc && !mire->notmatch) || (rc && mire->notmatch))
2193 sprintf(numbuf,
"%d", (
int) *u.i16p);
2194 rc = mireRegexec(mire, numbuf);
2195 if ((!rc && !mire->notmatch) || (rc && mire->notmatch))
2199 sprintf(numbuf,
"%d", (
int) *u.i32p);
2200 rc = mireRegexec(mire, numbuf);
2201 if ((!rc && !mire->notmatch) || (rc && mire->notmatch))
2205 rc = mireRegexec(mire, u.str);
2206 if ((!rc && !mire->notmatch) || (rc && mire->notmatch))
2211 for (j = 0; j < c; j++) {
2212 rc = mireRegexec(mire, u.argv[j]);
2213 if ((!rc && !mire->notmatch) || (rc && mire->notmatch)) {
2224 if ((i+1) < mi->
mi_nre && mire[0].tag == mire[1].tag) {
2233 u.ptr = hfd(u.ptr, t);
2240 return (ntags > 0 && ntags == nmatches ? 0 : 1);
2248 rc = (mi->
mi_cflags & DB_WRITECURSOR) ? 1 : 0;
2267 rpmRC (*hdrchk) (
rpmts ts,
const void *uh,
size_t uc,
const char ** msg))
2311 memset(key, 0,
sizeof(*key));
2313 memset(data, 0,
sizeof(*data));
2330 if (dbiByteSwapped(dbi) == 1)
2333 keylen =
sizeof(mi_offset.
ui);
2336 key->data = keyp = (
void *)mi->
mi_keyp;
2341 data->flags |= DB_DBT_MALLOC;
2343 rc = dbiGet(dbi, mi->
mi_dbc, key, data,
2344 (key->data == NULL ? DB_NEXT : DB_SET));
2359 if (keyp && mi->
mi_setx && rc == 0) {
2360 memcpy(&mi_offset, keyp,
sizeof(mi_offset.
ui));
2361 if (dbiByteSwapped(dbi) == 1)
2386 #if !defined(_USE_COPY_LOAD)
2387 data->
flags |= DB_DBT_MALLOC;
2389 rc = dbiGet(dbi, mi->
mi_dbc, key, data, DB_SET);
2413 if (mi->
mi_db->db_bits) {
2424 const char * msg = NULL;
2430 (rpmrc ==
RPMRC_FAIL ?
_(
"rpmdbNextIterator: skipping") :
" read"),
2451 #if !defined(_USE_COPY_LOAD)
2462 _(
"rpmdb: damaged header #%u retrieved -- skipping.\n"),
2479 sprintf(origin,
"rpmdb (h#%u)", mi->
mi_offset);
2501 #if defined(__GLIBC__)
2516 unsigned int exclude,
unsigned int tag)
2535 if (key->data == NULL)
2542 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
2543 rc = dbiGet(dbi, dbcursor, key, data, DB_SET);
2545 xx = dbiCclose(dbi, dbcursor, 0);
2550 if (rc != DB_NOTFOUND)
2552 _(
"error(%d) getting \"%s\" records from %s index\n"),
2555 xx = dbiCclose(dbi, dbcursor, 0);
2562 (void)
dbt2set(dbi, data, &
set);
2565 for (i = j = 0; i <
set->count; i++) {
2566 if (exclude && set->recs[i].hdrNum == exclude)
2570 if ((set->recs[i].tagNum & 0xffff0000) != tag)
2572 set->recs[i].tagNum &= 0x0000ffff;
2575 set->recs[j] =
set->recs[i];
2580 xx = dbiCclose(dbi, dbcursor, 0);
2588 for (i = 0; i <
set->count; i++)
2589 set->recs[i].fpNum = fpNum;
2592 xx = dbiCclose(dbi, dbcursor, 0);
2597 if (mi->
mi_set == NULL) {
2601 fprintf(stderr,
"+++ %d = %d + %d\t\"%s\"\n", (mi->
mi_set->count + set->count), mi->
mi_set->count, set->count, ((
char *)key->data));
2604 (mi->
mi_set->count + set->count) *
sizeof(*(mi->
mi_set->recs)));
2605 memcpy(mi->
mi_set->recs + mi->
mi_set->count, set->recs,
2606 set->count *
sizeof(*(mi->
mi_set->recs)));
2607 mi->
mi_set->count +=
set->count;
2617 int nHdrNums,
int sorted)
2619 if (mi == NULL || hdrNums == NULL || nHdrNums <= 0)
2629 if (mi == NULL || hdrNums == NULL || nHdrNums <= 0)
2639 const void * keyp,
size_t keylen)
2648 const void * mi_keyp = NULL;
2680 DBC * dbcursor = NULL;
2685 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
2687 xx = dbiCclose(dbi, dbcursor, 0);
2692 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
2695 key->data = (
void *) keyp;
2698 if (key->data && key->size == 0) key->size = strlen((
char *)key->data);
2699 if (key->data && key->size == 0) key->size++;
2702 rc = dbiGet(dbi, dbcursor, key, data, DB_SET);
2706 _(
"error(%d) getting \"%s\" records from %s index\n"),
2707 rc, (key->data ? key->data :
"???"),
mapTagName(dbi->dbi_rpmtag));
2712 (void)
dbt2set(dbi, data, &
set);
2714 xx = dbiCclose(dbi, dbcursor, 0);
2733 assert(keylen ==
sizeof(k->
ui));
2735 memcpy(k, keyp, keylen);
2736 if (dbiByteSwapped(dbi) == 1)
2743 keylen = strlen(keyp);
2746 memcpy(k, keyp, keylen);
2782 rpmRC (*hdrchk) (
rpmts ts,
const void *uh,
size_t uc,
const char ** msg))
2784 DBC * dbcursor = NULL;
2785 DBT * key =
alloca(
sizeof(*key));
2786 DBT * data =
alloca(
sizeof(*data));
2791 sigset_t signalMask;
2798 memset(key, 0,
sizeof(*key));
2799 memset(data, 0,
sizeof(*data));
2811 "rpmdbRemove", hdrNum);
2817 if (rid != 0 && rid != -1) {
2823 {
const char *n, *v, *r;
2834 if (db->db_tagn != NULL)
2835 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
2838 const char ** rpmvals = NULL;
2848 rpmtag = db->db_tagn[dbix];
2861 if (db->db_export != NULL)
2862 xx = db->db_export(db, h, 0);
2868 mi_offset.
ui = hdrNum;
2869 if (dbiByteSwapped(dbi) == 1)
2871 key->data = &mi_offset;
2873 key->size =
sizeof(mi_offset.
ui);
2875 rc = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, DB_WRITECURSOR);
2876 rc = dbiGet(dbi, dbcursor, key, data, DB_SET);
2879 _(
"error(%d) setting header #%d record for %s removal\n"),
2882 rc = dbiDel(dbi, dbcursor, key, data, 0);
2883 xx = dbiCclose(dbi, dbcursor, DB_WRITECURSOR);
2885 if (!dbi->dbi_no_dbsync)
2886 xx = dbiSync(dbi, 0);
2892 if (!hge(h, rpmtag, &rpmtype, &rpmvals, &rpmcnt))
2901 av[0] = (
const char *) rpmvals;
2907 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, DB_WRITECURSOR);
2909 for (i = 0; i < rpmcnt; i++) {
2914 switch (dbi->dbi_rpmtag) {
2917 if (!(rpmvals[i] && *rpmvals[i] !=
'\0'))
2931 key->data = rpmvals + i;
2934 key->size =
sizeof(
int_16);
2935 key->data = rpmvals + i;
2938 key->size =
sizeof(
int_32);
2939 key->data = rpmvals + i;
2944 key->data = rpmvals;
2955 const char * s = rpmvals[i];
2956 size_t dlen = strlen(s);
2958 assert((dlen & 1) == 0);
2961 for (j = 0; j < dlen; j++, t++, s += 2)
2981 key->data = (
void *) rpmvals[i];
2982 key->size = strlen(rpmvals[i]);
2988 if (rpmcnt == 1 && stringvalued) {
2990 D_(
"removing \"%s\" from %s index.\n"),
2991 (
char *)key->data,
mapTagName(dbi->dbi_rpmtag));
2994 D_(
"removing %d entries from %s index.\n"),
3011 if (key->size == 0) key->size = strlen((
char *)key->data);
3012 if (key->size == 0) key->size++;
3015 rc = dbiGet(dbi, dbcursor, key, data, DB_SET);
3017 (void)
dbt2set(dbi, data, &
set);
3018 }
else if (rc == DB_NOTFOUND) {
3022 _(
"error(%d) setting \"%s\" records from %s index\n"),
3038 if (set->count > 0) {
3039 (void)
set2dbt(dbi, data,
set);
3040 rc = dbiPut(dbi, dbcursor, key, data, DB_KEYLAST);
3043 _(
"error(%d) storing record \"%s\" into %s\n"),
3047 data->data =
_free(data->data);
3050 rc = dbiDel(dbi, dbcursor, key, data, 0);
3053 _(
"error(%d) removing record \"%s\" from %s\n"),
3063 xx = dbiCclose(dbi, dbcursor, DB_WRITECURSOR);
3066 if (!dbi->dbi_no_dbsync)
3067 xx = dbiSync(dbi, 0);
3071 rpmvals = hfd(rpmvals, rpmtype);
3092 rpmRC (*hdrchk) (
rpmts ts,
const void *uh,
size_t uc,
const char ** msg))
3094 DBC * dbcursor = NULL;
3095 DBT * key =
alloca(
sizeof(*key));
3096 DBT * data =
alloca(
sizeof(*data));
3100 sigset_t signalMask;
3101 const char ** baseNames;
3103 const char ** dirNames;
3110 unsigned int hdrNum = 0;
3121 memset(key, 0,
sizeof(*key));
3122 memset(data, 0,
sizeof(*data));
3127 if (iid != 0 && iid != -1) {
3152 unsigned int firstkey = 0;
3153 void * keyp = &firstkey;
3154 size_t keylen =
sizeof(firstkey);
3155 void * datap = NULL;
3166 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, DB_WRITECURSOR);
3174 data->size = datalen;
3175 ret = dbiGet(dbi, dbcursor, key, data, DB_SET);
3179 datalen = data->size;
3184 if (ret == 0 && datap) {
3185 memcpy(&mi_offset, datap,
sizeof(mi_offset.
ui));
3186 if (dbiByteSwapped(dbi) == 1)
3188 hdrNum = mi_offset.
ui;
3191 mi_offset.
ui = hdrNum;
3192 if (dbiByteSwapped(dbi) == 1)
3194 if (ret == 0 && datap) {
3195 memcpy(datap, &mi_offset,
sizeof(mi_offset.
ui));
3198 datalen =
sizeof(mi_offset.
ui);
3207 data->size = datalen;
3210 ret = dbiPut(dbi, dbcursor, key, data, DB_KEYLAST);
3212 xx = dbiSync(dbi, 0);
3214 xx = dbiCclose(dbi, dbcursor, DB_WRITECURSOR);
3223 _(
"error(%d) allocating new package instance\n"), ret);
3236 if (db->db_tagn != NULL)
3237 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
3239 const char **rpmvals = NULL;
3250 requireFlags = NULL;
3252 rpmtag = db->db_tagn[dbix];
3264 if (db->db_export != NULL)
3265 xx = db->db_export(db, h, 1);
3269 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, DB_WRITECURSOR);
3271 mi_offset.
ui = hdrNum;
3272 if (dbiByteSwapped(dbi) == 1)
3275 key->data = (
void *) &mi_offset;
3277 key->size =
sizeof(mi_offset.
ui);
3283 const char * msg = NULL;
3286 rpmrc = (*hdrchk) (ts, data->data, data->size, &msg);
3289 (rpmrc ==
RPMRC_FAIL ?
_(
"rpmdbAdd: skipping") :
" +++"),
3290 hdrNum, (msg ? msg :
"\n"));
3294 if (data->data != NULL && rpmrc !=
RPMRC_FAIL) {
3296 xx = dbiPut(dbi, dbcursor, key, data, DB_KEYLAST);
3298 xx = dbiSync(dbi, 0);
3300 data->data =
_free(data->data);
3302 xx = dbiCclose(dbi, dbcursor, DB_WRITECURSOR);
3304 if (!dbi->dbi_no_dbsync)
3305 xx = dbiSync(dbi, 0);
3310 rpmvals = baseNames;
3314 xx = hge(h, rpmtag, &rpmtype, &rpmvals, &rpmcnt);
3318 xx = hge(h, rpmtag, &rpmtype, &rpmvals, &rpmcnt);
3329 rpmvals = (
const char **)
"Unknown";
3341 av[0] = (
const char *) rpmvals;
3348 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, DB_WRITECURSOR);
3351 for (i = 0; i < rpmcnt; i++) {
3361 switch (dbi->dbi_rpmtag) {
3365 rec->tagNum |=
taghash(dirNames[dirIndexes[i]]);
3371 if (!(rpmvals[i] && *rpmvals[i] !=
'\0'))
3376 if (requireFlags && isInstallPreReq(requireFlags[i]))
3382 for (j = 0; j < i; j++) {
3383 if (!strcmp(rpmvals[i], rpmvals[j]))
3401 key->size =
sizeof(
int_8);
3402 key->data = rpmvals + i;
3405 key->size =
sizeof(
int_16);
3406 key->data = rpmvals + i;
3409 key->size =
sizeof(
int_32);
3410 key->data = rpmvals + i;
3415 key->data = rpmvals;
3426 const char * s = rpmvals[i];
3427 size_t dlen = strlen(s);
3429 assert((dlen & 1) == 0);
3432 for (j = 0; j < dlen; j++, t++, s += 2)
3452 key->data = (
void *) rpmvals[i];
3453 key->size = strlen(rpmvals[i]);
3459 if (rpmcnt == 1 && stringvalued) {
3461 D_(
"adding \"%s\" to %s index.\n"),
3462 (
char *)key->data,
mapTagName(dbi->dbi_rpmtag));
3465 D_(
"adding %d entries to %s index.\n"),
3475 if (key->size == 0) key->size = strlen((
char *)key->data);
3476 if (key->size == 0) key->size++;
3479 rc = dbiGet(dbi, dbcursor, key, data, DB_SET);
3482 if (!dbi->dbi_permit_dups)
3483 (void)
dbt2set(dbi, data, &
set);
3484 }
else if (rc != DB_NOTFOUND) {
3486 _(
"error(%d) getting \"%s\" records from %s index\n"),
3494 set =
xcalloc(1,
sizeof(*
set));
3499 (void)
set2dbt(dbi, data,
set);
3500 rc = dbiPut(dbi, dbcursor, key, data, DB_KEYLAST);
3505 _(
"error(%d) storing record %s into %s\n"),
3510 data->data =
_free(data->data);
3517 xx = dbiCclose(dbi, dbcursor, DB_WRITECURSOR);
3520 if (!dbi->dbi_no_dbsync)
3521 xx = dbiSync(dbi, 0);
3526 rpmvals = hfd(rpmvals, rpmtype);
3539 dirIndexes = hfd(dirIndexes, dit);
3540 dirNames = hfd(dirNames, dnt);
3548 int numItems,
unsigned int exclude)
3559 if (db == NULL)
return 0;
3570 for (i = 0; i < numItems; i++) {
3574 matchList[i] =
xcalloc(1,
sizeof(*(matchList[i])));
3578 key->data = (
void *) fpList[i].baseName;
3580 key->size = strlen((
char *)key->data);
3581 if (key->size == 0) key->size++;
3600 const char ** dirNames;
3601 const char ** baseNames;
3602 const char ** fullBaseNames;
3613 im = mi->
mi_set->recs + start;
3617 for (end = start + 1; end < mi->
mi_set->count; end++) {
3618 if (im->hdrNum != mi->
mi_set->recs[end].hdrNum)
3629 baseNames =
xcalloc(num,
sizeof(*baseNames));
3630 dirIndexes =
xcalloc(num,
sizeof(*dirIndexes));
3632 for (i = 0; i < num; i++) {
3633 baseNames[i] = fullBaseNames[im[i].tagNum];
3634 dirIndexes[i] = fullDirIndexes[im[i].tagNum];
3638 fps =
xcalloc(num,
sizeof(*fps));
3639 fpLookupList(fpc, dirNames, baseNames, dirIndexes, num, fps);
3643 for (i = 0; i < num; i++, im++) {
3645 if (!
FP_EQUAL(fps[i], fpList[im->fpNum]))
3648 xx =
dbiAppendSet(matchList[im->fpNum], im, 1,
sizeof(*im), 0);
3653 dirNames = hfd(dirNames, dnt);
3654 fullBaseNames = hfd(fullBaseNames, bnt);
3655 baseNames =
_free(baseNames);
3656 dirIndexes =
_free(dirIndexes);
3684 if (*fn ==
'\0') fn =
"/";
3693 if (
Stat(fn, &buf)) {
3711 const char * dbpath,
int _dbapi,
3712 const int * dbiTags,
int dbiTagsMax)
3722 if (dbpath[i - 1] !=
'/') {
3724 strcpy(filename, dbpath);
3726 filename[i + 1] =
'\0';
3731 filename =
alloca(strlen(prefix) + strlen(dbpath) + 40);
3738 if (dbiTags != NULL)
3739 for (i = 0; i < dbiTagsMax; i++) {
3743 sprintf(filename,
"%s/%s/%s", prefix, dbpath, base);
3750 for (i = 0; i < 16; i++) {
3751 sprintf(filename,
"%s/%s/__db.%03d", prefix, dbpath, i);
3764 sprintf(filename,
"%s/%s", prefix, dbpath);
3766 xx = rmdir(filename);
3772 const char * olddbpath,
int _olddbapi,
3773 const char * newdbpath,
int _newdbapi,
3774 const int * dbiTags,
int dbiTagsMax)
3780 struct stat * nst =
alloca(
sizeof(*nst));
3786 i = strlen(olddbpath);
3788 if (olddbpath[i - 1] !=
'/') {
3790 strcpy(ofn, olddbpath);
3797 i = strlen(newdbpath);
3799 if (newdbpath[i - 1] !=
'/') {
3801 strcpy(nfn, newdbpath);
3808 ofn =
alloca(strlen(prefix) + strlen(olddbpath) + 40);
3809 nfn =
alloca(strlen(prefix) + strlen(newdbpath) + 40);
3812 switch (_olddbapi) {
3816 if (dbiTags != NULL)
3817 for (i = 0; i < dbiTagsMax; i++) {
3822 switch ((rpmtag = dbiTags[i])) {
3834 sprintf(ofn,
"%s/%s/%s", prefix, olddbpath, base);
3838 sprintf(nfn,
"%s/%s/%s", prefix, newdbpath, base);
3845 if (stat(nfn, nst) < 0)
3846 if (stat(ofn, nst) < 0)
3849 if ((xx = rename(ofn, nfn)) != 0) {
3855 xx = chown(nfn, nst->st_uid, nst->st_gid);
3856 xx = chmod(nfn, (nst->st_mode & 07777));
3857 {
struct utimbuf stamp;
3858 stamp.actime = nst->st_atime;
3859 stamp.modtime = nst->st_mtime;
3860 xx = utime(nfn, &stamp);
3870 for (i = 0; i < 16; i++) {
3871 sprintf(ofn,
"%s/%s/__db.%03d", prefix, olddbpath, i);
3875 sprintf(nfn,
"%s/%s/__db.%03d", prefix, newdbpath, i);
3889 matchpathcon_fini();
3894 rpmRC (*hdrchk) (
rpmts ts,
const void *uh,
size_t uc,
const char ** msg))
3899 const char * dbpath = NULL;
3900 const char * rootdbpath = NULL;
3902 const char * newdbpath = NULL;
3903 const char * newrootdbpath = NULL;
3911 int * dbiTags = NULL;
3915 if (prefix == NULL) prefix =
"/";
3928 if (!(tfn && tfn[0] !=
'\0'))
3935 dbpath = rootdbpath =
rpmGetPath(prefix, tfn, NULL);
3936 if (!(prefix[0] ==
'/' && prefix[1] ==
'\0'))
3937 dbpath += strlen(prefix);
3941 tfn =
rpmGetPath(
"%{?_dbpath_rebuild}", NULL);
3944 if (!(tfn && tfn[0] !=
'\0' && strcmp(tfn, dbpath)))
3949 sprintf(pidbuf,
"rebuilddb.%d", (
int) getpid());
3950 t =
xmalloc(strlen(dbpath) + strlen(pidbuf) + 1);
3958 newdbpath = newrootdbpath =
rpmGetPath(prefix, tfn, NULL);
3959 if (!(prefix[0] ==
'/' && prefix[1] ==
'\0'))
3960 newdbpath += strlen(prefix) - 1;
3964 rootdbpath, newrootdbpath);
3974 if (
Mkdir(newrootdbpath, 0755)) {
3976 newrootdbpath, strerror(
errno));
3993 _dbapi = olddb->db_api;
3999 if (
rpmdbOpenDatabase(prefix, newdbpath, _dbapi_rebuild, &newdb, O_RDWR | O_CREAT, 0644, 0)) {
4007 _dbapi_rebuild = newdb->db_api;
4011 #define _RECNUM rpmdbGetIteratorOffset(mi)
4026 _(
"header #%u in the database is bad -- skipping.\n"),
4033 const char *
name, * version, * release;
4036 (void)
headerNVR(h, &name, &version, &release);
4042 RPMMIRE_DEFAULT, version);
4044 RPMMIRE_DEFAULT, release);
4060 rc =
rpmdbAdd(newdb, -1, (nh ? nh : h), ts, hdrchk);
4066 _(
"cannot add record originally at %u\n"),
_RECNUM);
4081 "remains in place\n"));
4084 dbiTags, dbiTagsMax);
4087 }
else if (!nocleanup) {
4089 dbiTags, dbiTagsMax);
4095 "to recover"), dbpath, newdbpath);
4103 if (removedir && !(rc == 0 && nocleanup)) {
4105 if (
Rmdir(newrootdbpath))
4107 newrootdbpath, strerror(
errno));
4109 newrootdbpath =
_free(newrootdbpath);
4110 rootdbpath =
_free(rootdbpath);
4111 dbiTags =
_free(dbiTags);
4112 prefix =
_free(prefix);