|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)comsat.c 5.5 (Berkeley) 10/24/85";
15: #endif not lint
16:
17: #include <sys/types.h>
18: #include <sys/socket.h>
19: #include <sys/stat.h>
20: #include <sys/wait.h>
21: #include <sys/file.h>
22:
23: #include <netinet/in.h>
24:
25: #include <stdio.h>
26: #include <sgtty.h>
27: #include <utmp.h>
28: #include <signal.h>
29: #include <errno.h>
30: #include <netdb.h>
31: #include <syslog.h>
32:
33: /*
34: * comsat
35: */
36: int debug = 0;
37: #define dprintf if (debug) printf
38:
39: struct sockaddr_in sin = { AF_INET };
40: extern errno;
41:
42: char hostname[32];
43: struct utmp *utmp = NULL;
44: int nutmp;
45: int uf;
46: unsigned utmpmtime = 0; /* last modification time for utmp */
47: unsigned utmpsize = 0; /* last malloced size for utmp */
48: int onalrm();
49: int reapchildren();
50: long lastmsgtime;
51: char *malloc(), *realloc();
52:
53: #define MAXIDLE 120
54: #define NAMLEN (sizeof (uts[0].ut_name) + 1)
55:
56: main(argc, argv)
57: int argc;
58: char *argv[];
59: {
60: register int cc;
61: char buf[BUFSIZ];
62: char msgbuf[100];
63: struct sockaddr_in from;
64: int fromlen;
65:
66: /* verify proper invocation */
67: fromlen = sizeof (from);
68: if (getsockname(0, &from, &fromlen) < 0) {
69: fprintf(stderr, "%s: ", argv[0]);
70: perror("getsockname");
71: _exit(1);
72: }
73: chdir("/usr/spool/mail");
74: if ((uf = open("/etc/utmp",0)) < 0) {
75: openlog("comsat", 0, LOG_DAEMON);
76: syslog(LOG_ERR, "/etc/utmp: %m");
77: (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
78: exit(1);
79: }
80: lastmsgtime = time(0);
81: gethostname(hostname, sizeof (hostname));
82: onalrm();
83: signal(SIGALRM, onalrm);
84: signal(SIGTTOU, SIG_IGN);
85: signal(SIGCHLD, reapchildren);
86: for (;;) {
87: cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
88: if (cc <= 0) {
89: if (errno != EINTR)
90: sleep(1);
91: errno = 0;
92: continue;
93: }
94: sigblock(sigmask(SIGALRM));
95: msgbuf[cc] = 0;
96: lastmsgtime = time(0);
97: mailfor(msgbuf);
98: sigsetmask(0);
99: }
100: }
101:
102: reapchildren()
103: {
104:
105: while (wait3((struct wait *)0, WNOHANG, (struct rusage *)0) > 0)
106: ;
107: }
108:
109: onalrm()
110: {
111: struct stat statbf;
112:
113: if (time(0) - lastmsgtime >= MAXIDLE)
114: exit(0);
115: dprintf("alarm\n");
116: alarm(15);
117: fstat(uf, &statbf);
118: if (statbf.st_mtime > utmpmtime) {
119: dprintf(" changed\n");
120: utmpmtime = statbf.st_mtime;
121: if (statbf.st_size > utmpsize) {
122: utmpsize = statbf.st_size + 10 * sizeof(struct utmp);
123: if (utmp)
124: utmp = (struct utmp *)realloc(utmp, utmpsize);
125: else
126: utmp = (struct utmp *)malloc(utmpsize);
127: if (! utmp) {
128: dprintf("malloc failed\n");
129: exit(1);
130: }
131: }
132: lseek(uf, 0, 0);
133: nutmp = read(uf,utmp,statbf.st_size)/sizeof(struct utmp);
134: } else
135: dprintf(" ok\n");
136: }
137:
138: mailfor(name)
139: char *name;
140: {
141: register struct utmp *utp = &utmp[nutmp];
142: register char *cp;
143: char *rindex();
144: int offset;
145:
146: dprintf("mailfor %s\n", name);
147: cp = name;
148: while (*cp && *cp != '@')
149: cp++;
150: if (*cp == 0) {
151: dprintf("bad format\n");
152: return;
153: }
154: *cp = 0;
155: offset = atoi(cp+1);
156: while (--utp >= utmp)
157: if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
158: notify(utp, offset);
159: }
160:
161: char *cr;
162:
163: notify(utp, offset)
164: register struct utmp *utp;
165: {
166: FILE *tp;
167: struct sgttyb gttybuf;
168: char tty[20], name[sizeof (utmp[0].ut_name) + 1];
169: struct stat stb;
170:
171: strcpy(tty, "/dev/");
172: strncat(tty, utp->ut_line, sizeof(utp->ut_line));
173: dprintf("notify %s on %s\n", utp->ut_name, tty);
174: if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) {
175: dprintf("wrong mode\n");
176: return;
177: }
178: if (fork())
179: return;
180: signal(SIGALRM, SIG_DFL);
181: alarm(30);
182: if ((tp = fopen(tty,"w")) == 0) {
183: dprintf("fopen failed\n");
184: exit(-1);
185: }
186: ioctl(fileno(tp), TIOCGETP, >tybuf);
187: cr = (gttybuf.sg_flags&CRMOD) && !(gttybuf.sg_flags&RAW) ? "" : "\r";
188: strncpy(name, utp->ut_name, sizeof (utp->ut_name));
189: name[sizeof (name) - 1] = '\0';
190: fprintf(tp,"%s\n\007New mail for %s@%.*s\007 has arrived:%s\n",
191: cr, name, sizeof (hostname), hostname, cr);
192: fprintf(tp,"----%s\n", cr);
193: jkfprintf(tp, name, offset);
194: exit(0);
195: }
196:
197: jkfprintf(tp, name, offset)
198: register FILE *tp;
199: {
200: register FILE *fi;
201: register int linecnt, charcnt;
202: char line[BUFSIZ];
203: int inheader;
204:
205: dprintf("HERE %s's mail starting at %d\n",
206: name, offset);
207: if ((fi = fopen(name,"r")) == NULL) {
208: dprintf("Cant read the mail\n");
209: return;
210: }
211: fseek(fi, offset, L_SET);
212: /*
213: * Print the first 7 lines or 560 characters of the new mail
214: * (whichever comes first). Skip header crap other than
215: * From, Subject, To, and Date.
216: */
217: linecnt = 7;
218: charcnt = 560;
219: inheader = 1;
220: while (fgets(line, sizeof (line), fi) != NULL) {
221: register char *cp;
222: char *index();
223: int cnt;
224:
225: if (linecnt <= 0 || charcnt <= 0) {
226: fprintf(tp,"...more...%s\n", cr);
227: return;
228: }
229: if (strncmp(line, "From ", 5) == 0)
230: continue;
231: if (inheader && (line[0] == ' ' || line[0] == '\t'))
232: continue;
233: cp = index(line, ':');
234: if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp))
235: inheader = 0;
236: else
237: cnt = cp - line;
238: if (inheader &&
239: strncmp(line, "Date", cnt) &&
240: strncmp(line, "From", cnt) &&
241: strncmp(line, "Subject", cnt) &&
242: strncmp(line, "To", cnt))
243: continue;
244: cp = index(line, '\n');
245: if (cp)
246: *cp = '\0';
247: fprintf(tp,"%s%s\n", line, cr);
248: linecnt--, charcnt -= strlen(line);
249: }
250: fprintf(tp,"----%s\n", cr);
251: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.