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