[PATCH setup 05/14] Hoist uninstall up to Installer::uninstallOne()

Jon Turney jon.turney@dronecode.org.uk
Wed May 31 10:53:00 GMT 2017


This calls packagemeta, which applies to packageversion (which delegates
through packageversion_ to cygpackage) to return lines from the .lst.gz file
(pretending that we know it contains a file list for that specific version)
and to remove the .lst.gz file when done.

Move this all up into Installer::uninstallOne(), where it's all in the same
place as the operation it is reversing, Installer::installOne().
---
 cygpackage.cc      | 46 +---------------------------------
 cygpackage.h       | 14 -----------
 install.cc         | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 package_meta.cc    | 70 ---------------------------------------------------
 package_meta.h     |  1 -
 package_version.cc | 21 ----------------
 package_version.h  |  9 -------
 7 files changed, 73 insertions(+), 161 deletions(-)

diff --git a/cygpackage.cc b/cygpackage.cc
index 56c1da8..32b9403 100644
--- a/cygpackage.cc
+++ b/cygpackage.cc
@@ -36,12 +36,8 @@ packagev (),
 canonical (),
 sdesc (),
 ldesc (),
-type (package_binary),
-listdata (),
-listfile ()
+type (package_binary)
 {
-  memset( getfilenamebuffer, '\0', CYG_PATH_MAX);
-
   /* FIXME: query the install database for the currently installed 
    * version details
    */
@@ -104,46 +100,6 @@ cygpackage::~cygpackage ()
 }
 
 const std::string
-cygpackage::getfirstfile ()
-{
-  if (listdata)
-    delete listdata;
-  listfile =
-    io_stream::open ("cygfile:///etc/setup/" + name + ".lst.gz", "rb", 0);
-  listdata = compress::decompress (listfile);
-  if (!listdata)
-    return std::string();
-  /* std::string(NULL) will crash, so be careful to test for that. */
-  const char *result = listdata->gets (getfilenamebuffer, sizeof (getfilenamebuffer));
-  if (result == NULL)
-    Log (LOG_PLAIN) << "Corrupt package listing for " << name << ", can't uninstall old files." << endLog;
-  return std::string (result ? result : "");
-}
-
-const std::string
-cygpackage::getnextfile ()
-{
-  if (listdata)
-  {
-    /* std::string(NULL) will crash, so be careful to test for that. */
-    const char *sz = listdata->gets (getfilenamebuffer,
-                                     sizeof (getfilenamebuffer));
-    if (sz)
-      return std::string(sz);
-  }
-  return std::string();
-}
-
-void
-cygpackage::uninstall ()
-{
-  if (listdata)
-    delete listdata;
-  listdata = 0;
-  io_stream::remove ("cygfile:///etc/setup/" + name + ".lst.gz");
-}
-
-const std::string
 cygpackage::Name ()
 {
   return name;
diff --git a/cygpackage.h b/cygpackage.h
index 4022472..c6d0657 100644
--- a/cygpackage.h
+++ b/cygpackage.h
@@ -20,9 +20,6 @@
  * arbitrate acceess to cygwin binary packages amd cygwin source packages
  */
 
-/* for MAX_PATH */
-#include "win32.h" 
-
 #include "package_version.h"
 
 class io_stream;
@@ -48,19 +45,11 @@ public:
   {
     return ldesc;
   };
-  virtual void uninstall ();
-
 
   /* pass the name of the package when constructing */
   void setCanonicalVersion (const std::string& );
 
-
   virtual ~ cygpackage ();
-  /* TODO: we should probably return a metaclass - file name & path & size & type
-     - ie doc/script/binary
-   */
-  virtual const std::string getfirstfile ();
-  virtual const std::string getnextfile ();
 
   /* pass the name of the package when constructing */
   static packageversion createInstance (const std::string& pkgname,
@@ -77,12 +66,9 @@ private:
   std::string packagev;
   std::string canonical;
   std::string sdesc, ldesc;
-  char getfilenamebuffer[CYG_PATH_MAX];
 
 //  package_stability_t stability;
   package_type_t type;
-
-  io_stream *listdata, *listfile;
 };
 
 #endif /* SETUP_CYGPACKAGE_H */
diff --git a/install.cc b/install.cc
index fee2e19..9c4c01b 100644
--- a/install.cc
+++ b/install.cc
@@ -165,10 +165,81 @@ Installer::preremoveOne (packagemeta & pkg)
 void
 Installer::uninstallOne (packagemeta & pkg)
 {
+  if (!pkg.installed)
+    return;
+
   Progress.SetText1 ("Uninstalling...");
   Progress.SetText2 (pkg.name.c_str());
   Log (LOG_PLAIN) << "Uninstalling " << pkg.name << endLog;
-  pkg.uninstall ();
+
+  std::set<std::string> dirs;
+
+  io_stream *listfile = io_stream::open ("cygfile:///etc/setup/" + pkg.name + ".lst.gz", "rb", 0);
+  io_stream *listdata = compress::decompress (listfile);
+
+  while (listdata)
+    {
+      char getfilenamebuffer[CYG_PATH_MAX];
+      const char *sz = listdata->gets (getfilenamebuffer, sizeof (getfilenamebuffer));
+      if (sz == NULL)
+        break;
+
+      std::string line(sz);
+
+      /* Insert the paths of all parent directories of line into dirs. */
+      size_t idx = line.length();
+      while ((idx = line.find_last_of('/', idx-1)) != string::npos)
+      {
+        std::string dir_path = line.substr(0, idx);
+        bool was_new = dirs.insert(dir_path).second;
+        /* If the path was already present in dirs, then all parent paths
+         * must necessarily be present also, so don't do any further work.
+         * */
+        if (!was_new) break;
+      }
+
+      std::string d = cygpath ("/" + line);
+      WCHAR wname[d.size () + 11]; /* Prefix + ".lnk". */
+      mklongpath (wname, d.c_str (), d.size () + 11);
+      DWORD dw = GetFileAttributesW (wname);
+      if (dw != INVALID_FILE_ATTRIBUTES
+          && !(dw & FILE_ATTRIBUTE_DIRECTORY))
+        {
+          Log (LOG_BABBLE) << "unlink " << d << endLog;
+          SetFileAttributesW (wname, dw & ~FILE_ATTRIBUTE_READONLY);
+          DeleteFileW (wname);
+        }
+      /* Check for Windows shortcut of same name. */
+      d += ".lnk";
+      wcscat (wname, L".lnk");
+      dw = GetFileAttributesW (wname);
+      if (dw != INVALID_FILE_ATTRIBUTES
+          && !(dw & FILE_ATTRIBUTE_DIRECTORY))
+        {
+          Log (LOG_BABBLE) << "unlink " << d << endLog;
+          SetFileAttributesW (wname, dw & ~FILE_ATTRIBUTE_READONLY);
+          DeleteFileW (wname);
+        }
+    }
+
+  /* Remove the listing file */
+  delete listdata;
+  io_stream::remove ("cygfile:///etc/setup/" + pkg.name + ".lst.gz");
+
+  /* An STL set maintains itself in sorted order. Thus, iterating over it
+   * in reverse order will ensure we process directories depth-first. */
+  set<string>::const_iterator it = dirs.end();
+  while (it != dirs.begin())
+  {
+    it--;
+    std::string d = cygpath("/" + *it);
+    WCHAR wname[d.size () + 11];
+    mklongpath (wname, d.c_str (), d.size () + 11);
+    if (RemoveDirectoryW (wname))
+      Log (LOG_BABBLE) << "rmdir " << d << endLog;
+  }
+
+  pkg.installed = packageversion();
   num_uninstalls++;
 }
 
diff --git a/package_meta.cc b/package_meta.cc
index 55fe471..f4678f0 100644
--- a/package_meta.cc
+++ b/package_meta.cc
@@ -140,76 +140,6 @@ packagemeta::set_installed (packageversion & thepkg)
     installed = thepkg;
 }
 
-/* uninstall a package if it's installed */
-void
-packagemeta::uninstall ()
-{
-  if (installed)
-    {
-      /* this will need to be pushed down to the version, or even the source level
-       * to allow differences between formats to be seamlessly managed
-       * but for now: here is ok
-       */
-      set<string> dirs;
-      string line = installed.getfirstfile ();
-
-      while (line.size())
-	{
-          /* Insert the paths of all parent directories of line into dirs. */
-          size_t idx = line.length();
-          while ((idx = line.find_last_of('/', idx-1)) != string::npos)
-          {
-            string dir_path = line.substr(0, idx);
-            bool was_new = dirs.insert(dir_path).second;
-            /* If the path was already present in dirs, then all parent paths
-             * must necessarily be present also, so don't do any further work.
-             * */
-            if (!was_new) break;
-          }
-
-	  std::string d = cygpath ("/" + line);
-	  WCHAR wname[d.size () + 11]; /* Prefix + ".lnk". */
-	  mklongpath (wname, d.c_str (), d.size () + 11);
-	  DWORD dw = GetFileAttributesW (wname);
-	  if (dw != INVALID_FILE_ATTRIBUTES
-	      && !(dw & FILE_ATTRIBUTE_DIRECTORY))
-	    {
-	      Log (LOG_BABBLE) << "unlink " << d << endLog;
-	      SetFileAttributesW (wname, dw & ~FILE_ATTRIBUTE_READONLY);
-	      DeleteFileW (wname);
-	    }
-	  /* Check for Windows shortcut of same name. */
-	  d += ".lnk";
-	  wcscat (wname, L".lnk");
-	  dw = GetFileAttributesW (wname);
-	  if (dw != INVALID_FILE_ATTRIBUTES
-	      && !(dw & FILE_ATTRIBUTE_DIRECTORY))
-	    {
-	      Log (LOG_BABBLE) << "unlink " << d << endLog;
-	      SetFileAttributesW (wname, dw & ~FILE_ATTRIBUTE_READONLY);
-	      DeleteFileW (wname);
-	    }
-	  line = installed.getnextfile ();
-	}
-      installed.uninstall ();
-
-      /* An STL set maintains itself in sorted order. Thus, iterating over it
-       * in reverse order will ensure we process directories depth-first. */
-      set<string>::const_iterator it = dirs.end();
-      while (it != dirs.begin())
-      {
-        it--;
-        std::string d = cygpath("/" + *it);
-	WCHAR wname[d.size () + 11];
-	mklongpath (wname, d.c_str (), d.size () + 11);
-	if (RemoveDirectoryW (wname))
-	  Log (LOG_BABBLE) << "rmdir " << d << endLog;
-      }
-    }
-  installed = packageversion();
-}
-
-
 void
 packagemeta::add_category (const std::string& cat)
 {
diff --git a/package_meta.h b/package_meta.h
index dbd8eb9..529b2a2 100644
--- a/package_meta.h
+++ b/package_meta.h
@@ -71,7 +71,6 @@ public:
   static const _actions Uninstall_action;
   void set_action (trusts const t);
   void set_action (_actions, packageversion const & default_version);
-  void uninstall ();
 
   void set_message (const std::string& message_id, const std::string& message_string)
   {
diff --git a/package_version.cc b/package_version.cc
index bb68229..3dcd7ea 100644
--- a/package_version.cc
+++ b/package_version.cc
@@ -46,13 +46,10 @@ public:
   const std::string Canonical_version() {return std::string();}
   void setCanonicalVersion (const std::string& ) {}
   package_type_t Type () {return package_binary;}
-  const std::string getfirstfile () {return std::string();}
-  const std::string getnextfile () {return std::string();}
   const std::string SDesc () {return std::string();}
   void set_sdesc (const std::string& ) {}
   const std::string LDesc () {return std::string();}
   void set_ldesc (const std::string& ) {}
-  void uninstall (){}
 };
 static _defaultversion defaultversion;
 
@@ -170,18 +167,6 @@ packageversion::Type () const
 }
 
 const std::string
-packageversion::getfirstfile ()
-{
-  return data->getfirstfile ();
-}
-
-const std::string
-packageversion::getnextfile ()
-{
-  return data->getnextfile ();
-}
-
-const std::string
 packageversion::SDesc () const
 {
   return data->SDesc ();
@@ -235,12 +220,6 @@ packageversion::depends() const
   return data->depends;
 }
 
-void
-packageversion::uninstall ()
-{
- data->uninstall ();
-}
-
 packagesource *
 packageversion::source () const
 {
diff --git a/package_version.h b/package_version.h
index 9351f26..fc8a084 100644
--- a/package_version.h
+++ b/package_version.h
@@ -98,8 +98,6 @@ public:
   const std::string Canonical_version () const;
   void setCanonicalVersion (const std::string& );
   package_type_t Type () const;
-  const std::string getfirstfile ();
-  const std::string getnextfile ();
   const std::string SDesc () const;
   void set_sdesc (const std::string& );
   const std::string LDesc () const;
@@ -111,7 +109,6 @@ public:
   void setDepends(const PackageDepends);
   const PackageDepends depends() const;
 
-  void uninstall ();
   /* invariant: never null */
   packagesource *source() const; /* where can we source the file from */
 
@@ -145,11 +142,6 @@ public:
   virtual void setCanonicalVersion (const std::string& ) = 0;
 //  virtual package_stability_t Stability () = 0;
   virtual package_type_t Type () = 0;
-  /* TODO: we should probably return a metaclass - file name & path & size & type
-     - ie doc/script/binary
-   */
-  virtual const std::string getfirstfile () = 0;
-  virtual const std::string getnextfile () = 0;
   virtual const std::string SDesc () = 0;
   virtual void set_sdesc (const std::string& ) = 0;
   virtual const std::string LDesc () = 0;
@@ -165,7 +157,6 @@ public:
 
   PackageDepends depends;
 
-  virtual void uninstall () = 0;
   packagesource source; /* where can we source the file from */
 
   virtual bool accessible () const;
-- 
2.12.3



More information about the Cygwin-apps mailing list