rpm  5.4.15
reqprov.c
Go to the documentation of this file.
1 
6 #include "system.h"
7 
8 #include <rpmio.h>
9 #include <rpmiotypes.h>
10 #define _RPMEVR_INTERNAL
11 #include "rpmbuild.h"
12 #include "debug.h"
13 
14 int addReqProv(/*@unused@*/ Spec spec, Header h,
15  /*@unused@*/ rpmTag tagN,
16  const char * N, const char * EVR, rpmsenseFlags Flags,
17  rpmuint32_t index)
18 {
19  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
20  const char ** names;
21  rpmTag nametag = 0;
22  rpmTag versiontag = 0;
23  rpmTag flagtag = 0;
24  rpmTag indextag = 0;
25  int len;
26  rpmsenseFlags extra = RPMSENSE_ANY;
27  int xx;
28 
29  if (Flags & RPMSENSE_PROVIDES) {
30  nametag = RPMTAG_PROVIDENAME;
31  versiontag = RPMTAG_PROVIDEVERSION;
32  flagtag = RPMTAG_PROVIDEFLAGS;
33  extra = Flags & RPMSENSE_FIND_PROVIDES;
34  } else if (Flags & RPMSENSE_OBSOLETES) {
35  nametag = RPMTAG_OBSOLETENAME;
36  versiontag = RPMTAG_OBSOLETEVERSION;
37  flagtag = RPMTAG_OBSOLETEFLAGS;
38  } else if (Flags & RPMSENSE_CONFLICTS) {
39  nametag = RPMTAG_CONFLICTNAME;
40  versiontag = RPMTAG_CONFLICTVERSION;
41  flagtag = RPMTAG_CONFLICTFLAGS;
42  } else if (Flags & RPMSENSE_TRIGGER) {
43  nametag = RPMTAG_TRIGGERNAME;
44  versiontag = RPMTAG_TRIGGERVERSION;
45  flagtag = RPMTAG_TRIGGERFLAGS;
46  indextag = RPMTAG_TRIGGERINDEX;
47  extra = Flags & RPMSENSE_TRIGGER;
48  } else {
49  nametag = RPMTAG_REQUIRENAME;
50  versiontag = RPMTAG_REQUIREVERSION;
51  flagtag = RPMTAG_REQUIREFLAGS;
52  extra = Flags & _ALL_REQUIRES_MASK;
53  }
54 
55  Flags = (Flags & RPMSENSE_SENSEMASK) | extra;
56 
57  if (EVR == NULL)
58  EVR = "";
59 #if defined(RPM_VENDOR_MANDRIVA)
60  /* Check that provide isn't duplicate of package */
61  else if (nametag == RPMTAG_PROVIDENAME) {
62  const char *NEVR;
63  size_t len;
64  int duplicate;
65 
66  len = strlen(N);
67  NEVR = headerSprintf(h, "%{NAME}-%|EPOCH?{%{EPOCH}:}|%{VERSION}-%{RELEASE}", NULL, NULL, NULL);
68  duplicate = !strncmp(NEVR, N, len) && !strcmp(NEVR+len+1, EVR);
69 
70  _free(NEVR);
71 
72  if (duplicate)
73  return 0;
74  }
75 #endif
76 
77  /* Check for duplicate dependencies. */
78  he->tag = nametag;
79  xx = headerGet(h, he, 0);
80  names = he->p.argv;
81  len = he->c;
82  if (xx) {
83  const char ** versions = NULL;
84  rpmuint32_t * flags = NULL;
85  rpmuint32_t * indexes = NULL;
86  int duplicate = 0;
87 
88  if (flagtag) {
89  he->tag = versiontag;
90  xx = headerGet(h, he, 0);
91  versions = he->p.argv;
92  he->tag = flagtag;
93  xx = headerGet(h, he, 0);
94  flags = he->p.ui32p;
95  }
96  if (indextag) {
97  he->tag = indextag;
98  xx = headerGet(h, he, 0);
99  indexes = he->p.ui32p;
100  }
101 
102  while (len > 0) {
103  len--;
104  if (strcmp(names[len], N))
105  continue;
106 
107 #if defined(RPM_VENDOR_MANDRIVA) /* filter-overlapping-dependencies */
108  /* XXX: Potential drawbacks? Need to study & discuess this one a
109  * bit further, leaving under #ifdef for now...
110  * TODO: auto-generated deps too
111  */
112  if (Flags & RPMSENSE_TRIGGER)
113  continue;
114 
115  if (flagtag && versions != NULL) {
116  int overlap;
117 
118  if(*EVR && !*versions[len]) {
119  overlap = 1;
120  flags[len] = Flags;
121  he->tag = flagtag;
122  he->t = RPM_UINT32_TYPE;
123  he->p.argv = (void *) &Flags;
124  xx = headerMod(h, he, 0);
125  } else {
126  EVR_t lEVR = rpmEVRnew(RPMSENSE_ANY, 0),
127  rEVR = rpmEVRnew(RPMSENSE_ANY, 0);
128 
129  rpmEVRparse(EVR, lEVR);
130  rpmEVRparse(versions[len], rEVR);
131  lEVR->Flags = Flags | RPMSENSE_EQUAL;
132  rEVR->Flags = flags[len] | RPMSENSE_EQUAL;
133  overlap = rpmEVRoverlap(lEVR, rEVR);
134  if (!overlap)
135  if (rpmEVRoverlap(rEVR, lEVR))
136  duplicate = 1;
137  lEVR = rpmEVRfree(lEVR);
138  rEVR = rpmEVRfree(rEVR);
139  }
140  if (overlap) {
141  versions[len] = EVR;
142  he->tag = versiontag;
143  he->t = RPM_STRING_ARRAY_TYPE;
144  he->p.argv = versions;
145  xx = headerMod(h, he, 0);
146  } else
147  continue;
148  }
149 #else
150  if (flagtag && versions != NULL &&
151  (strcmp(versions[len], EVR) || (rpmsenseFlags)flags[len] != Flags))
152  continue;
153 #endif
154 
155  if (indextag && indexes != NULL && indexes[len] != index)
156  continue;
157 
158  /* This is a duplicate dependency. */
159  duplicate = 1;
160 
161  break;
162  }
163 /*@-usereleased@*/
164  names = _free(names);
165  versions = _free(versions);
166  flags = _free(flags);
167  indexes = _free(indexes);
168 /*@=usereleased@*/
169  if (duplicate)
170  return 0;
171  }
172 
173  /* Add this dependency. */
174  he->tag = nametag;
175  he->t = RPM_STRING_ARRAY_TYPE;
176  he->p.argv = &N;
177  he->c = 1;
178  he->append = 1;
179  xx = headerPut(h, he, 0);
180  he->append = 0;
181 
182  if (flagtag) {
183  he->tag = versiontag;
184  he->t = RPM_STRING_ARRAY_TYPE;
185  he->p.argv = &EVR;
186  he->c = 1;
187  he->append = 1;
188  xx = headerPut(h, he, 0);
189  he->append = 0;
190 
191  he->tag = flagtag;
192  he->t = RPM_UINT32_TYPE;
193  he->p.ui32p = (void *) &Flags;
194  he->c = 1;
195  he->append = 1;
196  xx = headerPut(h, he, 0);
197  he->append = 0;
198  }
199  if (indextag) {
200  he->tag = indextag;
201  he->t = RPM_UINT32_TYPE;
202  he->p.ui32p = &index;
203  he->c = 1;
204  he->append = 1;
205  xx = headerPut(h, he, 0);
206  he->append = 0;
207  }
208 
209  return 0;
210 }
211 
212 int rpmlibNeedsFeature(Header h, const char * feature, const char * featureEVR)
213 {
214  char * reqname = alloca(sizeof("rpmlib()") + strlen(feature));
215 
216  (void) stpcpy( stpcpy( stpcpy(reqname, "rpmlib("), feature), ")");
217 
218  /* XXX 1st arg is unused */
219  return addReqProv(NULL, h, RPMTAG_REQUIRENAME, reqname, featureEVR,
220  RPMSENSE_RPMLIB|(RPMSENSE_LESS|RPMSENSE_EQUAL), 0);
221 }
rpmTagType t
Definition: rpmtag.h:504
rpmTag tag
Definition: rpmtag.h:503
const char ** argv
Definition: rpmtag.h:75
const char const char size_t len
Definition: bson.h:823
#define RPMSENSE_SENSEMASK
Definition: rpmevr.h:76
rpmuint32_t * ui32p
Definition: rpmtag.h:70
int headerGet(Header h, HE_t he, unsigned int flags)
Retrieve extension or tag value from a header.
Definition: header.c:2231
int headerPut(Header h, HE_t he, unsigned int flags)
Add or append tag container to header.
Definition: header.c:2294
int addReqProv(Spec spec, Header h, rpmTag tagN, const char *N, const char *EVR, rpmsenseFlags Flags, rpmuint32_t index)
Add dependency to header, filtering duplicates.
Definition: reqprov.c:14
The Header data structure.
int rpmEVRparse(const char *evrstr, EVR_t evr)
Split EVR string into epoch, version, and release components.
Definition: rpmevr.c:181
struct EVR_s * EVR_t
Definition: rpmevr.h:22
char * headerSprintf(Header h, const char *fmt, headerTagTableEntry tags, headerSprintfExtension exts, errmsg_t *errmsg)
Return formatted output string from header tags.
Definition: hdrfmt.c:6730
char * alloca()
int headerMod(Header h, HE_t he, unsigned int flags)
Modify tag container in header.
Definition: header.c:2319
unsigned int rpmuint32_t
Definition: rpmiotypes.h:28
struct _HE_s * HE_t
Definition: rpmtag.h:59
enum evrFlags_e rpmsenseFlags
Definition: rpmevr.h:74
rpmTagData p
Definition: rpmtag.h:506
rpmTagCount c
Definition: rpmtag.h:507
The structure used to store values parsed from a spec file.
Definition: rpmspec.h:113
const char const bson int mongo_write_concern int flags
Definition: mongo.h:485
EVR_t rpmEVRnew(uint32_t Flags, int initialize)
Create a new EVR container.
Definition: rpmevr.c:31
Definition: rpmtag.h:502
EVR_t rpmEVRfree(EVR_t evr)
Destroy an EVR container.
Definition: rpmevr.c:47
This is the only module users of librpmbuild should need to include.
int rpmEVRoverlap(EVR_t a, EVR_t b)
Compare EVR containers for overlap.
Definition: rpmevr.c:339
char * stpcpy(char *dest, const char *src)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
enum rpmTag_e rpmTag
Definition: rpmtag.h:470
int rpmlibNeedsFeature(Header h, const char *feature, const char *featureEVR)
Add rpmlib feature dependency.
Definition: reqprov.c:212
unsigned int append
Definition: rpmtag.h:511