xref: /csrg-svn/usr.bin/write/write.c (revision 13599)
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