19289Ssam #ifndef lint 2*22545Sbloom static char sccsid[] = "@(#)comsat.c 4.14 (Berkeley) 06/06/85"; 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 279878Ssam struct sockaddr_in sin = { AF_INET }; 286394Sroot extern errno; 296394Sroot 3016587Ssam char hostname[32]; 31*22545Sbloom struct utmp *utmp = NULL; 321513Sroot int nutmp; 331513Sroot int uf; 34*22545Sbloom unsigned utmpmtime = 0; /* last modification time for utmp */ 35*22545Sbloom unsigned utmpsize = 0; /* last malloced size for utmp */ 361513Sroot int onalrm(); 3716587Ssam int reapchildren(); 3816367Skarels long lastmsgtime; 39*22545Sbloom char *malloc(), *realloc(); 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 10116367Skarels if (time(0) - lastmsgtime >= MAXIDLE) 10216808Sralph exit(0); 1031513Sroot dprintf("alarm\n"); 1041513Sroot alarm(15); 10516808Sralph fstat(uf, &statbf); 1061513Sroot if (statbf.st_mtime > utmpmtime) { 1071513Sroot dprintf(" changed\n"); 1081513Sroot utmpmtime = statbf.st_mtime; 109*22545Sbloom if (statbf.st_size > utmpsize) { 110*22545Sbloom utmpsize = statbf.st_size + 10 * sizeof(struct utmp); 111*22545Sbloom if (utmp) 112*22545Sbloom utmp = (struct utmp *)realloc(utmp, utmpsize); 113*22545Sbloom else 114*22545Sbloom utmp = (struct utmp *)malloc(utmpsize); 115*22545Sbloom if (! utmp) { 116*22545Sbloom dprintf("malloc failed\n"); 117*22545Sbloom exit(1); 118*22545Sbloom } 119*22545Sbloom } 1201513Sroot lseek(uf, 0, 0); 121*22545Sbloom nutmp = read(uf,utmp,statbf.st_size)/sizeof(struct utmp); 1221513Sroot } else 1231513Sroot dprintf(" ok\n"); 1241513Sroot } 1251513Sroot 1261513Sroot mailfor(name) 1271513Sroot char *name; 1281513Sroot { 1291513Sroot register struct utmp *utp = &utmp[nutmp]; 1301513Sroot register char *cp; 1311513Sroot char *rindex(); 1321513Sroot int offset; 1331513Sroot 1341513Sroot dprintf("mailfor %s\n", name); 1351513Sroot cp = name; 1361513Sroot while (*cp && *cp != '@') 1371513Sroot cp++; 1381513Sroot if (*cp == 0) { 1391513Sroot dprintf("bad format\n"); 1401513Sroot return; 1411513Sroot } 1421513Sroot *cp = 0; 1431513Sroot offset = atoi(cp+1); 1441513Sroot while (--utp >= utmp) 1451513Sroot if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name))) 14616587Ssam notify(utp, offset); 1471513Sroot } 1481513Sroot 14916808Sralph char *cr; 1501513Sroot 1511513Sroot notify(utp, offset) 1521513Sroot register struct utmp *utp; 1531513Sroot { 15417189Sralph FILE *tp; 1551513Sroot struct sgttyb gttybuf; 15617189Sralph char tty[20], name[sizeof (utmp[0].ut_name) + 1]; 1571513Sroot struct stat stb; 1581513Sroot 1591513Sroot strcpy(tty, "/dev/"); 1601513Sroot strncat(tty, utp->ut_line, sizeof(utp->ut_line)); 1611513Sroot dprintf("notify %s on %s\n", utp->ut_name, tty); 1621513Sroot if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) { 1631513Sroot dprintf("wrong mode\n"); 1641513Sroot return; 1651513Sroot } 16617189Sralph if (fork()) 16716587Ssam return; 16817189Sralph signal(SIGALRM, SIG_DFL); 16917189Sralph alarm(30); 17017189Sralph if ((tp = fopen(tty,"w")) == 0) { 17117189Sralph dprintf("fopen failed\n"); 17217189Sralph exit(-1); 1731513Sroot } 17417189Sralph ioctl(fileno(tp), TIOCGETP, >tybuf); 1751513Sroot cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r"; 1761513Sroot strncpy(name, utp->ut_name, sizeof (utp->ut_name)); 17716587Ssam name[sizeof (name) - 1] = '\0'; 17817189Sralph fprintf(tp,"%s\n\007New mail for %s@%s\007 has arrived:%s\n", 17912746Ssam cr, name, hostname, cr); 18017189Sralph fprintf(tp,"----%s\n", cr); 18117189Sralph jkfprintf(tp, name, offset); 18216587Ssam exit(0); 1831513Sroot } 1841513Sroot 18517189Sralph jkfprintf(tp, name, offset) 18617189Sralph register FILE *tp; 1871513Sroot { 1881513Sroot register FILE *fi; 1891513Sroot register int linecnt, charcnt; 19012746Ssam char line[BUFSIZ]; 19113783Ssam int inheader; 1921513Sroot 19317189Sralph dprintf("HERE %s's mail starting at %d\n", 19417189Sralph name, offset); 19517189Sralph if ((fi = fopen(name,"r")) == NULL) { 1961513Sroot dprintf("Cant read the mail\n"); 1971513Sroot return; 1981513Sroot } 19916587Ssam fseek(fi, offset, L_SET); 20012746Ssam /* 20112746Ssam * Print the first 7 lines or 560 characters of the new mail 20212746Ssam * (whichever comes first). Skip header crap other than 20313783Ssam * From, Subject, To, and Date. 20412746Ssam */ 2051513Sroot linecnt = 7; 2061513Sroot charcnt = 560; 20713783Ssam inheader = 1; 20812746Ssam while (fgets(line, sizeof (line), fi) != NULL) { 20912746Ssam register char *cp; 21012746Ssam char *index(); 21113783Ssam int cnt; 2121513Sroot 21312746Ssam if (linecnt <= 0 || charcnt <= 0) { 21417189Sralph fprintf(tp,"...more...%s\n", cr); 21513022Ssam return; 2161513Sroot } 21713783Ssam if (strncmp(line, "From ", 5) == 0) 21813783Ssam continue; 21913783Ssam if (inheader && (line[0] == ' ' || line[0] == '\t')) 22013783Ssam continue; 22112746Ssam cp = index(line, ':'); 22213783Ssam if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp)) 22313783Ssam inheader = 0; 22413783Ssam else 22513783Ssam cnt = cp - line; 22613783Ssam if (inheader && 22713783Ssam strncmp(line, "Date", cnt) && 22813783Ssam strncmp(line, "From", cnt) && 22913783Ssam strncmp(line, "Subject", cnt) && 23013783Ssam strncmp(line, "To", cnt)) 23112746Ssam continue; 23212746Ssam cp = index(line, '\n'); 23312746Ssam if (cp) 23412746Ssam *cp = '\0'; 23517189Sralph fprintf(tp,"%s%s\n", line, cr); 23612746Ssam linecnt--, charcnt -= strlen(line); 2371513Sroot } 23817189Sralph fprintf(tp,"----%s\n", cr); 2391513Sroot } 240