]> cygwin.com Git - cygwin-apps/setup.git/blobdiff - download.cc
Add an option to set the GUI language
[cygwin-apps/setup.git] / download.cc
index 4a36e641ed784f444e8d6ac8c7fab3cac01fd632..fd1253b98f3cbc996826059aae38274186f5187e 100644 (file)
 
 #include "package_db.h"
 #include "package_meta.h"
-#include "package_version.h"
 #include "package_source.h"
 
 #include "threebar.h"
 
 #include "Exception.h"
 
-#include "getopt++/BoolOption.h"
-
-using namespace std;
-
 extern ThreeBarProgressPage Progress;
 
-BoolOption IncludeSource (false, 'I', "include-source", "Automatically include source download");
-
+// Return true if selected checks pass, false if they don't and the
+// user chooses to delete the file; otherwise throw an exception.
 static bool
-validateCachedPackage (const std::string& fullname, packagesource & pkgsource)
+validateCachedPackage (const std::string& fullname, packagesource & pkgsource,
+                      HWND owner, bool check_hash, bool check_size)
 {
-  DWORD size = get_file_size(fullname);
-  if (size != pkgsource.size)
-  {
-    Log (LOG_BABBLE) << "INVALID PACKAGE: " << fullname
-      << " - Size mismatch: Ini-file: " << pkgsource.size
-      << " != On-disk: " << size << endLog;
-    return false;
-  }
-  return true;
+  try
+    {
+      if (check_size)
+       pkgsource.check_size_and_cache (fullname);
+      if (check_hash)
+       pkgsource.check_hash ();
+      return true;
+    }
+  catch (Exception *e)
+    {
+      pkgsource.set_cached ("");
+      const char *filename = fullname.c_str ();
+      if (strncmp (filename, "file://", 7) == 0)
+       filename += 7;
+      if (e->errNo() == APPERR_CORRUPT_PACKAGE
+         && yesno (owner, IDS_QUERY_CORRUPT, filename) == IDYES)
+       remove (filename);
+      else
+       throw e;
+    }
+  return false;
 }
 
-/* 0 on failure
+/* 0 if not cached; may throw exception if validation fails.
  */
 int
-check_for_cached (packagesource & pkgsource, bool mirror_mode)
+check_for_cached (packagesource & pkgsource, HWND owner, bool mirror_mode,
+                 bool check_hash)
 {
-  // Already found one.
-  if (pkgsource.Cached())
-    return 1;
+  /* If the packagesource doesn't have a filename, it can't possibly be in the
+     cache */
+  if (!pkgsource.Canonical())
+    {
+      return 0;
+    }
 
   /* Note that the cache dir is represented by a mirror site of file://local_dir */
   std::string prefix = "file://" + local_dir + "/";
-  std::string fullname = prefix + (pkgsource.Canonical() ? pkgsource.Canonical() : "");
+  std::string fullname = prefix + pkgsource.Canonical();
 
   if (mirror_mode)
     {
       /* Just assume correctness of mirror. */
-      pkgsource.set_cached (fullname);
+      if (!pkgsource.Cached())
+       pkgsource.set_cached (fullname);
       return 1;
     }
 
+  // Already found one, which we can assume to have the right size.
+  if (pkgsource.Cached())
+    {
+      if (validateCachedPackage (pkgsource.Cached(), pkgsource, owner,
+                                check_hash, false))
+       return 1;
+      // If we get here, pkgsource.Cached() was corrupt and deleted.
+      pkgsource.set_cached ("");
+    }
+
   /*
      1) is there a legacy version in the cache dir available.
   */
   if (io_stream::exists (fullname))
     {
-      if (validateCachedPackage (fullname, pkgsource))
-        pkgsource.set_cached (fullname);
-      else
-        throw new Exception (TOSTRING(__LINE__) " " __FILE__,
-            "Package validation failure for " + fullname,
-            APPERR_CORRUPT_PACKAGE);
-      return 1;
+      if (validateCachedPackage (fullname, pkgsource, owner, check_hash, true))
+       return 1;
+      // If we get here, fullname was corrupt and deleted, but it
+      // might have been cached.
+      pkgsource.set_cached ("");
     }
 
   /*
@@ -111,15 +132,14 @@ check_for_cached (packagesource & pkgsource, bool mirror_mode)
     std::string fullname = prefix + rfc1738_escape_part (n->key) + "/" +
       pkgsource.Canonical ();
     if (io_stream::exists(fullname))
-    {
-      if (validateCachedPackage (fullname, pkgsource))
-        pkgsource.set_cached (fullname);
-      else
-        throw new Exception (TOSTRING(__LINE__) " " __FILE__,
-            "Package validation failure for " + fullname,
-            APPERR_CORRUPT_PACKAGE);
-      return 1;
-    }
+       {
+         if (validateCachedPackage (fullname, pkgsource, owner, check_hash,
+                                    true))
+           return 1;
+         // If we get here, fullname was corrupt and deleted, but it
+         // might have been cached.
+         pkgsource.set_cached ("");
+       }
   }
   return 0;
 }
@@ -130,7 +150,7 @@ download_one (packagesource & pkgsource, HWND owner)
 {
   try
     {
-      if (check_for_cached (pkgsource))
+      if (check_for_cached (pkgsource, owner))
         return 0;
     }
   catch (Exception * e)
@@ -163,26 +183,36 @@ download_one (packagesource & pkgsource, HWND owner)
        }
       else
        {
-         size_t size = get_file_size ("file://" + local + ".tmp");
-         if (size == pkgsource.size)
+         try
            {
-             Log (LOG_PLAIN) << "Downloaded " << local << endLog;
              if (_access (local.c_str(), 0) == 0)
                remove (local.c_str());
              rename ((local + ".tmp").c_str(), local.c_str());
+             pkgsource.check_size_and_cache ("file://" + local);
+             pkgsource.check_hash ();
+             Log (LOG_PLAIN) << "Downloaded " << local << endLog;
              success = 1;
-             pkgsource.set_cached ("file://" + local);
              // FIXME: move the downloaded file to the 
              //  original locations - without the mirror site dir in the way
              continue;
            }
-         else
+         catch (Exception *e)
            {
-             Log (LOG_PLAIN) << "Download " << local << " wrong size (" <<
-               size << " actual vs " << pkgsource.size << " expected)" << 
-               endLog;
-             remove ((local + ".tmp").c_str());
-             continue;
+             remove (local.c_str());
+             pkgsource.set_cached ("");
+             if (e->errNo() == APPERR_CORRUPT_PACKAGE)
+               {
+                 Log (LOG_PLAIN) << "Downloaded file " << local
+                                 << " is corrupt; deleting." << endLog;
+                 continue;
+               }
+             else
+               {
+                 Log (LOG_PLAIN) << "Unexpected exception while validating "
+                                 << "downloaded file " << local
+                                 << "; deleting." << endLog;
+                 throw e;
+               }
            }
        }
     }
@@ -248,64 +278,47 @@ do_download_thread (HINSTANCE h, HWND owner)
   total_download_bytes_sofar = 0;
   download_failures.clear ();
 
-  Progress.SetText1 ("Checking for packages to download...");
+  Progress.SetText1 (IDS_PROGRESS_CHECKING);
   Progress.SetText2 ("");
   Progress.SetText3 ("");
 
   packagedb db;
-  /* calculate the amount needed */
-  for (packagedb::packagecollection::iterator i = db.packages.begin ();
-       i != db.packages.end (); ++i)
+  const SolverTransactionList &t = db.solution.transactions();
+
+  /* calculate the total size of the download */
+  for (SolverTransactionList::const_iterator i = t.begin (); i != t.end (); ++i)
     {
-      packagemeta & pkg = *(i->second);
-      if (pkg.desired && (pkg.picked () || pkg.srcpicked ()))
-       {
-         packageversion version = pkg.desired;
-         packageversion sourceversion = version.sourcePackage();
-         try 
-           {
-             if (pkg.picked())
-               {
-                   if (!check_for_cached (*version.source()))
-                     total_download_bytes += version.source()->size;
-               }
-             if (pkg.srcpicked () || IncludeSource)
-               {
-                   if (!check_for_cached (*sourceversion.source()))
-                     total_download_bytes += sourceversion.source()->size;
-               }
-           }
-         catch (Exception * e)
-           {
-             // We know what to do with these..
-             if (e->errNo() == APPERR_CORRUPT_PACKAGE)
-               fatal (owner, IDS_CORRUPT_PACKAGE, pkg.name.c_str());
-             // Unexpected exception.
-             throw e;
-           }
-       }
+      if (i->type != SolverTransaction::transInstall)
+        continue;
+      packageversion version = i->version;
+
+      try
+        {
+          if (!check_for_cached (*version.source(), owner))
+            total_download_bytes += version.source()->size;
+        }
+      catch (Exception * e)
+        {
+          // We know what to do with these..
+          if (e->errNo() == APPERR_CORRUPT_PACKAGE)
+            fatal (owner, IDS_CORRUPT_PACKAGE, version.Name().c_str());
+          // 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 (packagedb::packagecollection::iterator i = db.packages.begin ();
-       i != db.packages.end (); ++i)
+  for (SolverTransactionList::const_iterator i = t.begin (); i != t.end (); ++i)
     {
-      packagemeta & pkg = *(i->second);
-      if (pkg.desired && (pkg.picked () || pkg.srcpicked ()))
+      if (i->type != SolverTransaction::transInstall)
+        continue;
+      packageversion version = i->version;
+
        {
          int e = 0;
-         packageversion version = pkg.desired;
-         packageversion sourceversion = version.sourcePackage();
-         if (pkg.picked())
-           {
-               e += download_one (*version.source(), owner);
-           }
-         if (sourceversion && (pkg.srcpicked() || IncludeSource))
-           {
-               e += download_one (*sourceversion.source (), owner);
-           }
+          e += download_one (*version.source(), owner);
          errors += e;
          if (e)
            download_failures.push_back (version);
@@ -369,6 +382,8 @@ do_download_reflector (void *p)
   HANDLE *context;
   context = (HANDLE *) p;
 
+  SetThreadUILanguage(langid);
+
   try
   {
     int next_dialog =
This page took 0.031438 seconds and 5 git commands to generate.