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