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