Annotation of 41BSD/cmd/comsat.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)comsat.c    4.2 (Berkeley) 10/20/80";
                      2: #include <stdio.h>
                      3: #include <sys/mx.h>
                      4: #include <sgtty.h>
                      5: #include <utmp.h>
                      6: #include <sys/types.h>
                      7: #include <stat.h>
                      8: #include <wait.h>
                      9: #include <signal.h>
                     10: 
                     11: /*
                     12:  * comsat
                     13:  */
                     14: #define        dprintf if (0) printf
                     15: int    xd;
                     16: 
                     17: struct  ctp {
                     18:        short   ctrl;
                     19:        short   ctrlarg;
                     20:        struct  sgttyb ctrlv;
                     21: } ctp;
                     22: 
                     23: #define MAXUTMP 100            /* down from init */
                     24: 
                     25: struct utmp utmp[100];
                     26: int    nutmp;
                     27: int    uf;
                     28: unsigned utmpmtime;                    /* last modification time for utmp */
                     29: int    onalrm();
                     30: 
                     31: #define NAMLEN (sizeof (uts[0].ut_name) + 1)
                     32: 
                     33: main(argc, argv)
                     34: char **argv;
                     35: {
                     36:        register cc;
                     37:        char buf[BUFSIZ];
                     38: 
                     39:        if (fork())
                     40:                exit();
                     41:        chdir("/usr/spool/mail");
                     42:        if((uf = open("/etc/utmp",0)) < 0)
                     43:                perror("/etc/utmp"), exit(1);
                     44:        while (fork())
                     45:                wait(0);
                     46:        sleep(10);
                     47:        onalrm();
                     48:        sigset(SIGALRM, onalrm);
                     49:        sigignore(SIGTTOU);
                     50:        unlink("/dev/mail");
                     51:        xd = mpx("/dev/mail", 0666);
                     52:        if (xd < 0) {
                     53:                close(2);
                     54:                open("/dev/console", 1);
                     55:                perror("/dev/mail");
                     56:                exit(1);
                     57:        }
                     58:        while((cc=read(xd, buf, BUFSIZ)) >= 0) {
                     59:                dprintf("0: got %d bytes\n", cc);
                     60:                unpack(buf, cc);
                     61:        }
                     62:        _exit(1);
                     63: }
                     64: 
                     65: #define        skip(rp, c)     ((struct rh *)(((char *)rp)+c))
                     66: 
                     67: unpack(rp, cc)
                     68:        register struct rh *rp;
                     69: {
                     70:        register struct rh *end;
                     71:        int i;
                     72: 
                     73:        i = 0;
                     74:        end = skip(rp, cc);
                     75:        while (rp < end) {
                     76:                dprintf("%d: ", ++i);
                     77:                if (rp->count==0) {
                     78:                        dprintf("%d byte control message\n", rp->ccount);
                     79:                        control(rp->index, rp+1, rp->ccount);
                     80:                } else {
                     81:                        dprintf("%*.*s\n", rp->count, rp->count, rp+1);
                     82:                        sighold(SIGALRM);
                     83:                        mailfor(rp+1);
                     84:                        sigrelse(SIGALRM);
                     85:                }
                     86:                rp->count += rp->ccount;
                     87:                if (rp->count & 1)
                     88:                        rp->count++;
                     89:                rp = skip(rp, rp->count);
                     90:                rp++;
                     91:        }
                     92: }
                     93: 
                     94: control(x, cb, cc)
                     95:        register char *cb;
                     96: {
                     97:        register char *end;
                     98:        int cmd;
                     99:        short *sp;
                    100:        struct wh or;
                    101: 
                    102:        end = cb + cc;
                    103:        cmd = *cb++;
                    104:        sp = (short *)cb+1;
                    105:        switch (cmd) {
                    106: 
                    107:        case M_WATCH:
                    108:                dprintf("attach %x, uid %d\n", x, *sp);
                    109:                attach(x, xd);
                    110:                break;
                    111: 
                    112:        case M_CLOSE:
                    113:                sp = (short *)cb;
                    114:                dprintf("detach %x, uid %d\n", x, *sp);
                    115:                detach(x, xd);
                    116:                break;
                    117: 
                    118:        case M_IOCTL:
                    119:                dprintf("ioctl %x\n", x);
                    120:                or.index = x;
                    121:                or.count = 0;
                    122:                or.ccount = sizeof ctp;
                    123:                or.data = (char *) &ctp.ctrlarg;
                    124:                ctp.ctrlarg = M_IOANS;
                    125:                write(xd, &or, sizeof or);
                    126:                break;
                    127:                
                    128:        default:
                    129:                dprintf("unknown command %d\n", cmd);
                    130:                return;
                    131:        }
                    132: }
                    133: 
                    134: onalrm()
                    135: {
                    136:        struct stat statbf;
                    137:        struct utmp *utp;
                    138: 
                    139:        dprintf("alarm\n");
                    140:        alarm(15);
                    141:        fstat(uf,&statbf);
                    142:        if (statbf.st_mtime > utmpmtime) {
                    143:                dprintf(" changed\n");
                    144:                utmpmtime = statbf.st_mtime;
                    145:                lseek(uf, 0, 0);
                    146:                nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp);
                    147:        } else
                    148:                dprintf(" ok\n");
                    149: }
                    150: 
                    151: mailfor(name)
                    152:        char *name;
                    153: {
                    154:        register struct utmp *utp = &utmp[nutmp];
                    155:        register char *cp;
                    156:        char *rindex();
                    157:        int offset;
                    158: 
                    159:        dprintf("mailfor %s\n", name);
                    160:        cp = name;
                    161:        while (*cp && *cp != '@')
                    162:                cp++;
                    163:        if (*cp == 0) {
                    164:                dprintf("bad format\n");
                    165:                return;
                    166:        }
                    167:        *cp = 0;
                    168:        offset = atoi(cp+1);
                    169:        while (--utp >= utmp)
                    170:                if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
                    171:                        if (fork() == 0) {
                    172:                                signal(SIGALRM, SIG_DFL);
                    173:                                alarm(30);
                    174:                                notify(utp, offset), exit(0);
                    175:                        } else
                    176:                                while (wait3(0, WNOHANG, 0) > 0)
                    177:                                        continue;
                    178: }
                    179: 
                    180: char *cr;
                    181: 
                    182: notify(utp, offset)
                    183:        register struct utmp *utp;
                    184: {
                    185:        FILE *tp;
                    186:        struct sgttyb gttybuf;
                    187:        char tty[20];
                    188:        char name[sizeof (utmp[0].ut_name) + 1];
                    189:        struct stat stb;
                    190: 
                    191:        strcpy(tty, "/dev/");
                    192:        strncat(tty, utp->ut_line, sizeof(utp->ut_line));
                    193:        dprintf("notify %s on %s\n", utp->ut_name, tty);
                    194:        if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) {
                    195:                dprintf("wrong mode\n");
                    196:                return;
                    197:        }
                    198:        if ((tp = fopen(tty,"w")) == 0) {
                    199:                dprintf("fopen failed\n");
                    200:                return;
                    201:        }
                    202:        gtty(fileno(tp),&gttybuf);
                    203:        cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r";
                    204:        strncpy(name, utp->ut_name, sizeof (utp->ut_name));
                    205:        name[sizeof (name) - 1] = 0;
                    206:        fprintf(tp,"%s\n\007New mail for %s\007 has arrived:%s\n",
                    207:            cr, name, cr);
                    208:        fprintf(tp,"----%s\n", cr);
                    209:        jkfprintf(tp, name, offset);
                    210:         fclose(tp);
                    211: }
                    212: 
                    213: jkfprintf(tp, name, offset)
                    214:        register FILE *tp;
                    215: {
                    216:        register FILE *fi;
                    217:        register int linecnt, charcnt;
                    218: 
                    219:        dprintf("HERE %s's mail starting at %d\n",
                    220:            name, offset);
                    221:        if ((fi = fopen(name,"r")) == NULL) {
                    222:                dprintf("Cant read the mail\n");
                    223:                return;
                    224:        }
                    225:        fseek(fi, offset, 0);
                    226:        linecnt = 7;
                    227:        charcnt = 560;
                    228:        /* 
                    229:         * print the first 7 lines or 560 characters of the new mail
                    230:         * (whichever comes first)
                    231:         */
                    232:        for (;;) {
                    233:                register ch;
                    234: 
                    235:                if ((ch = getc(fi)) == EOF) {  
                    236:                        fprintf(tp,"----%s\n", cr);
                    237:                        break;
                    238:                }
                    239:                if (ch == '\n') {  
                    240:                        fprintf(tp,"%s\n", cr);
                    241:                        if (linecnt-- < 0) {  
                    242:                                fprintf(tp,"...more...%s\n", cr);
                    243:                                break;
                    244:                        }
                    245:                } else if(linecnt <= 0) {  
                    246:                        fprintf(tp,"...more...%s\n", cr);
                    247:                        break;
                    248:                } else
                    249:                        putc(ch, tp);
                    250:                if (charcnt-- == 0) {   
                    251:                        fprintf(tp, "%s\n", cr);
                    252:                        break;
                    253:                }
                    254:        }
                    255: }

unix.superglobalmegacorp.com

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