Imported Upstream version 0.7.27
[platform/upstream/libsolv.git] / tools / susetags2solv.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 #define _GNU_SOURCE
9
10 #include <sys/types.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <dirent.h>
15 #include <unistd.h>
16
17 #include "pool.h"
18 #include "repo.h"
19 #include "repo_solv.h"
20 #include "repo_susetags.h"
21 #include "repo_content.h"
22 #ifdef SUSE
23 #include "repo_autopattern.h"
24 #endif
25 #include "common_write.h"
26 #include "solv_xfopen.h"
27
28 static void
29 usage(int status)
30 {
31   fprintf(stderr, "\nUsage:\n"
32           "susetags2solv [-c <content>][-d <descrdir>][-h][-n <name>]\n"
33           "  reads a 'susetags' repository from <stdin> and writes a .solv file to <stdout>\n"
34           "  -c <contentfile> : parse given contentfile (for product information)\n"
35           "  -d <descrdir> : do not read from stdin, but use data in descrdir\n"
36           "  -h : print help & exit\n"
37          );
38    exit(status);
39 }
40
41 /* content file query */
42 static void
43 doquery(Pool *pool, Repo *repo, const char *arg)
44 {
45   char qbuf[256];
46   const char *str;
47   Id id;
48
49   snprintf(qbuf, sizeof(qbuf), "susetags:%s", arg);
50   id = pool_str2id(pool, qbuf, 0);
51   if (!id)
52     return;
53   str = repo_lookup_str(repo, SOLVID_META, id);
54   if (str)
55     printf("%s\n", str);
56 }
57
58 int
59 main(int argc, char **argv)
60 {
61   const char *contentfile = 0;
62   const char *descrdir = 0;
63   const char *query = 0;
64   const char *mergefile = 0;
65   Id defvendor = 0;
66   int flags = 0;
67 #ifdef SUSE
68   int add_auto = 0;
69 #endif
70   int c;
71   Pool *pool;
72   Repo *repo;
73
74   while ((c = getopt(argc, argv, "hc:d:q:M:X")) >= 0)
75     {
76       switch (c)
77         {
78         case 'h':
79           usage(0);
80           break;
81         case 'c':
82           contentfile = optarg;
83           break;
84         case 'd':
85           descrdir = optarg;
86           break;
87         case 'q':
88           query = optarg;
89           break;
90         case 'M':
91           mergefile = optarg;
92           break;
93         case 'X':
94 #ifdef SUSE
95           add_auto = 1;
96 #endif
97           break;
98         default:
99           usage(1);
100           break;
101         }
102     }
103   pool = pool_create();
104   repo = repo_create(pool, "<susetags>");
105
106   repo_add_repodata(repo, 0);
107
108   if (contentfile)
109     {
110       FILE *fp = fopen(contentfile, "r");
111       if (!fp)
112         {
113           perror(contentfile);
114           exit(1);
115         }
116       if (repo_add_content(repo, fp, REPO_REUSE_REPODATA))
117         {
118           fprintf(stderr, "susetags2solv: %s: %s\n", contentfile, pool_errstr(pool));
119           exit(1);
120         }
121       defvendor = repo_lookup_id(repo, SOLVID_META, SUSETAGS_DEFAULTVENDOR);
122       fclose(fp);
123     }
124
125   /*
126    * descrdir path given, open files and read from there
127    */
128   
129   if (descrdir)
130     {
131       char *fnp;
132       int ndirs, i;
133       struct dirent **files;
134
135       ndirs = scandir(descrdir, &files, 0, alphasort);
136       if (ndirs < 0)
137         {
138           perror(descrdir);
139           exit(1);
140         }
141
142       /* bring packages to front */
143       for (i = 0; i < ndirs; i++)
144         {
145           char *fn = files[i]->d_name;
146           if (!strcmp(fn, "packages") || !strcmp(fn, "packages.gz"))
147             break;
148         }
149       if (i == ndirs)
150         {
151           fprintf(stderr, "found no packages file\n");
152           exit(1);
153         }
154       if (i)
155         {
156           struct dirent *de = files[i];
157           memmove(files + 1, files, i * sizeof(de));
158           files[0] = de;
159         }
160
161       fnp = solv_malloc(strlen(descrdir) + 128);
162       for (i = 0; i < ndirs; i++)
163         {
164           char *fn = files[i]->d_name;
165
166           if (!strcmp(fn, "packages") || !strcmp(fn, "packages.gz"))
167             {
168               FILE *fp;
169               sprintf(fnp, "%s/%s", descrdir, fn);
170               fp = solv_xfopen(fnp, 0);
171               if (!fp)
172                 {
173                   perror(fn);
174                   exit(1);
175                 }
176               if (repo_add_susetags(repo, fp, defvendor, 0, flags | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | SUSETAGS_RECORD_SHARES))
177                 {
178                   fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
179                   exit(1);
180                 }
181               fclose(fp);
182             }
183           else if (!strcmp(fn, "packages.DU") || !strcmp(fn, "packages.DU.gz"))
184             {
185               FILE *fp;
186               sprintf(fnp, "%s/%s", descrdir, fn);
187               fp = solv_xfopen(fnp, 0);
188               if (!fp)
189                 {
190                   perror(fn);
191                   exit(1);
192                 }
193               if (repo_add_susetags(repo, fp, defvendor, 0, flags | SUSETAGS_EXTEND | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
194                 {
195                   fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
196                   exit(1);
197                 }
198               fclose(fp);
199             }
200           else if (!strcmp(fn, "packages.FL") || !strcmp(fn, "packages.FL.gz"))
201             {
202 #if 0
203               sprintf(fnp, "%s/%s", descrdir, fn);
204               FILE *fp = solv_xfopen(fnp, 0);
205               if (!fp)
206                 {
207                   perror(fn);
208                   exit(1);
209                 }
210               if (repo_add_susetags(repo, fp, defvendor, 0, flags | SUSETAGS_EXTEND | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
211                 {
212                   fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
213                   exit(1);
214                 }
215               fclose(fp);
216 #else
217               /* ignore for now. reactivate when filters work */
218               continue;
219 #endif
220             }
221           else if (!strncmp(fn, "packages.", 9))
222             {
223               char lang[6];
224               char *p;
225               FILE *fp;
226               sprintf(fnp, "%s/%s", descrdir, fn);
227               p = strrchr(fnp, '.');
228               if (p && !strcmp(p, ".gz"))
229                 {
230                   *p = 0;
231                   p = strrchr(fnp, '.');
232                 }
233               if (!p || !p[1] || strlen(p + 1) > 5)
234                 continue;
235               strcpy(lang, p + 1);
236               sprintf(fnp, "%s/%s", descrdir, fn);
237               fp = solv_xfopen(fnp, 0);
238               if (!fp)
239                 {
240                   perror(fn);
241                   exit(1);
242                 }
243               if (repo_add_susetags(repo, fp, defvendor, lang, flags | SUSETAGS_EXTEND | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
244                 {
245                   fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
246                   exit(1);
247                 }
248               fclose(fp);
249             }
250         }
251       for (i = 0; i < ndirs; i++)
252         free(files[i]);
253       free(files);
254       free(fnp);
255       repo_internalize(repo);
256     }
257   else
258     {
259       /* read data from stdin */
260       if (repo_add_susetags(repo, stdin, defvendor, 0, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
261         {
262           fprintf(stderr, "susetags2solv: %s\n", pool_errstr(pool));
263           exit(1);
264         }
265     }
266   repo_internalize(repo);
267   if (mergefile)
268     {
269       FILE *fp = fopen(mergefile, "r");
270       if (!fp)
271         {
272           perror(mergefile);
273           exit(1);
274         }
275       if (repo_add_solv(repo, fp, 0))
276         {
277           fprintf(stderr, "susetags2solv: %s\n", pool_errstr(pool));
278           exit(1);
279         }
280       fclose(fp);
281     }
282 #ifdef SUSE
283   if (add_auto)
284     repo_add_autopattern(repo, 0); 
285 #endif
286
287   if (query)
288     doquery(pool, repo, query);
289   else
290     tool_write(repo, stdout);
291   pool_free(pool);
292   exit(0);
293 }