1 static char *sccsid = "@(#)comsat.c 4.3 82/03/31"; 2 3 #include <stdio.h> 4 #include <sgtty.h> 5 #include <utmp.h> 6 #include <sys/types.h> 7 #include <net/in.h> 8 #include <sys/socket.h> 9 #include <stat.h> 10 #include <wait.h> 11 #include <signal.h> 12 #include <errno.h> 13 14 /* 15 * comsat 16 */ 17 #define dprintf if (0) printf 18 19 #define MAXUTMP 100 /* down from init */ 20 21 struct sockaddr_in sin = { AF_INET, IPPORT_BIFFUDP }; 22 extern errno; 23 24 struct utmp utmp[100]; 25 int nutmp; 26 int uf; 27 unsigned utmpmtime; /* last modification time for utmp */ 28 int onalrm(); 29 30 #define NAMLEN (sizeof (uts[0].ut_name) + 1) 31 32 main(argc, argv) 33 char **argv; 34 { 35 register cc; 36 char buf[BUFSIZ]; 37 int s; 38 39 #ifndef DEBUG 40 if (fork()) 41 exit(); 42 #endif 43 chdir("/usr/spool/mail"); 44 if((uf = open("/etc/utmp",0)) < 0) 45 perror("/etc/utmp"), exit(1); 46 #ifndef DEBUG 47 while (fork()) 48 wait(0); 49 #endif 50 sleep(10); 51 onalrm(); 52 sigset(SIGALRM, onalrm); 53 sigignore(SIGTTOU); 54 #if vax 55 sin.sin_port = ((sin.sin_port<<8)&0xff00)|((sin.sin_port>>8)&0xff); 56 #endif 57 s = socket(SOCK_DGRAM, 0, &sin, 0); 58 if (s < 0) { 59 perror("socket"); 60 exit(1); 61 } 62 for (;;) { 63 char msgbuf[100]; 64 int cc; 65 66 cc = receive(s, 0, msgbuf, sizeof (msgbuf) - 1); 67 if (cc <= 0) { 68 if (errno != EINTR) 69 sleep(1); 70 errno = 0; 71 continue; 72 } 73 msgbuf[cc] = 0; 74 mailfor(msgbuf); 75 } 76 } 77 78 onalrm() 79 { 80 struct stat statbf; 81 struct utmp *utp; 82 83 dprintf("alarm\n"); 84 alarm(15); 85 fstat(uf,&statbf); 86 if (statbf.st_mtime > utmpmtime) { 87 dprintf(" changed\n"); 88 utmpmtime = statbf.st_mtime; 89 lseek(uf, 0, 0); 90 nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp); 91 } else 92 dprintf(" ok\n"); 93 } 94 95 mailfor(name) 96 char *name; 97 { 98 register struct utmp *utp = &utmp[nutmp]; 99 register char *cp; 100 char *rindex(); 101 int offset; 102 103 dprintf("mailfor %s\n", name); 104 cp = name; 105 while (*cp && *cp != '@') 106 cp++; 107 if (*cp == 0) { 108 dprintf("bad format\n"); 109 return; 110 } 111 *cp = 0; 112 offset = atoi(cp+1); 113 while (--utp >= utmp) 114 if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name))) 115 if (fork() == 0) { 116 signal(SIGALRM, SIG_DFL); 117 alarm(30); 118 notify(utp, offset), exit(0); 119 } else 120 while (wait3(0, WNOHANG, 0) > 0) 121 continue; 122 } 123 124 char *cr; 125 126 notify(utp, offset) 127 register struct utmp *utp; 128 { 129 FILE *tp; 130 struct sgttyb gttybuf; 131 char tty[20]; 132 char name[sizeof (utmp[0].ut_name) + 1]; 133 struct stat stb; 134 135 strcpy(tty, "/dev/"); 136 strncat(tty, utp->ut_line, sizeof(utp->ut_line)); 137 dprintf("notify %s on %s\n", utp->ut_name, tty); 138 if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) { 139 dprintf("wrong mode\n"); 140 return; 141 } 142 if ((tp = fopen(tty,"w")) == 0) { 143 dprintf("fopen failed\n"); 144 return; 145 } 146 gtty(fileno(tp),>tybuf); 147 cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r"; 148 strncpy(name, utp->ut_name, sizeof (utp->ut_name)); 149 name[sizeof (name) - 1] = 0; 150 fprintf(tp,"%s\n\007New mail for %s\007 has arrived:%s\n", 151 cr, name, cr); 152 fprintf(tp,"----%s\n", cr); 153 jkfprintf(tp, name, offset); 154 fclose(tp); 155 } 156 157 jkfprintf(tp, name, offset) 158 register FILE *tp; 159 { 160 register FILE *fi; 161 register int linecnt, charcnt; 162 163 dprintf("HERE %s's mail starting at %d\n", 164 name, offset); 165 if ((fi = fopen(name,"r")) == NULL) { 166 dprintf("Cant read the mail\n"); 167 return; 168 } 169 fseek(fi, offset, 0); 170 linecnt = 7; 171 charcnt = 560; 172 /* 173 * print the first 7 lines or 560 characters of the new mail 174 * (whichever comes first) 175 */ 176 for (;;) { 177 register ch; 178 179 if ((ch = getc(fi)) == EOF) { 180 fprintf(tp,"----%s\n", cr); 181 break; 182 } 183 if (ch == '\n') { 184 fprintf(tp,"%s\n", cr); 185 if (linecnt-- < 0) { 186 fprintf(tp,"...more...%s\n", cr); 187 break; 188 } 189 } else if(linecnt <= 0) { 190 fprintf(tp,"...more...%s\n", cr); 191 break; 192 } else 193 putc(ch, tp); 194 if (charcnt-- == 0) { 195 fprintf(tp, "%s\n", cr); 196 break; 197 } 198 } 199 } 200