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