split ugly pubkey handling into separate repo_rpmdb_pubkey.c
[platform/upstream/libsolv.git] / tools / rpmdb2solv.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 /*
9  * rpmdb2solv
10  * 
11  * Reads rpm database (and evtl. more, like product metadata) to build
12  * a .solv file of 'installed' solvables.
13  * Writes .solv to stdout
14  * 
15  */
16
17 #include <sys/types.h>
18 #include <limits.h>
19 #include <fcntl.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #include "pool.h"
26 #include "repo.h"
27 #include "repo_rpmdb.h"
28 #ifdef ENABLE_RPMDB_PUBKEY
29 #include "repo_rpmdb_pubkey.h"
30 #endif
31 #include "repo_products.h"
32 #include "repo_solv.h"
33 #include "common_write.h"
34
35 static void
36 usage(int status)
37 {
38   fprintf(stderr, "\nUsage:\n"
39           "rpmdb2solv [-n] [-x] [-b <basefile>] [-p <productsdir>] [-r <root>]\n"
40           " -n : No packages, do not read rpmdb, useful to only parse products\n"
41           " -x : use extrapool\n"
42           " -b <basefile> : Write .solv to <basefile>.solv instead of stdout\n"
43           " -p <productsdir> : Scan <productsdir> for .prod files, representing installed products\n"
44           " -r <root> : Prefix rpmdb path and <productsdir> with <root>\n"
45           " -o <solv> : Write .solv to file instead of stdout\n"
46          );
47   exit(status);
48 }
49
50
51 int
52 main(int argc, char **argv)
53 {
54   Pool *pool = pool_create();
55   Repo *repo, *ref = 0;
56   Repodata *data;
57   int c, percent = 0;
58   int extrapool = 0;
59   int nopacks = 0;
60   const char *root = 0;
61   const char *basefile = 0;
62   const char *refname = 0;
63 #ifdef ENABLE_SUSEREPO
64   char *proddir = 0;
65 #endif
66   char *outfile = 0;
67 #ifdef ENABLE_RPMDB_PUBKEY
68   int pubkeys = 0;
69 #endif
70
71   /*
72    * parse arguments
73    */
74   
75   while ((c = getopt(argc, argv, "Phnkxb:r:p:o:")) >= 0)
76     switch (c)
77       {
78       case 'h':
79           usage(0);
80         break;
81       case 'r':
82         root = optarg;
83         break;
84       case 'b':
85         basefile = optarg;
86         break;
87       case 'n':
88         nopacks = 1;
89         break;
90       case 'P':
91         percent = 1;
92         break;
93       case 'p':
94 #ifdef ENABLE_SUSEREPO
95         proddir = optarg;
96 #endif
97         break;
98       case 'x':
99         extrapool = 1;
100         break;
101       case 'o':
102         outfile = optarg;
103         break;
104 #ifdef ENABLE_RPMDB_PUBKEY
105       case 'k':
106         nopacks = 1;
107         pubkeys = 1;
108         break;
109 #endif
110       default:
111         usage(1);
112       }
113   
114   if (outfile && !freopen(outfile, "w", stdout))
115     {
116       perror(outfile);
117       exit(1);
118     }
119     
120   /*
121    * optional arg is old version of rpmdb solv file
122    * should make this a real option instead
123    */
124   
125   if (optind < argc)
126     refname = argv[optind];
127
128   if (refname && !nopacks)
129     {
130       FILE *fp;
131       if ((fp = fopen(refname, "r")) == NULL)
132         {
133           perror(refname);
134         }
135       else
136         {
137           Pool *refpool = extrapool ? pool_create() : 0;
138           ref = repo_create(refpool ? refpool : pool, "ref");
139           if (repo_add_solv(ref, fp, 0) != 0)
140             {
141               fprintf(stderr, "%s: %s\n", refname, pool_errstr(ref->pool));
142               if (ref->pool != pool)
143                 pool_free(ref->pool);
144               else
145                 repo_free(ref, 1);
146               ref = 0;
147             }
148           else
149             repo_disable_paging(ref);
150           fclose(fp);
151         }
152     }
153
154   /*
155    * create 'installed' repository
156    * add products
157    * add rpmdb
158    * write .solv
159    */
160
161   if (root && *root)
162     pool_set_rootdir(pool, root);
163
164   repo = repo_create(pool, "installed");
165   data = repo_add_repodata(repo, 0);
166
167   if (!nopacks)
168     {
169       if (repo_add_rpmdb(repo, ref, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | (percent ? RPMDB_REPORT_PROGRESS : 0)))
170         {
171           fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool));
172           exit(1);
173         }
174     }
175 #ifdef ENABLE_RPMDB_PUBKEY
176   if (pubkeys)
177     {
178       if (repo_add_rpmdb_pubkeys(repo, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
179         {
180           fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool));
181           exit(1);
182         }
183     }
184 #endif
185
186 #ifdef ENABLE_SUSEREPO
187   if (proddir && *proddir)
188     {
189       if (root && *root)
190         {
191           int rootlen = strlen(root);
192           if (!strncmp(root, proddir, rootlen))
193             {
194               proddir += rootlen;
195               if (*proddir != '/' && proddir[-1] == '/')
196                 proddir--;
197             }
198         }
199       if (repo_add_products(repo, proddir, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
200         {
201           fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool));
202           exit(1);
203         }
204     }
205 #endif
206   repodata_internalize(data);
207
208   if (ref)
209     {
210       if (ref->pool != pool)
211         pool_free(ref->pool);
212       else
213         repo_free(ref, 1);
214       ref = 0;
215     }
216
217   tool_write(repo, basefile, 0);
218   pool_free(pool);
219   exit(0);
220 }