Hi Jim,

attached is the second version of the patch.

On Thursday 21 of January 2010 13:04:27 Jim Meyering wrote:
> >> It would be helpful to say how to determine the appropriate group name.
> >> Something like "ls -lg /dev/tty" or
> >>     $ stat --format %G /dev/tty
> >>     tty
> >
> > Do you mean directly in the help string or somewhere else?
>
> I was thinking of a comment in the .m4 file,
> but now that you mention the help string, perhaps that's better.
> You choose.

Well, let it be a shell comment then.

> You're right that we go to extremes to avoid in-functions #ifdefs.
> In-function #ifdefs are evil, but so is code duplication.
> It's a trade-off.  Since this function is so small,
> and the fraction of duplicated code would have been so high,
> the in-function #ifdef is clearly the lesser evil.

It makes sense to me.

Kamil
From 55d223fee4900620d7147f134ebebe39fdca90a9 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <[email protected]>
Date: Fri, 22 Jan 2010 15:17:19 +0100
Subject: [PATCH] who --mesg now checks the group of TTY devices

... if coreutils is compiled with --with-tty-group.  Based on a patch
written by Piotr Gackiewicz.  Details at
https://bugzilla.redhat.com/454261

* src/who.c (is_tty_writable): A new function returning true if a TTY
device is writable by the group.  Additionally it checks the group to be
the same as TTY_GROUP_NAME when compiled with --with-tty-group.
* m4/jm-macros.m4: Introduce a new configure option --with-tty-group.
* NEWS: Mention the change.
---
 NEWS            |    6 ++++++
 THANKS          |    1 +
 m4/jm-macros.m4 |   19 +++++++++++++++++++
 src/who.c       |   22 +++++++++++++++++++++-
 4 files changed, 47 insertions(+), 1 deletions(-)

diff --git a/NEWS b/NEWS
index 530ff95..0af7b9a 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,12 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** New features
+
+  who --mesg used to ignore the group of a TTY device when checking if it is
+  possible to send messages there.  Now, if coreutils is compiled with
+  --with-tty-group[=NAME] configure option, it also compares the group of the
+  TTY device with NAME (or "tty" if no group is specified).
 
 * Noteworthy changes in release 8.4 (2010-01-13) [stable]
 
diff --git a/THANKS b/THANKS
index 1207368..d8cdf82 100644
--- a/THANKS
+++ b/THANKS
@@ -495,6 +495,7 @@ Philippe Schnoebelen                [email protected]
 Phillip Jones                       [email protected]
 Piergiorgio Sartor                  [email protected]
 Pieter Bowman                       [email protected]
+Piotr Gackiewicz                    [email protected]
 Piotr Kwapulinski                   [email protected]
 Prashant TR                         [email protected]
 Priit Jõerüüt                       [email protected]
diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4
index 2713827..e0efd29 100644
--- a/m4/jm-macros.m4
+++ b/m4/jm-macros.m4
@@ -144,6 +144,25 @@ AC_DEFUN([coreutils_MACROS],
     ])
 
   AC_REQUIRE([AM_LANGINFO_CODESET])
+
+  # configure options --with-tty-group/--without-tty-group
+  # usually you can determine the group of TTYs by 'stat --format %G /dev/tty'
+  # omitting this option is equal to --without-tty-group
+  AC_ARG_WITH([tty-group],
+    AS_HELP_STRING([--with-tty-group[[[=NAME]]]],
+      [group used by system for TTYs, "tty" when not specified]
+      [ (default: do not rely on any group used for TTYs)]),
+    [tty_group_name=$withval],
+    [tty_group_name=no])
+
+  if test "x$tty_group_name" != xno; then
+    if test "x$tty_group_name" = xyes; then
+      tty_group_name=tty
+    fi
+    AC_MSG_NOTICE([TTY group used by system set to "$tty_group_name"])
+    AC_DEFINE_UNQUOTED([TTY_GROUP_NAME], ["$tty_group_name"],
+      [group used by system for TTYs])
+  fi
 ])
 
 AC_DEFUN([gl_CHECK_ALL_HEADERS],
diff --git a/src/who.c b/src/who.c
index f71db3b..4110d37 100644
--- a/src/who.c
+++ b/src/who.c
@@ -37,6 +37,10 @@
 #include "hard-locale.h"
 #include "quote.h"
 
+#ifdef TTY_GROUP_NAME
+# include <grp.h>
+#endif
+
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "who"
 
@@ -308,6 +312,22 @@ print_line (int userlen, const char *user, const char state,
   free (x_exitstr);
 }
 
+/* Return true if a terminal device given as PSTAT allows other users
+   to send messages to; false otherwise */
+static bool
+is_tty_writable (const struct stat *pstat)
+{
+#ifdef TTY_GROUP_NAME
+  /* Ensure the group of the TTY device matches TTY_GROUP_NAME, more info at
+     https://bugzilla.redhat.com/454261 */
+  struct group *ttygr = getgrnam (TTY_GROUP_NAME);
+  if (!ttygr || (pstat->st_gid != ttygr->gr_gid))
+    return false;
+#endif
+
+  return pstat->st_mode & S_IWGRP;
+}
+
 /* Send properly parsed USER_PROCESS info to print_line.  The most
    recent boot time is BOOTTIME. */
 static void
@@ -346,7 +366,7 @@ print_user (const STRUCT_UTMP *utmp_ent, time_t boottime)
 
   if (stat (line, &stats) == 0)
     {
-      mesg = (stats.st_mode & S_IWGRP) ? '+' : '-';
+      mesg = is_tty_writable (&stats) ? '+' : '-';
       last_change = stats.st_atime;
     }
   else
-- 
1.6.2.5

Reply via email to