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@
This commit is contained in:
Warner Losh 2001-03-01 05:43:12 +00:00
parent 45d8008748
commit 6a20d55a59
3 changed files with 71 additions and 27 deletions

View File

@ -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;
}

View File

@ -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 ,

View File

@ -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;