Annotation of 42BSD/etc/comsat.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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