Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

lib/rpmte.c

Go to the documentation of this file.
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 /*@unchecked@*/
00020 int _rpmte_debug = 0;
00021 
00022 /*@access alKey @*/
00023 /*@access rpmtsi @*/
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         /*@globals fileSystem @*/
00040         /*@modifies p, fileSystem @*/
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 /*@-boundswrite@*/
00069     memset(p, 0, sizeof(*p));   /* XXX trash and burn */
00070 /*@=boundswrite@*/
00071     /*@-nullstate@*/ /* FIX: p->{NEVR,name} annotations */
00072     return;
00073     /*@=nullstate@*/
00074 }
00075 
00084 /*@-bounds@*/
00085 static void addTE(rpmts ts, rpmte p, Header h,
00086                 /*@dependent@*/ /*@null@*/ fnpyKey key,
00087                 /*@null@*/ rpmRelocation * relocs)
00088         /*@globals fileSystem @*/
00089         /*@modifies ts, p, h, fileSystem @*/
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 /*@-branchstate@*/
00139     if (ep) {
00140         p->epoch = xmalloc(20);
00141         sprintf(p->epoch, "%d", *ep);
00142     } else
00143         p->epoch = NULL;
00144 /*@=branchstate@*/
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 /*@-compdef@*/
00183     return;
00184 /*@=compdef@*/
00185 }
00186 /*@=bounds@*/
00187 
00188 rpmte rpmteFree(rpmte te)
00189 {
00190     if (te != NULL) {
00191         delTE(te);
00192         memset(te, 0, sizeof(*te));     /* XXX trash and burn */
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         /* XXX 256 is only an estimate of signature header. */
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 /*@-branchstate@*/
00337     if (te != NULL) {
00338         opte = te->parent;
00339         /*@-assignexpose -temptrans@*/
00340         te->parent = pte;
00341         /*@=assignexpose =temptrans@*/
00342     }
00343 /*@=branchstate@*/
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     /*@-compdef -retalias -retexpose -usereleased @*/
00365     return te->tsi;
00366     /*@=compdef =retalias =retexpose =usereleased @*/
00367 }
00368 
00369 void rpmteFreeTSI(rpmte te)
00370 {
00371     if (te != NULL && rpmteTSI(te) != NULL) {
00372         tsortInfo tsi;
00373 
00374         /* Clean up tsort remnants (if any). */
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     /*@-nullstate@*/ /* FIX: te->tsi is NULL */
00383     return;
00384     /*@=nullstate@*/
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     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
00434     return (te != NULL ? te->fd : NULL);
00435     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
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     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
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     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
00466 }
00467 
00468 rpmfi rpmteFI(rpmte te, rpmTag tag)
00469 {
00470     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
00471     if (te == NULL)
00472         return NULL;
00473 
00474     if (tag == RPMTAG_BASENAMES)
00475         return te->fi;
00476     else
00477         return NULL;
00478     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
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         /*@notreached@*/ 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     /* Calculate dependency color and reference count. */
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                 /*@innercontinue@*/ continue;
00529             ix &= 0x00ffffff;
00530 assert (ix < Count);
00531             colors[ix] |= val;
00532             refs[ix]++;
00533         }
00534     }
00535 
00536     /* Set color/refs values in dependency set. */
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(/*@only@*//*@null@*/ rpmtsi tsi,
00555                 const char * fn, unsigned int ln)
00556 {
00557     /* XXX watchout: a funky recursion segfaults here iff nrefs is wrong. */
00558     if (tsi)
00559         tsi->ts = rpmtsFree(tsi->ts);
00560 
00561 /*@-modfilesys@*/
00562 if (_rpmte_debug)
00563 fprintf(stderr, "*** tsi %p -- %s:%d\n", tsi, fn, ln);
00564 /*@=modfilesys@*/
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 /*@-modfilesys@*/
00578 if (_rpmte_debug)
00579 fprintf(stderr, "*** tsi %p ++ %s:%d\n", tsi, fn, ln);
00580 /*@=modfilesys@*/
00581     return tsi;
00582 }
00583 
00589 static /*@dependent@*/ /*@null@*/
00590 rpmte rpmtsiNextElement(rpmtsi tsi)
00591         /*@modifies tsi @*/
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 /*@-branchstate@*/
00606     if (oc != -1)
00607         te = rpmtsElement(tsi->ts, oc);
00608 /*@=branchstate@*/
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 }

Generated on Sun Oct 26 13:02:01 2003 for rpm by doxygen1.2.18