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