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 ();