122550Sdist /* 222550Sdist * Copyright (c) 1980 Regents of the University of California. 322550Sdist * All rights reserved. The Berkeley software License Agreement 422550Sdist * specifies the terms and conditions for redistribution. 522550Sdist */ 622550Sdist 79289Ssam #ifndef lint 822550Sdist char copyright[] = 922550Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1022550Sdist All rights reserved.\n"; 1122550Sdist #endif not lint 126394Sroot 1322550Sdist #ifndef lint 14*24850Seric static char sccsid[] = "@(#)comsat.c 5.4 (Berkeley) 09/17/85"; 1522550Sdist #endif not lint 1622550Sdist 179289Ssam #include <sys/types.h> 189289Ssam #include <sys/socket.h> 1913549Ssam #include <sys/stat.h> 2013549Ssam #include <sys/wait.h> 2116587Ssam #include <sys/file.h> 229289Ssam 239289Ssam #include <netinet/in.h> 249289Ssam 251513Sroot #include <stdio.h> 261513Sroot #include <sgtty.h> 271513Sroot #include <utmp.h> 281513Sroot #include <signal.h> 296394Sroot #include <errno.h> 309289Ssam #include <netdb.h> 3116808Sralph #include <syslog.h> 321513Sroot 331513Sroot /* 341513Sroot * comsat 351513Sroot */ 3612746Ssam int debug = 0; 3712746Ssam #define dprintf if (debug) printf 381513Sroot 399878Ssam struct sockaddr_in sin = { AF_INET }; 406394Sroot extern errno; 416394Sroot 4216587Ssam char hostname[32]; 4322545Sbloom struct utmp *utmp = NULL; 441513Sroot int nutmp; 451513Sroot int uf; 4622545Sbloom unsigned utmpmtime = 0; /* last modification time for utmp */ 4722545Sbloom unsigned utmpsize = 0; /* last malloced size for utmp */ 481513Sroot int onalrm(); 4916587Ssam int reapchildren(); 5016367Skarels long lastmsgtime; 5122545Sbloom char *malloc(), *realloc(); 521513Sroot 5316367Skarels #define MAXIDLE 120 541513Sroot #define NAMLEN (sizeof (uts[0].ut_name) + 1) 551513Sroot 561513Sroot main(argc, argv) 5716367Skarels int argc; 5816367Skarels char *argv[]; 591513Sroot { 6016367Skarels register int cc; 611513Sroot char buf[BUFSIZ]; 6216367Skarels char msgbuf[100]; 6316367Skarels struct sockaddr_in from; 6416367Skarels int fromlen; 651513Sroot 6616367Skarels /* verify proper invocation */ 6716367Skarels fromlen = sizeof (from); 6816367Skarels if (getsockname(0, &from, &fromlen) < 0) { 6916367Skarels fprintf(stderr, "%s: ", argv[0]); 7016367Skarels perror("getsockname"); 7116367Skarels _exit(1); 7216367Skarels } 7316367Skarels chdir("/usr/spool/mail"); 7416367Skarels if ((uf = open("/etc/utmp",0)) < 0) { 75*24850Seric openlog("comsat", 0, LOG_DAEMON); 7616808Sralph syslog(LOG_ERR, "/etc/utmp: %m"); 7716367Skarels (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0); 789289Ssam exit(1); 799289Ssam } 8016367Skarels lastmsgtime = time(0); 8116587Ssam gethostname(hostname, sizeof (hostname)); 821513Sroot onalrm(); 8313022Ssam signal(SIGALRM, onalrm); 8413022Ssam signal(SIGTTOU, SIG_IGN); 8516587Ssam signal(SIGCHLD, reapchildren); 866394Sroot for (;;) { 8716367Skarels cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0); 886394Sroot if (cc <= 0) { 896394Sroot if (errno != EINTR) 906394Sroot sleep(1); 916394Sroot errno = 0; 926394Sroot continue; 931513Sroot } 9422596Sbloom sigblock(sigmask(SIGALRM)); 956394Sroot msgbuf[cc] = 0; 9616367Skarels lastmsgtime = time(0); 976394Sroot mailfor(msgbuf); 9816367Skarels sigsetmask(0); 991513Sroot } 1001513Sroot } 1011513Sroot 10216587Ssam reapchildren() 10316587Ssam { 10416587Ssam 10516587Ssam while (wait3((struct wait *)0, WNOHANG, (struct rusage *)0) > 0) 10616587Ssam ; 10716587Ssam } 10816587Ssam 1091513Sroot onalrm() 1101513Sroot { 1111513Sroot struct stat statbf; 1121513Sroot 11316367Skarels if (time(0) - lastmsgtime >= MAXIDLE) 11416808Sralph exit(0); 1151513Sroot dprintf("alarm\n"); 1161513Sroot alarm(15); 11716808Sralph fstat(uf, &statbf); 1181513Sroot if (statbf.st_mtime > utmpmtime) { 1191513Sroot dprintf(" changed\n"); 1201513Sroot utmpmtime = statbf.st_mtime; 12122545Sbloom if (statbf.st_size > utmpsize) { 12222545Sbloom utmpsize = statbf.st_size + 10 * sizeof(struct utmp); 12322545Sbloom if (utmp) 12422545Sbloom utmp = (struct utmp *)realloc(utmp, utmpsize); 12522545Sbloom else 12622545Sbloom utmp = (struct utmp *)malloc(utmpsize); 12722545Sbloom if (! utmp) { 12822545Sbloom dprintf("malloc failed\n"); 12922545Sbloom exit(1); 13022545Sbloom } 13122545Sbloom } 1321513Sroot lseek(uf, 0, 0); 13322545Sbloom nutmp = read(uf,utmp,statbf.st_size)/sizeof(struct utmp); 1341513Sroot } else 1351513Sroot dprintf(" ok\n"); 1361513Sroot } 1371513Sroot 1381513Sroot mailfor(name) 1391513Sroot char *name; 1401513Sroot { 1411513Sroot register struct utmp *utp = &utmp[nutmp]; 1421513Sroot register char *cp; 1431513Sroot char *rindex(); 1441513Sroot int offset; 1451513Sroot 1461513Sroot dprintf("mailfor %s\n", name); 1471513Sroot cp = name; 1481513Sroot while (*cp && *cp != '@') 1491513Sroot cp++; 1501513Sroot if (*cp == 0) { 1511513Sroot dprintf("bad format\n"); 1521513Sroot return; 1531513Sroot } 1541513Sroot *cp = 0; 1551513Sroot offset = atoi(cp+1); 1561513Sroot while (--utp >= utmp) 1571513Sroot if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name))) 15816587Ssam notify(utp, offset); 1591513Sroot } 1601513Sroot 16116808Sralph char *cr; 1621513Sroot 1631513Sroot notify(utp, offset) 1641513Sroot register struct utmp *utp; 1651513Sroot { 16617189Sralph FILE *tp; 1671513Sroot struct sgttyb gttybuf; 16817189Sralph char tty[20], name[sizeof (utmp[0].ut_name) + 1]; 1691513Sroot struct stat stb; 1701513Sroot 1711513Sroot strcpy(tty, "/dev/"); 1721513Sroot strncat(tty, utp->ut_line, sizeof(utp->ut_line)); 1731513Sroot dprintf("notify %s on %s\n", utp->ut_name, tty); 1741513Sroot if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) { 1751513Sroot dprintf("wrong mode\n"); 1761513Sroot return; 1771513Sroot } 17817189Sralph if (fork()) 17916587Ssam return; 18017189Sralph signal(SIGALRM, SIG_DFL); 18117189Sralph alarm(30); 18217189Sralph if ((tp = fopen(tty,"w")) == 0) { 18317189Sralph dprintf("fopen failed\n"); 18417189Sralph exit(-1); 1851513Sroot } 18617189Sralph ioctl(fileno(tp), TIOCGETP, >tybuf); 18724523Sbloom cr = (gttybuf.sg_flags&CRMOD) && !(gttybuf.sg_flags&RAW) ? "" : "\r"; 1881513Sroot strncpy(name, utp->ut_name, sizeof (utp->ut_name)); 18916587Ssam name[sizeof (name) - 1] = '\0'; 19017189Sralph fprintf(tp,"%s\n\007New mail for %s@%s\007 has arrived:%s\n", 19112746Ssam cr, name, hostname, cr); 19217189Sralph fprintf(tp,"----%s\n", cr); 19317189Sralph jkfprintf(tp, name, offset); 19416587Ssam exit(0); 1951513Sroot } 1961513Sroot 19717189Sralph jkfprintf(tp, name, offset) 19817189Sralph register FILE *tp; 1991513Sroot { 2001513Sroot register FILE *fi; 2011513Sroot register int linecnt, charcnt; 20212746Ssam char line[BUFSIZ]; 20313783Ssam int inheader; 2041513Sroot 20517189Sralph dprintf("HERE %s's mail starting at %d\n", 20617189Sralph name, offset); 20717189Sralph if ((fi = fopen(name,"r")) == NULL) { 2081513Sroot dprintf("Cant read the mail\n"); 2091513Sroot return; 2101513Sroot } 21116587Ssam fseek(fi, offset, L_SET); 21212746Ssam /* 21312746Ssam * Print the first 7 lines or 560 characters of the new mail 21412746Ssam * (whichever comes first). Skip header crap other than 21513783Ssam * From, Subject, To, and Date. 21612746Ssam */ 2171513Sroot linecnt = 7; 2181513Sroot charcnt = 560; 21913783Ssam inheader = 1; 22012746Ssam while (fgets(line, sizeof (line), fi) != NULL) { 22112746Ssam register char *cp; 22212746Ssam char *index(); 22313783Ssam int cnt; 2241513Sroot 22512746Ssam if (linecnt <= 0 || charcnt <= 0) { 22617189Sralph fprintf(tp,"...more...%s\n", cr); 22713022Ssam return; 2281513Sroot } 22913783Ssam if (strncmp(line, "From ", 5) == 0) 23013783Ssam continue; 23113783Ssam if (inheader && (line[0] == ' ' || line[0] == '\t')) 23213783Ssam continue; 23312746Ssam cp = index(line, ':'); 23413783Ssam if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp)) 23513783Ssam inheader = 0; 23613783Ssam else 23713783Ssam cnt = cp - line; 23813783Ssam if (inheader && 23913783Ssam strncmp(line, "Date", cnt) && 24013783Ssam strncmp(line, "From", cnt) && 24113783Ssam strncmp(line, "Subject", cnt) && 24213783Ssam strncmp(line, "To", cnt)) 24312746Ssam continue; 24412746Ssam cp = index(line, '\n'); 24512746Ssam if (cp) 24612746Ssam *cp = '\0'; 24717189Sralph fprintf(tp,"%s%s\n", line, cr); 24812746Ssam linecnt--, charcnt -= strlen(line); 2491513Sroot } 25017189Sralph fprintf(tp,"----%s\n", cr); 2511513Sroot } 252