BSD 4_1_snap release
[unix-history] / usr / src / cmd / wall.c
index 3771936..db9e9d3 100644 (file)
@@ -1,7 +1,18 @@
+static char *sccsid = "@(#)wall.c      4.5 (Berkeley) 81/06/12";
+/*
+ * wall.c - Broadcast a message to all users.
+ *
+ * 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 <stdio.h>
 #include <utmp.h>
 #include <time.h>
-#define        USERS   50
+#include <whoami.h>
+#include <signal.h>
+#define        USERS   128
+#define IGNOREUSER     "sleeper"
 
 char   mesg[3000];
 int    msize,sline;
 
 char   mesg[3000];
 int    msize,sline;
@@ -9,7 +20,7 @@ struct utmp utmp[USERS];
 char   *strcpy();
 char   *strcat();
 char who[9] = "???";
 char   *strcpy();
 char   *strcat();
 char who[9] = "???";
-long   clock;
+long   clock, time();
 struct tm *localtime();
 struct tm *localclock;
 
 struct tm *localtime();
 struct tm *localclock;
 
@@ -20,6 +31,7 @@ char *argv[];
        register char c;
        register struct utmp *p;
        FILE *f;
        register char c;
        register struct utmp *p;
        FILE *f;
+       FILE *mf;
 
        if((f = fopen("/etc/utmp", "r")) == NULL) {
                fprintf(stderr, "Cannot open /etc/utmp\n");
 
        if((f = fopen("/etc/utmp", "r")) == NULL) {
                fprintf(stderr, "Cannot open /etc/utmp\n");
@@ -27,29 +39,35 @@ char *argv[];
        }
        clock = time( 0 );
        localclock = localtime( &clock );
        }
        clock = time( 0 );
        localclock = localtime( &clock );
-       fread((char *)utmp, sizeof(struct utmp), USERS, f);
-       fclose(f);
-       f = stdin;
+       mf = stdin;
        if(argc >= 2) {
                /* take message from unix file instead of standard input */
        if(argc >= 2) {
                /* take message from unix file instead of standard input */
-               if((f = fopen(argv[1], "r")) == NULL) {
+               if((mf = fopen(argv[1], "r")) == NULL) {
                        fprintf(stderr,"Cannot open %s\n", argv[1]);
                        exit(1);
                }
        }
                        fprintf(stderr,"Cannot open %s\n", argv[1]);
                        exit(1);
                }
        }
-       while((i = getc(f)) != EOF) mesg[msize++] = i;
-       fclose(f);
-       sline = ttyslot(2); /* 'utmp' slot no. of sender */
-       if (sline) {
-               for (i=0;c=utmp[sline].ut_name[i];i++)
-                       who[i]=c;
-               who[i] = '\0'; /* sender initials */
+       while((i = getc(mf)) != EOF) {
+               if (msize >= sizeof mesg) {
+                       fprintf(stderr, "Message too long\n");
+                       exit(1);
                }
                }
+               mesg[msize++] = i;
+       }
+       fclose(mf);
+       sline = ttyslot(2); /* 'utmp' slot no. of sender */
+       fread((char *)utmp, sizeof(struct utmp), USERS, f);
+       fclose(f);
+       if (sline)
+               strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name));
        for(i=0; i<USERS; i++) {
                p = &utmp[i];
        for(i=0; i<USERS; i++) {
                p = &utmp[i];
-               if(p->ut_name[0] == 0)
+               if ((p->ut_name[0] == 0) ||
+                   (strncmp (p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0))
                        continue;
                        continue;
+       /***            this might be nice, but utmp gets so out of date !!
                sleep(1);
                sleep(1);
+       ***/
                sendmes(p->ut_line);
        }
        exit(0);
                sendmes(p->ut_line);
        }
        exit(0);
@@ -64,24 +82,40 @@ char *tty;
        register int c, ch;
        FILE *f;
 
        register int c, ch;
        FILE *f;
 
+/***                   you can't do this with lots of users & MAXUPROC
        i = fork();
        if(i == -1) {
                fprintf(stderr, "Try again\n");
                return;
        }
        i = fork();
        if(i == -1) {
                fprintf(stderr, "Try again\n");
                return;
        }
+ ***/
+       while ((i = fork()) == -1)
+               if (wait((int *)0) == -1) {
+                       fprintf(stderr, "Try again\n");
+                       return;
+               }
        if(i)
                return;
        strcpy(t, "/dev/");
        strcat(t, tty);
 
        if(i)
                return;
        strcpy(t, "/dev/");
        strcat(t, tty);
 
+       signal(SIGALRM, SIG_DFL);       /* blow away if open hangs */
+       alarm(10);
+
        if((f = fopen(t, "w")) == NULL) {
                fprintf(stderr,"cannot open %s\n", t);
                exit(1);
        }
        setbuf(f, buf);
        if((f = fopen(t, "w")) == NULL) {
                fprintf(stderr,"cannot open %s\n", t);
                exit(1);
        }
        setbuf(f, buf);
-       fprintf(f, "\n\a\a\aBroadcast Message from %s (%s) at %d:%02d ...\r\n\n"
-              ,who, utmp[sline].ut_line
-              , localclock -> tm_hour , localclock -> tm_min );
+       fprintf(f,
+           "\n\a\a\aBroadcast Message from %s!%s (%.*s) at %d:%02d ...\r\n\n"
+               , sysname
+               , who
+               , sizeof(utmp[sline].ut_line)
+               , utmp[sline].ut_line
+               , localclock -> tm_hour
+               , localclock -> tm_min
+       );
        /* fwrite(mesg, msize, 1, f); */
        for (cp = mesg, c = msize; c-- > 0; cp++) {
                ch = *cp;
        /* fwrite(mesg, msize, 1, f); */
        for (cp = mesg, c = msize; c-- > 0; cp++) {
                ch = *cp;