1 #ifdef ENABLE_DEBIAN
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <sys/utsname.h>
7 
8 #include "pool.h"
9 #include "repo.h"
10 #include "chksum.h"
11 #include "repo_deb.h"
12 
13 #include "repoinfo.h"
14 #include "repoinfo_cache.h"
15 #include "repoinfo_download.h"
16 #include "repoinfo_type_debian.h"
17 
18 static const char *
debian_find_component(struct repoinfo * cinfo,FILE * fp,char * comp,const unsigned char ** chksump,Id * chksumtypep)19 debian_find_component(struct repoinfo *cinfo, FILE *fp, char *comp, const unsigned char **chksump, Id *chksumtypep)
20 {
21   char buf[4096];
22   Id chksumtype;
23   unsigned char *chksum;
24   Id curchksumtype;
25   int l, compl;
26   char *ch, *fn, *bp;
27   char *filename;
28   static char *basearch;
29   char *binarydir;
30   int lbinarydir;
31 
32   if (!basearch)
33     {
34       struct utsname un;
35       if (uname(&un))
36 	{
37 	  perror("uname");
38 	  exit(1);
39 	}
40       basearch = strdup(un.machine);
41       if (basearch[0] == 'i' && basearch[1] && !strcmp(basearch + 2, "86"))
42 	basearch[1] = '3';
43     }
44   binarydir = solv_dupjoin("binary-", basearch, "/");
45   lbinarydir = strlen(binarydir);
46   compl = strlen(comp);
47   rewind(fp);
48   curchksumtype = 0;
49   filename = 0;
50   chksum = solv_malloc(32);
51   chksumtype = 0;
52   while(fgets(buf, sizeof(buf), fp))
53     {
54       l = strlen(buf);
55       if (l == 0)
56 	continue;
57       while (l && (buf[l - 1] == '\n' || buf[l - 1] == ' ' || buf[l - 1] == '\t'))
58 	buf[--l] = 0;
59       if (!strncasecmp(buf, "MD5Sum:", 7))
60 	{
61 	  curchksumtype = REPOKEY_TYPE_MD5;
62 	  continue;
63 	}
64       if (!strncasecmp(buf, "SHA1:", 5))
65 	{
66 	  curchksumtype = REPOKEY_TYPE_SHA1;
67 	  continue;
68 	}
69       if (!strncasecmp(buf, "SHA256:", 7))
70 	{
71 	  curchksumtype = REPOKEY_TYPE_SHA256;
72 	  continue;
73 	}
74       if (!curchksumtype)
75 	continue;
76       bp = buf;
77       if (*bp++ != ' ')
78 	{
79 	  curchksumtype = 0;
80 	  continue;
81 	}
82       ch = bp;
83       while (*bp && *bp != ' ' && *bp != '\t')
84 	bp++;
85       if (!*bp)
86 	continue;
87       *bp++ = 0;
88       while (*bp == ' ' || *bp == '\t')
89 	bp++;
90       while (*bp && *bp != ' ' && *bp != '\t')
91 	bp++;
92       if (!*bp)
93 	continue;
94       while (*bp == ' ' || *bp == '\t')
95 	bp++;
96       fn = bp;
97       if (strncmp(fn, comp, compl) != 0 || fn[compl] != '/')
98 	continue;
99       bp += compl + 1;
100       if (strncmp(bp, binarydir, lbinarydir))
101 	continue;
102       bp += lbinarydir;
103       if (!strcmp(bp, "Packages") || !strcmp(bp, "Packages.gz"))
104 	{
105 	  unsigned char curchksum[32];
106 	  int curl;
107 	  if (filename && !strcmp(bp, "Packages"))
108 	    continue;
109 	  curl = solv_chksum_len(curchksumtype);
110 	  if (!curl || (chksumtype && solv_chksum_len(chksumtype) > curl))
111 	    continue;
112           if (solv_hex2bin((const char **)&ch, curchksum, sizeof(curchksum)) != curl)
113 	    continue;
114 	  solv_free(filename);
115 	  filename = strdup(fn);
116 	  chksumtype = curchksumtype;
117 	  memcpy(chksum, curchksum, curl);
118 	}
119     }
120   free(binarydir);
121   if (filename)
122     {
123       fn = solv_dupjoin("/", filename, 0);
124       solv_free(filename);
125       filename = solv_dupjoin("dists/", cinfo->name, fn);
126       solv_free(fn);
127     }
128   if (!chksumtype)
129     chksum = solv_free(chksum);
130   *chksump = chksum;
131   *chksumtypep = chksumtype;
132   return filename;
133 }
134 
135 int
debian_load(struct repoinfo * cinfo,Pool ** sigpoolp)136 debian_load(struct repoinfo *cinfo, Pool **sigpoolp)
137 {
138   Repo *repo = cinfo->repo;
139   Pool *pool = repo->pool;
140   const char *filename;
141   const unsigned char *filechksum;
142   Id filechksumtype;
143   FILE *fp, *fpr;
144   int j;
145 
146   printf("debian repo '%s':", cinfo->alias);
147   fflush(stdout);
148   filename = solv_dupjoin("dists/", cinfo->name, "/Release");
149   if ((fpr = curlfopen(cinfo, filename, 0, 0, 0, 0)) == 0)
150     {
151       printf(" no Release file\n");
152       free((char *)filename);
153       cinfo->incomplete = 1;
154       return 0;
155     }
156   solv_free((char *)filename);
157   if (cinfo->repo_gpgcheck)
158     {
159       filename = solv_dupjoin("dists/", cinfo->name, "/Release.gpg");
160       if (!downloadchecksig(cinfo, fpr, filename, sigpoolp))
161 	{
162 	  fclose(fpr);
163 	  solv_free((char *)filename);
164 	  cinfo->incomplete = 1;
165 	  return 0;
166 	}
167       solv_free((char *)filename);
168     }
169   calc_cookie_fp(fpr, REPOKEY_TYPE_SHA256, cinfo->cookie);
170   cinfo->cookieset = 1;
171   if (usecachedrepo(cinfo, 0, 1))
172     {
173       printf(" cached\n");
174       fclose(fpr);
175       return 1;
176     }
177   printf(" fetching\n");
178   for (j = 0; j < cinfo->ncomponents; j++)
179     {
180       if (!(filename = debian_find_component(cinfo, fpr, cinfo->components[j], &filechksum, &filechksumtype)))
181 	{
182 	  printf("[component %s not found]\n", cinfo->components[j]);
183 	  continue;
184 	}
185       if ((fp = curlfopen(cinfo, filename, 1, filechksum, filechksumtype, 1)) != 0)
186 	{
187 	  if (repo_add_debpackages(repo, fp, 0))
188 	    {
189 	      printf("component %s: %s\n", cinfo->components[j], pool_errstr(pool));
190 	      cinfo->incomplete = 1;
191 	    }
192 	  fclose(fp);
193 	}
194       solv_free((char *)filechksum);
195       solv_free((char *)filename);
196     }
197   fclose(fpr);
198   writecachedrepo(cinfo, 0, 0);
199   return 1;
200 }
201 
202 #endif
203