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