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