summaryrefslogtreecommitdiffstats
path: root/usr.bin/wall
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2001-03-01 05:43:12 +0000
committerimp <imp@FreeBSD.org>2001-03-01 05:43:12 +0000
commit6da2732b8bb631f2fce34f2ac6d45f2bb63f9888 (patch)
treedd90f30714fe005d110a1b8d4006a61c385fc025 /usr.bin/wall
parent2d1163e370d4fb97297838d1fe7872a653dce6bb (diff)
downloadFreeBSD-src-6da2732b8bb631f2fce34f2ac6d45f2bb63f9888.zip
FreeBSD-src-6da2732b8bb631f2fce34f2ac6d45f2bb63f9888.tar.gz
o Add support for wall -g. This will send a message to all members of
a given group. o Minor code style cleanups while I'm here Reviewed by: bde, kris, markm, audit@
Diffstat (limited to 'usr.bin/wall')
-rw-r--r--usr.bin/wall/ttymsg.c25
-rw-r--r--usr.bin/wall/wall.17
-rw-r--r--usr.bin/wall/wall.c66
3 files changed, 71 insertions, 27 deletions
diff --git a/usr.bin/wall/ttymsg.c b/usr.bin/wall/ttymsg.c
index a42ef41..3dccfbc 100644
--- a/usr.bin/wall/ttymsg.c
+++ b/usr.bin/wall/ttymsg.c
@@ -59,26 +59,23 @@ static const char rcsid[] =
* ignored (exclusive-use, lack of permission, etc.).
*/
char *
-ttymsg(iov, iovcnt, line, tmout)
- struct iovec *iov;
- int iovcnt;
- char *line;
- int tmout;
+ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout)
{
+ struct iovec localiov[7];
+ int cnt, fd, left, wret;
static char device[MAXNAMLEN] = _PATH_DEV;
static char errbuf[1024];
- register int cnt, fd, left, wret;
- struct iovec localiov[7];
- int forked = 0;
+ int forked;
+ forked = 0;
if (iovcnt > sizeof(localiov) / sizeof(localiov[0]))
return ("too many iov's (change code in wall/ttymsg.c)");
- (void) strcpy(device + sizeof(_PATH_DEV) - 1, line);
+ strlcat(device, line, sizeof(device));
if (strchr(device + sizeof(_PATH_DEV) - 1, '/')) {
/* A slash is an attempt to break security... */
- (void) snprintf(errbuf, sizeof(errbuf), "'/' in \"%s\"",
- device);
+ (void) snprintf(errbuf, sizeof(errbuf),
+ "Too many '/' in \"%s\"", device);
return (errbuf);
}
@@ -89,8 +86,8 @@ ttymsg(iov, iovcnt, line, tmout)
if ((fd = open(device, O_WRONLY|O_NONBLOCK, 0)) < 0) {
if (errno == EBUSY || errno == EACCES)
return (NULL);
- (void) snprintf(errbuf, sizeof(errbuf),
- "%s: %s", device, strerror(errno));
+ (void) snprintf(errbuf, sizeof(errbuf), "%s: %s", device,
+ strerror(errno));
return (errbuf);
}
@@ -104,7 +101,7 @@ ttymsg(iov, iovcnt, line, tmout)
if (wret >= 0) {
left -= wret;
if (iov != localiov) {
- bcopy(iov, localiov,
+ bcopy(iov, localiov,
iovcnt * sizeof(struct iovec));
iov = localiov;
}
diff --git a/usr.bin/wall/wall.1 b/usr.bin/wall/wall.1
index 1ba23d5..ff41979 100644
--- a/usr.bin/wall/wall.1
+++ b/usr.bin/wall/wall.1
@@ -40,6 +40,7 @@
.Nd write a message to users
.Sh SYNOPSIS
.Nm
+.Op Fl g Ar group
.Op Ar file
.Sh DESCRIPTION
.Nm Wall
@@ -52,6 +53,12 @@ Only the super-user can write on the
terminals of users who have chosen
to deny messages or are using a program which
automatically denies messages.
+.Bl -tag -width indent
+.It Fl g
+Send messages to users in this group. This option may be specified
+multiple times, and any user in any of the specified groups will
+receive the message.
+.El
.Sh SEE ALSO
.Xr mesg 1 ,
.Xr talk 1 ,
diff --git a/usr.bin/wall/wall.c b/usr.bin/wall/wall.c
index 7a01d0e..4506386 100644
--- a/usr.bin/wall/wall.c
+++ b/usr.bin/wall/wall.c
@@ -56,6 +56,7 @@ static const char rcsid[] =
#include <ctype.h>
#include <err.h>
+#include <grp.h>
#include <locale.h>
#include <paths.h>
#include <pwd.h>
@@ -66,38 +67,54 @@ static const char rcsid[] =
#include <unistd.h>
#include <utmp.h>
-void makemsg __P((char *));
-static void usage __P((void));
-char *ttymsg __P((struct iovec *, int, char *, int));
+static void makemsg(char *);
+static void usage(void);
+char *ttymsg(struct iovec *, int, const char *, int);
#define IGNOREUSER "sleeper"
+struct wallgroup {
+ struct wallgroup *next;
+ char *name;
+ gid_t gid;
+} *grouplist;
int nobanner;
int mbufsize;
char *mbuf;
-/* ARGSUSED */
int
-main(argc, argv)
- int argc;
- char **argv;
+main(int argc, char *argv[])
{
- int ch;
struct iovec iov;
struct utmp utmp;
+ gid_t grps[NGROUPS_MAX];
+ int ch;
+ int ingroup, ngrps, i;
FILE *fp;
+ struct wallgroup *g;
+ struct group *grp;
char *p;
+ struct passwd *pw;
char line[sizeof(utmp.ut_line) + 1];
+ char username[sizeof(utmp.ut_name) + 1];
+ ingroup = 0;
(void)setlocale(LC_CTYPE, "");
- while ((ch = getopt(argc, argv, "n")) != -1)
+ while ((ch = getopt(argc, argv, "g:n")) != -1)
switch (ch) {
case 'n':
/* undoc option for shutdown: suppress banner */
if (geteuid() == 0)
nobanner = 1;
break;
+ case 'g':
+ g = (struct wallgroup *)malloc(sizeof *g);
+ g->next = grouplist;
+ g->name = optarg;
+ g->gid = -1;
+ grouplist = g;
+ break;
case '?':
default:
usage();
@@ -107,6 +124,12 @@ main(argc, argv)
if (argc > 1)
usage();
+ for (g = grouplist; g; g = g->next) {
+ grp = getgrnam(g->name);
+ if (grp)
+ g->gid = grp->gr_gid;
+ }
+
makemsg(*argv);
if (!(fp = fopen(_PATH_UTMP, "r")))
@@ -118,6 +141,24 @@ main(argc, argv)
if (!utmp.ut_name[0] ||
!strncmp(utmp.ut_name, IGNOREUSER, sizeof(utmp.ut_name)))
continue;
+ if (grouplist) {
+ strlcpy(username, utmp.ut_name, sizeof(utmp.ut_name));
+ pw = getpwnam(username);
+ if (!pw)
+ continue;
+ ngrps = getgroups(pw->pw_gid, grps);
+ for (g = grouplist; g && ingroup == 0; g = g->next) {
+ if (g->gid == -1)
+ continue;
+ if (g->gid == pw->pw_gid)
+ ingroup = 1;
+ for (i = 0; i < ngrps && ingroup == 0; i++)
+ if (g->gid == grps[i])
+ ingroup = 1;
+ }
+ if (ingroup == 0)
+ continue;
+ }
strncpy(line, utmp.ut_line, sizeof(utmp.ut_line));
line[sizeof(utmp.ut_line)] = '\0';
if ((p = ttymsg(&iov, 1, line, 60*5)) != NULL)
@@ -134,11 +175,10 @@ usage()
}
void
-makemsg(fname)
- char *fname;
+makemsg(char *fname)
{
- register int cnt;
- register unsigned char ch;
+ int cnt;
+ unsigned char ch;
struct tm *lt;
struct passwd *pw;
struct stat sbuf;
OpenPOWER on IntegriCloud