|
|
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.