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