122608Sserge #ifndef lint 2*26068Skarels static char *sccsid = "@(#)write.c 4.11 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]; 27*26068Skarels 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; 47*26068Skarels 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"); 601169Sbill goto cont; 611169Sbill } 621169Sbill mytty = ttyname(2); 631169Sbill if (mytty == NULL) { 6422608Sserge fprintf(stderr, "write: Can't find your tty\n"); 651169Sbill exit(1); 661169Sbill } 676202Sroot if (stat(mytty, &stbuf) < 0) { 6822608Sserge perror("write: Can't stat your tty"); 696202Sroot exit(1); 701881Serics } 71*26068Skarels if ((stbuf.st_mode&02) == 0) { 7222608Sserge fprintf(stderr, 7322608Sserge "write: You have write permission turned off\n"); 74*26068Skarels if (!suser) 75*26068Skarels exit(1); 761881Serics } 771169Sbill mytty = rindex(mytty, '/') + 1; 781169Sbill if (histtya) { 791169Sbill strcpy(histty, "/dev/"); 801169Sbill strcat(histty, histtya); 811169Sbill } 821169Sbill while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) { 831799Seric if (ubuf.ut_name[0] == '\0') 841799Seric continue; 851169Sbill if (strcmp(ubuf.ut_line, mytty)==0) { 866202Sroot for (i=0; i<NMAX; i++) { 871169Sbill c1 = ubuf.ut_name[i]; 886202Sroot if (c1 == ' ') 891169Sbill c1 = 0; 901169Sbill me[i] = c1; 916202Sroot if (c1 == 0) 921169Sbill break; 931169Sbill } 941169Sbill } 9522608Sserge if (him[0] == '-' && him[1] == 0) 9622608Sserge goto nomat; 976202Sroot for (i=0; i<NMAX; i++) { 981169Sbill c1 = him[i]; 991169Sbill c2 = ubuf.ut_name[i]; 1006202Sroot if (c1 == 0) 1016202Sroot if (c2 == 0 || c2 == ' ') 1021169Sbill break; 1036202Sroot if (c1 != c2) 1041169Sbill goto nomat; 1051169Sbill } 106*26068Skarels if (histtya && strncmp(histtya, ubuf.ut_line, 107*26068Skarels sizeof(ubuf.ut_line))) 108*26068Skarels continue; 1091169Sbill logcnt++; 110*26068Skarels if (histty[0]==0 || nomesg && histtya == 0) { 111*26068Skarels strcpy(ttybuf, "/dev/"); 112*26068Skarels strcat(ttybuf, ubuf.ut_line); 113*26068Skarels if (histty[0]==0) 114*26068Skarels strcpy(histty, ttybuf); 115*26068Skarels if (access(ttybuf, 0) < 0 || stat(ttybuf, &stbuf) < 0 || 116*26068Skarels (stbuf.st_mode&02) == 0) 117*26068Skarels nomesg++; 118*26068Skarels else { 119*26068Skarels strcpy(histty, ttybuf); 120*26068Skarels nomesg = 0; 121*26068Skarels } 1221169Sbill } 1231169Sbill nomat: 1241169Sbill ; 1251169Sbill } 1261169Sbill cont: 127*26068Skarels if (logcnt==0) { 12822608Sserge fprintf(stderr, "write: %s not logged in\n", him); 1291169Sbill exit(1); 1301169Sbill } 13122608Sserge if (uf != NULL) 13222608Sserge fclose(uf); 1331169Sbill if (histtya==0 && logcnt > 1) { 13422608Sserge fprintf(stderr, 13522608Sserge "write: %s logged in more than once ... writing to %s\n", 13622608Sserge him, histty+5); 1371169Sbill } 138*26068Skarels if (logcnt == 0) { 1391169Sbill printf(him); 140*26068Skarels if (histtya) 141*26068Skarels printf(" not on that tty\n"); 142*26068Skarels else 1431169Sbill printf(" not logged in\n"); 1441169Sbill exit(1); 1451169Sbill } 1461169Sbill if (access(histty, 0) < 0) { 14722608Sserge fprintf(stderr, "write: No such tty\n"); 1481169Sbill exit(1); 1491169Sbill } 1501169Sbill signal(SIGALRM, timout); 1511169Sbill alarm(5); 152*26068Skarels if ((tf = fopen(histty, "w")) == NULL) { 153*26068Skarels fprintf(stderr, "write: Permission denied\n"); 154*26068Skarels exit(1); 155*26068Skarels } 1561169Sbill alarm(0); 1571169Sbill sigs(eof); 1586202Sroot { char hostname[32]; 1596202Sroot gethostname(hostname, sizeof (hostname)); 16022608Sserge fprintf(tf, 16122608Sserge "\r\nMessage from %s@%s on %s at %d:%02d ...\r\n\007\007\007", 16222608Sserge me, hostname, mytty, localclock->tm_hour, localclock->tm_min); 16322608Sserge fflush(tf); 1646202Sroot } 1656202Sroot for (;;) { 16622608Sserge char buf[BUFSIZ]; 16722608Sserge register char *bp; 16822608Sserge i = read(0, buf, sizeof buf); 1696202Sroot if (i <= 0) 1701169Sbill eof(); 1716202Sroot if (buf[0] == '!') { 1721169Sbill buf[i] = 0; 1731169Sbill ex(buf); 1741169Sbill continue; 1751169Sbill } 17622608Sserge for (bp = buf; --i >= 0; bp++) { 17722608Sserge if (*bp == '\n') 17822608Sserge putc('\r', tf); 17922608Sserge 18022608Sserge if (!isascii(*bp)) { 18122608Sserge putc('M', tf); 18222608Sserge putc('-', tf); 18322608Sserge *bp = toascii(*bp); 18422608Sserge } 18522608Sserge 18622608Sserge if (isprint(*bp) || 18722608Sserge *bp == ' ' || *bp == '\t' || *bp == '\n') { 18822608Sserge putc(*bp, tf); 18922608Sserge } else { 19022608Sserge putc('^', tf); 19122608Sserge putc(*bp ^ 0100, tf); 19222608Sserge } 19322608Sserge 19422608Sserge if (*bp == '\n') 19522608Sserge fflush(tf); 19622608Sserge 19722608Sserge if (ferror(tf) || feof(tf)) { 19822608Sserge printf("\n\007Write failed (%s logged out?)\n", 19922608Sserge him); 20022608Sserge exit(1); 20122608Sserge } 2027401Skre } 2031169Sbill } 2041169Sbill } 2051169Sbill 2061169Sbill timout() 2071169Sbill { 2081169Sbill 20922608Sserge fprintf(stderr, "write: Timeout opening their tty\n"); 2101169Sbill exit(1); 2111169Sbill } 2121169Sbill 2131169Sbill eof() 2141169Sbill { 2151169Sbill 2161169Sbill fprintf(tf, "EOF\r\n"); 2171169Sbill exit(0); 2181169Sbill } 2191169Sbill 2201169Sbill ex(bp) 2216202Sroot char *bp; 2221169Sbill { 2231169Sbill register i; 2241169Sbill 2251169Sbill sigs(SIG_IGN); 2261169Sbill i = fork(); 2276202Sroot if (i < 0) { 2281169Sbill printf("Try again\n"); 2291169Sbill goto out; 2301169Sbill } 2316202Sroot if (i == 0) { 2321169Sbill sigs((int (*)())0); 2336202Sroot execl(getenv("SHELL") ? 2346202Sroot getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0); 2351169Sbill exit(0); 2361169Sbill } 2376202Sroot while (wait((int *)NULL) != i) 2381169Sbill ; 2391169Sbill printf("!\n"); 2401169Sbill out: 2411169Sbill sigs(eof); 2421169Sbill } 2431169Sbill 2441169Sbill sigs(sig) 2456202Sroot int (*sig)(); 2461169Sbill { 2471169Sbill register i; 2481169Sbill 2496202Sroot for (i=0; signum[i]; i++) 2506202Sroot signal(signum[i], sig); 2511169Sbill } 252