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