]> cygwin.com Git - cygwin-apps/setup.git/blame - download.cc
2002-05-02 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / download.cc
CommitLineData
23c9e63c 1/*
9fe1181b 2 * Copyright (c) 2000, 2001, Red Hat, Inc.
23c9e63c
DD
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by DJ Delorie <dj@cygnus.com>
13 *
14 */
15
16/* The purpose of this file is to download all the files we need to
17 do the installation. */
18
b24c88b3
RC
19#if 0
20static const char *cvsid =
21 "\n%%% $Id$\n";
22#endif
8507f105 23
23c9e63c
DD
24#include "win32.h"
25
26#include <stdio.h>
42bf5b92 27#include <unistd.h>
ab57ceaa 28#include <process.h>
23c9e63c
DD
29
30#include "resource.h"
31#include "msg.h"
32#include "ini.h"
33#include "dialog.h"
3c054baf 34#include "String++.h"
23c9e63c
DD
35#include "geturl.h"
36#include "state.h"
37#include "mkdir.h"
89b1a15b 38#include "log.h"
341988b9 39#include "filemanip.h"
42bf5b92 40#include "port.h"
23c9e63c 41
bb849dbd
RC
42#include "io_stream.h"
43
44#include "package_db.h"
45#include "package_meta.h"
46#include "package_version.h"
47#include "package_source.h"
48
49#include "rfc1738.h"
50
ab57ceaa 51#include "threebar.h"
58ee6135
RC
52
53#include "md5.h"
54
55#include "Exception.h"
56
57#include "download.h"
58
ab57ceaa
RC
59extern ThreeBarProgressPage Progress;
60
bb849dbd
RC
61/* 0 on failure
62 */
58ee6135 63int
bb849dbd 64check_for_cached (packagesource & pkgsource)
3b9077d4 65{
bb849dbd
RC
66 /* search algo:
67 1) is there a legacy version in the cache dir available.
68 (Note that the cache dir is represented by a mirror site of
69 file://local_dir
70 */
3b9077d4 71
58ee6135
RC
72 // Already found one.
73 if (pkgsource.Cached())
74 return 1;
75
88a77116 76 DWORD size;
bb849dbd 77 if ((size =
3c054baf 78 get_file_size (local_dir + "/" + pkgsource.Canonical ())) >
bb849dbd
RC
79 0)
80 if (size == pkgsource.size)
81 {
82 pkgsource.
3c054baf 83 set_cached (String ("file://") + local_dir + "/" + pkgsource.Canonical ());
bb849dbd
RC
84 return 1;
85 }
3b9077d4 86
bb849dbd
RC
87 /*
88 2) is there a version from one of the selected mirror sites available ?
89 */
90 for (size_t n = 1; n <= pkgsource.sites.number (); n++)
58ee6135
RC
91 {
92 String fullname = local_dir + "/" +
93 rfc1738_escape_part (pkgsource.sites[n]->key) + "/" +
94 pkgsource.Canonical ();
bb849dbd 95 if ((size =
58ee6135 96 get_file_size (fullname)) > 0)
bb849dbd
RC
97 if (size == pkgsource.size)
98 {
58ee6135
RC
99 if (pkgsource.md5.isSet())
100 {
101 // check the MD5 sum of the cached file here
102 io_stream *thefile = io_stream::open (String("file://") + fullname, "rb");
103 if (!thefile)
104 return 0;
105 md5_state_t pns;
106 md5_init (&pns);
107
108 unsigned char buffer[16384];
109 ssize_t count;
110 while ((count = thefile->read (buffer, 16384)) > 0)
111 md5_append (&pns, buffer, count);
112 delete thefile;
113 if (count < 0)
114 throw new Exception ("__LINE__ __FILE__", (String ("IO Error reading ") + pkgsource.Cached()).cstr_oneuse(), APPERR_IO_ERROR);
115
116 md5_byte_t tempdigest[16];
117 md5_finish(&pns, tempdigest);
118 md5 tempMD5;
119 tempMD5.set (tempdigest);
120
121 log (LOG_BABBLE, String ("For file") + pkgsource.Cached() +
122 " ini digest is" + pkgsource.md5.print() +
123 " file digest is " + tempMD5.print());
124
125 if (pkgsource.md5 != tempMD5)
126 throw new Exception ("__LINE__ __FILE__", (String ("MD5 Checksum failure for ") + pkgsource.Cached()).cstr_oneuse(), APPERR_CORRUPT_PACKAGE);
127 }
bb849dbd 128 pkgsource.
58ee6135 129 set_cached (String ("file://") + fullname );
bb849dbd
RC
130 return 1;
131 }
58ee6135 132 }
bb849dbd
RC
133 return 0;
134}
135
136/* download a file from a mirror site to the local cache. */
137static int
ab57ceaa 138download_one (packagesource & pkgsource, HWND owner)
bb849dbd 139{
58ee6135
RC
140 try
141 {
142 if (check_for_cached (pkgsource))
143 return 0;
144 }
145 catch (Exception * e)
146 {
147 // We know what to do with these..
148 if (e->errNo() == APPERR_CORRUPT_PACKAGE)
149 {
150 fatal (owner, IDS_CORRUPT_PACKAGE, pkgsource.Canonical());
151 return 1;
152 }
153 // Unexpected exception.
154 throw e;
155 }
bb849dbd
RC
156 /* try the download sites one after another */
157
158 int success = 0;
159 for (size_t n = 1; n <= pkgsource.sites.number () && !success; n++)
d4a4527d 160 {
3c054baf 161 String const local = local_dir + "/" +
ab57ceaa 162 rfc1738_escape_part (pkgsource.sites[n]->
3c054baf
RC
163 key) + "/" +
164 pkgsource.Canonical ();
1ac649ed 165 io_stream::mkpath_p (PATH_TO_FILE, String ("file://") + local);
3c054baf 166
1ac649ed
RC
167 if (get_url_to_file(pkgsource.sites[n]->key + "/" +
168 pkgsource.Canonical (),
169 local + ".tmp", pkgsource.size, owner))
3b9077d4 170 {
bb849dbd
RC
171 /* FIXME: note new source ? */
172 continue;
3b9077d4
DD
173 }
174 else
175 {
3c054baf 176 size_t size = get_file_size (local + ".tmp");
bb849dbd
RC
177 if (size == pkgsource.size)
178 {
1ac649ed 179 log (LOG_PLAIN, String ("Downloaded ") + local);
3c054baf
RC
180 if (_access (local.cstr_oneuse(), 0) == 0)
181 remove (local.cstr_oneuse());
182 rename ((local + ".tmp").cstr_oneuse(), local.cstr_oneuse());
bb849dbd 183 success = 1;
3c054baf
RC
184 pkgsource.set_cached (String ("file://") + local);
185 // FIXME: move the downloaded file to the
186 // original locations - without the mirror site dir in the way
bb849dbd
RC
187 continue;
188 }
189 else
190 {
1ac649ed
RC
191 log (LOG_PLAIN,
192 "Download %s wrong size (%u actual vs %d expected)",
3c054baf
RC
193 local.cstr_oneuse(), size, pkgsource.size);
194 remove ((local + ".tmp").cstr_oneuse());
bb849dbd
RC
195 continue;
196 }
3b9077d4
DD
197 }
198 }
bb849dbd
RC
199 if (success)
200 return 0;
201 /* FIXME: Do we want to note this? if so how? */
202 return 1;
3b9077d4
DD
203}
204
ab57ceaa
RC
205static void
206do_download_thread (HINSTANCE h, HWND owner)
23c9e63c 207{
2a1a01e0 208 int errors = 0;
2f9645a1
CV
209 total_download_bytes = 0;
210 total_download_bytes_sofar = 0;
211
bb849dbd
RC
212 packagedb db;
213 /* calculate the amount needed */
3bab9a49 214 for (size_t n = 1; n <= db.packages.number (); n++)
cbfc4215 215 {
ab57ceaa 216 packagemeta & pkg = *db.packages[n];
cbfc4215 217 if (pkg.desired && (pkg.desired->srcpicked || pkg.desired->binpicked))
ab57ceaa
RC
218 {
219 packageversion *version = pkg.desired;
58ee6135
RC
220 try
221 {
222 if (!check_for_cached (version->bin) && pkg.desired->binpicked)
223 total_download_bytes += version->bin.size;
224 if (!check_for_cached (version->src) && pkg.desired->srcpicked)
225 total_download_bytes += version->src.size;
226 }
227 catch (Exception * e)
228 {
229 // We know what to do with these..
230 if (e->errNo() == APPERR_CORRUPT_PACKAGE)
231 fatal (owner, IDS_CORRUPT_PACKAGE, pkg.name.cstr_oneuse());
232 // Unexpected exception.
233 throw e;
234 }
ab57ceaa 235 }
cbfc4215 236 }
23c9e63c 237
bb849dbd
RC
238 /* and do the download. FIXME: This here we assign a new name for the cached version
239 * and check that above.
240 */
3bab9a49 241 for (size_t n = 1; n <= db.packages.number (); n++)
cbfc4215 242 {
ab57ceaa
RC
243 packagemeta & pkg = *db.packages[n];
244 if (pkg.desired && (pkg.desired->srcpicked || pkg.desired->binpicked))
245 {
246 int e = 0;
247 packageversion *version = pkg.desired;
248 if (version->binpicked)
249 e += download_one (version->bin, owner);
250 if (version->srcpicked)
251 e += download_one (version->src, owner);
252 errors += e;
bb849dbd 253#if 0
ab57ceaa
RC
254 if (e)
255 pkg->action = ACTION_ERROR;
bb849dbd 256#endif
ab57ceaa 257 }
cbfc4215 258 }
23c9e63c 259
2a1a01e0
DD
260 if (errors)
261 {
ab57ceaa 262 if (yesno (owner, IDS_DOWNLOAD_INCOMPLETE) == IDYES)
2a1a01e0
DD
263 {
264 next_dialog = IDD_SITE;
265 return;
266 }
267 }
268
bf1d5889
DD
269 if (source == IDC_SOURCE_DOWNLOAD)
270 {
2a1a01e0
DD
271 if (errors)
272 exit_msg = IDS_DOWNLOAD_INCOMPLETE;
273 else
274 exit_msg = IDS_DOWNLOAD_COMPLETE;
bf1d5889
DD
275 next_dialog = 0;
276 }
277 else
278 next_dialog = IDD_S_INSTALL;
23c9e63c 279}
ab57ceaa 280
45e01f23 281static DWORD WINAPI
ab57ceaa
RC
282do_download_reflector (void *p)
283{
284 HANDLE *context;
285 context = (HANDLE *) p;
286
287 do_download_thread ((HINSTANCE) context[0], (HWND) context[1]);
288
289 // Tell the progress page that we're done downloading
290 Progress.PostMessage (WM_APP_DOWNLOAD_THREAD_COMPLETE, 0, next_dialog);
291
45e01f23 292 ExitThread(0);
ab57ceaa
RC
293}
294
295static HANDLE context[2];
296
297void
298do_download (HINSTANCE h, HWND owner)
299{
300 context[0] = h;
301 context[1] = owner;
302
45e01f23
RC
303 DWORD threadID;
304 CreateThread (NULL, 0, do_download_reflector, context, 0, &threadID);
ab57ceaa 305}
This page took 0.065542 seconds and 5 git commands to generate.