support ADD_WITH_SUBKEYS/ADD_MULTIPLE_PUBKEYS/ADD_WITH_KEYSIGNATURES
[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
35 static void
36 usage(int status)
37 {
38   fprintf(stderr, "\nUsage:\n"
39           "rpmdb2solv [-n] [-b <basefile>] [-p <productsdir>] [-r <root>]\n"
40           " -n : No packages, do not read rpmdb, useful to only parse products\n"
41           " -b <basefile> : Write .solv to <basefile>.solv instead of stdout\n"
42           " -p <productsdir> : Scan <productsdir> for .prod files, representing installed products\n"
43           " -r <root> : Prefix rpmdb path and <productsdir> with <root>\n"
44           " -o <solv> : Write .solv to file instead of stdout\n"
45          );
46   exit(status);
47 }
48
49
50 int
51 main(int argc, char **argv)
52 {
53   FILE *reffp = 0;
54   Pool *pool = pool_create();
55   Repo *repo;
56   Repodata *data;
57   int c, percent = 0;
58   int nopacks = 0;
59   const char *root = 0;
60   const char *basefile = 0;
61   const char *refname = 0;
62 #ifdef ENABLE_SUSEREPO
63   char *proddir = 0;
64 #endif
65   char *outfile = 0;
66 #ifdef ENABLE_PUBKEY
67   int pubkeys = 0;
68 #endif
69
70   /*
71    * parse arguments
72    */
73   
74   while ((c = getopt(argc, argv, "Phnkxb:r:p:o:")) >= 0)
75     switch (c)
76       {
77       case 'h':
78           usage(0);
79         break;
80       case 'r':
81         root = optarg;
82         break;
83       case 'b':
84         basefile = optarg;
85         break;
86       case 'n':
87         nopacks = 1;
88         break;
89       case 'P':
90         percent = 1;
91         break;
92       case 'p':
93 #ifdef ENABLE_SUSEREPO
94         proddir = optarg;
95 #endif
96         break;
97       case 'x':
98         break;
99       case 'o':
100         outfile = optarg;
101         break;
102 #ifdef ENABLE_PUBKEY
103       case 'k':
104         nopacks = 1;
105         pubkeys = 1;
106         break;
107 #endif
108       default:
109         usage(1);
110       }
111   
112   if (outfile && !freopen(outfile, "w", stdout))
113     {
114       perror(outfile);
115       exit(1);
116     }
117     
118   /*
119    * optional arg is old version of rpmdb solv file
120    * should make this a real option instead
121    */
122   
123   if (optind < argc)
124     refname = argv[optind];
125
126   if (refname && !nopacks)
127     {
128       if ((reffp = fopen(refname, "r")) == NULL)
129         perror(refname);
130     }
131
132   /*
133    * create 'installed' repository
134    * add products
135    * add rpmdb
136    * write .solv
137    */
138
139   if (root && *root)
140     pool_set_rootdir(pool, root);
141
142   repo = repo_create(pool, "installed");
143   data = repo_add_repodata(repo, 0);
144
145   if (!nopacks)
146     {
147       if (repo_add_rpmdb_reffp(repo, reffp, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | (percent ? RPMDB_REPORT_PROGRESS : 0)))
148         {
149           fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool));
150           exit(1);
151         }
152     }
153 #ifdef ENABLE_PUBKEY
154   if (pubkeys)
155     {
156       if (repo_add_rpmdb_pubkeys(repo, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | ADD_WITH_KEYSIGNATURES))
157         {
158           fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool));
159           exit(1);
160         }
161     }
162 #endif
163
164 #ifdef ENABLE_SUSEREPO
165   if (proddir && *proddir)
166     {
167       if (root && *root)
168         {
169           int rootlen = strlen(root);
170           if (!strncmp(root, proddir, rootlen))
171             {
172               proddir += rootlen;
173               if (*proddir != '/' && proddir[-1] == '/')
174                 proddir--;
175             }
176         }
177       if (repo_add_products(repo, proddir, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
178         {
179           fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool));
180           exit(1);
181         }
182     }
183 #endif
184   repodata_internalize(data);
185
186   if (reffp)
187     fclose(reffp);
188
189   tool_write(repo, basefile, 0);
190   pool_free(pool);
191   exit(0);
192 }