V10/cmd/wall.c
/*
*
* This program is not related to David Wall, whose Stanford Ph.D. thesis
* is entitled "Mechanisms for Broadcast and Selective Broadcast".
*/
#include <stdio.h>
#include <utmp.h>
#include <time.h>
#include <utsname.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
char *strcpy(), *strncpy();
char *strcat(), *strncat();
long time();
struct tm *localtime();
main()
{
register int c;
register char *p;
struct utmp utmp;
struct tm *tm;
long clock;
FILE *f;
char *who, *mytty;
struct utsname node;
char mesg[3000];
char *getlogin(), *ttyname();
long time();
struct tm *localtime();
if((f = fopen("/etc/utmp", "r")) == NULL) {
fprintf(stderr, "Cannot open /etc/utmp\n");
exit(1);
}
if ((who = getlogin()) == NULL)
who = "greg";
if ((mytty = ttyname(2)) == NULL)
mytty = "???";
else if (strncmp(mytty, "/dev/", 5) == 0)
mytty += 5; /* for prettiness */
uname(&node);
clock = time((long *)0);
tm = localtime(&clock);
sprintf(mesg, "\nBroadcast Message from %s!%s (%s) at %d:%02d ...\r\n",
node.nodename, who, mytty, tm->tm_hour, tm->tm_min);
p = &mesg[strlen(mesg)];
while((c = getchar()) != EOF) {
if (p >= &mesg[sizeof(mesg)]) {
fprintf(stderr, "Message too long\n");
exit(1);
}
if (c == '\n')
*p++ = '\r';
*p++ = c;
}
while (fread((char *)&utmp, sizeof(utmp), 1, f) == 1) {
if (utmp.ut_name[0] == 0)
continue;
/* reject people not really logged in */
for (c = 0; c < sizeof(utmp.ut_name); c++)
if (utmp.ut_name[c] == '*')
break;
if (c < sizeof(utmp.ut_name))
continue;
sendmes(utmp.ut_line, sizeof(utmp.ut_line), mesg, p - mesg);
}
exit(0);
}
sendmes(tty, len, mesg, mlen)
char *tty, *mesg;
int len, mlen;
{
int i;
char t[50];
int fd;
while ((i = fork()) == -1)
if (wait((int *)0) == -1) {
fprintf(stderr, "Try again\n");
return;
}
if(i)
return;
sprintf(t, "/dev/%.*s", len, tty);
if (ckmode(t) == 0)
exit(0);
signal(SIGALRM, SIG_DFL); /* blow away if open hangs */
alarm(10);
if((fd = open(t, 1)) < 0) {
fprintf(stderr,"cannot open %s\n", t);
exit(1);
}
write(fd, mesg, mlen);
close(fd);
/*
* Bitchin'.
*/
exit(0);
}
/*
* don't write on ttys whose mode is 0
* hack to prevent hanging ndcon
*/
ckmode(tty)
char *tty;
{
struct stat sb;
if (stat(tty, &sb) < 0)
return (1); /* eh? */
if (sb.st_mode & ~S_IFMT)
return (1);
return (0);
}