BSD 4_3 release
[unix-history] / usr / src / bin / wall.c
index 0d886f9..b8b740a 100644 (file)
@@ -1,4 +1,19 @@
-static char *sccsid = "@(#)wall.c      4.7 (Berkeley) 83/07/01";
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif not lint
+
+#ifndef lint
+static char sccsid[] = "@(#)wall.c     5.3 (Berkeley) 4/20/86";
+#endif not lint
+
 /*
  * wall.c - Broadcast a message to all users.
  *
 /*
  * wall.c - Broadcast a message to all users.
  *
@@ -8,63 +23,83 @@ static char *sccsid = "@(#)wall.c    4.7 (Berkeley) 83/07/01";
 
 #include <stdio.h>
 #include <utmp.h>
 
 #include <stdio.h>
 #include <utmp.h>
-#include <sys/time.h>
+#include <errno.h>
 #include <signal.h>
 #include <signal.h>
-#define        USERS   128
+#include <sys/time.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
 #define IGNOREUSER     "sleeper"
 
 char   hostname[32];
 char   mesg[3000];
 int    msize,sline;
 #define IGNOREUSER     "sleeper"
 
 char   hostname[32];
 char   mesg[3000];
 int    msize,sline;
-struct utmp utmp[USERS];
+struct utmp *utmp;
 char   *strcpy();
 char   *strcat();
 char   *strcpy();
 char   *strcat();
-char who[9] = "???";
+char   *malloc();
+char   who[9] = "???";
 long   clock, time();
 struct tm *localtime();
 struct tm *localclock;
 
 long   clock, time();
 struct tm *localtime();
 struct tm *localclock;
 
+extern errno;
+
 main(argc, argv)
 char *argv[];
 {
 main(argc, argv)
 char *argv[];
 {
-       register i;
-       register char c;
+       register int i, c;
        register struct utmp *p;
        register struct utmp *p;
-       FILE *f;
-       FILE *mf;
+       int f;
+       struct stat statb;
 
 
-       gethostname(hostname, sizeof (hostname));
-       if((f = fopen("/etc/utmp", "r")) == NULL) {
+       (void) gethostname(hostname, sizeof (hostname));
+       if ((f = open("/etc/utmp", O_RDONLY, 0)) < 0) {
                fprintf(stderr, "Cannot open /etc/utmp\n");
                exit(1);
        }
        clock = time( 0 );
        localclock = localtime( &clock );
                fprintf(stderr, "Cannot open /etc/utmp\n");
                exit(1);
        }
        clock = time( 0 );
        localclock = localtime( &clock );
-       mf = stdin;
-       if(argc >= 2) {
+       sline = ttyslot();      /* 'utmp' slot no. of sender */
+       (void) fstat(f, &statb);
+       utmp = (struct utmp *)malloc(statb.st_size);
+       c = read(f, (char *)utmp, statb.st_size);
+       (void) close(f);
+       c /= sizeof(struct utmp);
+       if (sline)
+               strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name));
+       sprintf(mesg,
+           "\n\007\007Broadcast Message from %s@%s (%.*s) at %d:%02d ...\r\n\n"
+               , who
+               , hostname
+               , sizeof(utmp[sline].ut_line)
+               , utmp[sline].ut_line
+               , localclock -> tm_hour
+               , localclock -> tm_min
+       );
+       msize = strlen(mesg);
+       if (argc >= 2) {
                /* take message from unix file instead of standard input */
                /* take message from unix file instead of standard input */
-               if((mf = fopen(argv[1], "r")) == NULL) {
-                       fprintf(stderr,"Cannot open %s\n", argv[1]);
+               if (freopen(argv[1], "r", stdin) == NULL) {
+                       perror(argv[1]);
                        exit(1);
                }
        }
                        exit(1);
                }
        }
-       while((i = getc(mf)) != EOF) {
+       while ((i = getchar()) != EOF) {
+               if (i == '\n')
+                       mesg[msize++] = '\r';
                if (msize >= sizeof mesg) {
                        fprintf(stderr, "Message too long\n");
                        exit(1);
                }
                mesg[msize++] = i;
        }
                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++) {
+       fclose(stdin);
+       for (i=0; i<c; i++) {
                p = &utmp[i];
                p = &utmp[i];
-               if ((p->ut_name[0] == 0) ||
-                   (strncmp (p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0))
+               if (p->ut_name[0] == 0 ||
+                   strncmp(p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0)
                        continue;
                sendmes(p->ut_line);
        }
                        continue;
                sendmes(p->ut_line);
        }
@@ -74,50 +109,47 @@ char *argv[];
 sendmes(tty)
 char *tty;
 {
 sendmes(tty)
 char *tty;
 {
-       register i;
-       char t[50], buf[BUFSIZ];
-       register char *cp;
-       register int c, ch;
-       FILE *f;
+       register f, flags;
+       static char t[50] = "/dev/";
+       int e, i;
+
+       strcpy(t + 5, tty);
 
 
+       if ((f = open(t, O_WRONLY|O_NDELAY)) < 0) {
+               if (errno != EWOULDBLOCK)
+                       perror(t);
+               return;
+       }
+       if ((flags = fcntl(f, F_GETFL, 0)) == -1) {
+               perror(t);
+               return;
+       }
+       if (fcntl(f, F_SETFL, flags | FNDELAY) == -1)
+               goto oldway;
+       i = write(f, mesg, msize);
+       e = errno;
+       (void) fcntl(f, F_SETFL, flags);
+       if (i == msize) {
+               (void) close(f);
+               return;
+       }
+       if (e != EWOULDBLOCK) {
+               errno = e;
+               perror(t);
+               (void) close(f);
+               return;
+       }
+oldway:
        while ((i = fork()) == -1)
                if (wait((int *)0) == -1) {
                        fprintf(stderr, "Try again\n");
                        return;
                }
        while ((i = fork()) == -1)
                if (wait((int *)0) == -1) {
                        fprintf(stderr, "Try again\n");
                        return;
                }
-       if(i)
+       if (i) {
+               (void) close(f);
                return;
                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);
-       fprintf(f,
-           "\n\a\a\aBroadcast Message from %s!%s (%.*s) at %d:%02d ...\r\n\n"
-               , hostname
-               , 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;
-               if (ch == '\n')
-                       putc('\r', f);
-               putc(ch, f);
        }
 
        }
 
-       /*
-        * Bitchin'.
-        */
-
+       (void) write(f, mesg, msize);
        exit(0);
 }
        exit(0);
 }