]> cygwin.com Git - cygwin-apps/setup.git/commitdiff
2003-03-16 Robert Collins <rbtcollins@hotmail.com>
authorRobert Collins <rbtcollins@hotmail.com>
Mon, 17 Mar 2003 22:23:33 +0000 (22:23 +0000)
committerRobert Collins <rbtcollins@hotmail.com>
Mon, 17 Mar 2003 22:23:33 +0000 (22:23 +0000)
* package_db.h (PackageDBConnectedIterator): Typedef for connected loop detection collection iterator.
* package_db.cc (ConnectedLoopDetector): An implementation of R.E. Tarjans strongly connected set visitor algorithm.
* postinstall.cc (do_postinstall): Use the new iterator for visiting postinstall scripts.

2003-03-16  Robert Collins  <rbtcollins@hotmail.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.

ChangeLog
String++.cc
String++.h
install.cc
package_db.cc
package_db.h
package_version.cc
package_version.h
postinstall.cc
script.cc
script.h

index 351da72a863b478f0df6994de42e64d9417e55af..bb094599719da68fd09773edbdded7cc462c4e8a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2003-03-16  Robert Collins  <rbtcollins@hotmail.com>
+
+       * package_db.h (PackageDBConnectedIterator): Typedef for connected loop detection collection iterator.
+       * package_db.cc (ConnectedLoopDetector): An implementation of R.E. Tarjans strongly connected set visitor algorithm.
+       * postinstall.cc (do_postinstall): Use the new iterator for visiting postinstall scripts.
+
+2003-03-16  Robert Collins  <rbtcollins@hotmail.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-16  Max Bowsher  <maxb@ukf.net>
 
        * .cvsignore: Create, to ignore configure, aclocal.m4, Makefile.in and
index 4d089a86d706adc16c422d8022e31d3d647d0bc5..56ca450e0ed2815584703a25c350c955412bcf60 100644 (file)
@@ -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 bd8f6f9a7d851988aa6e97e7016b55fc2e9f6a99..81c6561e4261bdeb8eba8f6ec31a122c003cba59 100644 (file)
@@ -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 686c24b4c3861abca41b009c4752eaf9bc49097f..def8b207e519634917583ee752cbd4f0cee27983 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2000, Red Hat, Inc.
+ * Copyright (c) 2003, Robert Collins <rbtcollins@hotmail.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@cygnus.com>
+ * Originally Written by DJ Delorie <dj@cygnus.com>
  *
  */
 
@@ -79,28 +80,44 @@ static BoolOption NoReplaceOnReboot (false, 'r', "no-replaceonreboot",
                                     "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 &errors)
 
 /* 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 &rebootneeded)
 }
 
 /* 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, packagesource & source,
            }
 
          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, packagesource & source,
                  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, packagesource & source,
                                          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, packagesource & source,
                                                       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, packagesource & source,
                                       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, packagesource & source,
       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 owner)
 
   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 owner)
   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 owner)
       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 owner)
        {
          try {
              int e = 0;
-           e += replace_one (pkg);
+           e += myInstaller.replaceOne (pkg);
            if (e)
              errors++;
          }
index 766954a743ee82f13f5b3b91adb50163ae02a267..773fe6f56d4e23d3f503d2729a65280c0b7cfccd 100644 (file)
@@ -39,6 +39,7 @@ static const char *cvsid =
 #include "cygpackage.h"
 #include "package_db.h"
 #include "package_meta.h"
+#include "Exception.h"
 
 using namespace std;
 
@@ -207,3 +208,143 @@ vector <packagemeta *> packagedb::sourcePackages;
 PackageDBActions
   packagedb::task =
   PackageDB_Install;
+std::vector <packagemeta *> 
+packagedb::dependencyOrderedPackages;
+
+#include "LogSingleton.h"
+#include <stack>
+
+class
+ConnectedLoopFinder
+{
+  public:
+  ConnectedLoopFinder();
+  void doIt();
+  packagedb db;
+  size_t visited;
+  std::vector<size_t> visitOrder;
+  size_t visit (size_t const nodeToVisit);
+  std::stack<size_t> nodesInStronglyConnectedComponent;
+};
+
+ConnectedLoopFinder::ConnectedLoopFinder() : visited(0)
+{
+  for (size_t counter = 0; counter < db.packages.size(); ++counter)
+    visitOrder.push_back(0);
+}
+
+void
+ConnectedLoopFinder::doIt()
+{
+  /* XXX this could be done useing a class to hold both the visitedInIteration and the package
+   * meta reference. Then we could use a range, not an int loop. 
+   */
+  for (size_t i = 0; i < db.packages.size(); ++i)
+    {
+      packagemeta &pkg (*db.packages[i]);
+      if (pkg.installed && ! visitOrder[i])
+       visit (i);
+    }
+  log (LOG_PLAIN) << "Visited: " << visited << " nodes out of " << db.packages.size() << "." << endLog;
+}
+
+static bool
+checkForInstalled (PackageSpecification *spec)
+{
+  packagedb db;
+  packagemeta *required = db.findBinary (*spec);
+  if (!required)
+    return false;
+  if (spec->satisfies (required->installed)
+      && required->desired == required->installed )
+    /* done, found a satisfactory installed version that will remain
+       installed */
+    return true;
+  return false;
+}
+
+size_t
+ConnectedLoopFinder::visit(size_t const nodeToVisit)
+{
+  if (!db.packages[nodeToVisit]->installed)
+    /* Can't visit this node, and it is not less than any visted node */
+    return db.packages.size() + 1;
+  ++visited;
+  visitOrder[nodeToVisit] = visited;
+
+  size_t minimumVisitId = visited;
+  nodesInStronglyConnectedComponent.push(nodeToVisit);
+
+  vector <vector <PackageSpecification *> *>::iterator dp = db.packages[nodeToVisit]->installed.depends ()->begin();
+  /* walk through each and clause (a link in the graph) */
+  while (dp != db.packages[nodeToVisit]->installed.depends ()->end())
+    {
+      /* check each or clause for an installed match */
+      vector <PackageSpecification *>::iterator i =
+       find_if ((*dp)->begin(), (*dp)->end(), checkForInstalled);
+      if (i != (*dp)->end())
+       {
+         /* we found an installed ok package */
+         /* visit it if needed */
+         /* UGLY. Need to refactor. iterators in the outer would help as we could simply
+          * vist the iterator
+          */
+          size_t nodeJustVisited = 0;
+          while (nodeJustVisited < db.packages.size() && db.packages[nodeJustVisited]->name.casecompare((*i)->packageName())) 
+            ++nodeJustVisited;
+          if (nodeJustVisited == db.packages.size())
+            log (LOG_PLAIN) << "Search for package '" << (*i)->packageName() << "' failed." << endLog;
+          else
+          {
+            if (visitOrder[nodeJustVisited])
+              minimumVisitId = std::min (minimumVisitId, visitOrder[nodeJustVisited]);
+            else
+              minimumVisitId = std::min (minimumVisitId, visit (nodeJustVisited));
+          }
+         /* next and clause */
+         ++dp;
+         continue;
+       }
+       /* not installed or not available we ignore */
+      ++dp;
+    }
+  
+  if (minimumVisitId == visitOrder[nodeToVisit])
+  {
+    size_t popped;
+    do {
+      popped = nodesInStronglyConnectedComponent.top();
+      nodesInStronglyConnectedComponent.pop();
+      db.dependencyOrderedPackages.push_back(db.packages[popped]);
+      /* mark as displayed in a connected component */
+      visitOrder[popped] = db.packages.size() + 2;
+    } while (popped != nodeToVisit);
+  }
+  
+  return minimumVisitId;
+}  
+
+PackageDBConnectedIterator
+packagedb::connectedBegin()
+{
+  if (!dependencyOrderedPackages.size())
+  {
+  ConnectedLoopFinder doMe;
+  doMe.doIt();
+  log(LOG_PLAIN) << "Dependency ordered install:" << endLog;
+  for (std::vector<packagemeta *>::iterator i = dependencyOrderedPackages.begin();
+    i != dependencyOrderedPackages.end(); ++i)
+    {
+      packagemeta &pkg (**i);
+      log(LOG_PLAIN) << pkg.name << endLog;
+    }
+  }
+    
+  return dependencyOrderedPackages.begin();
+}
+
+PackageDBConnectedIterator
+packagedb::connectedEnd()
+{
+  return dependencyOrderedPackages.end();
+}
index 54a3bf704ab13be28db53c07bb184295fad78926..25e26e1ee6c019b4f4e05218518bf6cdff0d0fbf 100644 (file)
@@ -30,6 +30,10 @@ typedef enum {
   PackageDB_Download
 } PackageDBActions;
 
+
+class packagedb;
+typedef std::vector <packagemeta *>::iterator PackageDBConnectedIterator;
+
 /*TODO: add mutexs */
 class packagedb
 {
@@ -39,6 +43,8 @@ public:
   int flush ();
   packagemeta * findBinary (PackageSpecification const &) const;
   packagemeta * findSource (PackageSpecification const &) const;
+  PackageDBConnectedIterator connectedBegin();
+  PackageDBConnectedIterator connectedEnd();
   /* all seen binary packages */
   static std::vector < packagemeta *> packages;
   /* all seen source packages */
@@ -49,6 +55,8 @@ public:
   static PackageDBActions task;
 private:
   static int installeddbread;  /* do we have to reread this */
+  friend class ConnectedLoopFinder;
+  static std::vector <packagemeta *> dependencyOrderedPackages;
 };
 
 #endif /* _PACKAGE_DB_H_ */
index 63a71a60463934c93548ed169b8e2d3d7a55f69a..086b82c081e5f06d30f0d23e5b4141bcc93df49a 100644 (file)
@@ -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 deftrust, size_t depth)
   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)
@@ -520,3 +536,15 @@ _packageversion::changeRequested ()
 {
   return (picked || sourcePackage().picked());
 }
+
+void
+_packageversion::addScript(Script const &aScript)
+{
+  scripts().push_back(aScript);
+}
+
+std::vector <Script> &
+_packageversion::scripts()
+{
+  return scripts_;
+}
index af6637871839f31a90b7ffd4957878374e8459a9..92a035cccb5995992704fdcdc8f184092993f357 100644 (file)
@@ -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 ced84cf8a0c8f313cc1beefa22a993db1ddac371..da75eb9d2e531f768262387f137ce4feeba70e37 100644 (file)
@@ -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;
+  PackageDBConnectedIterator i = db.connectedBegin ();
+  while (i != db.connectedEnd ())
+    {
+      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 5df875f659c2478c36de96d81db761e63b02bd79..a6eb8b4e380c88934905d1caabf2e4cde6ee0d15 100644 (file)
--- a/script.cc
+++ b/script.cc
@@ -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, String const &fname)
     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 9b1e462d3e067b41a1c2940c3555844f99f89ca0..78bdc9d65cc15bf565a6151bbd2578e92efa0184 100644 (file)
--- a/script.h
+++ b/script.h
@@ -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 */
This page took 0.063339 seconds and 5 git commands to generate.