Annotation of cci/usr/src/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: struct sockaddr_in sin = { AF_INET };
                     26: extern errno;
                     27: 
                     28: struct utmp *utmp = 0;
                     29: int    nutmp;
                     30: int    uf;
                     31: unsigned utmpmtime;                    /* last modification time for utmp */
                     32: int    onalrm();
                     33: int    free();
                     34: char   *malloc();
                     35: struct servent *sp;
                     36: 
                     37: #define NAMLEN (sizeof (utmp->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:        if (argc > 1)
                     67:                sp->s_port = atoi(argv[1]);
                     68:        sin.sin_port = sp->s_port;
                     69:        if (bind(s, &sin, sizeof (sin), 0) < 0) {
                     70:                perror("bind");
                     71:                exit(1);
                     72:        }
                     73:        for (;;) {
                     74:                char msgbuf[100];
                     75:                int cc;
                     76: 
                     77:                cc = recv(s, msgbuf, sizeof (msgbuf) - 1, 0);
                     78:                if (cc <= 0) {
                     79:                        if (errno != EINTR)
                     80:                                sleep(1);
                     81:                        errno = 0;
                     82:                        continue;
                     83:                }
                     84:                msgbuf[cc] = 0;
                     85:                mailfor(msgbuf);
                     86:        }
                     87: }
                     88: 
                     89: int    old_size = 0;
                     90: 
                     91: onalrm()
                     92: {
                     93:        struct stat statbf;
                     94:        int nretries;
                     95: 
                     96:        dprintf("alarm\n");
                     97:        alarm(15);
                     98:        fstat(uf,&statbf);
                     99:        if (statbf.st_mtime > utmpmtime) {
                    100:                dprintf("changed\n");
                    101:                utmpmtime = statbf.st_mtime;
                    102:                lseek(uf, 0, 0);
                    103:                if (statbf.st_size > old_size) {
                    104:                        if (utmp)
                    105:                                free((char *)utmp);
                    106:                        old_size = statbf.st_size;
                    107:                        nretries = 0;
                    108: retry:
                    109:                        utmp = (struct utmp *)malloc(statbf.st_size);
                    110:                }
                    111:                if (utmp == 0) {
                    112:                    if (++nretries > 20) {
                    113:                        fprintf(stderr,"comsat: can't get buffer for utmp table\n");
                    114:                        exit(1);
                    115:                    }
                    116:                    goto retry;
                    117:                }
                    118:                nutmp=read(uf,utmp,statbf.st_size)/sizeof(struct utmp);
                    119:                dprintf("utmpsize %d nutmp %d\n", statbf.st_size, nutmp);
                    120:        } else
                    121:                dprintf("ok\n");
                    122: }
                    123: 
                    124: mailfor(name)
                    125:        char *name;
                    126: {
                    127:        register struct utmp *utp;
                    128:        register char *cp;
                    129:        char *rindex();
                    130:        int offset, i;
                    131: 
                    132:        utp =  utmp + nutmp;    /* seeks to end of utmp area */
                    133: 
                    134:        dprintf("mailfor %s\n", name);
                    135:        cp = name;
                    136:        while (*cp && *cp != '@') 
                    137:                cp++;
                    138:        if (*cp == 0) {
                    139:                dprintf("bad format\n");
                    140:                return;
                    141:        }
                    142:        *cp = 0;
                    143:        offset = atoi(cp+1);
                    144:        while (--utp >= utmp) { 
                    145:                if (!strncmp(utp->ut_name, name, sizeof(utp->ut_name))) {
                    146:                        if (fork() == 0) {
                    147:                                signal(SIGALRM, SIG_DFL);
                    148:                                alarm(30);
                    149:                                notify(utp, offset), exit(0);
                    150:                        } else
                    151:                                while (wait(0) > 0)
                    152:                                        continue;
                    153:                }
                    154:        }
                    155: }
                    156: 
                    157: char *cr;
                    158: 
                    159: notify(utp, offset)
                    160:        register struct utmp *utp;
                    161: {
                    162:        FILE *tp;
                    163:        struct sgttyb gttybuf;
                    164:        char tty[20], hostname[32];
                    165:        char name[sizeof (utmp->ut_name) + 1];
                    166:        struct stat stb;
                    167: 
                    168:        strcpy(tty, "/dev/");
                    169:        strncat(tty, utp->ut_line, sizeof(utp->ut_line));
                    170:        dprintf("notify %s on %s\n", utp->ut_name, tty);
                    171:        if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) {
                    172:                dprintf("wrong tty mode %o\n", stb.st_mode);
                    173:                return;
                    174:        }
                    175:        if ((tp = fopen(tty,"w")) == 0) {
                    176:                dprintf("fopen failed\n");
                    177:                return;
                    178:        }
                    179:        ioctl(fileno(tp), TIOCGETP, &gttybuf);
                    180:        cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r";
                    181:        gethostname(hostname, sizeof (hostname));
                    182:        strncpy(name, utp->ut_name, sizeof (utp->ut_name));
                    183:        name[sizeof (name) - 1] = 0;
                    184:        fprintf(tp,"%s\n\007New mail for %s@%s\007 has arrived:%s\n",
                    185:            cr, name, hostname, cr);
                    186:        fprintf(tp,"----%s\n", cr);
                    187:        jkfprintf(tp, name, offset);
                    188:        fclose(tp);
                    189: }
                    190: 
                    191: jkfprintf(tp, name, offset)
                    192:        register FILE *tp;
                    193: {
                    194:        register FILE *fi;
                    195:        register int linecnt, charcnt;
                    196:        char line[BUFSIZ];
                    197:        int inheader;
                    198: 
                    199:        dprintf("HERE %s's mail starting at %d\n",
                    200:            name, offset);
                    201:        if ((fi = fopen(name,"r")) == NULL) {
                    202:                dprintf("Cant read the mail\n");
                    203:                return;
                    204:        }
                    205:        fseek(fi, offset, 0);
                    206:        /* 
                    207:         * Print the first 7 lines or 560 characters of the new mail
                    208:         * (whichever comes first).  Skip header crap other than
                    209:         * From, Subject, To, and Date.
                    210:         */
                    211:        linecnt = 7;
                    212:        charcnt = 560;
                    213:        inheader = 1;
                    214:        while (fgets(line, sizeof (line), fi) != NULL) {
                    215:                register char *cp;
                    216:                char *index();
                    217:                int cnt;
                    218: 
                    219:                if (linecnt <= 0 || charcnt <= 0) {  
                    220:                        fprintf(tp,"...more...%s\n", cr);
                    221:                        return;
                    222:                }
                    223:                if (strncmp(line, "From ", 5) == 0)
                    224:                        continue;
                    225:                if (inheader && (line[0] == ' ' || line[0] == '\t'))
                    226:                        continue;
                    227:                cp = index(line, ':');
                    228:                if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp))
                    229:                        inheader = 0;
                    230:                else
                    231:                        cnt = cp - line;
                    232:                if (inheader &&
                    233:                    strncmp(line, "Date", cnt) &&
                    234:                    strncmp(line, "From", cnt) &&
                    235:                    strncmp(line, "Subject", cnt) &&
                    236:                    strncmp(line, "To", cnt))
                    237:                        continue;
                    238:                cp = index(line, '\n');
                    239:                if (cp)
                    240:                        *cp = '\0';
                    241:                fprintf(tp,"%s%s\n", line, cr);
                    242:                linecnt--, charcnt -= strlen(line);
                    243:        }
                    244:        fprintf(tp,"----%s\n", cr);
                    245: }

unix.superglobalmegacorp.com

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