1: #ifndef lint 2: static char *sccsid = "@(#)write.c 4.13 3/13/86"; 3: #endif 4: /* 5: * write to another user 6: */ 7: 8: #include <stdio.h> 9: #include <ctype.h> 10: #include <sys/types.h> 11: #include <sys/stat.h> 12: #include <signal.h> 13: #include <utmp.h> 14: #include <sys/time.h> 15: 16: #define NMAX sizeof(ubuf.ut_name) 17: #define LMAX sizeof(ubuf.ut_line) 18: 19: char *strcat(); 20: char *strcpy(); 21: struct utmp ubuf; 22: int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 23: char me[NMAX + 1] = "???"; 24: char *him; 25: char *mytty; 26: char histty[32]; 27: char ttybuf[32]; 28: char *histtya; 29: char *ttyname(); 30: char *rindex(); 31: int logcnt; 32: int eof(); 33: int timout(); 34: FILE *tf; 35: char *getenv(); 36: 37: main(argc, argv) 38: int argc; 39: char *argv[]; 40: { 41: struct stat stbuf; 42: register i; 43: register FILE *uf; 44: int c1, c2; 45: long clock = time(0); 46: int suser = getuid() == 0; 47: int nomesg = 0; 48: struct tm *localtime(); 49: struct tm *localclock = localtime( &clock ); 50: 51: if (argc < 2) { 52: fprintf(stderr, "Usage: write user [ttyname]\n"); 53: exit(1); 54: } 55: him = argv[1]; 56: if (argc > 2) 57: histtya = argv[2]; 58: if ((uf = fopen("/etc/utmp", "r")) == NULL) { 59: perror("write: Can't open /etc/utmp"); 60: if (histtya == 0) 61: exit(10); 62: goto cont; 63: } 64: mytty = ttyname(2); 65: if (mytty == NULL) { 66: fprintf(stderr, "write: Can't find your tty\n"); 67: exit(1); 68: } 69: if (stat(mytty, &stbuf) < 0) { 70: perror("write: Can't stat your tty"); 71: exit(1); 72: } 73: if ((stbuf.st_mode&020) == 0) { 74: fprintf(stderr, 75: "write: You have write permission turned off\n"); 76: if (!suser) 77: exit(1); 78: } 79: mytty = rindex(mytty, '/') + 1; 80: if (histtya) { 81: strcpy(histty, "/dev/"); 82: strcat(histty, histtya); 83: } 84: while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) { 85: if (ubuf.ut_name[0] == '\0') 86: continue; 87: if (strcmp(ubuf.ut_line, mytty)==0) { 88: for (i=0; i<NMAX; i++) { 89: c1 = ubuf.ut_name[i]; 90: if (c1 == ' ') 91: c1 = 0; 92: me[i] = c1; 93: if (c1 == 0) 94: break; 95: } 96: } 97: if (him[0] == '-' && him[1] == 0) 98: goto nomat; 99: for (i=0; i<NMAX; i++) { 100: c1 = him[i]; 101: c2 = ubuf.ut_name[i]; 102: if (c1 == 0) 103: if (c2 == 0 || c2 == ' ') 104: break; 105: if (c1 != c2) 106: goto nomat; 107: } 108: if (histtya && strncmp(histtya, ubuf.ut_line, 109: sizeof(ubuf.ut_line))) 110: continue; 111: logcnt++; 112: if (histty[0]==0 || nomesg && histtya == 0) { 113: strcpy(ttybuf, "/dev/"); 114: strcat(ttybuf, ubuf.ut_line); 115: if (histty[0]==0) 116: strcpy(histty, ttybuf); 117: if (access(ttybuf, 0) < 0 || stat(ttybuf, &stbuf) < 0 || 118: (stbuf.st_mode&020) == 0) 119: nomesg++; 120: else { 121: strcpy(histty, ttybuf); 122: nomesg = 0; 123: } 124: } 125: nomat: 126: ; 127: } 128: fclose(uf); 129: if (logcnt==0) { 130: fprintf(stderr, "write: %s not logged in%s\n", him, 131: histtya ? " on that tty" : ""); 132: exit(1); 133: } 134: if (histtya==0 && logcnt > 1) { 135: fprintf(stderr, 136: "write: %s logged in more than once ... writing to %s\n", 137: him, histty+5); 138: } 139: cont: 140: if (access(histty, 0) < 0) { 141: fprintf(stderr, "write: No such tty\n"); 142: exit(1); 143: } 144: signal(SIGALRM, timout); 145: alarm(5); 146: if ((tf = fopen(histty, "w")) == NULL) { 147: fprintf(stderr, "write: Permission denied\n"); 148: exit(1); 149: } 150: alarm(0); 151: sigs(eof); 152: { char hostname[32]; 153: gethostname(hostname, sizeof (hostname)); 154: fprintf(tf, 155: "\r\nMessage from %s@%s on %s at %d:%02d ...\r\n\007\007\007", 156: me, hostname, mytty, localclock->tm_hour, localclock->tm_min); 157: fflush(tf); 158: } 159: for (;;) { 160: char buf[BUFSIZ]; 161: register char *bp; 162: i = read(0, buf, sizeof buf); 163: if (i <= 0) 164: eof(); 165: if (buf[0] == '!') { 166: buf[i] = 0; 167: ex(buf); 168: continue; 169: } 170: for (bp = buf; --i >= 0; bp++) { 171: if (*bp == '\n') 172: putc('\r', tf); 173: 174: if (!isascii(*bp)) { 175: putc('M', tf); 176: putc('-', tf); 177: *bp = toascii(*bp); 178: } 179: 180: if (isprint(*bp) || 181: *bp == ' ' || *bp == '\t' || *bp == '\n') { 182: putc(*bp, tf); 183: } else { 184: putc('^', tf); 185: putc(*bp ^ 0100, tf); 186: } 187: 188: if (*bp == '\n') 189: fflush(tf); 190: 191: if (ferror(tf) || feof(tf)) { 192: printf("\n\007Write failed (%s logged out?)\n", 193: him); 194: exit(1); 195: } 196: } 197: } 198: } 199: 200: timout() 201: { 202: 203: fprintf(stderr, "write: Timeout opening their tty\n"); 204: exit(1); 205: } 206: 207: eof() 208: { 209: 210: fprintf(tf, "EOF\r\n"); 211: exit(0); 212: } 213: 214: ex(bp) 215: char *bp; 216: { 217: register i; 218: 219: sigs(SIG_IGN); 220: i = fork(); 221: if (i < 0) { 222: printf("Try again\n"); 223: goto out; 224: } 225: if (i == 0) { 226: fclose(tf); /* Close his terminal */ 227: setgid(getgid()); /* Give up effective group privs */ 228: sigs((int (*)())0); 229: execl(getenv("SHELL") ? 230: getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0); 231: exit(0); 232: } 233: while (wait((int *)NULL) != i) 234: ; 235: printf("!\n"); 236: out: 237: sigs(eof); 238: } 239: 240: sigs(sig) 241: int (*sig)(); 242: { 243: register i; 244: 245: for (i=0; signum[i]; i++) 246: signal(signum[i], sig); 247: }