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