Realize the remaining bits of direct rpmdb interface are dead too
[platform/upstream/rpm.git] / build / reqprov.c
1 /** \ingroup rpmbuild
2  * \file build/reqprov.c
3  *  Add dependency tags to package header(s).
4  */
5
6 #include "system.h"
7
8 #include <rpm/header.h>
9 #include <rpm/rpmbuild.h>
10 #include "debug.h"
11
12 static int isNewDep(Header h, rpmTag nametag,
13                   const char *N, const char *EVR, rpmsenseFlags Flags,
14                   rpmTag indextag, uint32_t index)
15 {
16     int new = 1;
17     struct rpmtd_s idx;
18     rpmds ads = rpmdsNew(h, nametag, 0);
19     rpmds bds = rpmdsSingle(nametag, N, EVR, Flags);
20
21     if (indextag) {
22         headerGet(h, indextag, &idx, HEADERGET_MINMEM);
23     }
24
25     /* XXX there's no guarantee the ds is sorted here so rpmdsFind() wont do */
26     rpmdsInit(ads);
27     while (new && rpmdsNext(ads) >= 0) {
28         if (!rstreq(rpmdsN(ads), rpmdsN(bds))) continue;
29         if (!rstreq(rpmdsEVR(ads), rpmdsEVR(bds))) continue;
30         if (rpmdsFlags(ads) != rpmdsFlags(bds)) continue;
31         if (indextag && rpmtdSetIndex(&idx, rpmdsIx(ads)) >= 0 &&
32                         rpmtdGetNumber(&idx) != index) continue;
33         new = 0;
34     }
35     
36     if (indextag) {
37         rpmtdFreeData(&idx);
38     }
39     rpmdsFree(ads);
40     rpmdsFree(bds);
41     return new;
42 }
43
44 int addReqProv(rpmSpec spec, Header h, rpmTag tagN,
45                 const char * N, const char * EVR, rpmsenseFlags Flags,
46                 uint32_t index)
47 {
48     rpmTag nametag = 0;
49     rpmTag versiontag = 0;
50     rpmTag flagtag = 0;
51     rpmTag indextag = 0;
52     rpmsenseFlags extra = RPMSENSE_ANY;
53     
54     if (Flags & RPMSENSE_PROVIDES) {
55         nametag = RPMTAG_PROVIDENAME;
56         versiontag = RPMTAG_PROVIDEVERSION;
57         flagtag = RPMTAG_PROVIDEFLAGS;
58         extra = Flags & RPMSENSE_FIND_PROVIDES;
59     } else if (Flags & RPMSENSE_OBSOLETES) {
60         nametag = RPMTAG_OBSOLETENAME;
61         versiontag = RPMTAG_OBSOLETEVERSION;
62         flagtag = RPMTAG_OBSOLETEFLAGS;
63     } else if (Flags & RPMSENSE_CONFLICTS) {
64         nametag = RPMTAG_CONFLICTNAME;
65         versiontag = RPMTAG_CONFLICTVERSION;
66         flagtag = RPMTAG_CONFLICTFLAGS;
67     } else if (Flags & RPMSENSE_PREREQ) {
68         nametag = RPMTAG_REQUIRENAME;
69         versiontag = RPMTAG_REQUIREVERSION;
70         flagtag = RPMTAG_REQUIREFLAGS;
71         extra = Flags & _ALL_REQUIRES_MASK;
72     } else if (Flags & RPMSENSE_TRIGGER) {
73         nametag = RPMTAG_TRIGGERNAME;
74         versiontag = RPMTAG_TRIGGERVERSION;
75         flagtag = RPMTAG_TRIGGERFLAGS;
76         indextag = RPMTAG_TRIGGERINDEX;
77         extra = Flags & RPMSENSE_TRIGGER;
78     } else {
79         nametag = RPMTAG_REQUIRENAME;
80         versiontag = RPMTAG_REQUIREVERSION;
81         flagtag = RPMTAG_REQUIREFLAGS;
82         extra = Flags & _ALL_REQUIRES_MASK;
83     }
84
85     Flags = (Flags & RPMSENSE_SENSEMASK) | extra;
86
87     if (EVR == NULL)
88         EVR = "";
89     
90     /* Avoid adding duplicate dependencies. */
91     if (isNewDep(h, nametag, N, EVR, Flags, indextag, index)) {
92         headerPutString(h, nametag, N);
93         headerPutString(h, versiontag, EVR);
94         headerPutUint32(h, flagtag, &Flags, 1);
95         if (indextag) {
96             headerPutUint32(h, indextag, &index, 1);
97         }
98     }
99
100     return 0;
101 }
102
103 int rpmlibNeedsFeature(Header h, const char * feature, const char * featureEVR)
104 {
105     char *reqname = NULL;
106     int res;
107
108     rasprintf(&reqname, "rpmlib(%s)", feature);
109
110     /* XXX 1st arg is unused */
111     res = addReqProv(NULL, h, RPMTAG_REQUIRENAME, reqname, featureEVR,
112                      RPMSENSE_RPMLIB|(RPMSENSE_LESS|RPMSENSE_EQUAL), 0);
113
114     free(reqname);
115
116     return res;
117 }