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 rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
00089         /*@modifies ts, p, h,
00090                 rpmGlobalMacroContext, fileSystem, internalState @*/
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     /* Set db_instance to 0 as it has not been installed
00109      * necessarily yet.
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 /*@-branchstate@*/
00150     if (ep) {
00151         p->epoch = xmalloc(20);
00152         sprintf(p->epoch, "%d", *ep);
00153     } else
00154         p->epoch = NULL;
00155 /*@=branchstate@*/
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 /*@-compdef@*/
00194     return;
00195 /*@=compdef@*/
00196 }
00197 /*@=bounds@*/
00198 
00199 rpmte rpmteFree(rpmte te)
00200 {
00201     if (te != NULL) {
00202         delTE(te);
00203         memset(te, 0, sizeof(*te));     /* XXX trash and burn */
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         /* XXX 256 is only an estimate of signature header. */
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 /* Get the DB Instance value */
00240 unsigned int rpmteDBInstance(rpmte te) 
00241 {
00242     return (te != NULL ? te->db_instance : 0);
00243 }
00244 
00245 /* Set the DB Instance value */
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 /*@-branchstate@*/
00396     if (te != NULL) {
00397         opte = te->parent;
00398         /*@-assignexpose -temptrans@*/
00399         te->parent = pte;
00400         /*@=assignexpose =temptrans@*/
00401     }
00402 /*@=branchstate@*/
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     /*@-compdef -retalias -retexpose -usereleased @*/
00424     return te->tsi;
00425     /*@=compdef =retalias =retexpose =usereleased @*/
00426 }
00427 
00428 void rpmteFreeTSI(rpmte te)
00429 {
00430     if (te != NULL && rpmteTSI(te) != NULL) {
00431         tsortInfo tsi;
00432 
00433         /* Clean up tsort remnants (if any). */
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     /*@-nullstate@*/ /* FIX: te->tsi is NULL */
00442     return;
00443     /*@=nullstate@*/
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     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
00493     return (te != NULL ? te->fd : NULL);
00494     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
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     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
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     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
00525 }
00526 
00527 rpmfi rpmteFI(rpmte te, rpmTag tag)
00528 {
00529     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
00530     if (te == NULL)
00531         return NULL;
00532 
00533     if (tag == RPMTAG_BASENAMES)
00534         return te->fi;
00535     else
00536         return NULL;
00537     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
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         /*@notreached@*/ 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     /* Calculate dependency color and reference count. */
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                 /*@innercontinue@*/ continue;
00588             ix &= 0x00ffffff;
00589 assert (ix < Count);
00590             colors[ix] |= val;
00591             refs[ix]++;
00592         }
00593     }
00594 
00595     /* Set color/refs values in dependency set. */
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(/*@only@*//*@null@*/ rpmtsi tsi,
00614                 const char * fn, unsigned int ln)
00615 {
00616     /* XXX watchout: a funky recursion segfaults here iff nrefs is wrong. */
00617 /*@-internalglobs@*/
00618     if (tsi)
00619         tsi->ts = rpmtsFree(tsi->ts);
00620 /*@=internalglobs@*/
00621 
00622 /*@-modfilesys@*/
00623 if (_rpmte_debug)
00624 fprintf(stderr, "*** tsi %p -- %s:%d\n", tsi, fn, ln);
00625 /*@=modfilesys@*/
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 /*@-modfilesys@*/
00639 if (_rpmte_debug)
00640 fprintf(stderr, "*** tsi %p ++ %s:%d\n", tsi, fn, ln);
00641 /*@=modfilesys@*/
00642     return tsi;
00643 }
00644 
00650 static /*@null@*/ /*@dependent@*/
00651 rpmte rpmtsiNextElement(rpmtsi tsi)
00652         /*@modifies tsi @*/
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 /*@-branchstate@*/
00667     if (oc != -1)
00668         te = rpmtsElement(tsi->ts, oc);
00669 /*@=branchstate@*/
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 }

Generated on Fri Oct 12 08:44:54 2007 for rpm by  doxygen 1.5.2