[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