Imported Upstream version 0.6.28
[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 static void
107 mdk_add_ext(Repo *repo, Repodata *data, const char *what, const char *ext, const char *filename, Id chksumtype, const unsigned char *chksum)
108 {
109   Id handle = repodata_new_handle(data);
110   /* we mis-use the repomd ids here... need something generic in the future */
111   repodata_set_poolstr(data, handle, REPOSITORY_REPOMD_TYPE, what);
112   repodata_set_str(data, handle, REPOSITORY_REPOMD_LOCATION, filename);
113   repodata_set_bin_checksum(data, handle, REPOSITORY_REPOMD_CHECKSUM, chksumtype, chksum);
114   add_ext_keys(data, handle, ext);
115   repodata_add_flexarray(data, SOLVID_META, REPOSITORY_EXTERNAL, handle);
116 }
117
118 int
119 mdk_load(struct repoinfo *cinfo, Pool **sigpoolp)
120 {
121   Repo *repo = cinfo->repo;
122   Pool *pool = repo->pool;
123   Repodata *data;
124   const char *compression;
125   FILE *fp, *cfp;
126   char *md5sums;
127   unsigned char probe[5];
128   unsigned char md5[16];
129
130   printf("mdk repo '%s':", cinfo->alias);
131   fflush(stdout);
132   if ((fp = curlfopen(cinfo, "media_info/MD5SUM", 0, 0, 0, 0)) == 0)
133     {
134       printf(" no media_info/MD5SUM file\n");
135       cinfo->incomplete = 1;
136       return 0;
137     }
138   calc_cookie_fp(fp, REPOKEY_TYPE_SHA256, cinfo->cookie);
139   cinfo->cookieset = 1;
140   if (usecachedrepo(cinfo, 0, 1))
141     {
142       printf(" cached\n");
143       fclose(fp);
144       return 1;
145     }
146   md5sums = slurp(fp);
147   fclose(fp);
148   printf(" fetching\n");
149   if (!mdk_find(md5sums, "synthesis.hdlist.cz", md5))
150     {
151       solv_free(md5sums);
152       cinfo->incomplete = 1;
153       return 0; /* hopeless */
154     }
155   if ((fp = curlfopen(cinfo, "media_info/synthesis.hdlist.cz", 0, md5, REPOKEY_TYPE_MD5, 1)) == 0)
156     {
157       solv_free(md5sums);
158       cinfo->incomplete = 1;
159       return 0; /* hopeless */
160     }
161   /* probe compression */
162   if (fread(probe, 5, 1, fp) != 1)
163     {
164       fclose(fp);
165       solv_free(md5sums);
166       cinfo->incomplete = 1;
167       return 0; /* hopeless */
168     }
169   if (probe[0] == 0xfd && memcmp(probe + 1, "7zXZ", 4) == 0)
170     compression = "synthesis.hdlist.xz";
171   else
172     compression = "synthesis.hdlist.gz";
173   lseek(fileno(fp), 0, SEEK_SET);
174   cfp = solv_xfopen_fd(compression, dup(fileno(fp)), "r");
175   fclose(fp);
176   fp = cfp;
177   if (!fp)
178     {
179       solv_free(md5sums);
180       cinfo->incomplete = 1;
181       return 0; /* hopeless */
182     }
183   if (repo_add_mdk(repo, fp, REPO_NO_INTERNALIZE))
184     {
185       printf("synthesis.hdlist.cz: %s\n", pool_errstr(pool));
186       fclose(fp);
187       solv_free(md5sums);
188       cinfo->incomplete = 1;
189       return 0; /* hopeless */
190     }
191   fclose(fp);
192   /* add info, could do this on demand, but always having the summary is nice */
193   if (mdk_find(md5sums, "info.xml.lzma", md5))
194     {
195       if ((fp = curlfopen(cinfo, "media_info/info.xml.lzma", 1, md5, REPOKEY_TYPE_MD5, 1)) != 0)
196         {
197           if (repo_add_mdk_info(repo, fp, REPO_NO_INTERNALIZE|REPO_REUSE_REPODATA|REPO_EXTEND_SOLVABLES))
198             {
199               printf("info.xml.lzma: %s\n", pool_errstr(pool));
200               cinfo->incomplete = 1;
201             }
202           fclose(fp);
203         }
204     }
205   repo_internalize(repo);
206   data = repo_add_repodata(repo, 0);
207   /* setup on-demand loading of filelist data */
208   if (mdk_find(md5sums, "files.xml.lzma", md5))
209     {
210       repodata_extend_block(data, repo->start, repo->end - repo->start);
211       mdk_add_ext(repo, data, "filelists", "FL", "media_info/files.xml.lzma", REPOKEY_TYPE_MD5, md5);
212     }
213   solv_free(md5sums);
214   repodata_internalize(data);
215   writecachedrepo(cinfo, 0, 0);
216   repodata_create_stubs(repo_last_repodata(repo));
217   return 1;
218 }
219
220 #endif