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