|
|
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),>tybuf); ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.