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]

[PATCH setup 3/3] Add support for 'trigger:' lines in setup.ini


This is intended as a replacement for the setup.hint 'incver_ifdep:' line,
processed by upset, which is now only used by the _update-info-dir package.

The appearance in setup.ini of a 'trigger: <prefix>' line for a package causes
setup to create the file /var/cache/setup-triggers/<packagename> whenever a file
or directory with <prefix> as an initial substring is installed or uninstalled.

Once this is deployed, the _update-info-dir package can be updated to add
'trigger: usr/share/info/' to it's setup.hint, and contain a permanent
postinstall script which updates the info directory if the trigger file
/var/cache/setup-triggers/_update-info-dir is present.

(The current /etc/postinstall/update-info-dir script checks both /usr/info and
/usr/share/info, but there are no packages which install anything into
/usr/info, and the packaging guidelines require --infodir=/usr/share/info)

(Also currently nothing is updated when a package containing info files is
removed, which is possibly wrong)

This isn't the best solution.  Perhaps ideally, the packages which contain info
files would themselves create these trigger files on install and remove (which
could be achieved by having cygport add postinstall and preremove scripts to
create this trigger), but it's rather too late for that now.

	* IniDBBuilder.h (IniDBBuilder:buildTrigger): Define for base class.
	* IniDBBuilderPackage.cc (buildTrigger): Define.
	* IniDBBuilderPackage.h (IniDBBuilder): Declare.
	* Makefile.am (@SETUP@_SOURCES): Add trigger.cc and trigger.h
	* inilex.ll: Add 'trigger' token recognition.
	* iniparse.yy: Parse 'trigger' lines
	* install.cc (installOne): Check triggers.
	* package_meta.cc (uninstall): Check triggers.
	* trigger.cc: New file.
	* trigger.h: New file.

Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
---
 ChangeLog              | 13 ++++++++++
 IniDBBuilder.h         |  1 +
 IniDBBuilderPackage.cc |  7 +++++
 IniDBBuilderPackage.h  |  1 +
 Makefile.am            |  2 ++
 inilex.ll              |  1 +
 iniparse.yy            |  2 ++
 install.cc             |  4 +++
 package_meta.cc        |  3 +++
 trigger.cc             | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++
 trigger.h              | 42 ++++++++++++++++++++++++++++++
 11 files changed, 145 insertions(+)
 create mode 100644 trigger.cc
 create mode 100644 trigger.h

diff --git a/ChangeLog b/ChangeLog
index 4a6b3b8..a8cd291 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2015-09-22  Jon Turney  <jon.turney@dronecode.org.uk>
+
+	* IniDBBuilder.h (IniDBBuilder:buildTrigger): Define for base class.
+	* IniDBBuilderPackage.cc (buildTrigger): Define.
+	* IniDBBuilderPackage.h (IniDBBuilder): Declare.
+	* Makefile.am (@SETUP@_SOURCES): Add trigger.cc and trigger.h
+	* inilex.ll: Add 'trigger' token recognition.
+	* iniparse.yy: Parse 'trigger' lines
+	* install.cc (installOne): Check triggers.
+	* package_meta.cc (uninstall): Check triggers.
+	* trigger.cc: New file.
+	* trigger.h: New file.
+
 2015-09-18  Jon Turney  <jon.turney@dronecode.org.uk>
 
 	* IniDBBuilder.h (IniDBBuilder::autodep): Remove.
diff --git a/IniDBBuilder.h b/IniDBBuilder.h
index 0756d91..9ec823b 100644
--- a/IniDBBuilder.h
+++ b/IniDBBuilder.h
@@ -60,6 +60,7 @@ public:
   virtual void buildPackageListOperator (PackageSpecification::_operators const &) = 0;
   virtual void buildPackageListOperatorVersion (const std::string& ) = 0;
   virtual void buildMessage (const std::string&, const std::string&) = 0;
+  virtual void buildTrigger (const std::string&) = 0;
   void set_arch (const std::string& a) { arch = a; }
   void set_release (const std::string& rel) { release = rel; }
 
diff --git a/IniDBBuilderPackage.cc b/IniDBBuilderPackage.cc
index b75d0fd..9c5cba0 100644
--- a/IniDBBuilderPackage.cc
+++ b/IniDBBuilderPackage.cc
@@ -30,6 +30,7 @@
 #include <string.h>
 #include "LogSingleton.h"
 #include "PackageSpecification.h"
+#include "trigger.h"
 #include <algorithm>
 
 using namespace std;
@@ -626,3 +627,9 @@ IniDBBuilderPackage::buildMessage (const std::string& message_id, const std::str
 {
   cp->set_message (message_id, message);
 }
+
+void
+IniDBBuilderPackage::buildTrigger (const std::string& path)
+{
+  Triggers::AddTrigger(cp->name, path);
+}
diff --git a/IniDBBuilderPackage.h b/IniDBBuilderPackage.h
index 7b9e0d6..f0e87c7 100644
--- a/IniDBBuilderPackage.h
+++ b/IniDBBuilderPackage.h
@@ -62,6 +62,7 @@ public:
   virtual void buildBeginBinary ();
   virtual void buildDescription (const std::string&);
   virtual void buildMessage (const std::string&, const std::string&);
+  virtual void buildTrigger (const std::string&);
   virtual void buildSourceName (const std::string& );
   virtual void buildSourceNameVersion (const std::string& );
   virtual void buildPackageListAndNode ();
diff --git a/Makefile.am b/Makefile.am
index ca7af01..65160f6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -260,6 +260,8 @@ inilint_SOURCES = \
 	String++.h \
 	threebar.cc \
 	threebar.h \
+	trigger.cc \
+	trigger.h \
 	UserSettings.cc \
 	UserSettings.h \
 	win32.cc \
diff --git a/inilex.ll b/inilex.ll
index 49bbfa6..87f96f4 100644
--- a/inilex.ll
+++ b/inilex.ll
@@ -119,6 +119,7 @@ B64	[a-zA-Z0-9_-]
 "sdesc:"		return SDESC;
 "ldesc:"		return LDESC;
 "message:"		return MESSAGE;
+"trigger:"		return TRIGGER;
 "Description:"		BEGIN (descriptionstate); return DESCTAG;
 "Size:"			return FILESIZE;
 "MD5sum:"		return MD5LINE;
diff --git a/iniparse.yy b/iniparse.yy
index da3e5d0..50ab18b 100644
--- a/iniparse.yy
+++ b/iniparse.yy
@@ -53,6 +53,7 @@ void add_correct_version();
 %token BINARYPACKAGE BUILDDEPENDS STANDARDSVERSION FORMAT DIRECTORY FILES
 %token MESSAGE
 %token ARCH RELEASE
+%token TRIGGER
 
 %%
 
@@ -125,6 +126,7 @@ singleitem /* non-empty */
  | BUILDDEPENDS { iniBuilder->buildBeginBuildDepends(); } versionedpackagelist NL
  | FILES NL SourceFilesList
  | MESSAGE STRING STRING NL	{ iniBuilder->buildMessage ($2, $3); }
+ | TRIGGER STRING NL	{ iniBuilder->buildTrigger ($2); }
  | DESCTAG mlinedesc
  | error 			{ yyerror (std::string("unrecognized line ") 
 					  + stringify(yylineno)
diff --git a/install.cc b/install.cc
index a5c4b10..2f72bfe 100644
--- a/install.cc
+++ b/install.cc
@@ -64,6 +64,7 @@ static const char *cvsid = "\n%%% $Id$\n";
 #include "threebar.h"
 #include "Exception.h"
 #include "processlist.h"
+#include "trigger.h"
 
 using namespace std;
 
@@ -490,9 +491,12 @@ Installer::installOne (packagemeta &pkgm, const packageversion &ver,
           std::string tmp = fn + "\n";
           lst->write (tmp.c_str(), tmp.size());
         }
+
       if (Script::isAScript (fn))
         pkgm.desired.addScript (Script (canonicalfn));
 
+      Triggers::CheckTriggers(fn);
+
       int iteration = 0;
       archive::extract_results extres;
       while ((extres = archive::extract_file (tarstream, prefixURL, prefixPath)) != archive::extract_ok)
diff --git a/package_meta.cc b/package_meta.cc
index 34ff78c..d5be3a3 100644
--- a/package_meta.cc
+++ b/package_meta.cc
@@ -48,6 +48,7 @@ using namespace std;
 
 #include <algorithm>
 #include "Generic.h"
+#include "trigger.h"
 
 using namespace std;
 
@@ -161,6 +162,8 @@ packagemeta::uninstall ()
 
       while (line.size())
 	{
+          Triggers::CheckTriggers(line);
+
           /* Insert the paths of all parent directories of line into dirs. */
           size_t idx = line.length();
           while ((idx = line.find_last_of('/', idx-1)) != string::npos)
diff --git a/trigger.cc b/trigger.cc
new file mode 100644
index 0000000..0c85686
--- /dev/null
+++ b/trigger.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015 Red Hat, Inc.
+ *
+ *     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/
+ *
+ */
+
+#include "trigger.h"
+#include "io_stream.h"
+#include "LogSingleton.h"
+
+// ---------------------------------------------------------------------------
+// implements class Triggers
+//
+// This maintains a list of packages and pathnames. Whenever a file is added or
+// removed, we should check it against this list, and if it matches, a trigger
+// file named after the package is created
+//
+// At the moment, the pathname is a simple initial substring.  More complex
+// matching using a regex could be added if needed.
+//
+// This list is anticipated to be very small, so a linear search is acceptable.
+// ---------------------------------------------------------------------------
+
+static const std::string triggerFilePrefix = "cygfile:///var/cache/setup-triggers/";
+std::list <Trigger> Triggers::triggers;
+
+void
+Triggers::AddTrigger(std::string package, std::string pathprefix)
+{
+  Log (LOG_PLAIN) << "Adding trigger path '" << pathprefix << "' for package '" << package << "'" << endLog;
+  Trigger t(package, pathprefix);
+  triggers.push_front(t);
+}
+
+void
+Triggers::CheckTriggers(std::string fn)
+{
+  Log (LOG_BABBLE) << "Checking '" << fn << "' against triggers" << endLog;
+  for (TriggerList::const_iterator i = triggers.begin();
+       i != triggers.end();
+       i++)
+    {
+      // check if pathprefix is an initial substring of the fn
+      if ((fn.size() >= i->pathprefix.size()) &&
+          (fn.compare(0, i->pathprefix.size(), i->pathprefix) == 0))
+        {
+          std::string triggerFile = triggerFilePrefix + i->package;
+
+          Log (LOG_PLAIN) << "Creating trigger file '" << triggerFile << "'" << endLog;
+
+          // ensure the directory exists
+          io_stream::mkpath_p(PATH_TO_DIR, triggerFilePrefix, 0644);
+
+          // create the trigger file
+          io_stream *tmp = io_stream::open (triggerFile, "wb", 0644);
+          if (tmp == NULL)
+            Log (LOG_PLAIN) << "Warning: Unable to create trigger file '" + triggerFile << "'" << endLog;
+          else
+            delete tmp;
+        }
+    }
+}
diff --git a/trigger.h b/trigger.h
new file mode 100644
index 0000000..59e1a81
--- /dev/null
+++ b/trigger.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015 Red Hat, Inc.
+ *
+ *     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/
+ *
+ */
+
+#ifndef TRIGGERS_H
+#define TRIGGERS_H
+
+#include <string>
+#include <list>
+
+class Trigger
+{
+ public:
+  std::string package;
+  std::string pathprefix;
+
+  Trigger(std::string _package, std::string _pathprefix)
+   : package(_package), pathprefix(_pathprefix)
+    { };
+};
+
+class Triggers
+{
+ public:
+  static void AddTrigger(std::string package, std::string pathprefix);
+  static void CheckTriggers(std::string fn);
+
+ private:
+  typedef std::list <Trigger> TriggerList;
+  static TriggerList triggers;
+};
+
+#endif /* TRIGGERS_H */
-- 
2.5.3


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