xref: /csrg-svn/usr.bin/write/write.c (revision 1799)
1*1799Seric static char *sccsid = "@(#)write.c	4.2 (Berkeley) 11/10/80";
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>
111169Sbill #include <time.h>
121169Sbill 
131169Sbill #define NMAX sizeof(ubuf.ut_name)
141169Sbill #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)
341169Sbill char *argv[];
351169Sbill {
361169Sbill 	struct stat stbuf;
371169Sbill 	register i;
381169Sbill 	register FILE *uf;
391169Sbill 	int c1, c2;
401169Sbill 	long	clock = time( 0 );
411169Sbill 	struct tm *localtime();
421169Sbill 	struct tm *localclock = localtime( &clock );
431169Sbill 
441169Sbill 	if(argc < 2) {
451169Sbill 		printf("usage: write user [ttyname]\n");
461169Sbill 		exit(1);
471169Sbill 	}
481169Sbill 	him = argv[1];
491169Sbill 	if(argc > 2)
501169Sbill 		histtya = argv[2];
511169Sbill 	if ((uf = fopen("/etc/utmp", "r")) == NULL) {
521169Sbill 		printf("cannot open /etc/utmp\n");
531169Sbill 		goto cont;
541169Sbill 	}
551169Sbill 	mytty = ttyname(2);
561169Sbill 	if (mytty == NULL) {
571169Sbill 		printf("Can't find your tty\n");
581169Sbill 		exit(1);
591169Sbill 	}
601169Sbill 	mytty = rindex(mytty, '/') + 1;
611169Sbill 	if (histtya) {
621169Sbill 		strcpy(histty, "/dev/");
631169Sbill 		strcat(histty, histtya);
641169Sbill 	}
651169Sbill 	while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) {
66*1799Seric 		if (ubuf.ut_name[0] == '\0')
67*1799Seric 			continue;
681169Sbill 		if (strcmp(ubuf.ut_line, mytty)==0) {
691169Sbill 			for(i=0; i<NMAX; i++) {
701169Sbill 				c1 = ubuf.ut_name[i];
711169Sbill 				if(c1 == ' ')
721169Sbill 					c1 = 0;
731169Sbill 				me[i] = c1;
741169Sbill 				if(c1 == 0)
751169Sbill 					break;
761169Sbill 			}
771169Sbill 		}
781169Sbill 		if(him[0] != '-' || him[1] != 0)
791169Sbill 		for(i=0; i<NMAX; i++) {
801169Sbill 			c1 = him[i];
811169Sbill 			c2 = ubuf.ut_name[i];
821169Sbill 			if(c1 == 0)
831169Sbill 				if(c2 == 0 || c2 == ' ')
841169Sbill 					break;
851169Sbill 			if(c1 != c2)
861169Sbill 				goto nomat;
871169Sbill 		}
881169Sbill 		logcnt++;
891169Sbill 		if (histty[0]==0) {
901169Sbill 			strcpy(histty, "/dev/");
911169Sbill 			strcat(histty, ubuf.ut_line);
921169Sbill 		}
931169Sbill 	nomat:
941169Sbill 		;
951169Sbill 	}
961169Sbill cont:
971169Sbill 	if (logcnt==0 && histty[0]=='\0') {
981169Sbill 		printf("%s not logged in.\n", him);
991169Sbill 		exit(1);
1001169Sbill 	}
1011169Sbill 	fclose(uf);
1021169Sbill 	if (histtya==0 && logcnt > 1) {
1031169Sbill 		printf("%s logged more than once\nwriting to %s\n", him, histty+5);
1041169Sbill 	}
1051169Sbill 	if(histty[0] == 0) {
1061169Sbill 		printf(him);
1071169Sbill 		if(logcnt)
1081169Sbill 			printf(" not on that tty\n"); else
1091169Sbill 			printf(" not logged in\n");
1101169Sbill 		exit(1);
1111169Sbill 	}
1121169Sbill 	if (access(histty, 0) < 0) {
1131169Sbill 		printf("No such tty\n");
1141169Sbill 		exit(1);
1151169Sbill 	}
1161169Sbill 	signal(SIGALRM, timout);
1171169Sbill 	alarm(5);
1181169Sbill 	if ((tf = fopen(histty, "w")) == NULL)
1191169Sbill 		goto perm;
1201169Sbill 	alarm(0);
1211169Sbill 	if (fstat(fileno(tf), &stbuf) < 0)
1221169Sbill 		goto perm;
1231169Sbill 	if ((stbuf.st_mode&02) == 0)
1241169Sbill 		goto perm;
1251169Sbill 	sigs(eof);
1261169Sbill 	fprintf(tf, "\r\nMessage from ");
1271169Sbill #ifdef interdata
1281169Sbill 	fprintf(tf, "(Interdata) " );
1291169Sbill #endif
1301169Sbill 	fprintf(tf, "%s on %s at %d:%02d ...\r\n"
1311169Sbill 	       , me, mytty , localclock -> tm_hour , localclock -> tm_min );
1321169Sbill 	fflush(tf);
1331169Sbill 	for(;;) {
1341169Sbill 		char buf[128];
1351169Sbill 		i = read(0, buf, 128);
1361169Sbill 		if(i <= 0)
1371169Sbill 			eof();
1381169Sbill 		if(buf[0] == '!') {
1391169Sbill 			buf[i] = 0;
1401169Sbill 			ex(buf);
1411169Sbill 			continue;
1421169Sbill 		}
1431169Sbill 		write(fileno(tf), buf, i);
1441169Sbill 		if ( buf[ i - 1 ] == '\n' )
1451169Sbill 		    write( fileno( tf ) , "\r" , 1 );
1461169Sbill 	}
1471169Sbill 
1481169Sbill perm:
1491169Sbill 	printf("Permission denied\n");
1501169Sbill 	exit(1);
1511169Sbill }
1521169Sbill 
1531169Sbill timout()
1541169Sbill {
1551169Sbill 
1561169Sbill 	printf("Timeout opening their tty\n");
1571169Sbill 	exit(1);
1581169Sbill }
1591169Sbill 
1601169Sbill eof()
1611169Sbill {
1621169Sbill 
1631169Sbill 	fprintf(tf, "EOF\r\n");
1641169Sbill 	exit(0);
1651169Sbill }
1661169Sbill 
1671169Sbill ex(bp)
1681169Sbill char *bp;
1691169Sbill {
1701169Sbill 	register i;
1711169Sbill 
1721169Sbill 	sigs(SIG_IGN);
1731169Sbill 	i = fork();
1741169Sbill 	if(i < 0) {
1751169Sbill 		printf("Try again\n");
1761169Sbill 		goto out;
1771169Sbill 	}
1781169Sbill 	if(i == 0) {
1791169Sbill 		sigs((int (*)())0);
1801169Sbill 		execl(getenv("SHELL") ? getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0);
1811169Sbill 		exit(0);
1821169Sbill 	}
1831169Sbill 	while(wait((int *)NULL) != i)
1841169Sbill 		;
1851169Sbill 	printf("!\n");
1861169Sbill out:
1871169Sbill 	sigs(eof);
1881169Sbill }
1891169Sbill 
1901169Sbill sigs(sig)
1911169Sbill int (*sig)();
1921169Sbill {
1931169Sbill 	register i;
1941169Sbill 
1951169Sbill 	for(i=0;signum[i];i++)
1961169Sbill 		signal(signum[i],sig);
1971169Sbill }
198