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