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 "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"
58 extern ThreeBarProgressPage Progress
;
63 check_for_cached (packagesource
& pkgsource
)
66 1) is there a legacy version in the cache dir available.
67 (Note that the cache dir is represented by a mirror site of
72 if (pkgsource
.Cached())
75 String prefix
= String ("file://") + local_dir
+ "/";
77 if ((size
= get_file_size (prefix
+ pkgsource
.Canonical ())) > 0)
78 if (size
== pkgsource
.size
)
80 pkgsource
.set_cached (prefix
+ pkgsource
.Canonical ());
85 2) is there a version from one of the selected mirror sites available ?
87 for (size_t n
= 1; n
<= pkgsource
.sites
.number (); n
++)
89 String fullname
= prefix
+
90 rfc1738_escape_part (pkgsource
.sites
[n
]->key
) + "/" +
91 pkgsource
.Canonical ();
92 if ((size
= get_file_size (fullname
)) > 0)
93 if (size
== pkgsource
.size
)
95 if (pkgsource
.md5
.isSet())
97 // check the MD5 sum of the cached file here
98 io_stream
*thefile
= io_stream::open (fullname
, "rb");
104 unsigned char buffer
[16384];
106 while ((count
= thefile
->read (buffer
, 16384)) > 0)
107 md5_append (&pns
, buffer
, count
);
110 throw new Exception ("__LINE__ __FILE__", (String ("IO Error reading ") + pkgsource
.Cached()).cstr_oneuse(), APPERR_IO_ERROR
);
112 md5_byte_t tempdigest
[16];
113 md5_finish(&pns
, tempdigest
);
115 tempMD5
.set (tempdigest
);
117 log (LOG_BABBLE
, String ("For file '") + fullname
+
118 " ini digest is " + pkgsource
.md5
.print() +
119 " file digest is " + tempMD5
.print());
121 if (pkgsource
.md5
!= tempMD5
)
122 throw new Exception ("__LINE__ __FILE__", (String ("MD5 Checksum failure for ") + pkgsource
.Cached()).cstr_oneuse(), APPERR_CORRUPT_PACKAGE
);
125 set_cached (fullname
);
132 /* download a file from a mirror site to the local cache. */
134 download_one (packagesource
& pkgsource
, HWND owner
)
138 if (check_for_cached (pkgsource
))
141 catch (Exception
* e
)
143 // We know what to do with these..
144 if (e
->errNo() == APPERR_CORRUPT_PACKAGE
)
146 fatal (owner
, IDS_CORRUPT_PACKAGE
, pkgsource
.Canonical());
149 // Unexpected exception.
152 /* try the download sites one after another */
155 for (size_t n
= 1; n
<= pkgsource
.sites
.number () && !success
; n
++)
157 String
const local
= local_dir
+ "/" +
158 rfc1738_escape_part (pkgsource
.sites
[n
]->
160 pkgsource
.Canonical ();
161 io_stream::mkpath_p (PATH_TO_FILE
, String ("file://") + local
);
163 if (get_url_to_file(pkgsource
.sites
[n
]->key
+ "/" +
164 pkgsource
.Canonical (),
165 local
+ ".tmp", pkgsource
.size
, owner
))
167 /* FIXME: note new source ? */
172 size_t size
= get_file_size (String("file://") + local
+ ".tmp");
173 if (size
== pkgsource
.size
)
175 log (LOG_PLAIN
, String ("Downloaded ") + local
);
176 if (_access (local
.cstr_oneuse(), 0) == 0)
177 remove (local
.cstr_oneuse());
178 rename ((local
+ ".tmp").cstr_oneuse(), local
.cstr_oneuse());
180 pkgsource
.set_cached (String ("file://") + local
);
181 // FIXME: move the downloaded file to the
182 // original locations - without the mirror site dir in the way
188 "Download %s wrong size (%u actual vs %d expected)",
189 local
.cstr_oneuse(), size
, pkgsource
.size
);
190 remove ((local
+ ".tmp").cstr_oneuse());
197 /* FIXME: Do we want to note this? if so how? */
202 do_download_thread (HINSTANCE h
, HWND owner
)
205 total_download_bytes
= 0;
206 total_download_bytes_sofar
= 0;
209 /* calculate the amount needed */
210 for (size_t n
= 1; n
<= db
.packages
.number (); n
++)
212 packagemeta
& pkg
= *db
.packages
[n
];
213 if (pkg
.desired
&& (pkg
.desired
->srcpicked
|| pkg
.desired
->binpicked
))
215 packageversion
*version
= pkg
.desired
;
218 if (!check_for_cached (version
->bin
) && pkg
.desired
->binpicked
)
219 total_download_bytes
+= version
->bin
.size
;
220 if (!check_for_cached (version
->src
) && pkg
.desired
->srcpicked
)
221 total_download_bytes
+= version
->src
.size
;
223 catch (Exception
* e
)
225 // We know what to do with these..
226 if (e
->errNo() == APPERR_CORRUPT_PACKAGE
)
227 fatal (owner
, IDS_CORRUPT_PACKAGE
, pkg
.name
.cstr_oneuse());
228 // Unexpected exception.
234 /* and do the download. FIXME: This here we assign a new name for the cached version
235 * and check that above.
237 for (size_t n
= 1; n
<= db
.packages
.number (); n
++)
239 packagemeta
& pkg
= *db
.packages
[n
];
240 if (pkg
.desired
&& (pkg
.desired
->srcpicked
|| pkg
.desired
->binpicked
))
243 packageversion
*version
= pkg
.desired
;
244 if (version
->binpicked
)
245 e
+= download_one (version
->bin
, owner
);
246 if (version
->srcpicked
)
247 e
+= download_one (version
->src
, owner
);
251 pkg
->action
= ACTION_ERROR
;
258 if (yesno (owner
, IDS_DOWNLOAD_INCOMPLETE
) == IDYES
)
260 next_dialog
= IDD_SITE
;
265 if (source
== IDC_SOURCE_DOWNLOAD
)
268 exit_msg
= IDS_DOWNLOAD_INCOMPLETE
;
270 exit_msg
= IDS_DOWNLOAD_COMPLETE
;
274 next_dialog
= IDD_S_INSTALL
;
278 do_download_reflector (void *p
)
281 context
= (HANDLE
*) p
;
283 do_download_thread ((HINSTANCE
) context
[0], (HWND
) context
[1]);
285 // Tell the progress page that we're done downloading
286 Progress
.PostMessage (WM_APP_DOWNLOAD_THREAD_COMPLETE
, 0, next_dialog
);
291 static HANDLE context
[2];
294 do_download (HINSTANCE h
, HWND owner
)
300 CreateThread (NULL
, 0, do_download_reflector
, context
, 0, &threadID
);