1*6394Sroot static char *sccsid = "@(#)comsat.c 4.3 82/03/31"; 2*6394Sroot 31513Sroot #include <stdio.h> 41513Sroot #include <sgtty.h> 51513Sroot #include <utmp.h> 61513Sroot #include <sys/types.h> 7*6394Sroot #include <net/in.h> 8*6394Sroot #include <sys/socket.h> 91513Sroot #include <stat.h> 101513Sroot #include <wait.h> 111513Sroot #include <signal.h> 12*6394Sroot #include <errno.h> 131513Sroot 141513Sroot /* 151513Sroot * comsat 161513Sroot */ 171513Sroot #define dprintf if (0) printf 181513Sroot 191513Sroot #define MAXUTMP 100 /* down from init */ 201513Sroot 21*6394Sroot struct sockaddr_in sin = { AF_INET, IPPORT_BIFFUDP }; 22*6394Sroot extern errno; 23*6394Sroot 241513Sroot struct utmp utmp[100]; 251513Sroot int nutmp; 261513Sroot int uf; 271513Sroot unsigned utmpmtime; /* last modification time for utmp */ 281513Sroot int onalrm(); 291513Sroot 301513Sroot #define NAMLEN (sizeof (uts[0].ut_name) + 1) 311513Sroot 321513Sroot main(argc, argv) 331513Sroot char **argv; 341513Sroot { 351513Sroot register cc; 361513Sroot char buf[BUFSIZ]; 37*6394Sroot int s; 381513Sroot 39*6394Sroot #ifndef DEBUG 401513Sroot if (fork()) 411513Sroot exit(); 42*6394Sroot #endif 431513Sroot chdir("/usr/spool/mail"); 441513Sroot if((uf = open("/etc/utmp",0)) < 0) 451513Sroot perror("/etc/utmp"), exit(1); 46*6394Sroot #ifndef DEBUG 471513Sroot while (fork()) 481513Sroot wait(0); 49*6394Sroot #endif 501572Sbill sleep(10); 511513Sroot onalrm(); 521513Sroot sigset(SIGALRM, onalrm); 531513Sroot sigignore(SIGTTOU); 54*6394Sroot #if vax 55*6394Sroot sin.sin_port = ((sin.sin_port<<8)&0xff00)|((sin.sin_port>>8)&0xff); 56*6394Sroot #endif 57*6394Sroot s = socket(SOCK_DGRAM, 0, &sin, 0); 58*6394Sroot if (s < 0) { 59*6394Sroot perror("socket"); 601513Sroot exit(1); 611513Sroot } 62*6394Sroot for (;;) { 63*6394Sroot char msgbuf[100]; 64*6394Sroot int cc; 651513Sroot 66*6394Sroot cc = receive(s, 0, msgbuf, sizeof (msgbuf) - 1); 67*6394Sroot if (cc <= 0) { 68*6394Sroot if (errno != EINTR) 69*6394Sroot sleep(1); 70*6394Sroot errno = 0; 71*6394Sroot continue; 721513Sroot } 73*6394Sroot msgbuf[cc] = 0; 74*6394Sroot mailfor(msgbuf); 751513Sroot } 761513Sroot } 771513Sroot 781513Sroot onalrm() 791513Sroot { 801513Sroot struct stat statbf; 811513Sroot struct utmp *utp; 821513Sroot 831513Sroot dprintf("alarm\n"); 841513Sroot alarm(15); 851513Sroot fstat(uf,&statbf); 861513Sroot if (statbf.st_mtime > utmpmtime) { 871513Sroot dprintf(" changed\n"); 881513Sroot utmpmtime = statbf.st_mtime; 891513Sroot lseek(uf, 0, 0); 901513Sroot nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp); 911513Sroot } else 921513Sroot dprintf(" ok\n"); 931513Sroot } 941513Sroot 951513Sroot mailfor(name) 961513Sroot char *name; 971513Sroot { 981513Sroot register struct utmp *utp = &utmp[nutmp]; 991513Sroot register char *cp; 1001513Sroot char *rindex(); 1011513Sroot int offset; 1021513Sroot 1031513Sroot dprintf("mailfor %s\n", name); 1041513Sroot cp = name; 1051513Sroot while (*cp && *cp != '@') 1061513Sroot cp++; 1071513Sroot if (*cp == 0) { 1081513Sroot dprintf("bad format\n"); 1091513Sroot return; 1101513Sroot } 1111513Sroot *cp = 0; 1121513Sroot offset = atoi(cp+1); 1131513Sroot while (--utp >= utmp) 1141513Sroot if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name))) 1151513Sroot if (fork() == 0) { 1161513Sroot signal(SIGALRM, SIG_DFL); 1171513Sroot alarm(30); 1181513Sroot notify(utp, offset), exit(0); 1191513Sroot } else 1201513Sroot while (wait3(0, WNOHANG, 0) > 0) 1211513Sroot continue; 1221513Sroot } 1231513Sroot 1241513Sroot char *cr; 1251513Sroot 1261513Sroot notify(utp, offset) 1271513Sroot register struct utmp *utp; 1281513Sroot { 1291513Sroot FILE *tp; 1301513Sroot struct sgttyb gttybuf; 1311513Sroot char tty[20]; 1321513Sroot char name[sizeof (utmp[0].ut_name) + 1]; 1331513Sroot struct stat stb; 1341513Sroot 1351513Sroot strcpy(tty, "/dev/"); 1361513Sroot strncat(tty, utp->ut_line, sizeof(utp->ut_line)); 1371513Sroot dprintf("notify %s on %s\n", utp->ut_name, tty); 1381513Sroot if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) { 1391513Sroot dprintf("wrong mode\n"); 1401513Sroot return; 1411513Sroot } 1421513Sroot if ((tp = fopen(tty,"w")) == 0) { 1431513Sroot dprintf("fopen failed\n"); 1441513Sroot return; 1451513Sroot } 1461513Sroot gtty(fileno(tp),>tybuf); 1471513Sroot cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r"; 1481513Sroot strncpy(name, utp->ut_name, sizeof (utp->ut_name)); 1491513Sroot name[sizeof (name) - 1] = 0; 1501513Sroot fprintf(tp,"%s\n\007New mail for %s\007 has arrived:%s\n", 1511513Sroot cr, name, cr); 1521513Sroot fprintf(tp,"----%s\n", cr); 1531513Sroot jkfprintf(tp, name, offset); 1541513Sroot fclose(tp); 1551513Sroot } 1561513Sroot 1571513Sroot jkfprintf(tp, name, offset) 1581513Sroot register FILE *tp; 1591513Sroot { 1601513Sroot register FILE *fi; 1611513Sroot register int linecnt, charcnt; 1621513Sroot 1631513Sroot dprintf("HERE %s's mail starting at %d\n", 1641513Sroot name, offset); 1651513Sroot if ((fi = fopen(name,"r")) == NULL) { 1661513Sroot dprintf("Cant read the mail\n"); 1671513Sroot return; 1681513Sroot } 1691513Sroot fseek(fi, offset, 0); 1701513Sroot linecnt = 7; 1711513Sroot charcnt = 560; 1721513Sroot /* 1731513Sroot * print the first 7 lines or 560 characters of the new mail 1741513Sroot * (whichever comes first) 1751513Sroot */ 1761513Sroot for (;;) { 1771513Sroot register ch; 1781513Sroot 1791513Sroot if ((ch = getc(fi)) == EOF) { 1801513Sroot fprintf(tp,"----%s\n", cr); 1811513Sroot break; 1821513Sroot } 1831513Sroot if (ch == '\n') { 1841513Sroot fprintf(tp,"%s\n", cr); 1851513Sroot if (linecnt-- < 0) { 1861513Sroot fprintf(tp,"...more...%s\n", cr); 1871513Sroot break; 1881513Sroot } 1891513Sroot } else if(linecnt <= 0) { 1901513Sroot fprintf(tp,"...more...%s\n", cr); 1911513Sroot break; 1921513Sroot } else 1931513Sroot putc(ch, tp); 1941513Sroot if (charcnt-- == 0) { 1951513Sroot fprintf(tp, "%s\n", cr); 1961513Sroot break; 1971513Sroot } 1981513Sroot } 1991513Sroot } 200