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