xref: /original-bsd/usr.bin/write/write.c (revision b64b0d54)
1 static char *sccsid = "@(#)write.c	4.7 03/01/83";
2 /*
3  * write to another user
4  */
5 
6 #include <stdio.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <signal.h>
10 #include <utmp.h>
11 #include <time.h>
12 
13 #define	NMAX	sizeof(ubuf.ut_name)
14 #define	LMAX	sizeof(ubuf.ut_line)
15 
16 char	*strcat();
17 char	*strcpy();
18 struct	utmp ubuf;
19 int	signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
20 char	me[10]	= "???";
21 char	*him;
22 char	*mytty;
23 char	histty[32];
24 char	*histtya;
25 char	*ttyname();
26 char	*rindex();
27 int	logcnt;
28 int	eof();
29 int	timout();
30 FILE	*tf;
31 char	*getenv();
32 
33 main(argc, argv)
34 	int argc;
35 	char *argv[];
36 {
37 	struct stat stbuf;
38 	register i;
39 	register FILE *uf;
40 	int c1, c2;
41 	long clock = time(0);
42 	struct tm *localtime();
43 	struct tm *localclock = localtime( &clock );
44 
45 	if (argc < 2) {
46 		printf("usage: write user [ttyname]\n");
47 		exit(1);
48 	}
49 	him = argv[1];
50 	if (argc > 2)
51 		histtya = argv[2];
52 	if ((uf = fopen("/etc/utmp", "r")) == NULL) {
53 		printf("cannot open /etc/utmp\n");
54 		goto cont;
55 	}
56 	mytty = ttyname(2);
57 	if (mytty == NULL) {
58 		printf("Can't find your tty\n");
59 		exit(1);
60 	}
61 	if (stat(mytty, &stbuf) < 0) {
62 		printf("Can't stat your tty\n");
63 		exit(1);
64 	}
65 	if ((stbuf.st_mode&02) == 0) {
66 		printf("You have write permission turned off.\n");
67 		exit(1);
68 	}
69 	mytty = rindex(mytty, '/') + 1;
70 	if (histtya) {
71 		strcpy(histty, "/dev/");
72 		strcat(histty, histtya);
73 	}
74 	while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) {
75 		if (ubuf.ut_name[0] == '\0')
76 			continue;
77 		if (strcmp(ubuf.ut_line, mytty)==0) {
78 			for (i=0; i<NMAX; i++) {
79 				c1 = ubuf.ut_name[i];
80 				if (c1 == ' ')
81 					c1 = 0;
82 				me[i] = c1;
83 				if (c1 == 0)
84 					break;
85 			}
86 		}
87 		if (him[0] != '-' || him[1] != 0)
88 		for (i=0; i<NMAX; i++) {
89 			c1 = him[i];
90 			c2 = ubuf.ut_name[i];
91 			if (c1 == 0)
92 				if (c2 == 0 || c2 == ' ')
93 					break;
94 			if (c1 != c2)
95 				goto nomat;
96 		}
97 		logcnt++;
98 		if (histty[0]==0) {
99 			strcpy(histty, "/dev/");
100 			strcat(histty, ubuf.ut_line);
101 		}
102 	nomat:
103 		;
104 	}
105 cont:
106 	if (logcnt==0 && histty[0]=='\0') {
107 		printf("%s not logged in.\n", him);
108 		exit(1);
109 	}
110 	fclose(uf);
111 	if (histtya==0 && logcnt > 1) {
112 		printf("%s logged more than once\nwriting to %s\n", him, histty+5);
113 	}
114 	if (histty[0] == 0) {
115 		printf(him);
116 		if (logcnt)
117 			printf(" not on that tty\n"); else
118 			printf(" not logged in\n");
119 		exit(1);
120 	}
121 	if (access(histty, 0) < 0) {
122 		printf("No such tty\n");
123 		exit(1);
124 	}
125 	signal(SIGALRM, timout);
126 	alarm(5);
127 	if ((tf = fopen(histty, "w")) == NULL)
128 		goto perm;
129 	alarm(0);
130 	if (fstat(fileno(tf), &stbuf) < 0)
131 		goto perm;
132 	if ((stbuf.st_mode&02) == 0)
133 		goto perm;
134 	sigs(eof);
135 	{ char hostname[32];
136 	  gethostname(hostname, sizeof (hostname));
137 	  fprintf(tf, "\r\nMessage from ");
138 	  fprintf(tf, "%s!%s on %s at %d:%02d ...\r\n\007\007\007",
139 	      hostname, me, mytty, localclock->tm_hour, localclock->tm_min);
140 	}
141 	fflush(tf);
142 	for (;;) {
143 		char buf[128];
144 		i = read(0, buf, 128);
145 		if (i <= 0)
146 			eof();
147 		if (buf[0] == '!') {
148 			buf[i] = 0;
149 			ex(buf);
150 			continue;
151 		}
152 		if (write(fileno(tf), buf, i) != i) {
153 			printf("\n\007Write failed (%s logged out?)\n", him);
154 			exit(1);
155 		}
156 		if (buf[i-1] == '\n')
157 			write(fileno(tf), "\r", 1);
158 	}
159 perm:
160 	printf("Permission denied\n");
161 	exit(1);
162 }
163 
164 timout()
165 {
166 
167 	printf("Timeout opening their tty\n");
168 	exit(1);
169 }
170 
171 eof()
172 {
173 
174 	fprintf(tf, "EOF\r\n");
175 	exit(0);
176 }
177 
178 ex(bp)
179 	char *bp;
180 {
181 	register i;
182 
183 	sigs(SIG_IGN);
184 	i = fork();
185 	if (i < 0) {
186 		printf("Try again\n");
187 		goto out;
188 	}
189 	if (i == 0) {
190 		sigs((int (*)())0);
191 		execl(getenv("SHELL") ?
192 		    getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0);
193 		exit(0);
194 	}
195 	while (wait((int *)NULL) != i)
196 		;
197 	printf("!\n");
198 out:
199 	sigs(eof);
200 }
201 
202 sigs(sig)
203 	int (*sig)();
204 {
205 	register i;
206 
207 	for (i=0; signum[i]; i++)
208 		signal(signum[i], sig);
209 }
210