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
00020 int _rpmte_debug = 0;
00021
00022
00023
00024
00025 void rpmteCleanDS(rpmte te)
00026 {
00027 te->PRCO = rpmdsFreePRCO(te->PRCO);
00028 }
00029
00034 static void delTE(rpmte p)
00035
00036
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
00074 memset(p, 0, sizeof(*p));
00075
00076
00077 return;
00078
00079 }
00080
00089
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 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
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
00171 if (ep) {
00172 p->epoch = xmalloc(20);
00173 sprintf(p->epoch, "%d", *ep);
00174 } else
00175 p->epoch = NULL;
00176
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
00213 return;
00214
00215 }
00216
00217
00218 rpmte rpmteFree(rpmte te)
00219 {
00220 if (te != NULL) {
00221 delTE(te);
00222 memset(te, 0, sizeof(*te));
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
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
00260 unsigned int rpmteDBInstance(rpmte te)
00261 {
00262 return (te != NULL ? te->db_instance : 0);
00263 }
00264
00265
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
00416 if (te != NULL) {
00417 opte = te->parent;
00418
00419 te->parent = pte;
00420
00421 }
00422
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
00444 return te->tsi;
00445
00446 }
00447
00448 void rpmteFreeTSI(rpmte te)
00449 {
00450 if (te != NULL && rpmteTSI(te) != NULL) {
00451 tsortInfo tsi;
00452
00453
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
00462 return;
00463
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
00518 return (te != NULL ? te->fd : NULL);
00519
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
00535 if (te == NULL)
00536 return NULL;
00537
00538 if (tag == RPMTAG_BASENAMES)
00539 return te->fi;
00540 else
00541 return NULL;
00542
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 int_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 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
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 continue;
00593 ix &= 0x00ffffff;
00594 assert (ix < Count);
00595 colors[ix] |= val;
00596 refs[ix]++;
00597 }
00598 }
00599
00600
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
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
00627 if (msg == NULL)
00628 msg = "";
00629
00630 blinkNEVRA = hGetNEVRA(oh, NULL);
00631
00632
00633
00634
00635
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
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
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
00684
00685 blinkNEVRA = _free(blinkNEVRA);
00686 blinkPkgid = _free(blinkPkgid);
00687 #ifdef NOTYET
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( rpmtsi tsi,
00700 const char * fn, unsigned int ln)
00701 {
00702
00703
00704 if (tsi)
00705 tsi->ts = rpmtsFree(tsi->ts);
00706
00707
00708
00709 if (_rpmte_debug)
00710 fprintf(stderr, "*** tsi %p -- %s:%d\n", tsi, fn, ln);
00711
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
00725 if (_rpmte_debug)
00726 fprintf(stderr, "*** tsi %p ++ %s:%d\n", tsi, fn, ln);
00727
00728 return tsi;
00729 }
00730
00736 static
00737 rpmte rpmtsiNextElement(rpmtsi tsi)
00738
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
00753 if (oc != -1)
00754 te = rpmtsElement(tsi->ts, oc);
00755
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 }