xref: /csrg-svn/libexec/comsat/comsat.c (revision 6394)
1*6394Sroot static	char *sccsid = "@(#)comsat.c	4.3 82/03/31";
2*6394Sroot 
31513Sroot #include <stdio.h>
41513Sroot #include <sgtty.h>
51513Sroot #include <utmp.h>
61513Sroot #include <sys/types.h>
7*6394Sroot #include <net/in.h>
8*6394Sroot #include <sys/socket.h>
91513Sroot #include <stat.h>
101513Sroot #include <wait.h>
111513Sroot #include <signal.h>
12*6394Sroot #include <errno.h>
131513Sroot 
141513Sroot /*
151513Sroot  * comsat
161513Sroot  */
171513Sroot #define	dprintf	if (0) printf
181513Sroot 
191513Sroot #define MAXUTMP 100		/* down from init */
201513Sroot 
21*6394Sroot struct	sockaddr_in sin = { AF_INET, IPPORT_BIFFUDP };
22*6394Sroot extern	errno;
23*6394Sroot 
241513Sroot struct	utmp utmp[100];
251513Sroot int	nutmp;
261513Sroot int	uf;
271513Sroot unsigned utmpmtime;			/* last modification time for utmp */
281513Sroot int	onalrm();
291513Sroot 
301513Sroot #define NAMLEN (sizeof (uts[0].ut_name) + 1)
311513Sroot 
321513Sroot main(argc, argv)
331513Sroot char **argv;
341513Sroot {
351513Sroot 	register cc;
361513Sroot 	char buf[BUFSIZ];
37*6394Sroot 	int s;
381513Sroot 
39*6394Sroot #ifndef DEBUG
401513Sroot 	if (fork())
411513Sroot 		exit();
42*6394Sroot #endif
431513Sroot 	chdir("/usr/spool/mail");
441513Sroot 	if((uf = open("/etc/utmp",0)) < 0)
451513Sroot 		perror("/etc/utmp"), exit(1);
46*6394Sroot #ifndef DEBUG
471513Sroot 	while (fork())
481513Sroot 		wait(0);
49*6394Sroot #endif
501572Sbill 	sleep(10);
511513Sroot 	onalrm();
521513Sroot 	sigset(SIGALRM, onalrm);
531513Sroot 	sigignore(SIGTTOU);
54*6394Sroot #if vax
55*6394Sroot 	sin.sin_port = ((sin.sin_port<<8)&0xff00)|((sin.sin_port>>8)&0xff);
56*6394Sroot #endif
57*6394Sroot 	s = socket(SOCK_DGRAM, 0, &sin, 0);
58*6394Sroot 	if (s < 0) {
59*6394Sroot 		perror("socket");
601513Sroot 		exit(1);
611513Sroot 	}
62*6394Sroot 	for (;;) {
63*6394Sroot 		char msgbuf[100];
64*6394Sroot 		int cc;
651513Sroot 
66*6394Sroot 		cc = receive(s, 0, msgbuf, sizeof (msgbuf) - 1);
67*6394Sroot 		if (cc <= 0) {
68*6394Sroot 			if (errno != EINTR)
69*6394Sroot 				sleep(1);
70*6394Sroot 			errno = 0;
71*6394Sroot 			continue;
721513Sroot 		}
73*6394Sroot 		msgbuf[cc] = 0;
74*6394Sroot 		mailfor(msgbuf);
751513Sroot 	}
761513Sroot }
771513Sroot 
781513Sroot onalrm()
791513Sroot {
801513Sroot 	struct stat statbf;
811513Sroot 	struct utmp *utp;
821513Sroot 
831513Sroot 	dprintf("alarm\n");
841513Sroot 	alarm(15);
851513Sroot 	fstat(uf,&statbf);
861513Sroot 	if (statbf.st_mtime > utmpmtime) {
871513Sroot 		dprintf(" changed\n");
881513Sroot 		utmpmtime = statbf.st_mtime;
891513Sroot 		lseek(uf, 0, 0);
901513Sroot 		nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp);
911513Sroot 	} else
921513Sroot 		dprintf(" ok\n");
931513Sroot }
941513Sroot 
951513Sroot mailfor(name)
961513Sroot 	char *name;
971513Sroot {
981513Sroot 	register struct utmp *utp = &utmp[nutmp];
991513Sroot 	register char *cp;
1001513Sroot 	char *rindex();
1011513Sroot 	int offset;
1021513Sroot 
1031513Sroot 	dprintf("mailfor %s\n", name);
1041513Sroot 	cp = name;
1051513Sroot 	while (*cp && *cp != '@')
1061513Sroot 		cp++;
1071513Sroot 	if (*cp == 0) {
1081513Sroot 		dprintf("bad format\n");
1091513Sroot 		return;
1101513Sroot 	}
1111513Sroot 	*cp = 0;
1121513Sroot 	offset = atoi(cp+1);
1131513Sroot 	while (--utp >= utmp)
1141513Sroot 		if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
1151513Sroot 			if (fork() == 0) {
1161513Sroot 				signal(SIGALRM, SIG_DFL);
1171513Sroot 				alarm(30);
1181513Sroot 				notify(utp, offset), exit(0);
1191513Sroot 			} else
1201513Sroot 				while (wait3(0, WNOHANG, 0) > 0)
1211513Sroot 					continue;
1221513Sroot }
1231513Sroot 
1241513Sroot char *cr;
1251513Sroot 
1261513Sroot notify(utp, offset)
1271513Sroot 	register struct utmp *utp;
1281513Sroot {
1291513Sroot 	FILE *tp;
1301513Sroot 	struct sgttyb gttybuf;
1311513Sroot 	char tty[20];
1321513Sroot 	char name[sizeof (utmp[0].ut_name) + 1];
1331513Sroot 	struct stat stb;
1341513Sroot 
1351513Sroot 	strcpy(tty, "/dev/");
1361513Sroot 	strncat(tty, utp->ut_line, sizeof(utp->ut_line));
1371513Sroot 	dprintf("notify %s on %s\n", utp->ut_name, tty);
1381513Sroot 	if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) {
1391513Sroot 		dprintf("wrong mode\n");
1401513Sroot 		return;
1411513Sroot 	}
1421513Sroot 	if ((tp = fopen(tty,"w")) == 0) {
1431513Sroot 		dprintf("fopen failed\n");
1441513Sroot 		return;
1451513Sroot 	}
1461513Sroot 	gtty(fileno(tp),&gttybuf);
1471513Sroot 	cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r";
1481513Sroot 	strncpy(name, utp->ut_name, sizeof (utp->ut_name));
1491513Sroot 	name[sizeof (name) - 1] = 0;
1501513Sroot 	fprintf(tp,"%s\n\007New mail for %s\007 has arrived:%s\n",
1511513Sroot 	    cr, name, cr);
1521513Sroot 	fprintf(tp,"----%s\n", cr);
1531513Sroot 	jkfprintf(tp, name, offset);
1541513Sroot 	 fclose(tp);
1551513Sroot }
1561513Sroot 
1571513Sroot jkfprintf(tp, name, offset)
1581513Sroot 	register FILE *tp;
1591513Sroot {
1601513Sroot 	register FILE *fi;
1611513Sroot 	register int linecnt, charcnt;
1621513Sroot 
1631513Sroot 	dprintf("HERE %s's mail starting at %d\n",
1641513Sroot 	    name, offset);
1651513Sroot 	if ((fi = fopen(name,"r")) == NULL) {
1661513Sroot 		dprintf("Cant read the mail\n");
1671513Sroot 		return;
1681513Sroot 	}
1691513Sroot 	fseek(fi, offset, 0);
1701513Sroot 	linecnt = 7;
1711513Sroot 	charcnt = 560;
1721513Sroot 	/*
1731513Sroot 	 * print the first 7 lines or 560 characters of the new mail
1741513Sroot 	 * (whichever comes first)
1751513Sroot 	 */
1761513Sroot 	for (;;) {
1771513Sroot 		register ch;
1781513Sroot 
1791513Sroot 	 	if ((ch = getc(fi)) == EOF) {
1801513Sroot 			fprintf(tp,"----%s\n", cr);
1811513Sroot 			break;
1821513Sroot 		}
1831513Sroot 		if (ch == '\n') {
1841513Sroot 			fprintf(tp,"%s\n", cr);
1851513Sroot 		 	if (linecnt-- < 0) {
1861513Sroot 				fprintf(tp,"...more...%s\n", cr);
1871513Sroot 				break;
1881513Sroot 			}
1891513Sroot 		} else if(linecnt <= 0) {
1901513Sroot 			fprintf(tp,"...more...%s\n", cr);
1911513Sroot 			break;
1921513Sroot 		} else
1931513Sroot 			putc(ch, tp);
1941513Sroot 		if (charcnt-- == 0) {
1951513Sroot 			fprintf(tp, "%s\n", cr);
1961513Sroot 			break;
1971513Sroot 		}
1981513Sroot 	}
1991513Sroot }
200