1*22608Sserge #ifndef lint 2*22608Sserge static char *sccsid = "@(#)write.c 4.9 06/07/85"; 3*22608Sserge #endif 41169Sbill /* 51169Sbill * write to another user 61169Sbill */ 71169Sbill 81169Sbill #include <stdio.h> 9*22608Sserge #include <ctype.h> 101169Sbill #include <sys/types.h> 111169Sbill #include <sys/stat.h> 121169Sbill #include <signal.h> 131169Sbill #include <utmp.h> 1413599Swnj #include <sys/time.h> 151169Sbill 166202Sroot #define NMAX sizeof(ubuf.ut_name) 176202Sroot #define LMAX sizeof(ubuf.ut_line) 181169Sbill 191169Sbill char *strcat(); 201169Sbill char *strcpy(); 211169Sbill struct utmp ubuf; 221169Sbill int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 23*22608Sserge char me[NMAX + 1] = "???"; 241169Sbill char *him; 251169Sbill char *mytty; 261169Sbill char histty[32]; 271169Sbill char *histtya; 281169Sbill char *ttyname(); 291169Sbill char *rindex(); 301169Sbill int logcnt; 311169Sbill int eof(); 321169Sbill int timout(); 331169Sbill FILE *tf; 341169Sbill char *getenv(); 351169Sbill 361169Sbill main(argc, argv) 376202Sroot int argc; 386202Sroot char *argv[]; 391169Sbill { 401169Sbill struct stat stbuf; 411169Sbill register i; 421169Sbill register FILE *uf; 431169Sbill int c1, c2; 446202Sroot long clock = time(0); 451169Sbill struct tm *localtime(); 461169Sbill struct tm *localclock = localtime( &clock ); 471169Sbill 486202Sroot if (argc < 2) { 49*22608Sserge fprintf(stderr, "Usage: write user [ttyname]\n"); 501169Sbill exit(1); 511169Sbill } 521169Sbill him = argv[1]; 536202Sroot if (argc > 2) 541169Sbill histtya = argv[2]; 551169Sbill if ((uf = fopen("/etc/utmp", "r")) == NULL) { 56*22608Sserge perror("write: Can't open /etc/utmp"); 571169Sbill goto cont; 581169Sbill } 591169Sbill mytty = ttyname(2); 601169Sbill if (mytty == NULL) { 61*22608Sserge fprintf(stderr, "write: Can't find your tty\n"); 621169Sbill exit(1); 631169Sbill } 646202Sroot if (stat(mytty, &stbuf) < 0) { 65*22608Sserge perror("write: Can't stat your tty"); 666202Sroot exit(1); 671881Serics } 681881Serics if ((stbuf.st_mode&02) == 0) { 69*22608Sserge fprintf(stderr, 70*22608Sserge "write: You have write permission turned off\n"); 716202Sroot exit(1); 721881Serics } 731169Sbill mytty = rindex(mytty, '/') + 1; 741169Sbill if (histtya) { 751169Sbill strcpy(histty, "/dev/"); 761169Sbill strcat(histty, histtya); 771169Sbill } 781169Sbill while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) { 791799Seric if (ubuf.ut_name[0] == '\0') 801799Seric continue; 811169Sbill if (strcmp(ubuf.ut_line, mytty)==0) { 826202Sroot for (i=0; i<NMAX; i++) { 831169Sbill c1 = ubuf.ut_name[i]; 846202Sroot if (c1 == ' ') 851169Sbill c1 = 0; 861169Sbill me[i] = c1; 876202Sroot if (c1 == 0) 881169Sbill break; 891169Sbill } 901169Sbill } 91*22608Sserge if (him[0] == '-' && him[1] == 0) 92*22608Sserge goto nomat; 936202Sroot for (i=0; i<NMAX; i++) { 941169Sbill c1 = him[i]; 951169Sbill c2 = ubuf.ut_name[i]; 966202Sroot if (c1 == 0) 976202Sroot if (c2 == 0 || c2 == ' ') 981169Sbill break; 996202Sroot if (c1 != c2) 1001169Sbill goto nomat; 1011169Sbill } 1021169Sbill logcnt++; 1031169Sbill if (histty[0]==0) { 1041169Sbill strcpy(histty, "/dev/"); 1051169Sbill strcat(histty, ubuf.ut_line); 1061169Sbill } 1071169Sbill nomat: 1081169Sbill ; 1091169Sbill } 1101169Sbill cont: 1111169Sbill if (logcnt==0 && histty[0]=='\0') { 112*22608Sserge fprintf(stderr, "write: %s not logged in\n", him); 1131169Sbill exit(1); 1141169Sbill } 115*22608Sserge if (uf != NULL) 116*22608Sserge fclose(uf); 1171169Sbill if (histtya==0 && logcnt > 1) { 118*22608Sserge fprintf(stderr, 119*22608Sserge "write: %s logged in more than once ... writing to %s\n", 120*22608Sserge him, histty+5); 1211169Sbill } 1226202Sroot if (histty[0] == 0) { 1231169Sbill printf(him); 1246202Sroot if (logcnt) 1251169Sbill printf(" not on that tty\n"); else 1261169Sbill printf(" not logged in\n"); 1271169Sbill exit(1); 1281169Sbill } 1291169Sbill if (access(histty, 0) < 0) { 130*22608Sserge fprintf(stderr, "write: No such tty\n"); 1311169Sbill exit(1); 1321169Sbill } 1331169Sbill signal(SIGALRM, timout); 1341169Sbill alarm(5); 1351169Sbill if ((tf = fopen(histty, "w")) == NULL) 1361169Sbill goto perm; 1371169Sbill alarm(0); 1381169Sbill if (fstat(fileno(tf), &stbuf) < 0) 1391169Sbill goto perm; 1401169Sbill if ((stbuf.st_mode&02) == 0) 1411169Sbill goto perm; 1421169Sbill sigs(eof); 1436202Sroot { char hostname[32]; 1446202Sroot gethostname(hostname, sizeof (hostname)); 145*22608Sserge fprintf(tf, 146*22608Sserge "\r\nMessage from %s@%s on %s at %d:%02d ...\r\n\007\007\007", 147*22608Sserge me, hostname, mytty, localclock->tm_hour, localclock->tm_min); 148*22608Sserge fflush(tf); 1496202Sroot } 1506202Sroot for (;;) { 151*22608Sserge char buf[BUFSIZ]; 152*22608Sserge register char *bp; 153*22608Sserge i = read(0, buf, sizeof buf); 1546202Sroot if (i <= 0) 1551169Sbill eof(); 1566202Sroot if (buf[0] == '!') { 1571169Sbill buf[i] = 0; 1581169Sbill ex(buf); 1591169Sbill continue; 1601169Sbill } 161*22608Sserge for (bp = buf; --i >= 0; bp++) { 162*22608Sserge if (*bp == '\n') 163*22608Sserge putc('\r', tf); 164*22608Sserge 165*22608Sserge if (!isascii(*bp)) { 166*22608Sserge putc('M', tf); 167*22608Sserge putc('-', tf); 168*22608Sserge *bp = toascii(*bp); 169*22608Sserge } 170*22608Sserge 171*22608Sserge if (isprint(*bp) || 172*22608Sserge *bp == ' ' || *bp == '\t' || *bp == '\n') { 173*22608Sserge putc(*bp, tf); 174*22608Sserge } else { 175*22608Sserge putc('^', tf); 176*22608Sserge putc(*bp ^ 0100, tf); 177*22608Sserge } 178*22608Sserge 179*22608Sserge if (*bp == '\n') 180*22608Sserge fflush(tf); 181*22608Sserge 182*22608Sserge if (ferror(tf) || feof(tf)) { 183*22608Sserge printf("\n\007Write failed (%s logged out?)\n", 184*22608Sserge him); 185*22608Sserge exit(1); 186*22608Sserge } 1877401Skre } 1881169Sbill } 1891169Sbill perm: 190*22608Sserge fprintf(stderr, "write: Permission denied\n"); 1911169Sbill exit(1); 1921169Sbill } 1931169Sbill 1941169Sbill timout() 1951169Sbill { 1961169Sbill 197*22608Sserge fprintf(stderr, "write: Timeout opening their tty\n"); 1981169Sbill exit(1); 1991169Sbill } 2001169Sbill 2011169Sbill eof() 2021169Sbill { 2031169Sbill 2041169Sbill fprintf(tf, "EOF\r\n"); 2051169Sbill exit(0); 2061169Sbill } 2071169Sbill 2081169Sbill ex(bp) 2096202Sroot char *bp; 2101169Sbill { 2111169Sbill register i; 2121169Sbill 2131169Sbill sigs(SIG_IGN); 2141169Sbill i = fork(); 2156202Sroot if (i < 0) { 2161169Sbill printf("Try again\n"); 2171169Sbill goto out; 2181169Sbill } 2196202Sroot if (i == 0) { 2201169Sbill sigs((int (*)())0); 2216202Sroot execl(getenv("SHELL") ? 2226202Sroot getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0); 2231169Sbill exit(0); 2241169Sbill } 2256202Sroot while (wait((int *)NULL) != i) 2261169Sbill ; 2271169Sbill printf("!\n"); 2281169Sbill out: 2291169Sbill sigs(eof); 2301169Sbill } 2311169Sbill 2321169Sbill sigs(sig) 2336202Sroot int (*sig)(); 2341169Sbill { 2351169Sbill register i; 2361169Sbill 2376202Sroot for (i=0; signum[i]; i++) 2386202Sroot signal(signum[i], sig); 2391169Sbill } 240