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