xref: /original-bsd/usr.bin/write/write.c (revision 0b685140)
1 static char *sccsid = "@(#)write.c	4.4 (Berkeley) 01/27/82";
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 #include <whoami.h>
13 
14 #define NMAX sizeof(ubuf.ut_name)
15 #define LMAX sizeof(ubuf.ut_line)
16 
17 char	*strcat();
18 char	*strcpy();
19 struct	utmp ubuf;
20 int	signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
21 char	me[10]	= "???";
22 char	*him;
23 char	*mytty;
24 char	histty[32];
25 char	*histtya;
26 char	*ttyname();
27 char	*rindex();
28 int	logcnt;
29 int	eof();
30 int	timout();
31 FILE	*tf;
32 char	*getenv();
33 
34 main(argc, argv)
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 	fprintf(tf, "\r\nMessage from ");
136 #ifdef interdata
137 	fprintf(tf, "(Interdata) " );
138 #endif
139 	fprintf(tf, "%s!%s on %s at %d:%02d ...\r\n"
140 	       , sysname , me, mytty , localclock -> tm_hour , localclock -> tm_min );
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 		write(fileno(tf), buf, i);
153 		if ( buf[ i - 1 ] == '\n' )
154 		    write( fileno( tf ) , "\r" , 1 );
155 	}
156 
157 perm:
158 	printf("Permission denied\n");
159 	exit(1);
160 }
161 
162 timout()
163 {
164 
165 	printf("Timeout opening their tty\n");
166 	exit(1);
167 }
168 
169 eof()
170 {
171 
172 	fprintf(tf, "EOF\r\n");
173 	exit(0);
174 }
175 
176 ex(bp)
177 char *bp;
178 {
179 	register i;
180 
181 	sigs(SIG_IGN);
182 	i = fork();
183 	if(i < 0) {
184 		printf("Try again\n");
185 		goto out;
186 	}
187 	if(i == 0) {
188 		sigs((int (*)())0);
189 		execl(getenv("SHELL") ? getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0);
190 		exit(0);
191 	}
192 	while(wait((int *)NULL) != i)
193 		;
194 	printf("!\n");
195 out:
196 	sigs(eof);
197 }
198 
199 sigs(sig)
200 int (*sig)();
201 {
202 	register i;
203 
204 	for(i=0;signum[i];i++)
205 		signal(signum[i],sig);
206 }
207