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