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