bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

patch to add logging to `install' in coreutils-4.5.12


From: Sverre H. Huseby
Subject: patch to add logging to `install' in coreutils-4.5.12
Date: Sat, 10 May 2003 13:36:49 +0200
User-agent: Mutt/1.4.1i

Hi!

I've previously modified fileutils-3.16 and fileutils-4.1 to add
simple logging capabilities to the install program.  Now I "ported" my
patch to coreutils-4.5.12.  (Very little testing has been done after
the port.)

Logging is controlled by two environment variables:

  INSTALL_LOG_FILE     name of a file in which to add log lines.
  INSTALL_LOG_ID       (optional) tag to use in the logged lines.

If INSTALL_LOG_FILE is not set, install works just like it used to.
The logging install have helped me maintain my system since 1997.

According to http://www.gnu.org/software/coreutils/ you want a unified
diff, and you want it inline, not as an attachment, so here we go:




diff -ru coreutils-4.5.12/doc/coreutils.texi 
coreutils-4.5.12-shh/doc/coreutils.texi
--- coreutils-4.5.12/doc/coreutils.texi Thu Mar 27 16:54:46 2003
+++ coreutils-4.5.12-shh/doc/coreutils.texi     Sat May 10 13:25:22 2003
@@ -6463,6 +6463,50 @@
 
 @end table
 
+By setting the environment variable @code{INSTALL_LOG_FILE} to the
+name of a file, @code{install} will log changes by appending lines to
+the end of the given file.  An identifier for the installation process
+may be given in the environment variable @code{INSTALL_LOG_ID}.  This
+identifier is usefull if you want to separate files that come from
+different source packages.
+  
+Lines in the log file contains the following fields, separated by
+a single space character:
+
address@hidden @samp
+
address@hidden date
+The date of the installation, in ISO date format.
+
address@hidden time
+The time of the installation, in local time.
+
address@hidden ID
+Identifier as given by the @code{INSTALL_LOG_ID} environment variable.
+Defaults to "no-id" if the environment variable is unset.  Note that
+any occurences of space characters in the ID is replaced by an
+underscore character.  This simplifies automatic extraction of fields
+from the log file.
+
address@hidden mode
+The octal file permission mode of the file.
+
address@hidden owner
+The owner of the installed file.
+
address@hidden group
+The group of the file.
+
address@hidden directory
+Indicates whether the file name refers to a directory or not.  A 1 in
+this field means the file is a directory.  A 0 indicates a regular
+file.
+
address@hidden name
+The directory and name of the installed file.
+
address@hidden table
+
 
 @node mv invocation
 @section @command{mv}: Move (rename) files
diff -ru coreutils-4.5.12/src/install.c coreutils-4.5.12-shh/src/install.c
--- coreutils-4.5.12/src/install.c      Sun Dec 15 15:35:48 2002
+++ coreutils-4.5.12-shh/src/install.c  Sat May 10 13:25:30 2003
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 #include <pwd.h>
 #include <grp.h>
+#include <time.h>
 
 #include "system.h"
 #include "backupfile.h"
@@ -82,6 +83,9 @@
 static int change_attributes (const char *path);
 static int copy_file (const char *from, const char *to,
                      const struct cp_options *x);
+/* SHH: logging */
+static void log_install (const char *to,
+                         int mode, uid_t uid, gid_t gid, int is_dir);
 static int install_file_to_path (const char *from, const char *to,
                                 const struct cp_options *x);
 static int install_file_in_dir (const char *from, const char *to_dir,
@@ -119,6 +123,15 @@
 /* If nonzero, install a directory instead of a regular file. */
 static int dir_arg;
 
+/* SHH: If non-NULL, name of the file to which logging should be written. */
+static char *log_file;
+
+/* SHH: The current identification to include in loglines.  No SPC allowed. */
+static char *log_id;
+
+/* SHH: Perform logging to a file? */
+static int log_enabled = 0;
+
 static struct option const long_options[] =
 {
   {"backup", optional_argument, NULL, 'b'},
@@ -186,6 +199,8 @@
   struct cp_options x;
   int n_files;
   char **file;
+  /* SHH: logging */
+  char *log;
 
   program_name = argv[0];
   setlocale (LC_ALL, "");
@@ -206,6 +221,21 @@
      we'll actually use backup_suffix_string.  */
   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
 
+  /* SHH: log stuff */
+  log = getenv ("INSTALL_LOG_FILE");
+  if (log)
+    {
+      log_file = log;
+      log_enabled = 1;
+    }
+  log = getenv ("INSTALL_LOG_ID");
+  if (log)
+    {
+      /* make a copy, since this one may be changed later. */
+      log_id = xmalloc (strlen (log) + 1);
+      strcpy (log_id, log);
+    }
+
   while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pvV:S:", long_options,
                              NULL)) != -1)
     {
@@ -268,6 +298,20 @@
     error (EXIT_FAILURE, 0,
           _("the strip option may not be used when installing a directory"));
 
+  /* SHH: Remove any spaces from the log_id to simplify interpretation
+   * of the log file. */
+  if (log_id)
+    {
+      char *s = log_id;
+
+      while (*s)
+        {
+          if (*s == ' ')
+            *s = '_';
+          ++s;
+        }
+    }
+
   if (backup_suffix_string)
     simple_backup_suffix = xstrdup (backup_suffix_string);
 
@@ -302,9 +346,15 @@
       int i;
       for (i = 0; i < n_files; i++)
        {
-         errors |=
-           make_path (file[i], mode, mode, owner_id, group_id, 0,
-                      (x.verbose ? _("creating directory %s") : NULL));
+          int result;
+
+          result =
+            make_path (file[i], mode, mode, owner_id, group_id, 0,
+                       (x.verbose ? _("creating directory %s") : NULL));
+          /* SHH: log it */
+          if (result == 0)
+            log_install (file[i], mode, owner_id, group_id, 1);
+          errors |= result;
        }
     }
   else
@@ -346,6 +396,69 @@
   exit (errors);
 }
 
+/* SHH: Write logging information to a log file, if specified on the
+   command line or in environment variables. */
+
+static void
+log_install (const char *to, int mode,
+             uid_t uid, gid_t gid,
+             int is_dir)
+{
+  static FILE *f;  /* Log file. Closed on program termination. */
+  time_t t;
+  struct tm *tm;
+  struct passwd *pw;
+  char pws[20], *pwp;
+  struct group *gr;
+  char grs[20], *grp;
+
+  if (!log_enabled)
+    return;
+
+  if (!f && (f = fopen (log_file, "a")) == NULL)
+    {
+      error (0, errno, "%s", log_file);
+      log_enabled = 0;
+      return;
+    }
+
+  time (&t);
+  tm = localtime (&t);
+  /* Attempt mapping the user id to something more human. */
+  if (uid == (uid_t) -1)
+    uid = geteuid();
+  if ((pw = getpwuid (uid)) == NULL)
+    {
+      sprintf (pws, "%u", (unsigned) uid);
+      pwp = pws;
+    }
+  else
+    pwp = pw->pw_name;
+
+  /* Ditto for the group id. */
+  if (gid == (uid_t) -1)
+    gid = getegid();
+  if ((gr = getgrgid (gid)) == NULL)
+    {
+      sprintf (grs, "%u", (unsigned) gid);
+      grp = grs;
+    }
+  else
+    grp = gr->gr_name;
+
+  if (fprintf (f,
+               "%04d-%02d-%02d %02d:%02d:%02d %s %o %s %s %d %s\n",
+               tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+               tm->tm_hour, tm->tm_min, tm->tm_sec,
+               log_id ? log_id : "no-id",
+               mode, pwp, grp,
+               is_dir, to) < 0)
+    {
+      error (0, errno, "%s", log_file);
+      log_enabled = 0;
+    }
+}
+
 /* Copy file FROM onto file TO, creating any missing parent directories of TO.
    Return 0 if successful, 1 if an error occurs */
 
@@ -389,6 +502,7 @@
 {
   if (copy_file (from, to, x))
     return 1;
+  log_install (to, mode, owner_id, group_id, 0);
   if (strip_files)
     strip (to);
   if (change_attributes (to))




-- 
address@hidden
http://shh.thathost.com/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]