Add define for Kirk Smith's USR Courier driver. Change default baud
[unix-history] / usr / src / usr.bin / write / write.c
index b246f2c..c0ddb19 100644 (file)
@@ -1,14 +1,17 @@
-static char *sccsid = "@(#)write.c     4.5 %G%";
+#ifndef        lint
+static char *sccsid = "@(#)write.c     4.13 %G%";
+#endif
 /*
  * write to another user
  */
 
 #include <stdio.h>
 /*
  * write to another user
  */
 
 #include <stdio.h>
+#include <ctype.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <signal.h>
 #include <utmp.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <signal.h>
 #include <utmp.h>
-#include <time.h>
+#include <sys/time.h>
 
 #define        NMAX    sizeof(ubuf.ut_name)
 #define        LMAX    sizeof(ubuf.ut_line)
 
 #define        NMAX    sizeof(ubuf.ut_name)
 #define        LMAX    sizeof(ubuf.ut_line)
@@ -17,10 +20,11 @@ char        *strcat();
 char   *strcpy();
 struct utmp ubuf;
 int    signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
 char   *strcpy();
 struct utmp ubuf;
 int    signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
-char   me[10]  = "???";
+char   me[NMAX + 1]    = "???";
 char   *him;
 char   *mytty;
 char   histty[32];
 char   *him;
 char   *mytty;
 char   histty[32];
+char   ttybuf[32];
 char   *histtya;
 char   *ttyname();
 char   *rindex();
 char   *histtya;
 char   *ttyname();
 char   *rindex();
@@ -39,32 +43,38 @@ main(argc, argv)
        register FILE *uf;
        int c1, c2;
        long clock = time(0);
        register FILE *uf;
        int c1, c2;
        long clock = time(0);
+       int suser = getuid() == 0;
+       int nomesg = 0;
        struct tm *localtime();
        struct tm *localclock = localtime( &clock );
 
        if (argc < 2) {
        struct tm *localtime();
        struct tm *localclock = localtime( &clock );
 
        if (argc < 2) {
-               printf("usage: write user [ttyname]\n");
+               fprintf(stderr, "Usage: write user [ttyname]\n");
                exit(1);
        }
        him = argv[1];
        if (argc > 2)
                histtya = argv[2];
        if ((uf = fopen("/etc/utmp", "r")) == NULL) {
                exit(1);
        }
        him = argv[1];
        if (argc > 2)
                histtya = argv[2];
        if ((uf = fopen("/etc/utmp", "r")) == NULL) {
-               printf("cannot open /etc/utmp\n");
+               perror("write: Can't open /etc/utmp");
+               if (histtya == 0)
+                       exit(10);
                goto cont;
        }
        mytty = ttyname(2);
        if (mytty == NULL) {
                goto cont;
        }
        mytty = ttyname(2);
        if (mytty == NULL) {
-               printf("Can't find your tty\n");
+               fprintf(stderr, "write: Can't find your tty\n");
                exit(1);
        }
        if (stat(mytty, &stbuf) < 0) {
                exit(1);
        }
        if (stat(mytty, &stbuf) < 0) {
-               printf("Can't stat your tty\n");
+               perror("write: Can't stat your tty");
                exit(1);
        }
                exit(1);
        }
-       if ((stbuf.st_mode&02) == 0) {
-               printf("You have write permission turned off.\n");
-               exit(1);
+       if ((stbuf.st_mode&020) == 0) {
+               fprintf(stderr,
+                       "write: You have write permission turned off\n");
+               if (!suser)
+                       exit(1);
        }
        mytty = rindex(mytty, '/') + 1;
        if (histtya) {
        }
        mytty = rindex(mytty, '/') + 1;
        if (histtya) {
@@ -84,7 +94,8 @@ main(argc, argv)
                                        break;
                        }
                }
                                        break;
                        }
                }
-               if (him[0] != '-' || him[1] != 0)
+               if (him[0] == '-' && him[1] == 0)
+                       goto nomat;
                for (i=0; i<NMAX; i++) {
                        c1 = him[i];
                        c2 = ubuf.ut_name[i];
                for (i=0; i<NMAX; i++) {
                        c1 = him[i];
                        c2 = ubuf.ut_name[i];
@@ -94,54 +105,61 @@ main(argc, argv)
                        if (c1 != c2)
                                goto nomat;
                }
                        if (c1 != c2)
                                goto nomat;
                }
+               if (histtya && strncmp(histtya, ubuf.ut_line,
+                   sizeof(ubuf.ut_line)))
+                       continue;
                logcnt++;
                logcnt++;
-               if (histty[0]==0) {
-                       strcpy(histty, "/dev/");
-                       strcat(histty, ubuf.ut_line);
+               if (histty[0]==0 || nomesg && histtya == 0) {
+                       strcpy(ttybuf, "/dev/");
+                       strcat(ttybuf, ubuf.ut_line);
+                       if (histty[0]==0)
+                               strcpy(histty, ttybuf);
+                       if (access(ttybuf, 0) < 0 || stat(ttybuf, &stbuf) < 0 ||
+                           (stbuf.st_mode&020) == 0)
+                               nomesg++;
+                       else {
+                               strcpy(histty, ttybuf);
+                               nomesg = 0;
+                       }
                }
        nomat:
                ;
        }
                }
        nomat:
                ;
        }
-cont:
-       if (logcnt==0 && histty[0]=='\0') {
-               printf("%s not logged in.\n", him);
+       fclose(uf);
+       if (logcnt==0) {
+               fprintf(stderr, "write: %s not logged in%s\n", him,
+                       histtya ? " on that tty" : "");
                exit(1);
        }
                exit(1);
        }
-       fclose(uf);
        if (histtya==0 && logcnt > 1) {
        if (histtya==0 && logcnt > 1) {
-               printf("%s logged more than once\nwriting to %s\n", him, histty+5);
-       }
-       if (histty[0] == 0) {
-               printf(him);
-               if (logcnt)
-                       printf(" not on that tty\n"); else
-                       printf(" not logged in\n");
-               exit(1);
+               fprintf(stderr,
+               "write: %s logged in more than once ... writing to %s\n",
+                       him, histty+5);
        }
        }
+cont:
        if (access(histty, 0) < 0) {
        if (access(histty, 0) < 0) {
-               printf("No such tty\n");
+               fprintf(stderr, "write: No such tty\n");
                exit(1);
        }
        signal(SIGALRM, timout);
        alarm(5);
                exit(1);
        }
        signal(SIGALRM, timout);
        alarm(5);
-       if ((tf = fopen(histty, "w")) == NULL)
-               goto perm;
+       if ((tf = fopen(histty, "w")) == NULL) {
+               fprintf(stderr, "write: Permission denied\n");
+               exit(1);
+       }
        alarm(0);
        alarm(0);
-       if (fstat(fileno(tf), &stbuf) < 0)
-               goto perm;
-       if ((stbuf.st_mode&02) == 0)
-               goto perm;
        sigs(eof);
        { char hostname[32];
          gethostname(hostname, sizeof (hostname));
        sigs(eof);
        { char hostname[32];
          gethostname(hostname, sizeof (hostname));
-         fprintf(tf, "\r\nMessage from ");
-         fprintf(tf, "%s!%s on %s at %d:%02d ...\r\n\a\a\a",
-             hostname, me, mytty, localclock->tm_hour, localclock->tm_min);
-       }
+         fprintf(tf,
+             "\r\nMessage from %s@%s on %s at %d:%02d ...\r\n\007\007\007",
+             me, hostname, mytty, localclock->tm_hour, localclock->tm_min);
        fflush(tf);
        fflush(tf);
+       }
        for (;;) {
        for (;;) {
-               char buf[128];
-               i = read(0, buf, 128);
+               char buf[BUFSIZ];
+               register char *bp;
+               i = read(0, buf, sizeof buf);
                if (i <= 0)
                        eof();
                if (buf[0] == '!') {
                if (i <= 0)
                        eof();
                if (buf[0] == '!') {
@@ -149,19 +167,40 @@ cont:
                        ex(buf);
                        continue;
                }
                        ex(buf);
                        continue;
                }
-               write(fileno(tf), buf, i);
-               if (buf[i-1] == '\n')
-                       write(fileno(tf), "\r", 1);
+               for (bp = buf; --i >= 0; bp++) {
+                       if (*bp == '\n')
+                               putc('\r', tf);
+
+                       if (!isascii(*bp)) {
+                               putc('M', tf);
+                               putc('-', tf);
+                               *bp = toascii(*bp);
+                       }
+
+                       if (isprint(*bp) ||
+                           *bp == ' ' || *bp == '\t' || *bp == '\n') {
+                               putc(*bp, tf);
+                       } else {
+                               putc('^', tf);
+                               putc(*bp ^ 0100, tf);
+                       }
+
+                       if (*bp == '\n')
+                               fflush(tf);
+
+                       if (ferror(tf) || feof(tf)) {
+                               printf("\n\007Write failed (%s logged out?)\n",
+                                       him);
+                               exit(1);
+                       }
+               }
        }
        }
-perm:
-       printf("Permission denied\n");
-       exit(1);
 }
 
 timout()
 {
 
 }
 
 timout()
 {
 
-       printf("Timeout opening their tty\n");
+       fprintf(stderr, "write: Timeout opening their tty\n");
        exit(1);
 }
 
        exit(1);
 }
 
@@ -184,6 +223,8 @@ ex(bp)
                goto out;
        }
        if (i == 0) {
                goto out;
        }
        if (i == 0) {
+               fclose(tf);             /* Close his terminal */
+               setgid(getgid());       /* Give up effective group privs */
                sigs((int (*)())0);
                execl(getenv("SHELL") ?
                    getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0);
                sigs((int (*)())0);
                execl(getenv("SHELL") ?
                    getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0);