1*13599Swnj static char *sccsid = "@(#)write.c 4.8 07/01/83"; 21169Sbill /* 31169Sbill * write to another user 41169Sbill */ 51169Sbill 61169Sbill #include <stdio.h> 71169Sbill #include <sys/types.h> 81169Sbill #include <sys/stat.h> 91169Sbill #include <signal.h> 101169Sbill #include <utmp.h> 11*13599Swnj #include <sys/time.h> 121169Sbill 136202Sroot #define NMAX sizeof(ubuf.ut_name) 146202Sroot #define LMAX sizeof(ubuf.ut_line) 151169Sbill 161169Sbill char *strcat(); 171169Sbill char *strcpy(); 181169Sbill struct utmp ubuf; 191169Sbill int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; 201169Sbill char me[10] = "???"; 211169Sbill char *him; 221169Sbill char *mytty; 231169Sbill char histty[32]; 241169Sbill char *histtya; 251169Sbill char *ttyname(); 261169Sbill char *rindex(); 271169Sbill int logcnt; 281169Sbill int eof(); 291169Sbill int timout(); 301169Sbill FILE *tf; 311169Sbill char *getenv(); 321169Sbill 331169Sbill main(argc, argv) 346202Sroot int argc; 356202Sroot char *argv[]; 361169Sbill { 371169Sbill struct stat stbuf; 381169Sbill register i; 391169Sbill register FILE *uf; 401169Sbill int c1, c2; 416202Sroot long clock = time(0); 421169Sbill struct tm *localtime(); 431169Sbill struct tm *localclock = localtime( &clock ); 441169Sbill 456202Sroot if (argc < 2) { 461169Sbill printf("usage: write user [ttyname]\n"); 471169Sbill exit(1); 481169Sbill } 491169Sbill him = argv[1]; 506202Sroot if (argc > 2) 511169Sbill histtya = argv[2]; 521169Sbill if ((uf = fopen("/etc/utmp", "r")) == NULL) { 531169Sbill printf("cannot open /etc/utmp\n"); 541169Sbill goto cont; 551169Sbill } 561169Sbill mytty = ttyname(2); 571169Sbill if (mytty == NULL) { 581169Sbill printf("Can't find your tty\n"); 591169Sbill exit(1); 601169Sbill } 616202Sroot if (stat(mytty, &stbuf) < 0) { 626202Sroot printf("Can't stat your tty\n"); 636202Sroot exit(1); 641881Serics } 651881Serics if ((stbuf.st_mode&02) == 0) { 666202Sroot printf("You have write permission turned off.\n"); 676202Sroot exit(1); 681881Serics } 691169Sbill mytty = rindex(mytty, '/') + 1; 701169Sbill if (histtya) { 711169Sbill strcpy(histty, "/dev/"); 721169Sbill strcat(histty, histtya); 731169Sbill } 741169Sbill while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) { 751799Seric if (ubuf.ut_name[0] == '\0') 761799Seric continue; 771169Sbill if (strcmp(ubuf.ut_line, mytty)==0) { 786202Sroot for (i=0; i<NMAX; i++) { 791169Sbill c1 = ubuf.ut_name[i]; 806202Sroot if (c1 == ' ') 811169Sbill c1 = 0; 821169Sbill me[i] = c1; 836202Sroot if (c1 == 0) 841169Sbill break; 851169Sbill } 861169Sbill } 876202Sroot if (him[0] != '-' || him[1] != 0) 886202Sroot for (i=0; i<NMAX; i++) { 891169Sbill c1 = him[i]; 901169Sbill c2 = ubuf.ut_name[i]; 916202Sroot if (c1 == 0) 926202Sroot if (c2 == 0 || c2 == ' ') 931169Sbill break; 946202Sroot if (c1 != c2) 951169Sbill goto nomat; 961169Sbill } 971169Sbill logcnt++; 981169Sbill if (histty[0]==0) { 991169Sbill strcpy(histty, "/dev/"); 1001169Sbill strcat(histty, ubuf.ut_line); 1011169Sbill } 1021169Sbill nomat: 1031169Sbill ; 1041169Sbill } 1051169Sbill cont: 1061169Sbill if (logcnt==0 && histty[0]=='\0') { 1071169Sbill printf("%s not logged in.\n", him); 1081169Sbill exit(1); 1091169Sbill } 1101169Sbill fclose(uf); 1111169Sbill if (histtya==0 && logcnt > 1) { 1121169Sbill printf("%s logged more than once\nwriting to %s\n", him, histty+5); 1131169Sbill } 1146202Sroot if (histty[0] == 0) { 1151169Sbill printf(him); 1166202Sroot if (logcnt) 1171169Sbill printf(" not on that tty\n"); else 1181169Sbill printf(" not logged in\n"); 1191169Sbill exit(1); 1201169Sbill } 1211169Sbill if (access(histty, 0) < 0) { 1221169Sbill printf("No such tty\n"); 1231169Sbill exit(1); 1241169Sbill } 1251169Sbill signal(SIGALRM, timout); 1261169Sbill alarm(5); 1271169Sbill if ((tf = fopen(histty, "w")) == NULL) 1281169Sbill goto perm; 1291169Sbill alarm(0); 1301169Sbill if (fstat(fileno(tf), &stbuf) < 0) 1311169Sbill goto perm; 1321169Sbill if ((stbuf.st_mode&02) == 0) 1331169Sbill goto perm; 1341169Sbill sigs(eof); 1356202Sroot { char hostname[32]; 1366202Sroot gethostname(hostname, sizeof (hostname)); 1376202Sroot fprintf(tf, "\r\nMessage from "); 13811362Sleres fprintf(tf, "%s!%s on %s at %d:%02d ...\r\n\007\007\007", 1396202Sroot hostname, me, mytty, localclock->tm_hour, localclock->tm_min); 1406202Sroot } 1411169Sbill fflush(tf); 1426202Sroot for (;;) { 1431169Sbill char buf[128]; 1441169Sbill i = read(0, buf, 128); 1456202Sroot if (i <= 0) 1461169Sbill eof(); 1476202Sroot if (buf[0] == '!') { 1481169Sbill buf[i] = 0; 1491169Sbill ex(buf); 1501169Sbill continue; 1511169Sbill } 1527401Skre if (write(fileno(tf), buf, i) != i) { 15311362Sleres printf("\n\007Write failed (%s logged out?)\n", him); 1547401Skre exit(1); 1557401Skre } 1566202Sroot if (buf[i-1] == '\n') 1576202Sroot write(fileno(tf), "\r", 1); 1581169Sbill } 1591169Sbill perm: 1601169Sbill printf("Permission denied\n"); 1611169Sbill exit(1); 1621169Sbill } 1631169Sbill 1641169Sbill timout() 1651169Sbill { 1661169Sbill 1671169Sbill printf("Timeout opening their tty\n"); 1681169Sbill exit(1); 1691169Sbill } 1701169Sbill 1711169Sbill eof() 1721169Sbill { 1731169Sbill 1741169Sbill fprintf(tf, "EOF\r\n"); 1751169Sbill exit(0); 1761169Sbill } 1771169Sbill 1781169Sbill ex(bp) 1796202Sroot char *bp; 1801169Sbill { 1811169Sbill register i; 1821169Sbill 1831169Sbill sigs(SIG_IGN); 1841169Sbill i = fork(); 1856202Sroot if (i < 0) { 1861169Sbill printf("Try again\n"); 1871169Sbill goto out; 1881169Sbill } 1896202Sroot if (i == 0) { 1901169Sbill sigs((int (*)())0); 1916202Sroot execl(getenv("SHELL") ? 1926202Sroot getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0); 1931169Sbill exit(0); 1941169Sbill } 1956202Sroot while (wait((int *)NULL) != i) 1961169Sbill ; 1971169Sbill printf("!\n"); 1981169Sbill out: 1991169Sbill sigs(eof); 2001169Sbill } 2011169Sbill 2021169Sbill sigs(sig) 2036202Sroot int (*sig)(); 2041169Sbill { 2051169Sbill register i; 2061169Sbill 2076202Sroot for (i=0; signum[i]; i++) 2086202Sroot signal(signum[i], sig); 2091169Sbill } 210