3 * Routine(s) to handle a "rpmts" transaction sets.
10 #include <rpm/rpmtypes.h>
11 #include <rpm/rpmlib.h> /* rpmReadPackage etc */
12 #include <rpm/rpmmacro.h>
13 #include <rpm/rpmfileutil.h> /* rpmtsOpenDB() needs rpmGetPath */
14 #include <rpm/rpmstring.h>
15 #include <rpm/rpmkeyring.h>
17 #include <rpm/rpmdb.h>
18 #include <rpm/rpmds.h>
19 #include <rpm/rpmfi.h>
20 #include <rpm/rpmlog.h>
21 #include <rpm/rpmte.h>
22 #include <rpm/rpmplugins.h>
24 #include "rpmio/digest.h"
25 #include "lib/rpmal.h"
26 #include "lib/rpmchroot.h"
27 #include "lib/rpmts_internal.h"
28 #include "lib/rpmte_internal.h"
34 * Iterator across transaction elements, forward on install, backward on erase.
37 rpmts ts; /*!< transaction set. */
38 int oc; /*!< iterator index. */
41 static void loadKeyring(rpmts ts);
45 static rpmts rpmtsUnlink(rpmts ts)
52 rpmts rpmtsLink(rpmts ts)
59 int rpmtsCloseDB(rpmts ts)
63 if (ts->rdb != NULL) {
64 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBGET),
65 rpmdbOp(ts->rdb, RPMDB_OP_DBGET));
66 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBPUT),
67 rpmdbOp(ts->rdb, RPMDB_OP_DBPUT));
68 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBDEL),
69 rpmdbOp(ts->rdb, RPMDB_OP_DBDEL));
70 rc = rpmdbClose(ts->rdb);
76 int rpmtsOpenDB(rpmts ts, int dbmode)
80 if (ts->rdb != NULL && ts->dbmode == dbmode)
83 (void) rpmtsCloseDB(ts);
85 /* XXX there's a potential db lock race here. */
88 rc = rpmdbOpen(ts->rootDir, &ts->rdb, ts->dbmode, 0644);
90 char * dn = rpmGetPath(ts->rootDir, "%{_dbpath}", NULL);
92 _("cannot open Packages database in %s\n"), dn);
98 int rpmtsInitDB(rpmts ts, int dbmode)
100 rpmlock lock = rpmtsAcquireLock(ts);
103 rc = rpmdbInit(ts->rootDir, dbmode);
108 int rpmtsGetDBMode(rpmts ts)
114 int rpmtsSetDBMode(rpmts ts, int dbmode)
117 /* mode setting only permitted on non-open db */
118 if (ts != NULL && rpmtsGetRdb(ts) == NULL) {
126 int rpmtsRebuildDB(rpmts ts)
129 rpmlock lock = rpmtsAcquireLock(ts);
130 if (!lock) return -1;
131 if (!(ts->vsflags & RPMVSF_NOHDRCHK))
132 rc = rpmdbRebuild(ts->rootDir, ts, headerCheck);
134 rc = rpmdbRebuild(ts->rootDir, NULL, NULL);
139 int rpmtsVerifyDB(rpmts ts)
142 rpmlock lock = rpmtsAcquireLock(ts);
144 rc = rpmdbVerify(ts->rootDir);
150 /* keyp might no be defined. */
151 rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmDbiTagVal rpmtag,
152 const void * keyp, size_t keylen)
154 rpmdbMatchIterator mi = NULL;
155 const char * arch = NULL;
162 if (ts && ts->keyring == NULL)
165 if (ts->rdb == NULL && rpmtsOpenDB(ts, ts->dbmode))
168 /* Parse out "N(EVR).A" tokens from a label key. */
169 if (rpmtag == RPMDBI_LABEL && keyp != NULL) {
170 const char *se, *s = keyp;
172 size_t slen = strlen(s);
176 tmp = xmalloc(slen+1);
178 while ((c = *s++) != '\0') {
184 /* XXX Fail if nested parens. */
186 rpmlog(RPMLOG_ERR, _("extra '(' in package label: %s\n"), (const char*)keyp);
189 /* Parse explicit epoch. */
190 for (se = s; *se && risdigit(*se); se++)
193 /* XXX skip explicit epoch's (for now) */
197 /* No Epoch: found. Convert '(' to '-' and chug. */
202 /* XXX Fail if nested parens. */
204 rpmlog(RPMLOG_ERR, _("missing '(' in package label: %s\n"), (const char*)keyp);
207 /* Don't copy trailing ')' */
212 rpmlog(RPMLOG_ERR, _("missing ')' in package label: %s\n"), (const char*)keyp);
218 /* Is this a valid ".arch" suffix? */
219 if (t != NULL && rpmIsKnownArch(t+1)) {
225 mi = rpmdbInitIterator(ts->rdb, rpmtag, keyp, keylen);
227 /* Verify header signature/digest during retrieve (if not disabled). */
228 if (mi && !(ts->vsflags & RPMVSF_NOHDRCHK))
229 (void) rpmdbSetHdrChk(mi, ts, headerCheck);
231 /* Select specified arch only. */
233 xx = rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_DEFAULT, arch);
241 rpmKeyring rpmtsGetKeyring(rpmts ts, int autoload)
243 rpmKeyring keyring = NULL;
245 if (ts->keyring == NULL && autoload) {
248 keyring = rpmKeyringLink(ts->keyring);
253 int rpmtsSetKeyring(rpmts ts, rpmKeyring keyring)
256 * Should we permit switching keyring on the fly? For now, require
257 * rpmdb isn't open yet (fairly arbitrary limitation)...
259 if (ts == NULL || rpmtsGetRdb(ts) != NULL)
262 rpmKeyringFree(ts->keyring);
263 ts->keyring = rpmKeyringLink(keyring);
267 static int loadKeyringFromFiles(rpmts ts)
270 /* XXX TODO: deal with chroot path issues */
271 char *pkpath = rpmGetPath(ts->rootDir, "%{_keyringpath}/*.key", NULL);
274 rpmlog(RPMLOG_DEBUG, "loading keyring from pubkeys in %s\n", pkpath);
275 if (rpmGlob(pkpath, NULL, &files)) {
276 rpmlog(RPMLOG_DEBUG, "couldn't find any keys in %s\n", pkpath);
280 for (char **f = files; *f; f++) {
281 rpmPubkey key = rpmPubkeyRead(*f);
283 rpmlog(RPMLOG_ERR, _("%s: reading of public key failed.\n"), *f);
286 if (rpmKeyringAddKey(ts->keyring, key) == 0) {
288 rpmlog(RPMLOG_DEBUG, "added key %s to keyring\n", *f);
298 static int loadKeyringFromDB(rpmts ts)
301 rpmdbMatchIterator mi;
304 rpmlog(RPMLOG_DEBUG, "loading keyring from rpmdb\n");
305 mi = rpmtsInitIterator(ts, RPMDBI_NAME, "gpg-pubkey", 0);
306 while ((h = rpmdbNextIterator(mi)) != NULL) {
307 struct rpmtd_s pubkeys;
310 if (!headerGet(h, RPMTAG_PUBKEYS, &pubkeys, HEADERGET_MINMEM))
313 while ((key = rpmtdNextString(&pubkeys))) {
317 if (b64decode(key, (void **) &pkt, &pktlen) == 0) {
318 rpmPubkey key = rpmPubkeyNew(pkt, pktlen);
319 if (rpmKeyringAddKey(ts->keyring, key) == 0) {
320 char *nvr = headerGetAsString(h, RPMTAG_NVR);
321 rpmlog(RPMLOG_DEBUG, "added key %s to keyring\n", nvr);
329 rpmtdFreeData(&pubkeys);
331 rpmdbFreeIterator(mi);
336 static void loadKeyring(rpmts ts)
338 ts->keyring = rpmKeyringNew();
339 if (loadKeyringFromFiles(ts) == 0) {
340 if (loadKeyringFromDB(ts) > 0) {
341 /* XXX make this a warning someday... */
342 rpmlog(RPMLOG_DEBUG, "Using legacy gpg-pubkey(s) from rpmdb\n");
347 /* Build pubkey header. */
348 static int makePubkeyHeader(rpmts ts, rpmPubkey key, Header h)
350 const char * afmt = "%{pubkeys:armor}";
351 const char * group = "Public Keys";
352 const char * license = "pubkey";
353 const char * buildhost = "localhost";
354 rpmsenseFlags pflags = (RPMSENSE_KEYRING|RPMSENSE_EQUAL);
357 pgpDigParams pubp = NULL;
367 if ((enc = rpmPubkeyBase64(key)) == NULL)
369 if ((dig = rpmPubkeyDig(key)) == NULL)
372 /* Build header elements. */
374 v = pgpHexStr(pubp->signid, sizeof(pubp->signid));
375 r = pgpHexStr(pubp->time, sizeof(pubp->time));
377 rasprintf(&n, "gpg(%s)", v+8);
378 rasprintf(&u, "gpg(%s)", pubp->userid ? pubp->userid : "none");
379 rasprintf(&evr, "%d:%s-%s", pubp->version, v, r);
381 headerPutString(h, RPMTAG_PUBKEYS, enc);
383 if ((d = headerFormat(h, afmt, NULL)) == NULL)
386 headerPutString(h, RPMTAG_NAME, "gpg-pubkey");
387 headerPutString(h, RPMTAG_VERSION, v+8);
388 headerPutString(h, RPMTAG_RELEASE, r);
389 headerPutString(h, RPMTAG_DESCRIPTION, d);
390 headerPutString(h, RPMTAG_GROUP, group);
391 headerPutString(h, RPMTAG_LICENSE, license);
392 headerPutString(h, RPMTAG_SUMMARY, u);
394 headerPutUint32(h, RPMTAG_SIZE, &zero, 1);
396 headerPutString(h, RPMTAG_PROVIDENAME, u);
397 headerPutString(h, RPMTAG_PROVIDEVERSION, evr);
398 headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pflags, 1);
400 headerPutString(h, RPMTAG_PROVIDENAME, n);
401 headerPutString(h, RPMTAG_PROVIDEVERSION, evr);
402 headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pflags, 1);
404 headerPutString(h, RPMTAG_RPMVERSION, RPMVERSION);
405 headerPutString(h, RPMTAG_BUILDHOST, buildhost);
406 headerPutString(h, RPMTAG_SOURCERPM, "(none)");
408 { rpm_tid_t tid = rpmtsGetTid(ts);
409 headerPutUint32(h, RPMTAG_INSTALLTIME, &tid, 1);
410 headerPutUint32(h, RPMTAG_INSTALLTID, &tid, 1);
411 headerPutUint32(h, RPMTAG_BUILDTIME, &tid, 1);
428 rpmRC rpmtsImportPubkey(const rpmts ts, const unsigned char * pkt, size_t pktlen)
430 Header h = headerNew();
431 rpmRC rc = RPMRC_FAIL; /* assume failure */
432 rpmPubkey pubkey = NULL;
433 rpmKeyring keyring = rpmtsGetKeyring(ts, 1);
436 if ((pubkey = rpmPubkeyNew(pkt, pktlen)) == NULL)
438 krc = rpmKeyringAddKey(keyring, pubkey);
442 /* If we dont already have the key, make a persistent record of it */
444 if (makePubkeyHeader(ts, pubkey, h) != 0)
447 /* Add header to database. */
448 if (rpmtsOpenDB(ts, (O_RDWR|O_CREAT)))
450 if (rpmdbAdd(rpmtsGetRdb(ts), h) != 0)
458 rpmPubkeyFree(pubkey);
459 rpmKeyringFree(keyring);
463 int rpmtsSetSolveCallback(rpmts ts,
464 int (*solve) (rpmts ts, rpmds key, const void * data),
465 const void * solveData)
471 ts->solveData = solveData;
476 int rpmtsSolve(rpmts ts, rpmds key)
478 int rc = 1; /* assume not found */
479 if (ts && ts->solve) {
480 rc = (*ts->solve)(ts, key, ts->solveData);
485 rpmps rpmtsProblems(rpmts ts)
487 rpmps ps = rpmpsCreate();
488 rpmtsi pi = rpmtsiInit(ts);
491 while ((p = rpmtsiNext(pi, 0)) != NULL) {
492 rpmps teprobs = rpmteProblems(p);
493 rpmpsMerge(ps, teprobs);
498 /* Return NULL on no problems instead of an empty set */
499 if (rpmpsNumProblems(ps) == 0) {
506 void rpmtsCleanProblems(rpmts ts)
509 rpmtsi pi = rpmtsiInit(ts);
510 while ((p = rpmtsiNext(pi, 0)) != NULL)
511 rpmteCleanProblems(p);
515 void rpmtsClean(rpmts ts)
518 tsMembers tsmem = rpmtsMembers(ts);
523 /* Clean up after dependency checks. */
525 while ((p = rpmtsiNext(pi, 0)) != NULL)
529 tsmem->addedPackages = rpmalFree(tsmem->addedPackages);
531 rpmtsCleanProblems(ts);
534 /* hash comparison function */
535 static int uintCmp(unsigned int a, unsigned int b)
541 static unsigned int uintId(unsigned int a)
546 void rpmtsEmpty(rpmts ts)
548 tsMembers tsmem = rpmtsMembers(ts);
554 for (int oc = 0; oc < tsmem->orderCount; oc++) {
555 tsmem->order[oc] = rpmteFree(tsmem->order[oc]);
558 tsmem->orderCount = 0;
559 intHashEmpty(tsmem->removedPackages);
563 static void rpmtsPrintStat(const char * name, struct rpmop_s * op)
565 static const unsigned int scale = (1000 * 1000);
566 if (op != NULL && op->count > 0)
567 fprintf(stderr, " %s %6d %6lu.%06lu MB %6lu.%06lu secs\n",
569 (unsigned long)op->bytes/scale, (unsigned long)op->bytes%scale,
570 op->usecs/scale, op->usecs%scale);
573 static void rpmtsPrintStats(rpmts ts)
575 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_TOTAL), 0);
577 rpmtsPrintStat("total: ", rpmtsOp(ts, RPMTS_OP_TOTAL));
578 rpmtsPrintStat("check: ", rpmtsOp(ts, RPMTS_OP_CHECK));
579 rpmtsPrintStat("order: ", rpmtsOp(ts, RPMTS_OP_ORDER));
580 rpmtsPrintStat("fingerprint: ", rpmtsOp(ts, RPMTS_OP_FINGERPRINT));
581 rpmtsPrintStat("install: ", rpmtsOp(ts, RPMTS_OP_INSTALL));
582 rpmtsPrintStat("erase: ", rpmtsOp(ts, RPMTS_OP_ERASE));
583 rpmtsPrintStat("scriptlets: ", rpmtsOp(ts, RPMTS_OP_SCRIPTLETS));
584 rpmtsPrintStat("compress: ", rpmtsOp(ts, RPMTS_OP_COMPRESS));
585 rpmtsPrintStat("uncompress: ", rpmtsOp(ts, RPMTS_OP_UNCOMPRESS));
586 rpmtsPrintStat("digest: ", rpmtsOp(ts, RPMTS_OP_DIGEST));
587 rpmtsPrintStat("signature: ", rpmtsOp(ts, RPMTS_OP_SIGNATURE));
588 rpmtsPrintStat("dbadd: ", rpmtsOp(ts, RPMTS_OP_DBADD));
589 rpmtsPrintStat("dbremove: ", rpmtsOp(ts, RPMTS_OP_DBREMOVE));
590 rpmtsPrintStat("dbget: ", rpmtsOp(ts, RPMTS_OP_DBGET));
591 rpmtsPrintStat("dbput: ", rpmtsOp(ts, RPMTS_OP_DBPUT));
592 rpmtsPrintStat("dbdel: ", rpmtsOp(ts, RPMTS_OP_DBDEL));
595 rpmts rpmtsFree(rpmts ts)
597 tsMembers tsmem = rpmtsMembers(ts);
602 return rpmtsUnlink(ts);
606 (void) rpmtsCloseDB(ts);
608 tsmem->removedPackages = intHashFree(tsmem->removedPackages);
609 tsmem->order = _free(tsmem->order);
610 ts->members = _free(ts->members);
612 ts->dsi = _free(ts->dsi);
614 if (ts->scriptFd != NULL) {
615 ts->scriptFd = fdFree(ts->scriptFd);
618 ts->rootDir = _free(ts->rootDir);
619 ts->lockPath = _free(ts->lockPath);
621 ts->keyring = rpmKeyringFree(ts->keyring);
622 ts->netsharedPaths = argvFree(ts->netsharedPaths);
623 ts->installLangs = argvFree(ts->installLangs);
625 ts->plugins = rpmpluginsFree(ts->plugins);
630 (void) rpmtsUnlink(ts);
637 rpmVSFlags rpmtsVSFlags(rpmts ts)
639 rpmVSFlags vsflags = 0;
641 vsflags = ts->vsflags;
645 rpmVSFlags rpmtsSetVSFlags(rpmts ts, rpmVSFlags vsflags)
647 rpmVSFlags ovsflags = 0;
649 ovsflags = ts->vsflags;
650 ts->vsflags = vsflags;
655 const char * rpmtsRootDir(rpmts ts)
657 return ts ? ts->rootDir : NULL;
660 int rpmtsSetRootDir(rpmts ts, const char * rootDir)
662 if (ts == NULL || (rootDir && rootDir[0] != '/')) {
666 ts->rootDir = _free(ts->rootDir);
667 /* Ensure clean path with a trailing slash */
668 ts->rootDir = rootDir ? rpmGetPath(rootDir, NULL) : xstrdup("/");
669 if (!rstreq(ts->rootDir, "/")) {
670 rstrcat(&ts->rootDir, "/");
675 FD_t rpmtsScriptFd(rpmts ts)
677 FD_t scriptFd = NULL;
679 scriptFd = ts->scriptFd;
684 void rpmtsSetScriptFd(rpmts ts, FD_t scriptFd)
688 if (ts->scriptFd != NULL) {
689 ts->scriptFd = fdFree(ts->scriptFd);
692 if (scriptFd != NULL)
693 ts->scriptFd = fdLink(scriptFd);
697 struct selabel_handle * rpmtsSELabelHandle(rpmts ts)
701 return ts->selabelHandle;
707 rpmRC rpmtsSELabelInit(rpmts ts, const char *path)
710 if (ts == NULL || path == NULL) {
714 struct selinux_opt opts[] = {
715 {SELABEL_OPT_PATH, path}
718 if (ts->selabelHandle) {
719 rpmtsSELabelFini(ts);
721 ts->selabelHandle = selabel_open(SELABEL_CTX_FILE, opts, 1);
723 if (!ts->selabelHandle) {
730 void rpmtsSELabelFini(rpmts ts)
733 if (ts && ts->selabelHandle) {
734 selabel_close(ts->selabelHandle);
735 ts->selabelHandle = NULL;
740 rpm_tid_t rpmtsGetTid(rpmts ts)
742 rpm_tid_t tid = (rpm_tid_t)-1; /* XXX -1 is time(2) error return. */
749 rpm_tid_t rpmtsSetTid(rpmts ts, rpm_tid_t tid)
751 rpm_tid_t otid = (rpm_tid_t)-1; /* XXX -1 is time(2) error return. */
759 rpmdb rpmtsGetRdb(rpmts ts)
768 void * rpmtsNotify(rpmts ts, rpmte te,
769 rpmCallbackType what, rpm_loff_t amount, rpm_loff_t total)
772 if (ts && ts->notify) {
774 fnpyKey cbkey = NULL;
777 cbkey = rpmteKey(te);
779 ptr = ts->notify(h, what, amount, total, cbkey, ts->notifyData);
782 headerFree(h); /* undo rpmteHeader() ref */
788 int rpmtsNElements(rpmts ts)
791 tsMembers tsmem = rpmtsMembers(ts);
792 if (tsmem != NULL && tsmem->order != NULL) {
793 nelements = tsmem->orderCount;
798 rpmte rpmtsElement(rpmts ts, int ix)
801 tsMembers tsmem = rpmtsMembers(ts);
802 if (tsmem != NULL && tsmem->order != NULL) {
803 if (ix >= 0 && ix < tsmem->orderCount)
804 te = tsmem->order[ix];
809 rpmprobFilterFlags rpmtsFilterFlags(rpmts ts)
811 return (ts != NULL ? ts->ignoreSet : 0);
814 rpmtransFlags rpmtsFlags(rpmts ts)
816 return (ts != NULL ? ts->transFlags : 0);
819 rpmtransFlags rpmtsSetFlags(rpmts ts, rpmtransFlags transFlags)
821 rpmtransFlags otransFlags = 0;
823 otransFlags = ts->transFlags;
824 ts->transFlags = transFlags;
829 rpm_color_t rpmtsColor(rpmts ts)
831 return (ts != NULL ? ts->color : 0);
834 rpm_color_t rpmtsSetColor(rpmts ts, rpm_color_t color)
836 rpm_color_t ocolor = 0;
844 rpm_color_t rpmtsPrefColor(rpmts ts)
846 return (ts != NULL ? ts->prefcolor : 0);
849 rpm_color_t rpmtsSetPrefColor(rpmts ts, rpm_color_t color)
851 rpm_color_t ocolor = 0;
853 ocolor = ts->prefcolor;
854 ts->prefcolor = color;
859 rpmop rpmtsOp(rpmts ts, rpmtsOpX opx)
863 if (ts != NULL && opx >= 0 && opx < RPMTS_OP_MAX)
868 rpmPlugins rpmtsPlugins(rpmts ts)
870 return (ts != NULL ? ts->plugins : NULL);
873 int rpmtsSetNotifyCallback(rpmts ts,
874 rpmCallbackFunction notify, rpmCallbackData notifyData)
878 ts->notifyData = notifyData;
883 tsMembers rpmtsMembers(rpmts ts)
885 return (ts != NULL) ? ts->members : NULL;
888 rpmts rpmtsCreate(void)
893 ts = xcalloc(1, sizeof(*ts));
894 memset(&ts->ops, 0, sizeof(ts->ops));
895 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_TOTAL), -1);
899 ts->solveData = NULL;
902 ts->dbmode = O_RDONLY;
905 ts->tid = (rpm_tid_t) time(NULL);
907 ts->color = rpmExpandNumeric("%{?_transaction_color}");
908 ts->prefcolor = rpmExpandNumeric("%{?_prefer_color}")?:2;
910 ts->netsharedPaths = NULL;
911 ts->installLangs = NULL;
912 { char *tmp = rpmExpand("%{_netsharedpath}", NULL);
913 if (tmp && *tmp != '%') {
914 argvSplit(&ts->netsharedPaths, tmp, ":");
918 tmp = rpmExpand("%{_install_langs}", NULL);
919 if (tmp && *tmp != '%') {
921 argvSplit(&langs, tmp, ":");
922 /* If we'll be installing all languages anyway, don't bother */
923 for (ARGV_t l = langs; *l; l++) {
924 if (rstreq(*l, "all")) {
925 langs = argvFree(langs);
929 ts->installLangs = langs;
934 tsmem = xcalloc(1, sizeof(*ts->members));
936 tsmem->addedPackages = NULL;
937 tsmem->removedPackages = intHashCreate(128, uintId, uintCmp, NULL);
938 tsmem->orderAlloced = 0;
939 tsmem->orderCount = 0;
946 ts->selabelHandle = NULL;
950 ts->plugins = rpmpluginsNew(ts);
952 return rpmtsLink(ts);
955 rpmtsi rpmtsiFree(rpmtsi tsi)
957 /* XXX watchout: a funky recursion segfaults here iff nrefs is wrong. */
959 tsi->ts = rpmtsFree(tsi->ts);
965 rpmtsi rpmtsiInit(rpmts ts)
969 tsi = xcalloc(1, sizeof(*tsi));
970 tsi->ts = rpmtsLink(ts);
976 * Return next transaction element.
977 * @param tsi transaction element iterator
978 * @return transaction element, NULL on termination
981 rpmte rpmtsiNextElement(rpmtsi tsi)
986 if (tsi == NULL || tsi->ts == NULL || rpmtsNElements(tsi->ts) <= 0)
989 if (tsi->oc < rpmtsNElements(tsi->ts)) oc = tsi->oc++;
991 te = rpmtsElement(tsi->ts, oc);
995 rpmte rpmtsiNext(rpmtsi tsi, rpmElementTypes types)
999 while ((te = rpmtsiNextElement(tsi)) != NULL) {
1000 if (types == 0 || (rpmteType(te) & types) != 0)
1006 #define RPMLOCK_PATH LOCALSTATEDIR "/rpm/.rpm.lock"
1007 rpmlock rpmtsAcquireLock(rpmts ts)
1009 static const char * const rpmlock_path_default = "%{?_rpmlock_path}";
1011 if (ts->lockPath == NULL) {
1012 const char *rootDir = rpmtsRootDir(ts);
1015 if (!rootDir || rpmChrootDone())
1018 t = rpmGenPath(rootDir, rpmlock_path_default, NULL);
1019 if (t == NULL || *t == '\0' || *t == '%') {
1021 t = xstrdup(RPMLOCK_PATH);
1023 ts->lockPath = xstrdup(t);
1024 (void) rpmioMkpath(dirname(t), 0755, getuid(), getgid());
1027 return rpmlockAcquire(ts->lockPath, _("transaction"));