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

lib/rpmds.c

Go to the documentation of this file.
00001 
00004 #include "system.h"
00005 
00006 #include <rpmlib.h>
00007 
00008 #define _RPMDS_INTERNAL
00009 #include "rpmds.h"
00010 
00011 #include "debug.h"
00012 
00016 /*@unchecked@*/
00017 static int _noisy_range_comparison_debug_message = 0;
00018 
00019 /*@unchecked@*/
00020 int _rpmds_debug = 0;
00021 
00022 /*@unchecked@*/
00023 int _rpmds_nopromote = 1;
00024 
00025 /*@unchecked@*/
00026 /*@-exportheadervar@*/
00027 int _rpmds_unspecified_epoch_noise = 0;
00028 /*@=exportheadervar@*/
00029 
00030 rpmds XrpmdsUnlink(rpmds ds, const char * msg, const char * fn, unsigned ln)
00031 {
00032     if (ds == NULL) return NULL;
00033 /*@-modfilesys@*/
00034 if (_rpmds_debug && msg != NULL)
00035 fprintf(stderr, "--> ds %p -- %d %s at %s:%u\n", ds, ds->nrefs, msg, fn, ln);
00036 /*@=modfilesys@*/
00037     ds->nrefs--;
00038     return NULL;
00039 }
00040 
00041 rpmds XrpmdsLink(rpmds ds, const char * msg, const char * fn, unsigned ln)
00042 {
00043     if (ds == NULL) return NULL;
00044     ds->nrefs++;
00045 
00046 /*@-modfilesys@*/
00047 if (_rpmds_debug && msg != NULL)
00048 fprintf(stderr, "--> ds %p ++ %d %s at %s:%u\n", ds, ds->nrefs, msg, fn, ln);
00049 /*@=modfilesys@*/
00050 
00051     /*@-refcounttrans@*/ return ds; /*@=refcounttrans@*/
00052 }
00053 
00054 rpmds rpmdsFree(rpmds ds)
00055 {
00056     HFD_t hfd = headerFreeData;
00057     rpmTag tagEVR, tagF;
00058 
00059     if (ds == NULL)
00060         return NULL;
00061 
00062     if (ds->nrefs > 1)
00063         return rpmdsUnlink(ds, ds->Type);
00064 
00065 /*@-modfilesys@*/
00066 if (_rpmds_debug < 0)
00067 fprintf(stderr, "*** ds %p\t%s[%d]\n", ds, ds->Type, ds->Count);
00068 /*@=modfilesys@*/
00069 
00070     if (ds->tagN == RPMTAG_PROVIDENAME) {
00071         tagEVR = RPMTAG_PROVIDEVERSION;
00072         tagF = RPMTAG_PROVIDEFLAGS;
00073     } else
00074     if (ds->tagN == RPMTAG_REQUIRENAME) {
00075         tagEVR = RPMTAG_REQUIREVERSION;
00076         tagF = RPMTAG_REQUIREFLAGS;
00077     } else
00078     if (ds->tagN == RPMTAG_CONFLICTNAME) {
00079         tagEVR = RPMTAG_CONFLICTVERSION;
00080         tagF = RPMTAG_CONFLICTFLAGS;
00081     } else
00082     if (ds->tagN == RPMTAG_OBSOLETENAME) {
00083         tagEVR = RPMTAG_OBSOLETEVERSION;
00084         tagF = RPMTAG_OBSOLETEFLAGS;
00085     } else
00086     if (ds->tagN == RPMTAG_TRIGGERNAME) {
00087         tagEVR = RPMTAG_TRIGGERVERSION;
00088         tagF = RPMTAG_TRIGGERFLAGS;
00089     } else
00090         return NULL;
00091 
00092     /*@-branchstate@*/
00093     if (ds->Count > 0) {
00094         ds->N = hfd(ds->N, ds->Nt);
00095         ds->EVR = hfd(ds->EVR, ds->EVRt);
00096         /*@-evalorder@*/
00097         ds->Flags = (ds->h != NULL ? hfd(ds->Flags, ds->Ft) : _free(ds->Flags));
00098         /*@=evalorder@*/
00099         ds->h = headerFree(ds->h);
00100     }
00101     /*@=branchstate@*/
00102 
00103     ds->DNEVR = _free(ds->DNEVR);
00104 
00105     (void) rpmdsUnlink(ds, ds->Type);
00106     /*@-refcounttrans -usereleased@*/
00107 /*@-boundswrite@*/
00108     memset(ds, 0, sizeof(*ds));         /* XXX trash and burn */
00109 /*@=boundswrite@*/
00110     ds = _free(ds);
00111     /*@=refcounttrans =usereleased@*/
00112     return NULL;
00113 }
00114 
00115 rpmds rpmdsNew(Header h, rpmTag tagN, int scareMem)
00116 {
00117     HGE_t hge =
00118         (scareMem ? (HGE_t) headerGetEntryMinMemory : (HGE_t) headerGetEntry);
00119     rpmTag tagEVR, tagF;
00120     rpmds ds = NULL;
00121     const char * Type;
00122     const char ** N;
00123     rpmTagType Nt;
00124     int_32 Count;
00125 
00126     if (tagN == RPMTAG_PROVIDENAME) {
00127         Type = "Provides";
00128         tagEVR = RPMTAG_PROVIDEVERSION;
00129         tagF = RPMTAG_PROVIDEFLAGS;
00130     } else
00131     if (tagN == RPMTAG_REQUIRENAME) {
00132         Type = "Requires";
00133         tagEVR = RPMTAG_REQUIREVERSION;
00134         tagF = RPMTAG_REQUIREFLAGS;
00135     } else
00136     if (tagN == RPMTAG_CONFLICTNAME) {
00137         Type = "Conflicts";
00138         tagEVR = RPMTAG_CONFLICTVERSION;
00139         tagF = RPMTAG_CONFLICTFLAGS;
00140     } else
00141     if (tagN == RPMTAG_OBSOLETENAME) {
00142         Type = "Obsoletes";
00143         tagEVR = RPMTAG_OBSOLETEVERSION;
00144         tagF = RPMTAG_OBSOLETEFLAGS;
00145     } else
00146     if (tagN == RPMTAG_TRIGGERNAME) {
00147         Type = "Trigger";
00148         tagEVR = RPMTAG_TRIGGERVERSION;
00149         tagF = RPMTAG_TRIGGERFLAGS;
00150     } else
00151         goto exit;
00152 
00153     /*@-branchstate@*/
00154     if (hge(h, tagN, &Nt, (void **) &N, &Count)
00155      && N != NULL && Count > 0)
00156     {
00157         int xx;
00158 
00159         ds = xcalloc(1, sizeof(*ds));
00160         ds->Type = Type;
00161         ds->h = (scareMem ? headerLink(h) : NULL);
00162         ds->i = -1;
00163         ds->DNEVR = NULL;
00164         ds->tagN = tagN;
00165         ds->N = N;
00166         ds->Nt = Nt;
00167         ds->Count = Count;
00168         ds->nopromote = 0;
00169 
00170         xx = hge(h, tagEVR, &ds->EVRt, (void **) &ds->EVR, NULL);
00171         xx = hge(h, tagF, &ds->Ft, (void **) &ds->Flags, NULL);
00172 /*@-boundsread@*/
00173         if (!scareMem && ds->Flags != NULL)
00174             ds->Flags = memcpy(xmalloc(ds->Count * sizeof(*ds->Flags)),
00175                                 ds->Flags, ds->Count * sizeof(*ds->Flags));
00176 /*@=boundsread@*/
00177 
00178 /*@-modfilesys@*/
00179 if (_rpmds_debug < 0)
00180 fprintf(stderr, "*** ds %p\t%s[%d]\n", ds, ds->Type, ds->Count);
00181 /*@=modfilesys@*/
00182 
00183     }
00184     /*@=branchstate@*/
00185 
00186 exit:
00187     /*@-nullstate@*/ /* FIX: ds->Flags may be NULL */
00188     return rpmdsLink(ds, (ds ? ds->Type : NULL));
00189     /*@=nullstate@*/
00190 }
00191 
00192 char * rpmdsNewDNEVR(const char * dspfx, const rpmds ds)
00193 {
00194     char * tbuf, * t;
00195     size_t nb;
00196 
00197     nb = 0;
00198     if (dspfx)  nb += strlen(dspfx) + 1;
00199 /*@-boundsread@*/
00200     if (ds->N[ds->i])   nb += strlen(ds->N[ds->i]);
00201     if (ds->Flags[ds->i] & RPMSENSE_SENSEMASK) {
00202         if (nb) nb++;
00203         if (ds->Flags[ds->i] & RPMSENSE_LESS)   nb++;
00204         if (ds->Flags[ds->i] & RPMSENSE_GREATER) nb++;
00205         if (ds->Flags[ds->i] & RPMSENSE_EQUAL)  nb++;
00206     }
00207     if (ds->EVR[ds->i] && *ds->EVR[ds->i]) {
00208         if (nb) nb++;
00209         nb += strlen(ds->EVR[ds->i]);
00210     }
00211 /*@=boundsread@*/
00212 
00213 /*@-boundswrite@*/
00214     t = tbuf = xmalloc(nb + 1);
00215     if (dspfx) {
00216         t = stpcpy(t, dspfx);
00217         *t++ = ' ';
00218     }
00219     if (ds->N[ds->i])
00220         t = stpcpy(t, ds->N[ds->i]);
00221     if (ds->Flags[ds->i] & RPMSENSE_SENSEMASK) {
00222         if (t != tbuf)  *t++ = ' ';
00223         if (ds->Flags[ds->i] & RPMSENSE_LESS)   *t++ = '<';
00224         if (ds->Flags[ds->i] & RPMSENSE_GREATER) *t++ = '>';
00225         if (ds->Flags[ds->i] & RPMSENSE_EQUAL)  *t++ = '=';
00226     }
00227     if (ds->EVR[ds->i] && *ds->EVR[ds->i]) {
00228         if (t != tbuf)  *t++ = ' ';
00229         t = stpcpy(t, ds->EVR[ds->i]);
00230     }
00231     *t = '\0';
00232 /*@=boundswrite@*/
00233     return tbuf;
00234 }
00235 
00236 rpmds rpmdsThis(Header h, rpmTag tagN, int_32 Flags)
00237 {
00238     HGE_t hge = (HGE_t) headerGetEntryMinMemory;
00239     rpmds ds = NULL;
00240     const char * Type;
00241     const char * n, * v, * r;
00242     int_32 * ep;
00243     const char ** N, ** EVR;
00244     char * t;
00245     int xx;
00246 
00247     if (tagN == RPMTAG_PROVIDENAME) {
00248         Type = "Provides";
00249     } else
00250     if (tagN == RPMTAG_REQUIRENAME) {
00251         Type = "Requires";
00252     } else
00253     if (tagN == RPMTAG_CONFLICTNAME) {
00254         Type = "Conflicts";
00255     } else
00256     if (tagN == RPMTAG_OBSOLETENAME) {
00257         Type = "Obsoletes";
00258     } else
00259     if (tagN == RPMTAG_TRIGGERNAME) {
00260         Type = "Trigger";
00261     } else
00262         goto exit;
00263 
00264     xx = headerNVR(h, &n, &v, &r);
00265     ep = NULL;
00266     xx = hge(h, RPMTAG_EPOCH, NULL, (void **)&ep, NULL);
00267 
00268     t = xmalloc(sizeof(*N) + strlen(n) + 1);
00269 /*@-boundswrite@*/
00270     N = (const char **) t;
00271     t += sizeof(*N);
00272     N[0] = t;
00273     t = stpcpy(t, n);
00274 
00275     t = xmalloc(sizeof(*EVR) +
00276                 (ep ? 20 : 0) + strlen(v) + strlen(r) + sizeof("-"));
00277     EVR = (const char **) t;
00278     t += sizeof(*EVR);
00279     EVR[0] = t;
00280     if (ep) {
00281         sprintf(t, "%d:", *ep);
00282 /*@-compdef@*/
00283         t += strlen(t);
00284 /*@=compdef@*/
00285     }
00286     t = stpcpy( stpcpy( stpcpy( t, v), "-"), r);
00287 /*@=boundswrite@*/
00288 
00289     ds = xcalloc(1, sizeof(*ds));
00290     ds->h = NULL;
00291     ds->Type = Type;
00292     ds->tagN = tagN;
00293     ds->Count = 1;
00294     ds->N = N;
00295     ds->Nt = -1;        /* XXX to insure that hfd will free */
00296     ds->EVR = EVR;
00297     ds->EVRt = -1;      /* XXX to insure that hfd will free */
00298 /*@-boundswrite@*/
00299     ds->Flags = xmalloc(sizeof(*ds->Flags));    ds->Flags[0] = Flags;
00300 /*@=boundswrite@*/
00301     ds->i = 0;
00302     {   char pre[2];
00303 /*@-boundsread@*/
00304         pre[0] = ds->Type[0];
00305 /*@=boundsread@*/
00306         pre[1] = '\0';
00307         /*@-nullstate@*/ /* LCL: ds->Type may be NULL ??? */
00308         ds->DNEVR = rpmdsNewDNEVR(pre, ds);
00309         /*@=nullstate@*/
00310     }
00311 
00312 exit:
00313     return rpmdsLink(ds, (ds ? ds->Type : NULL));
00314 }
00315 
00316 rpmds rpmdsSingle(rpmTag tagN, const char * N, const char * EVR, int_32 Flags)
00317 {
00318     rpmds ds = NULL;
00319     const char * Type;
00320 
00321     if (tagN == RPMTAG_PROVIDENAME) {
00322         Type = "Provides";
00323     } else
00324     if (tagN == RPMTAG_REQUIRENAME) {
00325         Type = "Requires";
00326     } else
00327     if (tagN == RPMTAG_CONFLICTNAME) {
00328         Type = "Conflicts";
00329     } else
00330     if (tagN == RPMTAG_OBSOLETENAME) {
00331         Type = "Obsoletes";
00332     } else
00333     if (tagN == RPMTAG_TRIGGERNAME) {
00334         Type = "Trigger";
00335     } else
00336         goto exit;
00337 
00338     ds = xcalloc(1, sizeof(*ds));
00339     ds->h = NULL;
00340     ds->Type = Type;
00341     ds->tagN = tagN;
00342     ds->Count = 1;
00343     /*@-assignexpose@*/
00344 /*@-boundswrite@*/
00345     ds->N = xmalloc(sizeof(*ds->N));            ds->N[0] = N;
00346     ds->Nt = -1;        /* XXX to insure that hfd will free */
00347     ds->EVR = xmalloc(sizeof(*ds->EVR));        ds->EVR[0] = EVR;
00348     ds->EVRt = -1;      /* XXX to insure that hfd will free */
00349     /*@=assignexpose@*/
00350     ds->Flags = xmalloc(sizeof(*ds->Flags));    ds->Flags[0] = Flags;
00351 /*@=boundswrite@*/
00352     ds->i = 0;
00353     {   char t[2];
00354 /*@-boundsread@*/
00355         t[0] = ds->Type[0];
00356 /*@=boundsread@*/
00357         t[1] = '\0';
00358         ds->DNEVR = rpmdsNewDNEVR(t, ds);
00359     }
00360 
00361 exit:
00362     return rpmdsLink(ds, (ds ? ds->Type : NULL));
00363 }
00364 
00365 int rpmdsCount(const rpmds ds)
00366 {
00367     return (ds != NULL ? ds->Count : 0);
00368 }
00369 
00370 int rpmdsIx(const rpmds ds)
00371 {
00372     return (ds != NULL ? ds->i : -1);
00373 }
00374 
00375 int rpmdsSetIx(rpmds ds, int ix)
00376 {
00377     int i = -1;
00378 
00379     if (ds != NULL) {
00380         i = ds->i;
00381         ds->i = ix;
00382     }
00383     return i;
00384 }
00385 
00386 const char * rpmdsDNEVR(const rpmds ds)
00387 {
00388     const char * DNEVR = NULL;
00389 
00390     if (ds != NULL && ds->i >= 0 && ds->i < ds->Count) {
00391 /*@-boundsread@*/
00392         if (ds->DNEVR != NULL)
00393             DNEVR = ds->DNEVR;
00394 /*@=boundsread@*/
00395     }
00396     return DNEVR;
00397 }
00398 
00399 const char * rpmdsN(const rpmds ds)
00400 {
00401     const char * N = NULL;
00402 
00403     if (ds != NULL && ds->i >= 0 && ds->i < ds->Count) {
00404 /*@-boundsread@*/
00405         if (ds->N != NULL)
00406             N = ds->N[ds->i];
00407 /*@=boundsread@*/
00408     }
00409     return N;
00410 }
00411 
00412 const char * rpmdsEVR(const rpmds ds)
00413 {
00414     const char * EVR = NULL;
00415 
00416     if (ds != NULL && ds->i >= 0 && ds->i < ds->Count) {
00417 /*@-boundsread@*/
00418         if (ds->EVR != NULL)
00419             EVR = ds->EVR[ds->i];
00420 /*@=boundsread@*/
00421     }
00422     return EVR;
00423 }
00424 
00425 int_32 rpmdsFlags(const rpmds ds)
00426 {
00427     int_32 Flags = 0;
00428 
00429     if (ds != NULL && ds->i >= 0 && ds->i < ds->Count) {
00430 /*@-boundsread@*/
00431         if (ds->Flags != NULL)
00432             Flags = ds->Flags[ds->i];
00433 /*@=boundsread@*/
00434     }
00435     return Flags;
00436 }
00437 
00438 rpmTag rpmdsTagN(const rpmds ds)
00439 {
00440     rpmTag tagN = 0;
00441 
00442     if (ds != NULL && ds->i >= 0 && ds->i < ds->Count) {
00443         tagN = ds->tagN;
00444     }
00445     return tagN;
00446 }
00447 
00448 int rpmdsNoPromote(const rpmds ds)
00449 {
00450     int nopromote = 0;
00451 
00452     if (ds != NULL)
00453         nopromote = ds->nopromote;
00454     return nopromote;
00455 }
00456 
00457 int rpmdsSetNoPromote(rpmds ds, int nopromote)
00458 {
00459     int onopromote = 0;
00460 
00461     if (ds != NULL) {
00462         onopromote = ds->nopromote;
00463         ds->nopromote = nopromote;
00464     }
00465     return onopromote;
00466 }
00467 
00468 void rpmdsNotify(rpmds ds, const char * where, int rc)
00469 {
00470     if (!(ds != NULL && ds->i >= 0 && ds->i < ds->Count))
00471         return;
00472     if (!(ds->Type != NULL && ds->DNEVR != NULL))
00473         return;
00474 
00475     rpmMessage(RPMMESS_DEBUG, "%9s: %-45s %-s %s\n", ds->Type,
00476                 (!strcmp(ds->DNEVR, "cached") ? ds->DNEVR : ds->DNEVR+2),
00477                 (rc ? _("NO ") : _("YES")),
00478                 (where != NULL ? where : ""));
00479 }
00480 
00481 int rpmdsNext(/*@null@*/ rpmds ds)
00482         /*@modifies ds @*/
00483 {
00484     int i = -1;
00485 
00486     if (ds != NULL && ++ds->i >= 0) {
00487         if (ds->i < ds->Count) {
00488             char t[2];
00489             i = ds->i;
00490             ds->DNEVR = _free(ds->DNEVR);
00491             t[0] = ((ds->Type != NULL) ? ds->Type[0] : '\0');
00492             t[1] = '\0';
00493             /*@-nullstate@*/
00494             ds->DNEVR = rpmdsNewDNEVR(t, ds);
00495             /*@=nullstate@*/
00496 
00497         } else
00498             ds->i = -1;
00499 
00500 /*@-modfilesys @*/
00501 if (_rpmds_debug  < 0 && i != -1)
00502 fprintf(stderr, "*** ds %p\t%s[%d]: %s\n", ds, (ds->Type ? ds->Type : "?Type?"), i, (ds->DNEVR ? ds->DNEVR : "?DNEVR?"));
00503 /*@=modfilesys @*/
00504 
00505     }
00506 
00507     return i;
00508 }
00509 
00510 rpmds rpmdsInit(/*@null@*/ rpmds ds)
00511         /*@modifies ds @*/
00512 {
00513     if (ds != NULL)
00514         ds->i = -1;
00515     /*@-refcounttrans@*/
00516     return ds;
00517     /*@=refcounttrans@*/
00518 }
00519 
00527 static
00528 void parseEVR(char * evr,
00529                 /*@exposed@*/ /*@out@*/ const char ** ep,
00530                 /*@exposed@*/ /*@out@*/ const char ** vp,
00531                 /*@exposed@*/ /*@out@*/ const char ** rp)
00532         /*@modifies *ep, *vp, *rp @*/
00533 {
00534     const char *epoch;
00535     const char *version;                /* assume only version is present */
00536     const char *release;
00537     char *s, *se;
00538 
00539     s = evr;
00540 /*@-boundsread@*/
00541     while (*s && xisdigit(*s)) s++;     /* s points to epoch terminator */
00542     se = strrchr(s, '-');               /* se points to version terminator */
00543 
00544     if (*s == ':') {
00545         epoch = evr;
00546         *s++ = '\0';
00547         version = s;
00548         /*@-branchstate@*/
00549         if (*epoch == '\0') epoch = "0";
00550         /*@=branchstate@*/
00551     } else {
00552         epoch = NULL;   /* XXX disable epoch compare if missing */
00553         version = evr;
00554     }
00555 /*@=boundsread@*/
00556     if (se) {
00557 /*@-boundswrite@*/
00558         *se++ = '\0';
00559 /*@=boundswrite@*/
00560         release = se;
00561     } else {
00562         release = NULL;
00563     }
00564 
00565 /*@-boundswrite@*/
00566     if (ep) *ep = epoch;
00567     if (vp) *vp = version;
00568     if (rp) *rp = release;
00569 /*@=boundswrite@*/
00570 }
00571 
00572 int rpmdsCompare(const rpmds A, const rpmds B)
00573 {
00574     const char *aDepend = (A->DNEVR != NULL ? xstrdup(A->DNEVR+2) : "");
00575     const char *bDepend = (B->DNEVR != NULL ? xstrdup(B->DNEVR+2) : "");
00576     char *aEVR, *bEVR;
00577     const char *aE, *aV, *aR, *bE, *bV, *bR;
00578     int result;
00579     int sense;
00580 
00581 /*@-boundsread@*/
00582     /* Different names don't overlap. */
00583     if (strcmp(A->N[A->i], B->N[B->i])) {
00584         result = 0;
00585         goto exit;
00586     }
00587 
00588     /* Same name. If either A or B is an existence test, always overlap. */
00589     if (!((A->Flags[A->i] & RPMSENSE_SENSEMASK) && (B->Flags[B->i] & RPMSENSE_SENSEMASK))) {
00590         result = 1;
00591         goto exit;
00592     }
00593 
00594     /* If either EVR is non-existent or empty, always overlap. */
00595     if (!(A->EVR[A->i] && *A->EVR[A->i] && B->EVR[B->i] && *B->EVR[B->i])) {
00596         result = 1;
00597         goto exit;
00598     }
00599 
00600     /* Both AEVR and BEVR exist. */
00601     aEVR = xstrdup(A->EVR[A->i]);
00602     parseEVR(aEVR, &aE, &aV, &aR);
00603     bEVR = xstrdup(B->EVR[B->i]);
00604     parseEVR(bEVR, &bE, &bV, &bR);
00605 
00606     /* Compare {A,B} [epoch:]version[-release] */
00607     sense = 0;
00608     if (aE && *aE && bE && *bE)
00609         sense = rpmvercmp(aE, bE);
00610     else if (aE && *aE && atol(aE) > 0) {
00611         if (!B->nopromote) {
00612             int lvl = (_rpmds_unspecified_epoch_noise  ? RPMMESS_WARNING : RPMMESS_DEBUG);
00613             rpmMessage(lvl, _("The \"B\" dependency needs an epoch (assuming same epoch as \"A\")\n\tA = \"%s\"\tB = \"%s\"\n"),
00614                 aDepend, bDepend);
00615             sense = 0;
00616         } else
00617             sense = 1;
00618     } else if (bE && *bE && atol(bE) > 0)
00619         sense = -1;
00620 
00621     if (sense == 0) {
00622         sense = rpmvercmp(aV, bV);
00623         if (sense == 0 && aR && *aR && bR && *bR) {
00624             sense = rpmvercmp(aR, bR);
00625         }
00626     }
00627 /*@=boundsread@*/
00628     aEVR = _free(aEVR);
00629     bEVR = _free(bEVR);
00630 
00631     /* Detect overlap of {A,B} range. */
00632     result = 0;
00633     if (sense < 0 && ((A->Flags[A->i] & RPMSENSE_GREATER) || (B->Flags[B->i] & RPMSENSE_LESS))) {
00634         result = 1;
00635     } else if (sense > 0 && ((A->Flags[A->i] & RPMSENSE_LESS) || (B->Flags[B->i] & RPMSENSE_GREATER))) {
00636         result = 1;
00637     } else if (sense == 0 &&
00638         (((A->Flags[A->i] & RPMSENSE_EQUAL) && (B->Flags[B->i] & RPMSENSE_EQUAL)) ||
00639          ((A->Flags[A->i] & RPMSENSE_LESS) && (B->Flags[B->i] & RPMSENSE_LESS)) ||
00640          ((A->Flags[A->i] & RPMSENSE_GREATER) && (B->Flags[B->i] & RPMSENSE_GREATER)))) {
00641         result = 1;
00642     }
00643 
00644 exit:
00645     if (_noisy_range_comparison_debug_message)
00646     rpmMessage(RPMMESS_DEBUG, _("  %s    A %s\tB %s\n"),
00647         (result ? _("YES") : _("NO ")), aDepend, bDepend);
00648     aDepend = _free(aDepend);
00649     bDepend = _free(bDepend);
00650     return result;
00651 }
00652 
00653 void rpmdsProblem(rpmps ps, const char * pkgNEVR, const rpmds ds,
00654         const fnpyKey * suggestedKeys, int adding)
00655 {
00656     const char * Name =  rpmdsN(ds);
00657     const char * DNEVR = rpmdsDNEVR(ds);
00658     const char * EVR = rpmdsEVR(ds);
00659     rpmProblemType type;
00660     fnpyKey key;
00661 
00662     if (ps == NULL) return;
00663 
00664     /*@-branchstate@*/
00665     if (Name == NULL) Name = "?N?";
00666     if (EVR == NULL) EVR = "?EVR?";
00667     if (DNEVR == NULL) DNEVR = "? ?N? ?OP? ?EVR?";
00668     /*@=branchstate@*/
00669 
00670     rpmMessage(RPMMESS_DEBUG, _("package %s has unsatisfied %s: %s\n"),
00671             pkgNEVR, ds->Type, DNEVR+2);
00672 
00673     switch ((unsigned)DNEVR[0]) {
00674     case 'C':   type = RPMPROB_CONFLICT;        break;
00675     default:
00676     case 'R':   type = RPMPROB_REQUIRES;        break;
00677     }
00678 
00679     key = (suggestedKeys ? suggestedKeys[0] : NULL);
00680     rpmpsAppend(ps, type, pkgNEVR, key, NULL, NULL, DNEVR, adding);
00681 }
00682 
00683 int rpmdsAnyMatchesDep (const Header h, const rpmds req, int nopromote)
00684 {
00685     int scareMem = 1;
00686     rpmds provides = NULL;
00687     int result = 0;
00688 
00689 /*@-boundsread@*/
00690     if (!(req->Flags[req->i] & RPMSENSE_SENSEMASK) || !req->EVR[req->i] || *req->EVR[req->i] == '\0')
00691         return 1;
00692 /*@=boundsread@*/
00693 
00694     /* Get provides information from header */
00695     provides = rpmdsInit(rpmdsNew(h, RPMTAG_PROVIDENAME, scareMem));
00696     if (provides == NULL)
00697         goto exit;      /* XXX should never happen */
00698     if (nopromote)
00699         (void) rpmdsSetNoPromote(provides, nopromote);
00700 
00701     /*
00702      * Rpm prior to 3.0.3 did not have versioned provides.
00703      * If no provides version info is available, match any/all requires
00704      * with same name.
00705      */
00706     if (provides->EVR == NULL) {
00707         result = 1;
00708         goto exit;
00709     }
00710 
00711     result = 0;
00712     if (provides != NULL)
00713     while (rpmdsNext(provides) >= 0) {
00714 
00715         /* Filter out provides that came along for the ride. */
00716 /*@-boundsread@*/
00717         if (strcmp(provides->N[provides->i], req->N[req->i]))
00718             continue;
00719 /*@=boundsread@*/
00720 
00721         result = rpmdsCompare(provides, req);
00722 
00723         /* If this provide matches the require, we're done. */
00724         if (result)
00725             break;
00726     }
00727 
00728 exit:
00729     provides = rpmdsFree(provides);
00730 
00731     return result;
00732 }
00733 
00734 int rpmdsNVRMatchesDep(const Header h, const rpmds req, int nopromote)
00735 {
00736     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00737     const char * pkgN, * v, * r;
00738     int_32 * epoch;
00739     const char * pkgEVR;
00740     char * t;
00741     int_32 pkgFlags = RPMSENSE_EQUAL;
00742     rpmds pkg;
00743     int rc = 1; /* XXX assume match, names already match here */
00744 
00745 /*@-boundsread@*/
00746     if (!((req->Flags[req->i] & RPMSENSE_SENSEMASK) && req->EVR[req->i] && *req->EVR[req->i]))
00747         return rc;
00748 /*@=boundsread@*/
00749 
00750     /* Get package information from header */
00751     (void) headerNVR(h, &pkgN, &v, &r);
00752 
00753 /*@-boundswrite@*/
00754     t = alloca(21 + strlen(v) + 1 + strlen(r) + 1);
00755     pkgEVR = t;
00756     *t = '\0';
00757     if (hge(h, RPMTAG_EPOCH, NULL, (void **) &epoch, NULL)) {
00758         sprintf(t, "%d:", *epoch);
00759         while (*t != '\0')
00760             t++;
00761     }
00762     (void) stpcpy( stpcpy( stpcpy(t, v) , "-") , r);
00763 /*@=boundswrite@*/
00764 
00765     if ((pkg = rpmdsSingle(RPMTAG_PROVIDENAME, pkgN, pkgEVR, pkgFlags)) != NULL) {
00766         if (nopromote)
00767             (void) rpmdsSetNoPromote(pkg, nopromote);
00768         rc = rpmdsCompare(pkg, req);
00769         pkg = rpmdsFree(pkg);
00770     }
00771 
00772     return rc;
00773 }

Generated on Wed Sep 4 12:49:52 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002