Annotation of 43BSD/etc/comsat.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)comsat.c   5.5 (Berkeley) 10/24/85";
        !            15: #endif not lint
        !            16: 
        !            17: #include <sys/types.h>
        !            18: #include <sys/socket.h>
        !            19: #include <sys/stat.h>
        !            20: #include <sys/wait.h>
        !            21: #include <sys/file.h>
        !            22: 
        !            23: #include <netinet/in.h>
        !            24: 
        !            25: #include <stdio.h>
        !            26: #include <sgtty.h>
        !            27: #include <utmp.h>
        !            28: #include <signal.h>
        !            29: #include <errno.h>
        !            30: #include <netdb.h>
        !            31: #include <syslog.h>
        !            32: 
        !            33: /*
        !            34:  * comsat
        !            35:  */
        !            36: int    debug = 0;
        !            37: #define        dprintf if (debug) printf
        !            38: 
        !            39: struct sockaddr_in sin = { AF_INET };
        !            40: extern errno;
        !            41: 
        !            42: char   hostname[32];
        !            43: struct utmp *utmp = NULL;
        !            44: int    nutmp;
        !            45: int    uf;
        !            46: unsigned utmpmtime = 0;                        /* last modification time for utmp */
        !            47: unsigned utmpsize = 0;                 /* last malloced size for utmp */
        !            48: int    onalrm();
        !            49: int    reapchildren();
        !            50: long   lastmsgtime;
        !            51: char   *malloc(), *realloc();
        !            52: 
        !            53: #define        MAXIDLE 120
        !            54: #define NAMLEN (sizeof (uts[0].ut_name) + 1)
        !            55: 
        !            56: main(argc, argv)
        !            57:        int argc;
        !            58:        char *argv[];
        !            59: {
        !            60:        register int cc;
        !            61:        char buf[BUFSIZ];
        !            62:        char msgbuf[100];
        !            63:        struct sockaddr_in from;
        !            64:        int fromlen;
        !            65: 
        !            66:        /* verify proper invocation */
        !            67:        fromlen = sizeof (from);
        !            68:        if (getsockname(0, &from, &fromlen) < 0) {
        !            69:                fprintf(stderr, "%s: ", argv[0]);
        !            70:                perror("getsockname");
        !            71:                _exit(1);
        !            72:        }
        !            73:        chdir("/usr/spool/mail");
        !            74:        if ((uf = open("/etc/utmp",0)) < 0) {
        !            75:                openlog("comsat", 0, LOG_DAEMON);
        !            76:                syslog(LOG_ERR, "/etc/utmp: %m");
        !            77:                (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
        !            78:                exit(1);
        !            79:        }
        !            80:        lastmsgtime = time(0);
        !            81:        gethostname(hostname, sizeof (hostname));
        !            82:        onalrm();
        !            83:        signal(SIGALRM, onalrm);
        !            84:        signal(SIGTTOU, SIG_IGN);
        !            85:        signal(SIGCHLD, reapchildren);
        !            86:        for (;;) {
        !            87:                cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
        !            88:                if (cc <= 0) {
        !            89:                        if (errno != EINTR)
        !            90:                                sleep(1);
        !            91:                        errno = 0;
        !            92:                        continue;
        !            93:                }
        !            94:                sigblock(sigmask(SIGALRM));
        !            95:                msgbuf[cc] = 0;
        !            96:                lastmsgtime = time(0);
        !            97:                mailfor(msgbuf);
        !            98:                sigsetmask(0);
        !            99:        }
        !           100: }
        !           101: 
        !           102: reapchildren()
        !           103: {
        !           104: 
        !           105:        while (wait3((struct wait *)0, WNOHANG, (struct rusage *)0) > 0)
        !           106:                ;
        !           107: }
        !           108: 
        !           109: onalrm()
        !           110: {
        !           111:        struct stat statbf;
        !           112: 
        !           113:        if (time(0) - lastmsgtime >= MAXIDLE)
        !           114:                exit(0);
        !           115:        dprintf("alarm\n");
        !           116:        alarm(15);
        !           117:        fstat(uf, &statbf);
        !           118:        if (statbf.st_mtime > utmpmtime) {
        !           119:                dprintf(" changed\n");
        !           120:                utmpmtime = statbf.st_mtime;
        !           121:                if (statbf.st_size > utmpsize) {
        !           122:                        utmpsize = statbf.st_size + 10 * sizeof(struct utmp);
        !           123:                        if (utmp)
        !           124:                                utmp = (struct utmp *)realloc(utmp, utmpsize);
        !           125:                        else
        !           126:                                utmp = (struct utmp *)malloc(utmpsize);
        !           127:                        if (! utmp) {
        !           128:                                dprintf("malloc failed\n");
        !           129:                                exit(1);
        !           130:                        }
        !           131:                }
        !           132:                lseek(uf, 0, 0);
        !           133:                nutmp = read(uf,utmp,statbf.st_size)/sizeof(struct utmp);
        !           134:        } else
        !           135:                dprintf(" ok\n");
        !           136: }
        !           137: 
        !           138: mailfor(name)
        !           139:        char *name;
        !           140: {
        !           141:        register struct utmp *utp = &utmp[nutmp];
        !           142:        register char *cp;
        !           143:        char *rindex();
        !           144:        int offset;
        !           145: 
        !           146:        dprintf("mailfor %s\n", name);
        !           147:        cp = name;
        !           148:        while (*cp && *cp != '@')
        !           149:                cp++;
        !           150:        if (*cp == 0) {
        !           151:                dprintf("bad format\n");
        !           152:                return;
        !           153:        }
        !           154:        *cp = 0;
        !           155:        offset = atoi(cp+1);
        !           156:        while (--utp >= utmp)
        !           157:                if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
        !           158:                        notify(utp, offset);
        !           159: }
        !           160: 
        !           161: char   *cr;
        !           162: 
        !           163: notify(utp, offset)
        !           164:        register struct utmp *utp;
        !           165: {
        !           166:        FILE *tp;
        !           167:        struct sgttyb gttybuf;
        !           168:        char tty[20], name[sizeof (utmp[0].ut_name) + 1];
        !           169:        struct stat stb;
        !           170: 
        !           171:        strcpy(tty, "/dev/");
        !           172:        strncat(tty, utp->ut_line, sizeof(utp->ut_line));
        !           173:        dprintf("notify %s on %s\n", utp->ut_name, tty);
        !           174:        if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) {
        !           175:                dprintf("wrong mode\n");
        !           176:                return;
        !           177:        }
        !           178:        if (fork())
        !           179:                return;
        !           180:        signal(SIGALRM, SIG_DFL);
        !           181:        alarm(30);
        !           182:        if ((tp = fopen(tty,"w")) == 0) {
        !           183:                dprintf("fopen failed\n");
        !           184:                exit(-1);
        !           185:        }
        !           186:        ioctl(fileno(tp), TIOCGETP, &gttybuf);
        !           187:        cr = (gttybuf.sg_flags&CRMOD) && !(gttybuf.sg_flags&RAW) ? "" : "\r";
        !           188:        strncpy(name, utp->ut_name, sizeof (utp->ut_name));
        !           189:        name[sizeof (name) - 1] = '\0';
        !           190:        fprintf(tp,"%s\n\007New mail for %s@%.*s\007 has arrived:%s\n",
        !           191:            cr, name, sizeof (hostname), hostname, cr);
        !           192:        fprintf(tp,"----%s\n", cr);
        !           193:        jkfprintf(tp, name, offset);
        !           194:        exit(0);
        !           195: }
        !           196: 
        !           197: jkfprintf(tp, name, offset)
        !           198:        register FILE *tp;
        !           199: {
        !           200:        register FILE *fi;
        !           201:        register int linecnt, charcnt;
        !           202:        char line[BUFSIZ];
        !           203:        int inheader;
        !           204: 
        !           205:        dprintf("HERE %s's mail starting at %d\n",
        !           206:            name, offset);
        !           207:        if ((fi = fopen(name,"r")) == NULL) {
        !           208:                dprintf("Cant read the mail\n");
        !           209:                return;
        !           210:        }
        !           211:        fseek(fi, offset, L_SET);
        !           212:        /* 
        !           213:         * Print the first 7 lines or 560 characters of the new mail
        !           214:         * (whichever comes first).  Skip header crap other than
        !           215:         * From, Subject, To, and Date.
        !           216:         */
        !           217:        linecnt = 7;
        !           218:        charcnt = 560;
        !           219:        inheader = 1;
        !           220:        while (fgets(line, sizeof (line), fi) != NULL) {
        !           221:                register char *cp;
        !           222:                char *index();
        !           223:                int cnt;
        !           224: 
        !           225:                if (linecnt <= 0 || charcnt <= 0) {  
        !           226:                        fprintf(tp,"...more...%s\n", cr);
        !           227:                        return;
        !           228:                }
        !           229:                if (strncmp(line, "From ", 5) == 0)
        !           230:                        continue;
        !           231:                if (inheader && (line[0] == ' ' || line[0] == '\t'))
        !           232:                        continue;
        !           233:                cp = index(line, ':');
        !           234:                if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp))
        !           235:                        inheader = 0;
        !           236:                else
        !           237:                        cnt = cp - line;
        !           238:                if (inheader &&
        !           239:                    strncmp(line, "Date", cnt) &&
        !           240:                    strncmp(line, "From", cnt) &&
        !           241:                    strncmp(line, "Subject", cnt) &&
        !           242:                    strncmp(line, "To", cnt))
        !           243:                        continue;
        !           244:                cp = index(line, '\n');
        !           245:                if (cp)
        !           246:                        *cp = '\0';
        !           247:                fprintf(tp,"%s%s\n", line, cr);
        !           248:                linecnt--, charcnt -= strlen(line);
        !           249:        }
        !           250:        fprintf(tp,"----%s\n", cr);
        !           251: }

unix.superglobalmegacorp.com

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