This is the mail archive of the cygwin-apps@cygwin.com 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]

package driven postinstall scripts.


Igor,
	what do you think of the attached patch.

It's a halfway house between your embedded ordering and the package ordering I'm proposing.

This patch changes setups behaviour on only one way:
package included post-install scripts will run before hand placed scripts. (i.e. Pierre's security testing script).


It doesn't (yet) add dependencies to the the script ordering, but that is truely trivial given an ordered iterator for the package db.

Will I be causing grief for you by applying this patch?

The install.cc changes I plan to apply regardless, modulo the 'Note script files as they are installed' 2-liner.

If this goes in, then I can easily throw a package-ordered iterator at postinstall and solve the root problem.

BTW: What was the test case that prompted a need for ordered postinstall scripts?

Rob

2003-03-15 Robert Collins <rbtcollins at hotmail dot com>

* install.cc: Introduce Installer class.
(init_dialog): Rename to Installer::initDialog.
(progress): Rename to Installer::progress.
(standard_dirs): Rename to Installer::StandardDirs.
(uninstall_one): Rename to Installer::uninstallOne.
(replace_one): Rename to Installer::replaceOne.
(log_ror_failure): Rename to Installer::replaceOnRebootFailed.
(log_ror_success): Rename to Installer::replaceOnRebootSucceeded.
(install_one_source): Rename to Installer::installOneSource.
Note script files as they are installed.
* package_version.cc (packageversion::addScript): Implement.
(packageversion::scripts): Implement.
* package_version.h (packageversion::addScript): Record the presence of a script.
* script.h (Script): New class to track scripts.
* postinstall.cc (do_postinstall): Iterate through the package listed scripts before searching for scripts.
* String++.cc (String::substr): Second argument needed to be signed.
* String++.h (String::substr): Second argument needed to be signed.


? .inilex.l.swp
? .list.h.swp
? aclocal.m4
? autom4te.cache
? c
? cat.exe.stackdump
? changes
? configure
? diff3.out
? fix-gcc3-main.patch
? i.h
? inilex.rob
? inilex.test
? iniparse.rob
? iniparse.test
? io_stream_physical.h
? libgetopt++
? librsync-0.9.3
? librsync-0.9.3.tar.gz
? librsync-0[1].9.5-0.14.diff
? librsyncupdate.patch
? Makefile.in
? mirrors.lst
? postinstallChange.patch
? replaceself.patch
? rsync.patch
? setup.bz2
? t
? t.c
? bz2lib/autom4te.cache
? rsync/autom4te.cache
? zlib/autom4te.cache
Index: ChangeLog
===================================================================
RCS file: /cvs/cygwin-apps/setup/ChangeLog,v
retrieving revision 2.334
diff -u -p -r2.334 ChangeLog
--- ChangeLog	15 Mar 2003 22:14:40 -0000	2.334
+++ ChangeLog	16 Mar 2003 04:35:59 -0000
@@ -1,5 +1,25 @@
 2003-03-15  Robert Collins  <rbtcollins at hotmail dot com>
 
+	* install.cc: Introduce Installer class.
+	(init_dialog): Rename to Installer::initDialog.
+	(progress): Rename to Installer::progress.
+	(standard_dirs): Rename to Installer::StandardDirs.
+	(uninstall_one): Rename to Installer::uninstallOne.
+	(replace_one): Rename to Installer::replaceOne.
+	(log_ror_failure): Rename to Installer::replaceOnRebootFailed.
+	(log_ror_success): Rename to Installer::replaceOnRebootSucceeded.
+	(install_one_source): Rename to Installer::installOneSource.
+	Note script files as they are installed.
+	* package_version.cc (packageversion::addScript): Implement.
+	(packageversion::scripts): Implement.
+	* package_version.h (packageversion::addScript): Record the presence of a script.
+	* script.h (Script): New class to track scripts.
+	* postinstall.cc (do_postinstall): Iterate through the package listed scripts before searching for scripts.
+	* String++.cc (String::substr): Second argument needed to be signed.
+	* String++.h (String::substr): Second argument needed to be signed.
+
+2003-03-15  Robert Collins  <rbtcollins at hotmail dot com>
+
 	* script.cc (run): Rename variable b to createSucceeded.
 
 2003-03-15  Igor Pechtchanski <pechtcha at cs dot nyu dot edu>
Index: String++.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/String++.cc,v
retrieving revision 2.8
diff -u -p -r2.8 String++.cc
--- String++.cc	9 Mar 2003 01:16:06 -0000	2.8
+++ String++.cc	16 Mar 2003 04:35:59 -0000
@@ -124,7 +124,7 @@ String::find(char aChar) const
 }
 
 String
-String::substr(size_t start, size_t len) const
+String::substr(size_t start, int len) const
 {
   // Adapt the C++ string class
   return string(cstr_oneuse()).substr(start, len);
Index: String++.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/String++.h,v
retrieving revision 2.8
diff -u -p -r2.8 String++.h
--- String++.h	9 Nov 2002 13:48:16 -0000	2.8
+++ String++.h	16 Mar 2003 04:35:59 -0000
@@ -43,7 +43,7 @@ public:
   			      // pretends to be const !!
   inline size_t size() const; // number of characters (!= storage size).
   size_t find (char) const;
-  String substr (size_t start = 0, size_t len = -1) const;
+  String substr (size_t start = 0, int len = -1) const;
   // operator == and != can be done if/when we have a 'casesensitive' flag to
   // the constructors
   // - means this sorts to the left of the parameter
Index: install.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/install.cc,v
retrieving revision 2.59
diff -u -p -r2.59 install.cc
--- install.cc	14 Mar 2003 09:54:35 -0000	2.59
+++ install.cc	16 Mar 2003 04:35:59 -0000
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2000, Red Hat, Inc.
+ * Copyright (c) 2003, Robert Collins <rbtcollins at hotmail dot com>
  *
  *     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
@@ -9,7 +10,7 @@
  *     A copy of the GNU General Public License can be found at
  *     http://www.gnu.org/
  *
- * Written by DJ Delorie <dj at cygnus dot com>
+ * Originally Written by DJ Delorie <dj at cygnus dot com>
  *
  */
 
@@ -79,28 +80,44 @@ static BoolOption NoReplaceOnReboot (fal
 				     "Disable replacing in-use files on next "
 				     "reboot.");
 
-static void
-init_dialog ()
+class Installer
+{
+  public:
+  static const char *StandardDirs[];
+  Installer();
+  void initDialog();
+  void progress (int bytes);
+  void uninstallOne (packagemeta &);
+  int replaceOne (packagemeta &);
+  void replaceOnRebootFailed (String const &fn);
+  void replaceOnRebootSucceeded (String const &fn, bool &rebootneeded);
+  int installOneSource (packagemeta &, packagesource &, String const &, String const &, package_type_t);
+  int errors;
+};
+
+Installer::Installer() : errors(0)
+{
+}
+
+void
+Installer::initDialog()
 {
   Progress.SetText2 ("");
   Progress.SetText3 ("");
 }
 
-static void
-progress (int bytes)
+void
+Installer::progress (int bytes)
 {
   if (package_bytes > 0)
-    {
       Progress.SetBar1 (bytes, package_bytes);
-    }
 
   if (total_bytes > 0)
-    {
       Progress.SetBar2 (total_bytes_sofar + bytes, total_bytes);
-    }
 }
 
-static const char *standard_dirs[] = {
+const char *
+Installer::StandardDirs[] = {
   "/bin",
   "/etc",
   "/lib",
@@ -120,16 +137,11 @@ static const char *standard_dirs[] = {
 };
 
 static int num_installs, num_replacements, num_uninstalls;
-static void uninstall_one (packagemeta &);
-static int replace_one (packagemeta &);
-static int install_one_source (packagemeta &, packagesource &, String const &,
-			       String const &, package_type_t);
 static void md5_one (const packagesource& source);
 static bool rebootneeded;
 
-/* FIXME: upgrades should be a method too */
-static void
-uninstall_one (packagemeta & pkgm)
+void
+Installer::uninstallOne (packagemeta & pkgm)
 {
   Progress.SetText1 ("Uninstalling...");
   Progress.SetText2 (pkgm.name.cstr_oneuse());
@@ -144,8 +156,8 @@ uninstall_one (packagemeta & pkgm)
  * ASSUMPTIONS: pkgm is installed.
  *		pkgm has a desired package.
  */
-static int
-replace_one (packagemeta & pkg)
+int
+Installer::replaceOne (packagemeta &pkg)
 {
   int errors = 0;
   Progress.SetText1 ("Replacing...");
@@ -155,7 +167,7 @@ replace_one (packagemeta & pkg)
   pkg.uninstall ();
 
   errors +=
-    install_one_source (pkg, *pkg.desired.source(), "cygfile://","/", package_binary);
+    installOneSource (pkg, *pkg.desired.source(), "cygfile://","/", package_binary);
   if (!errors)
     pkg.installed = pkg.desired;
   num_replacements++;
@@ -164,8 +176,8 @@ replace_one (packagemeta & pkg)
 
 /* log failed scheduling of replace-on-reboot of a given file. */
 /* also increment errors. */
-static void
-log_ror_failure (String const &fn, int &errors)
+void
+Installer::replaceOnRebootFailed (String const &fn)
 {
   log (LOG_TIMESTAMP,
        "Unable to schedule reboot replacement of file %s with %s (Win32 Error %ld)",
@@ -177,8 +189,8 @@ log_ror_failure (String const &fn, int &
 
 /* log successful scheduling of replace-on-reboot of a given file. */
 /* also set rebootneeded. */
-static void
-log_ror_success (String const &fn, bool &rebootneeded)
+void
+Installer::replaceOnRebootSucceeded (String const &fn, bool &rebootneeded)
 {
   log (LOG_TIMESTAMP,
        "Scheduled reboot replacement of file %s with %s",
@@ -188,11 +200,10 @@ log_ror_success (String const &fn, bool 
 }
 
 /* install one source at a given prefix. */
-static int
-install_one_source (packagemeta & pkgm, packagesource & source,
+int
+Installer::installOneSource (packagemeta & pkgm, packagesource & source,
 		    String const &prefixURL, String const &prefixPath, package_type_t type)
 {
-  int errors = 0;
   Progress.SetText2 (source.Base ());
   if (!source.Cached () || !io_stream::exists (source.Cached ()))
     {
@@ -243,6 +254,8 @@ install_one_source (packagemeta & pkgm, 
 	    }
 
 	  String canonicalfn = prefixPath + fn;
+	  if (Script::isAScript (fn))
+	    pkgm.desired.addScript (Script (canonicalfn));
 
 	  Progress.SetText3 (canonicalfn.cstr_oneuse());
 	  log (LOG_BABBLE, String("Installing file ") + prefixURL + prefixPath + fn);
@@ -261,7 +274,7 @@ install_one_source (packagemeta & pkgm, 
 		  log (LOG_PLAIN,
 		       String("Unable to install file ") +
 		       prefixURL + prefixPath + fn);
-		  errors++;
+		  ++errors;
 		}
 	      else
 		//switch Win32::OS
@@ -277,7 +290,7 @@ install_one_source (packagemeta & pkgm, 
 					  source, MAX_PATH);
 		      if (!len || len > MAX_PATH)
 			{
-			  log_ror_failure (fn, errors);
+			  replaceOnRebootFailed(fn);
 			}
 		      else
 			{
@@ -287,20 +300,14 @@ install_one_source (packagemeta & pkgm, 
 						       fn).cstr_oneuse(),
 					      dest, MAX_PATH);
 			  if (!len || len > MAX_PATH)
-			    {
-			      log_ror_failure (fn, errors);
-			    }
+			      replaceOnRebootFailed (fn);
 			  else
 			    /* trigger a replacement on reboot */
 			  if (!WritePrivateProfileString
 				("rename", dest, source, "WININIT.INI"))
-			    {
-			      log_ror_failure (fn, errors);
-			    }
+			      replaceOnRebootFailed (fn);
 			  else
-			    {
-			      log_ror_success (fn, rebootneeded);
-			    }
+			      replaceOnRebootSucceeded (fn, rebootneeded);
 			}
 		    }
 		      break;
@@ -316,17 +323,16 @@ install_one_source (packagemeta & pkgm, 
 				       MOVEFILE_DELAY_UNTIL_REBOOT |
 				       MOVEFILE_REPLACE_EXISTING))
 			{
-			  log_ror_failure (fn, errors);
+			  replaceOnRebootFailed (fn);
 			}
 		      else
 			{
-			  log_ror_success (fn, rebootneeded);
+			  replaceOnRebootSucceeded (fn, rebootneeded);
 			}
 		      break;
 		    }
 		}
 	    }
-
 	  progress (tmp->tell ());
 	  num_installs++;
 	}
@@ -335,7 +341,6 @@ install_one_source (packagemeta & pkgm, 
       total_bytes_sofar += package_bytes;
     }
 
-
   progress (0);
 
   int df = diskfull (get_root_dir ().cstr_oneuse());
@@ -353,17 +358,18 @@ install_one (packagemeta & pkg)
 {
   int errors = 0;
 
+  Installer myInstaller;
   if (pkg.installed != pkg.desired && pkg.desired.picked())
     {
       errors +=
-	install_one_source (pkg, *pkg.desired.source(), "cygfile://","/",
+	myInstaller.installOneSource (pkg, *pkg.desired.source(), "cygfile://","/",
 			    package_binary);
       if (!errors)
 	pkg.installed = pkg.desired;
     }
   if (pkg.desired.sourcePackage().picked())
     errors +=
-      install_one_source (pkg, *pkg.desired.sourcePackage().source(), "cygfile://","/usr/src/",
+      myInstaller.installOneSource (pkg, *pkg.desired.sourcePackage().source(), "cygfile://","/usr/src/",
 			  package_source);
 
   /* FIXME: make a upgrade method and reinstate this */
@@ -453,9 +459,9 @@ do_install_thread (HINSTANCE h, HWND own
 
   io_stream::mkpath_p (PATH_TO_DIR, String ("file://") + get_root_dir ());
 
-  for (i = 0; standard_dirs[i]; i++)
+  for (i = 0; Installer::StandardDirs[i]; i++)
     {
-      String p = cygpath (standard_dirs[i]);
+      String p = cygpath (Installer::StandardDirs[i]);
       if (p.size())
 	io_stream::mkpath_p (PATH_TO_DIR, String ("file://") + p);
     }
@@ -464,7 +470,8 @@ do_install_thread (HINSTANCE h, HWND own
   io_stream *utmp = io_stream::open ("cygfile:///var/run/utmp", "wb");
   delete utmp;
 
-  init_dialog ();
+  Installer myInstaller;
+  myInstaller.initDialog();
 
   total_bytes = 0;
   total_bytes_sofar = 0;
@@ -529,7 +536,7 @@ do_install_thread (HINSTANCE h, HWND own
       packagemeta & pkg = **i;
       if (pkg.installed && (!pkg.desired || (pkg.desired != pkg.installed &&
 	  pkg.desired.picked ())))
-	uninstall_one (pkg);
+	myInstaller.uninstallOne (pkg);
     }
 
   /* now in-place binary upgrades/reinstalls, as these may remove fils 
@@ -544,7 +551,7 @@ do_install_thread (HINSTANCE h, HWND own
 	{
 	  try {
 	      int e = 0;
-	    e += replace_one (pkg);
+	    e += myInstaller.replaceOne (pkg);
  	    if (e)
 	      errors++;
 	  }
Index: package_version.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/package_version.cc,v
retrieving revision 2.16
diff -u -p -r2.16 package_version.cc
--- package_version.cc	9 Mar 2003 02:17:49 -0000	2.16
+++ package_version.cc	16 Mar 2003 04:35:59 -0000
@@ -57,6 +57,10 @@ public:
   void set_ldesc (String const &) {}
   void uninstall (){}
   void pick(bool const &newValue){/* Ignore attempts to pick this!. Throw an exception here if you want to detect such attemtps instead */}
+  virtual void addScript(Script const &) {}
+  virtual std::vector <Script> &scripts() { scripts_.clear();  return scripts_;}
+  private:
+    std::vector <Script> scripts_;
 };
 static _defaultversion defaultversion;
 
@@ -448,6 +452,18 @@ packageversion::set_requirements (trusts
   return changed;
 }
 
+void
+packageversion::addScript(Script const &aScript)
+{
+  return data->addScript (aScript);
+}
+
+std::vector <Script> &
+packageversion::scripts()
+{
+  return data->scripts();
+}
+
 /* the parent data class */
   
 _packageversion::_packageversion ():picked (false), references (0)
@@ -519,4 +535,16 @@ bool
 _packageversion::changeRequested ()
 {
   return (picked || sourcePackage().picked());
+}
+
+void
+_packageversion::addScript(Script const &aScript)
+{
+  scripts().push_back(aScript);
+}
+
+std::vector <Script> &
+_packageversion::scripts()
+{
+  return scripts_;
 }
Index: package_version.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/package_version.h,v
retrieving revision 2.14
diff -u -p -r2.14 package_version.h
--- package_version.h	9 Mar 2003 02:17:49 -0000	2.14
+++ package_version.h	16 Mar 2003 04:35:59 -0000
@@ -44,6 +44,7 @@ class CategoryList;
 #include "String++.h"
 #include "PackageSpecification.h"
 #include "PackageTrust.h"
+#include "script.h"
 #include <vector>
 
 typedef enum
@@ -141,6 +142,9 @@ public:
   /* ensure that the depends clause is satisfied */
   int set_requirements (trusts deftrust = TRUST_CURR, size_t depth = 0);
 
+  void addScript(Script const &);
+  std::vector <Script> &scripts();
+
 private:
   _packageversion *data; /* Invariant: * data is always valid */
 };
@@ -200,10 +204,13 @@ public:
      static package_meta * scan_package (io_stream *);
    */
   size_t references;
+  virtual void addScript(Script const &);
+  virtual std::vector <Script> &scripts();
 protected:
   /* only meaningful for binary packages */
   PackageSpecification _sourcePackage;
   packageversion sourceVersion;
+  std::vector <Script> scripts_;
 };
 
 #endif /* _PACKAGE_VERSION_H_ */
Index: postinstall.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/postinstall.cc,v
retrieving revision 2.9
diff -u -p -r2.9 postinstall.cc
--- postinstall.cc	19 May 2002 03:07:51 -0000	2.9
+++ postinstall.cc	16 Mar 2003 04:35:59 -0000
@@ -26,6 +26,8 @@ static const char *cvsid =
 #include "mount.h"
 #include "script.h"
 #include "FindVisitor.h"
+#include "package_db.h"
+#include "package_meta.h"
 
 class RunFindVisitor : public FindVisitor
 {
@@ -47,7 +49,18 @@ do_postinstall (HINSTANCE h, HWND owner)
   next_dialog = 0;
   init_run_script ();
   SetCurrentDirectory (get_root_dir ().cstr_oneuse());
+  packagedb db;
+  std::vector <packagemeta *>::iterator i = db.packages.begin ();
+  while (i != db.packages.end ())
+    {
+      packagemeta & pkg = **i;
+      if (pkg.installed)
+	for (std::vector<Script>::iterator script=pkg.installed.scripts().begin(); script != pkg.installed.scripts().end(); ++script) 
+	  run_script ("/etc/postinstall/", script->baseName());
+      ++i;
+    }
   RunFindVisitor myVisitor;
   String postinst = cygpath ("/etc/postinstall");
   Find (postinst).accept (myVisitor);
+  
 }
Index: script.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/script.cc,v
retrieving revision 2.5
diff -u -p -r2.5 script.cc
--- script.cc	15 Mar 2003 22:14:40 -0000	2.5
+++ script.cc	16 Mar 2003 04:35:59 -0000
@@ -30,6 +30,7 @@ static const char *cvsid =
 #include "filemanip.h"
 #include "mount.h"
 #include "io_stream.h"
+#include "script.h"
 
 static String sh = String();
 static const char *cmd = 0;
@@ -139,3 +140,27 @@ try_run_script (String const &dir, Strin
     run_script (dir.cstr_oneuse(), (fname + ".bat").cstr_oneuse());
 }
 
+bool
+Script::isAScript (String const &file)
+{
+    /* file may be /etc/postinstall or etc/postinstall */
+    if (file.casecompare ("/etc/postinstall/", 17) && file.casecompare ("etc/postinstall/", 16))
+      return false;
+    if (file.cstr_oneuse()[file.size() - 1] == '/')
+      return false;
+    return true;
+}
+
+Script::Script (String const &fileName) : scriptName (fileName)
+{
+  
+}
+
+String
+Script::baseName()const
+{
+  String result = scriptName;
+  while (result.find ('/'))
+    result = result.substr(result.find ('/'));
+  return result;
+}
Index: script.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/script.h,v
retrieving revision 2.2
diff -u -p -r2.2 script.h
--- script.h	18 Feb 2002 12:35:23 -0000	2.2
+++ script.h	16 Mar 2003 04:35:59 -0000
@@ -29,4 +29,13 @@ void init_run_script ();
 /* Run the scripts fname.sh and fname.bat, found in dir. */
 void try_run_script (String const &dir, String const &fname);
 
+class Script {
+  public:
+    static bool isAScript (String const &file);
+    Script (String const &fileName);
+    String baseName()const;
+  private:
+    String scriptName;
+};
+
 #endif /* SCRIPT_H */

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