|
|
1.1 root 1: static char *sccsid = "@(#)comsat.c 4.2 (Berkeley) 10/20/80";
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
15: int xd;
16:
17: struct ctp {
18: short ctrl;
19: short ctrlarg;
20: struct sgttyb ctrlv;
21: } ctp;
22:
23: #define MAXUTMP 100 /* down from init */
24:
25: struct utmp utmp[100];
26: int nutmp;
27: int uf;
28: unsigned utmpmtime; /* last modification time for utmp */
29: int onalrm();
30:
31: #define NAMLEN (sizeof (uts[0].ut_name) + 1)
32:
33: main(argc, argv)
34: char **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);
46: sleep(10);
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: }
62: _exit(1);
63: }
64:
65: #define skip(rp, c) ((struct rh *)(((char *)rp)+c))
66:
67: unpack(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:
94: control(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:
134: onalrm()
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:
151: mailfor(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:
180: char *cr;
181:
182: notify(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),>tybuf);
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:
213: jkfprintf(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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.