version 1.14, 2001/02/13 09:16:04 |
version 1.15, 2001/09/04 23:25:56 |
|
|
*/ |
*/ |
|
|
#ifndef lint |
#ifndef lint |
static char copyright[] = |
static const char copyright[] = |
"@(#) Copyright (c) 1988, 1990, 1993\n\ |
"@(#) Copyright (c) 1988, 1990, 1993\n\ |
The Regents of the University of California. All rights reserved.\n"; |
The Regents of the University of California. All rights reserved.\n"; |
#endif /* not lint */ |
#endif /* not lint */ |
|
|
#ifndef lint |
#ifndef lint |
#if 0 |
#if 0 |
static char sccsid[] = "@(#)wall.c 8.2 (Berkeley) 11/16/93"; |
static const char sccsid[] = "@(#)wall.c 8.2 (Berkeley) 11/16/93"; |
#endif |
#endif |
static char rcsid[] = "$OpenBSD$"; |
static const char rcsid[] = "$OpenBSD$"; |
#endif /* not lint */ |
#endif /* not lint */ |
|
|
/* |
/* |
|
|
#include <err.h> |
#include <err.h> |
|
|
struct wallgroup { |
struct wallgroup { |
struct wallgroup *next; |
|
char *name; |
|
gid_t gid; |
gid_t gid; |
|
char *name; |
|
char **mem; |
|
struct wallgroup *next; |
} *grouplist; |
} *grouplist; |
|
|
void makemsg __P((char *)); |
void makemsg(char *); |
|
void addgroup(struct group *, char *); |
|
char *ttymsg(struct iovec *, int, char *, int); |
|
__dead void usage(void); |
|
|
#define IGNOREUSER "sleeper" |
#define IGNOREUSER "sleeper" |
|
|
|
|
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
int |
main(argc, argv) |
main(int argc, char **argv) |
int argc; |
|
char **argv; |
|
{ |
{ |
extern int optind; |
FILE *fp; |
int ch; |
int ch, ingroup; |
struct iovec iov; |
struct iovec iov; |
struct utmp utmp; |
struct utmp utmp; |
FILE *fp; |
char *p, **mem; |
char *p, *ttymsg(); |
|
struct passwd *pep = getpwnam("nobody"); |
|
char line[sizeof(utmp.ut_line) + 1]; |
char line[sizeof(utmp.ut_line) + 1]; |
|
char username[sizeof(utmp.ut_name) + 1]; |
|
struct passwd *pw; |
|
struct group *grp; |
struct wallgroup *g; |
struct wallgroup *g; |
|
|
while ((ch = getopt(argc, argv, "ng:")) != -1) |
while ((ch = getopt(argc, argv, "ng:")) != -1) |
switch (ch) { |
switch (ch) { |
case 'n': |
case 'n': |
/* undoc option for shutdown: suppress banner */ |
/* undoc option for shutdown: suppress banner */ |
if (geteuid() == 0 || (pep && getuid() == pep->pw_uid)) |
pw = getpwnam("nobody"); |
|
if (geteuid() == 0 || (pw && getuid() == pw->pw_uid)) |
nobanner = 1; |
nobanner = 1; |
break; |
break; |
case 'g': |
case 'g': |
g = (struct wallgroup *)malloc(sizeof *g); |
grp = getgrnam(optarg); |
g->next = grouplist; |
if ((grp = getgrnam(optarg)) == NULL) |
g->name = optarg; |
errx(1, "unknown group `%s'", optarg); |
g->gid = -1; |
addgroup(grp, optarg); |
grouplist = g; |
|
break; |
break; |
case '?': |
|
default: |
default: |
usage: |
usage(); |
(void)fprintf(stderr, "usage: wall [-g group] [file]\n"); |
|
exit(1); |
|
} |
} |
argc -= optind; |
argc -= optind; |
argv += optind; |
argv += optind; |
if (argc > 1) |
if (argc > 1) |
goto usage; |
usage(); |
|
|
for (g = grouplist; g; g = g->next) { |
|
struct group *grp; |
|
|
|
grp = getgrnam(g->name); |
|
if (grp) |
|
g->gid = grp->gr_gid; |
|
} |
|
|
|
makemsg(*argv); |
makemsg(*argv); |
|
|
if (!(fp = fopen(_PATH_UTMP, "r"))) |
if (!(fp = fopen(_PATH_UTMP, "r"))) |
|
|
iov.iov_base = mbuf; |
iov.iov_base = mbuf; |
iov.iov_len = mbufsize; |
iov.iov_len = mbufsize; |
/* NOSTRICT */ |
/* NOSTRICT */ |
while (fread((char *)&utmp, sizeof(utmp), 1, fp) == 1) { |
while (fread(&utmp, sizeof(utmp), 1, fp) == 1) { |
if (!utmp.ut_name[0] || |
if (!utmp.ut_name[0] || |
!strncmp(utmp.ut_name, IGNOREUSER, sizeof(utmp.ut_name))) |
!strncmp(utmp.ut_name, IGNOREUSER, sizeof(utmp.ut_name))) |
continue; |
continue; |
if (grouplist) { |
if (grouplist) { |
int ingroup = 0, ngrps, i; |
ingroup = 0; |
char username[MAXLOGNAME]; |
strncpy(username, utmp.ut_name, sizeof(utmp.ut_name)); |
struct passwd *pw; |
username[sizeof(utmp.ut_name)] = '\0'; |
gid_t grps[NGROUPS_MAX]; |
|
|
|
bzero(username, sizeof username); |
|
strncpy(username, utmp.ut_name, sizeof utmp.ut_name); |
|
pw = getpwnam(username); |
pw = getpwnam(username); |
if (!pw) |
if (!pw) |
continue; |
continue; |
ngrps = getgroups(pw->pw_gid, grps); |
|
for (g = grouplist; g && ingroup == 0; g = g->next) { |
for (g = grouplist; g && ingroup == 0; g = g->next) { |
if (g->gid == -1) |
|
continue; |
|
if (g->gid == pw->pw_gid) |
if (g->gid == pw->pw_gid) |
ingroup = 1; |
ingroup = 1; |
for (i = 0; i < ngrps && ingroup == 0; i++) |
for (mem = g->mem; *mem && ingroup == 0; mem++) |
if (g->gid == grps[i]) |
if (strcmp(username, *mem) == 0) |
ingroup = 1; |
ingroup = 1; |
} |
} |
if (ingroup == 0) |
if (ingroup == 0) |
|
|
} |
} |
|
|
void |
void |
makemsg(fname) |
makemsg(char *fname) |
char *fname; |
|
{ |
{ |
register int ch, cnt; |
int ch, cnt; |
struct tm *lt; |
struct tm *lt; |
struct passwd *pw; |
struct passwd *pw; |
struct stat sbuf; |
struct stat sbuf; |
|
|
char *ttynam; |
char *ttynam; |
|
|
snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP); |
snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP); |
if ((fd = mkstemp(tmpname)) == -1 || !(fp = fdopen(fd, "r+"))) |
if ((fd = mkstemp(tmpname)) >= 0) { |
|
(void)unlink(tmpname); |
|
fp = fdopen(fd, "r+"); |
|
} |
|
if (fd == -1 || fp == NULL) |
errx(1, "can't open temporary file."); |
errx(1, "can't open temporary file."); |
(void)unlink(tmpname); |
|
|
|
if (!nobanner) { |
if (!nobanner) { |
if (!(whom = getlogin())) |
if (!(whom = getlogin())) |
|
|
if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize) |
if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize) |
errx(1, "can't read temporary file."); |
errx(1, "can't read temporary file."); |
(void)close(fd); |
(void)close(fd); |
|
} |
|
|
|
void |
|
addgroup(struct group *grp, char *name) |
|
{ |
|
int i; |
|
struct wallgroup *g; |
|
|
|
for (i = 0; grp->gr_mem[i]; i++) |
|
; |
|
|
|
g = (struct wallgroup *)malloc(sizeof *g); |
|
if (g == NULL) |
|
errx(1, "out of memory."); |
|
g->gid = grp->gr_gid; |
|
g->name = name; |
|
g->mem = (char **)malloc(i + 1); |
|
if (g->mem == NULL) |
|
errx(1, "out of memory."); |
|
for (i = 0; grp->gr_mem[i] != NULL; i++) { |
|
g->mem[i] = strdup(grp->gr_mem[i]); |
|
if (g->mem[i] == NULL) |
|
errx(1, "out of memory."); |
|
} |
|
g->mem[i] = NULL; |
|
g->next = grouplist; |
|
grouplist = g; |
|
} |
|
|
|
void |
|
usage(void) |
|
{ |
|
extern char *__progname; |
|
|
|
(void)fprintf(stderr, "usage: %s [-g group] [file]\n", __progname); |
|
exit(1); |
} |
} |