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