|
|
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.