* Copyright (c) 1988 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1988 Regents of the University of California.\n\
static char sccsid
[] = "@(#)wall.c 5.5 (Berkeley) %G%";
* This program is not related to David Wall, whose Stanford Ph.D. thesis
* is entitled "Mechanisms for Broadcast and Selective Broadcast".
#define IGNOREUSER "sleeper"
fprintf(stderr
, "usage: wall [file]\n");
if (!(fp
= fopen(UTMP
, "r"))) {
fprintf(stderr
, "wall: cannot read /etc/utmp.\n");
while (fread((char *)&utmp
, sizeof(utmp
), 1, fp
) == 1) {
!strncmp(utmp
.ut_name
, IGNOREUSER
, sizeof(utmp
.ut_name
)))
struct passwd
*pw
, *getpwuid();
char *p
, *whom
, hostname
[MAXHOSTNAMELEN
], lbuf
[100], tmpname
[15];
char *getlogin(), *malloc(), *strcpy(), *ttyname();
(void)strcpy(tmpname
, "/tmp/wall.XXX");
if (!(fd
= mkstemp(tmpname
)) || !(fp
= fdopen(fd
, "r+"))) {
fprintf(stderr
, "wall: can't open temporary file.\n");
if (!(whom
= getlogin()))
whom
= (pw
= getpwuid(getuid())) ? pw
->pw_name
: "???";
(void)gethostname(hostname
, sizeof(hostname
));
* all this stuff is to blank out a square for the message; we
* limit message lines to 75 characters, and blank out to 79.
* Not 80 'cause some terminals do weird stuff then.
fprintf(fp
, "\r%79s\r\n", " ");
(void)sprintf(lbuf
, "Broadcast Message from %s@%s", whom
, hostname
);
fprintf(fp
, "%-79.79s\007\007\r\n", lbuf
);
(void)sprintf(lbuf
, " (%s) at %d:%02d ...", ttyname(2),
lt
->tm_hour
, lt
->tm_min
);
fprintf(fp
, "%-79.79s\r\n", lbuf
);
fprintf(fp
, "%79s\r\n", " ");
if (*++argv
&& !(freopen(*argv
, "r", stdin
))) {
fprintf(stderr
, "wall: can't read %s.\n", *argv
);
while (fgets(lbuf
, sizeof(lbuf
), stdin
))
for (cnt
= 0, p
= lbuf
; ch
= *p
; ++p
, ++cnt
)
if (cnt
== 75 || ch
== '\n') {
fprintf(fp
, "%79s\r\n", " ");
fprintf(stderr
, "wall: can't stat temporary file.\n");
if (!(mbuf
= malloc((u_int
)mbufsize
))) {
fprintf(stderr
, "wall: out of memory.\n");
(void)fread(mbuf
, sizeof(*mbuf
), mbufsize
, fp
);
static char device
[MAXNAMLEN
] = "/dev/";
register int fd
, flags
, nread
;
(void)strcpy(device
+ 5, line
);
if ((fd
= open(device
, O_WRONLY
, 0)) < 0) {
fprintf(stderr
, "wall: %s: ", device
);
flags
= fcntl(fd
, F_GETFL
, 0);
if (!(flags
& FNDELAY
)) {
/* NDELAY bit not set; if can't set, fork instead */
if (fcntl(fd
, F_SETFL
, flags
|FNDELAY
) == -1) {
while ((nread
= write(fd
, lp
, mbufsize
)) != mbufsize
) {
} else if (errno
== EWOULDBLOCK
) {
/* child resets FNDELAY if necessary; parent leaves */
(void)fcntl(fd
, F_SETFL
, flags
);
/* wait 5 minutes and then quit */
(void)alarm((u_int
)(60 * 5));
(void)write(fd
, mbuf
, mbufsize
);
fprintf(stderr
, "wall: %s: ", device
);
/* write was successful, or error != EWOULDBLOCK; cleanup */
(void)fcntl(fd
, F_SETFL
, flags
);