Imported Upstream version 0.6.13
[platform/upstream/libsolv.git] / examples / solv / repoinfo_type_mdk.c
1 #ifdef ENABLE_MDKREPO
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_mdk.h"
11 #include "solv_xfopen.h"
12
13 #include "repoinfo.h"
14 #include "repoinfo_cache.h"
15 #include "repoinfo_download.h"
16 #include "repoinfo_type_mdk.h"
17
18 static int
19 mdk_find(const char *md5sums, const char *what, unsigned char *chksum)
20 {
21   const char *sp, *ep;
22   int wl = strlen(what);
23   for (sp = md5sums; (ep = strchr(sp, '\n')) != 0; sp = ep + 1)
24     {
25       int l = ep - sp;
26       if (l <= 34)
27         continue;
28       if (sp[32] != ' ' || sp[33] != ' ')
29         continue;
30       if (wl != l - 34 || strncmp(what, sp + 34, wl) != 0)
31         continue;
32       if (solv_hex2bin(&sp, chksum, 16) != 16)
33         continue;
34       return 1;
35     }
36   return 0;
37 }
38
39 static char *
40 slurp(FILE *fp)
41 {
42   int l, ll;
43   char *buf = 0;
44   int bufl = 0;
45
46   for (l = 0; ; l += ll)
47     {
48       if (bufl - l < 4096)
49         {
50           bufl += 4096;
51           buf = solv_realloc(buf, bufl);
52         }
53       ll = fread(buf + l, 1, bufl - l, fp);
54       if (ll < 0)
55         {
56           buf = solv_free(buf);
57           l = 0;
58           break;
59         }
60       if (ll == 0)
61         {
62           buf[l] = 0;
63           break;
64         }
65     }
66   return buf;
67 }
68
69 int
70 mdk_load_ext(Repo *repo, Repodata *data)
71 {
72   struct repoinfo *cinfo = repo->appdata;
73   const char *type, *ext, *filename;
74   const unsigned char *filechksum;
75   Id filechksumtype;
76   int r = 0;
77   FILE *fp;
78
79   type = repodata_lookup_str(data, SOLVID_META, REPOSITORY_REPOMD_TYPE);
80   if (strcmp(type, "filelists") != 0)
81     return 0;
82   ext = "FL";
83   printf("[%s:%s", repo->name, ext);
84   if (usecachedrepo(cinfo, ext, 0))
85     {
86       printf(" cached]\n"); fflush(stdout);
87       return 1;
88     }
89   printf(" fetching]\n"); fflush(stdout);
90   filename = repodata_lookup_str(data, SOLVID_META, REPOSITORY_REPOMD_LOCATION);
91   filechksumtype = 0;
92   filechksum = repodata_lookup_bin_checksum(data, SOLVID_META, REPOSITORY_REPOMD_CHECKSUM, &filechksumtype);
93   if ((fp = curlfopen(cinfo, filename, 1, filechksum, filechksumtype, 0)) == 0)
94     return 0;
95   r = repo_add_mdk_info(repo, fp, REPO_USE_LOADING|REPO_EXTEND_SOLVABLES|REPO_LOCALPOOL);
96   fclose(fp);
97   if (r)
98     {
99       printf("%s\n", pool_errstr(repo->pool));
100       return 0;
101     }
102   writecachedrepo(cinfo, ext, data);
103   return 1;
104 }
105
106 int
107 mdk_load(struct repoinfo *cinfo, Pool **sigpoolp)
108 {
109   Repo *repo = cinfo->repo;
110   Pool *pool = repo->pool;
111   Repodata *data;
112   const char *compression;
113   FILE *fp, *cfp;
114   char *md5sums;
115   unsigned char probe[5];
116   unsigned char md5[16];
117
118   printf("mdk repo '%s':", cinfo->alias);
119   fflush(stdout);
120   if ((fp = curlfopen(cinfo, "media_info/MD5SUM", 0, 0, 0, 0)) == 0)
121     {
122       printf(" no media_info/MD5SUM file\n");
123       cinfo->incomplete = 1;
124       return 0;
125     }
126   calc_cookie_fp(fp, REPOKEY_TYPE_SHA256, cinfo->cookie);
127   cinfo->cookieset = 1;
128   if (usecachedrepo(cinfo, 0, 1))
129     {
130       printf(" cached\n");
131       fclose(fp);
132       return 1;
133     }
134   md5sums = slurp(fp);
135   fclose(fp);
136   printf(" fetching\n");
137   if (!mdk_find(md5sums, "synthesis.hdlist.cz", md5))
138     {
139       solv_free(md5sums);
140       cinfo->incomplete = 1;
141       return 0; /* hopeless */
142     }
143   if ((fp = curlfopen(cinfo, "media_info/synthesis.hdlist.cz", 0, md5, REPOKEY_TYPE_MD5, 1)) == 0)
144     {
145       solv_free(md5sums);
146       cinfo->incomplete = 1;
147       return 0; /* hopeless */
148     }
149   /* probe compression */
150   if (fread(probe, 5, 1, fp) != 1)
151     {
152       fclose(fp);
153       solv_free(md5sums);
154       cinfo->incomplete = 1;
155       return 0; /* hopeless */
156     }
157   if (probe[0] == 0xfd && memcmp(probe + 1, "7zXZ", 4) == 0)
158     compression = "synthesis.hdlist.xz";
159   else
160     compression = "synthesis.hdlist.gz";
161   lseek(fileno(fp), 0, SEEK_SET);
162   cfp = solv_xfopen_fd(compression, dup(fileno(fp)), "r");
163   fclose(fp);
164   fp = cfp;
165   if (!fp)
166     {
167       solv_free(md5sums);
168       cinfo->incomplete = 1;
169       return 0; /* hopeless */
170     }
171   if (repo_add_mdk(repo, fp, REPO_NO_INTERNALIZE))
172     {
173       printf("synthesis.hdlist.cz: %s\n", pool_errstr(pool));
174       fclose(fp);
175       solv_free(md5sums);
176       cinfo->incomplete = 1;
177       return 0; /* hopeless */
178     }
179   fclose(fp);
180   /* add info, could do this on demand, but always having the summary is nice */
181   if (mdk_find(md5sums, "info.xml.lzma", md5))
182     {
183       if ((fp = curlfopen(cinfo, "media_info/info.xml.lzma", 1, md5, REPOKEY_TYPE_MD5, 1)) != 0)
184         {
185           if (repo_add_mdk_info(repo, fp, REPO_NO_INTERNALIZE|REPO_REUSE_REPODATA|REPO_EXTEND_SOLVABLES))
186             {
187               printf("info.xml.lzma: %s\n", pool_errstr(pool));
188               cinfo->incomplete = 1;
189             }
190           fclose(fp);
191         }
192     }
193   repo_internalize(repo);
194   data = repo_add_repodata(repo, 0);
195   /* setup on-demand loading of filelist data */
196   if (mdk_find(md5sums, "files.xml.lzma", md5))
197     {
198       Id handle = repodata_new_handle(data);
199       /* we mis-use the repomd ids here... need something generic in the future */
200       repodata_set_poolstr(data, handle, REPOSITORY_REPOMD_TYPE, "filelists");
201       repodata_set_str(data, handle, REPOSITORY_REPOMD_LOCATION, "media_info/files.xml.lzma");
202       repodata_set_bin_checksum(data, handle, REPOSITORY_REPOMD_CHECKSUM, REPOKEY_TYPE_MD5, md5);
203       add_ext_keys(data, handle, "FL");
204       repodata_add_flexarray(data, SOLVID_META, REPOSITORY_EXTERNAL, handle);
205     }
206   solv_free(md5sums);
207   repodata_internalize(data);
208   writecachedrepo(cinfo, 0, 0);
209   repodata_create_stubs(repo_last_repodata(repo));
210   return 1;
211 }
212
213 #endif