19289Ssam #ifndef lint 2*17189Sralph static char sccsid[] = "@(#)comsat.c 4.13 (Berkeley) 09/13/84"; 39289Ssam #endif 46394Sroot 59289Ssam #include <sys/types.h> 69289Ssam #include <sys/socket.h> 713549Ssam #include <sys/stat.h> 813549Ssam #include <sys/wait.h> 916587Ssam #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> 1916808Sralph #include <syslog.h> 201513Sroot 211513Sroot /* 221513Sroot * comsat 231513Sroot */ 2412746Ssam int debug = 0; 2512746Ssam #define dprintf if (debug) printf 261513Sroot 271513Sroot #define MAXUTMP 100 /* down from init */ 281513Sroot 299878Ssam struct sockaddr_in sin = { AF_INET }; 306394Sroot extern errno; 316394Sroot 3216587Ssam char hostname[32]; 331513Sroot struct utmp utmp[100]; 341513Sroot int nutmp; 351513Sroot int uf; 361513Sroot unsigned utmpmtime; /* last modification time for utmp */ 371513Sroot int onalrm(); 3816587Ssam int reapchildren(); 3916367Skarels long lastmsgtime; 401513Sroot 4116367Skarels #define MAXIDLE 120 421513Sroot #define NAMLEN (sizeof (uts[0].ut_name) + 1) 431513Sroot 441513Sroot main(argc, argv) 4516367Skarels int argc; 4616367Skarels char *argv[]; 471513Sroot { 4816367Skarels register int cc; 491513Sroot char buf[BUFSIZ]; 5016367Skarels char msgbuf[100]; 5116367Skarels struct sockaddr_in from; 5216367Skarels int fromlen; 531513Sroot 5416367Skarels /* verify proper invocation */ 5516367Skarels fromlen = sizeof (from); 5616367Skarels if (getsockname(0, &from, &fromlen) < 0) { 5716367Skarels fprintf(stderr, "%s: ", argv[0]); 5816367Skarels perror("getsockname"); 5916367Skarels _exit(1); 6016367Skarels } 6116367Skarels chdir("/usr/spool/mail"); 6216367Skarels if ((uf = open("/etc/utmp",0)) < 0) { 6316808Sralph openlog("comsat", 0, 0); 6416808Sralph syslog(LOG_ERR, "/etc/utmp: %m"); 6516367Skarels (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0); 669289Ssam exit(1); 679289Ssam } 6816367Skarels lastmsgtime = time(0); 6916587Ssam gethostname(hostname, sizeof (hostname)); 701513Sroot onalrm(); 7113022Ssam signal(SIGALRM, onalrm); 7213022Ssam signal(SIGTTOU, SIG_IGN); 7316587Ssam signal(SIGCHLD, reapchildren); 746394Sroot for (;;) { 7516367Skarels cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0); 766394Sroot if (cc <= 0) { 776394Sroot if (errno != EINTR) 786394Sroot sleep(1); 796394Sroot errno = 0; 806394Sroot continue; 811513Sroot } 8216367Skarels sigblock(1<<SIGALRM); 836394Sroot msgbuf[cc] = 0; 8416367Skarels lastmsgtime = time(0); 856394Sroot mailfor(msgbuf); 8616367Skarels sigsetmask(0); 871513Sroot } 881513Sroot } 891513Sroot 9016587Ssam reapchildren() 9116587Ssam { 9216587Ssam 9316587Ssam while (wait3((struct wait *)0, WNOHANG, (struct rusage *)0) > 0) 9416587Ssam ; 9516587Ssam } 9616587Ssam 971513Sroot onalrm() 981513Sroot { 991513Sroot struct stat statbf; 1001513Sroot struct utmp *utp; 1011513Sroot 10216367Skarels if (time(0) - lastmsgtime >= MAXIDLE) 10316808Sralph exit(0); 1041513Sroot dprintf("alarm\n"); 1051513Sroot alarm(15); 10616808Sralph fstat(uf, &statbf); 1071513Sroot if (statbf.st_mtime > utmpmtime) { 1081513Sroot dprintf(" changed\n"); 1091513Sroot utmpmtime = statbf.st_mtime; 1101513Sroot lseek(uf, 0, 0); 1111513Sroot nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp); 1121513Sroot } else 1131513Sroot dprintf(" ok\n"); 1141513Sroot } 1151513Sroot 1161513Sroot mailfor(name) 1171513Sroot char *name; 1181513Sroot { 1191513Sroot register struct utmp *utp = &utmp[nutmp]; 1201513Sroot register char *cp; 1211513Sroot char *rindex(); 1221513Sroot int offset; 1231513Sroot 1241513Sroot dprintf("mailfor %s\n", name); 1251513Sroot cp = name; 1261513Sroot while (*cp && *cp != '@') 1271513Sroot cp++; 1281513Sroot if (*cp == 0) { 1291513Sroot dprintf("bad format\n"); 1301513Sroot return; 1311513Sroot } 1321513Sroot *cp = 0; 1331513Sroot offset = atoi(cp+1); 1341513Sroot while (--utp >= utmp) 1351513Sroot if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name))) 13616587Ssam notify(utp, offset); 1371513Sroot } 1381513Sroot 13916808Sralph char *cr; 1401513Sroot 1411513Sroot notify(utp, offset) 1421513Sroot register struct utmp *utp; 1431513Sroot { 144*17189Sralph FILE *tp; 1451513Sroot struct sgttyb gttybuf; 146*17189Sralph char tty[20], name[sizeof (utmp[0].ut_name) + 1]; 1471513Sroot struct stat stb; 1481513Sroot 1491513Sroot strcpy(tty, "/dev/"); 1501513Sroot strncat(tty, utp->ut_line, sizeof(utp->ut_line)); 1511513Sroot dprintf("notify %s on %s\n", utp->ut_name, tty); 1521513Sroot if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) { 1531513Sroot dprintf("wrong mode\n"); 1541513Sroot return; 1551513Sroot } 156*17189Sralph if (fork()) 15716587Ssam return; 158*17189Sralph signal(SIGALRM, SIG_DFL); 159*17189Sralph alarm(30); 160*17189Sralph if ((tp = fopen(tty,"w")) == 0) { 161*17189Sralph dprintf("fopen failed\n"); 162*17189Sralph exit(-1); 1631513Sroot } 164*17189Sralph ioctl(fileno(tp), TIOCGETP, >tybuf); 1651513Sroot cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r"; 1661513Sroot strncpy(name, utp->ut_name, sizeof (utp->ut_name)); 16716587Ssam name[sizeof (name) - 1] = '\0'; 168*17189Sralph fprintf(tp,"%s\n\007New mail for %s@%s\007 has arrived:%s\n", 16912746Ssam cr, name, hostname, cr); 170*17189Sralph fprintf(tp,"----%s\n", cr); 171*17189Sralph jkfprintf(tp, name, offset); 17216587Ssam exit(0); 1731513Sroot } 1741513Sroot 175*17189Sralph jkfprintf(tp, name, offset) 176*17189Sralph register FILE *tp; 1771513Sroot { 1781513Sroot register FILE *fi; 1791513Sroot register int linecnt, charcnt; 18012746Ssam char line[BUFSIZ]; 18113783Ssam int inheader; 1821513Sroot 183*17189Sralph dprintf("HERE %s's mail starting at %d\n", 184*17189Sralph name, offset); 185*17189Sralph if ((fi = fopen(name,"r")) == NULL) { 1861513Sroot dprintf("Cant read the mail\n"); 1871513Sroot return; 1881513Sroot } 18916587Ssam fseek(fi, offset, L_SET); 19012746Ssam /* 19112746Ssam * Print the first 7 lines or 560 characters of the new mail 19212746Ssam * (whichever comes first). Skip header crap other than 19313783Ssam * From, Subject, To, and Date. 19412746Ssam */ 1951513Sroot linecnt = 7; 1961513Sroot charcnt = 560; 19713783Ssam inheader = 1; 19812746Ssam while (fgets(line, sizeof (line), fi) != NULL) { 19912746Ssam register char *cp; 20012746Ssam char *index(); 20113783Ssam int cnt; 2021513Sroot 20312746Ssam if (linecnt <= 0 || charcnt <= 0) { 204*17189Sralph fprintf(tp,"...more...%s\n", cr); 20513022Ssam return; 2061513Sroot } 20713783Ssam if (strncmp(line, "From ", 5) == 0) 20813783Ssam continue; 20913783Ssam if (inheader && (line[0] == ' ' || line[0] == '\t')) 21013783Ssam continue; 21112746Ssam cp = index(line, ':'); 21213783Ssam if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp)) 21313783Ssam inheader = 0; 21413783Ssam else 21513783Ssam cnt = cp - line; 21613783Ssam if (inheader && 21713783Ssam strncmp(line, "Date", cnt) && 21813783Ssam strncmp(line, "From", cnt) && 21913783Ssam strncmp(line, "Subject", cnt) && 22013783Ssam strncmp(line, "To", cnt)) 22112746Ssam continue; 22212746Ssam cp = index(line, '\n'); 22312746Ssam if (cp) 22412746Ssam *cp = '\0'; 225*17189Sralph fprintf(tp,"%s%s\n", line, cr); 22612746Ssam linecnt--, charcnt -= strlen(line); 2271513Sroot } 228*17189Sralph fprintf(tp,"----%s\n", cr); 2291513Sroot } 230