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