|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: char copyright[] = ! 20: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 21: All rights reserved.\n"; ! 22: #endif /* not lint */ ! 23: ! 24: #ifndef lint ! 25: static char sccsid[] = "@(#)comsat.c 5.12 (Berkeley) 6/18/88"; ! 26: #endif /* not lint */ ! 27: ! 28: #include <sys/param.h> ! 29: #include <sys/socket.h> ! 30: #include <sys/stat.h> ! 31: #include <sys/file.h> ! 32: #include <sys/wait.h> ! 33: ! 34: #include <netinet/in.h> ! 35: ! 36: #include <stdio.h> ! 37: #include <sgtty.h> ! 38: #include <utmp.h> ! 39: #include <signal.h> ! 40: #include <errno.h> ! 41: #include <netdb.h> ! 42: #include <syslog.h> ! 43: #include <strings.h> ! 44: ! 45: /* ! 46: * comsat ! 47: */ ! 48: int debug = 0; ! 49: #define dsyslog if (debug) syslog ! 50: ! 51: #define MAXIDLE 120 ! 52: ! 53: char hostname[MAXHOSTNAMELEN]; ! 54: struct utmp *utmp = NULL; ! 55: time_t lastmsgtime, time(); ! 56: int nutmp, uf; ! 57: ! 58: main(argc, argv) ! 59: int argc; ! 60: char **argv; ! 61: { ! 62: extern int errno; ! 63: register int cc; ! 64: char msgbuf[100]; ! 65: struct sockaddr_in from; ! 66: int fromlen, reapchildren(), onalrm(); ! 67: ! 68: /* verify proper invocation */ ! 69: fromlen = sizeof (from); ! 70: if (getsockname(0, &from, &fromlen) < 0) { ! 71: fprintf(stderr, "%s: ", argv[0]); ! 72: perror("getsockname"); ! 73: exit(1); ! 74: } ! 75: openlog("comsat", LOG_PID, LOG_DAEMON); ! 76: if (chdir("/usr/spool/mail")) { ! 77: syslog(LOG_ERR, "chdir: /usr/spool/mail"); ! 78: exit(1); ! 79: } ! 80: if ((uf = open("/etc/utmp", O_RDONLY, 0)) < 0) { ! 81: syslog(LOG_ERR, ".main: /etc/utmp: %m"); ! 82: (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0); ! 83: exit(1); ! 84: } ! 85: (void)time(&lastmsgtime); ! 86: (void)gethostname(hostname, sizeof (hostname)); ! 87: onalrm(); ! 88: (void)signal(SIGALRM, onalrm); ! 89: (void)signal(SIGTTOU, SIG_IGN); ! 90: (void)signal(SIGCHLD, reapchildren); ! 91: for (;;) { ! 92: cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0); ! 93: if (cc <= 0) { ! 94: if (errno != EINTR) ! 95: sleep(1); ! 96: errno = 0; ! 97: continue; ! 98: } ! 99: if (!nutmp) /* no one has logged in yet */ ! 100: continue; ! 101: sigblock(sigmask(SIGALRM)); ! 102: msgbuf[cc] = 0; ! 103: (void)time(&lastmsgtime); ! 104: mailfor(msgbuf); ! 105: sigsetmask(0L); ! 106: } ! 107: } ! 108: ! 109: reapchildren() ! 110: { ! 111: while (wait3((union wait *)NULL, WNOHANG, (struct rusage *)NULL) > 0); ! 112: } ! 113: ! 114: onalrm() ! 115: { ! 116: static u_int utmpsize; /* last malloced size for utmp */ ! 117: static u_int utmpmtime; /* last modification time for utmp */ ! 118: struct stat statbf; ! 119: off_t lseek(); ! 120: char *malloc(), *realloc(); ! 121: ! 122: if (time((time_t *)NULL) - lastmsgtime >= MAXIDLE) ! 123: exit(0); ! 124: (void)alarm((u_int)15); ! 125: (void)fstat(uf, &statbf); ! 126: if (statbf.st_mtime > utmpmtime) { ! 127: utmpmtime = statbf.st_mtime; ! 128: if (statbf.st_size > utmpsize) { ! 129: utmpsize = statbf.st_size + 10 * sizeof(struct utmp); ! 130: if (utmp) ! 131: utmp = (struct utmp *)realloc((char *)utmp, utmpsize); ! 132: else ! 133: utmp = (struct utmp *)malloc(utmpsize); ! 134: if (!utmp) { ! 135: syslog(LOG_ERR, "malloc failed"); ! 136: exit(1); ! 137: } ! 138: } ! 139: (void)lseek(uf, 0L, L_SET); ! 140: nutmp = read(uf, utmp, (int)statbf.st_size)/sizeof(struct utmp); ! 141: } ! 142: } ! 143: ! 144: mailfor(name) ! 145: char *name; ! 146: { ! 147: register struct utmp *utp = &utmp[nutmp]; ! 148: register char *cp; ! 149: off_t offset, atol(); ! 150: ! 151: if (!(cp = index(name, '@'))) ! 152: return; ! 153: *cp = '\0'; ! 154: offset = atoi(cp + 1); ! 155: while (--utp >= utmp) ! 156: if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name))) ! 157: notify(utp, offset); ! 158: } ! 159: ! 160: static char *cr; ! 161: ! 162: notify(utp, offset) ! 163: register struct utmp *utp; ! 164: off_t offset; ! 165: { ! 166: static char tty[20] = "/dev/"; ! 167: struct sgttyb gttybuf; ! 168: FILE *tp; ! 169: char name[sizeof (utmp[0].ut_name) + 1]; ! 170: struct stat stb; ! 171: ! 172: (void)strncpy(tty + 5, utp->ut_line, sizeof(utp->ut_line)); ! 173: if (stat(tty, &stb) || !(stb.st_mode & S_IEXEC)) { ! 174: dsyslog(LOG_DEBUG, "%s: wrong mode on %s", utp->ut_name, tty); ! 175: return; ! 176: } ! 177: dsyslog(LOG_DEBUG, "notify %s on %s\n", utp->ut_name, tty); ! 178: if (fork()) ! 179: return; ! 180: (void)signal(SIGALRM, SIG_DFL); ! 181: (void)alarm((u_int)30); ! 182: if ((tp = fopen(tty, "w")) == NULL) { ! 183: dsyslog(LOG_ERR, "fopen of tty %s failed", tty); ! 184: _exit(-1); ! 185: } ! 186: (void)ioctl(fileno(tp), TIOCGETP, >tybuf); ! 187: cr = (gttybuf.sg_flags&CRMOD) && !(gttybuf.sg_flags&RAW) ? "" : "\r"; ! 188: (void)strncpy(name, utp->ut_name, sizeof (utp->ut_name)); ! 189: name[sizeof (name) - 1] = '\0'; ! 190: fprintf(tp, "%s\n\007New mail for %s@%.*s\007 has arrived:%s\n----%s\n", ! 191: cr, name, sizeof (hostname), hostname, cr, cr); ! 192: jkfprintf(tp, name, offset); ! 193: fclose(tp); ! 194: _exit(0); ! 195: } ! 196: ! 197: jkfprintf(tp, name, offset) ! 198: register FILE *tp; ! 199: char name[]; ! 200: off_t offset; ! 201: { ! 202: register char *cp; ! 203: register FILE *fi; ! 204: register int linecnt, charcnt, inheader; ! 205: char line[BUFSIZ]; ! 206: off_t fseek(); ! 207: ! 208: if ((fi = fopen(name, "r")) == NULL) ! 209: return; ! 210: (void)fseek(fi, offset, L_SET); ! 211: /* ! 212: * Print the first 7 lines or 560 characters of the new mail ! 213: * (whichever comes first). Skip header crap other than ! 214: * From, Subject, To, and Date. ! 215: */ ! 216: linecnt = 7; ! 217: charcnt = 560; ! 218: inheader = 1; ! 219: while (fgets(line, sizeof (line), fi) != NULL) { ! 220: if (inheader) { ! 221: if (line[0] == '\n') { ! 222: inheader = 0; ! 223: continue; ! 224: } ! 225: if (line[0] == ' ' || line[0] == '\t' || ! 226: strncmp(line, "From:", 5) && ! 227: strncmp(line, "Subject:", 8)) ! 228: continue; ! 229: } ! 230: if (cp = index(line, '\n')) ! 231: *cp = '\0'; ! 232: fprintf(tp, "%s%s\n", line, cr); ! 233: charcnt -= strlen(line); ! 234: if (--linecnt <= 0 || charcnt <= 0) { ! 235: fprintf(tp, "...more...%s\n", cr); ! 236: return; ! 237: } ! 238: } ! 239: fprintf(tp, "----%s\n", cr); ! 240: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.