This is the mail archive of the cygwin-apps-cvs mailing list for the cygwin-apps 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]

[setup] branch master, updated. release_2.871-7-g740db89




https://sourceware.org/git/gitweb.cgi?p=cygwin-setup.git;h=740db89981d031e7d72f98ab6174691f1bcee014

commit 740db89981d031e7d72f98ab6174691f1bcee014
Author: Achim Gratz <Stromeko@Stromeko.DE>
Date:   Sat Jul 11 23:24:11 2015 +0200

    fromcwd.cc: Remove debugging output

https://sourceware.org/git/gitweb.cgi?p=cygwin-setup.git;h=18837afa64984e98476401e99dcd772970cf9736

commit 18837afa64984e98476401e99dcd772970cf9736
Author: Achim Gratz <Stromeko@Stromeko.DE>
Date:   Sat Jul 11 21:58:30 2015 +0200

    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.

https://sourceware.org/git/gitweb.cgi?p=cygwin-setup.git;h=35addac4a65a1d70ab02b8d175f71efa83cf74ba

commit 35addac4a65a1d70ab02b8d175f71efa83cf74ba
Author: Achim Gratz <Stromeko@Stromeko.DE>
Date:   Wed Jul 1 21:36:12 2015 +0200

    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.

https://sourceware.org/git/gitweb.cgi?p=cygwin-setup.git;h=296c4272b13d8fdd3a16bb231fc2d2bfe3ba6c29

commit 296c4272b13d8fdd3a16bb231fc2d2bfe3ba6c29
Author: Achim Gratz <Stromeko@Stromeko.DE>
Date:   Sun Jun 28 13:34:11 2015 +0200

    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.


Diff:
---
 ChangeLog              |   56 ++++++++
 IniParseFindVisitor.cc |  116 ----------------
 IniParseFindVisitor.h  |   50 -------
 Makefile.am            |    2 -
 fromcwd.cc             |  113 +++++++++-------
 ini.cc                 |  347 +++++++++++++++++++++++++++---------------------
 ini.h                  |   15 ++-
 main.cc                |    8 +
 8 files changed, 336 insertions(+), 371 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1c50bfc..5fc1c86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,59 @@
+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
+	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.
+
+	* 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/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/fromcwd.cc b/fromcwd.cc
index 87da0ad..d571b02 100644
--- a/fromcwd.cc
+++ b/fromcwd.cc
@@ -25,77 +25,92 @@
    (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"
 
-/* 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)
+  {
+    if (inidir &&
+	(theFile->nFileSizeLow || theFile->nFileSizeHigh))
+      {
+	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++)
+	  {
+	    if (!casecompare (SetupBaseName + "." + *ext,  theFile->cFileName))
+	      *fi = true;
+	  }
+      }
+  }
+  virtual void visitDirectory (const std::string& basePath,
+			       WIN32_FIND_DATA const *aDir, int level)
+  {
+    if (level <= 0)
+      return;
+    inidir = !casecompare (SetupArch, aDir->cFileName);
+    if (level == 1 && !inidir)
+      return;
+    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)
 {
   // 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.
   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;
 }
diff --git a/ini.cc b/ini.cc
index e90f98c..f933c5b 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,14 @@ extern ThreeBarProgressPage Progress;
 
 unsigned int setup_timestamp = 0;
 std::string ini_setup_version;
-std::string current_ini_sig_name;
+// TODO: use C++11x initializer lists instead and drop the literal array
+IniList setup_ext_list (setup_exts,
+			setup_exts + (sizeof(setup_exts) / sizeof(*setup_exts)));
 
 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 +75,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 +89,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 +346,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 +382,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 +396,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 +424,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 ec09def..164e3d2 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,11 +48,6 @@ 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"
-
 /* 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().  */
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;


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