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 /*@access rpmts @*/
    00025
    00026 void rpmteCleanDS(rpmte te)
    00027 {
    00028     te->this = rpmdsFree(te->this);
    00029     te->provides = rpmdsFree(te->provides);
    00030     te->requires = rpmdsFree(te->requires);
    00031     te->conflicts = rpmdsFree(te->conflicts);
    00032     te->obsoletes = rpmdsFree(te->obsoletes);
    00033 }
    00034
    00037 static void delTE(rpmte p)
    00038         /*@globals fileSystem @*/
    00039         /*@modifies p, fileSystem @*/
    00040 {
    00041     rpmRelocation * r;
    00042
    00043     if (p->relocs) {
    00044         for (r = p->relocs; (r->oldPath || r->newPath); r++) {
    00045             r->oldPath = _free(r->oldPath);
    00046             r->newPath = _free(r->newPath);
    00047         }
    00048         p->relocs = _free(p->relocs);
    00049     }
    00050
    00051     rpmteCleanDS(p);
    00052
    00053     p->fi = rpmfiFree(p->fi);
    00054
    00055     /*@-noeffectuncon@*/
    00056     if (p->fd != NULL)
    00057         p->fd = fdFree(p->fd, "delTE");
    00058     /*@=noeffectuncon@*/
    00059
    00060     p->os = _free(p->os);
    00061     p->arch = _free(p->arch);
    00062     p->epoch = _free(p->epoch);
    00063     p->name = _free(p->name);
    00064     p->NEVR = _free(p->NEVR);
    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
    00078 /*@-bounds@*/
    00079 static void addTE(rpmts ts, rpmte p, Header h,
    00080                 /*@dependent@*/ /*@null@*/ fnpyKey key,
    00081                 /*@null@*/ rpmRelocation * relocs)
    00082         /*@globals fileSystem @*/
    00083         /*@modifies ts, p, h, fileSystem @*/
    00084 {
    00085     int scareMem = 0;
    00086     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
    00087     int_32 * ep;
    00088     const char * arch, * os;
    00089     int xx;
    00090
    00091     p->NEVR = hGetNEVR(h, NULL);
    00092     p->name = xstrdup(p->NEVR);
    00093     if ((p->release = strrchr(p->name, '-')) != NULL)
    00094         *p->release++ = '\0';
    00095     if ((p->version = strrchr(p->name, '-')) != NULL)
    00096         *p->version++ = '\0';
    00097
    00098     arch = NULL;
    00099     xx = hge(h, RPMTAG_ARCH, NULL, (void **)&arch, NULL);
    00100     p->arch = (arch != NULL ? xstrdup(arch) : NULL);
    00101     os = NULL;
    00102     xx = hge(h, RPMTAG_OS, NULL, (void **)&os, NULL);
    00103     p->os = (os != NULL ? xstrdup(os) : NULL);
    00104
    00105     ep = NULL;
    00106     xx = hge(h, RPMTAG_EPOCH, NULL, (void **)&ep, NULL);
    00107 /*@-branchstate@*/
    00108     if (ep) {
    00109         p->epoch = xmalloc(20);
    00110         sprintf(p->epoch, "%d", *ep);
    00111     } else
    00112         p->epoch = NULL;
    00113 /*@=branchstate@*/
    00114
    00115     p->this = rpmdsThis(h, RPMTAG_PROVIDENAME, RPMSENSE_EQUAL);
    00116     p->provides = rpmdsNew(h, RPMTAG_PROVIDENAME, scareMem);
    00117     p->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
    00118     p->requires = rpmdsNew(h, RPMTAG_REQUIRENAME, scareMem);
    00119     p->conflicts = rpmdsNew(h, RPMTAG_CONFLICTNAME, scareMem);
    00120     p->obsoletes = rpmdsNew(h, RPMTAG_OBSOLETENAME, scareMem);
    00121
    00122     p->key = key;
    00123
    00124     p->fd = NULL;
    00125
    00126     p->multiLib = 0;
    00127
    00128     if (relocs != NULL) {
    00129         rpmRelocation * r;
    00130         int i;
    00131
    00132         for (i = 0, r = relocs; r->oldPath || r->newPath; i++, r++)
    00133             {};
    00134         p->relocs = xmalloc((i + 1) * sizeof(*p->relocs));
    00135
    00136         for (i = 0, r = relocs; r->oldPath || r->newPath; i++, r++) {
    00137             p->relocs[i].oldPath = r->oldPath ? xstrdup(r->oldPath) : NULL;
    00138             p->relocs[i].newPath = r->newPath ? xstrdup(r->newPath) : NULL;
    00139         }
    00140         p->relocs[i].oldPath = NULL;
    00141         p->relocs[i].newPath = NULL;
    00142     } else {
    00143         p->relocs = NULL;
    00144     }
    00145 }
    00146 /*@=bounds@*/
    00147
    00148 rpmte rpmteFree(rpmte te)
    00149 {
    00150     if (te != NULL) {
    00151         delTE(te);
    00152         memset(te, 0, sizeof(*te));     /* XXX trash and burn */
    00153         te = _free(te);
    00154     }
    00155     return NULL;
    00156 }
    00157
    00158 rpmte rpmteNew(const rpmts ts, Header h,
    00159                 rpmElementType type,
    00160                 fnpyKey key,
    00161                 rpmRelocation * relocs,
    00162                 int dboffset,
    00163                 alKey pkgKey)
    00164 {
    00165     rpmte te = xcalloc(1, sizeof(*te));
    00166
    00167     addTE(ts, te, h, key, relocs);
    00168     switch (type) {
    00169     case TR_ADDED:
    00170         te->type = type;
    00171         te->u.addedKey = pkgKey;
    00172         break;
    00173     case TR_REMOVED:
    00174         te->type = type;
    00175         te->u.removed.dependsOnKey = pkgKey;
    00176         te->u.removed.dboffset = dboffset;
    00177         break;
    00178     }
    00179     return te;
    00180 }
    00181
    00182 rpmElementType rpmteType(rpmte te)
    00183 {
    00184     return (te != NULL ? te->type : -1);
    00185 }
    00186
    00187 const char * rpmteN(rpmte te)
    00188 {
    00189     return (te != NULL ? te->name : NULL);
    00190 }
    00191
    00192 const char * rpmteE(rpmte te)
    00193 {
    00194     return (te != NULL ? te->epoch : NULL);
    00195 }
    00196
    00197 const char * rpmteV(rpmte te)
    00198 {
    00199     return (te != NULL ? te->version : NULL);
    00200 }
    00201
    00202 const char * rpmteR(rpmte te)
    00203 {
    00204     return (te != NULL ? te->release : NULL);
    00205 }
    00206
    00207 const char * rpmteA(rpmte te)
    00208 {
    00209     return (te != NULL ? te->arch : NULL);
    00210 }
    00211
    00212 const char * rpmteO(rpmte te)
    00213 {
    00214     return (te != NULL ? te->os : NULL);
    00215 }
    00216
    00217 int rpmteMultiLib(rpmte te)
    00218 {
    00219     return (te != NULL ? te->multiLib : 0);
    00220 }
    00221
    00222 int rpmteSetMultiLib(rpmte te, int nmultiLib)
    00223 {
    00224     int omultiLib = 0;
    00225     if (te != NULL) {
    00226         omultiLib = te->multiLib;
    00227         te->multiLib = nmultiLib;
    00228     }
    00229     return omultiLib;
    00230 }
    00231
    00232 int rpmteDepth(rpmte te)
    00233 {
    00234     return (te != NULL ? te->depth : 0);
    00235 }
    00236
    00237 int rpmteSetDepth(rpmte te, int ndepth)
    00238 {
    00239     int odepth = 0;
    00240     if (te != NULL) {
    00241         odepth = te->depth;
    00242         te->depth = ndepth;
    00243     }
    00244     return odepth;
    00245 }
    00246
    00247 int rpmteNpreds(rpmte te)
    00248 {
    00249     return (te != NULL ? te->npreds : 0);
    00250 }
    00251
    00252 int rpmteSetNpreds(rpmte te, int npreds)
    00253 {
    00254     int opreds = 0;
    00255     if (te != NULL) {
    00256         opreds = te->npreds;
    00257         te->npreds = npreds;
    00258     }
    00259     return opreds;
    00260 }
    00261
    00262 int rpmteTree(rpmte te)
    00263 {
    00264     return (te != NULL ? te->tree : 0);
    00265 }
    00266
    00267 int rpmteSetTree(rpmte te, int ntree)
    00268 {
    00269     int otree = 0;
    00270     if (te != NULL) {
    00271         otree = te->tree;
    00272         te->tree = ntree;
    00273     }
    00274     return otree;
    00275 }
    00276
    00277 rpmte rpmteParent(rpmte te)
    00278 {
    00279     return (te != NULL ? te->parent : NULL);
    00280 }
    00281
    00282 rpmte rpmteSetParent(rpmte te, rpmte pte)
    00283 {
    00284     rpmte opte = NULL;
    00285 /*@-branchstate@*/
    00286     if (te != NULL) {
    00287         opte = te->parent;
    00288         /*@-assignexpose -temptrans@*/
    00289         te->parent = pte;
    00290         /*@=assignexpose =temptrans@*/
    00291     }
    00292 /*@=branchstate@*/
    00293     return opte;
    00294 }
    00295
    00296 int rpmteDegree(rpmte te)
    00297 {
    00298     return (te != NULL ? te->degree : 0);
    00299 }
    00300
    00301 int rpmteSetDegree(rpmte te, int ndegree)
    00302 {
    00303     int odegree = 0;
    00304     if (te != NULL) {
    00305         odegree = te->degree;
    00306         te->degree = ndegree;
    00307     }
    00308     return odegree;
    00309 }
    00310
    00311 tsortInfo rpmteTSI(rpmte te)
    00312 {
    00313     /*@-compdef -retalias -retexpose -usereleased @*/
    00314     return te->tsi;
    00315     /*@=compdef =retalias =retexpose =usereleased @*/
    00316 }
    00317
    00318 void rpmteFreeTSI(rpmte te)
    00319 {
    00320     if (te != NULL && rpmteTSI(te) != NULL) {
    00321         tsortInfo tsi;
    00322
    00323         /* Clean up tsort remnants (if any). */
    00324         while ((tsi = rpmteTSI(te)->tsi_next) != NULL) {
    00325             rpmteTSI(te)->tsi_next = tsi->tsi_next;
    00326             tsi->tsi_next = NULL;
    00327             tsi = _free(tsi);
    00328         }
    00329         te->tsi = _free(te->tsi);
    00330     }
    00331     /*@-nullstate@*/ /* FIX: te->tsi is NULL */
    00332     return;
    00333     /*@=nullstate@*/
    00334 }
    00335
    00336 void rpmteNewTSI(rpmte te)
    00337 {
    00338     if (te != NULL) {
    00339         rpmteFreeTSI(te);
    00340         te->tsi = xcalloc(1, sizeof(*te->tsi));
    00341     }
    00342 }
    00343
    00344 alKey rpmteAddedKey(rpmte te)
    00345 {
    00346     return (te != NULL ? te->u.addedKey : RPMAL_NOMATCH);
    00347 }
    00348
    00349 alKey rpmteSetAddedKey(rpmte te, alKey npkgKey)
    00350 {
    00351     alKey opkgKey = RPMAL_NOMATCH;
    00352     if (te != NULL) {
    00353         opkgKey = te->u.addedKey;
    00354         te->u.addedKey = npkgKey;
    00355     }
    00356     return opkgKey;
    00357 }
    00358
    00359
    00360 alKey rpmteDependsOnKey(rpmte te)
    00361 {
    00362     return (te != NULL ? te->u.removed.dependsOnKey : RPMAL_NOMATCH);
    00363 }
    00364
    00365 int rpmteDBOffset(rpmte te)
    00366 {
    00367     return (te != NULL ? te->u.removed.dboffset : 0);
    00368 }
    00369
    00370 const char * rpmteNEVR(rpmte te)
    00371 {
    00372     return (te != NULL ? te->NEVR : NULL);
    00373 }
    00374
    00375 FD_t rpmteFd(rpmte te)
    00376 {
    00377     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
    00378     return (te != NULL ? te->fd : NULL);
    00379     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
    00380 }
    00381
    00382 fnpyKey rpmteKey(rpmte te)
    00383 {
    00384     return (te != NULL ? te->key : NULL);
    00385 }
    00386
    00387 rpmds rpmteDS(rpmte te, rpmTag tag)
    00388 {
    00389     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
    00390     if (te == NULL)
    00391         return NULL;
    00392
    00393     if (tag == RPMTAG_NAME)
    00394         return te->this;
    00395     else
    00396     if (tag == RPMTAG_PROVIDENAME)
    00397         return te->provides;
    00398     else
    00399     if (tag == RPMTAG_REQUIRENAME)
    00400         return te->requires;
    00401     else
    00402     if (tag == RPMTAG_CONFLICTNAME)
    00403         return te->conflicts;
    00404     else
    00405     if (tag == RPMTAG_OBSOLETENAME)
    00406         return te->obsoletes;
    00407     else
    00408         return NULL;
    00409     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
    00410 }
    00411
    00412 rpmfi rpmteFI(rpmte te, rpmTag tag)
    00413 {
    00414     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
    00415     if (te == NULL)
    00416         return NULL;
    00417
    00418     if (tag == RPMTAG_BASENAMES)
    00419         return te->fi;
    00420     else
    00421         return NULL;
    00422     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
    00423 }
    00424
    00425 int rpmtsiOc(rpmtsi tsi)
    00426 {
    00427     return tsi->ocsave;
    00428 }
    00429
    00430 rpmtsi XrpmtsiFree(/*@only@*//*@null@*/ rpmtsi tsi,
    00431                 const char * fn, unsigned int ln)
    00432 {
    00433     /* XXX watchout: a funky recursion segfaults here iff nrefs is wrong. */
    00434     if (tsi)
    00435         tsi->ts = rpmtsFree(tsi->ts);
    00436
    00437 /*@-modfilesys@*/
    00438 if (_rpmte_debug)
    00439 fprintf(stderr, "*** tsi %p -- %s:%d\n", tsi, fn, ln);
    00440 /*@=modfilesys@*/
    00441     return _free(tsi);
    00442 }
    00443
    00444 rpmtsi XrpmtsiInit(rpmts ts, const char * fn, unsigned int ln)
    00445 {
    00446     rpmtsi tsi = NULL;
    00447
    00448     tsi = xcalloc(1, sizeof(*tsi));
    00449     tsi->ts = rpmtsLink(ts, "rpmtsi");
    00450     tsi->reverse = ((rpmtsFlags(ts) & RPMTRANS_FLAG_REVERSE) ? 1 : 0);
    00451     tsi->oc = (tsi->reverse ? (rpmtsNElements(ts) - 1) : 0);
    00452     tsi->ocsave = tsi->oc;
    00453 /*@-modfilesys@*/
    00454 if (_rpmte_debug)
    00455 fprintf(stderr, "*** tsi %p ++ %s:%d\n", tsi, fn, ln);
    00456 /*@=modfilesys@*/
    00457     return tsi;
    00458 }
    00459
    00465 static /*@dependent@*/ /*@null@*/
    00466 rpmte rpmtsiNextElement(rpmtsi tsi)
    00467         /*@modifies tsi @*/
    00468 {
    00469     rpmte te = NULL;
    00470     int oc = -1;
    00471
    00472     if (tsi == NULL || tsi->ts == NULL || rpmtsNElements(tsi->ts) <= 0)
    00473         return te;
    00474
    00475     if (tsi->reverse) {
    00476         if (tsi->oc >= 0)               oc = tsi->oc--;
    00477     } else {
    00478         if (tsi->oc < rpmtsNElements(tsi->ts))  oc = tsi->oc++;
    00479     }
    00480     tsi->ocsave = oc;
    00481 /*@-branchstate@*/
    00482     if (oc != -1)
    00483         te = rpmtsElement(tsi->ts, oc);
    00484 /*@=branchstate@*/
    00485     return te;
    00486 }
    00487
    00488 rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
    00489 {
    00490     rpmte te;
    00491
    00492     while ((te = rpmtsiNextElement(tsi)) != NULL) {
    00493         if (type == 0 || (te->type & type) != 0)
    00494             break;
    00495     }
    00496     return te;
    00497 }