00001
00005 #include "system.h"
00006
00007 #include "rpmio_internal.h"
00008 #include <rpmlib.h>
00009 #include <rpmmacro.h>
00010
00011 #define _RPMDB_INTERNAL
00012 #include "rpmdb.h"
00013
00014 #include "rpmal.h"
00015 #include "rpmds.h"
00016 #include "rpmfi.h"
00017 #include "rpmlock.h"
00018 #include "rpmns.h"
00019
00020 #define _RPMTE_INTERNAL
00021 #include "rpmte.h"
00022
00023 #define _RPMTS_INTERNAL
00024 #include "rpmts.h"
00025
00026 #include "fs.h"
00027
00028
00029
00030 #if STATFS_IN_SYS_STATVFS
00031
00032 #if defined(__LCLINT__)
00033
00034 extern int statvfs (const char * file, struct statvfs * buf)
00035
00036 ;
00037
00038
00039 #else
00040 # include <sys/statvfs.h>
00041 #endif
00042 #else
00043 # if STATFS_IN_SYS_VFS
00044 # include <sys/vfs.h>
00045 # else
00046 # if STATFS_IN_SYS_MOUNT
00047 # include <sys/mount.h>
00048 # else
00049 # if STATFS_IN_SYS_STATFS
00050 # include <sys/statfs.h>
00051 # endif
00052 # endif
00053 # endif
00054 #endif
00055
00056 #include "debug.h"
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 int _rpmts_debug = 0;
00071
00072
00073 int _rpmts_stats = 0;
00074
00075 rpmts XrpmtsUnlink(rpmts ts, const char * msg, const char * fn, unsigned ln)
00076 {
00077
00078 if (_rpmts_debug)
00079 fprintf(stderr, "--> ts %p -- %d %s at %s:%u\n", ts, ts->nrefs, msg, fn, ln);
00080
00081 ts->nrefs--;
00082 return NULL;
00083 }
00084
00085 rpmts XrpmtsLink(rpmts ts, const char * msg, const char * fn, unsigned ln)
00086 {
00087 ts->nrefs++;
00088
00089 if (_rpmts_debug)
00090 fprintf(stderr, "--> ts %p ++ %d %s at %s:%u\n", ts, ts->nrefs, msg, fn, ln);
00091
00092 return ts;
00093 }
00094
00095 int rpmtsCloseDB(rpmts ts)
00096 {
00097 int rc = 0;
00098
00099 if (ts->rdb != NULL) {
00100 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBGET), &ts->rdb->db_getops);
00101 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBPUT), &ts->rdb->db_putops);
00102 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBDEL), &ts->rdb->db_delops);
00103 rc = rpmdbClose(ts->rdb);
00104 ts->rdb = NULL;
00105 }
00106 return rc;
00107 }
00108
00109 int rpmtsOpenDB(rpmts ts, int dbmode)
00110 {
00111 int rc = 0;
00112
00113 if (ts->rdb != NULL && ts->dbmode == dbmode)
00114 return 0;
00115
00116 (void) rpmtsCloseDB(ts);
00117
00118
00119
00120 ts->dbmode = dbmode;
00121 rc = rpmdbOpen(ts->rootDir, &ts->rdb, ts->dbmode, 0644);
00122 if (rc) {
00123 const char * dn;
00124 dn = rpmGetPath(ts->rootDir, "%{_dbpath}", NULL);
00125 rpmMessage(RPMMESS_ERROR,
00126 _("cannot open Packages database in %s\n"), dn);
00127 dn = _free(dn);
00128 }
00129 return rc;
00130 }
00131
00132 int rpmtsInitDB(rpmts ts, int dbmode)
00133 {
00134 void *lock = rpmtsAcquireLock(ts);
00135 int rc = rpmdbInit(ts->rootDir, dbmode);
00136 lock = rpmtsFreeLock(lock);
00137 return rc;
00138 }
00139
00140 int rpmtsRebuildDB(rpmts ts)
00141 {
00142 void *lock = rpmtsAcquireLock(ts);
00143 int rc;
00144 if (!(ts->vsflags & RPMVSF_NOHDRCHK))
00145 rc = rpmdbRebuild(ts->rootDir, ts, headerCheck);
00146 else
00147 rc = rpmdbRebuild(ts->rootDir, NULL, NULL);
00148 lock = rpmtsFreeLock(lock);
00149 return rc;
00150 }
00151
00152 int rpmtsVerifyDB(rpmts ts)
00153 {
00154 return rpmdbVerify(ts->rootDir);
00155 }
00156
00157
00158 rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag,
00159 const void * keyp, size_t keylen)
00160 {
00161 rpmdbMatchIterator mi;
00162 const char * arch = NULL;
00163 int xx;
00164
00165 if (ts->rdb == NULL && rpmtsOpenDB(ts, ts->dbmode))
00166 return NULL;
00167
00168
00169
00170 if (rpmtag == RPMDBI_LABEL && keyp != NULL) {
00171 const char * s = keyp;
00172 const char *se;
00173 size_t slen = strlen(s);
00174 char *t = alloca(slen+1);
00175 int level = 0;
00176 int c;
00177
00178 keyp = t;
00179 while ((c = *s++) != '\0') {
00180 switch (c) {
00181 default:
00182 *t++ = c;
00183 break;
00184 case '(':
00185
00186 if (level++ != 0) {
00187 rpmError(RPMERR_QFMT, _("extra '(' in package label: %s\n"), keyp);
00188 return NULL;
00189 }
00190
00191 for (se = s; *se && xisdigit(*se); se++)
00192 {};
00193 if (*se == ':') {
00194
00195 *t++ = '-';
00196 s = se + 1;
00197 } else {
00198
00199 *t++ = '-';
00200 }
00201 break;
00202 case ')':
00203
00204 if (--level != 0) {
00205 rpmError(RPMERR_QFMT, _("missing '(' in package label: %s\n"), keyp);
00206 return NULL;
00207 }
00208
00209 break;
00210 }
00211 }
00212 if (level) {
00213 rpmError(RPMERR_QFMT, _("missing ')' in package label: %s\n"), keyp);
00214 return NULL;
00215 }
00216 *t = '\0';
00217 t = (char *) keyp;
00218 t = strrchr(t, '.');
00219
00220 if (t != NULL && rpmnsArch(t+1)) {
00221 *t++ = '\0';
00222 arch = t;
00223 }
00224 }
00225
00226
00227 mi = rpmdbInitIterator(ts->rdb, rpmtag, keyp, keylen);
00228
00229
00230 if (mi && !(ts->vsflags & RPMVSF_NOHDRCHK))
00231 (void) rpmdbSetHdrChk(mi, ts, headerCheck);
00232
00233
00234 if (arch != NULL)
00235 xx = rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_DEFAULT, arch);
00236 return mi;
00237 }
00238
00239
00240 rpmRC rpmtsFindPubkey(rpmts ts)
00241 {
00242 const void * sig = rpmtsSig(ts);
00243 pgpDig dig = rpmtsDig(ts);
00244 pgpDigParams sigp = rpmtsSignature(ts);
00245 pgpDigParams pubp = rpmtsPubkey(ts);
00246 rpmRC res = RPMRC_NOKEY;
00247 const char * pubkeysource = NULL;
00248 int xx;
00249
00250 if (sig == NULL || dig == NULL || sigp == NULL || pubp == NULL)
00251 goto exit;
00252
00253 #if 0
00254 fprintf(stderr, "==> find sig id %08x %08x ts pubkey id %08x %08x\n",
00255 pgpGrab(sigp->signid, 4), pgpGrab(sigp->signid+4, 4),
00256 pgpGrab(ts->pksignid, 4), pgpGrab(ts->pksignid+4, 4));
00257 #endif
00258
00259
00260 if (memcmp(sigp->signid, ts->pksignid, sizeof(ts->pksignid))) {
00261 #if 0
00262 fprintf(stderr, "*** free pkt %p[%d] id %08x %08x\n", ts->pkpkt, ts->pkpktlen, pgpGrab(ts->pksignid, 4), pgpGrab(ts->pksignid+4, 4));
00263 #endif
00264 ts->pkpkt = _free(ts->pkpkt);
00265 ts->pkpktlen = 0;
00266 memset(ts->pksignid, 0, sizeof(ts->pksignid));
00267 }
00268
00269
00270 if (ts->pkpkt == NULL) {
00271 int hx = -1;
00272 int ix = -1;
00273 rpmdbMatchIterator mi;
00274 Header h;
00275
00276
00277 mi = rpmtsInitIterator(ts, RPMTAG_PUBKEYS, sigp->signid, sizeof(sigp->signid));
00278 while ((h = rpmdbNextIterator(mi)) != NULL) {
00279 const char ** pubkeys;
00280 int_32 pt, pc;
00281
00282 if (!headerGetEntry(h, RPMTAG_PUBKEYS, &pt, (void **)&pubkeys, &pc))
00283 continue;
00284 hx = rpmdbGetIteratorOffset(mi);
00285 ix = rpmdbGetIteratorFileNum(mi);
00286
00287 if (ix >= pc
00288 || b64decode(pubkeys[ix], (void **) &ts->pkpkt, &ts->pkpktlen))
00289 ix = -1;
00290
00291 pubkeys = headerFreeData(pubkeys, pt);
00292 break;
00293 }
00294 mi = rpmdbFreeIterator(mi);
00295
00296
00297 if (ix >= 0) {
00298 char hnum[32];
00299 sprintf(hnum, "h#%d", hx);
00300 pubkeysource = xstrdup(hnum);
00301 } else {
00302 ts->pkpkt = _free(ts->pkpkt);
00303 ts->pkpktlen = 0;
00304 }
00305
00306 }
00307
00308
00309 if (ts->pkpkt == NULL) {
00310 const char * fn = rpmExpand("%{_hkp_keyserver_query}",
00311 pgpHexStr(sigp->signid, sizeof(sigp->signid)), NULL);
00312
00313 xx = 0;
00314 if (fn && *fn != '%') {
00315 xx = (pgpReadPkts(fn,&ts->pkpkt,&ts->pkpktlen) != PGPARMOR_PUBKEY);
00316 }
00317 fn = _free(fn);
00318
00319 if (xx) {
00320 ts->pkpkt = _free(ts->pkpkt);
00321 ts->pkpktlen = 0;
00322 } else {
00323
00324 pubkeysource = xstrdup("keyserver");
00325 }
00326
00327 }
00328
00329 #ifdef NOTNOW
00330
00331 if (ts->pkpkt == NULL) {
00332 const char * fn = rpmExpand("%{_gpg_pubkey}", NULL);
00333
00334 xx = 0;
00335 if (fn && *fn != '%')
00336 xx = (pgpReadPkts(fn,&ts->pkpkt,&ts->pkpktlen) != PGPARMOR_PUBKEY);
00337 fn = _free(fn);
00338 if (xx) {
00339 ts->pkpkt = _free(ts->pkpkt);
00340 ts->pkpktlen = 0;
00341 } else {
00342 pubkeysource = xstrdup("macro");
00343 }
00344 }
00345 #endif
00346
00347
00348 if (ts->pkpkt == NULL || ts->pkpktlen == 0)
00349 goto exit;
00350
00351
00352 xx = pgpPrtPkts(ts->pkpkt, ts->pkpktlen, dig, 0);
00353
00354
00355 if (sigp->pubkey_algo == pubp->pubkey_algo
00356 #ifdef NOTYET
00357 && sigp->hash_algo == pubp->hash_algo
00358 #endif
00359 && !memcmp(sigp->signid, pubp->signid, sizeof(sigp->signid)) )
00360 {
00361
00362
00363
00364
00365
00366 memcpy(ts->pksignid, pubp->signid, sizeof(ts->pksignid));
00367
00368
00369 if (pubkeysource)
00370 rpmMessage(RPMMESS_DEBUG, "========== %s pubkey id %08x %08x (%s)\n",
00371 (sigp->pubkey_algo == PGPPUBKEYALGO_DSA ? "DSA" :
00372 (sigp->pubkey_algo == PGPPUBKEYALGO_RSA ? "RSA" : "???")),
00373 pgpGrab(sigp->signid, 4), pgpGrab(sigp->signid+4, 4),
00374 pubkeysource);
00375
00376 res = RPMRC_OK;
00377 }
00378
00379 exit:
00380 pubkeysource = _free(pubkeysource);
00381 if (res != RPMRC_OK) {
00382 ts->pkpkt = _free(ts->pkpkt);
00383 ts->pkpktlen = 0;
00384 }
00385 return res;
00386 }
00387
00388 int rpmtsCloseSDB(rpmts ts)
00389 {
00390 int rc = 0;
00391
00392 if (ts->sdb != NULL) {
00393 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBGET), &ts->sdb->db_getops);
00394 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBPUT), &ts->sdb->db_putops);
00395 (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DBDEL), &ts->sdb->db_delops);
00396 rc = rpmdbClose(ts->sdb);
00397 ts->sdb = NULL;
00398 }
00399 return rc;
00400 }
00401
00402 int rpmtsOpenSDB(rpmts ts, int dbmode)
00403 {
00404 static int has_sdbpath = -1;
00405 int rc = 0;
00406
00407 if (ts->sdb != NULL && ts->sdbmode == dbmode)
00408 return 0;
00409
00410 if (has_sdbpath < 0)
00411 has_sdbpath = rpmExpandNumeric("%{?_solve_dbpath:1}");
00412
00413
00414 if (has_sdbpath <= 0)
00415 return 1;
00416
00417 addMacro(NULL, "_dbpath", NULL, "%{_solve_dbpath}", RMIL_DEFAULT);
00418
00419 rc = rpmdbOpen(ts->rootDir, &ts->sdb, ts->sdbmode, 0644);
00420 if (rc) {
00421 const char * dn;
00422 dn = rpmGetPath(ts->rootDir, "%{_dbpath}", NULL);
00423 rpmMessage(RPMMESS_WARNING,
00424 _("cannot open Solve database in %s\n"), dn);
00425 dn = _free(dn);
00426
00427 has_sdbpath = 0;
00428 }
00429 delMacro(NULL, "_dbpath");
00430
00431 return rc;
00432 }
00433
00440 static int sugcmp(const void * a, const void * b)
00441
00442 {
00443
00444 const char * astr = *(const char **)a;
00445 const char * bstr = *(const char **)b;
00446
00447 return strcmp(astr, bstr);
00448 }
00449
00450
00451 int rpmtsSolve(rpmts ts, rpmds ds, const void * data)
00452 {
00453 const char * errstr;
00454 const char * str = NULL;
00455 const char * qfmt;
00456 rpmdbMatchIterator mi;
00457 Header bh = NULL;
00458 Header h = NULL;
00459 size_t bhnamelen = 0;
00460 time_t bhtime = 0;
00461 rpmTag rpmtag;
00462 const char * keyp;
00463 size_t keylen = 0;
00464 int rc = 1;
00465 int xx;
00466
00467
00468 if (ts->goal != TSM_INSTALL)
00469 return rc;
00470
00471 switch (rpmdsTagN(ds)) {
00472 case RPMTAG_CONFLICTNAME:
00473 default:
00474 return rc;
00475 break;
00476 case RPMTAG_DIRNAMES:
00477 case RPMTAG_REQUIRENAME:
00478 case RPMTAG_FILELINKTOS:
00479 break;
00480 }
00481
00482 keyp = rpmdsN(ds);
00483 if (keyp == NULL)
00484 return rc;
00485
00486 if (ts->sdb == NULL) {
00487 xx = rpmtsOpenSDB(ts, ts->sdbmode);
00488 if (xx) return rc;
00489 }
00490
00491
00492 rpmtag = (*keyp == '/' ? RPMTAG_BASENAMES : RPMTAG_PROVIDENAME);
00493 mi = rpmdbInitIterator(ts->sdb, rpmtag, keyp, keylen);
00494 while ((h = rpmdbNextIterator(mi)) != NULL) {
00495 const char * hname;
00496 size_t hnamelen;
00497 time_t htime;
00498 int_32 * ip;
00499
00500 if (rpmtag == RPMTAG_PROVIDENAME && !rpmdsAnyMatchesDep(h, ds, 1))
00501 continue;
00502
00503 hname = NULL;
00504 hnamelen = 0;
00505 if (headerGetEntry(h, RPMTAG_NAME, NULL, (void **)&hname, NULL)) {
00506 if (hname)
00507 hnamelen = strlen(hname);
00508 }
00509
00510
00511 if (bhnamelen > 0)
00512 if (hnamelen > bhnamelen)
00513 continue;
00514
00515
00516 htime = 0;
00517 if (headerGetEntry(h, RPMTAG_BUILDTIME, NULL, (void **)&ip, NULL))
00518 htime = (time_t)*ip;
00519
00520 if (htime <= bhtime)
00521 continue;
00522
00523
00524 bh = headerFree(bh);
00525 bh = headerLink(h);
00526 bhtime = htime;
00527 bhnamelen = hnamelen;
00528 }
00529 mi = rpmdbFreeIterator(mi);
00530
00531
00532 if (bh == NULL)
00533 goto exit;
00534
00535
00536 qfmt = rpmExpand("%{?_solve_name_fmt}", NULL);
00537 if (qfmt == NULL || *qfmt == '\0')
00538 goto exit;
00539 str = headerSprintf(bh, qfmt, rpmTagTable, rpmHeaderFormats, &errstr);
00540 bh = headerFree(bh);
00541 qfmt = _free(qfmt);
00542 if (str == NULL) {
00543 rpmError(RPMERR_QFMT, _("incorrect solve path format: %s\n"), errstr);
00544 goto exit;
00545 }
00546
00547 if (ts->depFlags & RPMDEPS_FLAG_ADDINDEPS) {
00548 FD_t fd;
00549 rpmRC rpmrc;
00550
00551 fd = Fopen(str, "r");
00552 if (fd == NULL || Ferror(fd)) {
00553 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), str,
00554 Fstrerror(fd));
00555 if (fd != NULL) {
00556 xx = Fclose(fd);
00557 fd = NULL;
00558 }
00559 str = _free(str);
00560 goto exit;
00561 }
00562 rpmrc = rpmReadPackageFile(ts, fd, str, &h);
00563 xx = Fclose(fd);
00564 switch (rpmrc) {
00565 default:
00566 break;
00567 case RPMRC_NOTTRUSTED:
00568 case RPMRC_NOKEY:
00569 case RPMRC_OK:
00570 if (h != NULL &&
00571 !rpmtsAddInstallElement(ts, h, (fnpyKey)str, 1, NULL))
00572 {
00573 rpmMessage(RPMMESS_DEBUG, _("Adding: %s\n"), str);
00574 rc = -1;
00575 break;
00576 }
00577 break;
00578 }
00579 str = _free(str);
00580 h = headerFree(h);
00581 goto exit;
00582 }
00583
00584 rpmMessage(RPMMESS_DEBUG, _("Suggesting: %s\n"), str);
00585
00586 if (ts->suggests != NULL && ts->nsuggests > 0) {
00587 if (bsearch(&str, ts->suggests, ts->nsuggests,
00588 sizeof(*ts->suggests), sugcmp))
00589 {
00590 str = _free(str);
00591 goto exit;
00592 }
00593 }
00594
00595
00596 ts->suggests = xrealloc(ts->suggests,
00597 sizeof(*ts->suggests) * (ts->nsuggests + 2));
00598 ts->suggests[ts->nsuggests] = str;
00599 ts->nsuggests++;
00600 ts->suggests[ts->nsuggests] = NULL;
00601
00602 if (ts->nsuggests > 1)
00603 qsort(ts->suggests, ts->nsuggests, sizeof(*ts->suggests), sugcmp);
00604
00605 exit:
00606
00607 return rc;
00608
00609 }
00610
00611
00612 int rpmtsAvailable(rpmts ts, const rpmds ds)
00613 {
00614 fnpyKey * sugkey;
00615 int rc = 1;
00616
00617 if (ts->availablePackages == NULL)
00618 return rc;
00619 sugkey = rpmalAllSatisfiesDepend(ts->availablePackages, ds, NULL);
00620 if (sugkey == NULL)
00621 return rc;
00622
00623
00624 if (sugkey[0] != NULL) {
00625 ts->suggests = xrealloc(ts->suggests,
00626 sizeof(*ts->suggests) * (ts->nsuggests + 2));
00627 ts->suggests[ts->nsuggests] = sugkey[0];
00628 sugkey[0] = NULL;
00629 ts->nsuggests++;
00630 ts->suggests[ts->nsuggests] = NULL;
00631 }
00632 sugkey = _free(sugkey);
00633
00634 return rc;
00635
00636 }
00637
00638 int rpmtsSetSolveCallback(rpmts ts,
00639 int (*solve) (rpmts ts, rpmds key, const void * data),
00640 const void * solveData)
00641 {
00642 int rc = 0;
00643
00644
00645 if (ts) {
00646
00647 ts->solve = solve;
00648 ts->solveData = solveData;
00649
00650 }
00651
00652 return rc;
00653 }
00654
00655 rpmps rpmtsProblems(rpmts ts)
00656 {
00657 rpmps ps = NULL;
00658 if (ts) {
00659 if (ts->probs)
00660 ps = rpmpsLink(ts->probs, __FUNCTION__);
00661 }
00662 return ps;
00663 }
00664
00665 void rpmtsCleanDig(rpmts ts)
00666 {
00667 ts->sig = headerFreeData(ts->sig, ts->sigtype);
00668 ts->dig = pgpFreeDig(ts->dig);
00669 }
00670
00671 void rpmtsClean(rpmts ts)
00672 {
00673 rpmtsi pi; rpmte p;
00674
00675 if (ts == NULL)
00676 return;
00677
00678
00679 pi = rpmtsiInit(ts);
00680 while ((p = rpmtsiNext(pi, 0)) != NULL)
00681 rpmteCleanDS(p);
00682 pi = rpmtsiFree(pi);
00683
00684 ts->addedPackages = rpmalFree(ts->addedPackages);
00685 ts->numAddedPackages = 0;
00686
00687 ts->erasedPackages = rpmalFree(ts->erasedPackages);
00688 ts->numErasedPackages = 0;
00689
00690 ts->suggests = _free(ts->suggests);
00691 ts->nsuggests = 0;
00692
00693 ts->probs = rpmpsFree(ts->probs);
00694
00695 rpmtsCleanDig(ts);
00696 }
00697
00698 void rpmtsEmpty(rpmts ts)
00699 {
00700 rpmtsi pi; rpmte p;
00701 int oc;
00702
00703 if (ts == NULL)
00704 return;
00705
00706
00707 rpmtsClean(ts);
00708
00709
00710 for (pi = rpmtsiInit(ts), oc = 0; (p = rpmtsiNext(pi, 0)) != NULL; oc++) {
00711
00712 ts->order[oc] = rpmteFree(ts->order[oc]);
00713
00714 }
00715 pi = rpmtsiFree(pi);
00716
00717 ts->orderCount = 0;
00718 ts->ntrees = 0;
00719 ts->maxDepth = 0;
00720
00721 ts->numRemovedPackages = 0;
00722
00723 return;
00724
00725 }
00726
00727 static void rpmtsPrintStat(const char * name, struct rpmop_s * op)
00728
00729
00730 {
00731 static unsigned int scale = (1000 * 1000);
00732 if (op != NULL && op->count > 0)
00733 fprintf(stderr, " %s %8d %6lu.%06lu MB %6lu.%06lu secs\n",
00734 name, op->count,
00735 (unsigned long)op->bytes/scale, (unsigned long)op->bytes%scale,
00736 op->usecs/scale, op->usecs%scale);
00737 }
00738
00739 static void rpmtsPrintStats(rpmts ts)
00740
00741
00742 {
00743 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_TOTAL), 0);
00744
00745 rpmtsPrintStat("total: ", rpmtsOp(ts, RPMTS_OP_TOTAL));
00746 rpmtsPrintStat("check: ", rpmtsOp(ts, RPMTS_OP_CHECK));
00747 rpmtsPrintStat("order: ", rpmtsOp(ts, RPMTS_OP_ORDER));
00748 rpmtsPrintStat("fingerprint: ", rpmtsOp(ts, RPMTS_OP_FINGERPRINT));
00749 rpmtsPrintStat("repackage: ", rpmtsOp(ts, RPMTS_OP_REPACKAGE));
00750 rpmtsPrintStat("install: ", rpmtsOp(ts, RPMTS_OP_INSTALL));
00751 rpmtsPrintStat("erase: ", rpmtsOp(ts, RPMTS_OP_ERASE));
00752 rpmtsPrintStat("scriptlets: ", rpmtsOp(ts, RPMTS_OP_SCRIPTLETS));
00753 rpmtsPrintStat("compress: ", rpmtsOp(ts, RPMTS_OP_COMPRESS));
00754 rpmtsPrintStat("uncompress: ", rpmtsOp(ts, RPMTS_OP_UNCOMPRESS));
00755 rpmtsPrintStat("digest: ", rpmtsOp(ts, RPMTS_OP_DIGEST));
00756 rpmtsPrintStat("signature: ", rpmtsOp(ts, RPMTS_OP_SIGNATURE));
00757 rpmtsPrintStat("dbadd: ", rpmtsOp(ts, RPMTS_OP_DBADD));
00758 rpmtsPrintStat("dbremove: ", rpmtsOp(ts, RPMTS_OP_DBREMOVE));
00759 rpmtsPrintStat("dbget: ", rpmtsOp(ts, RPMTS_OP_DBGET));
00760 rpmtsPrintStat("dbput: ", rpmtsOp(ts, RPMTS_OP_DBPUT));
00761 rpmtsPrintStat("dbdel: ", rpmtsOp(ts, RPMTS_OP_DBDEL));
00762 rpmtsPrintStat("readhdr: ", rpmtsOp(ts, RPMTS_OP_READHDR));
00763 }
00764
00765 rpmts rpmtsFree(rpmts ts)
00766 {
00767 if (ts == NULL)
00768 return NULL;
00769
00770 if (ts->nrefs > 1)
00771 return rpmtsUnlink(ts, "tsCreate");
00772
00773
00774 rpmtsEmpty(ts);
00775
00776
00777 ts->PRCO = rpmdsFreePRCO(ts->PRCO);
00778
00779 (void) rpmtsCloseDB(ts);
00780
00781 (void) rpmtsCloseSDB(ts);
00782
00783 ts->sx = rpmsxFree(ts->sx);
00784
00785 ts->removedPackages = _free(ts->removedPackages);
00786
00787 ts->availablePackages = rpmalFree(ts->availablePackages);
00788 ts->numAvailablePackages = 0;
00789
00790 ts->dsi = _free(ts->dsi);
00791
00792 if (ts->scriptFd != NULL) {
00793 ts->scriptFd = fdFree(ts->scriptFd, "rpmtsFree");
00794 ts->scriptFd = NULL;
00795 }
00796 ts->rootDir = _free(ts->rootDir);
00797 ts->currDir = _free(ts->currDir);
00798
00799
00800 ts->order = _free(ts->order);
00801
00802 ts->orderAlloced = 0;
00803
00804 if (ts->pkpkt != NULL)
00805 ts->pkpkt = _free(ts->pkpkt);
00806 ts->pkpktlen = 0;
00807 memset(ts->pksignid, 0, sizeof(ts->pksignid));
00808
00809 if (_rpmts_stats)
00810 rpmtsPrintStats(ts);
00811
00812 (void) rpmtsUnlink(ts, "tsCreate");
00813
00814
00815 ts = _free(ts);
00816
00817
00818 return NULL;
00819 }
00820
00821 rpmVSFlags rpmtsVSFlags(rpmts ts)
00822 {
00823 rpmVSFlags vsflags = 0;
00824 if (ts != NULL)
00825 vsflags = ts->vsflags;
00826 return vsflags;
00827 }
00828
00829 rpmVSFlags rpmtsSetVSFlags(rpmts ts, rpmVSFlags vsflags)
00830 {
00831 rpmVSFlags ovsflags = 0;
00832 if (ts != NULL) {
00833 ovsflags = ts->vsflags;
00834 ts->vsflags = vsflags;
00835 }
00836 return ovsflags;
00837 }
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854 rpmTSType rpmtsType(rpmts ts)
00855 {
00856 return ((ts != NULL) ? ts->type : 0);
00857 }
00858
00859 void rpmtsSetType(rpmts ts, rpmTSType type)
00860 {
00861 if (ts != NULL)
00862 ts->type = type;
00863 }
00864
00865 uint_32 rpmtsARBGoal(rpmts ts)
00866 {
00867 return ((ts != NULL) ? ts->arbgoal : 0);
00868 }
00869
00870 void rpmtsSetARBGoal(rpmts ts, uint_32 goal)
00871 {
00872 if (ts != NULL)
00873 ts->arbgoal = goal;
00874 }
00875
00876 int rpmtsUnorderedSuccessors(rpmts ts, int first)
00877 {
00878 int unorderedSuccessors = 0;
00879 if (ts != NULL) {
00880 unorderedSuccessors = ts->unorderedSuccessors;
00881 if (first >= 0)
00882 ts->unorderedSuccessors = first;
00883 }
00884 return unorderedSuccessors;
00885 }
00886
00887 const char * rpmtsRootDir(rpmts ts)
00888 {
00889 const char * rootDir = NULL;
00890
00891
00892 if (ts != NULL && ts->rootDir != NULL) {
00893 urltype ut = urlPath(ts->rootDir, &rootDir);
00894 switch (ut) {
00895 case URL_IS_UNKNOWN:
00896 case URL_IS_PATH:
00897 break;
00898 case URL_IS_HTTPS:
00899 case URL_IS_HTTP:
00900 case URL_IS_HKP:
00901 case URL_IS_FTP:
00902 case URL_IS_DASH:
00903 default:
00904 rootDir = "/";
00905 break;
00906 }
00907 }
00908
00909 return rootDir;
00910 }
00911
00912 void rpmtsSetRootDir(rpmts ts, const char * rootDir)
00913 {
00914 if (ts != NULL) {
00915 size_t rootLen;
00916
00917 ts->rootDir = _free(ts->rootDir);
00918
00919 if (rootDir == NULL) {
00920 #ifndef DYING
00921 ts->rootDir = xstrdup("");
00922 #endif
00923 return;
00924 }
00925 rootLen = strlen(rootDir);
00926
00927
00928
00929 if (!(rootLen && rootDir[rootLen - 1] == '/')) {
00930 char * t = alloca(rootLen + 2);
00931 *t = '\0';
00932 (void) stpcpy( stpcpy(t, rootDir), "/");
00933 rootDir = t;
00934 }
00935
00936 ts->rootDir = xstrdup(rootDir);
00937 }
00938 }
00939
00940 const char * rpmtsCurrDir(rpmts ts)
00941 {
00942 const char * currDir = NULL;
00943 if (ts != NULL) {
00944 currDir = ts->currDir;
00945 }
00946 return currDir;
00947 }
00948
00949 void rpmtsSetCurrDir(rpmts ts, const char * currDir)
00950 {
00951 if (ts != NULL) {
00952 ts->currDir = _free(ts->currDir);
00953 if (currDir)
00954 ts->currDir = xstrdup(currDir);
00955 }
00956 }
00957
00958 FD_t rpmtsScriptFd(rpmts ts)
00959 {
00960 FD_t scriptFd = NULL;
00961 if (ts != NULL) {
00962 scriptFd = ts->scriptFd;
00963 }
00964
00965 return scriptFd;
00966
00967 }
00968
00969 void rpmtsSetScriptFd(rpmts ts, FD_t scriptFd)
00970 {
00971
00972 if (ts != NULL) {
00973 if (ts->scriptFd != NULL) {
00974 ts->scriptFd = fdFree(ts->scriptFd, "rpmtsSetScriptFd");
00975 ts->scriptFd = NULL;
00976 }
00977
00978 if (scriptFd != NULL)
00979 ts->scriptFd = fdLink((void *)scriptFd, "rpmtsSetScriptFd");
00980
00981 }
00982 }
00983
00984 int rpmtsSELinuxEnabled(rpmts ts)
00985 {
00986 return (ts != NULL ? (ts->selinuxEnabled > 0) : 0);
00987 }
00988
00989 int rpmtsChrootDone(rpmts ts)
00990 {
00991 return (ts != NULL ? ts->chrootDone : 0);
00992 }
00993
00994 int rpmtsSetChrootDone(rpmts ts, int chrootDone)
00995 {
00996 int ochrootDone = 0;
00997 if (ts != NULL) {
00998 ochrootDone = ts->chrootDone;
00999 if (ts->rdb != NULL)
01000 ts->rdb->db_chrootDone = chrootDone;
01001 ts->chrootDone = chrootDone;
01002 }
01003 return ochrootDone;
01004 }
01005
01006 rpmsx rpmtsREContext(rpmts ts)
01007 {
01008 return ( (ts && ts->sx ? rpmsxLink(ts->sx, __func__) : NULL) );
01009 }
01010
01011 int rpmtsSetREContext(rpmts ts, rpmsx sx)
01012 {
01013 int rc = -1;
01014 if (ts != NULL) {
01015 ts->sx = rpmsxFree(ts->sx);
01016 ts->sx = rpmsxLink(sx, __func__);
01017 if (ts->sx != NULL)
01018 rc = 0;
01019 }
01020 return rc;
01021 }
01022
01023 int_32 rpmtsGetTid(rpmts ts)
01024 {
01025 int_32 tid = -1;
01026 if (ts != NULL) {
01027 tid = ts->tid;
01028 }
01029 return tid;
01030 }
01031
01032 int_32 rpmtsSetTid(rpmts ts, int_32 tid)
01033 {
01034 int_32 otid = -1;
01035 if (ts != NULL) {
01036 otid = ts->tid;
01037 ts->tid = tid;
01038 }
01039 return otid;
01040 }
01041
01042 int_32 rpmtsSigtag(const rpmts ts)
01043 {
01044 int_32 sigtag = 0;
01045 if (ts != NULL)
01046 sigtag = ts->sigtag;
01047 return sigtag;
01048 }
01049
01050 int_32 rpmtsSigtype(const rpmts ts)
01051 {
01052 int_32 sigtype = 0;
01053 if (ts != NULL)
01054 sigtype = ts->sigtype;
01055 return sigtype;
01056 }
01057
01058 const void * rpmtsSig(const rpmts ts)
01059 {
01060 const void * sig = NULL;
01061 if (ts != NULL)
01062 sig = ts->sig;
01063 return sig;
01064 }
01065
01066 int_32 rpmtsSiglen(const rpmts ts)
01067 {
01068 int_32 siglen = 0;
01069 if (ts != NULL)
01070 siglen = ts->siglen;
01071 return siglen;
01072 }
01073
01074 int rpmtsSetSig(rpmts ts,
01075 int_32 sigtag, int_32 sigtype, const void * sig, int_32 siglen)
01076 {
01077 if (ts != NULL) {
01078 if (ts->sig && ts->sigtype)
01079 ts->sig = headerFreeData(ts->sig, ts->sigtype);
01080 ts->sigtag = sigtag;
01081 ts->sigtype = (sig ? sigtype : 0);
01082
01083 ts->sig = sig;
01084
01085 ts->siglen = siglen;
01086 }
01087 return 0;
01088 }
01089
01090 pgpDig rpmtsDig(rpmts ts)
01091 {
01092
01093 if (ts->dig == NULL)
01094 ts->dig = pgpNewDig();
01095
01096 if (ts->dig == NULL)
01097 return NULL;
01098 return ts->dig;
01099 }
01100
01101 pgpDigParams rpmtsSignature(const rpmts ts)
01102 {
01103 pgpDig dig = rpmtsDig(ts);
01104 if (dig == NULL) return NULL;
01105
01106 return &dig->signature;
01107
01108 }
01109
01110 pgpDigParams rpmtsPubkey(const rpmts ts)
01111 {
01112 pgpDig dig = rpmtsDig(ts);
01113 if (dig == NULL) return NULL;
01114
01115 return &dig->pubkey;
01116
01117 }
01118
01119 rpmdb rpmtsGetRdb(rpmts ts)
01120 {
01121 rpmdb rdb = NULL;
01122 if (ts != NULL) {
01123 rdb = ts->rdb;
01124 }
01125
01126 return rdb;
01127
01128 }
01129
01130 rpmPRCO rpmtsPRCO(rpmts ts)
01131 {
01132
01133 return (ts != NULL ? ts->PRCO : NULL);
01134
01135 }
01136
01137 int rpmtsInitDSI(const rpmts ts)
01138 {
01139 rpmDiskSpaceInfo dsi;
01140 struct stat sb;
01141 int rc;
01142 int i;
01143
01144 if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_DISKSPACE)
01145 return 0;
01146 if (ts->filesystems != NULL)
01147 return 0;
01148
01149 rpmMessage(RPMMESS_DEBUG, _("mounted filesystems:\n"));
01150 rpmMessage(RPMMESS_DEBUG,
01151 _(" i dev bsize bavail iavail mount point\n"));
01152
01153 rc = rpmGetFilesystemList(&ts->filesystems, &ts->filesystemCount);
01154 if (rc || ts->filesystems == NULL || ts->filesystemCount <= 0)
01155 return rc;
01156
01157
01158
01159 ts->dsi = _free(ts->dsi);
01160 ts->dsi = xcalloc((ts->filesystemCount + 1), sizeof(*ts->dsi));
01161
01162 dsi = ts->dsi;
01163
01164 if (dsi != NULL)
01165 for (i = 0; (i < ts->filesystemCount) && dsi; i++, dsi++) {
01166 #if STATFS_IN_SYS_STATVFS
01167 struct statvfs sfb;
01168 memset(&sfb, 0, sizeof(sfb));
01169 rc = statvfs(ts->filesystems[i], &sfb);
01170 #else
01171 struct statfs sfb;
01172 memset(&sfb, 0, sizeof(sfb));
01173 # if STAT_STATFS4
01174
01175
01176
01177
01178
01179 rc = statfs(ts->filesystems[i], &sfb, sizeof(sfb), 0);
01180 # else
01181 rc = statfs(ts->filesystems[i], &sfb);
01182 # endif
01183 #endif
01184 if (rc)
01185 break;
01186
01187 rc = stat(ts->filesystems[i], &sb);
01188 if (rc)
01189 break;
01190 dsi->dev = sb.st_dev;
01191
01192 #if STATFS_IN_SYS_STATVFS
01193 dsi->f_frsize = sfb.f_frsize;
01194 dsi->f_fsid = sfb.f_fsid;
01195 dsi->f_flag = sfb.f_flag;
01196 dsi->f_favail = sfb.f_favail;
01197 dsi->f_namemax = sfb.f_namemax;
01198 #else
01199 dsi->f_fsid = sfb.f_fsid;
01200 dsi->f_namemax = sfb.f_namelen;
01201 #endif
01202
01203 dsi->f_bsize = sfb.f_bsize;
01204 dsi->f_blocks = sfb.f_blocks;
01205 dsi->f_bfree = sfb.f_bfree;
01206 dsi->f_files = sfb.f_files;
01207 dsi->f_ffree = sfb.f_ffree;
01208
01209 dsi->bneeded = 0;
01210 dsi->ineeded = 0;
01211 #ifdef STATFS_HAS_F_BAVAIL
01212 dsi->f_bavail = sfb.f_bavail;
01213 if (sfb.f_ffree > 0 && sfb.f_files > 0 && sfb.f_favail > 0)
01214 dsi->f_favail = sfb.f_favail;
01215 else
01216 dsi->f_favail = !(sfb.f_ffree == 0 && sfb.f_files == 0)
01217 ? sfb.f_ffree : -1;
01218 #else
01219
01220
01221
01222
01223 dsi->f_bavail = sfb.f_blocks - sfb.f_bfree;
01224
01225 dsi->f_favail = !(sfb.f_ffree == 0 && sfb.f_files == 0)
01226 ? sfb.f_ffree : -1;
01227 #endif
01228
01229 #if !defined(ST_RDONLY)
01230 #define ST_RDONLY 1
01231 #endif
01232 rpmMessage(RPMMESS_DEBUG, _("%5d 0x%08x %8u %12ld %12ld %s %s\n"),
01233 i, (unsigned) dsi->dev, (unsigned) dsi->f_bsize,
01234 (signed long) dsi->f_bavail, (signed long) dsi->f_favail,
01235 ((dsi->f_flag & ST_RDONLY) ? "ro" : "rw"),
01236 ts->filesystems[i]);
01237 }
01238 return rc;
01239 }
01240
01241 void rpmtsUpdateDSI(const rpmts ts, dev_t dev,
01242 uint_32 fileSize, uint_32 prevSize, uint_32 fixupSize,
01243 fileAction action)
01244 {
01245 rpmDiskSpaceInfo dsi;
01246 unsigned long long bneeded;
01247
01248 dsi = ts->dsi;
01249 if (dsi) {
01250 while (dsi->f_bsize && dsi->dev != dev)
01251 dsi++;
01252 if (dsi->f_bsize == 0)
01253 dsi = NULL;
01254 }
01255 if (dsi == NULL)
01256 return;
01257
01258 bneeded = BLOCK_ROUND(fileSize, dsi->f_bsize);
01259
01260 switch (action) {
01261 case FA_BACKUP:
01262 case FA_SAVE:
01263 case FA_ALTNAME:
01264 dsi->ineeded++;
01265 dsi->bneeded += bneeded;
01266 break;
01267
01268
01269
01270
01271
01272
01273 case FA_CREATE:
01274 dsi->bneeded += bneeded;
01275 dsi->bneeded -= BLOCK_ROUND(prevSize, dsi->f_bsize);
01276 break;
01277
01278 case FA_ERASE:
01279 dsi->ineeded--;
01280 dsi->bneeded -= bneeded;
01281 break;
01282
01283 default:
01284 break;
01285 }
01286
01287 if (fixupSize)
01288 dsi->bneeded -= BLOCK_ROUND(fixupSize, dsi->f_bsize);
01289 }
01290
01291 void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)
01292 {
01293 rpmDiskSpaceInfo dsi;
01294 rpmps ps;
01295 int fc;
01296 int i;
01297
01298 if (ts->filesystems == NULL || ts->filesystemCount <= 0)
01299 return;
01300
01301 dsi = ts->dsi;
01302 if (dsi == NULL)
01303 return;
01304 fc = rpmfiFC( rpmteFI(te, RPMTAG_BASENAMES) );
01305 if (fc <= 0)
01306 return;
01307
01308 ps = rpmtsProblems(ts);
01309 for (i = 0; i < ts->filesystemCount; i++, dsi++) {
01310
01311 if (dsi->f_bavail > 0 && adj_fs_blocks(dsi->bneeded) > dsi->f_bavail) {
01312 rpmpsAppend(ps, RPMPROB_DISKSPACE,
01313 rpmteNEVR(te), rpmteKey(te),
01314 ts->filesystems[i], NULL, NULL,
01315 (adj_fs_blocks(dsi->bneeded) - dsi->f_bavail) * dsi->f_bsize);
01316 }
01317
01318 if (dsi->f_favail > 0 && adj_fs_blocks(dsi->ineeded) > dsi->f_favail) {
01319 rpmpsAppend(ps, RPMPROB_DISKNODES,
01320 rpmteNEVR(te), rpmteKey(te),
01321 ts->filesystems[i], NULL, NULL,
01322 (adj_fs_blocks(dsi->ineeded) - dsi->f_favail));
01323 }
01324
01325 if ((dsi->bneeded || dsi->ineeded) && (dsi->f_flag & ST_RDONLY)) {
01326 rpmpsAppend(ps, RPMPROB_RDONLY,
01327 rpmteNEVR(te), rpmteKey(te),
01328 ts->filesystems[i], NULL, NULL, 0);
01329 }
01330 }
01331 ps = rpmpsFree(ps);
01332 }
01333
01334 void * rpmtsNotify(rpmts ts, rpmte te,
01335 rpmCallbackType what, unsigned long long amount, unsigned long long total)
01336 {
01337 void * ptr = NULL;
01338 if (ts && ts->notify && te) {
01339 assert(!(te->type == TR_ADDED && te->h == NULL));
01340
01341
01342 ptr = ts->notify(te->h, what, amount, total,
01343 rpmteKey(te), ts->notifyData);
01344
01345
01346 }
01347 return ptr;
01348 }
01349
01350 int rpmtsNElements(rpmts ts)
01351 {
01352 int nelements = 0;
01353 if (ts != NULL && ts->order != NULL) {
01354 nelements = ts->orderCount;
01355 }
01356 return nelements;
01357 }
01358
01359 rpmte rpmtsElement(rpmts ts, int ix)
01360 {
01361 rpmte te = NULL;
01362 if (ts != NULL && ts->order != NULL) {
01363 if (ix >= 0 && ix < ts->orderCount)
01364 te = ts->order[ix];
01365 }
01366
01367 return te;
01368
01369 }
01370
01371 rpmprobFilterFlags rpmtsFilterFlags(rpmts ts)
01372 {
01373 return (ts != NULL ? ts->ignoreSet : 0);
01374 }
01375
01376 rpmtransFlags rpmtsFlags(rpmts ts)
01377 {
01378 return (ts != NULL ? ts->transFlags : 0);
01379 }
01380
01381 rpmtransFlags rpmtsSetFlags(rpmts ts, rpmtransFlags transFlags)
01382 {
01383 rpmtransFlags otransFlags = 0;
01384 if (ts != NULL) {
01385 otransFlags = ts->transFlags;
01386 ts->transFlags = transFlags;
01387 }
01388 return otransFlags;
01389 }
01390
01391 rpmdepFlags rpmtsDFlags(rpmts ts)
01392 {
01393 return (ts != NULL ? ts->depFlags : 0);
01394 }
01395
01396 rpmdepFlags rpmtsSetDFlags(rpmts ts, rpmdepFlags depFlags)
01397 {
01398 rpmdepFlags odepFlags = 0;
01399 if (ts != NULL) {
01400 odepFlags = ts->depFlags;
01401 ts->depFlags = depFlags;
01402 }
01403 return odepFlags;
01404 }
01405
01406 Spec rpmtsSpec(rpmts ts)
01407 {
01408
01409 return ts->spec;
01410
01411 }
01412
01413 Spec rpmtsSetSpec(rpmts ts, Spec spec)
01414 {
01415 Spec ospec = ts->spec;
01416
01417 ts->spec = spec;
01418
01419 return ospec;
01420 }
01421
01422 rpmte rpmtsRelocateElement(rpmts ts)
01423 {
01424
01425 return ts->relocateElement;
01426
01427 }
01428
01429 rpmte rpmtsSetRelocateElement(rpmts ts, rpmte relocateElement)
01430 {
01431 rpmte orelocateElement = ts->relocateElement;
01432
01433 ts->relocateElement = relocateElement;
01434
01435 return orelocateElement;
01436 }
01437
01438 uint_32 rpmtsColor(rpmts ts)
01439 {
01440 return (ts != NULL ? ts->color : 0);
01441 }
01442
01443 uint_32 rpmtsSetColor(rpmts ts, uint_32 color)
01444 {
01445 uint_32 ocolor = 0;
01446 if (ts != NULL) {
01447 ocolor = ts->color;
01448 ts->color = color;
01449 }
01450 return ocolor;
01451 }
01452
01453 uint_32 rpmtsPrefColor(rpmts ts)
01454 {
01455 return (ts != NULL ? ts->prefcolor : 0);
01456 }
01457
01458 rpmop rpmtsOp(rpmts ts, rpmtsOpX opx)
01459 {
01460 rpmop op = NULL;
01461
01462 if (ts != NULL && opx >= 0 && opx < RPMTS_OP_MAX)
01463 op = ts->ops + opx;
01464
01465 return op;
01466
01467 }
01468
01469 int rpmtsSetNotifyCallback(rpmts ts,
01470 rpmCallbackFunction notify, rpmCallbackData notifyData)
01471 {
01472 if (ts != NULL) {
01473 ts->notify = notify;
01474 ts->notifyData = notifyData;
01475 }
01476 return 0;
01477 }
01478
01479 rpmts rpmtsCreate(void)
01480 {
01481 rpmts ts;
01482 int xx;
01483
01484 ts = xcalloc(1, sizeof(*ts));
01485 memset(&ts->ops, 0, sizeof(ts->ops));
01486 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_TOTAL), -1);
01487 ts->type = RPMTRANS_TYPE_NORMAL;
01488 ts->goal = TSM_UNKNOWN;
01489 ts->filesystemCount = 0;
01490 ts->filesystems = NULL;
01491 ts->dsi = NULL;
01492
01493 ts->solve = rpmtsSolve;
01494 ts->solveData = NULL;
01495 ts->nsuggests = 0;
01496 ts->suggests = NULL;
01497
01498 ts->PRCO = rpmdsNewPRCO(NULL);
01499 { const char * fn = rpmGetPath("%{?_rpmds_sysinfo_path}", NULL);
01500 if (fn && *fn != '\0' && !rpmioAccess(fn, NULL, R_OK))
01501 xx = rpmdsSysinfo(ts->PRCO, NULL);
01502 fn = _free(fn);
01503 }
01504
01505 ts->sdb = NULL;
01506 ts->sdbmode = O_RDONLY;
01507
01508 ts->rdb = NULL;
01509 ts->dbmode = O_RDONLY;
01510
01511 ts->scriptFd = NULL;
01512 ts->tid = (int_32) time(NULL);
01513 ts->delta = 5;
01514
01515 ts->color = rpmExpandNumeric("%{?_transaction_color}");
01516 ts->prefcolor = rpmExpandNumeric("%{?_prefer_color}");
01517 if (!ts->prefcolor) ts->prefcolor = 0x2;
01518
01519 ts->numRemovedPackages = 0;
01520 ts->allocedRemovedPackages = ts->delta;
01521 ts->removedPackages = xcalloc(ts->allocedRemovedPackages,
01522 sizeof(*ts->removedPackages));
01523
01524 ts->rootDir = NULL;
01525 ts->currDir = NULL;
01526 ts->chrootDone = 0;
01527
01528 ts->selinuxEnabled = is_selinux_enabled();
01529
01530 ts->numAddedPackages = 0;
01531 ts->addedPackages = NULL;
01532
01533 ts->numErasedPackages = 0;
01534 ts->erasedPackages = NULL;
01535
01536 ts->numAvailablePackages = 0;
01537 ts->availablePackages = NULL;
01538
01539 ts->orderAlloced = 0;
01540 ts->orderCount = 0;
01541 ts->order = NULL;
01542 ts->ntrees = 0;
01543 ts->maxDepth = 0;
01544
01545 ts->probs = NULL;
01546
01547 ts->sig = NULL;
01548 ts->pkpkt = NULL;
01549 ts->pkpktlen = 0;
01550 memset(ts->pksignid, 0, sizeof(ts->pksignid));
01551 ts->dig = NULL;
01552
01553
01554 ts->arbgoal = 0xffffffff;
01555
01556 ts->nrefs = 0;
01557
01558 return rpmtsLink(ts, "tsCreate");
01559 }