19289Ssam #ifndef lint 2*16367Skarels static char sccsid[] = "@(#)comsat.c 4.10 (Berkeley) 04/11/84"; 39289Ssam #endif 46394Sroot 59289Ssam #include <sys/types.h> 69289Ssam #include <sys/socket.h> 713549Ssam #include <sys/stat.h> 813549Ssam #include <sys/wait.h> 99289Ssam 109289Ssam #include <netinet/in.h> 119289Ssam 121513Sroot #include <stdio.h> 131513Sroot #include <sgtty.h> 141513Sroot #include <utmp.h> 151513Sroot #include <signal.h> 166394Sroot #include <errno.h> 179289Ssam #include <netdb.h> 181513Sroot 191513Sroot /* 201513Sroot * comsat 211513Sroot */ 2212746Ssam int debug = 0; 2312746Ssam #define dprintf if (debug) printf 241513Sroot 251513Sroot #define MAXUTMP 100 /* down from init */ 261513Sroot 279878Ssam struct sockaddr_in sin = { AF_INET }; 286394Sroot extern errno; 296394Sroot 301513Sroot struct utmp utmp[100]; 311513Sroot int nutmp; 321513Sroot int uf; 331513Sroot unsigned utmpmtime; /* last modification time for utmp */ 341513Sroot int onalrm(); 35*16367Skarels long lastmsgtime; 361513Sroot 37*16367Skarels #define MAXIDLE 120 381513Sroot #define NAMLEN (sizeof (uts[0].ut_name) + 1) 391513Sroot 401513Sroot main(argc, argv) 41*16367Skarels int argc; 42*16367Skarels char *argv[]; 431513Sroot { 44*16367Skarels register int cc; 451513Sroot char buf[BUFSIZ]; 46*16367Skarels char msgbuf[100]; 47*16367Skarels struct sockaddr_in from; 48*16367Skarels int fromlen; 491513Sroot 50*16367Skarels /* verify proper invocation */ 51*16367Skarels fromlen = sizeof (from); 52*16367Skarels if (getsockname(0, &from, &fromlen) < 0) { 53*16367Skarels fprintf(stderr, "%s: ", argv[0]); 54*16367Skarels perror("getsockname"); 55*16367Skarels _exit(1); 56*16367Skarels } 57*16367Skarels chdir("/usr/spool/mail"); 58*16367Skarels if ((uf = open("/etc/utmp",0)) < 0) { 59*16367Skarels perror("/etc/utmp"); 60*16367Skarels (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0); 619289Ssam exit(1); 629289Ssam } 63*16367Skarels lastmsgtime = time(0); 641513Sroot onalrm(); 6513022Ssam signal(SIGALRM, onalrm); 6613022Ssam signal(SIGTTOU, SIG_IGN); 676394Sroot for (;;) { 68*16367Skarels cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0); 696394Sroot if (cc <= 0) { 706394Sroot if (errno != EINTR) 716394Sroot sleep(1); 726394Sroot errno = 0; 736394Sroot continue; 741513Sroot } 75*16367Skarels sigblock(1<<SIGALRM); 766394Sroot msgbuf[cc] = 0; 77*16367Skarels lastmsgtime = time(0); 786394Sroot mailfor(msgbuf); 79*16367Skarels sigsetmask(0); 801513Sroot } 811513Sroot } 821513Sroot 831513Sroot onalrm() 841513Sroot { 851513Sroot struct stat statbf; 861513Sroot struct utmp *utp; 871513Sroot 88*16367Skarels if (time(0) - lastmsgtime >= MAXIDLE) 89*16367Skarels exit(1); 901513Sroot dprintf("alarm\n"); 911513Sroot alarm(15); 921513Sroot fstat(uf,&statbf); 931513Sroot if (statbf.st_mtime > utmpmtime) { 941513Sroot dprintf(" changed\n"); 951513Sroot utmpmtime = statbf.st_mtime; 961513Sroot lseek(uf, 0, 0); 971513Sroot nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp); 981513Sroot } else 991513Sroot dprintf(" ok\n"); 1001513Sroot } 1011513Sroot 1021513Sroot mailfor(name) 1031513Sroot char *name; 1041513Sroot { 1051513Sroot register struct utmp *utp = &utmp[nutmp]; 1061513Sroot register char *cp; 1071513Sroot char *rindex(); 1081513Sroot int offset; 1091513Sroot 1101513Sroot dprintf("mailfor %s\n", name); 1111513Sroot cp = name; 1121513Sroot while (*cp && *cp != '@') 1131513Sroot cp++; 1141513Sroot if (*cp == 0) { 1151513Sroot dprintf("bad format\n"); 1161513Sroot return; 1171513Sroot } 1181513Sroot *cp = 0; 1191513Sroot offset = atoi(cp+1); 1201513Sroot while (--utp >= utmp) 1211513Sroot if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name))) 1221513Sroot if (fork() == 0) { 1231513Sroot signal(SIGALRM, SIG_DFL); 1241513Sroot alarm(30); 1251513Sroot notify(utp, offset), exit(0); 1261513Sroot } else 1271513Sroot while (wait3(0, WNOHANG, 0) > 0) 1281513Sroot continue; 1291513Sroot } 1301513Sroot 1311513Sroot char *cr; 1321513Sroot 1331513Sroot notify(utp, offset) 1341513Sroot register struct utmp *utp; 1351513Sroot { 1361513Sroot FILE *tp; 1371513Sroot struct sgttyb gttybuf; 13812746Ssam char tty[20], hostname[32]; 1391513Sroot char name[sizeof (utmp[0].ut_name) + 1]; 1401513Sroot struct stat stb; 1411513Sroot 1421513Sroot strcpy(tty, "/dev/"); 1431513Sroot strncat(tty, utp->ut_line, sizeof(utp->ut_line)); 1441513Sroot dprintf("notify %s on %s\n", utp->ut_name, tty); 1451513Sroot if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) { 1461513Sroot dprintf("wrong mode\n"); 1471513Sroot return; 1481513Sroot } 1491513Sroot if ((tp = fopen(tty,"w")) == 0) { 1501513Sroot dprintf("fopen failed\n"); 1511513Sroot return; 1521513Sroot } 15312746Ssam ioctl(fileno(tp), TIOCGETP, >tybuf); 1541513Sroot cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r"; 15512746Ssam gethostname(hostname, sizeof (hostname)); 1561513Sroot strncpy(name, utp->ut_name, sizeof (utp->ut_name)); 1571513Sroot name[sizeof (name) - 1] = 0; 15812746Ssam fprintf(tp,"%s\n\007New mail for %s@%s\007 has arrived:%s\n", 15912746Ssam cr, name, hostname, cr); 1601513Sroot fprintf(tp,"----%s\n", cr); 1611513Sroot jkfprintf(tp, name, offset); 16212746Ssam fclose(tp); 1631513Sroot } 1641513Sroot 1651513Sroot jkfprintf(tp, name, offset) 1661513Sroot register FILE *tp; 1671513Sroot { 1681513Sroot register FILE *fi; 1691513Sroot register int linecnt, charcnt; 17012746Ssam char line[BUFSIZ]; 17113783Ssam int inheader; 1721513Sroot 1731513Sroot dprintf("HERE %s's mail starting at %d\n", 1741513Sroot name, offset); 1751513Sroot if ((fi = fopen(name,"r")) == NULL) { 1761513Sroot dprintf("Cant read the mail\n"); 1771513Sroot return; 1781513Sroot } 1791513Sroot fseek(fi, offset, 0); 18012746Ssam /* 18112746Ssam * Print the first 7 lines or 560 characters of the new mail 18212746Ssam * (whichever comes first). Skip header crap other than 18313783Ssam * From, Subject, To, and Date. 18412746Ssam */ 1851513Sroot linecnt = 7; 1861513Sroot charcnt = 560; 18713783Ssam inheader = 1; 18812746Ssam while (fgets(line, sizeof (line), fi) != NULL) { 18912746Ssam register char *cp; 19012746Ssam char *index(); 19113783Ssam int cnt; 1921513Sroot 19312746Ssam if (linecnt <= 0 || charcnt <= 0) { 1941513Sroot fprintf(tp,"...more...%s\n", cr); 19513022Ssam return; 1961513Sroot } 19713783Ssam if (strncmp(line, "From ", 5) == 0) 19813783Ssam continue; 19913783Ssam if (inheader && (line[0] == ' ' || line[0] == '\t')) 20013783Ssam continue; 20112746Ssam cp = index(line, ':'); 20213783Ssam if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp)) 20313783Ssam inheader = 0; 20413783Ssam else 20513783Ssam cnt = cp - line; 20613783Ssam if (inheader && 20713783Ssam strncmp(line, "Date", cnt) && 20813783Ssam strncmp(line, "From", cnt) && 20913783Ssam strncmp(line, "Subject", cnt) && 21013783Ssam strncmp(line, "To", cnt)) 21112746Ssam continue; 21212746Ssam cp = index(line, '\n'); 21312746Ssam if (cp) 21412746Ssam *cp = '\0'; 21512746Ssam fprintf(tp,"%s%s\n", line, cr); 21612746Ssam linecnt--, charcnt -= strlen(line); 2171513Sroot } 21812746Ssam fprintf(tp,"----%s\n", cr); 2191513Sroot } 220