rpm 5.3.12
build/reqprov.c
Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 
00008 #include <rpmio.h>
00009 #include <rpmiotypes.h>
00010 #define _RPMEVR_INTERNAL
00011 #include "rpmbuild.h"
00012 #include "debug.h"
00013 
00014 int addReqProv(/*@unused@*/ Spec spec, Header h,
00015                 /*@unused@*/ rpmTag tagN,
00016                 const char * N, const char * EVR, rpmsenseFlags Flags,
00017                 rpmuint32_t index)
00018 {
00019     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00020     const char ** names;
00021     rpmTag nametag = 0;
00022     rpmTag versiontag = 0;
00023     rpmTag flagtag = 0;
00024     rpmTag indextag = 0;
00025     int len;
00026     rpmsenseFlags extra = RPMSENSE_ANY;
00027     int xx;
00028 
00029     if (Flags & RPMSENSE_PROVIDES) {
00030         nametag = RPMTAG_PROVIDENAME;
00031         versiontag = RPMTAG_PROVIDEVERSION;
00032         flagtag = RPMTAG_PROVIDEFLAGS;
00033         extra = Flags & RPMSENSE_FIND_PROVIDES;
00034     } else if (Flags & RPMSENSE_OBSOLETES) {
00035         nametag = RPMTAG_OBSOLETENAME;
00036         versiontag = RPMTAG_OBSOLETEVERSION;
00037         flagtag = RPMTAG_OBSOLETEFLAGS;
00038     } else if (Flags & RPMSENSE_CONFLICTS) {
00039         nametag = RPMTAG_CONFLICTNAME;
00040         versiontag = RPMTAG_CONFLICTVERSION;
00041         flagtag = RPMTAG_CONFLICTFLAGS;
00042     } else if (Flags & RPMSENSE_TRIGGER) {
00043         nametag = RPMTAG_TRIGGERNAME;
00044         versiontag = RPMTAG_TRIGGERVERSION;
00045         flagtag = RPMTAG_TRIGGERFLAGS;
00046         indextag = RPMTAG_TRIGGERINDEX;
00047         extra = Flags & RPMSENSE_TRIGGER;
00048     } else {
00049         nametag = RPMTAG_REQUIRENAME;
00050         versiontag = RPMTAG_REQUIREVERSION;
00051         flagtag = RPMTAG_REQUIREFLAGS;
00052         extra = Flags & _ALL_REQUIRES_MASK;
00053     }
00054 
00055     Flags = (Flags & RPMSENSE_SENSEMASK) | extra;
00056 
00057     if (EVR == NULL)
00058         EVR = "";
00059 #if defined(RPM_VENDOR_MANDRIVA)
00060     /* Check that provide isn't duplicate of package */
00061     else if (nametag == RPMTAG_PROVIDENAME) {
00062         const char *NEVR;
00063         size_t len;
00064         int duplicate;
00065 
00066         len = strlen(N);
00067         NEVR = headerSprintf(h, "%{NAME}-%|EPOCH?{%{EPOCH}:}|%{VERSION}-%{RELEASE}", NULL, NULL, NULL);
00068         duplicate = !strncmp(NEVR, N, len) && !strcmp(NEVR+len+1, EVR);
00069 
00070         _free(NEVR);
00071 
00072         if (duplicate)
00073             return 0;
00074     }
00075 #endif
00076 
00077     /* Check for duplicate dependencies. */
00078     he->tag = nametag;
00079     xx = headerGet(h, he, 0);
00080     names = he->p.argv;
00081     len = he->c;
00082     if (xx) {
00083         const char ** versions = NULL;
00084         rpmuint32_t * flags = NULL;
00085         rpmuint32_t * indexes = NULL;
00086         int duplicate = 0;
00087 
00088         if (flagtag) {
00089             he->tag = versiontag;
00090             xx = headerGet(h, he, 0);
00091             versions = he->p.argv;
00092             he->tag = flagtag;
00093             xx = headerGet(h, he, 0);
00094             flags = he->p.ui32p;
00095         }
00096         if (indextag) {
00097             he->tag = indextag;
00098             xx = headerGet(h, he, 0);
00099             indexes = he->p.ui32p;
00100         }
00101 
00102         while (len > 0) {
00103             len--;
00104             if (strcmp(names[len], N))
00105                 continue;
00106 
00107 #if defined(RPM_VENDOR_MANDRIVA) /* filter-overlapping-dependencies */
00108             /* XXX: Potential drawbacks? Need to study & discuess this one a
00109              * bit further, leaving under #ifdef for now...
00110              * TODO: auto-generated deps too
00111              */
00112             if (flagtag && versions != NULL && rpmExpandNumeric("%{?_use_internal_dependency_generator}")) {
00113                 int overlap;
00114 
00115                 if(*EVR && !*versions[len]) {
00116                     overlap = 1;
00117                     flags[len] = Flags;
00118                     he->tag = flagtag;
00119                     he->t = RPM_UINT32_TYPE;
00120                     he->p.argv = (void *) &Flags;
00121                     xx = headerMod(h, he, 0);
00122                 } else {
00123                     EVR_t lEVR = rpmEVRnew(RPMSENSE_ANY, 0),
00124                           rEVR = rpmEVRnew(RPMSENSE_ANY, 0);
00125 
00126                     rpmEVRparse(EVR, lEVR);
00127                     rpmEVRparse(versions[len], rEVR);
00128                     lEVR->Flags = Flags | RPMSENSE_EQUAL;
00129                     rEVR->Flags = flags[len] | RPMSENSE_EQUAL;
00130                     overlap = rpmEVRoverlap(lEVR, rEVR);
00131                     if (!overlap)
00132                         if (rpmEVRoverlap(rEVR, lEVR))
00133                             duplicate = 1;
00134                     lEVR = rpmEVRfree(lEVR);
00135                     rEVR = rpmEVRfree(rEVR);
00136                 }
00137                 if (overlap) {
00138                     versions[len] = EVR;
00139                     he->tag = versiontag;
00140                     he->t = RPM_STRING_ARRAY_TYPE;
00141                     he->p.argv = versions;
00142                     xx = headerMod(h, he, 0);
00143                 } else
00144                     continue;
00145             } else
00146 #else
00147             if (flagtag && versions != NULL &&
00148                 (strcmp(versions[len], EVR) || (rpmsenseFlags)flags[len] != Flags))
00149                 continue;
00150 #endif
00151 
00152             if (indextag && indexes != NULL && indexes[len] != index)
00153                 continue;
00154 
00155             /* This is a duplicate dependency. */
00156             duplicate = 1;
00157 
00158             break;
00159         }
00160 /*@-usereleased@*/
00161         names = _free(names);
00162         versions = _free(versions);
00163         flags = _free(flags);
00164         indexes = _free(indexes);
00165 /*@=usereleased@*/
00166         if (duplicate)
00167             return 0;
00168     }
00169 
00170     /* Add this dependency. */
00171     he->tag = nametag;
00172     he->t = RPM_STRING_ARRAY_TYPE;
00173     he->p.argv = &N;
00174     he->c = 1;
00175     he->append = 1;
00176     xx = headerPut(h, he, 0);
00177     he->append = 0;
00178 
00179     if (flagtag) {
00180         he->tag = versiontag;
00181         he->t = RPM_STRING_ARRAY_TYPE;
00182         he->p.argv = &EVR;
00183         he->c = 1;
00184         he->append = 1;
00185         xx = headerPut(h, he, 0);
00186         he->append = 0;
00187 
00188         he->tag = flagtag;
00189         he->t = RPM_UINT32_TYPE;
00190         he->p.ui32p = (void *) &Flags;
00191         he->c = 1;
00192         he->append = 1;
00193         xx = headerPut(h, he, 0);
00194         he->append = 0;
00195     }
00196     if (indextag) {
00197         he->tag = indextag;
00198         he->t = RPM_UINT32_TYPE;
00199         he->p.ui32p = &index;
00200         he->c = 1;
00201         he->append = 1;
00202         xx = headerPut(h, he, 0);
00203         he->append = 0;
00204     }
00205 
00206     return 0;
00207 }
00208 
00209 int rpmlibNeedsFeature(Header h, const char * feature, const char * featureEVR)
00210 {
00211     char * reqname = alloca(sizeof("rpmlib()") + strlen(feature));
00212 
00213     (void) stpcpy( stpcpy( stpcpy(reqname, "rpmlib("), feature), ")");
00214 
00215     /* XXX 1st arg is unused */
00216    return addReqProv(NULL, h, RPMTAG_REQUIRENAME, reqname, featureEVR,
00217         RPMSENSE_RPMLIB|(RPMSENSE_LESS|RPMSENSE_EQUAL), 0);
00218 }