bug-gnu-utils
[Top][All Lists]
Advanced

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

RFE gdiff & symlinks


From: Markus Gyger
Subject: RFE gdiff & symlinks
Date: Wed, 22 Nov 2000 15:57:14 -0500 (EST)

Hello,

it would be nice if gdiff would provide an option to not follow
symbolic links (like e.g. chown -h) to avoid endless recursions
with cyclic symbolic links.

I've appended some diffs as an example.


Markus

BTW: An option -Z like in gpatch would also be convenient.


diff -ur o/diffutils-2.7.2/diff.c ./diffutils-2.7.2/diff.c
--- o/diffutils-2.7.2/diff.c    Mon Sep 14 07:27:17 1998
+++ ./diffutils-2.7.2/diff.c    Wed Nov 22 20:21:20 2000
@@ -91,6 +91,9 @@
    Normally nothing is output when that happens.  */
 static int print_file_same_flag;
 
+/* Follow symbolic links (if not -h) */
+static int dereference = 1;
+
 
 /* Return a string containing the command options with which diff was invoked.
    Spaces appear between what were separate ARGV-elements.
@@ -236,6 +239,7 @@
   {"minimal", 0, 0, 'd'},
   {"ed", 0, 0, 'e'},
   {"forward-ed", 0, 0, 'f'},
+  {"no-dereference", 0, 0, 'h'},
   {"ignore-case", 0, 0, 'i'},
   {"paginate", 0, 0, 'l'},
   {"rcs", 0, 0, 'n'},
@@ -267,6 +271,7 @@
   {"from-file", 1, 0, CHAR_MAX + 15},
   {"to-file", 1, 0, CHAR_MAX + 16},
   {"inhibit-hunk-merge", 0, 0, CHAR_MAX + 17},
+  {"dereference", 0, 0, CHAR_MAX + 18},
   {0, 0, 0, 0}
 };
 
@@ -401,10 +406,8 @@
          break;
 
        case 'h':
-         /* Split the files into chunks of around 1500 lines
-            for faster processing.  Usually does not change the result.
-
-            This currently has no effect.  */
+         /* Don't follow symbolic links */
+         dereference = 0;
          break;
 
        case 'H':
@@ -627,6 +630,11 @@
          inhibit_hunk_merge = 1;
          break;
 
+       case CHAR_MAX + 18:
+         /* Follow symbolic links */
+         dereference = 1;
+         break;
+
        default:
          try_help (0, 0);
        }
@@ -899,6 +907,11 @@
   "--horizon-lines=NUM  Keep NUM lines of the common prefix and suffix.",
   "--inhibit-hunk-merge  Do not merge hunks.",
   "-d  --minimal  Try hard to find a smaller set of changes.",
+  "-h  --no-dereference  Don't follow symbolic links"
+#ifndef S_ISLNK
+  " (no effect on this platform)"
+#endif
+  ".",
   "-H  --speed-large-files  Assume large files and many scattered small 
changes.",
   "",
   "-v  --version  Output version info.",
@@ -997,10 +1010,15 @@
 #endif
 
   /* other popular file types */
-  /* S_ISLNK is impossible with `fstat' and `stat'.  */
+#ifdef S_ISLNK
+  if (S_ISLNK (st->st_mode)) return _("symbolic link");
+#endif
 #ifdef S_ISSOCK
   if (S_ISSOCK (st->st_mode)) return _("socket");
 #endif
+#ifdef S_ISDOOR
+  if (S_ISDOOR (st->st_mode)) return _("door");
+#endif
 
   return _("weird file");
 }
@@ -1108,7 +1126,12 @@
                    }
                }
            }
+#ifdef S_ISLNK
+         else if (dereference ? stat (cmp.file[i].name, &cmp.file[i].stat)
+                              : lstat (cmp.file[i].name, &cmp.file[i].stat))
+#else
          else if (stat (cmp.file[i].name, &cmp.file[i].stat) != 0)
+#endif
            cmp.file[i].desc = ERRNO_ENCODE (errno);
        }
     }
@@ -1158,7 +1181,12 @@
       if (strcmp (fnm, "-") == 0)
        fatal ("cannot compare `-' to a directory");
 
+#ifdef S_ISLNK
+      if (dereference ? (stat (filename, &cmp.file[dir_arg].stat) != 0)
+                     : (lstat (filename, &cmp.file[dir_arg].stat) != 0))
+#else
       if (stat (filename, &cmp.file[dir_arg].stat) != 0)
+#endif
        {
          perror_with_name (filename);
          status = 2;
@@ -1220,6 +1248,27 @@
              status = 1;
            }
        }
+#ifdef S_ISLNK
+      else if (S_ISLNK (cmp.file[0].stat.st_mode) &&
+               S_ISLNK (cmp.file[1].stat.st_mode))
+       {
+         int len0, len1;
+         char buf0[PATH_MAX+1], buf1[PATH_MAX+1];
+
+         if ((len0 = readlink(cmp.file[0].name, buf0, PATH_MAX)) < 0)
+           perror_with_name (cmp.file[0].name);
+         else if ((len1 = readlink(cmp.file[1].name, buf1, PATH_MAX)) < 0)
+           perror_with_name (cmp.file[1].name);
+         else if (len0 != len1 || memcmp(buf0, buf1, len0))
+           {
+             buf0[len0] = buf1[len1] = '\0';
+             message5 ("Symbolic link %s points to %s while %s points to %s\n",
+                       file_label[0] ? file_label[0] : cmp.file[0].name, buf0,
+                       file_label[1] ? file_label[1] : cmp.file[1].name, buf1);
+             status = 1;
+           }
+       }
+#endif
       else
        {
          /* We have two files that are not to be compared.  */
diff -ur o/diffutils-2.7.2/diff.texi ./diffutils-2.7.2/diff.texi
--- o/diffutils-2.7.2/diff.texi Mon Sep 14 06:13:10 1998
+++ ./diffutils-2.7.2/diff.texi Wed Nov 22 19:47:28 2000
@@ -2902,8 +2902,7 @@
 Compare @var{file} to each operand; @var{file} may be a directory.
 
 @item -h
-This option currently has no effect; it is present for Unix
-compatibility.
+Don't follow symbolic links.
 
 @item -H
 Use heuristics to speed handling of large files that have numerous
@@ -2997,6 +2996,9 @@
 Use @var{format} to output a line taken from just the second file in
 if-then-else format.  @xref{Line Formats}.
 
address@hidden --no-dereference
+Don't follow symbolic links.
+
 @item address@hidden
 Use @var{format} to output a group of lines taken from just the first
 file in if-then-else format.  @xref{Line Group Formats}.
@@ -3874,7 +3876,8 @@
 
 Some files are neither directories nor regular files: they are unusual
 files like symbolic links, device special files, named pipes, and
-sockets.  Currently, @code{diff} treats symbolic links like regular files;
+sockets.  @code{diff} treats symbolic links like regular files unless
+option @code{-h} or @code{--no-dereference} is specified;
 it treats other special files like regular files if they are specified
 at the top level, but simply reports their presence when comparing
 directories.  This means that @code{patch} cannot represent changes
diff -ur o/diffutils-2.7.2/getmsgids ./diffutils-2.7.2/getmsgids
--- o/diffutils-2.7.2/getmsgids Mon Sep 14 06:13:10 1998
+++ ./diffutils-2.7.2/getmsgids Wed Nov 22 20:15:14 2000
@@ -48,7 +48,7 @@
 
 # Extract the message IDs, removing duplicates.
 sed '
-  # Remove backslash-newlines.
+# Remove backslash-newlines.
   : start
   /\\$/{
     N
@@ -56,22 +56,22 @@
     b start
   }
 
-  # Translate escaped backslashes and double-quotes into something safe.
-  # Do backslashes first!
+# Translate escaped backslashes and double-quotes into something safe.
+# Do backslashes first!
   s/\\\\/\\134/g
   s/\\"/\\042/g
 
-  # Convert all strings between "...msgid[] =" and "}" lines to msgid lines.
+# Convert all strings between "...msgid[] =" and "}" lines to msgid lines.
   /^[   $*0-9A-Z_a-z]*msgid[    ]*\[[   ]*\][   ]*=/,/^[        ]*}/{
     s/"[^"][^"]*"/\
 msgid  &\
 /g
   }
 
-  # Convert caller msgid strings to msgid lines.
+# Convert caller msgid strings to msgid lines.
   '"$extractFromCallers"'
 
-  # Restore escaped backslashes and double-quotes.
+# Restore escaped backslashes and double-quotes.
   s/\\042/\\"/g
   s/\\134/\\\\/g
 
diff -ur o/diffutils-2.7.2/util.c ./diffutils-2.7.2/util.c
--- o/diffutils-2.7.2/util.c    Mon Sep 14 06:13:10 1998
+++ ./diffutils-2.7.2/util.c    Wed Nov 22 19:48:20 2000
@@ -215,7 +215,7 @@
                close (pipes[0]);
              }
 
-           execl (pr_program, pr_program, "-f", "-h", name, 0);
+           execlp (pr_program, pr_program, "-f", "-h", name, 0);
            /* Avoid stdio, because the parent process's buffers are inherited.
               Also, avoid gettext since it may modify the parent buffers.  */
            write (STDERR_FILENO, pr_program, strlen (pr_program));




reply via email to

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