xref: /original-bsd/libexec/comsat/comsat.c (revision fbed46ce)
1 static	char *sccsid = "@(#)comsat.c	4.3 82/03/31";
2 
3 #include <stdio.h>
4 #include <sgtty.h>
5 #include <utmp.h>
6 #include <sys/types.h>
7 #include <net/in.h>
8 #include <sys/socket.h>
9 #include <stat.h>
10 #include <wait.h>
11 #include <signal.h>
12 #include <errno.h>
13 
14 /*
15  * comsat
16  */
17 #define	dprintf	if (0) printf
18 
19 #define MAXUTMP 100		/* down from init */
20 
21 struct	sockaddr_in sin = { AF_INET, IPPORT_BIFFUDP };
22 extern	errno;
23 
24 struct	utmp utmp[100];
25 int	nutmp;
26 int	uf;
27 unsigned utmpmtime;			/* last modification time for utmp */
28 int	onalrm();
29 
30 #define NAMLEN (sizeof (uts[0].ut_name) + 1)
31 
32 main(argc, argv)
33 char **argv;
34 {
35 	register cc;
36 	char buf[BUFSIZ];
37 	int s;
38 
39 #ifndef DEBUG
40 	if (fork())
41 		exit();
42 #endif
43 	chdir("/usr/spool/mail");
44 	if((uf = open("/etc/utmp",0)) < 0)
45 		perror("/etc/utmp"), exit(1);
46 #ifndef DEBUG
47 	while (fork())
48 		wait(0);
49 #endif
50 	sleep(10);
51 	onalrm();
52 	sigset(SIGALRM, onalrm);
53 	sigignore(SIGTTOU);
54 #if vax
55 	sin.sin_port = ((sin.sin_port<<8)&0xff00)|((sin.sin_port>>8)&0xff);
56 #endif
57 	s = socket(SOCK_DGRAM, 0, &sin, 0);
58 	if (s < 0) {
59 		perror("socket");
60 		exit(1);
61 	}
62 	for (;;) {
63 		char msgbuf[100];
64 		int cc;
65 
66 		cc = receive(s, 0, msgbuf, sizeof (msgbuf) - 1);
67 		if (cc <= 0) {
68 			if (errno != EINTR)
69 				sleep(1);
70 			errno = 0;
71 			continue;
72 		}
73 		msgbuf[cc] = 0;
74 		mailfor(msgbuf);
75 	}
76 }
77 
78 onalrm()
79 {
80 	struct stat statbf;
81 	struct utmp *utp;
82 
83 	dprintf("alarm\n");
84 	alarm(15);
85 	fstat(uf,&statbf);
86 	if (statbf.st_mtime > utmpmtime) {
87 		dprintf(" changed\n");
88 		utmpmtime = statbf.st_mtime;
89 		lseek(uf, 0, 0);
90 		nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp);
91 	} else
92 		dprintf(" ok\n");
93 }
94 
95 mailfor(name)
96 	char *name;
97 {
98 	register struct utmp *utp = &utmp[nutmp];
99 	register char *cp;
100 	char *rindex();
101 	int offset;
102 
103 	dprintf("mailfor %s\n", name);
104 	cp = name;
105 	while (*cp && *cp != '@')
106 		cp++;
107 	if (*cp == 0) {
108 		dprintf("bad format\n");
109 		return;
110 	}
111 	*cp = 0;
112 	offset = atoi(cp+1);
113 	while (--utp >= utmp)
114 		if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
115 			if (fork() == 0) {
116 				signal(SIGALRM, SIG_DFL);
117 				alarm(30);
118 				notify(utp, offset), exit(0);
119 			} else
120 				while (wait3(0, WNOHANG, 0) > 0)
121 					continue;
122 }
123 
124 char *cr;
125 
126 notify(utp, offset)
127 	register struct utmp *utp;
128 {
129 	FILE *tp;
130 	struct sgttyb gttybuf;
131 	char tty[20];
132 	char name[sizeof (utmp[0].ut_name) + 1];
133 	struct stat stb;
134 
135 	strcpy(tty, "/dev/");
136 	strncat(tty, utp->ut_line, sizeof(utp->ut_line));
137 	dprintf("notify %s on %s\n", utp->ut_name, tty);
138 	if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) {
139 		dprintf("wrong mode\n");
140 		return;
141 	}
142 	if ((tp = fopen(tty,"w")) == 0) {
143 		dprintf("fopen failed\n");
144 		return;
145 	}
146 	gtty(fileno(tp),&gttybuf);
147 	cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r";
148 	strncpy(name, utp->ut_name, sizeof (utp->ut_name));
149 	name[sizeof (name) - 1] = 0;
150 	fprintf(tp,"%s\n\007New mail for %s\007 has arrived:%s\n",
151 	    cr, name, cr);
152 	fprintf(tp,"----%s\n", cr);
153 	jkfprintf(tp, name, offset);
154 	 fclose(tp);
155 }
156 
157 jkfprintf(tp, name, offset)
158 	register FILE *tp;
159 {
160 	register FILE *fi;
161 	register int linecnt, charcnt;
162 
163 	dprintf("HERE %s's mail starting at %d\n",
164 	    name, offset);
165 	if ((fi = fopen(name,"r")) == NULL) {
166 		dprintf("Cant read the mail\n");
167 		return;
168 	}
169 	fseek(fi, offset, 0);
170 	linecnt = 7;
171 	charcnt = 560;
172 	/*
173 	 * print the first 7 lines or 560 characters of the new mail
174 	 * (whichever comes first)
175 	 */
176 	for (;;) {
177 		register ch;
178 
179 	 	if ((ch = getc(fi)) == EOF) {
180 			fprintf(tp,"----%s\n", cr);
181 			break;
182 		}
183 		if (ch == '\n') {
184 			fprintf(tp,"%s\n", cr);
185 		 	if (linecnt-- < 0) {
186 				fprintf(tp,"...more...%s\n", cr);
187 				break;
188 			}
189 		} else if(linecnt <= 0) {
190 			fprintf(tp,"...more...%s\n", cr);
191 			break;
192 		} else
193 			putc(ch, tp);
194 		if (charcnt-- == 0) {
195 			fprintf(tp, "%s\n", cr);
196 			break;
197 		}
198 	}
199 }
200