- make unknown elements less fatal
[platform/upstream/libsolv.git] / tools / rpmmd2solv.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 <limits.h>
12 #include <fcntl.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <zlib.h>
18
19 #include "pool.h"
20 #include "repo.h"
21 #include "repo_rpmmd.h"
22 #include "common_write.h"
23
24
25 static ssize_t
26 cookie_gzread(void *cookie, char *buf, size_t nbytes)
27 {
28   return gzread((gzFile *)cookie, buf, nbytes);
29 }
30
31 static int
32 cookie_gzclose(void *cookie)
33 {
34   return gzclose((gzFile *)cookie);
35 }
36
37 FILE *
38 myfopen(const char *fn)
39 {
40   cookie_io_functions_t cio;
41   char *suf;
42   gzFile *gzf;
43
44   if (!fn)
45     return 0;
46   suf = strrchr(fn, '.');
47   if (!suf || strcmp(suf, ".gz") != 0)
48     return fopen(fn, "r");
49   gzf = gzopen(fn, "r");
50   if (!gzf)
51     return 0;
52   memset(&cio, 0, sizeof(cio));
53   cio.read = cookie_gzread;
54   cio.close = cookie_gzclose;
55   return  fopencookie(gzf, "r", cio);
56 }
57
58 static void
59 usage(int status)
60 {
61   fprintf(stderr, "\nUsage:\n"
62           "rpmmd2solv [-a][-h][-k][-n <attrname>][-l <locale>]\n"
63           "  reads 'primary' from a 'rpmmd' repository from <stdin> and writes a .solv file to <stdout>\n"
64           "  -h : print help & exit\n"
65           "  -k : don't mix kinds (experimental!)\n"
66           "  -n <name>: save attributes as <name>.attr\n"
67           "  -l <locale>: parse localization data for <locale>\n"
68          );
69    exit(status);
70 }
71
72 int
73 main(int argc, char **argv)
74 {
75   int c, flags = 0;
76   const char *attrname = 0;
77   const char *basefile = 0;
78   const char *dir = 0;
79   const char *locale = 0;
80   
81   Pool *pool = pool_create();
82   Repo *repo = repo_create(pool, "<stdin>");
83
84   while ((c = getopt (argc, argv, "hkn:b:d:l:")) >= 0)
85     {
86       switch(c)
87         {
88         case 'h':
89           usage(0);
90           break;
91         case 'k':
92           flags |= RPMMD_KINDS_SEPARATELY;   /* do not use! */
93           break;
94         case 'n':
95           attrname = optarg;
96           break;
97         case 'b':
98           basefile = optarg;
99           break;
100         case 'd':
101           dir = optarg;
102           break;
103         case 'l':
104           locale = optarg;
105           break;
106         default:
107           usage(1);
108           break;
109         }
110     }
111   if (dir)
112     {
113       FILE *fp;
114       int l;
115       char *fnp;
116       l = strlen(dir) + 128;
117       fnp = sat_malloc(l+1);
118       snprintf(fnp, l, "%s/primary.xml.gz", dir);
119       if (!(fp = myfopen(fnp)))
120         {
121           perror(fnp);
122           exit(1);
123         }
124       repo_add_rpmmd(repo, fp, 0, flags);
125       fclose(fp);
126       snprintf(fnp, l, "%s/diskusagedata.xml.gz", dir);
127       if ((fp = myfopen(fnp)))
128         {
129           repo_add_rpmmd(repo, fp, 0, flags);
130           fclose(fp);
131         }
132       if (locale)
133         {
134           if (snprintf(fnp, l, "%s/translation-%s.xml.gz", dir, locale) >= l)
135             {
136               fprintf(stderr, "-l parameter too long\n");
137               exit(1);
138             }
139           while (!(fp = myfopen(fnp)))
140             {
141               fprintf(stderr, "not opened %s\n", fnp);
142               if (strlen(locale) > 2)
143                 {
144                   if (snprintf(fnp, l, "%s/translation-%.2s.xml.gz", dir, locale) >= l)
145                     {
146                       fprintf(stderr, "-l parameter too long\n");
147                       exit(1);
148                     }
149                   if ((fp = myfopen(fnp)))
150                     break;
151                 }
152               perror(fnp);
153               exit(1);
154             }
155           fprintf(stderr, "opened %s\n", fnp);
156           repo_add_rpmmd(repo, fp, 0, flags);
157           fclose(fp);
158         }
159       sat_free(fnp);
160     }
161   else
162     repo_add_rpmmd(repo, stdin, 0, flags);
163   tool_write(repo, basefile, attrname);
164   pool_free(pool);
165   exit(0);
166 }