00001
00005 #include "system.h"
00006
00007 #include <rpmio.h>
00008 #include <rpmiotypes.h>
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
00023 int _rpmte_debug = 0;
00024
00025
00026
00027
00028
00029 void rpmteCleanDS(rpmte te)
00030 {
00031 te->PRCO = rpmdsFreePRCO(te->PRCO);
00032 }
00033
00038 static void delTE(rpmte p)
00039
00040
00041 {
00042 p->relocs = rpmfiFreeRelocations(p->relocs);
00043
00044 rpmteCleanDS(p);
00045
00046 p->fi = rpmfiFree(p->fi);
00047
00048
00049 if (p->fd != NULL)
00050 p->fd = fdFree(p->fd, "delTE");
00051
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
00081 return;
00082
00083 }
00084
00093 static void addTE(rpmts ts, rpmte p, Header h,
00094 fnpyKey key,
00095 rpmRelocation relocs)
00096
00097
00098
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
00202 return;
00203
00204 }
00205
00206 static void rpmteFini(void * _te)
00207
00208 {
00209 rpmte te = _te;
00210
00211 delTE(te);
00212 }
00213
00214
00215 rpmioPool _rpmtePool;
00216
00217 static rpmte rpmteGetPool( rpmioPool pool)
00218
00219
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
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
00265 unsigned int rpmteDBInstance(rpmte te)
00266 {
00267 return (te != NULL ? te->db_instance : 0);
00268 }
00269
00270
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
00280 return (te != NULL && te->h != NULL ? headerLink(te->h) : NULL);
00281
00282 }
00283
00284 Header rpmteSetHeader(rpmte te, Header h)
00285 {
00286 if (te != NULL) {
00287 (void)headerFree(te->h);
00288 te->h = NULL;
00289
00290 if (h != NULL)
00291 te->h = headerLink(h);
00292
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
00445 te->parent = pte;
00446
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
00469 return te->tsi;
00470
00471 }
00472
00473 void rpmteFreeTSI(rpmte te)
00474 {
00475 if (te != NULL && rpmteTSI(te) != NULL) {
00476 tsortInfo tsi;
00477
00478
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
00487 return;
00488
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
00548 return (te != NULL ? te->fd : NULL);
00549
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
00565 if (te == NULL)
00566 return NULL;
00567
00568 if (tag == RPMTAG_BASENAMES)
00569 return te->fi;
00570 else
00571 return NULL;
00572
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 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
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 continue;
00623 ix &= 0x00ffffff;
00624 assert ((int)ix < Count);
00625 colors[ix] |= val;
00626 refs[ix]++;
00627 }
00628 }
00629
00630
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
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
00661
00662
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
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
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
00723 static void rpmtsiFini(void * _tsi)
00724
00725 {
00726 rpmtsi tsi = _tsi;
00727
00728 (void)rpmtsFree(tsi->ts);
00729 tsi->ts = NULL;
00730
00731 }
00732
00733
00734
00735 rpmioPool _rpmtsiPool;
00736
00737 static rpmtsi rpmtsiGetPool( rpmioPool pool)
00738
00739
00740 {
00741 rpmtsi tsi;
00742
00743 if (_rpmtsiPool == NULL) {
00744 _rpmtsiPool = rpmioNewPool("tsi", sizeof(*tsi), -1, _rpmte_debug,
00745 NULL, NULL, rpmtsiFini);
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
00756 tsi->ts = rpmtsLink(ts, "rpmtsi");
00757
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
00771 rpmte rpmtsiNextElement(rpmtsi tsi)
00772
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 }