From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 108714 invoked by alias); 31 May 2017 10:53:34 -0000 Mailing-List: contact cygwin-apps-help@cygwin.com; run by ezmlm Precedence: bulk Sender: cygwin-apps-owner@cygwin.com List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Mail-Followup-To: cygwin-apps@cygwin.com Received: (qmail 108626 invoked by uid 89); 31 May 2017 10:53:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.3 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=delegates, formats X-HELO: rgout04.bt.lon5.cpcloud.co.uk Received: from rgout0406.bt.lon5.cpcloud.co.uk (HELO rgout04.bt.lon5.cpcloud.co.uk) (65.20.0.219) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 31 May 2017 10:53:23 +0000 X-OWM-Source-IP: 86.141.128.130 (GB) X-OWM-Env-Sender: jonturney@btinternet.com X-Junkmail-Premium-Raw: score=8/50,refid=2.7.2:2017.5.13.91815:17:8.707,ip=,rules=NO_URI_FOUND, NO_CTA_URI_FOUND, NO_MESSAGE_ID, NO_URI_HTTPS, TO_MALFORMED Received: from localhost.localdomain (86.141.128.130) by rgout04.bt.lon5.cpcloud.co.uk (9.0.019.13-1) (authenticated as jonturney@btinternet.com) id 58482DA21281A38F; Wed, 31 May 2017 11:53:26 +0100 From: Jon Turney To: cygwin-apps@cygwin.com Cc: Jon Turney Subject: [PATCH setup 05/14] Hoist uninstall up to Installer::uninstallOne() Date: Wed, 31 May 2017 10:53:00 -0000 Message-Id: <20170531105015.162228-6-jon.turney@dronecode.org.uk> In-Reply-To: <20170531105015.162228-1-jon.turney@dronecode.org.uk> References: <20170531105015.162228-1-jon.turney@dronecode.org.uk> X-SW-Source: 2017-05/txt/msg00165.txt.bz2 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 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::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 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::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