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