temporary kluge fix for setting script in .tiprc file
[unix-history] / usr / src / libexec / comsat / comsat.c
CommitLineData
d8455f48 1static char *sccsid = "@(#)comsat.c 4.2 (Berkeley) %G%";
6ae77bb7
BJ
2#include <stdio.h>
3#include <sys/mx.h>
4#include <sgtty.h>
5#include <utmp.h>
6#include <sys/types.h>
7#include <stat.h>
8#include <wait.h>
9#include <signal.h>
10
11/*
12 * comsat
13 */
14#define dprintf if (0) printf
15int xd;
16
17struct ctp {
18 short ctrl;
19 short ctrlarg;
20 struct sgttyb ctrlv;
21} ctp;
22
23#define MAXUTMP 100 /* down from init */
24
25struct utmp utmp[100];
26int nutmp;
27int uf;
28unsigned utmpmtime; /* last modification time for utmp */
29int onalrm();
30
31#define NAMLEN (sizeof (uts[0].ut_name) + 1)
32
33main(argc, argv)
34char **argv;
35{
36 register cc;
37 char buf[BUFSIZ];
38
39 if (fork())
40 exit();
41 chdir("/usr/spool/mail");
42 if((uf = open("/etc/utmp",0)) < 0)
43 perror("/etc/utmp"), exit(1);
44 while (fork())
45 wait(0);
d8455f48 46 sleep(10);
6ae77bb7
BJ
47 onalrm();
48 sigset(SIGALRM, onalrm);
49 sigignore(SIGTTOU);
50 unlink("/dev/mail");
51 xd = mpx("/dev/mail", 0666);
52 if (xd < 0) {
53 close(2);
54 open("/dev/console", 1);
55 perror("/dev/mail");
56 exit(1);
57 }
58 while((cc=read(xd, buf, BUFSIZ)) >= 0) {
59 dprintf("0: got %d bytes\n", cc);
60 unpack(buf, cc);
61 }
d8455f48 62 _exit(1);
6ae77bb7
BJ
63}
64
65#define skip(rp, c) ((struct rh *)(((char *)rp)+c))
66
67unpack(rp, cc)
68 register struct rh *rp;
69{
70 register struct rh *end;
71 int i;
72
73 i = 0;
74 end = skip(rp, cc);
75 while (rp < end) {
76 dprintf("%d: ", ++i);
77 if (rp->count==0) {
78 dprintf("%d byte control message\n", rp->ccount);
79 control(rp->index, rp+1, rp->ccount);
80 } else {
81 dprintf("%*.*s\n", rp->count, rp->count, rp+1);
82 sighold(SIGALRM);
83 mailfor(rp+1);
84 sigrelse(SIGALRM);
85 }
86 rp->count += rp->ccount;
87 if (rp->count & 1)
88 rp->count++;
89 rp = skip(rp, rp->count);
90 rp++;
91 }
92}
93
94control(x, cb, cc)
95 register char *cb;
96{
97 register char *end;
98 int cmd;
99 short *sp;
100 struct wh or;
101
102 end = cb + cc;
103 cmd = *cb++;
104 sp = (short *)cb+1;
105 switch (cmd) {
106
107 case M_WATCH:
108 dprintf("attach %x, uid %d\n", x, *sp);
109 attach(x, xd);
110 break;
111
112 case M_CLOSE:
113 sp = (short *)cb;
114 dprintf("detach %x, uid %d\n", x, *sp);
115 detach(x, xd);
116 break;
117
118 case M_IOCTL:
119 dprintf("ioctl %x\n", x);
120 or.index = x;
121 or.count = 0;
122 or.ccount = sizeof ctp;
123 or.data = (char *) &ctp.ctrlarg;
124 ctp.ctrlarg = M_IOANS;
125 write(xd, &or, sizeof or);
126 break;
127
128 default:
129 dprintf("unknown command %d\n", cmd);
130 return;
131 }
132}
133
134onalrm()
135{
136 struct stat statbf;
137 struct utmp *utp;
138
139 dprintf("alarm\n");
140 alarm(15);
141 fstat(uf,&statbf);
142 if (statbf.st_mtime > utmpmtime) {
143 dprintf(" changed\n");
144 utmpmtime = statbf.st_mtime;
145 lseek(uf, 0, 0);
146 nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp);
147 } else
148 dprintf(" ok\n");
149}
150
151mailfor(name)
152 char *name;
153{
154 register struct utmp *utp = &utmp[nutmp];
155 register char *cp;
156 char *rindex();
157 int offset;
158
159 dprintf("mailfor %s\n", name);
160 cp = name;
161 while (*cp && *cp != '@')
162 cp++;
163 if (*cp == 0) {
164 dprintf("bad format\n");
165 return;
166 }
167 *cp = 0;
168 offset = atoi(cp+1);
169 while (--utp >= utmp)
170 if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
171 if (fork() == 0) {
172 signal(SIGALRM, SIG_DFL);
173 alarm(30);
174 notify(utp, offset), exit(0);
175 } else
176 while (wait3(0, WNOHANG, 0) > 0)
177 continue;
178}
179
180char *cr;
181
182notify(utp, offset)
183 register struct utmp *utp;
184{
185 FILE *tp;
186 struct sgttyb gttybuf;
187 char tty[20];
188 char name[sizeof (utmp[0].ut_name) + 1];
189 struct stat stb;
190
191 strcpy(tty, "/dev/");
192 strncat(tty, utp->ut_line, sizeof(utp->ut_line));
193 dprintf("notify %s on %s\n", utp->ut_name, tty);
194 if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) {
195 dprintf("wrong mode\n");
196 return;
197 }
198 if ((tp = fopen(tty,"w")) == 0) {
199 dprintf("fopen failed\n");
200 return;
201 }
202 gtty(fileno(tp),&gttybuf);
203 cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r";
204 strncpy(name, utp->ut_name, sizeof (utp->ut_name));
205 name[sizeof (name) - 1] = 0;
206 fprintf(tp,"%s\n\007New mail for %s\007 has arrived:%s\n",
207 cr, name, cr);
208 fprintf(tp,"----%s\n", cr);
209 jkfprintf(tp, name, offset);
210 fclose(tp);
211}
212
213jkfprintf(tp, name, offset)
214 register FILE *tp;
215{
216 register FILE *fi;
217 register int linecnt, charcnt;
218
219 dprintf("HERE %s's mail starting at %d\n",
220 name, offset);
221 if ((fi = fopen(name,"r")) == NULL) {
222 dprintf("Cant read the mail\n");
223 return;
224 }
225 fseek(fi, offset, 0);
226 linecnt = 7;
227 charcnt = 560;
228 /*
229 * print the first 7 lines or 560 characters of the new mail
230 * (whichever comes first)
231 */
232 for (;;) {
233 register ch;
234
235 if ((ch = getc(fi)) == EOF) {
236 fprintf(tp,"----%s\n", cr);
237 break;
238 }
239 if (ch == '\n') {
240 fprintf(tp,"%s\n", cr);
241 if (linecnt-- < 0) {
242 fprintf(tp,"...more...%s\n", cr);
243 break;
244 }
245 } else if(linecnt <= 0) {
246 fprintf(tp,"...more...%s\n", cr);
247 break;
248 } else
249 putc(ch, tp);
250 if (charcnt-- == 0) {
251 fprintf(tp, "%s\n", cr);
252 break;
253 }
254 }
255}