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