From 6da2732b8bb631f2fce34f2ac6d45f2bb63f9888 Mon Sep 17 00:00:00 2001 From: imp Date: Thu, 1 Mar 2001 05:43:12 +0000 Subject: 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@ --- usr.bin/wall/ttymsg.c | 25 +++++++++---------- usr.bin/wall/wall.1 | 7 ++++++ usr.bin/wall/wall.c | 66 +++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 71 insertions(+), 27 deletions(-) (limited to 'usr.bin/wall') 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 #include +#include #include #include #include @@ -66,38 +67,54 @@ static const char rcsid[] = #include #include -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; -- cgit v1.1