summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/rpm/rpmresolve/rpmresolve.c
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/rpm/rpmresolve/rpmresolve.c')
-rw-r--r--meta/recipes-devtools/rpm/rpmresolve/rpmresolve.c273
1 files changed, 273 insertions, 0 deletions
diff --git a/meta/recipes-devtools/rpm/rpmresolve/rpmresolve.c b/meta/recipes-devtools/rpm/rpmresolve/rpmresolve.c
new file mode 100644
index 0000000000..9f6cdf28b8
--- /dev/null
+++ b/meta/recipes-devtools/rpm/rpmresolve/rpmresolve.c
@@ -0,0 +1,273 @@
1/* OpenEmbedded RPM resolver utility
2
3 Written by: Paul Eggleton <paul.eggleton@linux.intel.com>
4
5 Copyright 2012 Intel Corporation
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20*/
21
22#include <ctype.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <unistd.h>
26#include <fcntl.h>
27#include <sys/stat.h>
28
29#include <rpmdb.h>
30#include <rpmtypes.h>
31#include <rpmtag.h>
32#include <rpmts.h>
33#include <rpmmacro.h>
34#include <rpmcb.h>
35#include <rpmlog.h>
36#include <argv.h>
37#include <mire.h>
38
39int getPackageStr(rpmts ts, const char *NVRA, rpmTag tag, char **value)
40{
41 int rc = -1;
42 rpmmi mi = rpmtsInitIterator(ts, RPMTAG_NVRA, NVRA, 0);
43 Header h;
44 if ((h = rpmmiNext(mi)) != NULL) {
45 HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
46 he->tag = tag;
47 rc = (headerGet(h, he, 0) != 1);
48 if(rc==0)
49 *value = strdup((char *)he->p.ptr);
50 }
51 (void)rpmmiFree(mi);
52 return rc;
53}
54
55int loadTs(rpmts **ts, int *tsct, const char *dblistfn)
56{
57 int count = 0;
58 int sz = 5;
59 int rc = 0;
60 int listfile = 1;
61 struct stat st_buf;
62
63 rc = stat(dblistfn, &st_buf);
64 if(rc != 0) {
65 perror("stat");
66 return 1;
67 }
68 if(S_ISDIR(st_buf.st_mode))
69 listfile = 0;
70
71 if(listfile) {
72 *ts = malloc(sz * sizeof(rpmts));
73 FILE *f = fopen(dblistfn, "r" );
74 if(f) {
75 char line[2048];
76 while(fgets(line, sizeof(line), f)) {
77 int len = strlen(line) - 1;
78 if(len > 0)
79 // Trim trailing whitespace
80 while(len > 0 && isspace(line[len]))
81 line[len--] = '\0';
82
83 if(len > 0) {
84 // Expand array if needed
85 if(count == sz) {
86 sz += 5;
87 *ts = (rpmts *)realloc(*ts, sz);
88 }
89
90 char *dbpathm = malloc(strlen(line) + 10);
91 sprintf(dbpathm, "_dbpath %s", line);
92 rpmDefineMacro(NULL, dbpathm, RMIL_CMDLINE);
93 free(dbpathm);
94
95 rpmts tsi = rpmtsCreate();
96 (*ts)[count] = tsi;
97 rc = rpmtsOpenDB(tsi, O_RDONLY);
98 if( rc ) {
99 fprintf(stderr, "Failed to open database %s\n", line);
100 rc = -1;
101 break;
102 }
103
104 count++;
105 }
106 }
107 fclose(f);
108 *tsct = count;
109 }
110 else {
111 perror(dblistfn);
112 rc = -1;
113 }
114 }
115 else {
116 // Load from single database
117 *ts = malloc(sizeof(rpmts));
118 char *dbpathm = malloc(strlen(dblistfn) + 10);
119 sprintf(dbpathm, "_dbpath %s", dblistfn);
120 rpmDefineMacro(NULL, dbpathm, RMIL_CMDLINE);
121 free(dbpathm);
122
123 rpmts tsi = rpmtsCreate();
124 (*ts)[0] = tsi;
125 rc = rpmtsOpenDB(tsi, O_RDONLY);
126 if( rc ) {
127 fprintf(stderr, "Failed to open database %s\n", dblistfn);
128 rc = -1;
129 }
130 *tsct = 1;
131 }
132
133 return rc;
134}
135
136int processPackages(rpmts *ts, int tscount, const char *packagelistfn, int ignoremissing)
137{
138 int rc = 0;
139 int count = 0;
140 int sz = 100;
141 int i = 0;
142 int missing = 0;
143
144 FILE *f = fopen(packagelistfn, "r" );
145 if(f) {
146 char line[255];
147 while(fgets(line, sizeof(line), f)) {
148 int len = strlen(line) - 1;
149 if(len > 0)
150 // Trim trailing whitespace
151 while(len > 0 && isspace(line[len]))
152 line[len--] = '\0';
153
154 if(len > 0) {
155 int found = 0;
156 for(i=0; i<tscount; i++) {
157 ARGV_t keys = NULL;
158 rpmdb db = rpmtsGetRdb(ts[i]);
159 rc = rpmdbMireApply(db, RPMTAG_NAME,
160 RPMMIRE_STRCMP, line, &keys);
161 if (keys) {
162 int nkeys = argvCount(keys);
163 if( nkeys == 1 ) {
164 char *value = NULL;
165 rc = getPackageStr(ts[i], keys[0], RPMTAG_PACKAGEORIGIN, &value);
166 if(rc == 0)
167 printf("%s\n", value);
168 else
169 fprintf(stderr, "Failed to get package origin for %s\n", line);
170 found = 1;
171 }
172 else if( nkeys > 1 ) {
173 fprintf(stderr, "Multiple matches for %s!\n", line);
174 }
175 }
176 if(found)
177 break;
178 }
179
180 if( !found ) {
181 if( ignoremissing ) {
182 fprintf(stderr, "unable to find package %s - ignoring\n", line);
183 }
184 else {
185 fprintf(stderr, "unable to find package %s\n", line);
186 missing = 1;
187 }
188 }
189 }
190 count++;
191 }
192 fclose(f);
193
194 if( missing ) {
195 fprintf(stderr, "ERROR: some packages were missing\n");
196 rc = 1;
197 }
198 }
199 else {
200 perror(packagelistfn);
201 rc = -1;
202 }
203
204 return rc;
205}
206
207void usage()
208{
209 fprintf(stderr, "OpenEmbedded rpm resolver utility\n");
210 fprintf(stderr, "syntax: rpmresolve [-i] <dblistfile> <packagelistfile>\n");
211}
212
213int main(int argc, char **argv)
214{
215 rpmts *ts = NULL;
216 int tscount = 0;
217 int rc = 0;
218 int i;
219 int c;
220 int ignoremissing = 0;
221
222 opterr = 0;
223 while ((c = getopt (argc, argv, "i")) != -1) {
224 switch (c) {
225 case 'i':
226 ignoremissing = 1;
227 break;
228 case '?':
229 if(isprint(optopt))
230 fprintf(stderr, "Unknown option `-%c'.\n", optopt);
231 else
232 fprintf(stderr, "Unknown option character `\\x%x'.\n",
233 optopt);
234 usage();
235 return 1;
236 default:
237 abort();
238 }
239 }
240
241 if( argc - optind < 1 ) {
242 usage();
243 return 1;
244 }
245
246 const char *dblistfn = argv[optind];
247
248 //rpmSetVerbosity(RPMLOG_DEBUG);
249
250 rpmReadConfigFiles( NULL, NULL );
251 rpmDefineMacro(NULL, "__dbi_txn create nofsync", RMIL_CMDLINE);
252
253 rc = loadTs(&ts, &tscount, dblistfn);
254 if( rc )
255 return 1;
256 if( tscount == 0 ) {
257 fprintf(stderr, "Please specify database list file or database location\n");
258 return 1;
259 }
260
261 if( argc - optind < 2 ) {
262 fprintf(stderr, "Please specify package list file\n");
263 return 1;
264 }
265 const char *pkglistfn = argv[optind+1];
266 rc = processPackages(ts, tscount, pkglistfn, ignoremissing);
267
268 for(i=0; i<tscount; i++)
269 (void) rpmtsCloseDB(ts[i]);
270 free(ts);
271
272 return rc;
273}