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->this = rpmdsFree(te->this);
00028 te->provides = rpmdsFree(te->provides);
00029 te->requires = rpmdsFree(te->requires);
00030 te->conflicts = rpmdsFree(te->conflicts);
00031 te->obsoletes = rpmdsFree(te->obsoletes);
00032 }
00033
00038 static void delTE(rpmte p)
00039
00040
00041 {
00042 rpmRelocation * r;
00043
00044 if (p->relocs) {
00045 for (r = p->relocs; (r->oldPath || r->newPath); r++) {
00046 r->oldPath = _free(r->oldPath);
00047 r->newPath = _free(r->newPath);
00048 }
00049 p->relocs = _free(p->relocs);
00050 }
00051
00052 rpmteCleanDS(p);
00053
00054 p->fi = rpmfiFree(p->fi);
00055
00056 if (p->fd != NULL)
00057 p->fd = fdFree(p->fd, "delTE");
00058
00059 p->os = _free(p->os);
00060 p->arch = _free(p->arch);
00061 p->epoch = _free(p->epoch);
00062 p->name = _free(p->name);
00063 p->NEVR = _free(p->NEVR);
00064 p->NEVRA = _free(p->NEVRA);
00065
00066 p->h = headerFree(p->h);
00067
00068
00069 memset(p, 0, sizeof(*p));
00070
00071
00072 return;
00073
00074 }
00075
00084
00085 static void addTE(rpmts ts, rpmte p, Header h,
00086 fnpyKey key,
00087 rpmRelocation * relocs)
00088
00089
00090
00091 {
00092 int scareMem = 0;
00093 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00094 rpmte savep;
00095 int_32 * ep;
00096 const char * arch, * os;
00097 char * t;
00098 size_t nb;
00099 int xx;
00100
00101 p->NEVR = hGetNEVR(h, NULL);
00102 p->name = xstrdup(p->NEVR);
00103 if ((p->release = strrchr(p->name, '-')) != NULL)
00104 *p->release++ = '\0';
00105 if ((p->version = strrchr(p->name, '-')) != NULL)
00106 *p->version++ = '\0';
00107
00108
00109
00110
00111 p->db_instance = 0;
00112
00113 arch = NULL;
00114 xx = hge(h, RPMTAG_ARCH, NULL, (void **)&arch, NULL);
00115 if (arch != NULL) {
00116 p->arch = xstrdup(arch);
00117 p->archScore = rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch);
00118 } else {
00119 p->arch = NULL;
00120 p->archScore = 0;
00121 }
00122 os = NULL;
00123 xx = hge(h, RPMTAG_OS, NULL, (void **)&os, NULL);
00124 if (os != NULL) {
00125 p->os = xstrdup(os);
00126 p->osScore = rpmMachineScore(RPM_MACHTABLE_INSTOS, os);
00127 } else {
00128 p->os = NULL;
00129 p->osScore = 0;
00130 }
00131 p->isSource = headerIsEntry(h, RPMTAG_SOURCEPACKAGE);
00132
00133 nb = strlen(p->NEVR) + 1;
00134 if (p->isSource)
00135 nb += sizeof("src");
00136 else if (p->arch)
00137 nb += strlen(p->arch) + 1;
00138 t = xmalloc(nb);
00139 p->NEVRA = t;
00140 *t = '\0';
00141 t = stpcpy(t, p->NEVR);
00142 if (p->isSource)
00143 t = stpcpy( t, ".src");
00144 else if (p->arch)
00145 t = stpcpy( stpcpy( t, "."), p->arch);
00146
00147 ep = NULL;
00148 xx = hge(h, RPMTAG_EPOCH, NULL, (void **)&ep, NULL);
00149
00150 if (ep) {
00151 p->epoch = xmalloc(20);
00152 sprintf(p->epoch, "%d", *ep);
00153 } else
00154 p->epoch = NULL;
00155
00156
00157 p->nrelocs = 0;
00158 p->relocs = NULL;
00159 if (relocs != NULL) {
00160 rpmRelocation * r;
00161 int i;
00162
00163 for (r = relocs; r->oldPath || r->newPath; r++)
00164 p->nrelocs++;
00165 p->relocs = xmalloc((p->nrelocs + 1) * sizeof(*p->relocs));
00166
00167 for (i = 0, r = relocs; r->oldPath || r->newPath; i++, r++) {
00168 p->relocs[i].oldPath = r->oldPath ? xstrdup(r->oldPath) : NULL;
00169 p->relocs[i].newPath = r->newPath ? xstrdup(r->newPath) : NULL;
00170 }
00171 p->relocs[i].oldPath = NULL;
00172 p->relocs[i].newPath = NULL;
00173 }
00174 p->autorelocatex = -1;
00175
00176 p->key = key;
00177 p->fd = NULL;
00178
00179 p->pkgFileSize = 0;
00180
00181 p->this = rpmdsThis(h, RPMTAG_PROVIDENAME, RPMSENSE_EQUAL);
00182 p->provides = rpmdsNew(h, RPMTAG_PROVIDENAME, scareMem);
00183 p->requires = rpmdsNew(h, RPMTAG_REQUIRENAME, scareMem);
00184 p->conflicts = rpmdsNew(h, RPMTAG_CONFLICTNAME, scareMem);
00185 p->obsoletes = rpmdsNew(h, RPMTAG_OBSOLETENAME, scareMem);
00186
00187 savep = rpmtsSetRelocateElement(ts, p);
00188 p->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
00189 (void) rpmtsSetRelocateElement(ts, savep);
00190
00191 rpmteColorDS(p, RPMTAG_PROVIDENAME);
00192 rpmteColorDS(p, RPMTAG_REQUIRENAME);
00193
00194 return;
00195
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 rpmte p = xcalloc(1, sizeof(*p));
00217 int_32 * ep;
00218 int xx;
00219
00220 p->type = type;
00221 addTE(ts, p, h, key, relocs);
00222 switch (type) {
00223 case TR_ADDED:
00224 p->u.addedKey = pkgKey;
00225 ep = NULL;
00226 xx = headerGetEntry(h, RPMTAG_SIGSIZE, NULL, (void **)&ep, NULL);
00227
00228 if (ep != NULL)
00229 p->pkgFileSize += 96 + 256 + *ep;
00230 break;
00231 case TR_REMOVED:
00232 p->u.removed.dependsOnKey = pkgKey;
00233 p->u.removed.dboffset = dboffset;
00234 break;
00235 }
00236 return p;
00237 }
00238
00239
00240 unsigned int rpmteDBInstance(rpmte te)
00241 {
00242 return (te != NULL ? te->db_instance : 0);
00243 }
00244
00245
00246 void rpmteSetDBInstance(rpmte te, unsigned int instance)
00247 {
00248 if (te != NULL)
00249 te->db_instance = instance;
00250 }
00251
00252 Header rpmteHeader(rpmte te)
00253 {
00254 return (te != NULL && te->h != NULL ? headerLink(te->h) : NULL);
00255 }
00256
00257 Header rpmteSetHeader(rpmte te, Header h)
00258 {
00259 if (te != NULL) {
00260 te->h = headerFree(te->h);
00261 if (h != NULL)
00262 te->h = headerLink(h);
00263 }
00264 return NULL;
00265 }
00266
00267 rpmElementType rpmteType(rpmte te)
00268 {
00269 return (te != NULL ? te->type : -1);
00270 }
00271
00272 const char * rpmteN(rpmte te)
00273 {
00274 return (te != NULL ? te->name : NULL);
00275 }
00276
00277 const char * rpmteE(rpmte te)
00278 {
00279 return (te != NULL ? te->epoch : NULL);
00280 }
00281
00282 const char * rpmteV(rpmte te)
00283 {
00284 return (te != NULL ? te->version : NULL);
00285 }
00286
00287 const char * rpmteR(rpmte te)
00288 {
00289 return (te != NULL ? te->release : NULL);
00290 }
00291
00292 const char * rpmteA(rpmte te)
00293 {
00294 return (te != NULL ? te->arch : NULL);
00295 }
00296
00297 const char * rpmteO(rpmte te)
00298 {
00299 return (te != NULL ? te->os : NULL);
00300 }
00301
00302 int rpmteIsSource(rpmte te)
00303 {
00304 return (te != NULL ? te->isSource : NULL);
00305 }
00306
00307 uint_32 rpmteColor(rpmte te)
00308 {
00309 return (te != NULL ? te->color : 0);
00310 }
00311
00312 uint_32 rpmteSetColor(rpmte te, uint_32 color)
00313 {
00314 int ocolor = 0;
00315 if (te != NULL) {
00316 ocolor = te->color;
00317 te->color = color;
00318 }
00319 return ocolor;
00320 }
00321
00322 uint_32 rpmtePkgFileSize(rpmte te)
00323 {
00324 return (te != NULL ? te->pkgFileSize : 0);
00325 }
00326
00327 int rpmteDepth(rpmte te)
00328 {
00329 return (te != NULL ? te->depth : 0);
00330 }
00331
00332 int rpmteSetDepth(rpmte te, int ndepth)
00333 {
00334 int odepth = 0;
00335 if (te != NULL) {
00336 odepth = te->depth;
00337 te->depth = ndepth;
00338 }
00339 return odepth;
00340 }
00341
00342 int rpmteBreadth(rpmte te)
00343 {
00344 return (te != NULL ? te->depth : 0);
00345 }
00346
00347 int rpmteSetBreadth(rpmte te, int nbreadth)
00348 {
00349 int obreadth = 0;
00350 if (te != NULL) {
00351 obreadth = te->breadth;
00352 te->breadth = nbreadth;
00353 }
00354 return obreadth;
00355 }
00356
00357 int rpmteNpreds(rpmte te)
00358 {
00359 return (te != NULL ? te->npreds : 0);
00360 }
00361
00362 int rpmteSetNpreds(rpmte te, int npreds)
00363 {
00364 int opreds = 0;
00365 if (te != NULL) {
00366 opreds = te->npreds;
00367 te->npreds = npreds;
00368 }
00369 return opreds;
00370 }
00371
00372 int rpmteTree(rpmte te)
00373 {
00374 return (te != NULL ? te->tree : 0);
00375 }
00376
00377 int rpmteSetTree(rpmte te, int ntree)
00378 {
00379 int otree = 0;
00380 if (te != NULL) {
00381 otree = te->tree;
00382 te->tree = ntree;
00383 }
00384 return otree;
00385 }
00386
00387 rpmte rpmteParent(rpmte te)
00388 {
00389 return (te != NULL ? te->parent : NULL);
00390 }
00391
00392 rpmte rpmteSetParent(rpmte te, rpmte pte)
00393 {
00394 rpmte opte = NULL;
00395
00396 if (te != NULL) {
00397 opte = te->parent;
00398
00399 te->parent = pte;
00400
00401 }
00402
00403 return opte;
00404 }
00405
00406 int rpmteDegree(rpmte te)
00407 {
00408 return (te != NULL ? te->degree : 0);
00409 }
00410
00411 int rpmteSetDegree(rpmte te, int ndegree)
00412 {
00413 int odegree = 0;
00414 if (te != NULL) {
00415 odegree = te->degree;
00416 te->degree = ndegree;
00417 }
00418 return odegree;
00419 }
00420
00421 tsortInfo rpmteTSI(rpmte te)
00422 {
00423
00424 return te->tsi;
00425
00426 }
00427
00428 void rpmteFreeTSI(rpmte te)
00429 {
00430 if (te != NULL && rpmteTSI(te) != NULL) {
00431 tsortInfo tsi;
00432
00433
00434 while ((tsi = rpmteTSI(te)->tsi_next) != NULL) {
00435 rpmteTSI(te)->tsi_next = tsi->tsi_next;
00436 tsi->tsi_next = NULL;
00437 tsi = _free(tsi);
00438 }
00439 te->tsi = _free(te->tsi);
00440 }
00441
00442 return;
00443
00444 }
00445
00446 void rpmteNewTSI(rpmte te)
00447 {
00448 if (te != NULL) {
00449 rpmteFreeTSI(te);
00450 te->tsi = xcalloc(1, sizeof(*te->tsi));
00451 }
00452 }
00453
00454 alKey rpmteAddedKey(rpmte te)
00455 {
00456 return (te != NULL ? te->u.addedKey : RPMAL_NOMATCH);
00457 }
00458
00459 alKey rpmteSetAddedKey(rpmte te, alKey npkgKey)
00460 {
00461 alKey opkgKey = RPMAL_NOMATCH;
00462 if (te != NULL) {
00463 opkgKey = te->u.addedKey;
00464 te->u.addedKey = npkgKey;
00465 }
00466 return opkgKey;
00467 }
00468
00469
00470 alKey rpmteDependsOnKey(rpmte te)
00471 {
00472 return (te != NULL ? te->u.removed.dependsOnKey : RPMAL_NOMATCH);
00473 }
00474
00475 int rpmteDBOffset(rpmte te)
00476 {
00477 return (te != NULL ? te->u.removed.dboffset : 0);
00478 }
00479
00480 const char * rpmteNEVR(rpmte te)
00481 {
00482 return (te != NULL ? te->NEVR : NULL);
00483 }
00484
00485 const char * rpmteNEVRA(rpmte te)
00486 {
00487 return (te != NULL ? te->NEVRA : NULL);
00488 }
00489
00490 FD_t rpmteFd(rpmte te)
00491 {
00492
00493 return (te != NULL ? te->fd : NULL);
00494
00495 }
00496
00497 fnpyKey rpmteKey(rpmte te)
00498 {
00499 return (te != NULL ? te->key : NULL);
00500 }
00501
00502 rpmds rpmteDS(rpmte te, rpmTag tag)
00503 {
00504
00505 if (te == NULL)
00506 return NULL;
00507
00508 if (tag == RPMTAG_NAME)
00509 return te->this;
00510 else
00511 if (tag == RPMTAG_PROVIDENAME)
00512 return te->provides;
00513 else
00514 if (tag == RPMTAG_REQUIRENAME)
00515 return te->requires;
00516 else
00517 if (tag == RPMTAG_CONFLICTNAME)
00518 return te->conflicts;
00519 else
00520 if (tag == RPMTAG_OBSOLETENAME)
00521 return te->obsoletes;
00522 else
00523 return NULL;
00524
00525 }
00526
00527 rpmfi rpmteFI(rpmte te, rpmTag tag)
00528 {
00529
00530 if (te == NULL)
00531 return NULL;
00532
00533 if (tag == RPMTAG_BASENAMES)
00534 return te->fi;
00535 else
00536 return NULL;
00537
00538 }
00539
00540 void rpmteColorDS(rpmte te, rpmTag tag)
00541 {
00542 rpmfi fi = rpmteFI(te, RPMTAG_BASENAMES);
00543 rpmds ds = rpmteDS(te, tag);
00544 char deptype = 'R';
00545 char mydt;
00546 const int_32 * ddict;
00547 int_32 * colors;
00548 int_32 * refs;
00549 int_32 val;
00550 int Count;
00551 size_t nb;
00552 unsigned ix;
00553 int ndx, i;
00554
00555 if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfiFC(fi) > 0))
00556 return;
00557
00558 switch (tag) {
00559 default:
00560 return;
00561 break;
00562 case RPMTAG_PROVIDENAME:
00563 deptype = 'P';
00564 break;
00565 case RPMTAG_REQUIRENAME:
00566 deptype = 'R';
00567 break;
00568 }
00569
00570 nb = Count * sizeof(*colors);
00571 colors = memset(alloca(nb), 0, nb);
00572 nb = Count * sizeof(*refs);
00573 refs = memset(alloca(nb), -1, nb);
00574
00575
00576 fi = rpmfiInit(fi, 0);
00577 if (fi != NULL)
00578 while (rpmfiNext(fi) >= 0) {
00579 val = rpmfiFColor(fi);
00580 ddict = NULL;
00581 ndx = rpmfiFDepends(fi, &ddict);
00582 if (ddict != NULL)
00583 while (ndx-- > 0) {
00584 ix = *ddict++;
00585 mydt = ((ix >> 24) & 0xff);
00586 if (mydt != deptype)
00587 continue;
00588 ix &= 0x00ffffff;
00589 assert (ix < Count);
00590 colors[ix] |= val;
00591 refs[ix]++;
00592 }
00593 }
00594
00595
00596 ds = rpmdsInit(ds);
00597 while ((i = rpmdsNext(ds)) >= 0) {
00598 val = colors[i];
00599 te->color |= val;
00600 (void) rpmdsSetColor(ds, val);
00601 val = refs[i];
00602 if (val >= 0)
00603 val++;
00604 (void) rpmdsSetRefs(ds, val);
00605 }
00606 }
00607
00608 int rpmtsiOc(rpmtsi tsi)
00609 {
00610 return tsi->ocsave;
00611 }
00612
00613 rpmtsi XrpmtsiFree( rpmtsi tsi,
00614 const char * fn, unsigned int ln)
00615 {
00616
00617
00618 if (tsi)
00619 tsi->ts = rpmtsFree(tsi->ts);
00620
00621
00622
00623 if (_rpmte_debug)
00624 fprintf(stderr, "*** tsi %p -- %s:%d\n", tsi, fn, ln);
00625
00626 return _free(tsi);
00627 }
00628
00629 rpmtsi XrpmtsiInit(rpmts ts, const char * fn, unsigned int ln)
00630 {
00631 rpmtsi tsi = NULL;
00632
00633 tsi = xcalloc(1, sizeof(*tsi));
00634 tsi->ts = rpmtsLink(ts, "rpmtsi");
00635 tsi->reverse = ((rpmtsFlags(ts) & RPMTRANS_FLAG_REVERSE) ? 1 : 0);
00636 tsi->oc = (tsi->reverse ? (rpmtsNElements(ts) - 1) : 0);
00637 tsi->ocsave = tsi->oc;
00638
00639 if (_rpmte_debug)
00640 fprintf(stderr, "*** tsi %p ++ %s:%d\n", tsi, fn, ln);
00641
00642 return tsi;
00643 }
00644
00650 static
00651 rpmte rpmtsiNextElement(rpmtsi tsi)
00652
00653 {
00654 rpmte te = NULL;
00655 int oc = -1;
00656
00657 if (tsi == NULL || tsi->ts == NULL || rpmtsNElements(tsi->ts) <= 0)
00658 return te;
00659
00660 if (tsi->reverse) {
00661 if (tsi->oc >= 0) oc = tsi->oc--;
00662 } else {
00663 if (tsi->oc < rpmtsNElements(tsi->ts)) oc = tsi->oc++;
00664 }
00665 tsi->ocsave = oc;
00666
00667 if (oc != -1)
00668 te = rpmtsElement(tsi->ts, oc);
00669
00670 return te;
00671 }
00672
00673 rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
00674 {
00675 rpmte te;
00676
00677 while ((te = rpmtsiNextElement(tsi)) != NULL) {
00678 if (type == 0 || (te->type & type) != 0)
00679 break;
00680 }
00681 return te;
00682 }