13 #define _MIRE_INTERNAL
20 #define _RPMTAG_INTERNAL
23 #define _RPMEVR_INTERNAL
34 #define _RPMDB_INTERNAL
42 #if defined(__LCLINT__)
43 #define UINT32_T u_int32_t
45 #define UINT32_T rpmuint32_t
49 #if defined(__QNXNTO__)
70 #define _DB_TAGGED_FILE_INDICES 1
75 #define _DB_TAGGED_FINDBYFILE 1
80 #define _DBI_PERMS 0644
87 #define __PBM_NBITS (8 * sizeof(__pbm_bits))
88 #define __PBM_IX(d) ((d) / __PBM_NBITS)
89 #define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS))
95 #define __PBM_BITS(set) ((set)->bits)
97 #define PBM_FREE(s) _free(s);
98 #define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d))
99 #define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d))
100 #define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0)
102 #define PBM_ALLOC(d) xcalloc(__PBM_IX (d) + 1, __PBM_NBITS/8)
122 for (i =
__PBM_IX(*odp) + 1; i < nb; i++)
136 static inline unsigned char nibble(
char c)
139 if (c >=
'0' && c <=
'9')
140 return (
unsigned char)(c -
'0');
141 if (c >=
'A' && c <=
'F')
142 return (
unsigned char)((int)(c -
'A') + 10);
143 if (c >=
'a' && c <=
'f')
144 return (
unsigned char)((int)(c -
'a') + 10);
155 static char *
bin2hex(
const void *data,
size_t size)
158 static char hex[] =
"0123456789abcdef";
159 const char * s = data;
161 val = t =
xmalloc(size * 2 + 1);
165 *t++ = hex[ (i >> 4) & 0xf ];
166 *t++ = hex[ (i ) & 0xf ];
180 static int printable(
const void * ptr,
size_t len)
182 const char * s = ptr;
184 for (i = 0; i < len; i++, s++)
185 if (!(*s >=
' ' && *s <=
'~'))
return 0;
201 if (db->db_tags != NULL)
202 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
203 if (tag != db->db_tags[dbix].tag)
220 static const char *
const _dbiTagStr_default =
221 "Packages:Name:Basenames:Group:Requirename:Providename:Conflictname:Triggername:Dirnames:Requireversion:Provideversion:Installtid:Sigmd5:Sha1header:Filemd5s:Depends:Pubkeys";
224 char * dbiTagStr = NULL;
230 dbiTagStr =
rpmExpand(
"%{?_dbi_tags}", NULL);
231 if (!(dbiTagStr && *dbiTagStr)) {
232 dbiTagStr =
_free(dbiTagStr);
233 dbiTagStr =
xstrdup(_dbiTagStr_default);
237 dbiTags =
xcalloc(1,
sizeof(*dbiTags));
238 dbiTags[dbiNTags].str =
xstrdup(
"Packages");
240 dbiTags[dbiNTags].iob = NULL;
243 for (o = dbiTagStr; o && *o; o = oe) {
248 for (oe = o; oe && *oe; oe++) {
251 if (oe[0] ==
':' && !(oe[1] ==
'/' && oe[2] ==
'/'))
260 for (dbix = 0; dbix < dbiNTags; dbix++) {
261 if (tag == dbiTags[dbix].tag) {
269 dbiTags =
xrealloc(dbiTags, (dbiNTags + 1) *
sizeof(*dbiTags));
270 dbiTags[dbiNTags].str =
xstrdup(o);
271 dbiTags[dbiNTags].tag = tag;
272 dbiTags[dbiNTags].iob = NULL;
276 if (dbiNTagsP != NULL)
277 *dbiNTagsP = dbiNTags;
278 if (dbiTagsP != NULL)
282 dbiTagStr =
_free(dbiTagStr);
293 extern struct _dbiVec
db3vec;
295 #define DB3vec &db3vec
301 #ifdef HAVE_SQLITE3_H
307 #define SQLITEvec &sqlitevec
310 #define SQLITEvec NULL
320 static inline int checkfd(
const char * devnull,
int fdno,
int flags)
326 if (fstat(fdno, &sb) == -1 &&
errno == EBADF)
327 ret = (open(devnull, flags) == fdno) ? 1 : 2;
333 static int _oneshot = 0;
338 int _dbapi, _dbapi_rebuild, _dbapi_wanted;
343 static const char _devnull[] =
"/dev/null";
345 #if defined(STDIN_FILENO)
346 (void)
checkfd(_devnull, STDIN_FILENO, O_RDONLY);
348 #if defined(STDOUT_FILENO)
349 (void)
checkfd(_devnull, STDOUT_FILENO, O_WRONLY);
351 #if defined(STDERR_FILENO)
352 (void)
checkfd(_devnull, STDERR_FILENO, O_WRONLY);
360 fprintf(stderr,
"==> dbiOpen(%p, %s(%u), 0x%x)\n", db,
tagName(tag), tag, flags);
367 if (dbix >= db->db_ndbi)
369 dbiTag = db->db_tags + dbix;
370 dbiBN = (dbiTag->str != NULL ? dbiTag->str :
tagName(tag));
374 if (db->_dbi != NULL && (dbi = db->_dbi[dbix]) != NULL)
379 if (_dbapi_rebuild < 1 || _dbapi_rebuild > 4)
384 switch (_dbapi_wanted) {
386 _dbapi = _dbapi_wanted;
387 if (_dbapi < 0 || _dbapi >= 5 || mydbvecs[_dbapi] == NULL) {
393 rc = (*mydbvecs[_dbapi]->open) (db, tag, &dbi);
395 static int _printed[32];
396 if (!_printed[dbix & 0x1f]++)
398 _(
"cannot open %s(%u) index using db%d - %s (%d)\n"),
400 (rc > 0 ? strerror(rc) :
""), rc);
406 while (_dbapi-- > 1) {
407 if (mydbvecs[_dbapi] == NULL)
411 rc = (*mydbvecs[_dbapi]->open) (db, tag, &dbi);
416 static int _printed[32];
417 if (!_printed[dbix & 0x1f]++)
423 if (db->db_api == -1 && _dbapi > 0)
429 if (dbi != NULL && rc == 0) {
430 if (db->_dbi != NULL)
431 db->_dbi[dbix] = dbi;
464 rec->hdrNum = hdrNum;
465 rec->tagNum = tagNum;
474 #define _DBSWAP(_a) \
475 { unsigned char _b, *_c = (_a).uc; \
476 _b = _c[3]; _c[3] = _c[0]; _c[0] = _b; \
477 _b = _c[2]; _c[2] = _c[1]; _c[1] = _b; \
495 if (dbi == NULL || data == NULL || setp == NULL)
497 _dbbyteswapped = dbiByteSwapped(dbi);
499 if ((sdbir = data->
data) == NULL) {
505 set->count = (int) (data->
size / dbi->dbi_jlen);
509 switch (dbi->dbi_jlen) {
512 for (i = 0; i <
set->count; i++) {
515 memcpy(&hdrNum.
ui, sdbir,
sizeof(hdrNum.
ui));
516 sdbir +=
sizeof(hdrNum.
ui);
517 memcpy(&tagNum.
ui, sdbir,
sizeof(tagNum.
ui));
518 sdbir +=
sizeof(tagNum.
ui);
519 if (_dbbyteswapped) {
523 set->recs[i].hdrNum = hdrNum.
ui;
524 set->recs[i].tagNum = tagNum.
ui;
525 set->recs[i].fpNum = 0;
529 for (i = 0; i <
set->count; i++) {
532 memcpy(&hdrNum.
ui, sdbir,
sizeof(hdrNum.
ui));
533 sdbir +=
sizeof(hdrNum.
ui);
534 if (_dbbyteswapped) {
537 set->recs[i].hdrNum = hdrNum.
ui;
538 set->recs[i].tagNum = 0;
539 set->recs[i].fpNum = 0;
564 if (dbi == NULL || data == NULL ||
set == NULL)
566 _dbbyteswapped = dbiByteSwapped(dbi);
569 if (data->
size == 0) {
576 switch (dbi->dbi_jlen) {
579 for (i = 0; i < (unsigned)
set->count; i++) {
582 memset(&hdrNum, 0,
sizeof(hdrNum));
583 memset(&tagNum, 0,
sizeof(tagNum));
584 hdrNum.
ui =
set->recs[i].hdrNum;
585 tagNum.
ui =
set->recs[i].tagNum;
586 if (_dbbyteswapped) {
590 memcpy(tdbir, &hdrNum.
ui,
sizeof(hdrNum.
ui));
591 tdbir +=
sizeof(hdrNum.
ui);
592 memcpy(tdbir, &tagNum.
ui,
sizeof(tagNum.
ui));
593 tdbir +=
sizeof(tagNum.
ui);
597 for (i = 0; i < (unsigned)
set->count; i++) {
600 memset(&hdrNum, 0,
sizeof(hdrNum));
601 hdrNum.
ui =
set->recs[i].hdrNum;
602 if (_dbbyteswapped) {
605 memcpy(tdbir, &hdrNum.
ui,
sizeof(hdrNum.
ui));
606 tdbir +=
sizeof(hdrNum.
ui);
618 static int hdrNumCmp(
const void * one,
const void * two)
621 const int * a = one, * b = two;
635 int nrecs,
size_t recsize,
int sortset)
638 const char * rptr =
recs;
639 size_t rlen = (recsize <
sizeof(*(
set->recs)))
640 ? recsize :
sizeof(*(
set->recs));
642 if (
set == NULL || recs == NULL || nrecs <= 0 || recsize == 0)
646 (
set->count + nrecs) *
sizeof(*(
set->recs)));
648 memset(
set->recs +
set->count, 0, nrecs *
sizeof(*(
set->recs)));
650 while (nrecs-- > 0) {
652 memcpy(
set->recs +
set->count, rptr, rlen);
658 if (sortset &&
set->count > 1)
674 size_t recsize,
int sorted)
679 int num =
set->count;
682 assert(
set->count > 0);
683 if (nrecs > 1 && !sorted)
686 for (from = 0; from < num; from++) {
687 if (bsearch(&
set->recs[from], recs, nrecs, recsize,
hdrNumCmp)) {
692 set->recs[to] =
set->recs[from];
696 return (numCopied == num);
706 return (
unsigned)
set->recs[recno].hdrNum;
711 return (
unsigned)
set->recs[recno].tagNum;
761 sigset_t newMask, oldMask;
762 static int terminating = 0;
764 if (terminating)
return 1;
766 (void) sigfillset(&newMask);
767 (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask);
785 while ((mi = rpmmiRock) != NULL) {
792 while ((db = rpmdbRock) != NULL) {
793 rpmdbRock = db->db_next;
800 (void) sigprocmask(SIG_SETMASK, &oldMask, NULL);
828 (void) sigfillset(&newMask);
829 (void) sigprocmask(SIG_BLOCK, &newMask, oldMask);
830 (void) sigdelset(&newMask, SIGINT);
831 (void) sigdelset(&newMask, SIGQUIT);
832 (void) sigdelset(&newMask, SIGHUP);
833 (void) sigdelset(&newMask, SIGTERM);
834 (void) sigdelset(&newMask, SIGPIPE);
835 return sigprocmask(SIG_BLOCK, &newMask, NULL);
850 return sigprocmask(SIG_SETMASK, oldMask, NULL);
864 const char * errstr =
"(unkown error)";
888 HE_t he = memset(
alloca(
sizeof(*he)), 0,
sizeof(*he));
889 const char * fn = NULL;
892 {
const char * fnfmt =
rpmGetPath(
"%{?_hrmib_path}", NULL);
895 fnfmt =
_free(fnfmt);
909 struct utimbuf stamp;
910 stamp.actime = he->
p.
ui32p[0];
911 stamp.modtime = he->
p.
ui32p[0];
912 if (!
Utime(fn, &stamp))
936 if (_rpmdbPool == NULL) {
949 if (db == NULL)
return -2;
951 if (db->db_tags != NULL && db->_dbi != NULL)
952 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
954 int tag = dbiTag->tag;
957 if (db->_dbi[dbix] != NULL)
969 (void)
dbiOpen(db, tag, db->db_flags);
979 if (db == NULL || db->_dbi == NULL)
982 if (db->db_tags != NULL)
983 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
984 if (db->db_tags[dbix].tag != tagn)
986 db->db_tags[dbix].tag = tag;
997 if (db == NULL || db->_dbi == NULL)
1000 if (db->db_tags != NULL)
1001 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
1002 if (db->db_tags[dbix].tag != (
rpmTag)tag)
1004 if (db->_dbi[dbix] != NULL) {
1007 xx = dbiClose(db->_dbi[dbix], 0);
1008 if (xx && rc == 0) rc = xx;
1009 db->_dbi[dbix] = NULL;
1023 static const char msg[] =
"rpmdbClose";
1031 yarnPossess(db->_item.use);
1034 fprintf(stderr,
"--> db %p -- %ld %s at %s:%u\n", db, yarnPeekLock(db->_item.use), msg, __FILE__, __LINE__);
1037 if (yarnPeekLock(db->_item.use) <= 1
L) {
1040 for (dbix = db->db_ndbi; dbix;) {
1043 if (db->_dbi[dbix] == NULL)
1046 xx = dbiClose(db->_dbi[dbix], 0);
1047 if (xx && rc == 0) rc = xx;
1048 db->_dbi[dbix] = NULL;
1051 db->db_errpfx =
_free(db->db_errpfx);
1052 db->db_root =
_free(db->db_root);
1053 db->db_home =
_free(db->db_home);
1054 db->db_bits =
PBM_FREE(db->db_bits);
1056 db->_dbi =
_free(db->_dbi);
1061 while ((next = *prev) != NULL && next != db)
1062 prev = &next->db_next;
1064 *prev = next->db_next;
1065 next->db_next = NULL;
1069 if (rpmdbRock == NULL && rpmmiRock == NULL) {
1083 yarnTwist(db->_item.use, BY, -1);
1094 if (db == NULL)
return 0;
1095 if (db->_dbi != NULL)
1096 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
1098 if (db->_dbi[dbix] == NULL)
1100 if (db->_dbi[dbix]->dbi_no_dbsync)
1102 xx = dbiSync(db->_dbi[dbix], 0);
1103 if (xx && rc == 0) rc = xx;
1118 const char * fn = NULL;
1140 if (fn && *fn && *fn !=
'/') {
1144 if ((t =
Realpath(
".", dn)) != NULL) {
1146 if (t > dn && t[-1] !=
'/')
1148 t =
stpncpy(t, fn, (
sizeof(dn) - (t - dn)));
1160 #define _DB_ROOT "/"
1161 #define _DB_HOME "%{?_dbpath}"
1164 #define _DB_PERMS 0644
1166 #define _DB_MAJOR -1
1167 #define _DB_ERRPFX "rpmdb"
1173 int mode,
int perms,
int flags)
1179 static int oneshot = 0;
1183 fprintf(stderr,
"==> rpmdbNew(%s, %s, 0x%x, 0%o, 0x%x) db %p\n", root, home, mode, perms, flags, db);
1195 if (!(perms & 0600)) perms = 0644;
1197 db->db_mode = (mode >= 0) ? mode :
_DB_MODE;
1198 db->db_perms = (perms >= 0) ? perms :
_DB_PERMS;
1199 db->db_flags = (flags >= 0) ? flags :
_DB_FLAGS;
1204 if (!(db->db_home && db->db_home[0] && db->db_home[0] !=
'%')) {
1206 db->db_root =
_free(db->db_root);
1207 db->db_home =
_free(db->db_home);
1214 db->db_remove_env = 0;
1217 db->_dbi =
xcalloc(db->db_ndbi,
sizeof(*db->_dbi));
1226 const char * dbpath,
1227 int _dbapi,
rpmdb *dbp,
1228 int mode,
int perms,
int flags)
1240 if (_dbapi < -1 || _dbapi > 4)
1247 if (mode & O_WRONLY)
1250 db =
rpmdbNew(prefix, dbpath, mode, perms, flags);
1254 if (rpmdbRock == NULL && rpmmiRock == NULL) {
1268 db->db_api = _dbapi;
1273 if (db->db_tags != NULL)
1274 for (dbix = 0; rc == 0 && dbix < db->db_ndbi; dbix++) {
1276 rpmTag tag = dbiTag->tag;
1299 if (dbi == NULL) rc |= 1;
1302 if (db->db_api == 3)
1307 if (dbi == NULL) rc |= 1;
1318 if (rc || justCheck || dbp == NULL)
1340 #ifdef SUPPORT_INITDB
1349 if (xx && rc == 0) rc = xx;
1351 if (xx && rc == 0) rc = xx;
1362 #if defined(SUPPORT_VERIFYDB)
1368 if (db->_dbi != NULL)
1369 for (dbix = db->db_ndbi; dbix;) {
1371 if (db->_dbi[dbix] == NULL)
1374 xx = dbiVerify(db->_dbi[dbix], 0);
1375 if (xx && rc == 0) rc = xx;
1376 db->_dbi[dbix] = NULL;
1383 if (xx && rc == 0) rc = xx;
1393 #if defined(SUPPORT_VERIFYDB)
1398 if (!rc && db != NULL)
1414 while ((c = (
int) *s++) != 0) {
1419 return ((r & 0x7fff) | 0x8000) << 16;
1442 while (i < dnset->count) {
1443 while (j < bnset->count && brec->hdrNum <= drec->hdrNum) {
1444 if (brec->hdrNum == drec->hdrNum
1445 && tag == (brec->tagNum & 0xffff0000))
1450 if (j >= bnset->count)
1452 if (brec->hdrNum == drec->hdrNum
1453 && tag == (brec->tagNum & 0xffff0000))
1456 rec->tagNum &= 0x0000ffff;
1457 if (*matches == NULL)
1458 *matches =
xcalloc(1,
sizeof(**matches));
1466 return (*matches ? (*matches)->count : 0);
1486 const char * baseName;
1496 if (filespec == NULL)
return -2;
1498 if ((baseName = strrchr(filespec,
'/')) != NULL) {
1499 size_t len = baseName - filespec + 1;
1500 char * t = strncpy(
alloca(len + 1), filespec, len);
1506 baseName = filespec;
1508 assert(*dirName !=
'\0');
1509 assert(baseName != NULL);
1516 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
1519 key->
data = (
void *) baseName;
1524 rc = dbiGet(dbi, dbcursor, key, data,
DB_SET);
1527 _(
"error(%d) getting records from %s index\n"),
1528 rc,
tagName(dbi->dbi_rpmtag));
1531 (void)
dbt2set(dbi, data, &bnset);
1532 xx = dbiCclose(dbi, dbcursor, 0);
1535 assert(bnset != NULL);
1536 assert(bnset->count > 0);
1541 for (i = 0; i < bnset->count; i++) {
1542 if (bnset->recs[i].tagNum & 0x80000000)
1556 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
1559 key->
data = (
void *) dirName;
1564 rc = dbiGet(dbi, dbcursor, key, data,
DB_SET);
1567 _(
"error(%d) getting records from %s index\n"),
1568 rc,
tagName(dbi->dbi_rpmtag));
1571 (void)
dbt2set(dbi, data, &dnset);
1572 xx = dbiCclose(dbi, dbcursor, 0);
1575 if (rc == 0 && dnset && dnset->count > 0) {
1576 unsigned int tag =
taghash(dirName);
1580 return (*matches != NULL ? 0 : 1);
1588 unsigned int tag =
taghash(dirName);
1592 for (i = 0; i < bnset->count; i++) {
1593 if (bnset->recs[i].tagNum & 0x80000000) {
1594 unsigned int ctag = (bnset->recs[i].tagNum & 0xffff0000);
1595 bnset->recs[i].tagNum &= 0x0000ffff;
1600 bnset->recs[j] = bnset->recs[i];
1604 if (j > 0 && j < bnset->count)
1608 for (i = 0; i < bnset->count; i++) {
1609 if (bnset->recs[i].tagNum & 0x80000000)
1610 bnset->recs[i].tagNum &= 0x0000ffff;
1616 {
HE_t BN = memset(
alloca(
sizeof(*BN)), 0,
sizeof(*BN));
1617 HE_t DN = memset(
alloca(
sizeof(*DN)), 0,
sizeof(*DN));
1618 HE_t DI = memset(
alloca(
sizeof(*DI)), 0,
sizeof(*DI));
1622 unsigned int prevoff = 0;
1651 assert(num >= 0 && num < (
int)BN->
c);
1659 if (*matches == NULL)
1660 *matches =
xcalloc(1,
sizeof(**matches));
1673 return (*matches != NULL ? 0 : 1);
1678 DBC * dbcursor = NULL;
1685 if (db == NULL || keyp == NULL)
1693 keylen = strlen(keyp);
1696 k.
data = (
void *) keyp;
1700 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
1701 rc = dbiGet(dbi, dbcursor, &k, &v,
DB_SET);
1703 xx = dbiCclose(dbi, dbcursor, 0);
1711 (void)
dbt2set(dbi, &v, &matches);
1722 _(
"error(%d) getting records from %s index\n"),
1723 rc,
tagName(dbi->dbi_rpmtag));
1728 xx = dbiCclose(dbi, dbcursor, 0);
1756 const char * version,
1757 const char * release,
1769 key->
data = (
void *) name;
1773 rc = dbiGet(dbi, dbcursor, key, data,
DB_SET);
1776 (void)
dbt2set(dbi, data, matches);
1777 if (version == NULL && release == NULL)
1784 _(
"error(%d) getting records from %s index\n"),
1785 rc,
tagName(dbi->dbi_rpmtag));
1817 (*matches)->recs[gotMatches++] = (*matches)->recs[i];
1819 (*matches)->recs[i].hdrNum = 0;
1824 (*matches)->count = gotMatches;
1831 if (rc && matches && *matches)
1856 const char * release;
1866 rc =
dbiFindMatches(dbi, dbcursor, key, data, arg, NULL, NULL, matches);
1874 localarg =
alloca(strlen(arg) + 1);
1875 s =
stpcpy(localarg, arg);
1879 for (s -= 1; s > localarg; s--) {
1885 if (c !=
'[') brackets = 0;
1889 if (!brackets && *s ==
'-')
1897 rc =
dbiFindMatches(dbi, dbcursor, key, data, localarg, s + 1, NULL, matches);
1911 for (; s > localarg; s--) {
1917 if (c !=
'[') brackets = 0;
1921 if (!brackets && *s ==
'-')
1929 return dbiFindMatches(dbi, dbcursor, key, data, localarg, s + 1, release, matches);
1938 sw = &dbi->dbi_rpmdb->db_getops;
1941 sw = &dbi->dbi_rpmdb->db_putops;
1945 sw = &dbi->dbi_rpmdb->db_delops;
1965 if (mi == NULL || mi->
mi_h == NULL)
1983 const char * msg = NULL;
1986 assert(v.
data != NULL);
1990 rpmlog(lvl,
"%s h#%8u %s",
1991 (rpmrc ==
RPMRC_FAIL ?
_(
"miFreeHeader: skipping") :
"write"),
1997 sigset_t signalMask;
2002 _(
"error(%d) storing record #%d into %s\n"),
2005 xx = dbiSync(dbi, 0);
2030 while ((next = *prev) != NULL && next != mi)
2040 assert(dbi != NULL);
2045 xx = dbiCclose(dbi, mi->
mi_dbc, 0);
2074 if (_rpmmiPool == NULL) {
2075 _rpmmiPool =
rpmioNewPool(
"mi",
sizeof(*mi), -1, _rpmmi_debug,
2100 static int mireCmp(
const void * a,
const void * b)
2106 return (mireA->tag - mireB->tag);
2117 const char * pattern)
2137 nb = strlen(pattern) +
sizeof(
"^$");
2143 for (s = pattern; *s !=
'\0'; s++) {
2148 if (!brackets) nb++;
2157 if (c != (
int)
'[') brackets = 0;
2165 if (pattern[0] !=
'^') *t++ =
'^';
2170 for (s = pattern; *s !=
'\0'; s++, t++) {
2174 if (!brackets) *t++ =
'\\';
2177 if (!brackets) *t++ =
'.';
2186 if (c != (
int)
'[') brackets = 0;
2193 if (s > pattern && s[-1] !=
'$') *t++ =
'$';
2213 const char * allpat = NULL;
2218 const char *t =
rpmExpand(
"%{?_query_selector_match}", NULL);
2220 if (*t ==
'\0' || !strcmp(t,
"default"))
2222 else if (!strcmp(t,
"strcmp"))
2224 else if (!strcmp(t,
"regex"))
2226 else if (!strcmp(t,
"glob"))
2233 if (mi == NULL || pattern == NULL)
2237 if (*pattern ==
'!') {
2243 assert(nmire != NULL);
2244 allpat =
mireDup(nmire->tag, &nmire->mode, pattern);
2247 nmire->mode = defmode;
2253 if (mi->
mi_re == NULL) {
2257 void *use = mi->
mi_re->_item.use;
2258 void *pool = mi->
mi_re->_item.pool;
2261 memset(mire, 0,
sizeof(*mire));
2264 mire->_item.use = use;
2265 mire->_item.pool = pool;
2270 mire->mode = nmire->mode;
2271 mire->pattern = nmire->pattern; nmire->pattern = NULL;
2272 mire->preg = nmire->preg; nmire->preg = NULL;
2273 mire->cflags = nmire->cflags;
2274 mire->eflags = nmire->eflags;
2275 mire->fnflags = nmire->fnflags;
2276 mire->tag = nmire->tag;
2277 mire->notmatch = notmatch;
2279 mire->offsets = NULL;
2286 allpat =
_free(allpat);
2301 HE_t he = memset(
alloca(
sizeof(*he)), 0,
sizeof(*he));
2309 if (mi->
mi_h == NULL)
2316 if ((mire = mi->
mi_re) == NULL)
2319 for (i = 0; i < mi->
mi_nre; i++, mire++) {
2322 he->
tag = mire->tag;
2339 for (j = 0; j < (unsigned) he->
c; j++) {
2340 sprintf(numbuf,
"%u", (
unsigned) he->
p.
ui8p[j]);
2342 if ((rc >= 0 && !mire->notmatch) || (rc < 0 && mire->notmatch))
2347 for (j = 0; j < (unsigned) he->
c; j++) {
2348 sprintf(numbuf,
"%u", (
unsigned) he->
p.
ui16p[j]);
2350 if ((rc >= 0 && !mire->notmatch) || (rc < 0 && mire->notmatch))
2355 for (j = 0; j < (unsigned) he->
c; j++) {
2356 sprintf(numbuf,
"%u", (
unsigned) he->
p.
ui32p[j]);
2358 if ((rc >= 0 && !mire->notmatch) || (rc < 0 && mire->notmatch))
2364 for (j = 0; j < (unsigned) he->
c; j++) {
2365 sprintf(numbuf,
"%llu", (
unsigned long long)he->
p.
ui64p[j]);
2367 if ((rc >= 0 && !mire->notmatch) || (rc < 0 && mire->notmatch))
2374 if ((rc >= 0 && !mire->notmatch) || (rc < 0 && mire->notmatch))
2378 for (j = 0; j < (unsigned) he->
c; j++) {
2380 if ((rc >= 0 && !mire->notmatch) || (rc < 0 && mire->notmatch)) {
2388 assert(he->
p.
ptr != NULL);
2391 if ((rc >= 0 && !mire->notmatch) || (rc < 0 && mire->notmatch))
2399 if ((i+1) < mi->
mi_nre && mire[0].tag == mire[1].tag) {
2414 return (ntags > 0 && ntags == nmatches ? 0 : 1);
2460 switch (dbi->dbi_rpmdb->db_api) {
2461 default: map = 0;
break;
2466 static const int _prot = PROT_READ | PROT_WRITE;
2467 static const int _flags = MAP_PRIVATE| MAP_ANONYMOUS;
2468 static const int _fdno = -1;
2469 static const off_t _off = 0;
2471 vp->
flags |= DB_DBT_USERMEM;
2472 rc = dbiGet(dbi, dbcursor, kp, vp, flags);
2473 if (rc == DB_BUFFER_SMALL) {
2474 size_t uhlen = vp->
size;
2475 void * uh = mmap(NULL, uhlen, _prot, _flags, _fdno, _off);
2476 if (uh == NULL || uh == (
void *)-1)
2478 "==> mmap(%p[%u], 0x%x, 0x%x, %d, 0x%x) error(%d): %s\n",
2479 NULL, uhlen, _prot, _flags, _fdno, (
unsigned)_off,
2482 vp->ulen = (u_int32_t)uhlen;
2484 rc = dbiGet(dbi, dbcursor, kp, vp,
DB_SET);
2486 if (mprotect(uh, uhlen, PROT_READ) != 0)
2487 fprintf(stderr,
"==> mprotect(%p[%u],0x%x) error(%d): %s\n",
2488 uh, uhlen, PROT_READ,
2491 if (munmap(uh, uhlen) != 0)
2492 fprintf(stderr,
"==> munmap(%p[%u]) error(%d): %s\n",
2497 rc = dbiGet(dbi, dbcursor, kp, vp, flags);
2520 switch (dbi->dbi_rpmdb->db_api) {
2521 default: map = 0;
break;
2547 if (dbiByteSwapped(dbi) == 1)
2552 k.
size = (u_int32_t)
sizeof(mi_offset.
ui);
2565 memcpy(&mi_offset, k.
data,
sizeof(mi_offset.
ui));
2566 if (dbiByteSwapped(dbi) == 1)
2570 }
while (rc == 0 && mi_offset.
ui == 0);
2591 if (mi->
mi_db->db_bits) {
2602 const char * msg = NULL;
2608 rpmlog(lvl,
"%s h#%8u %s\n",
2609 (rpmrc ==
RPMRC_FAIL ?
_(
"rpmdb: skipping") :
_(
"rpmdb: read")),
2641 _(
"rpmdb: damaged header #%u retrieved -- skipping.\n"),
2658 sprintf(origin,
"rpmdb (h#%u)", mi->
mi_offset);
2679 #if defined(__GLIBC__)
2691 unsigned int exclude,
unsigned int tag)
2710 if (key->
data == NULL)
2717 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
2718 rc = dbiGet(dbi, dbcursor, key, data,
DB_SET);
2720 xx = dbiCclose(dbi, dbcursor, 0);
2727 _(
"error(%d) getting records from %s index\n"),
2728 rc,
tagName(dbi->dbi_rpmtag));
2730 xx = dbiCclose(dbi, dbcursor, 0);
2737 (void)
dbt2set(dbi, data, &
set);
2740 for (i = j = 0; i <
set->count; i++) {
2741 if (exclude &&
set->recs[i].hdrNum == exclude)
2745 if ((
set->recs[i].tagNum & 0xffff0000) != tag)
2747 set->recs[i].tagNum &= 0x0000ffff;
2750 set->recs[j] =
set->recs[i];
2755 xx = dbiCclose(dbi, dbcursor, 0);
2763 for (i = 0; i <
set->count; i++)
2764 set->recs[i].fpNum = fpNum;
2767 xx = dbiCclose(dbi, dbcursor, 0);
2771 if (mi->
mi_set == NULL) {
2775 fprintf(stderr,
"+++ %d = %d + %d\t\"%s\"\n", (mi->
mi_set->count +
set->count), mi->
mi_set->count,
set->count, ((
char *)key->
data));
2780 set->count *
sizeof(*(mi->
mi_set->recs)));
2781 mi->
mi_set->count +=
set->count;
2790 if (mi == NULL || hdrNums == NULL || nHdrNums <= 0)
2800 if (mi == NULL || hdrNums == NULL || nHdrNums <= 0)
2810 const void * keyp,
size_t keylen)
2843 assert(keylen == 0);
2849 assert(keylen ==
sizeof(hdrNum.
ui));
2850 memcpy(&hdrNum.
ui, keyp,
sizeof(hdrNum.
ui));
2852 set =
xcalloc(1,
sizeof(*
set));
2854 set->recs =
xcalloc(1,
sizeof(
set->recs[0]));
2855 set->recs[0].hdrNum = hdrNum.
ui;
2857 else if (keyp == NULL) {
2860 assert(keylen == 0);
2864 DBC * dbcursor = NULL;
2871 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
2873 xx = dbiCclose(dbi, dbcursor, 0);
2878 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
2881 k.
data = (
void *) keyp;
2888 rc = dbiGet(dbi, dbcursor, &k, &v,
DB_SET);
2892 _(
"error(%d) getting records from %s index\n"),
2893 rc,
tagName(dbi->dbi_rpmtag));
2898 (void)
dbt2set(dbi, &v, &
set);
2900 xx = dbiCclose(dbi, dbcursor, 0);
2903 if (rc ||
set == NULL ||
set->count < 1) {
2936 const char *** argvp)
2938 DBC * dbcursor = NULL;
2939 DBT * key = memset(
alloca(
sizeof(*key)), 0,
sizeof(*key));
2940 DBT * data = memset(
alloca(
sizeof(*data)), 0,
sizeof(*data));
2957 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
2959 while ((rc = dbiGet(dbi, dbcursor, key, data,
DB_NEXT)) == 0) {
2960 size_t ns = key->
size;
2964 if (mire == NULL ||
mireRegexec(mire, s, ns) >= 0)
2969 xx = dbiCclose(dbi, dbcursor, 0);
2974 rc,
tagName(dbi->dbi_rpmtag));
2992 HE_t he = memset(
alloca(
sizeof(*he)), 0,
sizeof(*he));
2994 sigset_t signalMask;
3012 "rpmdbRemove", hdrNum);
3018 if (rid != 0 && rid != -1) {
3041 if (db->db_tags != NULL)
3042 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
3044 DBC * dbcursor = NULL;
3050 rpmTag tag = dbiTag->tag;
3051 const char * dbiBN = (dbiTag->str != NULL
3052 ? dbiTag->str :
tagName(tag));
3071 if (db->db_export != NULL)
3072 xx = db->db_export(db, h, 0);
3078 mi_offset.
ui = hdrNum;
3079 if (dbiByteSwapped(dbi) == 1)
3081 k.
data = &mi_offset;
3086 rc = dbiGet(dbi, dbcursor, &k, &v,
DB_SET);
3089 _(
"error(%d) setting header #%d record for %s removal\n"),
3092 rc = dbiDel(dbi, dbcursor, &k, &v, 0);
3095 if (!dbi->dbi_no_dbsync)
3096 xx = dbiSync(dbi, 0);
3112 const char * s = he->
p.
str;
3117 (
void) strcpy(t, s);
3123 for (i = 0; i < (int) he->
c; i++) {
3128 switch (dbi->dbi_rpmtag) {
3131 if (!(he->
p.
argv[i] && *he->
p.
argv[i] !=
'\0'))
3169 const char * s = he->
p.
argv[i];
3170 size_t dlen = strlen(s);
3173 assert((dlen & 1) == 0);
3177 for (j = 0; j < (unsigned) dlen; j++, t++, s += 2)
3204 if (he->
c == 1 && stringvalued) {
3206 D_(
"removing \"%s\" from %s index.\n"),
3207 (
char *)k.
data, dbiBN);
3210 D_(
"removing %u entries from %s index.\n"),
3211 (
unsigned) he->
c, dbiBN);
3231 rc = dbiGet(dbi, dbcursor, &k, &v,
DB_SET);
3233 (void)
dbt2set(dbi, &v, &
set);
3238 _(
"error(%d) getting records from %s index\n"),
3254 if (
set->count > 0) {
3256 rc = dbiPut(dbi, dbcursor, &k, &v,
DB_KEYLAST);
3259 _(
"error(%d) storing record into %s\n"),
3266 rc = dbiDel(dbi, dbcursor, &k, &v, 0);
3269 _(
"error(%d) removing record from %s\n"),
3281 if (!dbi->dbi_no_dbsync)
3282 xx = dbiSync(dbi, 0);
3308 HE_t he = memset(
alloca(
sizeof(*he)), 0,
sizeof(*he));
3309 sigset_t signalMask;
3310 const char ** dirNames;
3315 unsigned int hdrNum = 0;
3330 if (iid != 0 && iid != -1) {
3360 dirNames = he->
p.
argv;
3365 dirIndexes = he->
p.
ui32p;
3374 unsigned int idx0 = 0;
3376 DBC * dbcursor = NULL;
3384 k.
size = (u_int32_t)
sizeof(idx0);
3385 ret = dbiGet(dbi, dbcursor, &k, &v,
DB_SET);
3388 if (ret == 0 && v.
data) {
3389 memcpy(&mi_offset, v.
data,
sizeof(mi_offset.
ui));
3390 if (dbiByteSwapped(dbi) == 1)
3392 hdrNum = (unsigned) mi_offset.
ui;
3395 mi_offset.
ui = hdrNum;
3396 if (dbiByteSwapped(dbi) == 1)
3398 if (ret == 0 && v.
data) {
3399 memcpy(v.
data, &mi_offset,
sizeof(mi_offset.
ui));
3402 v.
data = &mi_offset;
3404 v.
size = (u_int32_t)
sizeof(mi_offset.
ui);
3408 ret = dbiPut(dbi, dbcursor, &k, &v,
DB_KEYLAST);
3410 xx = dbiSync(dbi, 0);
3418 _(
"error(%d) allocating new package instance\n"), ret);
3430 if (db->db_tags != NULL)
3431 for (dbix = 0; dbix < db->db_ndbi; dbix++) {
3432 DBC * dbcursor = NULL;
3437 const char * dbiBN = (dbiTag->str != NULL
3438 ? dbiTag->str :
tagName(dbiTag->tag));
3445 requireFlags.
ptr = NULL;
3447 he->
tag = dbiTag->tag;
3461 if (db->db_export != NULL)
3462 xx = db->db_export(db, h, 1);
3468 mi_offset.
ui = hdrNum;
3469 if (dbiByteSwapped(dbi) == 1)
3472 k.
data = (
void *) &mi_offset;
3482 const char * msg = NULL;
3485 assert(v.
data != NULL);
3489 rpmlog(lvl,
"%s h#%8u %s\n",
3490 (rpmrc ==
RPMRC_FAIL ?
_(
"rpmdbAdd: skipping") :
" +++"),
3491 hdrNum, (msg ? msg :
""));
3497 xx = dbiPut(dbi, dbcursor, &k, &v,
DB_KEYLAST);
3499 xx = dbiSync(dbi, 0);
3504 if (!dbi->dbi_no_dbsync)
3505 xx = dbiSync(dbi, 0);
3536 const char * s = he->
p.
str;
3541 (
void) strcpy(t, s);
3548 for (i = 0; i < (int) he->
c; i++) {
3558 switch (dbi->dbi_rpmtag) {
3562 rec->tagNum |=
taghash(dirNames[dirIndexes[i]]);
3568 if (!(he->
p.
argv[i] && *he->
p.
argv[i] !=
'\0'))
3573 if (requireFlags.
ui32p
3574 && isInstallPreReq(requireFlags.
ui32p[i]))
3580 for (j = 0; j < i; j++) {
3623 const char * s = he->
p.
argv[i];
3624 size_t dlen = strlen(s);
3627 assert((dlen & 1) == 0);
3631 for (j = 0; j < (unsigned) dlen; j++, t++, s += 2)
3658 if (he->
c == 1 && stringvalued) {
3660 D_(
"adding \"%s\" to %s index.\n"),
3661 (
char *)k.
data, dbiBN);
3664 D_(
"adding %u entries to %s index.\n"),
3665 (
unsigned)he->
c, dbiBN);
3678 rc = dbiGet(dbi, dbcursor, &k, &v,
DB_SET);
3681 if (!dbi->dbi_permit_dups)
3682 (void)
dbt2set(dbi, &v, &
set);
3685 _(
"error(%d) getting records from %s index\n"),
3693 set =
xcalloc(1,
sizeof(*
set));
3699 rc = dbiPut(dbi, dbcursor, &k, &v,
DB_KEYLAST);
3704 _(
"error(%d) storing record into %s\n"),
3717 if (!dbi->dbi_no_dbsync)
3718 xx = dbiSync(dbi, 0);
3736 dirIndexes =
_free(dirIndexes);
3737 dirNames =
_free(dirNames);
3745 int numItems,
unsigned int exclude)
3751 HE_t he = memset(
alloca(
sizeof(*he)), 0,
sizeof(*he));
3757 if (db == NULL)
return 0;
3768 for (i = 0; i < numItems; i++) {
3771 matchList[i] =
xcalloc(1,
sizeof(*(matchList[i])));
3774 key->
data = (
void *) fpList[i].baseName;
3796 const char ** dirNames;
3797 const char ** baseNames;
3798 const char ** fullBaseNames;
3808 im = mi->
mi_set->recs + start;
3811 for (end = start + 1; end < mi->
mi_set->count; end++) {
3812 if (im->hdrNum != mi->
mi_set->recs[end].hdrNum)
3820 fullBaseNames = he->
p.
argv;
3823 dirNames = he->
p.
argv;
3826 fullDirIndexes = he->
p.
ui32p;
3828 baseNames =
xcalloc(num,
sizeof(*baseNames));
3829 dirIndexes =
xcalloc(num,
sizeof(*dirIndexes));
3830 for (i = 0; i < num; i++) {
3831 baseNames[i] = fullBaseNames[im[i].tagNum];
3832 dirIndexes[i] = fullDirIndexes[im[i].tagNum];
3835 fps =
xcalloc(num,
sizeof(*fps));
3836 fpLookupList(fpc, dirNames, baseNames, dirIndexes, num, fps);
3839 for (i = 0; i < num; i++, im++) {
3841 if (!
FP_EQUAL(fps[i], fpList[im->fpNum]))
3844 xx =
dbiAppendSet(matchList[im->fpNum], im, 1,
sizeof(*im), 0);
3848 fullBaseNames =
_free(fullBaseNames);
3850 dirNames =
_free(dirNames);
3852 fullDirIndexes =
_free(fullDirIndexes);
3853 baseNames =
_free(baseNames);
3854 dirIndexes =
_free(dirIndexes);
3882 if (*fn ==
'\0') fn =
"/";
3888 rc =
Stat(urlfn, &sb) == 0;
3892 rc =
Stat(fn, &sb) == 0;
3903 const char * dbpath,
int _dbapi,
3919 if (dbiTags != NULL)
3920 for (i = 0; i < dbiNTags; i++) {
3921 const char * dbiBN = (dbiTags[i].str != NULL
3922 ? dbiTags[i].str :
tagName(dbiTags[i].tag));
3923 fn =
rpmGetPath(prefix, dbpath,
"/", dbiBN, NULL);
3929 fn =
rpmGetPath(prefix, dbpath,
"/",
"__db.000", NULL);
3930 suffix = (
char *)(fn + strlen(fn) - (
sizeof(
"000") - 1));
3931 for (i = 0; i < 16; i++) {
3932 (void)
snprintf(suffix,
sizeof(
"000"),
"%03u", (unsigned)i);
3953 const char * olddbpath,
int _olddbapi,
3954 const char * newdbpath,
int _newdbapi,
3959 struct stat nsb, * nst = &nsb;
3960 const char * ofn, * nfn;
3969 switch (_olddbapi) {
3974 {
char *osuffix, *nsuffix;
3976 if (dbiTags != NULL)
3977 for (i = 0; i < dbiNTags; i++) {
3978 rpmTag tag = dbiTags[i].tag;
3979 const char * dbiBN = (dbiTags[i].str != NULL
3980 ? dbiTags[i].str :
tagName(tag));
3994 ofn =
rpmGetPath(prefix, olddbpath,
"/", dbiBN, NULL);
3995 nfn =
rpmGetPath(prefix, newdbpath,
"/", dbiBN, NULL);
4009 if (
Stat(nfn, nst) < 0 &&
Stat(ofn, nst) < 0)
4014 if ((xx =
Rename(ofn, nfn)) != 0) {
4020 xx =
Chown(nfn, nst->st_uid, nst->st_gid);
4021 xx =
Chmod(nfn, (nst->st_mode & 07777));
4022 {
struct utimbuf stamp;
4024 stamp.actime = (time_t)nst->st_atime;
4025 stamp.modtime = (time_t)nst->st_mtime;
4027 xx =
Utime(nfn, &stamp);
4044 ofn =
rpmGetPath(prefix, olddbpath,
"/",
"__db.000", NULL);
4045 osuffix = (
char *)(ofn + strlen(ofn) - (
sizeof(
"000") - 1));
4046 nfn =
rpmGetPath(prefix, newdbpath,
"/",
"__db.000", NULL);
4047 nsuffix = (
char *)(nfn + strlen(nfn) - (
sizeof(
"000") - 1));
4049 for (i = 0; i < 16; i++) {
4050 (void)
snprintf(osuffix,
sizeof(
"000"),
"%03u", (unsigned)i);
4055 (void)
snprintf(nsuffix,
sizeof(
"000"),
"%03u", (unsigned)i);
4082 const char * myprefix = NULL;
4084 const char * dbpath = NULL;
4085 const char * rootdbpath = NULL;
4087 const char * newdbpath = NULL;
4088 const char * newrootdbpath = NULL;
4097 size_t dbiNTags = 0;
4107 if (!(tfn && tfn[0] !=
'\0'))
4120 myprefix =
rpmGetPath((prefix ? prefix :
"/"), NULL);
4124 dbpath = rootdbpath =
rpmGetPath(myprefix, tfn, NULL);
4125 if (!(myprefix[0] ==
'/' && myprefix[1] ==
'\0'))
4126 dbpath += strlen(myprefix);
4130 tfn =
rpmGetPath(
"%{?_dbpath_rebuild}", NULL);
4132 if (!(tfn && tfn[0] !=
'\0' && strcmp(tfn, dbpath)))
4136 sprintf(pidbuf,
"rebuilddb.%d", (
int) getpid());
4137 t =
xmalloc(strlen(dbpath) + strlen(pidbuf) + 1);
4143 newdbpath = newrootdbpath =
rpmGetPath(myprefix, tfn, NULL);
4144 if (!(myprefix[0] ==
'/' && myprefix[1] ==
'\0'))
4145 newdbpath += strlen(myprefix);
4149 rootdbpath, newrootdbpath);
4159 if (
Mkdir(newrootdbpath, 0755)) {
4161 newrootdbpath, strerror(
errno));
4176 _dbapi = olddb->db_api;
4181 if (
rpmdbOpenDatabase(myprefix, newdbpath, _dbapi_rebuild, &newdb, O_RDWR | O_CREAT, 0644, 0)) {
4188 _dbapi_rebuild = newdb->db_api;
4192 #define _RECNUM rpmmiInstance(mi)
4207 _(
"header #%u in the database is bad -- skipping.\n"),
4215 _(
"header #%u in the database is SRPM -- skipping.\n"),
4222 const char *
name, * version, * release;
4225 (void)
headerNEVRA(h, &name, NULL, &version, &release, NULL);
4249 rc =
rpmdbAdd(newdb, -1, (nh ? nh : h), ts);
4256 _(
"cannot add record originally at %u\n"),
_RECNUM);
4271 "remains in place\n"));
4277 }
else if (!nocleanup) {
4285 "to recover"), dbpath, newdbpath);
4293 if (removedir && !(rc == 0 && nocleanup)) {
4295 if (
Rmdir(newrootdbpath))
4297 newrootdbpath, strerror(
errno));
4299 newrootdbpath =
_free(newrootdbpath);
4300 rootdbpath =
_free(rootdbpath);
4302 myprefix =
_free(myprefix);