Imported Upstream version 0.6.31
[platform/upstream/libsolv.git] / examples / solv / repoinfo_type_susetags.c
1 #ifdef ENABLE_SUSEREPO
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6
7 #include "pool.h"
8 #include "repo.h"
9 #include "chksum.h"
10 #include "repo_content.h"
11 #include "repo_susetags.h"
12 #ifdef ENABLE_APPDATA
13 #include "repo_appdata.h"
14 #endif
15 #ifdef SUSE
16 #include "repo_autopattern.h"
17 #endif
18
19 #include "repoinfo.h"
20 #include "repoinfo_cache.h"
21 #include "repoinfo_download.h"
22 #include "repoinfo_type_susetags.h"
23
24 /* susetags helpers */
25
26 static const char *
27 susetags_find(Repo *repo, const char *what, const unsigned char **chksump, Id *chksumtypep)
28 {
29   Pool *pool = repo->pool;
30   Dataiterator di;
31   const char *filename;
32
33   filename = 0;
34   *chksump = 0;
35   *chksumtypep = 0;
36   dataiterator_init(&di, pool, repo, SOLVID_META, SUSETAGS_FILE_NAME, what, SEARCH_STRING);
37   dataiterator_prepend_keyname(&di, SUSETAGS_FILE);
38   if (dataiterator_step(&di))
39     {
40       dataiterator_setpos_parent(&di);
41       *chksump = pool_lookup_bin_checksum(pool, SOLVID_POS, SUSETAGS_FILE_CHECKSUM, chksumtypep);
42       filename = what;
43     }
44   dataiterator_free(&di);
45   if (filename && !*chksumtypep)
46     {
47       printf("no %s file checksum!\n", what);
48       filename = 0;
49     }
50   return filename;
51 }
52
53 static void
54 susetags_add_ext(Repo *repo, Repodata *data)
55 {
56   Pool *pool = repo->pool;
57   Dataiterator di;
58   char ext[3];
59   Id handle, filechksumtype;
60   const unsigned char *filechksum;
61
62   dataiterator_init(&di, pool, repo, SOLVID_META, SUSETAGS_FILE_NAME, 0, 0);
63   dataiterator_prepend_keyname(&di, SUSETAGS_FILE);
64   while (dataiterator_step(&di))
65     {
66       if (strncmp(di.kv.str, "packages.", 9) != 0)
67         continue;
68       if (!strcmp(di.kv.str + 9, "gz"))
69         continue;
70       if (!di.kv.str[9] || !di.kv.str[10] || (di.kv.str[11] && di.kv.str[11] != '.'))
71         continue;
72       ext[0] = di.kv.str[9];
73       ext[1] = di.kv.str[10];
74       ext[2] = 0;
75       if (!strcmp(ext, "en"))
76         continue;
77       if (!susetags_find(repo, di.kv.str, &filechksum, &filechksumtype))
78         continue;
79       handle = repodata_new_handle(data);
80       repodata_set_str(data, handle, SUSETAGS_FILE_NAME, di.kv.str);
81       if (filechksumtype)
82         repodata_set_bin_checksum(data, handle, SUSETAGS_FILE_CHECKSUM, filechksumtype, filechksum);
83       add_ext_keys(data, handle, ext);
84       repodata_add_flexarray(data, SOLVID_META, REPOSITORY_EXTERNAL, handle);
85     }
86   dataiterator_free(&di);
87 }
88
89 int
90 susetags_load_ext(Repo *repo, Repodata *data)
91 {
92   const char *filename, *descrdir;
93   Id defvendor;
94   char ext[3];
95   FILE *fp;
96   struct repoinfo *cinfo;
97   const unsigned char *filechksum;
98   Id filechksumtype;
99   int flags;
100
101   cinfo = repo->appdata;
102   filename = repodata_lookup_str(data, SOLVID_META, SUSETAGS_FILE_NAME);
103   if (!filename)
104     return 0;
105   /* susetags load */
106   ext[0] = filename[9];
107   ext[1] = filename[10];
108   ext[2] = 0;
109   printf("[%s:%s", repo->name, ext);
110   if (usecachedrepo(cinfo, ext, 0))
111     {
112       printf(" cached]\n"); fflush(stdout);
113       return 1;
114     }
115   printf(" fetching]\n"); fflush(stdout);
116   defvendor = repo_lookup_id(repo, SOLVID_META, SUSETAGS_DEFAULTVENDOR);
117   descrdir = repo_lookup_str(repo, SOLVID_META, SUSETAGS_DESCRDIR);
118   if (!descrdir)
119     descrdir = "suse/setup/descr";
120   filechksumtype = 0;
121   filechksum = repodata_lookup_bin_checksum(data, SOLVID_META, SUSETAGS_FILE_CHECKSUM, &filechksumtype);
122   if ((fp = curlfopen(cinfo, pool_tmpjoin(repo->pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 0)) == 0)
123     return 0;
124   flags = REPO_USE_LOADING|REPO_EXTEND_SOLVABLES;
125   if (strcmp(ext, "DL") != 0)
126     flags |= REPO_LOCALPOOL;
127   if (repo_add_susetags(repo, fp, defvendor, ext, flags))
128     {
129       fclose(fp);
130       printf("%s\n", pool_errstr(repo->pool));
131       return 0;
132     }
133   fclose(fp);
134   writecachedrepo(cinfo, ext, data);
135   return 1;
136 }
137
138 int
139 susetags_load(struct repoinfo *cinfo, Pool **sigpoolp)
140 {
141   Repo *repo = cinfo->repo;
142   Pool *pool = repo->pool;
143   Repodata *data;
144   const char *filename;
145   const unsigned char *filechksum;
146   Id filechksumtype;
147   FILE *fp;
148   const char *descrdir;
149   int defvendor;
150
151   printf("susetags repo '%s':", cinfo->alias);
152   fflush(stdout);
153   descrdir = 0;
154   defvendor = 0;
155   if ((fp = curlfopen(cinfo, "content", 0, 0, 0, 0)) == 0)
156     {
157       printf(" no content file\n");
158       cinfo->incomplete = 1;
159       return 0;
160     }
161   calc_cookie_fp(fp, REPOKEY_TYPE_SHA256, cinfo->cookie);
162   cinfo->cookieset = 1;
163   if (usecachedrepo(cinfo, 0, 1))
164     {
165       printf(" cached\n");
166       fclose(fp);
167       return 1;
168     }
169   if (cinfo->repo_gpgcheck && !downloadchecksig(cinfo, fp, "content.asc", sigpoolp))
170     {
171       fclose(fp);
172       cinfo->incomplete = 1;
173       return 0;
174     }
175   if (repo_add_content(repo, fp, 0))
176     {
177       printf("content: %s\n", pool_errstr(pool));
178       fclose(fp);
179       cinfo->incomplete = 1;
180       return 0;
181     }
182   fclose(fp);
183   defvendor = repo_lookup_id(repo, SOLVID_META, SUSETAGS_DEFAULTVENDOR);
184   descrdir = repo_lookup_str(repo, SOLVID_META, SUSETAGS_DESCRDIR);
185   if (!descrdir)
186     descrdir = "suse/setup/descr";
187   filename = susetags_find(repo, "packages.gz", &filechksum, &filechksumtype);
188   if (!filename)
189     filename = susetags_find(repo, "packages", &filechksum, &filechksumtype);
190   if (!filename)
191     {
192       printf(" no packages file entry, skipped\n");
193       cinfo->incomplete = 1;
194       return 0;
195     }
196   printf(" fetching\n");
197   if ((fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 1)) == 0)
198     {
199       cinfo->incomplete = 1;
200       return 0; /* hopeless */
201     }
202   if (repo_add_susetags(repo, fp, defvendor, 0, REPO_NO_INTERNALIZE|SUSETAGS_RECORD_SHARES))
203     {
204       printf("packages: %s\n", pool_errstr(pool));
205       fclose(fp);
206       cinfo->incomplete = 1;
207       return 0; /* hopeless */
208     }
209   fclose(fp);
210   /* add default language */
211   filename = susetags_find(repo, "packages.en.gz", &filechksum, &filechksumtype);
212   if (!filename)
213     filename = susetags_find(repo, "packages.en", &filechksum, &filechksumtype);
214   if (filename)
215     {
216       if ((fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 1)) != 0)
217         {
218           if (repo_add_susetags(repo, fp, defvendor, 0, REPO_NO_INTERNALIZE|REPO_REUSE_REPODATA|REPO_EXTEND_SOLVABLES))
219             {
220               printf("packages.en: %s\n", pool_errstr(pool));
221               cinfo->incomplete = 1;
222             }
223           fclose(fp);
224         }
225     }
226   filename = susetags_find(repo, "patterns", &filechksum, &filechksumtype);
227   if (filename)
228     {
229       if ((fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 1)) != 0)
230         {
231           char pbuf[256];
232           while (fgets(pbuf, sizeof(pbuf), fp))
233             {
234               int l = strlen(pbuf);
235               FILE *fp2;
236               if (l && pbuf[l - 1] == '\n')
237                 pbuf[--l] = 0;
238               if (!*pbuf || *pbuf == '.' || strchr(pbuf, '/') != 0)
239                 continue;
240               filename = susetags_find(repo, pbuf, &filechksum, &filechksumtype);
241               if (filename && (fp2 = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 1)) != 0)
242                 {
243                   if (repo_add_susetags(repo, fp2, defvendor, 0, REPO_NO_INTERNALIZE))
244                     {
245                       printf("%s: %s\n", pbuf, pool_errstr(pool));
246                       cinfo->incomplete = 1;
247                     }
248                   fclose(fp2);
249                 }
250             }
251           fclose(fp);
252         }
253     }
254 #ifdef ENABLE_APPDATA
255   filename = susetags_find(repo, "appdata.xml.gz", &filechksum, &filechksumtype);
256   if (!filename)
257     filename = susetags_find(repo, "appdata.xml", &filechksum, &filechksumtype);
258   if (filename && (fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 1)) != 0)
259     {
260       if (repo_add_appdata(repo, fp, 0))
261         {
262           printf("appdata: %s\n", pool_errstr(pool));
263           cinfo->incomplete = 1;
264         }
265       fclose(fp);
266     }
267 #endif
268   repo_internalize(repo);
269 #ifdef SUSE
270   repo_add_autopattern(repo, 0);
271 #endif
272   data = repo_add_repodata(repo, 0);
273   repodata_extend_block(data, repo->start, repo->end - repo->start);
274   susetags_add_ext(repo, data);
275   repodata_internalize(data);
276   writecachedrepo(cinfo, 0, 0);
277   repodata_create_stubs(repo_last_repodata(repo));
278   return 1;
279 }
280
281 #endif