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