|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: char copyright[] = ! 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)comsat.c 5.5 (Berkeley) 10/24/85"; ! 15: #endif not lint ! 16: ! 17: #include <sys/types.h> ! 18: #include <sys/socket.h> ! 19: #include <sys/stat.h> ! 20: #include <sys/wait.h> ! 21: #include <sys/file.h> ! 22: ! 23: #include <netinet/in.h> ! 24: ! 25: #include <stdio.h> ! 26: #include <sgtty.h> ! 27: #include <utmp.h> ! 28: #include <signal.h> ! 29: #include <errno.h> ! 30: #include <netdb.h> ! 31: #include <syslog.h> ! 32: ! 33: /* ! 34: * comsat ! 35: */ ! 36: int debug = 0; ! 37: #define dprintf if (debug) printf ! 38: ! 39: struct sockaddr_in sin = { AF_INET }; ! 40: extern errno; ! 41: ! 42: char hostname[32]; ! 43: struct utmp *utmp = NULL; ! 44: int nutmp; ! 45: int uf; ! 46: unsigned utmpmtime = 0; /* last modification time for utmp */ ! 47: unsigned utmpsize = 0; /* last malloced size for utmp */ ! 48: int onalrm(); ! 49: int reapchildren(); ! 50: long lastmsgtime; ! 51: char *malloc(), *realloc(); ! 52: ! 53: #define MAXIDLE 120 ! 54: #define NAMLEN (sizeof (uts[0].ut_name) + 1) ! 55: ! 56: main(argc, argv) ! 57: int argc; ! 58: char *argv[]; ! 59: { ! 60: register int cc; ! 61: char buf[BUFSIZ]; ! 62: char msgbuf[100]; ! 63: struct sockaddr_in from; ! 64: int fromlen; ! 65: ! 66: /* verify proper invocation */ ! 67: fromlen = sizeof (from); ! 68: if (getsockname(0, &from, &fromlen) < 0) { ! 69: fprintf(stderr, "%s: ", argv[0]); ! 70: perror("getsockname"); ! 71: _exit(1); ! 72: } ! 73: chdir("/usr/spool/mail"); ! 74: if ((uf = open("/etc/utmp",0)) < 0) { ! 75: openlog("comsat", 0, LOG_DAEMON); ! 76: syslog(LOG_ERR, "/etc/utmp: %m"); ! 77: (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0); ! 78: exit(1); ! 79: } ! 80: lastmsgtime = time(0); ! 81: gethostname(hostname, sizeof (hostname)); ! 82: onalrm(); ! 83: signal(SIGALRM, onalrm); ! 84: signal(SIGTTOU, SIG_IGN); ! 85: signal(SIGCHLD, reapchildren); ! 86: for (;;) { ! 87: cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0); ! 88: if (cc <= 0) { ! 89: if (errno != EINTR) ! 90: sleep(1); ! 91: errno = 0; ! 92: continue; ! 93: } ! 94: sigblock(sigmask(SIGALRM)); ! 95: msgbuf[cc] = 0; ! 96: lastmsgtime = time(0); ! 97: mailfor(msgbuf); ! 98: sigsetmask(0); ! 99: } ! 100: } ! 101: ! 102: reapchildren() ! 103: { ! 104: ! 105: while (wait3((struct wait *)0, WNOHANG, (struct rusage *)0) > 0) ! 106: ; ! 107: } ! 108: ! 109: onalrm() ! 110: { ! 111: struct stat statbf; ! 112: ! 113: if (time(0) - lastmsgtime >= MAXIDLE) ! 114: exit(0); ! 115: dprintf("alarm\n"); ! 116: alarm(15); ! 117: fstat(uf, &statbf); ! 118: if (statbf.st_mtime > utmpmtime) { ! 119: dprintf(" changed\n"); ! 120: utmpmtime = statbf.st_mtime; ! 121: if (statbf.st_size > utmpsize) { ! 122: utmpsize = statbf.st_size + 10 * sizeof(struct utmp); ! 123: if (utmp) ! 124: utmp = (struct utmp *)realloc(utmp, utmpsize); ! 125: else ! 126: utmp = (struct utmp *)malloc(utmpsize); ! 127: if (! utmp) { ! 128: dprintf("malloc failed\n"); ! 129: exit(1); ! 130: } ! 131: } ! 132: lseek(uf, 0, 0); ! 133: nutmp = read(uf,utmp,statbf.st_size)/sizeof(struct utmp); ! 134: } else ! 135: dprintf(" ok\n"); ! 136: } ! 137: ! 138: mailfor(name) ! 139: char *name; ! 140: { ! 141: register struct utmp *utp = &utmp[nutmp]; ! 142: register char *cp; ! 143: char *rindex(); ! 144: int offset; ! 145: ! 146: dprintf("mailfor %s\n", name); ! 147: cp = name; ! 148: while (*cp && *cp != '@') ! 149: cp++; ! 150: if (*cp == 0) { ! 151: dprintf("bad format\n"); ! 152: return; ! 153: } ! 154: *cp = 0; ! 155: offset = atoi(cp+1); ! 156: while (--utp >= utmp) ! 157: if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name))) ! 158: notify(utp, offset); ! 159: } ! 160: ! 161: char *cr; ! 162: ! 163: notify(utp, offset) ! 164: register struct utmp *utp; ! 165: { ! 166: FILE *tp; ! 167: struct sgttyb gttybuf; ! 168: char tty[20], name[sizeof (utmp[0].ut_name) + 1]; ! 169: struct stat stb; ! 170: ! 171: strcpy(tty, "/dev/"); ! 172: strncat(tty, utp->ut_line, sizeof(utp->ut_line)); ! 173: dprintf("notify %s on %s\n", utp->ut_name, tty); ! 174: if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) { ! 175: dprintf("wrong mode\n"); ! 176: return; ! 177: } ! 178: if (fork()) ! 179: return; ! 180: signal(SIGALRM, SIG_DFL); ! 181: alarm(30); ! 182: if ((tp = fopen(tty,"w")) == 0) { ! 183: dprintf("fopen failed\n"); ! 184: exit(-1); ! 185: } ! 186: ioctl(fileno(tp), TIOCGETP, >tybuf); ! 187: cr = (gttybuf.sg_flags&CRMOD) && !(gttybuf.sg_flags&RAW) ? "" : "\r"; ! 188: strncpy(name, utp->ut_name, sizeof (utp->ut_name)); ! 189: name[sizeof (name) - 1] = '\0'; ! 190: fprintf(tp,"%s\n\007New mail for %s@%.*s\007 has arrived:%s\n", ! 191: cr, name, sizeof (hostname), hostname, cr); ! 192: fprintf(tp,"----%s\n", cr); ! 193: jkfprintf(tp, name, offset); ! 194: exit(0); ! 195: } ! 196: ! 197: jkfprintf(tp, name, offset) ! 198: register FILE *tp; ! 199: { ! 200: register FILE *fi; ! 201: register int linecnt, charcnt; ! 202: char line[BUFSIZ]; ! 203: int inheader; ! 204: ! 205: dprintf("HERE %s's mail starting at %d\n", ! 206: name, offset); ! 207: if ((fi = fopen(name,"r")) == NULL) { ! 208: dprintf("Cant read the mail\n"); ! 209: return; ! 210: } ! 211: fseek(fi, offset, L_SET); ! 212: /* ! 213: * Print the first 7 lines or 560 characters of the new mail ! 214: * (whichever comes first). Skip header crap other than ! 215: * From, Subject, To, and Date. ! 216: */ ! 217: linecnt = 7; ! 218: charcnt = 560; ! 219: inheader = 1; ! 220: while (fgets(line, sizeof (line), fi) != NULL) { ! 221: register char *cp; ! 222: char *index(); ! 223: int cnt; ! 224: ! 225: if (linecnt <= 0 || charcnt <= 0) { ! 226: fprintf(tp,"...more...%s\n", cr); ! 227: return; ! 228: } ! 229: if (strncmp(line, "From ", 5) == 0) ! 230: continue; ! 231: if (inheader && (line[0] == ' ' || line[0] == '\t')) ! 232: continue; ! 233: cp = index(line, ':'); ! 234: if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp)) ! 235: inheader = 0; ! 236: else ! 237: cnt = cp - line; ! 238: if (inheader && ! 239: strncmp(line, "Date", cnt) && ! 240: strncmp(line, "From", cnt) && ! 241: strncmp(line, "Subject", cnt) && ! 242: strncmp(line, "To", cnt)) ! 243: continue; ! 244: cp = index(line, '\n'); ! 245: if (cp) ! 246: *cp = '\0'; ! 247: fprintf(tp,"%s%s\n", line, cr); ! 248: linecnt--, charcnt -= strlen(line); ! 249: } ! 250: fprintf(tp,"----%s\n", cr); ! 251: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.