98c5d36716579cbe3809bc6f58236bc21902961c
[platform/upstream/libsolv.git] / examples / solv / repoinfo_type_rpmmd.c
1 #ifdef ENABLE_RPMMD
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_rpmmd.h"
11 #include "repo_deltainfoxml.h"
12 #include "repo_updateinfoxml.h"
13 #include "repo_repomdxml.h"
14 #ifdef ENABLE_APPDATA
15 #include "repo_appdata.h"
16 #endif
17
18 #include "repoinfo.h"
19 #include "repoinfo_cache.h"
20 #include "repoinfo_download.h"
21 #include "repoinfo_type_rpmmd.h"
22
23
24
25 static const char *
26 repomd_find(Repo *repo, const char *what, const unsigned char **chksump, Id *chksumtypep)
27 {
28   Pool *pool = repo->pool;
29   Dataiterator di;
30   const char *filename;
31
32   filename = 0;
33   *chksump = 0;
34   *chksumtypep = 0;
35   dataiterator_init(&di, pool, repo, SOLVID_META, REPOSITORY_REPOMD_TYPE, what, SEARCH_STRING);
36   dataiterator_prepend_keyname(&di, REPOSITORY_REPOMD);
37   if (dataiterator_step(&di))
38     {
39       dataiterator_setpos_parent(&di);
40       filename = pool_lookup_str(pool, SOLVID_POS, REPOSITORY_REPOMD_LOCATION);
41       *chksump = pool_lookup_bin_checksum(pool, SOLVID_POS, REPOSITORY_REPOMD_CHECKSUM, chksumtypep);
42     }
43   dataiterator_free(&di);
44   if (filename && !*chksumtypep)
45     {
46       printf("no %s file checksum!\n", what);
47       filename = 0;
48     }
49   return filename;
50 }
51
52 static void
53 repomd_add_ext(Repo *repo, Repodata *data, const char *what, const char *ext)
54 {
55   Id chksumtype, handle;
56   const unsigned char *chksum;
57   const char *filename;
58
59   filename = repomd_find(repo, what, &chksum, &chksumtype);
60   if (!filename && !strcmp(what, "deltainfo"))
61     filename = repomd_find(repo, "prestodelta", &chksum, &chksumtype);
62   if (!filename)
63     return;
64   handle = repodata_new_handle(data);
65   repodata_set_poolstr(data, handle, REPOSITORY_REPOMD_TYPE, what);
66   repodata_set_str(data, handle, REPOSITORY_REPOMD_LOCATION, filename);
67   repodata_set_bin_checksum(data, handle, REPOSITORY_REPOMD_CHECKSUM, chksumtype, chksum);
68   add_ext_keys(data, handle, ext);
69   repodata_add_flexarray(data, SOLVID_META, REPOSITORY_EXTERNAL, handle);
70 }
71
72 int
73 repomd_load_ext(Repo *repo, Repodata *data)
74 {
75   const char *filename, *repomdtype;
76   char ext[3];
77   FILE *fp;
78   struct repoinfo *cinfo;
79   const unsigned char *filechksum;
80   Id filechksumtype;
81   int r = 0;
82
83   cinfo = repo->appdata;
84   repomdtype = repodata_lookup_str(data, SOLVID_META, REPOSITORY_REPOMD_TYPE);
85   if (!repomdtype)
86     return 0;
87   if (!strcmp(repomdtype, "filelists"))
88     strcpy(ext, "FL");
89   else if (!strcmp(repomdtype, "deltainfo"))
90     strcpy(ext, "DL");
91   else
92     return 0;
93   printf("[%s:%s", repo->name, ext);
94   if (usecachedrepo(cinfo, ext, 0))
95     {
96       printf(" cached]\n"); fflush(stdout);
97       return 1;
98     }
99   printf(" fetching]\n"); fflush(stdout);
100   filename = repodata_lookup_str(data, SOLVID_META, REPOSITORY_REPOMD_LOCATION);
101   filechksumtype = 0;
102   filechksum = repodata_lookup_bin_checksum(data, SOLVID_META, REPOSITORY_REPOMD_CHECKSUM, &filechksumtype);
103   if ((fp = curlfopen(cinfo, filename, 1, filechksum, filechksumtype, 0)) == 0)
104     return 0;
105   if (!strcmp(ext, "FL"))
106     r = repo_add_rpmmd(repo, fp, ext, REPO_USE_LOADING|REPO_EXTEND_SOLVABLES|REPO_LOCALPOOL);
107   else if (!strcmp(ext, "DL"))
108     r = repo_add_deltainfoxml(repo, fp, REPO_USE_LOADING);
109   fclose(fp);
110   if (r)
111     {
112       printf("%s\n", pool_errstr(repo->pool));
113       return 0;
114     }
115   if (cinfo->extcookieset)
116     writecachedrepo(cinfo, ext, data);
117   return 1;
118 }
119
120 int
121 repomd_load(struct repoinfo *cinfo, Pool **sigpoolp)
122 {
123   Repo *repo = cinfo->repo;
124   Pool *pool = repo->pool;
125   Repodata *data;
126   const char *filename;
127   const unsigned char *filechksum;
128   Id filechksumtype;
129   FILE *fp;
130
131   printf("rpmmd repo '%s':", cinfo->alias);
132   fflush(stdout);
133   if ((fp = curlfopen(cinfo, "repodata/repomd.xml", 0, 0, 0, 0)) == 0)
134     {
135       printf(" no repomd.xml file\n");
136       cinfo->incomplete = 1;
137       return 0;
138     }
139   calc_cookie_fp(fp, REPOKEY_TYPE_SHA256, cinfo->cookie);
140   cinfo->cookieset = 1;
141   if (usecachedrepo(cinfo, 0, 1))
142     {
143       printf(" cached\n");
144       fclose(fp);
145       return 1;
146     }
147   if (cinfo->repo_gpgcheck && !downloadchecksig(cinfo, fp, "repodata/repomd.xml.asc", sigpoolp))
148     {
149       fclose(fp);
150       cinfo->incomplete = 1;
151       return 0;
152     }
153   if (repo_add_repomdxml(repo, fp, 0))
154     {
155       printf("repomd.xml: %s\n", pool_errstr(pool));
156       cinfo->incomplete = 1;
157       fclose(fp);
158       return 0;
159     }
160   fclose(fp);
161   printf(" fetching\n");
162   filename = repomd_find(repo, "primary", &filechksum, &filechksumtype);
163   if (filename && (fp = curlfopen(cinfo, filename, 1, filechksum, filechksumtype, 1)) != 0)
164     {
165       if (repo_add_rpmmd(repo, fp, 0, 0))
166         {
167           printf("primary: %s\n", pool_errstr(pool));
168           cinfo->incomplete = 1;
169         }
170       fclose(fp);
171     }
172   if (cinfo->incomplete)
173     return 0;   /* hopeless */
174
175   filename = repomd_find(repo, "updateinfo", &filechksum, &filechksumtype);
176   if (filename && (fp = curlfopen(cinfo, filename, 1, filechksum, filechksumtype, 1)) != 0)
177     {
178       if (repo_add_updateinfoxml(repo, fp, 0))
179         {
180           printf("updateinfo: %s\n", pool_errstr(pool));
181           cinfo->incomplete = 1;
182         }
183       fclose(fp);
184     }
185
186 #ifdef ENABLE_APPDATA
187   filename = repomd_find(repo, "appdata", &filechksum, &filechksumtype);
188   if (filename && (fp = curlfopen(cinfo, filename, 1, filechksum, filechksumtype, 1)) != 0)
189     {
190       if (repo_add_appdata(repo, fp, 0))
191         {
192           printf("appdata: %s\n", pool_errstr(pool));
193           cinfo->incomplete = 1;
194         }
195       fclose(fp);
196     }
197 #endif
198   data = repo_add_repodata(repo, 0);
199   repomd_add_ext(repo, data, "deltainfo", "DL");
200   repomd_add_ext(repo, data, "filelists", "FL");
201   repodata_internalize(data);
202   writecachedrepo(cinfo, 0, 0);
203   repodata_create_stubs(repo_last_repodata(repo));
204   return 1;
205 }
206
207 #endif