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
00017 #define _RPMTE_INTERNAL
00018 #include "rpmte.h"
00019
00020 #define _RPMTS_INTERNAL
00021 #include "rpmts.h"
00022
00023
00024
00025 #if STATFS_IN_SYS_STATVFS
00026
00027 #if defined(__LCLINT__)
00028
00029 extern int statvfs (const char * file, struct statvfs * buf)
00030
00031 ;
00032
00033
00034 #else
00035 # include <sys/statvfs.h>
00036 #endif
00037 #else
00038 # if STATFS_IN_SYS_VFS
00039 # include <sys/vfs.h>
00040 # else
00041 # if STATFS_IN_SYS_MOUNT
00042 # include <sys/mount.h>
00043 # else
00044 # if STATFS_IN_SYS_STATFS
00045 # include <sys/statfs.h>
00046 # endif
00047 # endif
00048 # endif
00049 #endif
00050
00051 #include "debug.h"
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 int _rpmts_debug = 0;
00067
00068 char * hGetNEVR(Header h, const char ** np)
00069 {
00070 const char * n, * v, * r;
00071 char * NVR, * t;
00072
00073 (void) headerNVR(h, &n, &v, &r);
00074 NVR = t = xcalloc(1, strlen(n) + strlen(v) + strlen(r) + sizeof("--"));
00075
00076 t = stpcpy(t, n);
00077 t = stpcpy(t, "-");
00078 t = stpcpy(t, v);
00079 t = stpcpy(t, "-");
00080 t = stpcpy(t, r);
00081 if (np)
00082 *np = n;
00083
00084 return NVR;
00085 }
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 rc = rpmdbClose(ts->rdb);
00113 ts->rdb = NULL;
00114 }
00115 return rc;
00116 }
00117
00118 int rpmtsOpenDB(rpmts ts, int dbmode)
00119 {
00120 int rc = 0;
00121
00122 if (ts->rdb != NULL && ts->dbmode == dbmode)
00123 return 0;
00124
00125 (void) rpmtsCloseDB(ts);
00126
00127
00128
00129 ts->dbmode = dbmode;
00130 rc = rpmdbOpen(ts->rootDir, &ts->rdb, ts->dbmode, 0644);
00131 if (rc) {
00132 const char * dn;
00133 dn = rpmGetPath(ts->rootDir, "%{_dbpath}", NULL);
00134 rpmMessage(RPMMESS_ERROR,
00135 _("cannot open Packages database in %s\n"), dn);
00136 dn = _free(dn);
00137 }
00138 return rc;
00139 }
00140
00141 int rpmtsInitDB(rpmts ts, int dbmode)
00142 {
00143 return rpmdbInit(ts->rootDir, dbmode);
00144 }
00145
00146 int rpmtsRebuildDB(rpmts ts)
00147 {
00148 int rc;
00149 if (!(ts->vsflags & RPMVSF_NOHDRCHK))
00150 rc = rpmdbRebuild(ts->rootDir, ts, headerCheck);
00151 else
00152 rc = rpmdbRebuild(ts->rootDir, NULL, NULL);
00153 return rc;
00154 }
00155
00156 int rpmtsVerifyDB(rpmts ts)
00157 {
00158 return rpmdbVerify(ts->rootDir);
00159 }
00160
00161 rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag,
00162 const void * keyp, size_t keylen)
00163 {
00164 rpmdbMatchIterator mi;
00165 if (ts->rdb == NULL && rpmtsOpenDB(ts, ts->dbmode))
00166 return NULL;
00167 mi = rpmdbInitIterator(ts->rdb, rpmtag, keyp, keylen);
00168 if (mi && !(ts->vsflags & RPMVSF_NOHDRCHK))
00169 (void) rpmdbSetHdrChk(mi, ts, headerCheck);
00170 return mi;
00171 }
00172
00173 rpmRC rpmtsFindPubkey(rpmts ts)
00174 {
00175 const void * sig = rpmtsSig(ts);
00176 pgpDig dig = rpmtsDig(ts);
00177 pgpDigParams sigp = rpmtsSignature(ts);
00178 pgpDigParams pubp = rpmtsSignature(ts);
00179 rpmRC res;
00180 int xx;
00181
00182 if (sig == NULL || dig == NULL || sigp == NULL || pubp == NULL) {
00183 res = RPMRC_NOKEY;
00184 goto exit;
00185 }
00186
00187 if (ts->pkpkt == NULL
00188 || memcmp(sigp->signid, ts->pksignid, sizeof(ts->pksignid)))
00189 {
00190 int ix = -1;
00191 rpmdbMatchIterator mi;
00192 Header h;
00193
00194 ts->pkpkt = _free(ts->pkpkt);
00195 ts->pkpktlen = 0;
00196 memset(ts->pksignid, 0, sizeof(ts->pksignid));
00197
00198
00199 mi = rpmtsInitIterator(ts, RPMTAG_PUBKEYS, sigp->signid, sizeof(sigp->signid));
00200 while ((h = rpmdbNextIterator(mi)) != NULL) {
00201 const char ** pubkeys;
00202 int_32 pt, pc;
00203
00204 if (!headerGetEntry(h, RPMTAG_PUBKEYS, &pt, (void **)&pubkeys, &pc))
00205 continue;
00206 ix = rpmdbGetIteratorFileNum(mi);
00207
00208 if (ix >= pc
00209 || b64decode(pubkeys[ix], (void **) &ts->pkpkt, &ts->pkpktlen))
00210 ix = -1;
00211
00212 pubkeys = headerFreeData(pubkeys, pt);
00213 break;
00214 }
00215 mi = rpmdbFreeIterator(mi);
00216
00217
00218 if (ix < 0 || ts->pkpkt == NULL) {
00219 res = RPMRC_NOKEY;
00220 goto exit;
00221 }
00222
00223
00224
00225
00226
00227 if (pgpPrtPkts(ts->pkpkt, ts->pkpktlen, NULL, 0)
00228 && sigp->pubkey_algo == pubp->pubkey_algo
00229 #ifdef NOTYET
00230 && sigp->hash_algo == pubp->hash_algo
00231 #endif
00232 && !memcmp(sigp->signid, pubp->signid, sizeof(sigp->signid)))
00233 {
00234 ts->pkpkt = _free(ts->pkpkt);
00235 ts->pkpktlen = 0;
00236 res = RPMRC_NOKEY;
00237 goto exit;
00238 }
00239
00240
00241
00242
00243
00244 memcpy(ts->pksignid, sigp->signid, sizeof(ts->pksignid));
00245
00246
00247 rpmMessage(RPMMESS_DEBUG, "========== %s pubkey id %s\n",
00248 (sigp->pubkey_algo == PGPPUBKEYALGO_DSA ? "DSA" :
00249 (sigp->pubkey_algo == PGPPUBKEYALGO_RSA ? "RSA" : "???")),
00250 pgpHexStr(sigp->signid, sizeof(sigp->signid)));
00251
00252 }
00253
00254 #ifdef NOTNOW
00255 {
00256 if (ts->pkpkt == NULL) {
00257 const char * pkfn = rpmExpand("%{_gpg_pubkey}", NULL);
00258 if (pgpReadPkts(pkfn, &ts->pkpkt, &ts->pkpktlen) != PGPARMOR_PUBKEY) {
00259 pkfn = _free(pkfn);
00260 res = RPMRC_NOKEY;
00261 goto exit;
00262 }
00263 pkfn = _free(pkfn);
00264 }
00265 }
00266 #endif
00267
00268
00269 xx = pgpPrtPkts(ts->pkpkt, ts->pkpktlen, dig, 0);
00270
00271
00272 if (sigp->pubkey_algo == pubp->pubkey_algo
00273 #ifdef NOTYET
00274 && sigp->hash_algo == pubp->hash_algo
00275 #endif
00276 && !memcmp(sigp->signid, pubp->signid, sizeof(sigp->signid)) )
00277 res = RPMRC_OK;
00278 else
00279 res = RPMRC_NOKEY;
00280
00281
00282
00283 exit:
00284 return res;
00285 }
00286
00287 int rpmtsCloseSDB(rpmts ts)
00288 {
00289 int rc = 0;
00290
00291 if (ts->sdb != NULL) {
00292 rc = rpmdbClose(ts->sdb);
00293 ts->sdb = NULL;
00294 }
00295 return rc;
00296 }
00297
00298 int rpmtsOpenSDB(rpmts ts, int dbmode)
00299 {
00300 static int has_sdbpath = -1;
00301 int rc = 0;
00302
00303 if (ts->sdb != NULL && ts->sdbmode == dbmode)
00304 return 0;
00305
00306 if (has_sdbpath < 0)
00307 has_sdbpath = rpmExpandNumeric("%{?_solve_dbpath:1}");
00308
00309
00310 if (has_sdbpath <= 0)
00311 return 1;
00312
00313 addMacro(NULL, "_dbpath", NULL, "%{_solve_dbpath}", RMIL_DEFAULT);
00314
00315 rc = rpmdbOpen(ts->rootDir, &ts->sdb, ts->sdbmode, 0644);
00316 if (rc) {
00317 const char * dn;
00318 dn = rpmGetPath(ts->rootDir, "%{_dbpath}", NULL);
00319 rpmMessage(RPMMESS_WARNING,
00320 _("cannot open Solve database in %s\n"), dn);
00321 dn = _free(dn);
00322 }
00323 delMacro(NULL, "_dbpath");
00324
00325 return rc;
00326 }
00327
00334 static int sugcmp(const void * a, const void * b)
00335
00336 {
00337
00338 const char * astr = *(const char **)a;
00339 const char * bstr = *(const char **)b;
00340
00341 return strcmp(astr, bstr);
00342 }
00343
00344
00345 int rpmtsSolve(rpmts ts, rpmds ds, const void * data)
00346 {
00347 const char * errstr;
00348 const char * str;
00349 const char * qfmt;
00350 rpmdbMatchIterator mi;
00351 Header bh;
00352 Header h;
00353 size_t bhnamelen;
00354 time_t bhtime;
00355 rpmTag rpmtag;
00356 const char * keyp;
00357 size_t keylen;
00358 int rc = 1;
00359 int xx;
00360
00361
00362 if (ts->goal != TSM_INSTALL)
00363 return rc;
00364
00365 if (rpmdsTagN(ds) != RPMTAG_REQUIRENAME)
00366 return rc;
00367
00368 keyp = rpmdsN(ds);
00369 if (keyp == NULL)
00370 return rc;
00371
00372 if (ts->sdb == NULL) {
00373 xx = rpmtsOpenSDB(ts, ts->sdbmode);
00374 if (xx) return rc;
00375 }
00376
00377
00378 rpmtag = (*keyp == '/' ? RPMTAG_BASENAMES : RPMTAG_PROVIDENAME);
00379 keylen = 0;
00380 mi = rpmdbInitIterator(ts->sdb, rpmtag, keyp, keylen);
00381 bhnamelen = 0;
00382 bhtime = 0;
00383 bh = NULL;
00384 while ((h = rpmdbNextIterator(mi)) != NULL) {
00385 const char * hname;
00386 size_t hnamelen;
00387 time_t htime;
00388 int_32 * ip;
00389
00390 if (rpmtag == RPMTAG_PROVIDENAME && !rpmdsAnyMatchesDep(h, ds, 1))
00391 continue;
00392
00393
00394 hname = NULL;
00395 hnamelen = 0;
00396 if (headerGetEntry(h, RPMTAG_NAME, NULL, (void **)&hname, NULL)) {
00397 if (hname)
00398 hnamelen = strlen(hname);
00399 }
00400 if (bhnamelen > 0 && hnamelen > bhnamelen)
00401 continue;
00402
00403
00404 htime = 0;
00405 if (headerGetEntry(h, RPMTAG_BUILDTIME, NULL, (void **)&ip, NULL))
00406 htime = (time_t)*ip;
00407
00408 if (htime <= bhtime)
00409 continue;
00410
00411 bh = headerFree(bh);
00412 bh = headerLink(h);
00413 bhtime = htime;
00414 bhnamelen = hnamelen;
00415 }
00416 mi = rpmdbFreeIterator(mi);
00417
00418
00419 if (bh == NULL)
00420 goto exit;
00421
00422
00423 qfmt = rpmExpand("%{?_solve_name_fmt}", NULL);
00424 if (qfmt == NULL || *qfmt == '\0')
00425 goto exit;
00426 str = headerSprintf(bh, qfmt, rpmTagTable, rpmHeaderFormats, &errstr);
00427 bh = headerFree(bh);
00428 qfmt = _free(qfmt);
00429 if (str == NULL) {
00430 rpmError(RPMERR_QFMT, _("incorrect format: %s\n"), errstr);
00431 goto exit;
00432 }
00433
00434 if (ts->transFlags & RPMTRANS_FLAG_ADDINDEPS) {
00435 FD_t fd;
00436 rpmRC rpmrc;
00437
00438 h = headerFree(h);
00439 fd = Fopen(str, "r.ufdio");
00440 if (fd == NULL || Ferror(fd)) {
00441 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), str,
00442 Fstrerror(fd));
00443 if (fd) {
00444 xx = Fclose(fd);
00445 fd = NULL;
00446 }
00447 str = _free(str);
00448 goto exit;
00449 }
00450 rpmrc = rpmReadPackageFile(ts, fd, str, &h);
00451 xx = Fclose(fd);
00452 switch (rpmrc) {
00453 default:
00454 str = _free(str);
00455 break;
00456 case RPMRC_NOTTRUSTED:
00457 case RPMRC_NOKEY:
00458 case RPMRC_OK:
00459 if (h != NULL &&
00460 !rpmtsAddInstallElement(ts, h, (fnpyKey)str, 1, NULL))
00461 {
00462 rpmMessage(RPMMESS_DEBUG, _("Adding: %s\n"), str);
00463 rc = -1;
00464
00465 break;
00466 }
00467 str = _free(str);
00468 break;
00469 }
00470 h = headerFree(h);
00471 goto exit;
00472 }
00473
00474 rpmMessage(RPMMESS_DEBUG, _("Suggesting: %s\n"), str);
00475
00476 if (ts->suggests != NULL && ts->nsuggests > 0) {
00477 if (bsearch(&str, ts->suggests, ts->nsuggests,
00478 sizeof(*ts->suggests), sugcmp))
00479 goto exit;
00480 }
00481
00482
00483 ts->suggests = xrealloc(ts->suggests,
00484 sizeof(*ts->suggests) * (ts->nsuggests + 2));
00485 ts->suggests[ts->nsuggests] = str;
00486 ts->nsuggests++;
00487 ts->suggests[ts->nsuggests] = NULL;
00488
00489 if (ts->nsuggests > 1)
00490 qsort(ts->suggests, ts->nsuggests, sizeof(*ts->suggests), sugcmp);
00491
00492 exit:
00493
00494 return rc;
00495
00496 }
00497
00498
00499 int rpmtsAvailable(rpmts ts, const rpmds ds)
00500 {
00501 fnpyKey * sugkey;
00502 int rc = 1;
00503
00504 if (ts->availablePackages == NULL)
00505 return rc;
00506 sugkey = rpmalAllSatisfiesDepend(ts->availablePackages, ds, NULL);
00507 if (sugkey == NULL)
00508 return rc;
00509
00510
00511 if (sugkey[0] != NULL) {
00512 ts->suggests = xrealloc(ts->suggests,
00513 sizeof(*ts->suggests) * (ts->nsuggests + 2));
00514 ts->suggests[ts->nsuggests] = sugkey[0];
00515 sugkey[0] = NULL;
00516 ts->nsuggests++;
00517 ts->suggests[ts->nsuggests] = NULL;
00518 }
00519 sugkey = _free(sugkey);
00520
00521 return rc;
00522
00523 }
00524
00525 int rpmtsSetSolveCallback(rpmts ts,
00526 int (*solve) (rpmts ts, rpmds key, const void * data),
00527 const void * solveData)
00528 {
00529 int rc = 0;
00530
00531
00532 if (ts) {
00533
00534 ts->solve = solve;
00535 ts->solveData = solveData;
00536
00537 }
00538
00539 return rc;
00540 }
00541
00542 rpmps rpmtsProblems(rpmts ts)
00543 {
00544 rpmps ps = NULL;
00545 if (ts) {
00546 if (ts->probs)
00547 ps = rpmpsLink(ts->probs, NULL);
00548 }
00549 return ps;
00550 }
00551
00552 void rpmtsCleanDig(rpmts ts)
00553 {
00554 ts->sig = headerFreeData(ts->sig, ts->sigtype);
00555 ts->dig = pgpFreeDig(ts->dig);
00556 }
00557
00558 void rpmtsClean(rpmts ts)
00559 {
00560 rpmtsi pi; rpmte p;
00561
00562 if (ts == NULL)
00563 return;
00564
00565
00566 pi = rpmtsiInit(ts);
00567 while ((p = rpmtsiNext(pi, 0)) != NULL)
00568 rpmteCleanDS(p);
00569 pi = rpmtsiFree(pi);
00570
00571 ts->addedPackages = rpmalFree(ts->addedPackages);
00572 ts->numAddedPackages = 0;
00573
00574 ts->suggests = _free(ts->suggests);
00575 ts->nsuggests = 0;
00576
00577 ts->probs = rpmpsFree(ts->probs);
00578
00579 rpmtsCleanDig(ts);
00580 }
00581
00582 void rpmtsEmpty(rpmts ts)
00583 {
00584 rpmtsi pi; rpmte p;
00585 int oc;
00586
00587 if (ts == NULL)
00588 return;
00589
00590
00591 rpmtsClean(ts);
00592
00593
00594 for (pi = rpmtsiInit(ts), oc = 0; (p = rpmtsiNext(pi, 0)) != NULL; oc++) {
00595
00596 ts->order[oc] = rpmteFree(ts->order[oc]);
00597
00598 }
00599 pi = rpmtsiFree(pi);
00600
00601 ts->orderCount = 0;
00602
00603 ts->numRemovedPackages = 0;
00604
00605 return;
00606
00607 }
00608
00609 rpmts rpmtsFree(rpmts ts)
00610 {
00611 if (ts == NULL)
00612 return NULL;
00613
00614 if (ts->nrefs > 1)
00615 return rpmtsUnlink(ts, "tsCreate");
00616
00617
00618 rpmtsEmpty(ts);
00619
00620
00621 (void) rpmtsCloseDB(ts);
00622
00623 (void) rpmtsCloseSDB(ts);
00624
00625 ts->removedPackages = _free(ts->removedPackages);
00626
00627 ts->availablePackages = rpmalFree(ts->availablePackages);
00628 ts->numAvailablePackages = 0;
00629
00630 ts->dsi = _free(ts->dsi);
00631
00632 if (ts->scriptFd != NULL) {
00633 ts->scriptFd = fdFree(ts->scriptFd, "rpmtsFree");
00634 ts->scriptFd = NULL;
00635 }
00636 ts->rootDir = _free(ts->rootDir);
00637 ts->currDir = _free(ts->currDir);
00638
00639
00640 ts->order = _free(ts->order);
00641
00642 ts->orderAlloced = 0;
00643
00644 if (ts->pkpkt != NULL)
00645 ts->pkpkt = _free(ts->pkpkt);
00646 ts->pkpktlen = 0;
00647 memset(ts->pksignid, 0, sizeof(ts->pksignid));
00648
00649 (void) rpmtsUnlink(ts, "tsCreate");
00650
00651
00652 ts = _free(ts);
00653
00654
00655 return NULL;
00656 }
00657
00658 rpmVSFlags rpmtsVSFlags(rpmts ts)
00659 {
00660 rpmVSFlags vsflags = 0;
00661 if (ts != NULL)
00662 vsflags = ts->vsflags;
00663 return vsflags;
00664 }
00665
00666 rpmVSFlags rpmtsSetVSFlags(rpmts ts, rpmVSFlags vsflags)
00667 {
00668 rpmVSFlags ovsflags = 0;
00669 if (ts != NULL) {
00670 ovsflags = ts->vsflags;
00671 ts->vsflags = vsflags;
00672 }
00673 return ovsflags;
00674 }
00675
00676 int rpmtsUnorderedSuccessors(rpmts ts, int first)
00677 {
00678 int unorderedSuccessors = 0;
00679 if (ts != NULL) {
00680 unorderedSuccessors = ts->unorderedSuccessors;
00681 if (first >= 0)
00682 ts->unorderedSuccessors = first;
00683 }
00684 return unorderedSuccessors;
00685 }
00686
00687 const char * rpmtsRootDir(rpmts ts)
00688 {
00689 return (ts != NULL ? ts->rootDir : NULL);
00690 }
00691
00692 void rpmtsSetRootDir(rpmts ts, const char * rootDir)
00693 {
00694 if (ts != NULL) {
00695 size_t rootLen;
00696
00697 ts->rootDir = _free(ts->rootDir);
00698
00699 if (rootDir == NULL) {
00700 #ifndef DYING
00701 ts->rootDir = xstrdup("");
00702 #endif
00703 return;
00704 }
00705 rootLen = strlen(rootDir);
00706
00707
00708
00709 if (!(rootLen && rootDir[rootLen - 1] == '/')) {
00710 char * t = alloca(rootLen + 2);
00711 *t = '\0';
00712 (void) stpcpy( stpcpy(t, rootDir), "/");
00713 rootDir = t;
00714 }
00715
00716 ts->rootDir = xstrdup(rootDir);
00717 }
00718 }
00719
00720 const char * rpmtsCurrDir(rpmts ts)
00721 {
00722 const char * currDir = NULL;
00723 if (ts != NULL) {
00724 currDir = ts->currDir;
00725 }
00726 return currDir;
00727 }
00728
00729 void rpmtsSetCurrDir(rpmts ts, const char * currDir)
00730 {
00731 if (ts != NULL) {
00732 ts->currDir = _free(ts->currDir);
00733 if (currDir)
00734 ts->currDir = xstrdup(currDir);
00735 }
00736 }
00737
00738 FD_t rpmtsScriptFd(rpmts ts)
00739 {
00740 FD_t scriptFd = NULL;
00741 if (ts != NULL) {
00742 scriptFd = ts->scriptFd;
00743 }
00744
00745 return scriptFd;
00746
00747 }
00748
00749 void rpmtsSetScriptFd(rpmts ts, FD_t scriptFd)
00750 {
00751
00752 if (ts != NULL) {
00753 if (ts->scriptFd != NULL) {
00754 ts->scriptFd = fdFree(ts->scriptFd, "rpmtsSetScriptFd");
00755 ts->scriptFd = NULL;
00756 }
00757 if (scriptFd != NULL)
00758 ts->scriptFd = fdLink(scriptFd, "rpmtsSetScriptFd");
00759 }
00760 }
00761
00762 int rpmtsChrootDone(rpmts ts)
00763 {
00764 int chrootDone = 0;
00765 if (ts != NULL) {
00766 chrootDone = ts->chrootDone;
00767 }
00768 return chrootDone;
00769 }
00770
00771 int rpmtsSetChrootDone(rpmts ts, int chrootDone)
00772 {
00773 int ochrootDone = 0;
00774 if (ts != NULL) {
00775 ochrootDone = ts->chrootDone;
00776 if (ts->rdb != NULL)
00777 ts->rdb->db_chrootDone = chrootDone;
00778 ts->chrootDone = chrootDone;
00779 }
00780 return ochrootDone;
00781 }
00782
00783 int_32 rpmtsGetTid(rpmts ts)
00784 {
00785 int_32 tid = 0;
00786 if (ts != NULL) {
00787 tid = ts->tid;
00788 }
00789 return tid;
00790 }
00791
00792 int_32 rpmtsSetTid(rpmts ts, int_32 tid)
00793 {
00794 int_32 otid = 0;
00795 if (ts != NULL) {
00796 otid = ts->tid;
00797 ts->tid = tid;
00798 }
00799 return otid;
00800 }
00801
00802 int_32 rpmtsSigtag(const rpmts ts)
00803 {
00804 int_32 sigtag = 0;
00805 if (ts != NULL)
00806 sigtag = ts->sigtag;
00807 return sigtag;
00808 }
00809
00810 int_32 rpmtsSigtype(const rpmts ts)
00811 {
00812 int_32 sigtag = 0;
00813 if (ts != NULL)
00814 sigtag = ts->sigtag;
00815 return sigtag;
00816 }
00817
00818 const void * rpmtsSig(const rpmts ts)
00819 {
00820 const void * sig = NULL;
00821 if (ts != NULL)
00822 sig = ts->sig;
00823 return sig;
00824 }
00825
00826 int_32 rpmtsSiglen(const rpmts ts)
00827 {
00828 int_32 siglen = 0;
00829 if (ts != NULL)
00830 siglen = ts->siglen;
00831 return siglen;
00832 }
00833
00834 int rpmtsSetSig(rpmts ts,
00835 int_32 sigtag, int_32 sigtype, const void * sig, int_32 siglen)
00836 {
00837 if (ts != NULL) {
00838 if (ts->sig && ts->sigtype)
00839 ts->sig = headerFreeData(ts->sig, ts->sigtype);
00840 ts->sigtag = sigtag;
00841 ts->sigtype = (sig ? sigtype : 0);
00842
00843 ts->sig = sig;
00844
00845 ts->siglen = siglen;
00846 }
00847 return 0;
00848 }
00849
00850 pgpDig rpmtsDig(rpmts ts)
00851 {
00852
00853 if (ts->dig == NULL)
00854 ts->dig = pgpNewDig();
00855
00856 if (ts->dig == NULL)
00857 return NULL;
00858 return ts->dig;
00859 }
00860
00861 pgpDigParams rpmtsSignature(const rpmts ts)
00862 {
00863 pgpDig dig = rpmtsDig(ts);
00864 if (dig == NULL) return NULL;
00865
00866 return &dig->signature;
00867
00868 }
00869
00870 pgpDigParams rpmtsPubkey(const rpmts ts)
00871 {
00872 pgpDig dig = rpmtsDig(ts);
00873 if (dig == NULL) return NULL;
00874
00875 return &dig->pubkey;
00876
00877 }
00878
00879 rpmdb rpmtsGetRdb(rpmts ts)
00880 {
00881 rpmdb rdb = NULL;
00882 if (ts != NULL) {
00883 rdb = ts->rdb;
00884 }
00885
00886 return rdb;
00887
00888 }
00889
00890 int rpmtsInitDSI(const rpmts ts)
00891 {
00892 rpmDiskSpaceInfo dsi;
00893 struct stat sb;
00894 int rc;
00895 int i;
00896
00897 if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_DISKSPACE)
00898 return 0;
00899
00900 rc = rpmGetFilesystemList(&ts->filesystems, &ts->filesystemCount);
00901 if (rc || ts->filesystems == NULL || ts->filesystemCount <= 0)
00902 return rc;
00903
00904
00905
00906 rpmMessage(RPMMESS_DEBUG, _("getting list of mounted filesystems\n"));
00907
00908 ts->dsi = _free(ts->dsi);
00909 ts->dsi = xcalloc((ts->filesystemCount + 1), sizeof(*ts->dsi));
00910
00911 dsi = ts->dsi;
00912
00913 if (dsi != NULL)
00914 for (i = 0; (i < ts->filesystemCount) && dsi; i++, dsi++) {
00915 #if STATFS_IN_SYS_STATVFS
00916 struct statvfs sfb;
00917 memset(&sfb, 0, sizeof(sfb));
00918 rc = statvfs(ts->filesystems[i], &sfb);
00919 #else
00920 struct statfs sfb;
00921 memset(&sfb, 0, sizeof(sfb));
00922 # if STAT_STATFS4
00923
00924
00925
00926
00927
00928 rc = statfs(ts->filesystems[i], &sfb, sizeof(sfb), 0);
00929 # else
00930 rc = statfs(ts->filesystems[i], &sfb);
00931 # endif
00932 #endif
00933 if (rc)
00934 break;
00935
00936 rc = stat(ts->filesystems[i], &sb);
00937 if (rc)
00938 break;
00939 dsi->dev = sb.st_dev;
00940
00941 dsi->bsize = sfb.f_bsize;
00942 dsi->bneeded = 0;
00943 dsi->ineeded = 0;
00944 #ifdef STATFS_HAS_F_BAVAIL
00945 dsi->bavail = sfb.f_bavail;
00946 #else
00947
00948
00949
00950
00951 dsi->bavail = sfb.f_blocks - sfb.f_bfree;
00952 #endif
00953
00954 dsi->iavail = !(sfb.f_ffree == 0 && sfb.f_files == 0)
00955 ? sfb.f_ffree : -1;
00956 }
00957 return rc;
00958 }
00959
00960 void rpmtsUpdateDSI(const rpmts ts, dev_t dev,
00961 uint_32 fileSize, uint_32 prevSize, uint_32 fixupSize,
00962 fileAction action)
00963 {
00964 rpmDiskSpaceInfo dsi;
00965 uint_32 bneeded;
00966
00967 dsi = ts->dsi;
00968 if (dsi) {
00969 while (dsi->bsize && dsi->dev != dev)
00970 dsi++;
00971 if (dsi->bsize == 0)
00972 dsi = NULL;
00973 }
00974 if (dsi == NULL)
00975 return;
00976
00977 bneeded = BLOCK_ROUND(fileSize, dsi->bsize);
00978
00979 switch (action) {
00980 case FA_BACKUP:
00981 case FA_SAVE:
00982 case FA_ALTNAME:
00983 dsi->ineeded++;
00984 dsi->bneeded += bneeded;
00985 break;
00986
00987
00988
00989
00990
00991
00992 case FA_CREATE:
00993 dsi->bneeded += bneeded;
00994 dsi->bneeded -= BLOCK_ROUND(prevSize, dsi->bsize);
00995 break;
00996
00997 case FA_ERASE:
00998 dsi->ineeded--;
00999 dsi->bneeded -= bneeded;
01000 break;
01001
01002 default:
01003 break;
01004 }
01005
01006 if (fixupSize)
01007 dsi->bneeded -= BLOCK_ROUND(fixupSize, dsi->bsize);
01008 }
01009
01010 void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)
01011 {
01012 rpmDiskSpaceInfo dsi;
01013 rpmps ps;
01014 int fc;
01015 int i;
01016
01017 if (ts->filesystems == NULL || ts->filesystemCount <= 0)
01018 return;
01019
01020 dsi = ts->dsi;
01021 if (dsi == NULL)
01022 return;
01023 fc = rpmfiFC( rpmteFI(te, RPMTAG_BASENAMES) );
01024 if (fc <= 0)
01025 return;
01026
01027 ps = rpmtsProblems(ts);
01028 for (i = 0; i < ts->filesystemCount; i++, dsi++) {
01029
01030 if (dsi->bavail > 0 && adj_fs_blocks(dsi->bneeded) > dsi->bavail) {
01031 rpmpsAppend(ps, RPMPROB_DISKSPACE,
01032 rpmteNEVR(te), rpmteKey(te),
01033 ts->filesystems[i], NULL, NULL,
01034 (adj_fs_blocks(dsi->bneeded) - dsi->bavail) * dsi->bsize);
01035 }
01036
01037 if (dsi->iavail > 0 && adj_fs_blocks(dsi->ineeded) > dsi->iavail) {
01038 rpmpsAppend(ps, RPMPROB_DISKNODES,
01039 rpmteNEVR(te), rpmteKey(te),
01040 ts->filesystems[i], NULL, NULL,
01041 (adj_fs_blocks(dsi->ineeded) - dsi->iavail));
01042 }
01043 }
01044 ps = rpmpsFree(ps);
01045 }
01046
01047 void * rpmtsNotify(rpmts ts, rpmte te,
01048 rpmCallbackType what, unsigned long amount, unsigned long total)
01049 {
01050 void * ptr = NULL;
01051 if (ts && ts->notify && te) {
01052 assert(!(te->type == TR_ADDED && te->h == NULL));
01053
01054
01055 ptr = ts->notify(te->h, what, amount, total,
01056 rpmteKey(te), ts->notifyData);
01057
01058
01059 }
01060 return ptr;
01061 }
01062
01063 int rpmtsNElements(rpmts ts)
01064 {
01065 int nelements = 0;
01066 if (ts != NULL && ts->order != NULL) {
01067 nelements = ts->orderCount;
01068 }
01069 return nelements;
01070 }
01071
01072 rpmte rpmtsElement(rpmts ts, int ix)
01073 {
01074 rpmte te = NULL;
01075 if (ts != NULL && ts->order != NULL) {
01076 if (ix >= 0 && ix < ts->orderCount)
01077 te = ts->order[ix];
01078 }
01079
01080 return te;
01081
01082 }
01083
01084 rpmprobFilterFlags rpmtsFilterFlags(rpmts ts)
01085 {
01086 return (ts != NULL ? ts->ignoreSet : 0);
01087 }
01088
01089 rpmtransFlags rpmtsFlags(rpmts ts)
01090 {
01091 return (ts != NULL ? ts->transFlags : 0);
01092 }
01093
01094 rpmtransFlags rpmtsSetFlags(rpmts ts, rpmtransFlags transFlags)
01095 {
01096 rpmtransFlags otransFlags = 0;
01097 if (ts != NULL) {
01098 otransFlags = ts->transFlags;
01099 ts->transFlags = transFlags;
01100 }
01101 return otransFlags;
01102 }
01103
01104 int rpmtsSetNotifyCallback(rpmts ts,
01105 rpmCallbackFunction notify, rpmCallbackData notifyData)
01106 {
01107 if (ts != NULL) {
01108 ts->notify = notify;
01109 ts->notifyData = notifyData;
01110 }
01111 return 0;
01112 }
01113
01114 int rpmtsGetKeys(const rpmts ts, fnpyKey ** ep, int * nep)
01115 {
01116 int rc = 0;
01117
01118 if (nep) *nep = ts->orderCount;
01119 if (ep) {
01120 rpmtsi pi; rpmte p;
01121 fnpyKey * e;
01122
01123 *ep = e = xmalloc(ts->orderCount * sizeof(*e));
01124 pi = rpmtsiInit(ts);
01125 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01126 switch (rpmteType(p)) {
01127 case TR_ADDED:
01128
01129 *e = rpmteKey(p);
01130
01131 break;
01132 case TR_REMOVED:
01133 default:
01134 *e = NULL;
01135 break;
01136 }
01137 e++;
01138 }
01139 pi = rpmtsiFree(pi);
01140 }
01141 return rc;
01142 }
01143
01144 rpmts rpmtsCreate(void)
01145 {
01146 rpmts ts;
01147
01148 ts = xcalloc(1, sizeof(*ts));
01149 ts->goal = TSM_UNKNOWN;
01150 ts->filesystemCount = 0;
01151 ts->filesystems = NULL;
01152 ts->dsi = NULL;
01153
01154 ts->solve = rpmtsSolve;
01155 ts->solveData = NULL;
01156 ts->nsuggests = 0;
01157 ts->suggests = NULL;
01158 ts->sdb = NULL;
01159 ts->sdbmode = O_RDONLY;
01160
01161 ts->rdb = NULL;
01162 ts->dbmode = O_RDONLY;
01163
01164 ts->scriptFd = NULL;
01165 ts->tid = (int_32) time(NULL);
01166 ts->delta = 5;
01167
01168 ts->numRemovedPackages = 0;
01169 ts->allocedRemovedPackages = ts->delta;
01170 ts->removedPackages = xcalloc(ts->allocedRemovedPackages,
01171 sizeof(*ts->removedPackages));
01172
01173 ts->rootDir = NULL;
01174 ts->currDir = NULL;
01175 ts->chrootDone = 0;
01176
01177 ts->numAddedPackages = 0;
01178 ts->addedPackages = NULL;
01179
01180 ts->numAvailablePackages = 0;
01181 ts->availablePackages = NULL;
01182
01183 ts->orderAlloced = 0;
01184 ts->orderCount = 0;
01185 ts->order = NULL;
01186
01187 ts->probs = NULL;
01188
01189 ts->sig = NULL;
01190 ts->pkpkt = NULL;
01191 ts->pkpktlen = 0;
01192 memset(ts->pksignid, 0, sizeof(ts->pksignid));
01193 ts->dig = NULL;
01194
01195 ts->nrefs = 0;
01196
01197 return rpmtsLink(ts, "tsCreate");
01198 }