1*9289Ssam #ifndef lint 2*9289Ssam static char *sccsid = "@(#)comsat.c 4.4 82/11/17"; 3*9289Ssam #endif 46394Sroot 5*9289Ssam #include <sys/types.h> 6*9289Ssam #include <sys/socket.h> 7*9289Ssam 8*9289Ssam #include <netinet/in.h> 9*9289Ssam 101513Sroot #include <stdio.h> 111513Sroot #include <sgtty.h> 121513Sroot #include <utmp.h> 131513Sroot #include <stat.h> 141513Sroot #include <wait.h> 151513Sroot #include <signal.h> 166394Sroot #include <errno.h> 17*9289Ssam #include <netdb.h> 181513Sroot 191513Sroot /* 201513Sroot * comsat 211513Sroot */ 221513Sroot #define dprintf if (0) printf 231513Sroot 241513Sroot #define MAXUTMP 100 /* down from init */ 251513Sroot 266394Sroot struct sockaddr_in sin = { AF_INET, IPPORT_BIFFUDP }; 276394Sroot extern errno; 286394Sroot 291513Sroot struct utmp utmp[100]; 301513Sroot int nutmp; 311513Sroot int uf; 321513Sroot unsigned utmpmtime; /* last modification time for utmp */ 331513Sroot int onalrm(); 34*9289Ssam struct servent *sp; 351513Sroot 361513Sroot #define NAMLEN (sizeof (uts[0].ut_name) + 1) 371513Sroot 381513Sroot main(argc, argv) 391513Sroot char **argv; 401513Sroot { 411513Sroot register cc; 421513Sroot char buf[BUFSIZ]; 436394Sroot int s; 441513Sroot 45*9289Ssam sp = getservbyname("biff", "udp"); 46*9289Ssam if (sp == 0) { 47*9289Ssam fprintf(stderr, "comsat: biff/udp: unknown service\n"); 48*9289Ssam exit(1); 49*9289Ssam } 506394Sroot #ifndef DEBUG 511513Sroot if (fork()) 521513Sroot exit(); 536394Sroot #endif 541513Sroot chdir("/usr/spool/mail"); 551513Sroot if((uf = open("/etc/utmp",0)) < 0) 561513Sroot perror("/etc/utmp"), exit(1); 576394Sroot #ifndef DEBUG 581513Sroot while (fork()) 591513Sroot wait(0); 606394Sroot #endif 611572Sbill sleep(10); 621513Sroot onalrm(); 631513Sroot sigset(SIGALRM, onalrm); 641513Sroot sigignore(SIGTTOU); 65*9289Ssam s = socket(AF_INET, SOCK_DGRAM, 0, 0); 666394Sroot if (s < 0) { 676394Sroot perror("socket"); 681513Sroot exit(1); 691513Sroot } 70*9289Ssam #if vax || pdp11 71*9289Ssam sp->s_port = htons((u_short)sp->s_port); 72*9289Ssam #endif 73*9289Ssam sin.sin_port = sp->s_port; 74*9289Ssam if (bind(s, &sin, sizeof (sin), 0) < 0) { 75*9289Ssam perror("bind"); 76*9289Ssam exit(1); 77*9289Ssam } 786394Sroot for (;;) { 796394Sroot char msgbuf[100]; 806394Sroot int cc; 811513Sroot 82*9289Ssam cc = recv(s, msgbuf, sizeof (msgbuf) - 1, 0); 836394Sroot if (cc <= 0) { 846394Sroot if (errno != EINTR) 856394Sroot sleep(1); 866394Sroot errno = 0; 876394Sroot continue; 881513Sroot } 896394Sroot msgbuf[cc] = 0; 906394Sroot mailfor(msgbuf); 911513Sroot } 921513Sroot } 931513Sroot 941513Sroot onalrm() 951513Sroot { 961513Sroot struct stat statbf; 971513Sroot struct utmp *utp; 981513Sroot 991513Sroot dprintf("alarm\n"); 1001513Sroot alarm(15); 1011513Sroot fstat(uf,&statbf); 1021513Sroot if (statbf.st_mtime > utmpmtime) { 1031513Sroot dprintf(" changed\n"); 1041513Sroot utmpmtime = statbf.st_mtime; 1051513Sroot lseek(uf, 0, 0); 1061513Sroot nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp); 1071513Sroot } else 1081513Sroot dprintf(" ok\n"); 1091513Sroot } 1101513Sroot 1111513Sroot mailfor(name) 1121513Sroot char *name; 1131513Sroot { 1141513Sroot register struct utmp *utp = &utmp[nutmp]; 1151513Sroot register char *cp; 1161513Sroot char *rindex(); 1171513Sroot int offset; 1181513Sroot 1191513Sroot dprintf("mailfor %s\n", name); 1201513Sroot cp = name; 1211513Sroot while (*cp && *cp != '@') 1221513Sroot cp++; 1231513Sroot if (*cp == 0) { 1241513Sroot dprintf("bad format\n"); 1251513Sroot return; 1261513Sroot } 1271513Sroot *cp = 0; 1281513Sroot offset = atoi(cp+1); 1291513Sroot while (--utp >= utmp) 1301513Sroot if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name))) 1311513Sroot if (fork() == 0) { 1321513Sroot signal(SIGALRM, SIG_DFL); 1331513Sroot alarm(30); 1341513Sroot notify(utp, offset), exit(0); 1351513Sroot } else 1361513Sroot while (wait3(0, WNOHANG, 0) > 0) 1371513Sroot continue; 1381513Sroot } 1391513Sroot 1401513Sroot char *cr; 1411513Sroot 1421513Sroot notify(utp, offset) 1431513Sroot register struct utmp *utp; 1441513Sroot { 1451513Sroot FILE *tp; 1461513Sroot struct sgttyb gttybuf; 1471513Sroot char tty[20]; 1481513Sroot char name[sizeof (utmp[0].ut_name) + 1]; 1491513Sroot struct stat stb; 1501513Sroot 1511513Sroot strcpy(tty, "/dev/"); 1521513Sroot strncat(tty, utp->ut_line, sizeof(utp->ut_line)); 1531513Sroot dprintf("notify %s on %s\n", utp->ut_name, tty); 1541513Sroot if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) { 1551513Sroot dprintf("wrong mode\n"); 1561513Sroot return; 1571513Sroot } 1581513Sroot if ((tp = fopen(tty,"w")) == 0) { 1591513Sroot dprintf("fopen failed\n"); 1601513Sroot return; 1611513Sroot } 1621513Sroot gtty(fileno(tp),>tybuf); 1631513Sroot cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r"; 1641513Sroot strncpy(name, utp->ut_name, sizeof (utp->ut_name)); 1651513Sroot name[sizeof (name) - 1] = 0; 1661513Sroot fprintf(tp,"%s\n\007New mail for %s\007 has arrived:%s\n", 1671513Sroot cr, name, cr); 1681513Sroot fprintf(tp,"----%s\n", cr); 1691513Sroot jkfprintf(tp, name, offset); 1701513Sroot fclose(tp); 1711513Sroot } 1721513Sroot 1731513Sroot jkfprintf(tp, name, offset) 1741513Sroot register FILE *tp; 1751513Sroot { 1761513Sroot register FILE *fi; 1771513Sroot register int linecnt, charcnt; 1781513Sroot 1791513Sroot dprintf("HERE %s's mail starting at %d\n", 1801513Sroot name, offset); 1811513Sroot if ((fi = fopen(name,"r")) == NULL) { 1821513Sroot dprintf("Cant read the mail\n"); 1831513Sroot return; 1841513Sroot } 1851513Sroot fseek(fi, offset, 0); 1861513Sroot linecnt = 7; 1871513Sroot charcnt = 560; 1881513Sroot /* 1891513Sroot * print the first 7 lines or 560 characters of the new mail 1901513Sroot * (whichever comes first) 1911513Sroot */ 1921513Sroot for (;;) { 1931513Sroot register ch; 1941513Sroot 1951513Sroot if ((ch = getc(fi)) == EOF) { 1961513Sroot fprintf(tp,"----%s\n", cr); 1971513Sroot break; 1981513Sroot } 1991513Sroot if (ch == '\n') { 2001513Sroot fprintf(tp,"%s\n", cr); 2011513Sroot if (linecnt-- < 0) { 2021513Sroot fprintf(tp,"...more...%s\n", cr); 2031513Sroot break; 2041513Sroot } 2051513Sroot } else if(linecnt <= 0) { 2061513Sroot fprintf(tp,"...more...%s\n", cr); 2071513Sroot break; 2081513Sroot } else 2091513Sroot putc(ch, tp); 2101513Sroot if (charcnt-- == 0) { 2111513Sroot fprintf(tp, "%s\n", cr); 2121513Sroot break; 2131513Sroot } 2141513Sroot } 2151513Sroot } 216