This is the mail archive of the cygwin-apps mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: setup


Corinna Vinschen writes:
> Sorry if that's a lot.  It just occured to me while reading your code.
> I'm not adamant about the structural change I outlined above, but to
> me it seems better to do it that way.  What do you think?

I've implemented your suggestions except the struct stuff.  I've not as
thoroughly tested it as last time, though.

>From 296c4272b13d8fdd3a16bb231fc2d2bfe3ba6c29 Mon Sep 17 00:00:00 2001
From: Achim Gratz <Stromeko@Stromeko.DE>
Date: Sun, 28 Jun 2015 13:34:11 +0200
Subject: [PATCH 1/6] Implement option "-i/--ini-basename" to set the basename
 for setup

	* ini.h: Declare extern SetupBaseName, SetupArch and SetupIniDir.
	Redefine macros to use them.

	* main.cc: Provide option "-i/--ini-basename" to set the basename
	for setup, keep the default as "setup" and store in SetupBaseName.
	Initialize SetupArch and SetupIniDir based on effective
	architecture.
---
 ChangeLog | 10 ++++++++++
 ini.h     | 17 +++++++++++++----
 main.cc   |  8 ++++++++
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1c50bfc..cb49b7e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2015-07-01  Achim Gratz  <Stromeko@NexGo.DE>
+
+	* ini.h: Declare extern SetupBaseName, SetupArch and SetupIniDir.
+	Redefine macros to use them.
+
+	* main.cc: Provide option "-i/--ini-basename" to set the basename
+	for setup, keep the default as "setup" and store in SetupBaseName.
+	Initialize SetupArch and SetupIniDir based on effective
+	architecture.
+
 2015-06-11  Achim Gratz  <Stromeko@NexGo.DE>
 
 	* inilex.ll: Increase read buffer size for the lexer input buffer
diff --git a/ini.h b/ini.h
index ec09def..1969da9 100644
--- a/ini.h
+++ b/ini.h
@@ -18,6 +18,16 @@
 
 class io_stream;
 #include <string>
+#include <vector>
+
+typedef std::vector <std::string> IniList;
+extern IniList found_ini_list, setup_ext_list;
+const std::string setup_exts[] = { "xz", "bz2", "ini" };
+extern bool is_64bit;
+extern std::string SetupArch;
+extern std::string SetupIniDir;
+extern std::string SetupBaseName;
+
 class IniState;
 class IniDBBuilder;
 class IniParseFeedback;
@@ -38,10 +48,9 @@ typedef enum
   EXCLUDE_NOT_FOUND
 } excludes;
 
-extern bool is_64bit;
-#define SETUP_INI_DIR	   (is_64bit ? "x86_64/" : "x86/")
-#define SETUP_INI_FILENAME "setup.ini"
-#define SETUP_BZ2_FILENAME "setup.bz2"
+#define SETUP_INI_DIR	   (SetupIniDir.c_str ())
+#define SETUP_INI_FILENAME ((SetupBaseName+".ini").c_str ())
+#define SETUP_BZ2_FILENAME ((SetupBaseName+".bz2").c_str ())
 
 /* The following three vars are used to facilitate error handling between the
    parser/lexer and its callers, namely ini.cc:do_remote_ini() and
diff --git a/main.cc b/main.cc
index e968d93..b0d78eb 100644
--- a/main.cc
+++ b/main.cc
@@ -86,6 +86,8 @@ extern char **_argv;
 #endif
 
 bool is_64bit;
+std::string SetupArch;
+std::string SetupIniDir;
 
 using namespace std;
 
@@ -97,6 +99,8 @@ static BoolOption PackageManagerOption (false, 'M', "package-manager", "Semi-att
 static BoolOption NoAdminOption (false, 'B', "no-admin", "Do not check for and enforce running as Administrator");
 static BoolOption WaitOption (false, 'W', "wait", "When elevating, wait for elevated child process");
 static BoolOption HelpOption (false, 'h', "help", "print help");
+static StringOption SetupBaseNameOpt ("setup", 'i', "ini-basename", "Use a different basename, e.g. \"foo\", instead of \"setup\"", false);
+std::string SetupBaseName;
 
 static void inline
 set_cout ()
@@ -262,6 +266,10 @@ WinMain (HINSTANCE h,
     if (unattended_mode || help_option)
       set_cout ();
 
+    SetupBaseName = SetupBaseNameOpt;
+    SetupArch = is_64bit ? "x86_64" : "x86";
+    SetupIniDir = SetupArch+"/";
+
     /* Get System info */
     OSVERSIONINFO version;
     version.dwOSVersionInfoSize = sizeof version;
-- 
2.4.5

>From 35addac4a65a1d70ab02b8d175f71efa83cf74ba Mon Sep 17 00:00:00 2001
From: Achim Gratz <Stromeko@Stromeko.DE>
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  <Stromeko@NexGo.DE>
 
+	* 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  <Stromeko@NexGo.DE>
+
 	* 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 <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
 
-#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<bool>::iterator fi = found_ini.begin ();
+	for (std::vector<std::string>::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<bool>::const_iterator fi = found_ini.begin ();
+	for (std::vector<std::string>::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<bool> 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

>From c843bf7d1e10f4d2e3d63807410298aca8cf63c4 Mon Sep 17 00:00:00 2001
From: Achim Gratz <Stromeko@Stromeko.DE>
Date: Sat, 11 Jul 2015 21:58:30 +0200
Subject: [PATCH 3/6] Refactor setup search and implement XZ compressed setup
 files

	* ini.cc: Construct setup_ext_list from array until we can use
	C++11 aggregate initializers.  Clean up function parenthesis.
	(decompress_ini): Refactored for use from do_local_ini and
	do_remote_ini.  Change outdated comment about setup.ini
	uncompressed size.
	(check_ini_sig): Factor out signature check.
	(fetch_remote_ini): Refactored for use from do_remote_ini.
	(do_local_ini): Iterate over search results in found_ini_list.
	Use decompress_ini and check_ini_sig.
	(do_remote_ini): Iterate over known setup file extensions from
	setup_ext_list with early-out semantics, preferring ".xz" over
	".bz2" over ".ini" extension.  Use fetch_remote_ini and
	check_ini_sig.
	* ini.h: Remove unused macros.
	* IniParseFindVisitor.cc: Remove, the search is already done by
	SetupFindVisitor in do_from_local_dir.
	* IniParseFindVisitor.cc: Ditto.
	* Makefile.am (@SETUP@_SOURCES): Ditto.
---
 ChangeLog              |  21 +++
 IniParseFindVisitor.cc | 116 -----------------
 IniParseFindVisitor.h  |  50 -------
 Makefile.am            |   2 -
 ini.cc                 | 345 ++++++++++++++++++++++++++++---------------------
 ini.h                  |   4 -
 6 files changed, 217 insertions(+), 321 deletions(-)
 delete mode 100644 IniParseFindVisitor.cc
 delete mode 100644 IniParseFindVisitor.h

diff --git a/ChangeLog b/ChangeLog
index e21e2e6..5fc1c86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
 2015-07-01  Achim Gratz  <Stromeko@NexGo.DE>
 
+	* ini.cc: Construct setup_ext_list from array until we can use
+	C++11 aggregate initializers.
+	(decompress_ini): Refactored for use from do_local_ini and
+	do_remote_ini.  Change outdated comment about setup.ini
+	uncompressed size.
+	(check_ini_sig): Factor out signature check.
+	(fetch_remote_ini): Refactored for use from do_remote_ini.
+	(do_local_ini): Iterate over search results in found_ini_list.
+	Use decompress_ini and check_ini_sig.
+	(do_remote_ini): Iterate over known setup file extensions from
+	setup_ext_list with early-out semantics, preferring ".xz" over
+	".bz2" over ".ini" extension.  Use fetch_remote_ini and
+	check_ini_sig.
+	* ini.h: Remove unused macros.
+	* IniParseFindVisitor.cc: Remove, the search is already done by
+	SetupFindVisitor in do_from_local_dir.
+	* IniParseFindVisitor.cc: Ditto.
+	* Makefile.am (@SETUP@_SOURCES): Ditto.
+
+2015-07-01  Achim Gratz  <Stromeko@NexGo.DE>
+
 	* 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
diff --git a/IniParseFindVisitor.cc b/IniParseFindVisitor.cc
deleted file mode 100644
index 871d6de..0000000
--- a/IniParseFindVisitor.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2002,2007 Robert Collins.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     A copy of the GNU General Public License can be found at
- *     http://www.gnu.org/
- *
- * Written by Robert Collins <robertc@hotmail.com>
- *
- */
-
-#if 0
-static const char *cvsid =
-  "\n%%% $Id$\n";
-#endif
-
-#include "IniParseFindVisitor.h"
-
-#include "csu_util/rfc1738.h"
-
-#include "IniParseFeedback.h"
-#include "IniDBBuilder.h"
-#include "io_stream.h"
-#include "ini.h"
-#include <stdexcept>
-
-using namespace std;
-
-extern int yyparse ();
-
-IniParseFindVisitor::IniParseFindVisitor(IniDBBuilder &aBuilder,
-                                         const std::string& localroot,
-                                         IniParseFeedback &feedback)
-  : _Builder (aBuilder), _feedback (feedback), baseLength (localroot.size()),
-    local_ini(0), setup_timestamp (0), setup_version()
-{}
-
-IniParseFindVisitor::~IniParseFindVisitor(){}
-
-/* look for potential packages we can add to the in-memory package
- * database
- */
-void
-IniParseFindVisitor::visitFile(const std::string& basePath,
-                               const WIN32_FIND_DATA *theFile)
-{
-  //TODO: Test for case sensitivity issues
-  if (casecompare(SETUP_INI_FILENAME, theFile->cFileName))
-    return;
-  
-  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;
-
-  current_ini_name = basePath + theFile->cFileName;
-  
-  io_stream *ini_file = io_stream::open("file://" + current_ini_name, "rb", 0);
-
-  if (!ini_file)
-    // We don't throw an exception, because while this is fatal to parsing, it
-    // isn't to the visitation.
-    {
-      // This should never happen
-      // If we want to handle it happening, use the log strategy call
-      throw new runtime_error ("IniParseFindVisitor: failed to open ini file, which should never happen");
-      return;
-    }
-  
-  _feedback.babble("Found ini file - " + current_ini_name);
-  _feedback.iniName (current_ini_name);
-  
-  /* Copy leading part of path to temporary buffer and unescape it */
-  
-  size_t pos = baseLength + 1;
-  size_t len = basePath.size () - (pos + strlen (SETUP_INI_DIR) + 1);
-  _Builder.parse_mirror = len <= 0 ? ""
-    			  : rfc1738_unescape (basePath.substr (pos, len));
-  ini_init (ini_file, &_Builder, _feedback);
-  
-  /*yydebug = 1; */
-
-  if (yyparse () || yyerror_count > 0)
-    _feedback.error (yyerror_messages);
-  else
-    local_ini++;
-
-  if (_Builder.timestamp > setup_timestamp)
-    {
-      setup_timestamp = _Builder.timestamp;
-      setup_version = _Builder.version;
-    }
-}
-
-int
-IniParseFindVisitor::iniCount() const
-{
-  return local_ini;
-}
-
-unsigned int 
-IniParseFindVisitor::timeStamp () const
-{
-  return setup_timestamp;
-}
-
-std::string
-IniParseFindVisitor::version() const
-{
-  return setup_version;
-}
diff --git a/IniParseFindVisitor.h b/IniParseFindVisitor.h
deleted file mode 100644
index ff48f70..0000000
--- a/IniParseFindVisitor.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2002,2007 Robert Collins.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     A copy of the GNU General Public License can be found at
- *     http://www.gnu.org/
- *
- * Written by Robert Collins <robertc@hotmail.com>
- *
- */
-
-#ifndef SETUP_INIPARSEFINDVISITOR_H
-#define SETUP_INIPARSEFINDVISITOR_H
-
-#include "FindVisitor.h"
-
-
-/* parse passed in setup.ini files from disk. */
-class IniDBBuilder;
-class IniParseFeedback;
-/* IniParse files and create a package db when no cached .ini exists */
-class IniParseFindVisitor : public FindVisitor
-{
-public:
-  IniParseFindVisitor (IniDBBuilder &aBuilder,
-                       const std::string& localroot,
-                       IniParseFeedback &);
-  virtual void visitFile(const std::string& basePath, const WIN32_FIND_DATA *);
-  virtual ~ IniParseFindVisitor ();
-
-  unsigned int timeStamp() const;
-  std::string version() const;
-  int iniCount() const;
-protected:
-  IniParseFindVisitor (IniParseFindVisitor const &);
-  IniParseFindVisitor & operator= (IniParseFindVisitor const &);
-private:
-  IniDBBuilder &_Builder;
-  IniParseFeedback &_feedback;
-  unsigned int baseLength;
-  int local_ini;
-  unsigned int setup_timestamp;
-  std::string setup_version;
-};
-
-#endif /* SETUP_INIPARSEFINDVISITOR_H */
diff --git a/Makefile.am b/Makefile.am
index 88330d5..e9263cc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -163,8 +163,6 @@ inilint_SOURCES = \
 	iniparse.yy \
 	IniParseFeedback.cc \
 	IniParseFeedback.h \
-	IniParseFindVisitor.cc \
-	IniParseFindVisitor.h \
 	install.cc \
 	io_stream.cc \
 	io_stream.h \
diff --git a/ini.cc b/ini.cc
index e90f98c..571ee2d 100644
--- a/ini.cc
+++ b/ini.cc
@@ -39,7 +39,6 @@
 #include "mount.h"
 #include "site.h"
 #include "find.h"
-#include "IniParseFindVisitor.h"
 #include "IniParseFeedback.h"
 
 #include "io_stream.h"
@@ -57,11 +56,12 @@ extern ThreeBarProgressPage Progress;
 
 unsigned int setup_timestamp = 0;
 std::string ini_setup_version;
-std::string current_ini_sig_name;
+IniList setup_ext_list ( setup_exts, setup_exts+3); // TODO: use C++11x initializer lists
 
 static BoolOption NoVerifyOption (false, 'X', "no-verify", "Don't verify setup.ini signatures");
 
 extern int yyparse ();
+
 /*extern int yydebug;*/
 
 class GuiParseFeedback : public IniParseFeedback
@@ -73,7 +73,7 @@ public:
       Progress.SetText3 ("");
       Progress.SetText4 ("Progress:");
     }
-  virtual void progress(unsigned long const pos, unsigned long const max)
+  virtual void progress (unsigned long const pos, unsigned long const max)
     {
       if (!max)
 	/* length not known or eof */
@@ -87,199 +87,247 @@ public:
 	  /* Log (LOG_BABBLE) << lastpct << "% (" << pos << " of " << max
 	    << " bytes of ini file read)" << endLog; */
 	}
-      Progress.SetBar1(pos, max);
+      Progress.SetBar1 (pos, max);
 
       static char buf[100];
-      sprintf(buf, "%d %%  (%ldk/%ldk)", lastpct, pos/1000, max/1000);
-      Progress.SetText3(buf);
+      sprintf (buf, "%d %%  (%ldk/%ldk)", lastpct, pos/1000, max/1000);
+      Progress.SetText3 (buf);
     }
   virtual void iniName (const std::string& name)
     {
       Progress.SetText1 ("Parsing...");
-      Progress.SetText2 (name.c_str());
+      Progress.SetText2 (name.c_str ());
       Progress.SetText3 ("");
     }
-  virtual void babble(const std::string& message)const
+  virtual void babble (const std::string& message)const
     {
       Log (LOG_BABBLE) << message << endLog;
     }
   virtual void warning (const std::string& message)const
     {
-      mbox (0, message.c_str(), "Warning", 0);
+      mbox (0, message.c_str (), "Warning", 0);
     }
-  virtual void error(const std::string& message)const
+  virtual void error (const std::string& message)const
     {
-      mbox (0, message.c_str(), "Parse Errors", 0);
+      mbox (0, message.c_str (), "Parse Errors", 0);
     }
   virtual ~ GuiParseFeedback ()
     {
-      Progress.SetText4("Package:");
+      Progress.SetText4 ("Package:");
     }
 private:
   unsigned int lastpct;
 };
 
-static int
-do_local_ini (HWND)
+static io_stream*
+decompress_ini (io_stream *ini_file)
 {
-  GuiParseFeedback myFeedback;
-  IniDBBuilderPackage findBuilder(myFeedback);
-  IniParseFindVisitor myVisitor (findBuilder, local_dir, myFeedback);
-  Find (local_dir).accept(myVisitor, 2);	// Only search two levels deep.
-  setup_timestamp = myVisitor.timeStamp();
-  ini_setup_version = myVisitor.version();
-  return myVisitor.iniCount();
+  // Replace the current compressed setup stream with its decompressed
+  // version.  Which decompressor to use is determined by file magic.
+  io_stream *compressed_stream = compress::decompress (ini_file);
+  if (!compressed_stream)
+    {
+      /* This isn't a known compression format or an uncompressed file
+	 stream.  Pass it on in case it was uncompressed, it will
+	 generate a parser error if it was some unknown format. */
+      delete compressed_stream;
+    }
+  else
+    {
+      /* Decompress the entire file in memory.  This has the advantage
+	 that input_stream->get_size () will work during parsing and
+	 we'll have an accurate status bar.  Also, we can't seek
+	 compressed streams, so when we write out a local cached copy
+	 of the .ini file below, we'd otherwise have to delete this
+	 stream and uncompress it again from the start, which is
+	 wasteful.  The current uncompressed size of the setup.ini
+	 file as of 2015 is about 5 MiB, so this is not a great deal
+	 of memory.  */
+      io_stream *uncompressed = new io_stream_memory ();
+      /* Note that the decompress io_stream now "owns" the underlying
+	 compressed io_stream instance, so it need not be deleted
+	 explicitly. */
+      if ((io_stream::copy (compressed_stream, uncompressed) != 0) ||
+	  (compressed_stream->error () != 0))
+	{
+	  /* There was a problem decompressing compressed_stream.  */
+	  Log (LOG_PLAIN) <<
+	    "Warning: Error code " << compressed_stream->error () <<
+	    " occurred while uncompressing " << current_ini_name <<
+	    " - possibly truncated or corrupt file. " << endLog;
+	  delete uncompressed;
+	  ini_file = NULL;
+	}
+      else
+	{
+	  ini_file = uncompressed;
+	  ini_file->seek (0, IO_SEEK_SET);
+	}
+    }
+  return ini_file;
 }
 
-static int
-do_remote_ini (HWND owner)
+static io_stream*
+check_ini_sig (io_stream* ini_file, io_stream* ini_sig_file,
+	       bool& sig_fail, const char* site, const char* sig_name, HWND owner)
 {
-  size_t ini_count = 0;
-  GuiParseFeedback myFeedback;
-  IniDBBuilderPackage aBuilder(myFeedback);
-  io_stream *ini_file, *ini_sig_file;
-
-  /* FIXME: Get rid of this io_stream pointer travesty.  The need to
-     explicitly delete these things is ridiculous.  Note that the
-     decompress io_stream "owns" the underlying compressed io_stream
-     instance, so it should not be deleted explicitly.  */
-
-  for (SiteList::const_iterator n = site_list.begin();
-       n != site_list.end(); ++n)
+  /* Unless the NoVerifyOption is set, check the signature for the
+     current setup and record the result.  On a failed signature check
+     the streams are invalidated so even if we tried to read in the
+     setup anyway there's be nothing to parse. */
+  if (!NoVerifyOption && ini_file)
     {
-      bool sig_fail = false;
-      /* First try to fetch the .bz2 compressed ini file.  */
-      current_ini_name = n->url + SETUP_INI_DIR + SETUP_BZ2_FILENAME;
-      current_ini_sig_name = n->url + SETUP_INI_DIR + SETUP_BZ2_FILENAME + ".sig";
-      ini_file = get_url_to_membuf (current_ini_name, owner);
-      if (!NoVerifyOption)
-	ini_sig_file = get_url_to_membuf (current_ini_sig_name, owner);
-      if (!NoVerifyOption && ini_file && !ini_sig_file)
+      if (!ini_sig_file)
 	{
-	  note (owner, IDS_SETUPINI_MISSING, current_ini_sig_name.c_str(), n->url.c_str());
+	  note (owner, IDS_SETUPINI_MISSING, sig_name, site);
 	  delete ini_file;
 	  ini_file = NULL;
 	  sig_fail = true;
 	}
-      else if (!NoVerifyOption && ini_file && !verify_ini_file_sig (ini_file, ini_sig_file, owner))
+      else if (!verify_ini_file_sig (ini_file, ini_sig_file, owner))
 	{
-	  note (owner, IDS_SIG_INVALID, current_ini_sig_name.c_str(), n->url.c_str());
-	  delete ini_file;
-	  ini_file = NULL;
+	  note (owner, IDS_SIG_INVALID, sig_name, site);
 	  delete ini_sig_file;
 	  ini_sig_file = NULL;
+	  delete ini_file;
+	  ini_file = NULL;
 	  sig_fail = true;
 	}
+    }
+  return ini_file;
+}
+
+static int
+do_local_ini (HWND owner)
+{
+  size_t ini_count = 0;
+  GuiParseFeedback myFeedback;
+  IniDBBuilderPackage aBuilder (myFeedback);
+  io_stream *ini_file, *ini_sig_file;
+  // iterate over all setup files found in do_from_local_dir
+  for (IniList::const_iterator n = found_ini_list.begin ();
+       n != found_ini_list.end (); ++n)
+    {
+      bool sig_fail = false;
+      std::string current_ini_ext, current_ini_name, current_ini_sig_name;
+
+      current_ini_name = *n;
+      current_ini_sig_name = current_ini_name + ".sig";
+      current_ini_ext = current_ini_name.substr (current_ini_name.rfind (".") + 1);
+      ini_sig_file = io_stream::open ("file://" + current_ini_sig_name, "rb", 0);
+      ini_file = io_stream::open ("file://" + current_ini_name, "rb", 0);
+      ini_file = check_ini_sig (ini_file, ini_sig_file, sig_fail,
+				"localdir", current_ini_sig_name.c_str (), owner);
       if (ini_file)
+	ini_file = decompress_ini (ini_file);
+      if (!ini_file || sig_fail)
 	{
-	  /* Decompress the entire file in memory right now.  This has the
-	     advantage that input_stream->get_size() will work during parsing
-	     and we'll have an accurate status bar.  Also, we can't seek
-	     bz2 streams, so when it comes time to write out a local cached
-	     copy of the .ini file below, we'd otherwise have to delete this
-	     stream and uncompress it again from the start, which is wasteful.
-	     The current uncompresed size of the .ini file as of 2007 is less
-	     than 600 kB, so this is not a great deal of memory.  */
-	  io_stream *bz2_stream = compress::decompress (ini_file);
-	  if (!bz2_stream)
-	    {
-	      /* This isn't a valid bz2 file.  */
-	      delete ini_file;
-	      ini_file = NULL;
-	    }
+	  // no setup found or signature invalid
+	  note (owner, IDS_SETUPINI_MISSING, SetupBaseName.c_str (),
+		"localdir");
+	}
+      else
+	{
+	  // grok information from setup
+	  myFeedback.babble ("Found ini file - " + current_ini_name);
+	  myFeedback.iniName (current_ini_name);
+	  aBuilder.parse_mirror = "";
+	  ini_init (ini_file, &aBuilder, myFeedback);
+	  
+	  /*yydebug = 1; */
+
+	  if (yyparse () || yyerror_count > 0)
+	    myFeedback.error (yyerror_messages);
 	  else
-	    {
-	      io_stream *uncompressed = new io_stream_memory ();
+	    ++ini_count;
 
-	      if ((io_stream::copy (bz2_stream, uncompressed) != 0) ||
-                  (bz2_stream->error() != 0))
-		{
-		  /* There was a problem decompressing bz2.  */
-		  ini_file = NULL;
-		  Log (LOG_PLAIN) <<
-		    "Warning: Error code " << bz2_stream->error() << " occurred while uncompressing " <<
-		    current_ini_name << " - possibly truncated or corrupt bzip2"
-		    " file.  Retrying with uncompressed version." << endLog;
-		  delete bz2_stream;
-		  delete uncompressed;
-		}
-	      else
-		{
-		  delete bz2_stream;
-		  ini_file = uncompressed;
-		  ini_file->seek (0, IO_SEEK_SET);
-		}
+	  if (aBuilder.timestamp > setup_timestamp)
+	    {
+	      setup_timestamp = aBuilder.timestamp;
+	      ini_setup_version = aBuilder.version;
 	    }
+	  delete ini_file;
+	  ini_file = NULL;
 	}
+    }
+  return ini_count;
+}
 
-      if (!ini_file)
+static int
+do_remote_ini (HWND owner)
+{
+  size_t ini_count = 0;
+  GuiParseFeedback myFeedback;
+  IniDBBuilderPackage aBuilder (myFeedback);
+  io_stream *ini_file, *ini_sig_file;
+
+  /* FIXME: Get rid of this io_stream pointer travesty.  The need to
+     explicitly delete these things is ridiculous. */
+
+  // iterate over all sites
+  for (SiteList::const_iterator n = site_list.begin ();
+       n != site_list.end (); ++n)
+    {
+      bool sig_fail = false;
+      std::string current_ini_ext, current_ini_name, current_ini_sig_name;
+      // iterate over known extensions for setup
+      for (IniList::const_iterator ext = setup_ext_list.begin ();
+	   ext != setup_ext_list.end ();
+	   ext++)
 	{
-	  /* Try to look for a plain .ini file because one of the following
-	     happened above:
-	       - there was no .bz2 file found on the mirror.
-	       - the .bz2 file didn't look like a valid bzip2 file.
-	       - there was an error during bzip2 decompression.  */
-	  current_ini_name = n->url + SETUP_INI_DIR + SETUP_INI_FILENAME;
-	  current_ini_sig_name = n->url + SETUP_INI_DIR + SETUP_INI_FILENAME + ".sig";
+	  current_ini_ext = *ext;
+	  current_ini_name = n->url + SetupIniDir + SetupBaseName + "." + current_ini_ext;
+	  current_ini_sig_name = current_ini_name + ".sig";
+	  ini_sig_file = get_url_to_membuf (current_ini_sig_name, owner);
 	  ini_file = get_url_to_membuf (current_ini_name, owner);
-	  if (!NoVerifyOption)
-	    ini_sig_file = get_url_to_membuf (current_ini_sig_name, owner);
-
-	  if (!NoVerifyOption && ini_file && !ini_sig_file)
-	    {
-	      note (owner, IDS_SETUPINI_MISSING, current_ini_sig_name.c_str(), n->url.c_str());
-	      delete ini_file;
-	      ini_file = NULL;
-	      sig_fail = true;
-	    }
-	  else if (!NoVerifyOption && ini_file && !verify_ini_file_sig (ini_file, ini_sig_file, owner))
-	    {
-	      note (owner, IDS_SIG_INVALID, current_ini_sig_name.c_str(), n->url.c_str());
-	      delete ini_file;
-	      ini_file = NULL;
-	      delete ini_sig_file;
-	      ini_sig_file = NULL;
-	      sig_fail = true;
-	    }
+	  ini_file = check_ini_sig (ini_file, ini_sig_file, sig_fail,
+				    n->url.c_str (), current_ini_sig_name.c_str (), owner);
+	  // stop searching as soon as we find a setup file
+	  if (ini_file)
+	    break;
 	}
-
-      if (!ini_file)
+      if (ini_file)
+	ini_file = decompress_ini (ini_file);
+      if (!ini_file || sig_fail)
 	{
-	  if (!sig_fail)
-	    note (owner, IDS_SETUPINI_MISSING, SETUP_INI_FILENAME, n->url.c_str());
-	  continue;
+	  // no setup found or signature invalid
+	  note (owner, IDS_SETUPINI_MISSING, SetupBaseName.c_str (), n->url.c_str ());
 	}
-
-      myFeedback.iniName (current_ini_name);
-      aBuilder.parse_mirror = n->url;
-      ini_init (ini_file, &aBuilder, myFeedback);
-
-      /*yydebug = 1; */
-
-      if (yyparse () || yyerror_count > 0)
-	myFeedback.error (yyerror_messages);
       else
 	{
-	  /* save known-good setup.ini locally */
-	  const std::string fp = "file://" + local_dir + "/" +
-				   rfc1738_escape_part (n->url) +
-				   "/" + SETUP_INI_DIR + SETUP_INI_FILENAME;
-	  io_stream::mkpath_p (PATH_TO_FILE, fp, 0);
-	  if (io_stream *out = io_stream::open (fp, "wb", 0))
+	  // grok information from setup
+	  myFeedback.iniName (current_ini_name);
+	  aBuilder.parse_mirror = n->url;
+	  ini_init (ini_file, &aBuilder, myFeedback);
+	  
+	  /*yydebug = 1; */
+
+	  if (yyparse () || yyerror_count > 0)
+	    myFeedback.error (yyerror_messages);
+	  else
 	    {
-	      ini_file->seek (0, IO_SEEK_SET);
-	      if (io_stream::copy (ini_file, out) != 0)
-		io_stream::remove (fp);
-	      delete out;
+	      /* save known-good setup.ini locally */
+	      const std::string fp = "file://" + local_dir + "/" +
+				      rfc1738_escape_part (n->url) +
+				      "/" + SetupIniDir + SetupBaseName + ".ini";
+	      io_stream::mkpath_p (PATH_TO_FILE, fp, 0);
+	      if (io_stream *out = io_stream::open (fp, "wb", 0))
+		{
+		  ini_file->seek (0, IO_SEEK_SET);
+		  if (io_stream::copy (ini_file, out) != 0)
+		    io_stream::remove (fp);
+		  delete out;
+		}
+	      ++ini_count;
 	    }
-	  ++ini_count;
-	}
-      if (aBuilder.timestamp > setup_timestamp)
-	{
-	  setup_timestamp = aBuilder.timestamp;
-	  ini_setup_version = aBuilder.version;
+	  if (aBuilder.timestamp > setup_timestamp)
+	    {
+	      setup_timestamp = aBuilder.timestamp;
+	      ini_setup_version = aBuilder.version;
+	    }
+	  delete ini_file;
+	  ini_file = NULL;
 	}
-      delete ini_file;
     }
   return ini_count;
 }
@@ -296,7 +344,7 @@ do_ini_thread (HINSTANCE h, HWND owner)
   if (ini_count == 0)
     return false;
 
-  if (get_root_dir ().c_str())
+  if (get_root_dir ().c_str ())
     {
       io_stream::mkpath_p (PATH_TO_DIR, "cygfile:///etc/setup", 0755);
 
@@ -332,7 +380,7 @@ do_ini_thread (HINSTANCE h, HWND owner)
 	}
     }
 
-  LogBabblePrintf (".ini setup_version is %s, our setup_version is %s", ini_setup_version.size() ?
+  LogBabblePrintf (".ini setup_version is %s, our setup_version is %s", ini_setup_version.size () ?
        ini_setup_version.c_str () : "(null)",
        setup_version);
   if (ini_setup_version.size ())
@@ -346,21 +394,21 @@ do_ini_thread (HINSTANCE h, HWND owner)
 }
 
 static DWORD WINAPI
-do_ini_thread_reflector(void* p)
+do_ini_thread_reflector (void* p)
 {
   HANDLE *context;
   context = (HANDLE*)p;
 
   try
   {
-    bool succeeded = do_ini_thread((HINSTANCE)context[0], (HWND)context[1]);
+    bool succeeded = do_ini_thread ((HINSTANCE)context[0], (HWND)context[1]);
 
     // Tell the progress page that we're done downloading
-    Progress.PostMessageNow(WM_APP_SETUP_INI_DOWNLOAD_COMPLETE, 0, succeeded);
+    Progress.PostMessageNow (WM_APP_SETUP_INI_DOWNLOAD_COMPLETE, 0, succeeded);
   }
-  TOPLEVEL_CATCH("ini");
+  TOPLEVEL_CATCH ("ini");
 
-  ExitThread(0);
+  ExitThread (0);
 }
 
 static HANDLE context[2];
@@ -374,4 +422,3 @@ do_ini (HINSTANCE h, HWND owner)
   DWORD threadID;
   CreateThread (NULL, 0, do_ini_thread_reflector, context, 0, &threadID);
 }
-
diff --git a/ini.h b/ini.h
index 1969da9..164e3d2 100644
--- a/ini.h
+++ b/ini.h
@@ -48,10 +48,6 @@ typedef enum
   EXCLUDE_NOT_FOUND
 } excludes;
 
-#define SETUP_INI_DIR	   (SetupIniDir.c_str ())
-#define SETUP_INI_FILENAME ((SetupBaseName+".ini").c_str ())
-#define SETUP_BZ2_FILENAME ((SetupBaseName+".bz2").c_str ())
-
 /* The following three vars are used to facilitate error handling between the
    parser/lexer and its callers, namely ini.cc:do_remote_ini() and
    IniParseFindVisitor::visitFile().  */
-- 
2.4.5

>From 7788675cb2cfc547de7ead3ff5ae9839ae531506 Mon Sep 17 00:00:00 2001
From: Achim Gratz <Stromeko@Stromeko.DE>
Date: Sat, 11 Jul 2015 23:24:11 +0200
Subject: [PATCH 4/6] fromcwd.cc: Remove debugging output

---
 fromcwd.cc | 45 ---------------------------------------------
 1 file changed, 45 deletions(-)

diff --git a/fromcwd.cc b/fromcwd.cc
index edb67a6..d571b02 100644
--- a/fromcwd.cc
+++ b/fromcwd.cc
@@ -34,13 +34,6 @@
 #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:
@@ -52,57 +45,27 @@ public:
   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<bool>::iterator fi = found_ini.begin ();
 	for (std::vector<std::string>::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<bool>::const_iterator fi = found_ini.begin ();
@@ -134,10 +97,6 @@ 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;
   // single mirror?
@@ -149,10 +108,6 @@ do_from_local_dir (HINSTANCE h, HWND owner, std::string &local_dir)
   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);
   ScanFindVisitor myVisitor (myBuilder);
-- 
2.4.5


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

Factory and User Sound Singles for Waldorf rackAttack:
http://Synth.Stromeko.net/Downloads.html#WaldorfSounds

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]