Imported Upstream version 0.6.13
[platform/upstream/libsolv.git] / examples / solv / fileprovides.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4
5 #include "pool.h"
6 #include "repo.h"
7
8 #include "repoinfo.h"
9 #include "repoinfo_cache.h"
10
11 #include "fileprovides.h"
12
13 static void
14 rewrite_repos(Pool *pool, Queue *addedfileprovides, Queue *addedfileprovides_inst)
15 {
16   Repo *repo;
17   Repodata *data;
18   Map providedids;
19   Queue fileprovidesq;
20   int i, j, n;
21   struct repoinfo *cinfo;
22
23   map_init(&providedids, pool->ss.nstrings);
24   queue_init(&fileprovidesq);
25   for (i = 0; i < addedfileprovides->count; i++)
26     MAPSET(&providedids, addedfileprovides->elements[i]);
27   FOR_REPOS(i, repo)
28     {
29       /* make sure all repodatas but the first are extensions */
30       if (repo->nrepodata < 2)
31         continue;
32       cinfo = repo->appdata;
33       if (!cinfo)
34         continue;       /* cmdline */
35       if (cinfo->incomplete)
36         continue;
37       data = repo_id2repodata(repo, 1);
38       if (data->loadcallback)
39         continue;
40       for (j = 2; j < repo->nrepodata; j++)
41         {
42           Repodata *edata = repo_id2repodata(repo, j);
43           if (!edata->loadcallback)
44             break;
45         }
46       if (j < repo->nrepodata)
47         continue;       /* found a non-extension repodata, can't rewrite  */
48       if (repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &fileprovidesq))
49         {
50           if (repo == pool->installed && addedfileprovides_inst)
51             {
52               for (j = 0; j < addedfileprovides->count; j++)
53                 MAPCLR(&providedids, addedfileprovides->elements[j]);
54               for (j = 0; j < addedfileprovides_inst->count; j++)
55                 MAPSET(&providedids, addedfileprovides_inst->elements[j]);
56             }
57           n = 0;
58           for (j = 0; j < fileprovidesq.count; j++)
59             if (MAPTST(&providedids, fileprovidesq.elements[j]))
60               n++;
61           if (repo == pool->installed && addedfileprovides_inst)
62             {
63               for (j = 0; j < addedfileprovides_inst->count; j++)
64                 MAPCLR(&providedids, addedfileprovides_inst->elements[j]);
65               for (j = 0; j < addedfileprovides->count; j++)
66                 MAPSET(&providedids, addedfileprovides->elements[j]);
67               if (n == addedfileprovides_inst->count)
68                 continue;       /* nothing new added */
69             }
70           else if (n == addedfileprovides->count)
71             continue;   /* nothing new added */
72         }
73       repodata_set_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, repo == pool->installed && addedfileprovides_inst ? addedfileprovides_inst : addedfileprovides);
74       repodata_internalize(data);
75       writecachedrepo(cinfo, 0, data);
76     }
77   queue_free(&fileprovidesq);
78   map_free(&providedids);
79 }
80
81 void
82 addfileprovides(Pool *pool)
83 {
84   Queue addedfileprovides;
85   Queue addedfileprovides_inst;
86
87   queue_init(&addedfileprovides);
88   queue_init(&addedfileprovides_inst);
89   pool_addfileprovides_queue(pool, &addedfileprovides, &addedfileprovides_inst);
90   if (addedfileprovides.count || addedfileprovides_inst.count)
91     rewrite_repos(pool, &addedfileprovides, &addedfileprovides_inst);
92   queue_free(&addedfileprovides);
93   queue_free(&addedfileprovides_inst);
94 }