From 35addac4a65a1d70ab02b8d175f71efa83cf74ba Mon Sep 17 00:00:00 2001 From: Achim Gratz Date: Wed, 1 Jul 2015 21:36:12 +0200 Subject: [PATCH 2/6] Correct local directory search * fromcwd.cc: Remove unused includes. Add global found_ini_list to record the search result. (SetupFindVisitor): Make setup.{ini,bz2,xz} known and provide bool private variables to record whether we found them. Another bool inidir to indicate whether we are currently inside a directory where setup.ini files should exist. (SetupFindVisitor::visitFile): When inidir is true, check if a setup file with one of the known extensions was found and set the corresponding bool variables. (SetupFindVisitor::visitDirectory): Set inidir when appropriate. Recurse into directories only if they are potential mirror dirs, based on level. Truncate search and recurse into inidir. Record any setup files in found_ini_list while preferring ".xz" over ".bz2" over ".ini" extension. (SetupFindVisitor::operator bool): Return true when found_ini_list is non-empty. (do_from_local_dir): Restrict search to either a single mirror hierarchy or multiple mirror hierarchy; setup files directly in local directory or mixed hierarchies are no longer recognized. The setup files must be present in an architecture dependent directory of "x86/" or "x86_64/", either in the local directory for single mirror or one level down for multiple mirrors. This patch already finds setup.xz files, but the code to deal with them will be in a later patch. The current code re-does the search and ignores the results from here. --- ChangeLog | 25 ++++++++++ fromcwd.cc | 154 ++++++++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 132 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index cb49b7e..e21e2e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,30 @@ 2015-07-01 Achim Gratz + * fromcwd.cc: Remove unused includes. Add global found_ini_list + to record the search result. + (SetupFindVisitor): Make setup.{ini,bz2,xz} known and provide bool + private variables to record whether we found them. Another bool + inidir to indicate whether we are currently inside a drectory + where setup.ini files should exist. + (SetupFindVisitor::visitFile): When inidir is true, check if a + setup file with one of the known extensions was found and set the + corresponding bool variables. + (SetupFindVisitor::visitDirectory): Set inidir when appropriate. + Recurse into directories only if they are potential mirror dirs, + based on level. Truncate search and recurse into inidir. Record + any setup files in found_ini_list while preferring ".xz" over + ".bz2" over ".ini" extension. + (SetupFindVisitor::operator bool): Return true when found_ini_list + is non-empty. + (do_from_local_dir): Restrict search to either a single mirror + hierarchy or multiple mirror hierarchy; setup files directly in + local directory or mixed hierarchies are no longer recognized. + The setup files must be present in an architecture dependent + directory of "x86/" or "x86_64/", either in the local directory + for single mirror or one level down for multiple mirrors. + +2015-07-01 Achim Gratz + * ini.h: Declare extern SetupBaseName, SetupArch and SetupIniDir. Redefine macros to use them. diff --git a/fromcwd.cc b/fromcwd.cc index 87da0ad..edb67a6 100644 --- a/fromcwd.cc +++ b/fromcwd.cc @@ -25,77 +25,137 @@ (otherwise, why would you have asked to install it?). Note that we search recursively. */ -#if 0 -static const char *cvsid = - "\n%%% $Id$\n"; -#endif - -#include "win32.h" - -#include -#include -#include -#include "resource.h" -#include "state.h" -#include "dialog.h" -#include "msg.h" +#include "String++.h" #include "find.h" -#include "ScanFindVisitor.h" -#include "filemanip.h" #include "ini.h" +#include "ScanFindVisitor.h" #include "IniDBBuilderPackage.h" #include "IniParseFeedback.h" +#define DEBUG_FROMCWD +#ifdef DEBUG_FROMCWD +#include "LogFile.h" +#endif + /* Trivial class for detecting the existence of setup.ini */ class SetupFindVisitor : public FindVisitor { public: - SetupFindVisitor (): found(false){} - virtual void visitFile(const std::string& basePath, - const WIN32_FIND_DATA *theFile) - { - if (!casecompare (SETUP_INI_FILENAME, theFile->cFileName) && - (theFile->nFileSizeLow || theFile->nFileSizeHigh)) - { - /* Check if base dir ends in SETUP_INI_DIR. */ - const char *dir = basePath.c_str() + basePath.size () - - strlen (SETUP_INI_DIR); - if (dir < basePath.c_str ()) - return; - if ((dir != basePath.c_str () && dir[-1] != '/' && dir[-1] != '\\') - || casecompare (SETUP_INI_DIR, dir)) - return; - found = true; - } - } + SetupFindVisitor () : inidir (false) + { + found_ini.resize (setup_ext_list.size ()); + found_ini.assign (setup_ext_list.size (), false); + } + virtual void visitFile (const std::string& basePath, + const WIN32_FIND_DATA *theFile) + { +#ifdef DEBUG_FROMCWD + Log (LOG_PLAIN) << "examining file: " + << basePath << "./" << theFile->cFileName << endLog; +#endif + if (inidir && + (theFile->nFileSizeLow || theFile->nFileSizeHigh)) + { +#ifdef DEBUG_FROMCWD + Log (LOG_PLAIN) << "checking extension: "; +#endif + std::vector::iterator fi = found_ini.begin (); + for (std::vector::const_iterator ext = setup_ext_list.begin (); + ext != setup_ext_list.end (); + ext++, fi++) + { +#ifdef DEBUG_FROMCWD + Log (LOG_PLAIN) << *ext << " "; +#endif + if (!casecompare (SetupBaseName + "." + *ext, theFile->cFileName)) + *fi = true; + } +#ifdef DEBUG_FROMCWD + Log (LOG_PLAIN) << endLog; +#endif + } +#ifdef DEBUG_FROMCWD + Log (LOG_PLAIN) << "state: " + << " inidir=" << inidir + << " found_xz=" << found_ini[0] + << " found_bz2=" << found_ini[1] + << " found_ini=" << found_ini[2] + << endLog; +#endif + } + virtual void visitDirectory (const std::string& basePath, + WIN32_FIND_DATA const *aDir, int level) + { +#ifdef DEBUG_FROMCWD + Log (LOG_PLAIN) << "examining directory: " + << basePath << "./" << aDir->cFileName + << endLog; +#endif + if (level <= 0) + return; + inidir = !casecompare (SetupArch, aDir->cFileName); + if (level == 1 && !inidir) + return; +#ifdef DEBUG_FROMCWD + Log (LOG_PLAIN) << " recurse into: " + << (inidir ? "inidir" : "mirror") << endLog; +#endif + Find aFinder (basePath + aDir->cFileName); + aFinder.accept (*this, inidir ? 0 : --level); + std::vector::const_iterator fi = found_ini.begin (); + for (std::vector::const_iterator ext = setup_ext_list.begin (); + ext != setup_ext_list.end (); + ext++, fi++) + { + if (*fi) + found_ini_list.push_back (basePath + "/" + aDir->cFileName + "/" + + SetupBaseName + "." + *ext); + } + found_ini.assign (setup_ext_list.size (), false); + } virtual ~ SetupFindVisitor (){} - operator bool () const {return found;} + operator bool () const + { + return !found_ini_list.empty (); + } protected: SetupFindVisitor (SetupFindVisitor const &); SetupFindVisitor & operator= (SetupFindVisitor const &); private: - bool found; + bool inidir; + std::vector found_ini; }; - + +IniList found_ini_list; + bool do_from_local_dir (HINSTANCE h, HWND owner, std::string &local_dir) { +#ifdef DEBUG_FROMCWD + Log (LOG_PLAIN) << "do_from_local_dir: " + << local_dir << endLog; +#endif // Assume we won't find the INI file. - SetupFindVisitor found_ini; - // Only search two levels deep. - Find (local_dir.c_str ()).accept(found_ini, 2); - if (found_ini) - { - // Found INI, load it. + SetupFindVisitor found; + // single mirror? + Find (local_dir.c_str ()).accept (found, 1); + if (found) return true; - } - + // multi-mirror? + Find (local_dir.c_str ()).accept (found, 2); + if (found) + return true; + // nope, do full scan. +#ifdef DEBUG_FROMCWD + Log (LOG_PLAIN) << " starting full scan from " + << local_dir << endLog; +#endif IniParseFeedback myFeedback; - IniDBBuilderPackage myBuilder(myFeedback); + IniDBBuilderPackage myBuilder (myFeedback); ScanFindVisitor myVisitor (myBuilder); - Find(local_dir.c_str ()).accept(myVisitor); + Find (local_dir.c_str ()).accept (myVisitor); return false; } -- 2.4.5