Commit | Line | Data |
---|---|---|
ebc8086f | 1 | #ifndef lint |
8daa86a6 | 2 | static 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 |
22 | int debug = 0; |
23 | #define dprintf if (debug) printf | |
6ae77bb7 BJ |
24 | |
25 | #define MAXUTMP 100 /* down from init */ | |
26 | ||
a591911b | 27 | struct sockaddr_in sin = { AF_INET }; |
9afb4b8a BJ |
28 | extern errno; |
29 | ||
6ae77bb7 BJ |
30 | struct utmp utmp[100]; |
31 | int nutmp; | |
32 | int uf; | |
33 | unsigned utmpmtime; /* last modification time for utmp */ | |
34 | int onalrm(); | |
ebc8086f | 35 | struct servent *sp; |
6ae77bb7 BJ |
36 | |
37 | #define NAMLEN (sizeof (uts[0].ut_name) + 1) | |
38 | ||
39 | main(argc, argv) | |
40 | char **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 | ||
90 | onalrm() | |
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 | ||
107 | mailfor(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 | ||
136 | char *cr; | |
137 | ||
138 | notify(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, >tybuf); |
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 | ||
170 | jkfprintf(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 | } |