|
|
1.1 root 1: /*
2: * fancied up comsat program.....
3: */
4:
5: #ifndef lint
6: static char *rcsid_comsat_c = "$Header: comsat.c,v 10.3 86/02/01 15:18:47 tony Rel $";
7: #endif lint
8:
9: #define XWIND
10: #define SHORTSWEET
11:
12: #ifndef lint
13: static char sccsid[] = "@(#)comsat.c 4.12 (Berkeley) 8/1/84";
14: #endif
15:
16: #ifndef XWIND
17: #include <sys/types.h>
18: #include <sys/socket.h>
19: #else
20: #include <X/Xlib.h>
21: #include <ttyent.h>
22: #include <pwd.h>
23: char *indexs();
24: extern char **environ;
25: #endif
26: #include <sys/stat.h>
27: #include <sys/wait.h>
28: #include <sys/file.h>
29:
30: #include <netinet/in.h>
31:
32: #include <stdio.h>
33: #include <sgtty.h>
34: #include <utmp.h>
35: #include <signal.h>
36: #include <errno.h>
37: #include <netdb.h>
38: #include <syslog.h>
39:
40: char *index(), *rindex();
41:
42: /*
43: * comsat
44: */
45: int debug = 0;
46: #define dprintf if (debug) printf
47:
48: #define MAXUTMP 100 /* down from init */
49:
50: struct sockaddr_in sin = { AF_INET };
51: extern errno;
52:
53: char hostname[32];
54: struct utmp utmp[100];
55: int nutmp;
56: int uf;
57: unsigned utmpmtime; /* last modification time for utmp */
58: int onalrm();
59: int reapchildren();
60: long lastmsgtime;
61:
62: #define MAXIDLE 120
63: #define NAMLEN (sizeof (uts[0].ut_name) + 1)
64:
65: main(argc, argv)
66: int argc;
67: char *argv[];
68: {
69: register int cc;
70: char buf[BUFSIZ];
71: char msgbuf[100];
72: struct sockaddr_in from;
73: int fromlen;
74:
75: /* verify proper invocation */
76: fromlen = sizeof (from);
77: if (getsockname(0, &from, &fromlen) < 0) {
78: fprintf(stderr, "%s: ", argv[0]);
79: perror("getsockname");
80: _exit(1);
81: }
82: chdir("/usr/spool/mail");
83: if ((uf = open("/etc/utmp",0)) < 0) {
84: openlog("comsat", 0, 0);
85: syslog(LOG_ERR, "/etc/utmp: %m");
86: (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
87: exit(1);
88: }
89: lastmsgtime = time(0);
90: gethostname(hostname, sizeof (hostname));
91: onalrm();
92: signal(SIGALRM, onalrm);
93: signal(SIGTTOU, SIG_IGN);
94: signal(SIGCHLD, reapchildren);
95: for (;;) {
96: cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
97: if (cc <= 0) {
98: if (errno != EINTR)
99: sleep(1);
100: errno = 0;
101: continue;
102: }
103: sigblock(1<<SIGALRM);
104: msgbuf[cc] = 0;
105: lastmsgtime = time(0);
106: mailfor(msgbuf);
107: sigsetmask(0);
108: }
109: }
110:
111: reapchildren()
112: {
113:
114: while (wait3((struct wait *)0, WNOHANG, (struct rusage *)0) > 0)
115: ;
116: }
117:
118: onalrm()
119: {
120: struct stat statbf;
121: struct utmp *utp;
122:
123: if (time(0) - lastmsgtime >= MAXIDLE)
124: exit(0);
125: dprintf("alarm\n");
126: alarm(15);
127: fstat(uf, &statbf);
128: if (statbf.st_mtime > utmpmtime) {
129: dprintf(" changed\n");
130: utmpmtime = statbf.st_mtime;
131: lseek(uf, 0, 0);
132: nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp);
133: } else
134: dprintf(" ok\n");
135: }
136:
137: mailfor(name)
138: char *name;
139: {
140: register struct utmp *utp = &utmp[nutmp];
141: register char *cp;
142: int offset;
143:
144: dprintf("mailfor %s\n", name);
145: cp = name;
146: while (*cp && *cp != '@')
147: cp++;
148: if (*cp == 0) {
149: dprintf("bad format\n");
150: return;
151: }
152: *cp = 0;
153: offset = atoi(cp+1);
154: while (--utp >= utmp)
155: if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
156: notify(utp, offset);
157: }
158:
159: char *cr;
160:
161: notify(utp, offset)
162: register struct utmp *utp;
163: {
164: int fd, flags, n, err, msglen;
165: struct sgttyb gttybuf;
166: char tty[sizeof (utmp[0].ut_line) + 6], msgbuf[BUFSIZ];
167: char name[sizeof (utmp[0].ut_name) + 1];
168: struct stat stb;
169: #ifdef XWIND
170: struct ttyent *te;
171: char *s;
172: char dname[260];
173: #endif
174:
175: strcpy(tty, "/dev/");
176: strncat(tty, utp->ut_line, sizeof(utp->ut_line));
177: dprintf("notify %s on %s\n", utp->ut_name, tty);
178: if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) {
179: dprintf("wrong mode\n");
180: return;
181: }
182: strncpy(name, utp->ut_name, sizeof (utp->ut_name));
183: name[sizeof (name) - 1] = '\0';
184: #ifdef XWIND
185: te = getttynam(tty+5);
186: if ((s = indexs(te->ty_getty, "xterm")) &&
187: (s = indexs(s, " -L ")) &&
188: (s = index(s, ':'))) {
189: while (*(--s) != ' ') ;
190: s++;
191: if (*s == ':') {
192: gethostname(dname, sizeof (dname));
193: strcat(dname, s);
194: } else
195: strcpy(dname, s);
196: Xprintf(msgbuf, name, offset);
197: if (fork())
198: return;
199: Xnotify(name, dname, msgbuf);
200: }
201: #endif
202: if ((fd = open(tty, O_WRONLY|O_NDELAY)) < 0) {
203: dprintf("%s: open failed\n", tty);
204: return;
205: }
206: if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
207: dprintf("fcntl(F_GETFL) failed %d\n", errno);
208: return;
209: }
210: ioctl(fd, TIOCGETP, >tybuf);
211: cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r";
212: #ifdef SHORTSWEET
213: sprintf(msgbuf, "%s\n\007New mail from ", cr);
214: #else
215: sprintf(msgbuf, "%s\n\007New mail for %s@%s\007 has arrived:%s\n",
216: cr, name, hostname, cr);
217: #endif
218: jkfprintf(msgbuf+strlen(msgbuf), name, offset);
219: if (fcntl(fd, F_SETFL, flags | FNDELAY) == -1)
220: goto oldway;
221: msglen = strlen(msgbuf);
222: n = write(fd, msgbuf, msglen);
223: err = errno;
224: (void) fcntl(fd, F_SETFL, flags);
225: (void) close(fd);
226: if (n == msglen)
227: return;
228: if (err != EWOULDBLOCK) {
229: dprintf("write failed %d\n", errno);
230: return;
231: }
232: oldway:
233: if (fork()) {
234: (void) close(fd);
235: return;
236: }
237: signal(SIGALRM, SIG_DFL);
238: alarm(30);
239: (void) write(fd, msgbuf, msglen);
240: exit(0);
241: }
242:
243: #ifdef SHORTSWEET
244: jkfprintf(mp, name, offset)
245: register char *mp;
246: {
247: register FILE *fi;
248: char line[BUFSIZ];
249:
250: dprintf("HERE %s's mail starting at %d\n", name, offset);
251:
252: if ((fi = fopen(name, "r")) == NULL) {
253: dprintf("Cant read the mail\n");
254: return;
255: }
256: fseek(fi, offset, L_SET);
257: /*
258: * put the contents of the From: line into mp buffer
259: */
260: while (fgets(line, sizeof (line), fi) != NULL) {
261: register char *cp;
262:
263: if (strncmp (line, "From:", 5) != 0)
264: continue;
265: cp = index(line, '\n');
266: if (cp)
267: *cp = '\0';
268: for (cp = line+5; (*cp == ' ' || *cp == '\t'); cp++);
269: sprintf(mp, "%s%s\n", cp, cr);
270: return;
271: }
272: /* didn't find the From: line */
273: sprintf (mp, "???%s\n", cr);
274: }
275: #else
276: jkfprintf(mp, name, offset)
277: register char *mp;
278: {
279: register FILE *fi;
280: register int linecnt, charcnt;
281: char line[BUFSIZ];
282: int inheader;
283:
284: dprintf("HERE %s's mail starting at %d\n", name, offset);
285:
286: if ((fi = fopen(name, "r")) == NULL) {
287: dprintf("Cant read the mail\n");
288: return;
289: }
290: fseek(fi, offset, L_SET);
291: /*
292: * Print the first 7 lines or 560 characters of the new mail
293: * (whichever comes first). Skip header crap other than
294: * From, Subject, To, and Date.
295: */
296: linecnt = 7;
297: charcnt = 560;
298: inheader = 1;
299: while (fgets(line, sizeof (line), fi) != NULL) {
300: register char *cp;
301: int cnt;
302:
303: if (linecnt <= 0 || charcnt <= 0) {
304: sprintf(mp, "...more...%s\n", cr);
305: mp += strlen(mp);
306: return;
307: }
308: if (strncmp(line, "From ", 5) == 0)
309: continue;
310: if (inheader && (line[0] == ' ' || line[0] == '\t'))
311: continue;
312: cp = index(line, ':');
313: if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp))
314: inheader = 0;
315: else
316: cnt = cp - line;
317: if (inheader &&
318: strncmp(line, "Date", cnt) &&
319: strncmp(line, "From", cnt) &&
320: strncmp(line, "Subject", cnt) &&
321: strncmp(line, "To", cnt))
322: continue;
323: cp = index(line, '\n');
324: if (cp)
325: *cp = '\0';
326: sprintf(mp, "%s%s\n", line, cr);
327: mp += strlen(mp);
328: linecnt--, charcnt -= strlen(line);
329: }
330: sprintf(mp, "----%s\n", cr);
331: mp += strlen(mp);
332: }
333: #endif
334:
335: #ifdef XWIND
336: char *indexs(s1, s2)
337: register char *s1, *s2;
338: {
339: register int z = strlen(s2);
340: while (*s1 && strncmp(s1, s2, z))
341: s1++;
342: return(s1);
343: }
344:
345: Xprintf(mp, name, offset)
346: register char *mp;
347: {
348: register FILE *fi;
349: char line[BUFSIZ];
350:
351: dprintf("HERE %s's mail starting at %d\n", name, offset);
352:
353: sprintf(mp, "You have new mail.");
354: if ((fi = fopen(name, "r")) == NULL) {
355: dprintf("Cant read the mail\n");
356: return;
357: }
358: fseek(fi, offset, L_SET);
359: /*
360: * put the contents of the From: line into mp buffer
361: */
362: while (fgets(line, sizeof (line), fi) != NULL) {
363: register char *cp;
364:
365: if (strncmp (line, "From:", 5) != 0)
366: continue;
367: cp = index(line, '\n');
368: if (cp)
369: *cp = '\0';
370: for (cp = line+5; (*cp == ' ' || *cp == '\t'); cp++);
371: sprintf(mp, "Mail from %s", cp);
372: break;
373: }
374: fclose(fi);
375: }
376:
377: short cursor[] = {0x0000, 0x7ffe, 0x4fc2, 0x4ffe, 0x7ffe,
378: 0x7ffe, 0x781e, 0x7ffe , 0x7ffe, 0x0000};
379:
380: Xnotify (name, dname, notice)
381: char *name;
382: char *dname;
383: char *notice;
384: {
385: struct passwd *pwent;
386: char *envbuf[2];
387: char homebuf[280];
388: Display *dpy;
389: WindowInfo winfo;
390: FontInfo finfo;
391: Font font;
392: int width, height;
393: Window w;
394: XEvent rep;
395: int timeout = 0;
396: int reverse = 0;
397: int bwidth = 2;
398: int inner = 2;
399: int vertical = 2;
400: int volume = 0;
401: int forepix = BlackPixel;
402: int backpix = WhitePixel;
403: int brdrpix = BlackPixel;
404: int mouspix = BlackPixel;
405: char *option;
406: char *font_name = "8x13";
407: char *fore_color = NULL;
408: char *back_color = NULL;
409: char *brdr_color = NULL;
410: char *mous_color = NULL;
411: Color cdef;
412:
413: if (!XOpenDisplay(dname))
414: exit(0);
415: if (pwent = getpwnam(name)) {
416: strcpy(homebuf, "HOME=");
417: strcat(homebuf, pwent->pw_dir);
418: envbuf[0] = homebuf;
419: envbuf[1] = NULL;
420: environ = envbuf;
421: if (option = XGetDefault("biff", "BodyFont"))
422: font_name = option;
423: fore_color = XGetDefault("biff", "Foreground");
424: back_color = XGetDefault("biff", "Background");
425: brdr_color = XGetDefault("biff", "Border");
426: mous_color = XGetDefault("biff", "Mouse");
427: if (option = XGetDefault("biff", "BorderWidth"))
428: bwidth = atoi(option);
429: if (option = XGetDefault("biff", "InternalBorder"))
430: inner = atoi(option);
431: if (option = XGetDefault("biff", "Timeout"))
432: timeout = atoi(option);
433: if (option = XGetDefault("biff", "Volume"))
434: volume = atoi(option);
435: if (option = XGetDefault("biff", "Offset"))
436: vertical = atoi(option);
437: if ((option = XGetDefault("biff", "ReverseVideo")) &&
438: strcmp(option, "on") == 0)
439: reverse = 1;
440: }
441: if (reverse) {
442: brdrpix = backpix;
443: backpix = forepix;
444: forepix = brdrpix;
445: mouspix = forepix;
446: }
447:
448: if ((font = XGetFont(font_name)) == NULL)
449: exit(0);
450: if (DisplayCells() > 2) {
451: if (back_color && XParseColor(back_color, &cdef) &&
452: XGetHardwareColor(&cdef))
453: backpix = cdef.pixel;
454: if (fore_color && XParseColor(fore_color, &cdef) &&
455: XGetHardwareColor(&cdef))
456: forepix = cdef.pixel;
457: if (brdr_color && XParseColor(brdr_color, &cdef) &&
458: XGetHardwareColor(&cdef))
459: brdrpix = cdef.pixel;
460: if (mous_color && XParseColor(mous_color, &cdef) &&
461: XGetHardwareColor(&cdef))
462: mouspix = cdef.pixel;
463: }
464: XQueryFont(font, &finfo);
465: XQueryWindow (RootWindow, &winfo);
466: width = XQueryWidth (notice, font) + (inner << 1);
467: height = finfo.height + (inner << 1);
468: if (vertical < 0)
469: vertical += winfo.height - height - (bwidth << 1);
470: w = XCreateWindow(RootWindow, (winfo.width - width - (bwidth << 1)) / 2,
471: vertical, width, height, bwidth,
472: XMakeTile(brdrpix), XMakeTile(backpix));
473: XStoreName(w, notice);
474: XSelectInput(w, ButtonPressed|ButtonReleased|ExposeWindow);
475: XDefineCursor(w, XCreateCursor(16, 10, cursor, NULL, 7, 5,
476: mouspix, backpix, GXcopy));
477: XMapWindow(w);
478: XFeep(volume);
479: if (timeout > 0) {
480: signal(SIGALRM, exit);
481: alarm(timeout * 60);
482: }
483: if (inner) inner--;
484: while (1) {
485: XText(w, inner, inner, notice, strlen(notice),
486: font, forepix, backpix);
487: XNextEvent(&rep);
488: if (rep.type == ButtonPressed)
489: exit(0);
490: }
491: }
492: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.