Annotation of 43BSD/contrib/X/comsat/comsat.c, revision 1.1.1.1

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, &gttybuf);
                    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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.