19289Ssam #ifndef lint 2*16587Ssam static char sccsid[] = "@(#)comsat.c 4.11 (Berkeley) 06/09/84"; 39289Ssam #endif 46394Sroot 59289Ssam #include <sys/types.h> 69289Ssam #include <sys/socket.h> 713549Ssam #include <sys/stat.h> 813549Ssam #include <sys/wait.h> 9*16587Ssam #include <sys/file.h> 109289Ssam 119289Ssam #include <netinet/in.h> 129289Ssam 131513Sroot #include <stdio.h> 141513Sroot #include <sgtty.h> 151513Sroot #include <utmp.h> 161513Sroot #include <signal.h> 176394Sroot #include <errno.h> 189289Ssam #include <netdb.h> 191513Sroot 201513Sroot /* 211513Sroot * comsat 221513Sroot */ 2312746Ssam int debug = 0; 2412746Ssam #define dprintf if (debug) printf 251513Sroot 261513Sroot #define MAXUTMP 100 /* down from init */ 271513Sroot 289878Ssam struct sockaddr_in sin = { AF_INET }; 296394Sroot extern errno; 306394Sroot 31*16587Ssam char hostname[32]; 321513Sroot struct utmp utmp[100]; 331513Sroot int nutmp; 341513Sroot int uf; 351513Sroot unsigned utmpmtime; /* last modification time for utmp */ 361513Sroot int onalrm(); 37*16587Ssam int reapchildren(); 3816367Skarels long lastmsgtime; 391513Sroot 4016367Skarels #define MAXIDLE 120 411513Sroot #define NAMLEN (sizeof (uts[0].ut_name) + 1) 421513Sroot 431513Sroot main(argc, argv) 4416367Skarels int argc; 4516367Skarels char *argv[]; 461513Sroot { 4716367Skarels register int cc; 481513Sroot char buf[BUFSIZ]; 4916367Skarels char msgbuf[100]; 5016367Skarels struct sockaddr_in from; 5116367Skarels int fromlen; 521513Sroot 5316367Skarels /* verify proper invocation */ 5416367Skarels fromlen = sizeof (from); 5516367Skarels if (getsockname(0, &from, &fromlen) < 0) { 5616367Skarels fprintf(stderr, "%s: ", argv[0]); 5716367Skarels perror("getsockname"); 5816367Skarels _exit(1); 5916367Skarels } 6016367Skarels chdir("/usr/spool/mail"); 6116367Skarels if ((uf = open("/etc/utmp",0)) < 0) { 6216367Skarels perror("/etc/utmp"); 6316367Skarels (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0); 649289Ssam exit(1); 659289Ssam } 6616367Skarels lastmsgtime = time(0); 67*16587Ssam gethostname(hostname, sizeof (hostname)); 681513Sroot onalrm(); 6913022Ssam signal(SIGALRM, onalrm); 7013022Ssam signal(SIGTTOU, SIG_IGN); 71*16587Ssam signal(SIGCHLD, reapchildren); 726394Sroot for (;;) { 7316367Skarels cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0); 746394Sroot if (cc <= 0) { 756394Sroot if (errno != EINTR) 766394Sroot sleep(1); 776394Sroot errno = 0; 786394Sroot continue; 791513Sroot } 8016367Skarels sigblock(1<<SIGALRM); 816394Sroot msgbuf[cc] = 0; 8216367Skarels lastmsgtime = time(0); 836394Sroot mailfor(msgbuf); 8416367Skarels sigsetmask(0); 851513Sroot } 861513Sroot } 871513Sroot 88*16587Ssam reapchildren() 89*16587Ssam { 90*16587Ssam 91*16587Ssam while (wait3((struct wait *)0, WNOHANG, (struct rusage *)0) > 0) 92*16587Ssam ; 93*16587Ssam } 94*16587Ssam 951513Sroot onalrm() 961513Sroot { 971513Sroot struct stat statbf; 981513Sroot struct utmp *utp; 991513Sroot 10016367Skarels if (time(0) - lastmsgtime >= MAXIDLE) 10116367Skarels exit(1); 1021513Sroot dprintf("alarm\n"); 1031513Sroot alarm(15); 1041513Sroot fstat(uf,&statbf); 1051513Sroot if (statbf.st_mtime > utmpmtime) { 1061513Sroot dprintf(" changed\n"); 1071513Sroot utmpmtime = statbf.st_mtime; 1081513Sroot lseek(uf, 0, 0); 1091513Sroot nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp); 1101513Sroot } else 1111513Sroot dprintf(" ok\n"); 1121513Sroot } 1131513Sroot 1141513Sroot mailfor(name) 1151513Sroot char *name; 1161513Sroot { 1171513Sroot register struct utmp *utp = &utmp[nutmp]; 1181513Sroot register char *cp; 1191513Sroot char *rindex(); 1201513Sroot int offset; 1211513Sroot 1221513Sroot dprintf("mailfor %s\n", name); 1231513Sroot cp = name; 1241513Sroot while (*cp && *cp != '@') 1251513Sroot cp++; 1261513Sroot if (*cp == 0) { 1271513Sroot dprintf("bad format\n"); 1281513Sroot return; 1291513Sroot } 1301513Sroot *cp = 0; 1311513Sroot offset = atoi(cp+1); 1321513Sroot while (--utp >= utmp) 1331513Sroot if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name))) 134*16587Ssam notify(utp, offset); 1351513Sroot } 1361513Sroot 1371513Sroot char *cr; 1381513Sroot 1391513Sroot notify(utp, offset) 1401513Sroot register struct utmp *utp; 1411513Sroot { 1421513Sroot FILE *tp; 1431513Sroot struct sgttyb gttybuf; 144*16587Ssam char tty[20], name[sizeof (utmp[0].ut_name) + 1]; 1451513Sroot struct stat stb; 1461513Sroot 1471513Sroot strcpy(tty, "/dev/"); 1481513Sroot strncat(tty, utp->ut_line, sizeof(utp->ut_line)); 1491513Sroot dprintf("notify %s on %s\n", utp->ut_name, tty); 1501513Sroot if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) { 1511513Sroot dprintf("wrong mode\n"); 1521513Sroot return; 1531513Sroot } 154*16587Ssam if (fork()) 155*16587Ssam return; 156*16587Ssam signal(SIGALRM, SIG_DFL); 157*16587Ssam alarm(30); 1581513Sroot if ((tp = fopen(tty,"w")) == 0) { 1591513Sroot dprintf("fopen failed\n"); 160*16587Ssam exit(-1); 1611513Sroot } 16212746Ssam ioctl(fileno(tp), TIOCGETP, >tybuf); 1631513Sroot cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r"; 1641513Sroot strncpy(name, utp->ut_name, sizeof (utp->ut_name)); 165*16587Ssam name[sizeof (name) - 1] = '\0'; 16612746Ssam fprintf(tp,"%s\n\007New mail for %s@%s\007 has arrived:%s\n", 16712746Ssam cr, name, hostname, cr); 1681513Sroot fprintf(tp,"----%s\n", cr); 1691513Sroot jkfprintf(tp, name, offset); 170*16587Ssam exit(0); 1711513Sroot } 1721513Sroot 1731513Sroot jkfprintf(tp, name, offset) 1741513Sroot register FILE *tp; 1751513Sroot { 1761513Sroot register FILE *fi; 1771513Sroot register int linecnt, charcnt; 17812746Ssam char line[BUFSIZ]; 17913783Ssam int inheader; 1801513Sroot 1811513Sroot dprintf("HERE %s's mail starting at %d\n", 1821513Sroot name, offset); 1831513Sroot if ((fi = fopen(name,"r")) == NULL) { 1841513Sroot dprintf("Cant read the mail\n"); 1851513Sroot return; 1861513Sroot } 187*16587Ssam fseek(fi, offset, L_SET); 18812746Ssam /* 18912746Ssam * Print the first 7 lines or 560 characters of the new mail 19012746Ssam * (whichever comes first). Skip header crap other than 19113783Ssam * From, Subject, To, and Date. 19212746Ssam */ 1931513Sroot linecnt = 7; 1941513Sroot charcnt = 560; 19513783Ssam inheader = 1; 19612746Ssam while (fgets(line, sizeof (line), fi) != NULL) { 19712746Ssam register char *cp; 19812746Ssam char *index(); 19913783Ssam int cnt; 2001513Sroot 20112746Ssam if (linecnt <= 0 || charcnt <= 0) { 2021513Sroot fprintf(tp,"...more...%s\n", cr); 20313022Ssam return; 2041513Sroot } 20513783Ssam if (strncmp(line, "From ", 5) == 0) 20613783Ssam continue; 20713783Ssam if (inheader && (line[0] == ' ' || line[0] == '\t')) 20813783Ssam continue; 20912746Ssam cp = index(line, ':'); 21013783Ssam if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp)) 21113783Ssam inheader = 0; 21213783Ssam else 21313783Ssam cnt = cp - line; 21413783Ssam if (inheader && 21513783Ssam strncmp(line, "Date", cnt) && 21613783Ssam strncmp(line, "From", cnt) && 21713783Ssam strncmp(line, "Subject", cnt) && 21813783Ssam strncmp(line, "To", cnt)) 21912746Ssam continue; 22012746Ssam cp = index(line, '\n'); 22112746Ssam if (cp) 22212746Ssam *cp = '\0'; 22312746Ssam fprintf(tp,"%s%s\n", line, cr); 22412746Ssam linecnt--, charcnt -= strlen(line); 2251513Sroot } 22612746Ssam fprintf(tp,"----%s\n", cr); 2271513Sroot } 228