I'm attaching the current patches from the debian coreutils package to make sure they don't get missed.

61_whoips: this one will be problematic to include directly as I don't have the autoconf-fu to make the network functions portable to non-linux platforms, and the core function was pulled from another program. It basically makes who output IP addresses rather than hostnames, which is quite useful as IPs are more reliable than PTRs. If not this patch, it would be good to add something similar. http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=363126

63_dd-appenderrors: makes dd spit out a helpful message when someone uses oflag=append without conv=notrunc and clobbers their output file. http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=373736

72_id_checkngroups: print a message if user is in more groups than the system can support
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=175994

78_kfbsd_tab: add some #ifdefs for termios items which aren't in kFreeBSD
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=520368

79_fix_ls_test_for_sticky: a different fix than currently slated for 7.6 (set the mode explicitly rather than assuming a particular umask, to make it obvious what the difference between sticky and owt are)
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=544965

80_tail-2_wait_max-unchanged-stats: another one that makes the kfreebsd guys happy. In all honesty I'm not sure what this one is all about.
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=545009

81_tail-f-: proposed change for handling "tail -f -" post 7.6
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=545422

82_symlink_utimensat_enosys: another ENOSYS caused by buildtime/runtime library issues. When calling utimensat to change the time on a symlink, simply ignore ENOSYS.
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=545306
#! /bin/sh /usr/share/dpatch/dpatch-run

@DPATCH@
diff -urNad coreutils-7.5~/src/who.c coreutils-7.5/src/who.c
--- coreutils-7.5~/src/who.c    2009-09-02 20:53:38.000000000 -0400
+++ coreutils-7.5/src/who.c     2009-09-04 17:47:42.661391006 -0400
@@ -28,6 +28,8 @@
 #include <stdio.h>
 
 #include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
 #include "system.h"
 
 #include "c-ctype.h"
@@ -100,6 +102,9 @@
 /* If true, attempt to canonicalize hostnames via a DNS lookup. */
 static bool do_lookup;
 
+/* If true, display ips instead of hostnames */
+static bool do_ips;
+
 /* If true, display only a list of usernames and count of
    the users logged on.
    Ignored for `who am i'.  */
@@ -155,7 +160,8 @@
 /* for long options with no corresponding short option, use enum */
 enum
 {
-  LOOKUP_OPTION = CHAR_MAX + 1
+  LOOKUP_OPTION = CHAR_MAX + 1,
+  IPS_OPTION = CHAR_MAX + 2
 };
 
 static struct option const longopts[] =
@@ -165,6 +171,7 @@
   {"count", no_argument, NULL, 'q'},
   {"dead", no_argument, NULL, 'd'},
   {"heading", no_argument, NULL, 'H'},
+  {"ips", no_argument, NULL, IPS_OPTION},
   {"login", no_argument, NULL, 'l'},
   {"lookup", no_argument, NULL, LOOKUP_OPTION},
   {"message", no_argument, NULL, 'T'},
@@ -417,6 +424,63 @@
     }
 #endif
 
+  /* Needs configure check for ut_addr_v6, etc */
+  if (do_ips &&
+      memcmp(utmp_ent->ut_addr_v6, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
+  {
+        /* Following code is from sysvinit-2.87dsf
+           (GPL Copyright 1991-2004 Miquel van Smoorenburg) */
+        struct sockaddr_in      sin;
+        struct sockaddr_in6     sin6;
+        struct sockaddr         *sa;
+        int                     salen, flags;
+        unsigned int            azero=0;
+       unsigned int            glblunicast=0, linklocal=0, localunicast=0;
+        int                     mapped = 0;
+        int                    *a = utmp_ent->ut_addr_v6;
+
+        hoststr = xrealloc(hoststr, 256);
+
+        flags = do_lookup ? 0 : NI_NUMERICHOST;
+
+        /*
+         *      IPv4 or IPv6 ? We use 2 heuristics:
+         *      1. Current IPv6 range uses 2000-3fff or fc00-fdff or 
fec0-feff. 
+         *         Outside of that is illegal and must be IPv4.
+         *      2. If last 3 bytes are 0, must be IPv4
+         *      3. If IPv6 in IPv4, handle as IPv4
+         *
+         *      Ugly.
+         */
+        if (a[0] == 0 && a[1] == 0 && a[2] == htonl (0xffff))
+                mapped = 1;
+
+       azero = ntohl((unsigned int)a[0]) >> 16;
+       glblunicast = (azero >= 0x2000 && azero <= 0x3fff) ? 1 : 0;
+       localunicast = (azero >= 0xfc00 && azero <= 0xfdff) ? 1 : 0;
+       linklocal = (azero >= 0xfec0 && azero <= 0xfeff) ? 1 : 0;
+
+        if (!(glblunicast || linklocal || localunicast) || mapped ||
+            (a[1] == 0 && a[2] == 0 && a[3] == 0)) {
+                /* IPv4 */
+                sin.sin_family = AF_INET;
+                sin.sin_port = 0;
+                sin.sin_addr.s_addr = mapped ? a[3] : a[0];
+                sa = (struct sockaddr *)&sin;
+                salen = sizeof(sin);
+        } else {
+                /* IPv6 */
+                memset(&sin6, 0, sizeof(sin6));
+                sin6.sin6_family = AF_INET6;
+                sin6.sin6_port = 0;
+                memcpy(sin6.sin6_addr.s6_addr, a, 16);
+                sa = (struct sockaddr *)&sin6;
+                salen = sizeof(sin6);
+        }
+
+       getnameinfo(sa, salen, hoststr, 256, NULL, 0, flags);
+  }
+
   print_line (sizeof UT_USER (utmp_ent), UT_USER (utmp_ent), mesg,
              sizeof utmp_ent->ut_line, utmp_ent->ut_line,
              time_string (utmp_ent), idlestr, pidstr,
@@ -639,6 +703,11 @@
   -H, --heading     print line of column headings\n\
 "), stdout);
       fputs (_("\
+      --ips         print ips instead of hostnames. with --lookup,\n\
+                    canonicalizes based on stored IP, if available,\n\
+                    rather than stored hostname\n\
+"), stdout);
+      fputs (_("\
   -l, --login       print system login processes\n\
 "), stdout);
       fputs (_("\
@@ -768,6 +837,10 @@
          do_lookup = true;
          break;
 
+        case IPS_OPTION:
+          do_ips = true;
+          break;
+
          case_GETOPT_HELP_CHAR;
 
          case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
#! /bin/sh /usr/share/dpatch/dpatch-run

@DPATCH@
--- coreutils-5.97/src/dd.c.orig        2006-06-26 10:17:02.143014002 -0400
+++ coreutils-6.10/src/dd.c     2006-06-26 10:20:17.456920048 -0400
@@ -954,6 +954,9 @@
     error (EXIT_FAILURE, 0, _("cannot combine lcase and ucase"));
   if (multiple_bits_set (conversions_mask & (C_EXCL | C_NOCREAT)))
     error (EXIT_FAILURE, 0, _("cannot combine excl and nocreat"));
+  if ((output_flags & O_APPEND) &&
+      ((conversions_mask & C_NOTRUNC) != C_NOTRUNC))
+    error (0, 0, _("you probably want conv=notrunc with oflag=append"));
 }
 
 /* Fix up translation table. */
#! /bin/sh /usr/share/dpatch/dpatch-run

@DPATCH@
--- coreutils-6.10/src/id.c.orig        2008-01-28 20:14:06.147283549 -0500
+++ coreutils-6.10/src/id.c     2008-01-28 20:27:39.523284910 -0500
@@ -370,6 +370,10 @@
        ok = false;
        return;
       }
+    else if (sysconf(_SC_NGROUPS_MAX) > 0 && n_groups > 
sysconf(_SC_NGROUPS_MAX))
+      {
+        fprintf (stderr, _("Warning: user %s is in more groups than system's 
configured maximum.\n"), (username != NULL)?username:"");
+      }
 
     if (n_groups > 0)
       fputs (_(" groups="), stdout);
#! /bin/sh /usr/share/dpatch/dpatch-run
## 78_kfbsd_tab.dpatch by Petr Salinger <[email protected]>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: fix build problem on kfreebsd

@DPATCH@
diff -urNad coreutils-7.2~/src/stty.c coreutils-7.2/src/stty.c
--- coreutils-7.2~/src/stty.c   2009-03-29 13:43:41.000000000 -0400
+++ coreutils-7.2/src/stty.c    2009-04-07 21:11:35.096288547 -0400
@@ -279,10 +279,18 @@
   {"cr0", output, SANE_SET, CR0, CRDLY},
 #endif
 #ifdef TABDLY
+#ifdef TAB3
   {"tab3", output, SANE_UNSET, TAB3, TABDLY},
+#endif
+#ifdef TAB2
   {"tab2", output, SANE_UNSET, TAB2, TABDLY},
+#endif
+#ifdef TAB1
   {"tab1", output, SANE_UNSET, TAB1, TABDLY},
+#endif
+#ifdef TAB0
   {"tab0", output, SANE_SET, TAB0, TABDLY},
+#endif
 #else
 # ifdef OXTABS
   {"tab3", output, SANE_UNSET, OXTABS, 0},
#! /bin/sh /usr/share/dpatch/dpatch-run
## 79_fix_ls_test_for_sticky.dpatch by Michael Stone <[email protected]>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: fix test which assumes file is not world writable

@DPATCH@
diff -urNad coreutils-7.5~/tests/misc/ls-misc coreutils-7.5/tests/misc/ls-misc
--- coreutils-7.5~/tests/misc/ls-misc   2009-08-15 11:25:32.000000000 -0400
+++ coreutils-7.5/tests/misc/ls-misc    2009-09-04 16:23:05.165410930 -0400
@@ -58,7 +58,7 @@
   my $test = shell_quote "$ENV{abs_top_builddir}/src/test";
   system (qq(touch setuid && chmod u+s setuid && $test -u setuid &&
           touch setgid && chmod g+s setgid && $test -g setgid &&
-          mkdir sticky && chmod +t sticky  && $test -k sticky &&
+          mkdir sticky && chmod +t,o-w sticky  && $test -k sticky &&
           mkdir owt    && chmod +t,o+w owt && $test -k owt &&
           mkdir owr    && chmod o+w owr)) == 0
             or (warn "$program_name: cannot create setuid/setgid/sticky files,"
#! /bin/sh /usr/share/dpatch/dpatch-run
## 80_tail-2_wait.dpatch by Petr Salinger <[email protected]>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: fix problem that inode checking isn't done quickly enough

@DPATCH@
diff -urNad coreutils-7.5~/tests/tail-2/wait coreutils-7.5/tests/tail-2/wait
--- coreutils-7.5~/tests/tail-2/wait    2009-08-15 11:25:32.000000000 -0400
+++ coreutils-7.5/tests/tail-2/wait     2009-09-04 16:32:29.145299359 -0400
@@ -118,7 +118,7 @@
 
 test -s tail.err && fail=1
 
-tail -s.1 -F k > tail.out &
+tail -s.1 --max-unchanged-stats=2 -F k > tail.out &
 pid=$!
 sleep .5
 mv k l
#! /bin/sh /usr/share/dpatch/dpatch-run
## 81_tail-f-.dpatch by Giuseppe Scrivano <[email protected]>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: fix tail -f - with inotify

@DPATCH@
diff --git a/src/tail.c b/src/tail.c
index e3b9529..b817ecb 100644
--- a/src/tail.c
+++ b/src/tail.c
@@ -134,7 +134,7 @@ struct File_spec
   int errnum;
 
 #if HAVE_INOTIFY
-  /* The watch descriptor used by inotify.  */
+  /* The watch descriptor used by inotify, -1 on error, -2 if stdin.  */
   int wd;
 
   /* The parent directory watch descriptor.  It is used only
@@ -1184,6 +1184,7 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t 
n_files,
   char *evbuf;
   size_t evbuf_off = 0;
   size_t len = 0;
+  struct File_spec *stdin_spec = NULL;
 
   wd_table = hash_initialize (n_files, NULL, wd_hasher, wd_comparator, NULL);
   if (! wd_table)
@@ -1196,6 +1197,34 @@ tail_forever_inotify (int wd, struct File_spec *f, 
size_t n_files,
     {
       if (!f[i].ignore)
         {
+          if (STREQ (f[i].name, "-"))
+            {
+              int old_flags = fcntl (f[i].fd, F_GETFL);
+              int new_flags = old_flags | O_NONBLOCK;
+
+              stdin_spec = &f[i];
+              found_watchable = true;
+
+              if (old_flags < 0
+                  || (new_flags != old_flags
+                      && fcntl (f[i].fd, F_SETFL, new_flags) == -1))
+                {
+                  /* Don't update f[i].blocking if fcntl fails.  */
+                  if (S_ISREG (f[i].mode) && errno == EPERM)
+                    {
+                      /* This happens when using tail -f on a file with
+                         the append-only attribute.  */
+                    }
+                  else
+                    error (EXIT_FAILURE, errno,
+                           _("%s: cannot change stdin nonblocking mode"));
+                }
+              f[i].blocking = false;
+              f[i].wd = -2;
+              prev_wd = f[i].wd;
+              continue;
+            }
+
           size_t fnlen = strlen (f[i].name);
           if (evlen < fnlen)
             evlen = fnlen;
@@ -1235,6 +1264,8 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t 
n_files,
               continue;
             }
 
+          prev_wd = f[i].wd;
+
           if (hash_insert (wd_table, &(f[i])) == NULL)
             xalloc_die ();
 
@@ -1245,8 +1276,6 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t 
n_files,
   if (follow_mode == Follow_descriptor && !found_watchable)
     return;
 
-  prev_wd = f[n_files - 1].wd;
-
   evlen += sizeof (struct inotify_event) + 1;
   evbuf = xmalloc (evlen);
 
@@ -1259,12 +1288,12 @@ tail_forever_inotify (int wd, struct File_spec *f, 
size_t n_files,
       struct File_spec *fspec;
       uintmax_t bytes_read;
       struct stat stats;
-
+      bool check_stdin = false;
       struct inotify_event *ev;
 
-      /* When watching a PID, ensure that a read from WD will not block
-         indefinetely.  */
-      if (pid)
+      /* When watching a PID or stdin, ensure that a read from WD will not 
block
+         indefinitely.  */
+      if (pid || stdin_spec)
         {
           fd_set rfd;
           struct timeval select_timeout;
@@ -1284,78 +1313,92 @@ tail_forever_inotify (int wd, struct File_spec *f, 
size_t n_files,
 
           if (n_descriptors == 0)
             {
-              /* See if the process we are monitoring is still alive.  */
-              if (kill (pid, 0) != 0 && errno != EPERM)
-                exit (EXIT_SUCCESS);
+              if (stdin_spec)
+                check_stdin = true;
+              if (pid)
+                {
+                  /* See if the process we are monitoring is still alive.  */
+                  if (kill (pid, 0) != 0 && errno != EPERM)
+                    exit (EXIT_SUCCESS);
 
-              continue;
+                  if (!check_stdin)
+                    continue;
+                }
             }
         }
 
-      if (len <= evbuf_off)
+      if (check_stdin)
         {
-          len = safe_read (wd, evbuf, evlen);
-          evbuf_off = 0;
-
-          /* For kernels prior to 2.6.21, read returns 0 when the buffer
-             is too small.  */
-          if ((len == 0 || (len == SAFE_READ_ERROR && errno == EINVAL))
-              && max_realloc--)
+          ev = NULL;
+          fspec = stdin_spec;
+          check_stdin = false;
+        }
+      else
+        {
+          if (len <= evbuf_off)
             {
-              len = 0;
-              evlen *= 2;
-              evbuf = xrealloc (evbuf, evlen);
-              continue;
-            }
+              len = safe_read (wd, evbuf, evlen);
+              evbuf_off = 0;
 
-          if (len == 0 || len == SAFE_READ_ERROR)
-            error (EXIT_FAILURE, errno, _("error reading inotify event"));
-        }
+              /* For kernels prior to 2.6.21, read returns 0 when the buffer
+                 is too small.  */
+              if ((len == 0 || (len == SAFE_READ_ERROR && errno == EINVAL))
+                  && max_realloc--)
+                {
+                  len = 0;
+                  evlen *= 2;
+                  evbuf = xrealloc (evbuf, evlen);
+                  continue;
+                }
 
-      ev = (struct inotify_event *) (evbuf + evbuf_off);
-      evbuf_off += sizeof (*ev) + ev->len;
+              if (len == 0 || len == SAFE_READ_ERROR)
+                error (EXIT_FAILURE, errno, _("error reading inotify event"));
+            }
 
-      if (ev->len)
-        {
-          for (i = 0; i < n_files; i++)
+          ev = (struct inotify_event *) (evbuf + evbuf_off);
+          evbuf_off += sizeof (*ev) + ev->len;
+
+          if (ev->len)
             {
-              /* With N=hundreds of frequently-changing files, this O(N^2)
-                 process might be a problem.  FIXME: use a hash table?  */
-              if (f[i].parent_wd == ev->wd
-                  && STREQ (ev->name, f[i].name + f[i].basename_start))
-                break;
-            }
+              for (i = 0; i < n_files; i++)
+                {
+                  /* With N=hundreds of frequently-changing files, this O(N^2)
+                     process might be a problem.  FIXME: use a hash table?  */
+                  if (f[i].parent_wd == ev->wd
+                      && STREQ (ev->name, f[i].name + f[i].basename_start))
+                    break;
+                }
 
-          /* It is not a watched file.  */
-          if (i == n_files)
-            continue;
+              /* It is not a watched file.  */
+              if (i == n_files)
+                continue;
 
-          f[i].wd = inotify_add_watch (wd, f[i].name, inotify_wd_mask);
+              f[i].wd = inotify_add_watch (wd, f[i].name, inotify_wd_mask);
 
-          if (f[i].wd < 0)
-            {
-              error (0, errno, _("cannot watch %s"), quote (f[i].name));
-              continue;
-            }
+              if (f[i].wd < 0)
+                {
+                  error (0, errno, _("cannot watch %s"), quote (f[i].name));
+                  continue;
+                }
 
-          fspec = &(f[i]);
-          if (hash_insert (wd_table, fspec) == NULL)
-            xalloc_die ();
+              fspec = &(f[i]);
+              if (hash_insert (wd_table, fspec) == NULL)
+                xalloc_die ();
 
-          if (follow_mode == Follow_name)
-            recheck (&(f[i]), false);
-        }
-      else
-        {
-          struct File_spec key;
-          key.wd = ev->wd;
-          fspec = hash_lookup (wd_table, &key);
+              if (follow_mode == Follow_name)
+                recheck (&(f[i]), false);
+            }
+          else
+            {
+              struct File_spec key;
+              key.wd = ev->wd;
+              fspec = hash_lookup (wd_table, &key);
+            }
         }
-
       if (! fspec)
         continue;
 
-      if (ev->mask & (IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF))
+      if (ev && ev->mask & (IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF))
         {
           if (ev->mask & (IN_DELETE_SELF | IN_MOVE_SELF))
             {
@@ -1364,7 +1407,6 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t 
n_files,
             }
           if (follow_mode == Follow_name)
             recheck (fspec, false);
-
           continue;
         }
 
@@ -1386,11 +1428,19 @@ tail_forever_inotify (int wd, struct File_spec *f, 
size_t n_files,
           fspec->size = stats.st_size;
         }
 
-      if (ev->wd != prev_wd)
+      if (fspec->mode == stats.st_mode
+          && (! S_ISREG (stats.st_mode) || fspec->size == stats.st_size)
+          && timespec_cmp (fspec->mtime, get_stat_mtime (&stats)) == 0)
+        continue;
+
+      fspec->mtime = get_stat_mtime (&stats);
+      fspec->mode = stats.st_mode;
+
+      if (fspec->wd != prev_wd)
         {
           if (print_headers)
             write_header (name);
-          prev_wd = ev->wd;
+          prev_wd = fspec->wd;
         }
 
       bytes_read = dump_remainder (name, fspec->fd, COPY_TO_EOF);
#! /bin/sh /usr/share/dpatch/dpatch-run
## 82_symlink_utimensat_enosys.dpatch by Michael Stone <[email protected]>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: ignore ENOSYS errors when trying to set symlink times

@DPATCH@
diff -urNad coreutils-7.5~/src/copy.c coreutils-7.5/src/copy.c
--- coreutils-7.5~/src/copy.c   2009-08-19 15:39:03.000000000 -0400
+++ coreutils-7.5/src/copy.c    2009-09-10 18:43:20.863579169 -0400
@@ -124,12 +124,14 @@
 utimens_symlink (char const *file, struct timespec const *timespec)
 {
 #if HAVE_UTIMENSAT
-  return utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW);
-#else
+  int ret=0;
+  ret = utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW);
+  if (ret && errno != ENOSYS) return ret;
+#endif
+
   /* Don't set errno=ENOTSUP here as we don't want
      to output an error message for this case.  */
   return 0;
-#endif
 }
 
 /* Perform the O(1) btrfs clone operation, if possible.

Reply via email to