Annotation of 43BSD/etc/comsat.c, revision 1.1.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.