rpm 5.3.7

lib/rpmte.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include <rpmio.h>
00008 #include <rpmiotypes.h>         /* XXX fnpyKey */
00009 
00010 #include <rpmtypes.h>
00011 #include <rpmtag.h>
00012 #include <rpmdb.h>              /* rpmmiFoo */
00013 #include <pkgio.h>              /* rpmReadPackageFile */
00014 
00015 #include "rpmds.h"
00016 #define _RPMFI_INTERNAL         /* pre/post trans scripts */
00017 #include "rpmfi.h"
00018 
00019 #define _RPMTE_INTERNAL
00020 #include "rpmte.h"
00021 #include "rpmts.h"
00022 
00023 #include "debug.h"
00024 
00025 /*@unchecked@*/
00026 int _rpmte_debug = 0;
00027 
00028 /*@access alKey @*/
00029 /*@access rpmts @*/     /* XXX cast */
00030 /*@access rpmtsi @*/
00031 
00032 void rpmteCleanDS(rpmte te)
00033 {
00034     te->PRCO = rpmdsFreePRCO(te->PRCO);
00035 }
00036 
00041 static void delTE(rpmte p)
00042         /*@globals fileSystem @*/
00043         /*@modifies p, fileSystem @*/
00044 {
00045     p->relocs = rpmfiFreeRelocations(p->relocs);
00046 
00047     rpmteCleanDS(p);
00048 
00049 /*@-refcounttrans@*/    /* FIX: XfdFree annotation */
00050     if (p->fd != NULL)
00051         p->fd = fdFree(p->fd, "delTE");
00052 /*@=refcounttrans@*/
00053 
00054     p->os = _free(p->os);
00055     p->arch = _free(p->arch);
00056     p->epoch = _free(p->epoch);
00057     p->name = _free(p->name);
00058     p->version = _free(p->version);
00059     p->release = _free(p->release);
00060 #ifdef  RPM_VENDOR_MANDRIVA
00061     p->distepoch = _free(p->distepoch);
00062 #endif
00063     p->NEVR = _free(p->NEVR);
00064     p->NEVRA = _free(p->NEVRA);
00065     p->pkgid = _free(p->pkgid);
00066     p->hdrid = _free(p->hdrid);
00067     p->sourcerpm = _free(p->sourcerpm);
00068 
00069     p->replaced = _free(p->replaced);
00070 
00071     p->flink.NEVRA = argvFree(p->flink.NEVRA);
00072     p->flink.Pkgid = argvFree(p->flink.Pkgid);
00073     p->flink.Hdrid = argvFree(p->flink.Hdrid);
00074     p->blink.NEVRA = argvFree(p->blink.NEVRA);
00075     p->blink.Pkgid = argvFree(p->blink.Pkgid);
00076     p->blink.Hdrid = argvFree(p->blink.Hdrid);
00077 
00078 assert(p->txn == NULL);         /* XXX FIXME */
00079     p->txn = NULL;
00080     p->fi = rpmfiFree(p->fi);
00081 
00082     (void)headerFree(p->h);
00083     p->h = NULL;
00084 
00085     /*@-nullstate@*/ /* FIX: p->{NEVR,name} annotations */
00086     return;
00087     /*@=nullstate@*/
00088 }
00089 
00098 static void addTE(rpmts ts, rpmte p, Header h,
00099                 /*@dependent@*/ /*@null@*/ fnpyKey key,
00100                 /*@null@*/ rpmRelocation relocs)
00101         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
00102         /*@modifies ts, p, h,
00103                 rpmGlobalMacroContext, fileSystem, internalState @*/
00104 {
00105     int scareMem = 0;
00106     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00107     int xx;
00108 
00109     he->tag = RPMTAG_NVRA;
00110     xx = headerGet(h, he, 0);
00111 assert(he->p.str != NULL);
00112     p->NEVR = (xx ? he->p.str : xstrdup("?N-?V-?R.?A"));
00113 
00114     he->tag = RPMTAG_NAME;
00115     xx = headerGet(h, he, 0);
00116     p->name = (xx ? he->p.str : xstrdup("?RPMTAG_NAME?"));
00117     he->tag = RPMTAG_VERSION;
00118     xx = headerGet(h, he, 0);
00119     p->version = (char *)(xx ? he->p.str : xstrdup("?RPMTAG_VERSION?"));
00120     he->tag = RPMTAG_RELEASE;
00121     xx = headerGet(h, he, 0);
00122     p->release = (char *)(xx ? he->p.str : xstrdup("?RPMTAG_RELEASE?"));
00123     
00124     p->db_instance = 0;
00125 
00126     he->tag = RPMTAG_PKGID;
00127     xx = headerGet(h, he, 0);
00128     if (he->p.ui8p != NULL) {
00129         static const char hex[] = "0123456789abcdef";
00130         char * t;
00131         rpmuint32_t i;
00132 
00133         p->pkgid = t = xmalloc((2*he->c) + 1);
00134         for (i = 0 ; i < he->c; i++) {
00135             *t++ = hex[ (unsigned)((he->p.ui8p[i] >> 4) & 0x0f) ];
00136             *t++ = hex[ (unsigned)((he->p.ui8p[i]     ) & 0x0f) ];
00137         }
00138         *t = '\0';
00139         he->p.ptr = _free(he->p.ptr);
00140     } else
00141         p->pkgid = NULL;
00142 
00143     he->tag = RPMTAG_HDRID;
00144     xx = headerGet(h, he, 0);
00145     p->hdrid = (xx ? he->p.str : xstrdup("?RPMTAG_HDRID?"));
00146 
00147     he->tag = RPMTAG_SOURCERPM;
00148     xx = headerGet(h, he, 0);
00149     p->sourcerpm = (xx ? he->p.str : NULL);
00150 
00151     he->tag = RPMTAG_ARCH;
00152     xx = headerGet(h, he, 0);
00153     p->arch = (xx ? he->p.str : xstrdup("?RPMTAG_ARCH?"));
00154 
00155     he->tag = RPMTAG_OS;
00156     xx = headerGet(h, he, 0);
00157     p->os = (xx ? he->p.str : xstrdup("?RPMTAG_OS?"));
00158 
00159     p->isSource =
00160         (headerIsEntry(h, RPMTAG_SOURCERPM) == 0 &&
00161          headerIsEntry(h, RPMTAG_ARCH) != 0);
00162 
00163     p->NEVRA = xstrdup(p->NEVR);
00164 
00165     he->tag = RPMTAG_EPOCH;
00166     xx = headerGet(h, he, 0);
00167     if (he->p.ui32p != NULL) {
00168         p->epoch = xmalloc(20);
00169         sprintf(p->epoch, "%u", he->p.ui32p[0]);
00170         he->p.ptr = _free(he->p.ptr);
00171     } else
00172         p->epoch = NULL;
00173 
00174 #ifdef  RPM_VENDOR_MANDRIVA
00175     he->tag = RPMTAG_DISTEPOCH;
00176     xx = headerGet(h, he, 0);
00177     if (he->p.str != NULL) {
00178         p->distepoch = (char*)(xx ? he->p.str : xstrdup("?RPMTAG_DISTEPOCH?"));
00179     } else
00180         p->distepoch = NULL;
00181 #endif
00182 
00183     p->installed = 0;
00184 
00185     p->relocs = rpmfiDupeRelocations(relocs, &p->nrelocs);
00186     p->autorelocatex = -1;
00187 
00188     p->key = key;
00189     p->fd = NULL;
00190 
00191     p->replaced = NULL;
00192 
00193     p->pkgFileSize = 0;
00194     memset(p->originTid, 0, sizeof(p->originTid));
00195     memset(p->originTime, 0, sizeof(p->originTime));
00196 
00197     p->PRCO = rpmdsNewPRCO(h);
00198 
00199     {   rpmte savep = rpmtsSetRelocateElement(ts, p);
00200         p->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
00201         (void) rpmtsSetRelocateElement(ts, savep);
00202     }
00203     p->txn = NULL;
00204 
00205     rpmteColorDS(p, RPMTAG_PROVIDENAME);
00206     rpmteColorDS(p, RPMTAG_REQUIRENAME);
00207 /*@-compdef@*/
00208     return;
00209 /*@=compdef@*/
00210 }
00211 
00212 static void rpmteFini(void * _te)
00213         /*@modifies _te @*/
00214 {
00215     rpmte te = _te;
00216 
00217     delTE(te);
00218 }
00219 
00220 /*@unchecked@*/ /*@only@*/ /*@null@*/
00221 rpmioPool _rpmtePool;
00222 
00223 static rpmte rpmteGetPool(/*@null@*/ rpmioPool pool)
00224         /*@globals _rpmtePool, fileSystem, internalState @*/
00225         /*@modifies pool, _rpmtePool, fileSystem, internalState @*/
00226 {
00227     rpmte te;
00228 
00229     if (_rpmtePool == NULL) {
00230         _rpmtePool = rpmioNewPool("te", sizeof(*te), -1, _rpmte_debug,
00231                         NULL, NULL, rpmteFini);
00232         pool = _rpmtePool;
00233     }
00234     te = (rpmte) rpmioGetPool(pool, sizeof(*te));
00235     memset(((char *)te)+sizeof(te->_item), 0, sizeof(*te)-sizeof(te->_item));
00236     return te;
00237 }
00238 
00239 rpmte rpmteNew(const rpmts ts, Header h,
00240                 rpmElementType type,
00241                 fnpyKey key,
00242                 rpmRelocation relocs,
00243                 uint32_t dboffset,
00244                 alKey pkgKey)
00245 {
00246     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00247     rpmte p = rpmteGetPool(_rpmtePool);
00248     int xx;
00249 
00250     p->type = type;
00251 
00252     addTE(ts, p, h, key, relocs);
00253     switch (type) {
00254     case TR_ADDED:
00255         p->u.addedKey = pkgKey;
00256         /* XXX 256 is only an estimate of signature header. */
00257         p->pkgFileSize = 96 + 256;
00258         he->tag = RPMTAG_SIGSIZE;
00259         xx = headerGet(h, he, 0);
00260         if (xx && he->p.ui32p)
00261             p->pkgFileSize += *he->p.ui32p;
00262         he->p.ptr = _free(he->p.ptr);
00263         break;
00264     case TR_REMOVED:
00265         p->u.addedKey = pkgKey;
00266         p->u.removed.dboffset = dboffset;
00267         break;
00268     }
00269     return p;
00270 }
00271 
00272 /* Get the DB Instance value */
00273 uint32_t rpmteDBInstance(rpmte te) 
00274 {
00275     return (te != NULL ? te->db_instance : 0);
00276 }
00277 
00278 /* Set the DB Instance value */
00279 void rpmteSetDBInstance(rpmte te, unsigned int instance) 
00280 {
00281     if (te != NULL) 
00282         te->db_instance = instance;
00283 }
00284 
00285 Header rpmteHeader(rpmte te)
00286 {
00287 /*@-castexpose -retalias -retexpose @*/
00288     return (te != NULL && te->h != NULL ? headerLink(te->h) : NULL);
00289 /*@=castexpose =retalias =retexpose @*/
00290 }
00291 
00292 Header rpmteSetHeader(rpmte te, Header h)
00293 {
00294     if (te != NULL)  {
00295         (void)headerFree(te->h);
00296         te->h = NULL;
00297 /*@-assignexpose -castexpose @*/
00298         if (h != NULL)
00299             te->h = headerLink(h);
00300 /*@=assignexpose =castexpose @*/
00301     }
00302     return NULL;
00303 }
00304 
00305 rpmElementType rpmteType(rpmte te)
00306 {
00307     return (te != NULL ? te->type : (rpmElementType)-1);
00308 }
00309 
00310 const char * rpmteN(rpmte te)
00311 {
00312     return (te != NULL ? te->name : NULL);
00313 }
00314 
00315 const char * rpmteE(rpmte te)
00316 {
00317     return (te != NULL ? te->epoch : NULL);
00318 }
00319 
00320 const char * rpmteV(rpmte te)
00321 {
00322     return (te != NULL ? te->version : NULL);
00323 }
00324 
00325 const char * rpmteR(rpmte te)
00326 {
00327     return (te != NULL ? te->release : NULL);
00328 }
00329 
00330 const char * rpmteD(rpmte te)
00331 {
00332 #ifdef  RPM_VENDOR_MANDRIVA
00333     return (te != NULL ? te->distepoch : NULL);
00334 #else
00335     return NULL;
00336 #endif
00337 }
00338 
00339 const char * rpmteA(rpmte te)
00340 {
00341     return (te != NULL ? te->arch : NULL);
00342 }
00343 
00344 const char * rpmteO(rpmte te)
00345 {
00346     return (te != NULL ? te->os : NULL);
00347 }
00348 
00349 int rpmteIsSource(rpmte te)
00350 {
00351     return (te != NULL ? te->isSource : 0);
00352 }
00353 
00354 rpmuint32_t rpmteColor(rpmte te)
00355 {
00356     return (te != NULL ? te->color : 0);
00357 }
00358 
00359 rpmuint32_t rpmteSetColor(rpmte te, rpmuint32_t color)
00360 {
00361     int ocolor = 0;
00362     if (te != NULL) {
00363         ocolor = te->color;
00364         te->color = color;
00365     }
00366     return ocolor;
00367 }
00368 
00369 rpmuint32_t rpmtePkgFileSize(rpmte te)
00370 {
00371     return (te != NULL ? te->pkgFileSize : 0);
00372 }
00373 
00374 rpmuint32_t * rpmteOriginTid(rpmte te)
00375 {
00376     return te->originTid;
00377 }
00378 
00379 rpmuint32_t * rpmteOriginTime(rpmte te)
00380 {
00381     return te->originTime;
00382 }
00383 
00384 int rpmteDepth(rpmte te)
00385 {
00386     return (te != NULL ? te->depth : 0);
00387 }
00388 
00389 int rpmteSetDepth(rpmte te, int ndepth)
00390 {
00391     int odepth = 0;
00392     if (te != NULL) {
00393         odepth = te->depth;
00394         te->depth = ndepth;
00395     }
00396     return odepth;
00397 }
00398 
00399 int rpmteBreadth(rpmte te)
00400 {
00401     return (te != NULL ? te->depth : 0);
00402 }
00403 
00404 int rpmteSetBreadth(rpmte te, int nbreadth)
00405 {
00406     int obreadth = 0;
00407     if (te != NULL) {
00408         obreadth = te->breadth;
00409         te->breadth = nbreadth;
00410     }
00411     return obreadth;
00412 }
00413 
00414 int rpmteNpreds(rpmte te)
00415 {
00416     return (te != NULL ? te->npreds : 0);
00417 }
00418 
00419 int rpmteSetNpreds(rpmte te, int npreds)
00420 {
00421     int opreds = 0;
00422     if (te != NULL) {
00423         opreds = te->npreds;
00424         te->npreds = npreds;
00425     }
00426     return opreds;
00427 }
00428 
00429 int rpmteTree(rpmte te)
00430 {
00431     return (te != NULL ? te->tree : 0);
00432 }
00433 
00434 int rpmteSetTree(rpmte te, int ntree)
00435 {
00436     int otree = 0;
00437     if (te != NULL) {
00438         otree = te->tree;
00439         te->tree = ntree;
00440     }
00441     return otree;
00442 }
00443 
00444 rpmte rpmteParent(rpmte te)
00445 {
00446     return (te != NULL ? te->parent : NULL);
00447 }
00448 
00449 rpmte rpmteSetParent(rpmte te, rpmte pte)
00450 {
00451     rpmte opte = NULL;
00452     if (te != NULL) {
00453         opte = te->parent;
00454         /*@-assignexpose -temptrans@*/
00455         te->parent = pte;
00456         /*@=assignexpose =temptrans@*/
00457     }
00458     return opte;
00459 }
00460 
00461 int rpmteDegree(rpmte te)
00462 {
00463     return (te != NULL ? te->degree : 0);
00464 }
00465 
00466 int rpmteSetDegree(rpmte te, int ndegree)
00467 {
00468     int odegree = 0;
00469     if (te != NULL) {
00470         odegree = te->degree;
00471         te->degree = ndegree;
00472     }
00473     return odegree;
00474 }
00475 
00476 tsortInfo rpmteTSI(rpmte te)
00477 {
00478     /*@-compdef -retalias -retexpose -usereleased @*/
00479     return te->tsi;
00480     /*@=compdef =retalias =retexpose =usereleased @*/
00481 }
00482 
00483 void rpmteFreeTSI(rpmte te)
00484 {
00485     if (te != NULL && rpmteTSI(te) != NULL) {
00486         tsortInfo tsi;
00487 
00488         /* Clean up tsort remnants (if any). */
00489         while ((tsi = rpmteTSI(te)->tsi_next) != NULL) {
00490             rpmteTSI(te)->tsi_next = tsi->tsi_next;
00491             tsi->tsi_next = NULL;
00492             tsi = _free(tsi);
00493         }
00494         te->tsi = _free(te->tsi);
00495     }
00496     /*@-nullstate@*/ /* FIX: te->tsi is NULL */
00497     return;
00498     /*@=nullstate@*/
00499 }
00500 
00501 void rpmteNewTSI(rpmte te)
00502 {
00503     if (te != NULL) {
00504         rpmteFreeTSI(te);
00505         te->tsi = xcalloc(1, sizeof(*te->tsi));
00506     }
00507 }
00508 
00509 alKey rpmteAddedKey(rpmte te)
00510 {
00511     return (te != NULL ? te->u.addedKey : RPMAL_NOMATCH);
00512 }
00513 
00514 alKey rpmteSetAddedKey(rpmte te, alKey npkgKey)
00515 {
00516     alKey opkgKey = RPMAL_NOMATCH;
00517     if (te != NULL) {
00518         opkgKey = te->u.addedKey;
00519         te->u.addedKey = npkgKey;
00520     }
00521     return opkgKey;
00522 }
00523 
00524 
00525 int rpmteDBOffset(rpmte te)
00526 {
00527     return (te != NULL ? te->u.removed.dboffset : 0);
00528 }
00529 
00530 const char * rpmteNEVR(rpmte te)
00531 {
00532     return (te != NULL ? te->NEVR : NULL);
00533 }
00534 
00535 const char * rpmteNEVRA(rpmte te)
00536 {
00537     return (te != NULL ? te->NEVRA : NULL);
00538 }
00539 
00540 const char * rpmtePkgid(rpmte te)
00541 {
00542     return (te != NULL ? te->pkgid : NULL);
00543 }
00544 
00545 const char * rpmteHdrid(rpmte te)
00546 {
00547     return (te != NULL ? te->hdrid : NULL);
00548 }
00549 
00550 const char * rpmteSourcerpm(rpmte te)
00551 {
00552     return (te != NULL ? te->sourcerpm : NULL);
00553 }
00554 
00555 FD_t rpmteFd(rpmte te)
00556 {
00557     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
00558     return (te != NULL ? te->fd : NULL);
00559     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
00560 }
00561 
00562 fnpyKey rpmteKey(rpmte te)
00563 {
00564     return (te != NULL ? te->key : NULL);
00565 }
00566 
00567 rpmds rpmteDS(rpmte te, rpmTag tag)
00568 {
00569     return (te != NULL ? rpmdsFromPRCO(te->PRCO, tag) : NULL);
00570 }
00571 
00572 #ifdef  REFERENCE
00573 rpmfi rpmteFI(rpmte te)
00574 {
00575     if (te == NULL)
00576         return NULL;
00577 
00578     return te->fi; /* XXX take fi reference here? */
00579 }
00580 #else
00581 rpmfi rpmteFI(rpmte te, rpmTag tag)
00582 {
00583     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
00584     if (te == NULL)
00585         return NULL;
00586 
00587     if (tag == RPMTAG_BASENAMES)
00588         return te->fi;
00589     else
00590         return NULL;
00591     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
00592 }
00593 #endif
00594 
00595 rpmfi rpmteSetFI(rpmte te, rpmfi fi)
00596 {
00597     if (te != NULL)  {
00598         te->fi = rpmfiFree(te->fi);
00599 /*@-assignexpose -castexpose @*/
00600         if (fi != NULL)
00601             te->fi = rpmfiLink(fi, __FUNCTION__);
00602 /*@=assignexpose =castexpose @*/
00603     }
00604     return NULL;
00605 }
00606 
00607 void rpmteColorDS(rpmte te, rpmTag tag)
00608 {
00609     rpmfi fi = rpmteFI(te, RPMTAG_BASENAMES);
00610     rpmds ds = rpmteDS(te, tag);
00611     char deptype = 'R';
00612     char mydt;
00613     const rpmuint32_t * ddict;
00614     rpmuint32_t * colors;
00615     rpmuint32_t * refs;
00616     rpmuint32_t val;
00617     int Count;
00618     size_t nb;
00619     unsigned ix;
00620     int ndx, i;
00621 
00622     if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfiFC(fi) > 0))
00623         return;
00624 
00625     switch (tag) {
00626     default:
00627         return;
00628         /*@notreached@*/ break;
00629     case RPMTAG_PROVIDENAME:
00630         deptype = 'P';
00631         break;
00632     case RPMTAG_REQUIRENAME:
00633         deptype = 'R';
00634         break;
00635     }
00636 
00637     nb = Count * sizeof(*colors);
00638     colors = memset(alloca(nb), 0, nb);
00639     nb = Count * sizeof(*refs);
00640     refs = memset(alloca(nb), -1, nb);
00641 
00642     /* Calculate dependency color and reference count. */
00643     fi = rpmfiInit(fi, 0);
00644     if (fi != NULL)
00645     while (rpmfiNext(fi) >= 0) {
00646         val = rpmfiFColor(fi);
00647         ddict = NULL;
00648         ndx = rpmfiFDepends(fi, &ddict);
00649         if (ddict != NULL)
00650         while (ndx-- > 0) {
00651             ix = *ddict++;
00652             mydt = (char)((ix >> 24) & 0xff);
00653             if (mydt != deptype)
00654                 /*@innercontinue@*/ continue;
00655             ix &= 0x00ffffff;
00656 assert ((int)ix < Count);
00657             colors[ix] |= val;
00658             refs[ix]++;
00659         }
00660     }
00661 
00662     /* Set color/refs values in dependency set. */
00663     ds = rpmdsInit(ds);
00664     while ((i = rpmdsNext(ds)) >= 0) {
00665         val = colors[i];
00666         te->color |= val;
00667         (void) rpmdsSetColor(ds, val);
00668         val = refs[i];
00669         (void) rpmdsSetRefs(ds, val);
00670     }
00671 }
00672 
00673 /*@unchecked@*/
00674 static int __mydebug = 0;
00675 
00676 int rpmteChain(rpmte p, rpmte q, Header oh, const char * msg)
00677 {
00678     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00679     const char * blinkNEVRA = NULL;
00680     const char * blinkPkgid = NULL;
00681     const char * blinkHdrid = NULL;
00682     int xx;
00683 
00684     if (msg == NULL)
00685         msg = "";
00686     he->tag = RPMTAG_NVRA;
00687     xx = headerGet(oh, he, 0);
00688 assert(he->p.str != NULL);
00689     blinkNEVRA = he->p.str;
00690 
00691     /*
00692      * Convert binary pkgid to a string.
00693      * XXX Yum's borken conception of a "header" doesn't have signature
00694      * tags appended.
00695      */
00696     he->tag = RPMTAG_PKGID;
00697     xx = headerGet(oh, he, 0);
00698     if (xx && he->p.ui8p != NULL) {
00699         static const char hex[] = "0123456789abcdef";
00700         char * t;
00701         rpmuint32_t i;
00702 
00703         blinkPkgid = t = xmalloc((2*he->c) + 1);
00704         for (i = 0 ; i < he->c; i++) {
00705             *t++ = hex[ ((he->p.ui8p[i] >> 4) & 0x0f) ];
00706             *t++ = hex[ ((he->p.ui8p[i]     ) & 0x0f) ];
00707         }
00708         *t = '\0';
00709         he->p.ptr = _free(he->p.ptr);
00710     } else
00711         blinkPkgid = NULL;
00712 
00713     he->tag = RPMTAG_HDRID;
00714     xx = headerGet(oh, he, 0);
00715     blinkHdrid = he->p.str;
00716 
00717 /*@-modfilesys@*/
00718 if (__mydebug)
00719 fprintf(stderr, "%s argvAdd(&q->flink.NEVRA, \"%s\")\n", msg, p->NEVRA);
00720         xx = argvAdd(&q->flink.NEVRA, p->NEVRA);
00721 if (__mydebug)
00722 fprintf(stderr, "%s argvAdd(&p->blink.NEVRA, \"%s\")\n", msg, blinkNEVRA);
00723         xx = argvAdd(&p->blink.NEVRA, blinkNEVRA);
00724 if (__mydebug)
00725 fprintf(stderr, "%s argvAdd(&q->flink.Pkgid, \"%s\")\n", msg, p->pkgid);
00726     if (p->pkgid != NULL)
00727         xx = argvAdd(&q->flink.Pkgid, p->pkgid);
00728 if (__mydebug)
00729 fprintf(stderr, "%s argvAdd(&p->blink.Pkgid, \"%s\")\n", msg, blinkPkgid);
00730     if (blinkPkgid != NULL)
00731         xx = argvAdd(&p->blink.Pkgid, blinkPkgid);
00732 if (__mydebug)
00733 fprintf(stderr, "%s argvAdd(&q->flink.Hdrid, \"%s\")\n", msg, p->hdrid);
00734     if (p->hdrid != NULL)
00735         xx = argvAdd(&q->flink.Hdrid, p->hdrid);
00736 if (__mydebug)
00737 fprintf(stderr, "%s argvAdd(&p->blink.Hdrid, \"%s\")\n", msg, blinkHdrid);
00738     if (blinkHdrid != NULL)
00739         xx = argvAdd(&p->blink.Hdrid, blinkHdrid);
00740 /*@=modfilesys@*/
00741 
00742     blinkNEVRA = _free(blinkNEVRA);
00743     blinkPkgid = _free(blinkPkgid);
00744     blinkHdrid = _free(blinkHdrid);
00745 
00746     return 0;
00747 }
00748 
00749 int rpmtsiOc(rpmtsi tsi)
00750 {
00751     return tsi->ocsave;
00752 }
00753 
00754 /*@-mustmod@*/
00755 static void rpmtsiFini(void * _tsi)
00756         /*@modifies _tsi @*/
00757 {
00758     rpmtsi tsi = _tsi;
00759 /*@-internalglobs@*/
00760     (void)rpmtsFree(tsi->ts);
00761     tsi->ts = NULL;
00762 /*@=internalglobs@*/
00763 }
00764 /*@=mustmod@*/
00765 
00766 /*@unchecked@*/ /*@only@*/ /*@null@*/
00767 rpmioPool _rpmtsiPool;
00768 
00769 static rpmtsi rpmtsiGetPool(/*@null@*/ rpmioPool pool)
00770         /*@globals _rpmtsiPool, fileSystem, internalState @*/
00771         /*@modifies pool, _rpmtsiPool, fileSystem, internalState @*/
00772 {
00773     rpmtsi tsi;
00774 
00775     if (_rpmtsiPool == NULL) {
00776         _rpmtsiPool = rpmioNewPool("tsi", sizeof(*tsi), -1, _rpmte_debug,
00777                         NULL, NULL, rpmtsiFini);/* XXX _rpmtsi_debug? */
00778         pool = _rpmtsiPool;
00779     }
00780     return (rpmtsi) rpmioGetPool(pool, sizeof(*tsi));
00781 }
00782 
00783 rpmtsi XrpmtsiInit(rpmts ts, const char * fn, unsigned int ln)
00784 {
00785     rpmtsi tsi = rpmtsiGetPool(_rpmtsiPool);
00786 
00787 /*@-assignexpose -castexpose @*/
00788     tsi->ts = rpmtsLink(ts, "rpmtsi");
00789 /*@=assignexpose =castexpose @*/
00790     tsi->reverse = 0;
00791     tsi->oc = (tsi->reverse ? (rpmtsNElements(ts) - 1) : 0);
00792     tsi->ocsave = tsi->oc;
00793 
00794     return (rpmtsi) rpmioLinkPoolItem((rpmioItem)tsi, "rpmtsiInit", fn, ln);
00795 }
00796 
00802 static /*@null@*/ /*@dependent@*/
00803 rpmte rpmtsiNextElement(rpmtsi tsi)
00804         /*@modifies tsi @*/
00805 {
00806     rpmte te = NULL;
00807     int oc = -1;
00808 
00809     if (tsi == NULL || tsi->ts == NULL || rpmtsNElements(tsi->ts) <= 0)
00810         return te;
00811 
00812     if (tsi->reverse) {
00813         if (tsi->oc >= 0)               oc = tsi->oc--;
00814     } else {
00815         if (tsi->oc < rpmtsNElements(tsi->ts))  oc = tsi->oc++;
00816     }
00817     tsi->ocsave = oc;
00818     if (oc != -1)
00819         te = rpmtsElement(tsi->ts, oc);
00820     return te;
00821 }
00822 
00823 rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
00824 {
00825     rpmte te;
00826 
00827     while ((te = rpmtsiNextElement(tsi)) != NULL) {
00828         if (type == 0 || (te->type & type) != 0)
00829             break;
00830     }
00831     return te;
00832 }
00833 
00834 /*@-mods@*/
00835 Header rpmteDBHeader(rpmts ts, uint32_t rec)
00836 {
00837     rpmmi mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, &rec, sizeof(rec));
00838     Header h;
00839 
00840     /* iterator returns weak refs, grab hold of header */
00841     if ((h = rpmmiNext(mi)) != NULL)
00842         h = headerLink(h);
00843     mi = rpmmiFree(mi);
00844     return h;
00845 }
00846 /*@=mods@*/
00847 
00848 Header rpmteFDHeader(rpmts ts, rpmte te)
00849 {
00850     Header h = NULL;
00851     te->fd = rpmtsNotify(ts, te, RPMCALLBACK_INST_OPEN_FILE, 0, 0);
00852     if (te->fd != NULL) {
00853         rpmVSFlags ovsflags;
00854         rpmRC pkgrc;
00855 
00856         ovsflags = rpmtsSetVSFlags(ts, rpmtsVSFlags(ts) | RPMVSF_NEEDPAYLOAD);
00857         pkgrc = rpmReadPackageFile(ts, rpmteFd(te), rpmteNEVR(te), &h);
00858         ovsflags = rpmtsSetVSFlags(ts, ovsflags);
00859         switch (pkgrc) {
00860         default:
00861             (void) rpmteClose(te, ts, 1);
00862             break;
00863         case RPMRC_NOTTRUSTED:
00864         case RPMRC_NOKEY:
00865         case RPMRC_OK:
00866             break;
00867         }
00868     }
00869     return h;
00870 }
00871 
00872 /*@-mods@*/
00873 int rpmteOpen(rpmte te, rpmts ts, int reload_fi)
00874 {
00875     Header h = NULL;
00876     uint32_t instance;
00877     int rc = 0; /* assume failure */
00878 
00879     if (te == NULL || ts == NULL)
00880         goto exit;
00881 
00882     instance = rpmteDBInstance(te);
00883     (void) rpmteSetHeader(te, NULL);
00884 
00885     switch (rpmteType(te)) {
00886     case TR_ADDED:
00887         h = instance ? rpmteDBHeader(ts, instance) : rpmteFDHeader(ts, te);
00888         break;
00889     case TR_REMOVED:
00890         h = rpmteDBHeader(ts, instance);
00891         break;
00892     }
00893     if (h != NULL) {
00894 #ifdef  REFERENCE
00895         if (reload_fi) {
00896             te->fi = getFI(te, ts, h);
00897         }
00898 #else
00899         if (reload_fi) {
00900             static int scareMem = 0;
00901             te->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
00902         }
00903 #endif
00904         
00905         (void) rpmteSetHeader(te, h);
00906         h = headerFree(h);
00907         rc = 1;
00908     }
00909 
00910 exit:
00911     return rc;
00912 }
00913 /*@=mods@*/
00914 
00915 int rpmteClose(rpmte te, rpmts ts, int reset_fi)
00916 {
00917     if (te == NULL || ts == NULL)
00918         return 0;
00919 
00920     switch (te->type) {
00921     case TR_ADDED:
00922         if (te->fd != NULL) {
00923             void * ptr;
00924             ptr = rpmtsNotify(ts, te, RPMCALLBACK_INST_CLOSE_FILE, 0, 0);
00925             te->fd = NULL;
00926         }
00927         break;
00928     case TR_REMOVED:
00929         /* eventually we'll want notifications for erase open too */
00930         break;
00931     }
00932     (void) rpmteSetHeader(te, NULL);
00933     if (reset_fi)
00934         (void) rpmteSetFI(te, NULL);
00935     return 1;
00936 }
00937 
00938 int rpmteFailed(rpmte te)
00939 {
00940     return (te != NULL) ? te->linkFailed : -1;
00941 }
00942 
00943 int rpmteHaveTransScript(rpmte te, rpmTag tag)
00944 {
00945     rpmfi fi = (te ? te->fi : NULL);
00946     int rc = 0;
00947 
00948     switch (tag) {
00949     default:
00950         break;
00951     case RPMTAG_PRETRANS:
00952         if (fi)
00953             rc = (fi->pretrans || fi->pretransprog) ? 1 : 0;
00954         break;
00955     case RPMTAG_POSTTRANS:
00956         if (fi)
00957             rc = (fi->posttrans || fi->posttransprog) ? 1 : 0;
00958         break;
00959     }
00960     return rc;
00961 }
00962 
00963 #ifdef  REFERENCE
00964 int rpmteMarkFailed(rpmte te, rpmts ts)
00965 {
00966     rpmtsi pi = rpmtsiInit(ts);
00967     int rc = 0;
00968     rpmte p;
00969 
00970     te->failed = 1;
00971     /* XXX we can do a much better here than this... */
00972     while ((p = rpmtsiNext(pi, TR_REMOVED))) {
00973         if (rpmteDependsOn(p) == te) {
00974             p->failed = 1;
00975         }
00976     }
00977     rpmtsiFree(pi);
00978     return rc;
00979 }
00980 
00981 rpmps rpmteProblems(rpmte te)
00982 {
00983     return te ? te->probs : NULL;
00984 }
00985 
00986 rpmfs rpmteGetFileStates(rpmte te) {
00987     return te->fs;
00988 }
00989 
00990 rpmfs rpmfsNew(unsigned int fc, rpmElementType type) {
00991     rpmfs fs = xmalloc(sizeof(*fs));
00992     fs->fc = fc;
00993     fs->replaced = NULL;
00994     fs->states = NULL;
00995     if (type == TR_ADDED) {
00996         fs->states = xmalloc(sizeof(*fs->states) * fs->fc);
00997         memset(fs->states, RPMFILE_STATE_NORMAL, fs->fc);
00998     }
00999     fs->actions = xmalloc(fc * sizeof(*fs->actions));
01000     memset(fs->actions, FA_UNKNOWN, fc * sizeof(*fs->actions));
01001     fs->numReplaced = fs->allocatedReplaced = 0;
01002     return fs;
01003 }
01004 
01005 rpmfs rpmfsFree(rpmfs fs) {
01006     fs->replaced = _free(fs->replaced);
01007     fs->states = _free(fs->states);
01008     fs->actions = _free(fs->actions);
01009 
01010     fs = _free(fs);
01011     return fs;
01012 }
01013 
01014 rpm_count_t rpmfsFC(rpmfs fs) {
01015     return fs->fc;
01016 }
01017 
01018 void rpmfsAddReplaced(rpmfs fs, int pkgFileNum, int otherPkg, int otherFileNum)
01019 {
01020     if (!fs->replaced) {
01021         fs->replaced = xcalloc(3, sizeof(*fs->replaced));
01022         fs->allocatedReplaced = 3;
01023     }
01024     if (fs->numReplaced>=fs->allocatedReplaced) {
01025         fs->allocatedReplaced += (fs->allocatedReplaced>>1) + 2;
01026         fs->replaced = xrealloc(fs->replaced, fs->allocatedReplaced*sizeof(*fs->replaced));
01027     }
01028     fs->replaced[fs->numReplaced].pkgFileNum = pkgFileNum;
01029     fs->replaced[fs->numReplaced].otherPkg = otherPkg;
01030     fs->replaced[fs->numReplaced].otherFileNum = otherFileNum;
01031 
01032     fs->numReplaced++;
01033 }
01034 
01035 sharedFileInfo rpmfsGetReplaced(rpmfs fs)
01036 {
01037     if (fs && fs->numReplaced)
01038         return fs->replaced;
01039     else
01040         return NULL;
01041 }
01042 
01043 sharedFileInfo rpmfsNextReplaced(rpmfs fs , sharedFileInfo replaced)
01044 {
01045     if (fs && replaced) {
01046         replaced++;
01047         if (replaced - fs->replaced < fs->numReplaced)
01048             return replaced;
01049     }
01050     return NULL;
01051 }
01052 
01053 void rpmfsSetState(rpmfs fs, unsigned int ix, rpmfileState state)
01054 {
01055     assert(ix < fs->fc);
01056     fs->states[ix] = state;
01057 }
01058 
01059 rpmfileState rpmfsGetState(rpmfs fs, unsigned int ix)
01060 {
01061     assert(ix < fs->fc);
01062     if (fs->states) return fs->states[ix];
01063     return RPMFILE_STATE_MISSING;
01064 }
01065 
01066 rpm_fstate_t * rpmfsGetStates(rpmfs fs)
01067 {
01068     return fs->states;
01069 }
01070 
01071 rpmFileAction rpmfsGetAction(rpmfs fs, unsigned int ix)
01072 {
01073     rpmFileAction action;
01074     if (fs->actions != NULL && ix < fs->fc) {
01075         action = fs->actions[ix];
01076     } else {
01077         action = FA_UNKNOWN;
01078     }
01079     return action;
01080 }
01081 
01082 void rpmfsSetAction(rpmfs fs, unsigned int ix, rpmFileAction action)
01083 {
01084     if (fs->actions != NULL && ix < fs->fc) {
01085         fs->actions[ix] = action;
01086     }
01087 }
01088 #endif  /* REFERENCE */