rpm 5.2.1

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 
00013 #include "rpmds.h"
00014 #include "rpmfi.h"
00015 
00016 #define _RPMTE_INTERNAL
00017 #include "rpmte.h"
00018 #include "rpmts.h"
00019 
00020 #include "debug.h"
00021 
00022 /*@unchecked@*/
00023 int _rpmte_debug = 0;
00024 
00025 /*@access alKey @*/
00026 /*@access rpmts @*/     /* XXX cast */
00027 /*@access rpmtsi @*/
00028 
00029 void rpmteCleanDS(rpmte te)
00030 {
00031     te->PRCO = rpmdsFreePRCO(te->PRCO);
00032 }
00033 
00038 static void delTE(rpmte p)
00039         /*@globals fileSystem @*/
00040         /*@modifies p, fileSystem @*/
00041 {
00042     p->relocs = rpmfiFreeRelocations(p->relocs);
00043 
00044     rpmteCleanDS(p);
00045 
00046     p->fi = rpmfiFree(p->fi);
00047 
00048 /*@-refcounttrans@*/    /* FIX: XfdFree annotation */
00049     if (p->fd != NULL)
00050         p->fd = fdFree(p->fd, "delTE");
00051 /*@=refcounttrans@*/
00052 
00053     p->os = _free(p->os);
00054     p->arch = _free(p->arch);
00055     p->epoch = _free(p->epoch);
00056     p->name = _free(p->name);
00057     p->version = _free(p->version);
00058     p->release = _free(p->release);
00059 #ifdef  RPM_VENDOR_MANDRIVA
00060     p->distepoch = _free(p->distepoch);
00061 #endif
00062     p->NEVR = _free(p->NEVR);
00063     p->NEVRA = _free(p->NEVRA);
00064     p->pkgid = _free(p->pkgid);
00065     p->hdrid = _free(p->hdrid);
00066     p->sourcerpm = _free(p->sourcerpm);
00067 
00068     p->replaced = _free(p->replaced);
00069 
00070     p->flink.NEVRA = argvFree(p->flink.NEVRA);
00071     p->flink.Pkgid = argvFree(p->flink.Pkgid);
00072     p->flink.Hdrid = argvFree(p->flink.Hdrid);
00073     p->blink.NEVRA = argvFree(p->blink.NEVRA);
00074     p->blink.Pkgid = argvFree(p->blink.Pkgid);
00075     p->blink.Hdrid = argvFree(p->blink.Hdrid);
00076 
00077     (void)headerFree(p->h);
00078     p->h = NULL;
00079 
00080     /*@-nullstate@*/ /* FIX: p->{NEVR,name} annotations */
00081     return;
00082     /*@=nullstate@*/
00083 }
00084 
00093 static void addTE(rpmts ts, rpmte p, Header h,
00094                 /*@dependent@*/ /*@null@*/ fnpyKey key,
00095                 /*@null@*/ rpmRelocation relocs)
00096         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
00097         /*@modifies ts, p, h,
00098                 rpmGlobalMacroContext, fileSystem, internalState @*/
00099 {
00100     int scareMem = 0;
00101     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00102     int xx;
00103 
00104     he->tag = RPMTAG_NVRA;
00105     xx = headerGet(h, he, 0);
00106 assert(he->p.str != NULL);
00107     p->NEVR = (xx ? he->p.str : xstrdup("?N-?V-?R.?A"));
00108 
00109     he->tag = RPMTAG_NAME;
00110     xx = headerGet(h, he, 0);
00111     p->name = (xx ? he->p.str : xstrdup("?RPMTAG_NAME?"));
00112     he->tag = RPMTAG_VERSION;
00113     xx = headerGet(h, he, 0);
00114     p->version = (char *)(xx ? he->p.str : xstrdup("?RPMTAG_VERSION?"));
00115     he->tag = RPMTAG_RELEASE;
00116     xx = headerGet(h, he, 0);
00117     p->release = (char *)(xx ? he->p.str : xstrdup("?RPMTAG_RELEASE?"));
00118     
00119     p->db_instance = 0;
00120 
00121     he->tag = RPMTAG_PKGID;
00122     xx = headerGet(h, he, 0);
00123     if (he->p.ui8p != NULL) {
00124         static const char hex[] = "0123456789abcdef";
00125         char * t;
00126         rpmuint32_t i;
00127 
00128         p->pkgid = t = xmalloc((2*he->c) + 1);
00129         for (i = 0 ; i < he->c; i++) {
00130             *t++ = hex[ (unsigned)((he->p.ui8p[i] >> 4) & 0x0f) ];
00131             *t++ = hex[ (unsigned)((he->p.ui8p[i]     ) & 0x0f) ];
00132         }
00133         *t = '\0';
00134         he->p.ptr = _free(he->p.ptr);
00135     } else
00136         p->pkgid = NULL;
00137 
00138     he->tag = RPMTAG_HDRID;
00139     xx = headerGet(h, he, 0);
00140     p->hdrid = (xx ? he->p.str : xstrdup("?RPMTAG_HDRID?"));
00141 
00142     he->tag = RPMTAG_SOURCERPM;
00143     xx = headerGet(h, he, 0);
00144     p->sourcerpm = (xx ? he->p.str : NULL);
00145 
00146     he->tag = RPMTAG_ARCH;
00147     xx = headerGet(h, he, 0);
00148     p->arch = (xx ? he->p.str : xstrdup("?RPMTAG_ARCH?"));
00149 
00150     he->tag = RPMTAG_OS;
00151     xx = headerGet(h, he, 0);
00152     p->os = (xx ? he->p.str : xstrdup("?RPMTAG_OS?"));
00153 
00154     p->isSource =
00155         (headerIsEntry(h, RPMTAG_SOURCERPM) == 0 &&
00156          headerIsEntry(h, RPMTAG_ARCH) != 0);
00157 
00158     p->NEVRA = xstrdup(p->NEVR);
00159 
00160     he->tag = RPMTAG_EPOCH;
00161     xx = headerGet(h, he, 0);
00162     if (he->p.ui32p != NULL) {
00163         p->epoch = xmalloc(20);
00164         sprintf(p->epoch, "%u", he->p.ui32p[0]);
00165         he->p.ptr = _free(he->p.ptr);
00166     } else
00167         p->epoch = NULL;
00168 
00169 #ifdef  RPM_VENDOR_MANDRIVA
00170     he->tag = RPMTAG_DISTEPOCH;
00171     xx = headerGet(h, he, 0);
00172     if (he->p.str != NULL) {
00173         p->distepoch = (char*)(xx ? he->p.str : xstrdup("?RPMTAG_DISTEPOCH?"));
00174     } else
00175         p->distepoch = NULL;
00176 #endif
00177 
00178     p->installed = 0;
00179 
00180     p->relocs = rpmfiDupeRelocations(relocs, &p->nrelocs);
00181     p->autorelocatex = -1;
00182 
00183     p->key = key;
00184     p->fd = NULL;
00185 
00186     p->replaced = NULL;
00187 
00188     p->pkgFileSize = 0;
00189     memset(p->originTid, 0, sizeof(p->originTid));
00190     memset(p->originTime, 0, sizeof(p->originTime));
00191 
00192     p->PRCO = rpmdsNewPRCO(h);
00193 
00194     {   rpmte savep = rpmtsSetRelocateElement(ts, p);
00195         p->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
00196         (void) rpmtsSetRelocateElement(ts, savep);
00197     }
00198 
00199     rpmteColorDS(p, RPMTAG_PROVIDENAME);
00200     rpmteColorDS(p, RPMTAG_REQUIRENAME);
00201 /*@-compdef@*/
00202     return;
00203 /*@=compdef@*/
00204 }
00205 
00206 static void rpmteFini(void * _te)
00207         /*@modifies _te @*/
00208 {
00209     rpmte te = _te;
00210 
00211     delTE(te);
00212 }
00213 
00214 /*@unchecked@*/ /*@only@*/ /*@null@*/
00215 rpmioPool _rpmtePool;
00216 
00217 static rpmte rpmteGetPool(/*@null@*/ rpmioPool pool)
00218         /*@globals _rpmtePool, fileSystem, internalState @*/
00219         /*@modifies pool, _rpmtePool, fileSystem, internalState @*/
00220 {
00221     rpmte te;
00222 
00223     if (_rpmtePool == NULL) {
00224         _rpmtePool = rpmioNewPool("te", sizeof(*te), -1, _rpmte_debug,
00225                         NULL, NULL, rpmteFini);
00226         pool = _rpmtePool;
00227     }
00228     return (rpmte) rpmioGetPool(pool, sizeof(*te));
00229 }
00230 
00231 rpmte rpmteNew(const rpmts ts, Header h,
00232                 rpmElementType type,
00233                 fnpyKey key,
00234                 rpmRelocation relocs,
00235                 int dboffset,
00236                 alKey pkgKey)
00237 {
00238     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00239     rpmte p = rpmteGetPool(_rpmtePool);
00240     int xx;
00241 
00242     p->type = type;
00243 
00244     addTE(ts, p, h, key, relocs);
00245     switch (type) {
00246     case TR_ADDED:
00247         p->u.addedKey = pkgKey;
00248         /* XXX 256 is only an estimate of signature header. */
00249         p->pkgFileSize = 96 + 256;
00250         he->tag = RPMTAG_SIGSIZE;
00251         xx = headerGet(h, he, 0);
00252         if (xx && he->p.ui32p)
00253             p->pkgFileSize += *he->p.ui32p;
00254         he->p.ptr = _free(he->p.ptr);
00255         break;
00256     case TR_REMOVED:
00257         p->u.addedKey = pkgKey;
00258         p->u.removed.dboffset = dboffset;
00259         break;
00260     }
00261     return p;
00262 }
00263 
00264 /* Get the DB Instance value */
00265 unsigned int rpmteDBInstance(rpmte te) 
00266 {
00267     return (te != NULL ? te->db_instance : 0);
00268 }
00269 
00270 /* Set the DB Instance value */
00271 void rpmteSetDBInstance(rpmte te, unsigned int instance) 
00272 {
00273     if (te != NULL) 
00274         te->db_instance = instance;
00275 }
00276 
00277 Header rpmteHeader(rpmte te)
00278 {
00279 /*@-castexpose -retalias -retexpose @*/
00280     return (te != NULL && te->h != NULL ? headerLink(te->h) : NULL);
00281 /*@=castexpose =retalias =retexpose @*/
00282 }
00283 
00284 Header rpmteSetHeader(rpmte te, Header h)
00285 {
00286     if (te != NULL)  {
00287         (void)headerFree(te->h);
00288         te->h = NULL;
00289 /*@-assignexpose -castexpose @*/
00290         if (h != NULL)
00291             te->h = headerLink(h);
00292 /*@=assignexpose =castexpose @*/
00293     }
00294     return NULL;
00295 }
00296 
00297 rpmElementType rpmteType(rpmte te)
00298 {
00299     return (te != NULL ? te->type : (rpmElementType)-1);
00300 }
00301 
00302 const char * rpmteN(rpmte te)
00303 {
00304     return (te != NULL ? te->name : NULL);
00305 }
00306 
00307 const char * rpmteE(rpmte te)
00308 {
00309     return (te != NULL ? te->epoch : NULL);
00310 }
00311 
00312 const char * rpmteV(rpmte te)
00313 {
00314     return (te != NULL ? te->version : NULL);
00315 }
00316 
00317 const char * rpmteR(rpmte te)
00318 {
00319     return (te != NULL ? te->release : NULL);
00320 }
00321 
00322 #ifdef  RPM_VENDOR_MANDRIVA
00323 const char * rpmteD(rpmte te)
00324 {
00325     return (te != NULL ? te->distepoch : NULL);
00326 }
00327 #endif
00328 
00329 const char * rpmteA(rpmte te)
00330 {
00331     return (te != NULL ? te->arch : NULL);
00332 }
00333 
00334 const char * rpmteO(rpmte te)
00335 {
00336     return (te != NULL ? te->os : NULL);
00337 }
00338 
00339 int rpmteIsSource(rpmte te)
00340 {
00341     return (te != NULL ? te->isSource : 0);
00342 }
00343 
00344 rpmuint32_t rpmteColor(rpmte te)
00345 {
00346     return (te != NULL ? te->color : 0);
00347 }
00348 
00349 rpmuint32_t rpmteSetColor(rpmte te, rpmuint32_t color)
00350 {
00351     int ocolor = 0;
00352     if (te != NULL) {
00353         ocolor = te->color;
00354         te->color = color;
00355     }
00356     return ocolor;
00357 }
00358 
00359 rpmuint32_t rpmtePkgFileSize(rpmte te)
00360 {
00361     return (te != NULL ? te->pkgFileSize : 0);
00362 }
00363 
00364 rpmuint32_t * rpmteOriginTid(rpmte te)
00365 {
00366     return te->originTid;
00367 }
00368 
00369 rpmuint32_t * rpmteOriginTime(rpmte te)
00370 {
00371     return te->originTime;
00372 }
00373 
00374 int rpmteDepth(rpmte te)
00375 {
00376     return (te != NULL ? te->depth : 0);
00377 }
00378 
00379 int rpmteSetDepth(rpmte te, int ndepth)
00380 {
00381     int odepth = 0;
00382     if (te != NULL) {
00383         odepth = te->depth;
00384         te->depth = ndepth;
00385     }
00386     return odepth;
00387 }
00388 
00389 int rpmteBreadth(rpmte te)
00390 {
00391     return (te != NULL ? te->depth : 0);
00392 }
00393 
00394 int rpmteSetBreadth(rpmte te, int nbreadth)
00395 {
00396     int obreadth = 0;
00397     if (te != NULL) {
00398         obreadth = te->breadth;
00399         te->breadth = nbreadth;
00400     }
00401     return obreadth;
00402 }
00403 
00404 int rpmteNpreds(rpmte te)
00405 {
00406     return (te != NULL ? te->npreds : 0);
00407 }
00408 
00409 int rpmteSetNpreds(rpmte te, int npreds)
00410 {
00411     int opreds = 0;
00412     if (te != NULL) {
00413         opreds = te->npreds;
00414         te->npreds = npreds;
00415     }
00416     return opreds;
00417 }
00418 
00419 int rpmteTree(rpmte te)
00420 {
00421     return (te != NULL ? te->tree : 0);
00422 }
00423 
00424 int rpmteSetTree(rpmte te, int ntree)
00425 {
00426     int otree = 0;
00427     if (te != NULL) {
00428         otree = te->tree;
00429         te->tree = ntree;
00430     }
00431     return otree;
00432 }
00433 
00434 rpmte rpmteParent(rpmte te)
00435 {
00436     return (te != NULL ? te->parent : NULL);
00437 }
00438 
00439 rpmte rpmteSetParent(rpmte te, rpmte pte)
00440 {
00441     rpmte opte = NULL;
00442     if (te != NULL) {
00443         opte = te->parent;
00444         /*@-assignexpose -temptrans@*/
00445         te->parent = pte;
00446         /*@=assignexpose =temptrans@*/
00447     }
00448     return opte;
00449 }
00450 
00451 int rpmteDegree(rpmte te)
00452 {
00453     return (te != NULL ? te->degree : 0);
00454 }
00455 
00456 int rpmteSetDegree(rpmte te, int ndegree)
00457 {
00458     int odegree = 0;
00459     if (te != NULL) {
00460         odegree = te->degree;
00461         te->degree = ndegree;
00462     }
00463     return odegree;
00464 }
00465 
00466 tsortInfo rpmteTSI(rpmte te)
00467 {
00468     /*@-compdef -retalias -retexpose -usereleased @*/
00469     return te->tsi;
00470     /*@=compdef =retalias =retexpose =usereleased @*/
00471 }
00472 
00473 void rpmteFreeTSI(rpmte te)
00474 {
00475     if (te != NULL && rpmteTSI(te) != NULL) {
00476         tsortInfo tsi;
00477 
00478         /* Clean up tsort remnants (if any). */
00479         while ((tsi = rpmteTSI(te)->tsi_next) != NULL) {
00480             rpmteTSI(te)->tsi_next = tsi->tsi_next;
00481             tsi->tsi_next = NULL;
00482             tsi = _free(tsi);
00483         }
00484         te->tsi = _free(te->tsi);
00485     }
00486     /*@-nullstate@*/ /* FIX: te->tsi is NULL */
00487     return;
00488     /*@=nullstate@*/
00489 }
00490 
00491 void rpmteNewTSI(rpmte te)
00492 {
00493     if (te != NULL) {
00494         rpmteFreeTSI(te);
00495         te->tsi = xcalloc(1, sizeof(*te->tsi));
00496     }
00497 }
00498 
00499 alKey rpmteAddedKey(rpmte te)
00500 {
00501     return (te != NULL ? te->u.addedKey : RPMAL_NOMATCH);
00502 }
00503 
00504 alKey rpmteSetAddedKey(rpmte te, alKey npkgKey)
00505 {
00506     alKey opkgKey = RPMAL_NOMATCH;
00507     if (te != NULL) {
00508         opkgKey = te->u.addedKey;
00509         te->u.addedKey = npkgKey;
00510     }
00511     return opkgKey;
00512 }
00513 
00514 
00515 int rpmteDBOffset(rpmte te)
00516 {
00517     return (te != NULL ? te->u.removed.dboffset : 0);
00518 }
00519 
00520 const char * rpmteNEVR(rpmte te)
00521 {
00522     return (te != NULL ? te->NEVR : NULL);
00523 }
00524 
00525 const char * rpmteNEVRA(rpmte te)
00526 {
00527     return (te != NULL ? te->NEVRA : NULL);
00528 }
00529 
00530 const char * rpmtePkgid(rpmte te)
00531 {
00532     return (te != NULL ? te->pkgid : NULL);
00533 }
00534 
00535 const char * rpmteHdrid(rpmte te)
00536 {
00537     return (te != NULL ? te->hdrid : NULL);
00538 }
00539 
00540 const char * rpmteSourcerpm(rpmte te)
00541 {
00542     return (te != NULL ? te->sourcerpm : NULL);
00543 }
00544 
00545 FD_t rpmteFd(rpmte te)
00546 {
00547     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
00548     return (te != NULL ? te->fd : NULL);
00549     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
00550 }
00551 
00552 fnpyKey rpmteKey(rpmte te)
00553 {
00554     return (te != NULL ? te->key : NULL);
00555 }
00556 
00557 rpmds rpmteDS(rpmte te, rpmTag tag)
00558 {
00559     return (te != NULL ? rpmdsFromPRCO(te->PRCO, tag) : NULL);
00560 }
00561 
00562 rpmfi rpmteFI(rpmte te, rpmTag tag)
00563 {
00564     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
00565     if (te == NULL)
00566         return NULL;
00567 
00568     if (tag == RPMTAG_BASENAMES)
00569         return te->fi;
00570     else
00571         return NULL;
00572     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
00573 }
00574 
00575 void rpmteColorDS(rpmte te, rpmTag tag)
00576 {
00577     rpmfi fi = rpmteFI(te, RPMTAG_BASENAMES);
00578     rpmds ds = rpmteDS(te, tag);
00579     char deptype = 'R';
00580     char mydt;
00581     const rpmuint32_t * ddict;
00582     rpmuint32_t * colors;
00583     rpmuint32_t * refs;
00584     rpmuint32_t val;
00585     int Count;
00586     size_t nb;
00587     unsigned ix;
00588     int ndx, i;
00589 
00590     if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfiFC(fi) > 0))
00591         return;
00592 
00593     switch (tag) {
00594     default:
00595         return;
00596         /*@notreached@*/ break;
00597     case RPMTAG_PROVIDENAME:
00598         deptype = 'P';
00599         break;
00600     case RPMTAG_REQUIRENAME:
00601         deptype = 'R';
00602         break;
00603     }
00604 
00605     nb = Count * sizeof(*colors);
00606     colors = memset(alloca(nb), 0, nb);
00607     nb = Count * sizeof(*refs);
00608     refs = memset(alloca(nb), -1, nb);
00609 
00610     /* Calculate dependency color and reference count. */
00611     fi = rpmfiInit(fi, 0);
00612     if (fi != NULL)
00613     while (rpmfiNext(fi) >= 0) {
00614         val = rpmfiFColor(fi);
00615         ddict = NULL;
00616         ndx = rpmfiFDepends(fi, &ddict);
00617         if (ddict != NULL)
00618         while (ndx-- > 0) {
00619             ix = *ddict++;
00620             mydt = (char)((ix >> 24) & 0xff);
00621             if (mydt != deptype)
00622                 /*@innercontinue@*/ continue;
00623             ix &= 0x00ffffff;
00624 assert ((int)ix < Count);
00625             colors[ix] |= val;
00626             refs[ix]++;
00627         }
00628     }
00629 
00630     /* Set color/refs values in dependency set. */
00631     ds = rpmdsInit(ds);
00632     while ((i = rpmdsNext(ds)) >= 0) {
00633         val = colors[i];
00634         te->color |= val;
00635         (void) rpmdsSetColor(ds, val);
00636         val = refs[i];
00637         (void) rpmdsSetRefs(ds, val);
00638     }
00639 }
00640 
00641 /*@unchecked@*/
00642 static int __mydebug = 0;
00643 
00644 int rpmteChain(rpmte p, rpmte q, Header oh, const char * msg)
00645 {
00646     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00647     const char * blinkNEVRA = NULL;
00648     const char * blinkPkgid = NULL;
00649     const char * blinkHdrid = NULL;
00650     int xx;
00651 
00652     if (msg == NULL)
00653         msg = "";
00654     he->tag = RPMTAG_NVRA;
00655     xx = headerGet(oh, he, 0);
00656 assert(he->p.str != NULL);
00657     blinkNEVRA = he->p.str;
00658 
00659     /*
00660      * Convert binary pkgid to a string.
00661      * XXX Yum's borken conception of a "header" doesn't have signature
00662      * tags appended.
00663      */
00664     he->tag = RPMTAG_PKGID;
00665     xx = headerGet(oh, he, 0);
00666     if (xx && he->p.ui8p != NULL) {
00667         static const char hex[] = "0123456789abcdef";
00668         char * t;
00669         rpmuint32_t i;
00670 
00671         blinkPkgid = t = xmalloc((2*he->c) + 1);
00672         for (i = 0 ; i < he->c; i++) {
00673             *t++ = hex[ ((he->p.ui8p[i] >> 4) & 0x0f) ];
00674             *t++ = hex[ ((he->p.ui8p[i]     ) & 0x0f) ];
00675         }
00676         *t = '\0';
00677         he->p.ptr = _free(he->p.ptr);
00678     } else
00679         blinkPkgid = NULL;
00680 
00681     he->tag = RPMTAG_HDRID;
00682     xx = headerGet(oh, he, 0);
00683     blinkHdrid = he->p.str;
00684 
00685 /*@-modfilesys@*/
00686 if (__mydebug)
00687 fprintf(stderr, "%s argvAdd(&q->flink.NEVRA, \"%s\")\n", msg, p->NEVRA);
00688         xx = argvAdd(&q->flink.NEVRA, p->NEVRA);
00689 if (__mydebug)
00690 fprintf(stderr, "%s argvAdd(&p->blink.NEVRA, \"%s\")\n", msg, blinkNEVRA);
00691         xx = argvAdd(&p->blink.NEVRA, blinkNEVRA);
00692 if (__mydebug)
00693 fprintf(stderr, "%s argvAdd(&q->flink.Pkgid, \"%s\")\n", msg, p->pkgid);
00694     if (p->pkgid != NULL)
00695         xx = argvAdd(&q->flink.Pkgid, p->pkgid);
00696 if (__mydebug)
00697 fprintf(stderr, "%s argvAdd(&p->blink.Pkgid, \"%s\")\n", msg, blinkPkgid);
00698     if (blinkPkgid != NULL)
00699         xx = argvAdd(&p->blink.Pkgid, blinkPkgid);
00700 if (__mydebug)
00701 fprintf(stderr, "%s argvAdd(&q->flink.Hdrid, \"%s\")\n", msg, p->hdrid);
00702     if (p->hdrid != NULL)
00703         xx = argvAdd(&q->flink.Hdrid, p->hdrid);
00704 if (__mydebug)
00705 fprintf(stderr, "%s argvAdd(&p->blink.Hdrid, \"%s\")\n", msg, blinkHdrid);
00706     if (blinkHdrid != NULL)
00707         xx = argvAdd(&p->blink.Hdrid, blinkHdrid);
00708 /*@=modfilesys@*/
00709 
00710     blinkNEVRA = _free(blinkNEVRA);
00711     blinkPkgid = _free(blinkPkgid);
00712     blinkHdrid = _free(blinkHdrid);
00713 
00714     return 0;
00715 }
00716 
00717 int rpmtsiOc(rpmtsi tsi)
00718 {
00719     return tsi->ocsave;
00720 }
00721 
00722 /*@-mustmod@*/
00723 static void rpmtsiFini(void * _tsi)
00724         /*@modifies _tsi @*/
00725 {
00726     rpmtsi tsi = _tsi;
00727 /*@-internalglobs@*/
00728     (void)rpmtsFree(tsi->ts);
00729     tsi->ts = NULL;
00730 /*@=internalglobs@*/
00731 }
00732 /*@=mustmod@*/
00733 
00734 /*@unchecked@*/ /*@only@*/ /*@null@*/
00735 rpmioPool _rpmtsiPool;
00736 
00737 static rpmtsi rpmtsiGetPool(/*@null@*/ rpmioPool pool)
00738         /*@globals _rpmtsiPool, fileSystem, internalState @*/
00739         /*@modifies pool, _rpmtsiPool, fileSystem, internalState @*/
00740 {
00741     rpmtsi tsi;
00742 
00743     if (_rpmtsiPool == NULL) {
00744         _rpmtsiPool = rpmioNewPool("tsi", sizeof(*tsi), -1, _rpmte_debug,
00745                         NULL, NULL, rpmtsiFini);/* XXX _rpmtsi_debug? */
00746         pool = _rpmtsiPool;
00747     }
00748     return (rpmtsi) rpmioGetPool(pool, sizeof(*tsi));
00749 }
00750 
00751 rpmtsi XrpmtsiInit(rpmts ts, const char * fn, unsigned int ln)
00752 {
00753     rpmtsi tsi = rpmtsiGetPool(_rpmtsiPool);
00754 
00755 /*@-assignexpose -castexpose @*/
00756     tsi->ts = rpmtsLink(ts, "rpmtsi");
00757 /*@=assignexpose =castexpose @*/
00758     tsi->reverse = 0;
00759     tsi->oc = (tsi->reverse ? (rpmtsNElements(ts) - 1) : 0);
00760     tsi->ocsave = tsi->oc;
00761 
00762     return (rpmtsi) rpmioLinkPoolItem((rpmioItem)tsi, "rpmtsiInit", fn, ln);
00763 }
00764 
00770 static /*@null@*/ /*@dependent@*/
00771 rpmte rpmtsiNextElement(rpmtsi tsi)
00772         /*@modifies tsi @*/
00773 {
00774     rpmte te = NULL;
00775     int oc = -1;
00776 
00777     if (tsi == NULL || tsi->ts == NULL || rpmtsNElements(tsi->ts) <= 0)
00778         return te;
00779 
00780     if (tsi->reverse) {
00781         if (tsi->oc >= 0)               oc = tsi->oc--;
00782     } else {
00783         if (tsi->oc < rpmtsNElements(tsi->ts))  oc = tsi->oc++;
00784     }
00785     tsi->ocsave = oc;
00786     if (oc != -1)
00787         te = rpmtsElement(tsi->ts, oc);
00788     return te;
00789 }
00790 
00791 rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
00792 {
00793     rpmte te;
00794 
00795     while ((te = rpmtsiNextElement(tsi)) != NULL) {
00796         if (type == 0 || (te->type & type) != 0)
00797             break;
00798     }
00799     return te;
00800 }