122608Sserge #ifndef lint 2*26069Skarels static char *sccsid = "@(#)write.c 4.12 02/04/86"; 322608Sserge #endif 41169Sbill /* 51169Sbill * write to another user 61169Sbill */ 71169Sbill 81169Sbill #include <stdio.h> 922608Sserge #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}; 2322608Sserge char me[NMAX + 1] = "???"; 241169Sbill char *him; 251169Sbill char *mytty; 261169Sbill char histty[32]; 2726068Skarels char ttybuf[32]; 281169Sbill char *histtya; 291169Sbill char *ttyname(); 301169Sbill char *rindex(); 311169Sbill int logcnt; 321169Sbill int eof(); 331169Sbill int timout(); 341169Sbill FILE *tf; 351169Sbill char *getenv(); 361169Sbill 371169Sbill main(argc, argv) 386202Sroot int argc; 396202Sroot char *argv[]; 401169Sbill { 411169Sbill struct stat stbuf; 421169Sbill register i; 431169Sbill register FILE *uf; 441169Sbill int c1, c2; 456202Sroot long clock = time(0); 4622703Slepreau int suser = getuid() == 0; 4726068Skarels int nomesg = 0; 481169Sbill struct tm *localtime(); 491169Sbill struct tm *localclock = localtime( &clock ); 501169Sbill 516202Sroot if (argc < 2) { 5222608Sserge fprintf(stderr, "Usage: write user [ttyname]\n"); 531169Sbill exit(1); 541169Sbill } 551169Sbill him = argv[1]; 566202Sroot if (argc > 2) 571169Sbill histtya = argv[2]; 581169Sbill if ((uf = fopen("/etc/utmp", "r")) == NULL) { 5922608Sserge perror("write: Can't open /etc/utmp"); 60*26069Skarels if (histtya == 0) 61*26069Skarels exit(10); 621169Sbill goto cont; 631169Sbill } 641169Sbill mytty = ttyname(2); 651169Sbill if (mytty == NULL) { 6622608Sserge fprintf(stderr, "write: Can't find your tty\n"); 671169Sbill exit(1); 681169Sbill } 696202Sroot if (stat(mytty, &stbuf) < 0) { 7022608Sserge perror("write: Can't stat your tty"); 716202Sroot exit(1); 721881Serics } 7326068Skarels if ((stbuf.st_mode&02) == 0) { 7422608Sserge fprintf(stderr, 7522608Sserge "write: You have write permission turned off\n"); 7626068Skarels if (!suser) 7726068Skarels exit(1); 781881Serics } 791169Sbill mytty = rindex(mytty, '/') + 1; 801169Sbill if (histtya) { 811169Sbill strcpy(histty, "/dev/"); 821169Sbill strcat(histty, histtya); 831169Sbill } 841169Sbill while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) { 851799Seric if (ubuf.ut_name[0] == '\0') 861799Seric continue; 871169Sbill if (strcmp(ubuf.ut_line, mytty)==0) { 886202Sroot for (i=0; i<NMAX; i++) { 891169Sbill c1 = ubuf.ut_name[i]; 906202Sroot if (c1 == ' ') 911169Sbill c1 = 0; 921169Sbill me[i] = c1; 936202Sroot if (c1 == 0) 941169Sbill break; 951169Sbill } 961169Sbill } 9722608Sserge if (him[0] == '-' && him[1] == 0) 9822608Sserge goto nomat; 996202Sroot for (i=0; i<NMAX; i++) { 1001169Sbill c1 = him[i]; 1011169Sbill c2 = ubuf.ut_name[i]; 1026202Sroot if (c1 == 0) 1036202Sroot if (c2 == 0 || c2 == ' ') 1041169Sbill break; 1056202Sroot if (c1 != c2) 1061169Sbill goto nomat; 1071169Sbill } 10826068Skarels if (histtya && strncmp(histtya, ubuf.ut_line, 10926068Skarels sizeof(ubuf.ut_line))) 11026068Skarels continue; 1111169Sbill logcnt++; 11226068Skarels if (histty[0]==0 || nomesg && histtya == 0) { 11326068Skarels strcpy(ttybuf, "/dev/"); 11426068Skarels strcat(ttybuf, ubuf.ut_line); 11526068Skarels if (histty[0]==0) 11626068Skarels strcpy(histty, ttybuf); 11726068Skarels if (access(ttybuf, 0) < 0 || stat(ttybuf, &stbuf) < 0 || 11826068Skarels (stbuf.st_mode&02) == 0) 11926068Skarels nomesg++; 12026068Skarels else { 12126068Skarels strcpy(histty, ttybuf); 12226068Skarels nomesg = 0; 12326068Skarels } 1241169Sbill } 1251169Sbill nomat: 1261169Sbill ; 1271169Sbill } 128*26069Skarels fclose(uf); 12926068Skarels if (logcnt==0) { 130*26069Skarels fprintf(stderr, "write: %s not logged in%s\n", him, 131*26069Skarels histtya ? " on that tty" : ""); 1321169Sbill exit(1); 1331169Sbill } 1341169Sbill if (histtya==0 && logcnt > 1) { 13522608Sserge fprintf(stderr, 13622608Sserge "write: %s logged in more than once ... writing to %s\n", 13722608Sserge him, histty+5); 1381169Sbill } 139*26069Skarels cont: 1401169Sbill if (access(histty, 0) < 0) { 14122608Sserge fprintf(stderr, "write: No such tty\n"); 1421169Sbill exit(1); 1431169Sbill } 1441169Sbill signal(SIGALRM, timout); 1451169Sbill alarm(5); 14626068Skarels if ((tf = fopen(histty, "w")) == NULL) { 14726068Skarels fprintf(stderr, "write: Permission denied\n"); 14826068Skarels exit(1); 14926068Skarels } 1501169Sbill alarm(0); 1511169Sbill sigs(eof); 1526202Sroot { char hostname[32]; 1536202Sroot gethostname(hostname, sizeof (hostname)); 15422608Sserge fprintf(tf, 15522608Sserge "\r\nMessage from %s@%s on %s at %d:%02d ...\r\n\007\007\007", 15622608Sserge me, hostname, mytty, localclock->tm_hour, localclock->tm_min); 15722608Sserge fflush(tf); 1586202Sroot } 1596202Sroot for (;;) { 16022608Sserge char buf[BUFSIZ]; 16122608Sserge register char *bp; 16222608Sserge i = read(0, buf, sizeof buf); 1636202Sroot if (i <= 0) 1641169Sbill eof(); 1656202Sroot if (buf[0] == '!') { 1661169Sbill buf[i] = 0; 1671169Sbill ex(buf); 1681169Sbill continue; 1691169Sbill } 17022608Sserge for (bp = buf; --i >= 0; bp++) { 17122608Sserge if (*bp == '\n') 17222608Sserge putc('\r', tf); 17322608Sserge 17422608Sserge if (!isascii(*bp)) { 17522608Sserge putc('M', tf); 17622608Sserge putc('-', tf); 17722608Sserge *bp = toascii(*bp); 17822608Sserge } 17922608Sserge 18022608Sserge if (isprint(*bp) || 18122608Sserge *bp == ' ' || *bp == '\t' || *bp == '\n') { 18222608Sserge putc(*bp, tf); 18322608Sserge } else { 18422608Sserge putc('^', tf); 18522608Sserge putc(*bp ^ 0100, tf); 18622608Sserge } 18722608Sserge 18822608Sserge if (*bp == '\n') 18922608Sserge fflush(tf); 19022608Sserge 19122608Sserge if (ferror(tf) || feof(tf)) { 19222608Sserge printf("\n\007Write failed (%s logged out?)\n", 19322608Sserge him); 19422608Sserge exit(1); 19522608Sserge } 1967401Skre } 1971169Sbill } 1981169Sbill } 1991169Sbill 2001169Sbill timout() 2011169Sbill { 2021169Sbill 20322608Sserge fprintf(stderr, "write: Timeout opening their tty\n"); 2041169Sbill exit(1); 2051169Sbill } 2061169Sbill 2071169Sbill eof() 2081169Sbill { 2091169Sbill 2101169Sbill fprintf(tf, "EOF\r\n"); 2111169Sbill exit(0); 2121169Sbill } 2131169Sbill 2141169Sbill ex(bp) 2156202Sroot char *bp; 2161169Sbill { 2171169Sbill register i; 2181169Sbill 2191169Sbill sigs(SIG_IGN); 2201169Sbill i = fork(); 2216202Sroot if (i < 0) { 2221169Sbill printf("Try again\n"); 2231169Sbill goto out; 2241169Sbill } 2256202Sroot if (i == 0) { 2261169Sbill sigs((int (*)())0); 2276202Sroot execl(getenv("SHELL") ? 2286202Sroot getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0); 2291169Sbill exit(0); 2301169Sbill } 2316202Sroot while (wait((int *)NULL) != i) 2321169Sbill ; 2331169Sbill printf("!\n"); 2341169Sbill out: 2351169Sbill sigs(eof); 2361169Sbill } 2371169Sbill 2381169Sbill sigs(sig) 2396202Sroot int (*sig)(); 2401169Sbill { 2411169Sbill register i; 2421169Sbill 2436202Sroot for (i=0; signum[i]; i++) 2446202Sroot signal(signum[i], sig); 2451169Sbill } 246