rpmdb2solv:
[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 #include "repo_products.h"
29 #include "repo_solv.h"
30 #include "common_write.h"
31
32 static void
33 usage(int status)
34 {
35   fprintf(stderr, "\nUsage:\n"
36           "rpmdb2solv [-n] [-x] [-b <basefile>] [-p <productsdir>] [-r <root>]\n"
37           " -n : No packages, do not read rpmdb, useful to only parse products\n"
38           " -x : use extrapool\n"
39           " -b <basefile> : Write .solv to <basefile>.solv instead of stdout\n"
40           " -p <productsdir> : Scan <productsdir> for .prod files, representing installed products\n"
41           " -r <root> : Prefix rpmdb path and <productsdir> with <root>\n"
42          );
43   exit(status);
44 }
45
46
47 int
48 main(int argc, char **argv)
49 {
50   Pool *pool = pool_create();
51   Repo *repo, *ref = 0;
52   Repodata *repodata;
53   FILE *fp;
54   Pool *refpool;
55   int c;
56   int extrapool = 0;
57   int nopacks = 0;
58   const char *root = 0;
59   const char *basefile = 0;
60   const char *proddir = 0;
61
62   /*
63    * parse arguments
64    */
65   
66   while ((c = getopt (argc, argv, "hnxb:r:p:")) >= 0)
67     switch (c)
68       {
69       case 'h':
70           usage(0);
71         break;
72       case 'r':
73         root = optarg;
74         break;
75       case 'b':
76         basefile = optarg;
77         break;
78       case 'n':
79         nopacks = 1;
80         break;
81       case 'p':
82         proddir = optarg;
83         break;
84       case 'x':
85         extrapool = 1;
86         break;
87       default:
88         usage(1);
89       }
90   
91   /*
92    * ???
93    */
94   
95   if (optind < argc)
96     {
97       if (extrapool)
98         refpool = pool_create();
99       else
100         refpool = pool;
101       if ((fp = fopen(argv[optind], "r")) == NULL)
102         {
103           perror(argv[optind]);
104           exit(1);
105         }
106       ref = repo_create(refpool, "ref");
107       repo_add_solv(ref, fp);
108       repo_disable_paging(ref);
109       fclose(fp);
110     }
111
112   /*
113    * create 'installed' repository
114    * add products
115    * add rpmdb
116    * write .solv
117    */
118
119   repo = repo_create(pool, "installed");
120   repodata = repo_add_repodata(repo, 0);
121
122   if (!nopacks)
123     repo_add_rpmdb(repo, repodata, ref, root);
124
125   if (proddir && *proddir)
126     {
127       /* if <root> given, not '/', and proddir does not start with <root> */
128       if (root && *root)
129         {
130           int rootlen = strlen(root);
131           if (strncmp(root, proddir, rootlen))
132             {
133               char *buf;
134               buf = (char *)sat_malloc(rootlen + strlen(proddir) + 2); /* + '/' + \0 */
135               strcpy(buf, root);
136               if (root[rootlen-1] != '/'
137                   && *proddir != '/')
138                 {
139                   strcpy(buf+rootlen, "/");
140                   ++rootlen;
141                 }
142               strcpy(buf+rootlen, proddir);
143               proddir = buf;
144             }
145         }
146       
147       repo_add_products(repo, repodata, proddir, root);
148     }
149       
150   if (repodata)
151     repodata_internalize(repodata);
152
153   if (ref)
154     {
155       if (ref->pool != pool)
156         pool_free(ref->pool);
157       else
158         repo_free(ref, 1);
159       ref = 0;
160     }
161
162   tool_write(repo, basefile, 0);
163   pool_free(pool);
164
165   exit(0);
166 }