2 * Copyright (c) 2000, 2001, Red Hat, Inc.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by DJ Delorie <dj@cygnus.com>
16 /* The purpose of this file is to download all the files we need to
17 do the installation. */
20 static const char *cvsid
=
38 #include "LogSingleton.h"
39 #include "filemanip.h"
41 #include "io_stream.h"
43 #include "package_db.h"
44 #include "package_meta.h"
45 #include "package_version.h"
46 #include "package_source.h"
54 #include "Exception.h"
56 extern ThreeBarProgressPage Progress
;
60 validateCachedPackage (String
const &fullname
, packagesource
& pkgsource
)
62 if (pkgsource
.md5
.isSet())
64 // check the MD5 sum of the cached file here
65 io_stream
*thefile
= io_stream::open (fullname
, "rb");
71 log (LOG_BABBLE
) << "Checking MD5 for " << fullname
<< endLog
;
73 Progress
.SetText1 ((String ("Checking MD5 for ") + pkgsource
.Base()).cstr_oneuse());
74 Progress
.SetText4 ("Progress:");
77 unsigned char buffer
[16384];
79 while ((count
= thefile
->read (buffer
, 16384)) > 0)
81 md5_append (&pns
, buffer
, count
);
82 Progress
.SetBar1 (thefile
->tell(), thefile
->get_size());
86 throw new Exception ("__LINE__ __FILE__", (String ("IO Error reading ") + pkgsource
.Cached()).cstr_oneuse(), APPERR_IO_ERROR
);
88 md5_byte_t tempdigest
[16];
89 md5_finish(&pns
, tempdigest
);
91 tempMD5
.set (tempdigest
);
93 log (LOG_BABBLE
) << "For file '" << fullname
<<
94 " ini digest is " << pkgsource
.md5
.print() <<
95 " file digest is " << tempMD5
.print() << endLog
;
97 if (pkgsource
.md5
!= tempMD5
)
106 check_for_cached (packagesource
& pkgsource
)
109 1) is there a legacy version in the cache dir available.
110 (Note that the cache dir is represented by a mirror site of
114 // Already found one.
115 if (pkgsource
.Cached())
118 String prefix
= String ("file://") + local_dir
+ "/";
120 if ((size
= get_file_size (prefix
+ pkgsource
.Canonical ())) > 0)
121 if (size
== pkgsource
.size
)
123 if (validateCachedPackage (prefix
+ pkgsource
.Canonical (), pkgsource
))
124 pkgsource
.set_cached (prefix
+ pkgsource
.Canonical ());
126 throw new Exception ("__LINE__ __FILE__", (String ("Package validation failure for ") + prefix
+ pkgsource
.Canonical ()).cstr_oneuse(), APPERR_CORRUPT_PACKAGE
);
131 2) is there a version from one of the selected mirror sites available ?
133 for (packagesource::sitestype::const_iterator n
= pkgsource
.sites
.begin();
134 n
!= pkgsource
.sites
.end(); ++n
)
136 String fullname
= prefix
+ rfc1738_escape_part (n
->key
) + "/" +
137 pkgsource
.Canonical ();
138 if ((size
= get_file_size (fullname
)) > 0)
139 if (size
== pkgsource
.size
)
141 if (validateCachedPackage (fullname
, pkgsource
))
142 pkgsource
.set_cached (fullname
);
144 throw new Exception ("__LINE__ __FILE__", (String ("Package validation failure for ") + fullname
).cstr_oneuse(), APPERR_CORRUPT_PACKAGE
);
151 /* download a file from a mirror site to the local cache. */
153 download_one (packagesource
& pkgsource
, HWND owner
)
157 if (check_for_cached (pkgsource
))
160 catch (Exception
* e
)
162 // We know what to do with these..
163 if (e
->errNo() == APPERR_CORRUPT_PACKAGE
)
165 fatal (owner
, IDS_CORRUPT_PACKAGE
, pkgsource
.Canonical());
168 // Unexpected exception.
171 /* try the download sites one after another */
174 for (packagesource::sitestype::const_iterator n
= pkgsource
.sites
.begin();
175 n
!= pkgsource
.sites
.end() && !success
; ++n
)
177 String
const local
= local_dir
+ "/" +
178 rfc1738_escape_part (n
->key
) + "/" +
179 pkgsource
.Canonical ();
180 io_stream::mkpath_p (PATH_TO_FILE
, String ("file://") + local
);
182 if (get_url_to_file(n
->key
+ "/" + pkgsource
.Canonical (),
183 local
+ ".tmp", pkgsource
.size
, owner
))
185 /* FIXME: note new source ? */
190 size_t size
= get_file_size (String("file://") + local
+ ".tmp");
191 if (size
== pkgsource
.size
)
193 log (LOG_PLAIN
) << "Downloaded " << local
<< endLog
;
194 if (_access (local
.cstr_oneuse(), 0) == 0)
195 remove (local
.cstr_oneuse());
196 rename ((local
+ ".tmp").cstr_oneuse(), local
.cstr_oneuse());
198 pkgsource
.set_cached (String ("file://") + local
);
199 // FIXME: move the downloaded file to the
200 // original locations - without the mirror site dir in the way
205 log (LOG_PLAIN
) << "Download " << local
<< " wrong size (" <<
206 size
<< " actual vs " << pkgsource
.size
<< " expected)" <<
208 remove ((local
+ ".tmp").cstr_oneuse());
215 /* FIXME: Do we want to note this? if so how? */
220 do_download_thread (HINSTANCE h
, HWND owner
)
223 total_download_bytes
= 0;
224 total_download_bytes_sofar
= 0;
227 /* calculate the amount needed */
228 for (vector
<packagemeta
*>::iterator i
= db
.packages
.begin ();
229 i
!= db
.packages
.end (); ++i
)
231 packagemeta
& pkg
= **i
;
232 if (pkg
.desired
.changeRequested())
234 packageversion version
= pkg
.desired
;
235 packageversion sourceversion
= version
.sourcePackage();
238 if (version
.picked() && !check_for_cached (*version
.source()))
239 total_download_bytes
+= version
.source()->size
;
240 if (sourceversion
.picked ()
241 && !check_for_cached (*sourceversion
.source()))
242 total_download_bytes
+= sourceversion
.source()->size
;
244 catch (Exception
* e
)
246 // We know what to do with these..
247 if (e
->errNo() == APPERR_CORRUPT_PACKAGE
)
248 fatal (owner
, IDS_CORRUPT_PACKAGE
, pkg
.name
.cstr_oneuse());
249 // Unexpected exception.
255 /* and do the download. FIXME: This here we assign a new name for the cached version
256 * and check that above.
258 for (vector
<packagemeta
*>::iterator i
= db
.packages
.begin ();
259 i
!= db
.packages
.end (); ++i
)
261 packagemeta
& pkg
= **i
;
262 if (pkg
.desired
.changeRequested())
265 packageversion version
= pkg
.desired
;
266 packageversion sourceversion
= version
.sourcePackage();
267 if (version
.picked())
268 e
+= download_one (*version
.source(), owner
);
269 if (sourceversion
&& sourceversion
.picked())
270 e
+= download_one (*sourceversion
.source(), owner
);
274 pkg
->action
= ACTION_ERROR
;
281 if (yesno (owner
, IDS_DOWNLOAD_INCOMPLETE
) == IDYES
)
283 next_dialog
= IDD_SITE
;
288 if (source
== IDC_SOURCE_DOWNLOAD
)
291 exit_msg
= IDS_DOWNLOAD_INCOMPLETE
;
293 exit_msg
= IDS_DOWNLOAD_COMPLETE
;
297 next_dialog
= IDD_S_INSTALL
;
301 do_download_reflector (void *p
)
304 context
= (HANDLE
*) p
;
306 do_download_thread ((HINSTANCE
) context
[0], (HWND
) context
[1]);
308 // Tell the progress page that we're done downloading
309 Progress
.PostMessage (WM_APP_DOWNLOAD_THREAD_COMPLETE
, 0, next_dialog
);
314 static HANDLE context
[2];
317 do_download (HINSTANCE h
, HWND owner
)
323 CreateThread (NULL
, 0, do_download_reflector
, context
, 0, &threadID
);