X-Git-Url: https://cygwin.com/git/?a=blobdiff_plain;f=download.cc;h=6a375a9c84172106369d039e1c58ee41388bfefb;hb=ec13f13ca57fba24a53d873e9aa80527fc0b8134;hp=0052de23627199df5c5f15513230687d0df55789;hpb=3bab9a49e8c2b470fbb7c92aea21b28d20f92b44;p=cygwin-apps%2Fsetup.git diff --git a/download.cc b/download.cc index 0052de23..6a375a9c 100644 --- a/download.cc +++ b/download.cc @@ -21,6 +21,8 @@ static const char *cvsid = "\n%%% $Id$\n"; #endif +#include "download.h" + #include "win32.h" #include @@ -29,15 +31,12 @@ static const char *cvsid = #include "resource.h" #include "msg.h" -#include "ini.h" #include "dialog.h" #include "String++.h" #include "geturl.h" #include "state.h" -#include "mkdir.h" -#include "log.h" +#include "LogSingleton.h" #include "filemanip.h" -#include "port.h" #include "io_stream.h" @@ -49,11 +48,61 @@ static const char *cvsid = #include "rfc1738.h" #include "threebar.h" + +#include "md5.h" + +#include "Exception.h" + extern ThreeBarProgressPage Progress; + +bool +validateCachedPackage (String const &fullname, packagesource & pkgsource) +{ + if (pkgsource.md5.isSet()) + { + // check the MD5 sum of the cached file here + io_stream *thefile = io_stream::open (fullname, "rb"); + if (!thefile) + return 0; + md5_state_t pns; + md5_init (&pns); + + log (LOG_BABBLE) << "Checking MD5 for " << fullname << endLog; + + Progress.SetText1 ((String ("Checking MD5 for ") + pkgsource.Base()).cstr_oneuse()); + Progress.SetText4 ("Progress:"); + Progress.SetBar1 (0); + + unsigned char buffer[16384]; + ssize_t count; + while ((count = thefile->read (buffer, 16384)) > 0) + { + md5_append (&pns, buffer, count); + Progress.SetBar1 (thefile->tell(), thefile->get_size()); + } + delete thefile; + if (count < 0) + throw new Exception ("__LINE__ __FILE__", (String ("IO Error reading ") + pkgsource.Cached()).cstr_oneuse(), APPERR_IO_ERROR); + + md5_byte_t tempdigest[16]; + md5_finish(&pns, tempdigest); + md5 tempMD5; + tempMD5.set (tempdigest); + + log (LOG_BABBLE) << "For file '" << fullname << + " ini digest is " << pkgsource.md5.print() << + " file digest is " << tempMD5.print() << endLog; + + if (pkgsource.md5 != tempMD5) + return false; + } + return true; +} + /* 0 on failure */ -static int +int check_for_cached (packagesource & pkgsource) { /* search algo: @@ -62,35 +111,40 @@ check_for_cached (packagesource & pkgsource) file://local_dir */ + // Already found one. + if (pkgsource.Cached()) + return 1; + + String prefix = String ("file://") + local_dir + "/"; DWORD size; - if ((size = - get_file_size (local_dir + "/" + pkgsource.Canonical ())) > - 0) + if ((size = get_file_size (prefix + pkgsource.Canonical ())) > 0) if (size == pkgsource.size) { - pkgsource. - set_cached (String ("file://") + local_dir + "/" + pkgsource.Canonical ()); + if (validateCachedPackage (prefix + pkgsource.Canonical (), pkgsource)) + pkgsource.set_cached (prefix + pkgsource.Canonical ()); + else + throw new Exception ("__LINE__ __FILE__", (String ("Package validation failure for ") + prefix + pkgsource.Canonical ()).cstr_oneuse(), APPERR_CORRUPT_PACKAGE); return 1; } /* 2) is there a version from one of the selected mirror sites available ? */ - for (size_t n = 1; n <= pkgsource.sites.number (); n++) - if ((size = - get_file_size (local_dir + "/" + - rfc1738_escape_part (pkgsource.sites[n]->key) + "/" + - pkgsource.Canonical ())) > 0) + for (packagesource::sitestype::const_iterator n = pkgsource.sites.begin(); + n != pkgsource.sites.end(); ++n) + { + String fullname = prefix + rfc1738_escape_part (n->key) + "/" + + pkgsource.Canonical (); + if ((size = get_file_size (fullname)) > 0) if (size == pkgsource.size) { - pkgsource. - set_cached (String ("file://") + local_dir + "/" + - rfc1738_escape_part (pkgsource.sites[n]-> - key) + "/" + - pkgsource.Canonical ()); + if (validateCachedPackage (fullname, pkgsource)) + pkgsource.set_cached (fullname ); + else + throw new Exception ("__LINE__ __FILE__", (String ("Package validation failure for ") + fullname).cstr_oneuse(), APPERR_CORRUPT_PACKAGE); return 1; } - + } return 0; } @@ -98,22 +152,34 @@ check_for_cached (packagesource & pkgsource) static int download_one (packagesource & pkgsource, HWND owner) { - if (check_for_cached (pkgsource) && source != IDC_SOURCE_DOWNLOAD) - return 0; - + try + { + if (check_for_cached (pkgsource)) + return 0; + } + catch (Exception * e) + { + // We know what to do with these.. + if (e->errNo() == APPERR_CORRUPT_PACKAGE) + { + fatal (owner, IDS_CORRUPT_PACKAGE, pkgsource.Canonical()); + return 1; + } + // Unexpected exception. + throw e; + } /* try the download sites one after another */ int success = 0; - for (size_t n = 1; n <= pkgsource.sites.number () && !success; n++) + for (packagesource::sitestype::const_iterator n = pkgsource.sites.begin(); + n != pkgsource.sites.end() && !success; ++n) { String const local = local_dir + "/" + - rfc1738_escape_part (pkgsource.sites[n]-> - key) + "/" + + rfc1738_escape_part (n->key) + "/" + pkgsource.Canonical (); io_stream::mkpath_p (PATH_TO_FILE, String ("file://") + local); - if (get_url_to_file(pkgsource.sites[n]->key + "/" + - pkgsource.Canonical (), + if (get_url_to_file(n->key + "/" + pkgsource.Canonical (), local + ".tmp", pkgsource.size, owner)) { /* FIXME: note new source ? */ @@ -121,10 +187,10 @@ download_one (packagesource & pkgsource, HWND owner) } else { - size_t size = get_file_size (local + ".tmp"); + size_t size = get_file_size (String("file://") + local + ".tmp"); if (size == pkgsource.size) { - log (LOG_PLAIN, String ("Downloaded ") + local); + log (LOG_PLAIN) << "Downloaded " << local << endLog; if (_access (local.cstr_oneuse(), 0) == 0) remove (local.cstr_oneuse()); rename ((local + ".tmp").cstr_oneuse(), local.cstr_oneuse()); @@ -136,9 +202,9 @@ download_one (packagesource & pkgsource, HWND owner) } else { - log (LOG_PLAIN, - "Download %s wrong size (%u actual vs %d expected)", - local.cstr_oneuse(), size, pkgsource.size); + log (LOG_PLAIN) << "Download " << local << " wrong size (" << + size << " actual vs " << pkgsource.size << " expected)" << + endLog; remove ((local + ".tmp").cstr_oneuse()); continue; } @@ -159,37 +225,70 @@ do_download_thread (HINSTANCE h, HWND owner) packagedb db; /* calculate the amount needed */ - for (size_t n = 1; n <= db.packages.number (); n++) + for (vector ::iterator i = db.packages.begin (); + i != db.packages.end (); ++i) { - packagemeta & pkg = *db.packages[n]; - if (pkg.desired && (pkg.desired->srcpicked || pkg.desired->binpicked)) + packagemeta & pkg = **i; + if (pkg.desired.changeRequested()) { - packageversion *version = pkg.desired; - if (! - (check_for_cached (version->bin) - && source != IDC_SOURCE_DOWNLOAD) && pkg.desired->binpicked) - total_download_bytes += version->bin.size; - if (! - (check_for_cached (version->src) - && source != IDC_SOURCE_DOWNLOAD) && pkg.desired->srcpicked) - total_download_bytes += version->src.size; + packageversion version = pkg.desired; + packageversion sourceversion = version.sourcePackage(); + try + { + if (version.picked()) + { + for (vector::iterator i = + version.sources ()->begin(); + i != version.sources ()->end(); ++i) + if (!check_for_cached (*i)) + total_download_bytes += i->size; + } + if (sourceversion.picked ()) + { + for (vector::iterator i = + sourceversion.sources ()->begin(); + i != sourceversion.sources ()->end(); ++i) + if (!check_for_cached (*i)) + total_download_bytes += i->size; + } + } + catch (Exception * e) + { + // We know what to do with these.. + if (e->errNo() == APPERR_CORRUPT_PACKAGE) + fatal (owner, IDS_CORRUPT_PACKAGE, pkg.name.cstr_oneuse()); + // Unexpected exception. + throw e; + } } } /* and do the download. FIXME: This here we assign a new name for the cached version * and check that above. */ - for (size_t n = 1; n <= db.packages.number (); n++) + for (vector ::iterator i = db.packages.begin (); + i != db.packages.end (); ++i) { - packagemeta & pkg = *db.packages[n]; - if (pkg.desired && (pkg.desired->srcpicked || pkg.desired->binpicked)) + packagemeta & pkg = **i; + if (pkg.desired.changeRequested()) { int e = 0; - packageversion *version = pkg.desired; - if (version->binpicked) - e += download_one (version->bin, owner); - if (version->srcpicked) - e += download_one (version->src, owner); + packageversion version = pkg.desired; + packageversion sourceversion = version.sourcePackage(); + if (version.picked()) + { + for (vector::iterator i = + version.sources ()->begin(); + i != version.sources ()->end(); ++i) + e += download_one (*i, owner); + } + if (sourceversion && sourceversion.picked()) + { + for (vector::iterator i = + sourceversion.sources ()->begin(); + i != sourceversion.sources ()->end(); ++i) + e += download_one (*i, owner); + } errors += e; #if 0 if (e) @@ -219,7 +318,7 @@ do_download_thread (HINSTANCE h, HWND owner) next_dialog = IDD_S_INSTALL; } -static void +static DWORD WINAPI do_download_reflector (void *p) { HANDLE *context; @@ -230,7 +329,7 @@ do_download_reflector (void *p) // Tell the progress page that we're done downloading Progress.PostMessage (WM_APP_DOWNLOAD_THREAD_COMPLETE, 0, next_dialog); - _endthread (); + ExitThread(0); } static HANDLE context[2]; @@ -241,5 +340,6 @@ do_download (HINSTANCE h, HWND owner) context[0] = h; context[1] = owner; - _beginthread (do_download_reflector, 0, context); + DWORD threadID; + CreateThread (NULL, 0, do_download_reflector, context, 0, &threadID); }