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