- kill SEARCH_EXTRA so we see where libzypp has to be changed
[platform/upstream/libsolv.git] / tools / dumpsolv.c
1 /*
2  * Copyright (c) 2007, Novell Inc.
3  *
4  * This program is licensed under the BSD license, read LICENSE.BSD
5  * for further information
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12
13 static int with_attr = 0;
14
15 #include "pool.h"
16 #include "repo_solv.h"
17
18 static int dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv);
19
20 static void
21 dump_repodata (Repo *repo)
22 {
23   unsigned i;
24   Repodata *data;
25   if (repo->nrepodata == 0)
26     return;
27   for (i = 0; i < 32; i++)
28     if (repo->rpmdbcookie[i])
29       break;
30   if (i < 32)
31     {
32       printf("rpmdb cookie: ");
33       for (i = 0; i < 32; i++)
34         printf("%02x", repo->rpmdbcookie[i]);
35       printf("\n");
36     }
37   printf("repo contains %d repodata sections:\n", repo->nrepodata);
38   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
39     {
40       unsigned int j;
41       printf("\nrepodata %d has %d keys, %d schemata\n", i + 1, data->nkeys - 1, data->nschemata - 1);
42       for (j = 1; j < data->nkeys; j++)
43         printf("  %s (type %s size %d storage %d)\n", id2str(repo->pool, data->keys[j].name), id2str(repo->pool, data->keys[j].type), data->keys[j].size, data->keys[j].storage);
44       if (data->localpool)
45         printf("  localpool has %d strings, size is %d\n", data->spool.nstrings, data->spool.sstrings);
46       if (data->dirpool.ndirs)
47         printf("  localpool has %d directories\n", data->dirpool.ndirs);
48       printf("\n");
49       repodata_search(data, REPOENTRY_META, 0, dump_repoattrs_cb, 0);
50     }
51   printf("\n");
52 }
53
54 static void
55 printids(Repo *repo, char *kind, Offset ido)
56 {
57   Pool *pool = repo->pool;
58   Id id, *ids;
59   if (!ido)
60     return;
61   printf("%s:\n", kind);
62   ids = repo->idarraydata + ido;
63   while((id = *ids++) != 0)
64     printf("  %s\n", dep2str(pool, id));
65 }
66
67 int
68 dump_attr(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
69 {
70   const char *keyname;
71   KeyValue *kvp;
72   int indent = 0;
73
74   keyname = id2str(repo->pool, key->name);
75   for (kvp = kv; (kvp = kvp->parent) != 0; indent += 2)
76     printf("  ");
77   switch(key->type)
78     {
79     case REPOKEY_TYPE_ID:
80       if (data && data->localpool)
81         kv->str = stringpool_id2str(&data->spool, kv->id);
82       else
83         kv->str = id2str(repo->pool, kv->id);
84       printf("%s: %s\n", keyname, kv->str);
85       break;
86     case REPOKEY_TYPE_CONSTANTID:
87       printf("%s: %s\n", keyname, dep2str(repo->pool, kv->id));
88       break;
89     case REPOKEY_TYPE_IDARRAY:
90       if (!kv->entry)
91         printf("%s:\n%*s", keyname, indent, "");
92       if (data && data->localpool)
93         printf("  %s\n", stringpool_id2str(&data->spool, kv->id));
94       else
95         printf("  %s\n", dep2str(repo->pool, kv->id));
96       break;
97     case REPOKEY_TYPE_STR:
98       printf("%s: %s\n", keyname, kv->str);
99       break;
100     case REPOKEY_TYPE_MD5:
101     case REPOKEY_TYPE_SHA1:
102     case REPOKEY_TYPE_SHA256:
103       printf("%s: %s (%s)\n", keyname, repodata_chk2str(data, key->type, (unsigned char *)kv->str), id2str(repo->pool, key->type));
104       break;
105     case REPOKEY_TYPE_VOID:
106       printf("%s: (void)\n", keyname);
107       break;
108     case REPOKEY_TYPE_U32:
109     case REPOKEY_TYPE_NUM:
110     case REPOKEY_TYPE_CONSTANT:
111       printf("%s: %d\n", keyname, kv->num);
112       break;
113     case REPOKEY_TYPE_DIRNUMNUMARRAY:
114       if (!kv->entry)
115         printf("%s:\n%*s", keyname, indent, "");
116       printf("  %s %d %d\n", repodata_dir2str(data, kv->id, 0), kv->num, kv->num2);
117       break;
118     case REPOKEY_TYPE_DIRSTRARRAY:
119       if (!kv->entry)
120         printf("%s:\n%*s", keyname, indent, "");
121       printf("  %s\n", repodata_dir2str(data, kv->id, kv->str));
122       break;
123     case REPOKEY_TYPE_FIXARRAY:
124     case REPOKEY_TYPE_FLEXARRAY:
125       if (!kv->entry)
126         printf("%s:\n", keyname);
127       else
128         printf("\n");
129       break;
130     default:
131       printf("%s: ?\n", keyname);
132       break;
133     }
134   return 0;
135 }
136
137 #if 1
138 static int
139 dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
140 {
141   if (key->name == REPOSITORY_SOLVABLES)
142     return SEARCH_NEXT_SOLVABLE;
143   return dump_attr(data->repo, data, key, kv);
144 }
145 #endif
146
147 /*
148  * dump all attributes for Id <p>
149  */
150
151 void
152 dump_repoattrs(Repo *repo, Id p)
153 {
154 #if 1
155   repo_search(repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE, dump_repoattrs_cb, 0);
156 #else
157   Dataiterator di;
158   dataiterator_init(&di, repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE);
159   while (dataiterator_step(&di))
160     dump_attr(repo, di.data, di.key, &di.kv);
161 #endif
162 }
163
164 #if 0
165 void
166 dump_some_attrs(Repo *repo, Solvable *s)
167 {
168   const char *summary = 0;
169   unsigned int medianr = -1, downloadsize = -1;
170   unsigned int time = -1;
171   summary = repo_lookup_str(s, SOLVABLE_SUMMARY);
172   medianr = repo_lookup_num(s, SOLVABLE_MEDIANR);
173   downloadsize = repo_lookup_num (s, SOLVABLE_DOWNLOADSIZE);
174   time = repo_lookup_num(s, SOLVABLE_BUILDTIME);
175   printf ("  XXX %d %d %u %s\n", medianr, downloadsize, time, summary);
176 }
177 #endif
178
179
180 static FILE *
181 loadcallback (Pool *pool, Repodata *data, void *vdata)
182 {
183   FILE *fp = 0;
184 printf("LOADCALLBACK\n");
185   const char *location = repodata_lookup_str(data, REPOENTRY_META, REPOSITORY_LOCATION);
186 printf("loc %s\n", location);
187   if (location && with_attr)
188     {
189       fprintf (stderr, "Loading SOLV file %s\n", location);
190       fp = fopen (location, "r");
191       if (!fp)
192         perror(location);
193     }
194   return fp;
195 }
196
197
198 static void
199 usage( const char *err )
200 {
201   if (err)
202     fprintf (stderr, "\n** Error:\n  %s\n", err);
203   fprintf( stderr, "\nUsage:\n"
204            "dumpsolv [-a] [<solvfile>]\n"
205            "  -a  read attributes.\n"
206            );
207   exit(0);
208 }
209
210 #if 0
211 static void
212 tryme (Repo *repo, Id p, Id keyname, const char *match, int flags)
213 {
214   Dataiterator di;
215   dataiterator_init(&di, repo, p, keyname, match, flags);
216   while (dataiterator_step(&di))
217     {
218       switch (di.key->type)
219         {
220           case REPOKEY_TYPE_ID:
221           case REPOKEY_TYPE_IDARRAY:
222               if (di.data && di.data->localpool)
223                 di.kv.str = stringpool_id2str(&di.data->spool, di.kv.id);
224               else
225                 di.kv.str = id2str(repo->pool, di.kv.id);
226               break;
227           case REPOKEY_TYPE_STR:
228           case REPOKEY_TYPE_DIRSTRARRAY:
229               break;
230           default:
231               di.kv.str = 0;
232         }
233       fprintf (stdout, "found: %d:%s %d %s %d %d %d\n",
234                di.solvid,
235                id2str(repo->pool, di.key->name),
236                di.kv.id,
237                di.kv.str, di.kv.num, di.kv.num2, di.kv.eof);
238     }
239 }
240 #endif
241
242 int main(int argc, char **argv)
243 {
244   Repo *repo;
245   Pool *pool;
246   int i, j, n;
247   Solvable *s;
248   
249   pool = pool_create();
250   pool_setdebuglevel(pool, 1);
251   pool_setloadcallback(pool, loadcallback, 0);
252
253   argv++;
254   argc--;
255   while (argc--)
256     {
257       const char *s = argv[0];
258       if (*s++ == '-')
259         while (*s)
260           switch (*s++)
261             {
262               case 'h': usage(NULL); break;
263               case 'a': with_attr = 1; break;
264               default : break;
265             }
266       else
267         {
268           if (freopen (argv[0], "r", stdin) == 0)
269             {
270               perror(argv[0]);
271               exit(1);
272             }
273           repo = repo_create(pool, argv[0]);
274           if (repo_add_solv(repo, stdin))
275             printf("could not read repository\n");
276         }
277       argv++;
278     }
279
280   if (!pool->nrepos)
281     {
282       repo = repo_create(pool, argc != 1 ? argv[1] : "<stdin>");
283       if (repo_add_solv(repo, stdin))
284         printf("could not read repository\n");
285     }
286   printf("pool contains %d strings, %d rels, string size is %d\n", pool->ss.nstrings, pool->nrels, pool->ss.sstrings);
287
288 #if 0
289 {
290   Dataiterator di;
291   dataiterator_init(&di, repo, -1, 0, "oo", DI_SEARCHSUB|SEARCH_SUBSTRING);
292   while (dataiterator_step(&di))
293     dump_attr(di.repo, di.data, di.key, &di.kv);
294   exit(0);
295 }
296 #endif
297
298   for (j = 0; 1 && j < pool->nrepos; j++)
299     {
300       repo = pool->repos[j];
301       dump_repodata(repo);
302
303       printf("repo %d contains %d solvables\n", j, repo->nsolvables);
304       printf("repo start: %d end: %d\n", repo->start, repo->end);
305       for (i = repo->start, n = 1; i < repo->end; i++)
306         {
307           s = pool->solvables + i;
308           if (s->repo != repo)
309             continue;
310           printf("\n");
311           printf("solvable %d (%d):\n", n, i);
312           if (s->name || s->evr || s->arch)
313             printf("name: %s %s %s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
314           if (s->vendor)
315             printf("vendor: %s\n", id2str(pool, s->vendor));
316           printids(repo, "provides", s->provides);
317           printids(repo, "obsoletes", s->obsoletes);
318           printids(repo, "conflicts", s->conflicts);
319           printids(repo, "requires", s->requires);
320           printids(repo, "recommends", s->recommends);
321           printids(repo, "suggests", s->suggests);
322           printids(repo, "supplements", s->supplements);
323           printids(repo, "enhances", s->enhances);
324           if (repo->rpmdbid)
325             printf("rpmdbid: %u\n", repo->rpmdbid[i - repo->start]);
326 #if 0
327           dump_attrs (repo, n - 1);
328 #endif
329           dump_repoattrs(repo, i);
330 #if 0
331           dump_some_attrs(repo, s);
332 #endif
333           n++;
334         }
335 #if 0
336       for (i = 0; i < repo->nextra; i++)
337         {
338           printf("\nextra %d:\n", i);
339           Dataiterator di;
340           dataiterator_init(&di, repo, -1 - i, 0, 0, SEARCH_EXTRA | SEARCH_NO_STORAGE_SOLVABLE);
341           while (dataiterator_step(&di))
342             dump_attr(repo, di.data, di.key, &di.kv);
343         }
344 #endif
345 #if 0
346       tryme(repo, 0, SOLVABLE_MEDIANR, 0, 0);
347       printf("\n");
348       tryme(repo, 0, 0, 0, 0);
349       printf("\n");
350       tryme(repo, 0, 0, "*y*e*", SEARCH_GLOB);
351 #endif
352     }
353 #if 0
354   printf ("\nSearchresults:\n");
355   Dataiterator di;
356   dataiterator_init(&di, pool->repos[0], 0, 0, "3", SEARCH_EXTRA | SEARCH_SUBSTRING | SEARCH_ALL_REPOS | SEARCH_FILES);
357   //int count = 0;
358   while (dataiterator_step(&di))
359     {
360       printf("%d:", di.solvid);
361       dump_attr(repo, di.data, di.key, &di.kv);
362       /*if (di.solvid == 4 && count++ == 0)
363         dataiterator_jump_to_solvable(&di, pool->solvables + 3);*/
364       //dataiterator_skip_attribute(&di);
365       //dataiterator_skip_solvable(&di);
366       //dataiterator_skip_repo(&di);
367     }
368 #endif
369   pool_free(pool);
370   exit(0);
371 }