Attached is a patch to setup that redirects the output of postinstall
scripts to a file (/var/log/setup.log.postinstall), bracketing it with
timestamped "Running <scriptname>" and "Done <scriptname>".

It's currently not tied into the logging mechanism, and it only redirects
the postinstall scripts (as compared to preremove and postremove), but
both are reasonably easy to add building on this patch.

The patch was tested on Win2k SP2 and Win98 (the two systems I have access
to).  In particular, I did a clean install on the Win98 machine, and the
output from all .sh and .bat postinstall scripts went into a (newly
created) /var/log/setup.log.postinstall.
        Igor

ChangeLog:
2002-10-17  Igor Pechtchanski <[EMAIL PROTECTED]>

        * script.cc (run): Add lname parameter.
        Redirect output of subprocess to file, creating the
        path if necessary.
        (run_script): Add optional lname parameter.
        (get_now_string): New function.
        (prepareOutputLog): New function.
        (closeOutputLog): New function.
        (log_failure_notified): New static variable.
        * script.h (run_script): Add optional lname parameter.
        * postinstall.cc (RunFindVisitor::visitFile): Pass
        filename to run_script().

-- 
                                http://cs.nyu.edu/~pechtcha/
      |\      _,,,---,,_                [EMAIL PROTECTED]
ZZZzz /,`.-'`'    -.  ;-;;,_            [EMAIL PROTECTED]
     |,4-  ) )-,_. ,\ (  `'-'           Igor Pechtchanski
    '---''(_/--'  `-'\_) fL     a.k.a JaguaR-R-R-r-r-r-.-.-.  Meow!

"Water molecules expand as they grow warmer" (C) Popular Science, Oct'02, p.51

--- ./postinstall.cc-orig       2002-05-18 23:07:52.000000000 -0400
+++ ./postinstall.cc    2002-10-16 19:40:07.000000000 -0400
@@ -33,7 +33,7 @@ public:
   RunFindVisitor (){}
   virtual void visitFile(String const &basePath, const WIN32_FIND_DATA *theFile)
     {
-      run_script ("/etc/postinstall/", theFile->cFileName);
+      run_script ("/etc/postinstall/", theFile->cFileName, 
+"/var/log/setup.log.postinstall");
     }
   virtual ~ RunFindVisitor () {}
 protected:
--- ./script.cc-orig    2002-02-18 08:53:08.000000000 -0500
+++ ./script.cc 2002-10-17 18:45:27.000000000 -0400
@@ -30,6 +30,11 @@ static const char *cvsid =
 #include "filemanip.h"
 #include "mount.h"
 #include "io_stream.h"
+#include <time.h>
+#include "script.h"
+#include "mkdir.h"
+#include "msg.h"
+#include "resource.h"
 
 static String sh = String();
 static const char *cmd = 0;
@@ -78,13 +83,74 @@ init_run_script ()
     }
 }
 
+static String const
+get_now_string()
+{
+  time_t now;
+  time (&now);
+  char buf[100];
+  struct tm *tm = localtime (&now);
+  strftime (buf, 100, "%Y/%m/%d %H:%M:%S ", tm);
+  return String(buf);
+}
+
+static BOOL
+prepareOutputLog(HANDLE &file_out, String const &lname, const char *cmdline)
+{
+  DWORD nout;
+  SECURITY_ATTRIBUTES sa;
+  memset (&sa, 0, sizeof (sa));
+  sa.nLength = sizeof (sa);
+  sa.bInheritHandle = TRUE;
+  sa.lpSecurityDescriptor = NULL;
+
+  if (mkdir_p (0, cygpath (lname).cstr_oneuse()))
+    return FALSE;
+
+  file_out = CreateFile (backslash (cygpath (lname)).cstr_oneuse(),
+      GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
+      &sa, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+  if (file_out == INVALID_HANDLE_VALUE)
+    return FALSE;
+
+  String msg = get_now_string () + "Running: " + cmdline + "\n";
+  DWORD msgl = (DWORD) msg.size();
+  SetFilePointer (file_out, 0, NULL, FILE_END);
+  if (!WriteFile (file_out, msg.cstr_oneuse(), msgl, &nout, NULL) ||
+      nout != msgl)
+    {
+      CloseHandle (file_out);
+      file_out = INVALID_HANDLE_VALUE;
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 static void
-run (const char *sh, const char *args, const char *file)
+closeOutputLog(HANDLE file_out, const char *cmdline)
+{
+  DWORD nout;
+  if (file_out == INVALID_HANDLE_VALUE)
+    return;
+
+  String msg = get_now_string () + "Done: " + cmdline + "\n";
+  WriteFile (file_out, msg.cstr_oneuse(), msg.size(), &nout, NULL);
+  CloseHandle (file_out);
+}
+
+static BOOL log_failure_notified = FALSE;
+
+static void
+run (const char *sh, const char *args, const char *file, String const &lname)
 {
   BOOL b;
   char cmdline[_MAX_PATH];
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
+  HANDLE file_out = INVALID_HANDLE_VALUE;
+  DWORD dwCPFlags = CREATE_NEW_CONSOLE;
+  BOOL bInheritHandles = FALSE;
 
   sprintf (cmdline, "%s %s %s", sh, args, file);
   memset (&pi, 0, sizeof (pi));
@@ -93,15 +159,37 @@ run (const char *sh, const char *args, c
   si.lpTitle = (char *) "Cygwin Setup Post-Install Script";
   si.dwFlags = STARTF_USEPOSITION;
 
-  b = CreateProcess (0, cmdline, 0, 0, 0,
-                    CREATE_NEW_CONSOLE, 0, get_root_dir ().cstr_oneuse(), &si, &pi);
+  if (lname.size())
+    if (prepareOutputLog (file_out, lname, cmdline))
+      {
+       bInheritHandles = TRUE;
+       si.dwFlags = STARTF_USESTDHANDLES;
+       si.hStdOutput = file_out;
+       si.hStdError = file_out;
+       dwCPFlags = 0;
+      }
+    else if (!log_failure_notified)
+      {
+       const char *err = strerror (errno);
+       if (!err)
+         err = "(unknown error)";
+       String serr = String (err) + "; using console";
+       note (0, IDS_ERR_OPEN_WRITE, lname.cstr_oneuse(), serr.cstr_oneuse());
+       log_failure_notified = TRUE;
+      }
+
+  b = CreateProcess (0, cmdline, 0, 0, bInheritHandles,
+                    dwCPFlags, 0, get_root_dir ().cstr_oneuse(), &si, &pi);
 
   if (b)
     WaitForSingleObject (pi.hProcess, INFINITE);
+
+  if (lname.size())
+    closeOutputLog (file_out, cmdline);
 }
 
 void
-run_script (String const &dir, String const &fname)
+run_script (String const &dir, String const &fname, String const &lname)
 {
   char *ext = strrchr (fname.cstr_oneuse(), '.');
   if (!ext)
@@ -111,13 +199,13 @@ run_script (String const &dir, String co
     {
       String f2 = dir + fname;
       log (LOG_PLAIN, String ("running: ") + sh + " -c " + f2);
-      run (sh.cstr_oneuse(), "-c", f2.cstr_oneuse());
+      run (sh.cstr_oneuse(), "-c", f2.cstr_oneuse(), lname);
     }
   else if (cmd && strcmp (ext, ".bat") == 0)
     {
       String f2 = backslash (cygpath (dir + fname));
       log (LOG_PLAIN, String ("running: ") + cmd + " /c " + f2);
-      run (cmd, "/c", f2.cstr_oneuse());
+      run (cmd, "/c", f2.cstr_oneuse(), lname);
     }
   else
     return;
--- ./script.h-orig     2002-02-18 07:35:24.000000000 -0500
+++ ./script.h  2002-10-16 18:55:55.000000000 -0400
@@ -21,7 +21,7 @@
    we have a Bourne shell, execute it using sh.  Otherwise, if fname
    has suffix .bat, execute using cmd */
    
-void run_script (String const &dir, String const &fname);
+void run_script (String const &dir, String const &fname, String const &lname = "");
 
 /* Initialisation stuff for run_script: sh, cmd, CYGWINROOT and PATH */
 void init_run_script ();

Reply via email to