|
|
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: #define MAXUTMP 100 /* down from init */
26:
27: struct sockaddr_in sin = { AF_INET };
28: extern errno;
29:
30: struct utmp utmp[100];
31: int nutmp;
32: int uf;
33: unsigned utmpmtime; /* last modification time for utmp */
34: int onalrm();
35: struct servent *sp;
36:
37: #define NAMLEN (sizeof (uts[0].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: sin.sin_port = sp->s_port;
67: if (bind(s, &sin, sizeof (sin), 0) < 0) {
68: perror("bind");
69: exit(1);
70: }
71: for (;;) {
72: char msgbuf[100];
73: int cc;
74:
75: cc = recv(s, msgbuf, sizeof (msgbuf) - 1, 0);
76: if (cc <= 0) {
77: if (errno != EINTR)
78: sleep(1);
79: errno = 0;
80: continue;
81: }
82: msgbuf[cc] = 0;
83: mailfor(msgbuf);
84: }
85: }
86:
87: onalrm()
88: {
89: struct stat statbf;
90: struct utmp *utp;
91:
92: dprintf("alarm\n");
93: alarm(15);
94: fstat(uf,&statbf);
95: if (statbf.st_mtime > utmpmtime) {
96: dprintf(" changed\n");
97: utmpmtime = statbf.st_mtime;
98: lseek(uf, 0, 0);
99: nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp);
100: } else
101: dprintf(" ok\n");
102: }
103:
104: mailfor(name)
105: char *name;
106: {
107: register struct utmp *utp = &utmp[nutmp];
108: register char *cp;
109: char *rindex();
110: int offset;
111:
112: dprintf("mailfor %s\n", name);
113: cp = name;
114: while (*cp && *cp != '@')
115: cp++;
116: if (*cp == 0) {
117: dprintf("bad format\n");
118: return;
119: }
120: *cp = 0;
121: offset = atoi(cp+1);
122: while (--utp >= utmp)
123: if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
124: if (fork() == 0) {
125: signal(SIGALRM, SIG_DFL);
126: alarm(30);
127: notify(utp, offset), exit(0);
128: } else
129: while (wait3(0, WNOHANG, 0) > 0)
130: continue;
131: }
132:
133: char *cr;
134:
135: notify(utp, offset)
136: register struct utmp *utp;
137: {
138: FILE *tp;
139: struct sgttyb gttybuf;
140: char tty[20], hostname[32];
141: char name[sizeof (utmp[0].ut_name) + 1];
142: struct stat stb;
143:
144: strcpy(tty, "/dev/");
145: strncat(tty, utp->ut_line, sizeof(utp->ut_line));
146: dprintf("notify %s on %s\n", utp->ut_name, tty);
147: if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) {
148: dprintf("wrong mode\n");
149: return;
150: }
151: if ((tp = fopen(tty,"w")) == 0) {
152: dprintf("fopen failed\n");
153: return;
154: }
155: ioctl(fileno(tp), TIOCGETP, >tybuf);
156: cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r";
157: gethostname(hostname, sizeof (hostname));
158: strncpy(name, utp->ut_name, sizeof (utp->ut_name));
159: name[sizeof (name) - 1] = 0;
160: fprintf(tp,"%s\n\007New mail for %s@%s\007 has arrived:%s\n",
161: cr, name, hostname, cr);
162: fprintf(tp,"----%s\n", cr);
163: jkfprintf(tp, name, offset);
164: fclose(tp);
165: }
166:
167: jkfprintf(tp, name, offset)
168: register FILE *tp;
169: {
170: register FILE *fi;
171: register int linecnt, charcnt;
172: char line[BUFSIZ];
173: int inheader;
174:
175: dprintf("HERE %s's mail starting at %d\n",
176: name, offset);
177: if ((fi = fopen(name,"r")) == NULL) {
178: dprintf("Cant read the mail\n");
179: return;
180: }
181: fseek(fi, offset, 0);
182: /*
183: * Print the first 7 lines or 560 characters of the new mail
184: * (whichever comes first). Skip header crap other than
185: * From, Subject, To, and Date.
186: */
187: linecnt = 7;
188: charcnt = 560;
189: inheader = 1;
190: while (fgets(line, sizeof (line), fi) != NULL) {
191: register char *cp;
192: char *index();
193: int cnt;
194:
195: if (linecnt <= 0 || charcnt <= 0) {
196: fprintf(tp,"...more...%s\n", cr);
197: return;
198: }
199: if (strncmp(line, "From ", 5) == 0)
200: continue;
201: if (inheader && (line[0] == ' ' || line[0] == '\t'))
202: continue;
203: cp = index(line, ':');
204: if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp))
205: inheader = 0;
206: else
207: cnt = cp - line;
208: if (inheader &&
209: strncmp(line, "Date", cnt) &&
210: strncmp(line, "From", cnt) &&
211: strncmp(line, "Subject", cnt) &&
212: strncmp(line, "To", cnt))
213: continue;
214: cp = index(line, '\n');
215: if (cp)
216: *cp = '\0';
217: fprintf(tp,"%s%s\n", line, cr);
218: linecnt--, charcnt -= strlen(line);
219: }
220: fprintf(tp,"----%s\n", cr);
221: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.