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