2 * Copyright (c) 1980 Regents of the University of California.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that this notice is preserved and that due credit is given
7 * to the University of California at Berkeley. The name of the University
8 * may not be used to endorse or promote products derived from this
9 * software without specific written prior permission. This software
10 * is provided ``as is'' without express or implied warranty.
13 #if !defined(lint) && defined(DOSCCS)
15 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
16 All rights reserved.\n";
18 static char sccsid[] = "@(#)comsat.c 5.11.2 (2.11BSD) 1999/9/15";
23 #include <sys/param.h>
24 #include <sys/socket.h>
29 #include <netinet/in.h>
45 #define dsyslog if (debug) syslog
49 char hostname[MAXHOSTNAMELEN];
50 struct utmp *utmp = NULL;
60 struct sockaddr_in from;
61 int fromlen, reapchildren(), onalrm();
64 /* verify proper invocation */
65 fromlen = sizeof (from);
66 if (getsockname(0, &from, &fromlen) < 0) {
67 fprintf(stderr, "%s: ", argv[0]);
68 perror("getsockname");
71 openlog("comsat", LOG_PID, LOG_DAEMON);
72 if (chdir("/usr/spool/mail")) {
73 syslog(LOG_ERR, "chdir: /usr/spool/mail: %m");
76 if ((uf = open(_PATH_UTMP, O_RDONLY, 0)) < 0) {
77 syslog(LOG_ERR, ".main: %s: %m", _PATH_UTMP);
78 (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
81 (void)time(&lastmsgtime);
82 (void)gethostname(hostname, sizeof (hostname));
84 (void)signal(SIGALRM, onalrm);
85 (void)signal(SIGTTOU, SIG_IGN);
86 (void)signal(SIGCHLD, reapchildren);
88 cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
93 if (!nutmp) /* no one has logged in yet */
96 sigaddset(&set, SIGALRM);
97 sigprocmask(SIG_BLOCK, &set, &oset);
99 (void)time(&lastmsgtime);
101 sigprocmask(SIG_SETMASK, &oset, NULL);
107 while (wait4(-1, NULL, WNOHANG, NULL) > 0)
113 static u_int utmpsize; /* last malloced size for utmp */
114 static u_int utmpmtime; /* last modification time for utmp */
117 if (time((time_t *)NULL) - lastmsgtime >= MAXIDLE)
119 (void)alarm((u_int)15);
120 (void)fstat(uf, &statbf);
121 if (statbf.st_mtime > utmpmtime) {
122 utmpmtime = statbf.st_mtime;
123 if (statbf.st_size > utmpsize) {
124 utmpsize = statbf.st_size + 10 * sizeof(struct utmp);
126 utmp = (struct utmp *)realloc((char *)utmp, utmpsize);
128 utmp = (struct utmp *)malloc(utmpsize);
130 syslog(LOG_ERR, "malloc failed");
134 (void)lseek(uf, 0L, L_SET);
135 nutmp = read(uf, utmp, (int)statbf.st_size)/sizeof(struct utmp);
142 register struct utmp *utp = &utmp[nutmp];
146 if (!(cp = index(name, '@')))
149 offset = atol(cp + 1);
150 while (--utp >= utmp)
151 if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
158 register struct utmp *utp;
161 static char tty[20] = "/dev/";
162 struct sgttyb gttybuf;
164 char name[sizeof (utmp[0].ut_name) + 1];
167 (void)strncpy(tty + 5, utp->ut_line, sizeof(utp->ut_line));
168 if (stat(tty, &stb) || !(stb.st_mode & S_IEXEC)) {
169 dsyslog(LOG_DEBUG, "%s: wrong mode on %s", utp->ut_name, tty);
172 dsyslog(LOG_DEBUG, "notify %s on %s\n", utp->ut_name, tty);
175 (void)signal(SIGALRM, SIG_DFL);
176 (void)alarm((u_int)30);
177 if ((tp = fopen(tty, "w")) == NULL) {
178 dsyslog(LOG_ERR, "fopen of tty %s failed", tty);
181 (void)ioctl(fileno(tp), TIOCGETP, >tybuf);
182 cr = (gttybuf.sg_flags&CRMOD) && !(gttybuf.sg_flags&RAW) ? "" : "\r";
183 (void)strncpy(name, utp->ut_name, sizeof (utp->ut_name));
184 name[sizeof (name) - 1] = '\0';
185 fprintf(tp, "%s\n\007New mail for %s@%.*s\007 has arrived:%s\n----%s\n",
186 cr, name, sizeof (hostname), hostname, cr, cr);
187 jkfprintf(tp, name, offset);
192 jkfprintf(tp, name, offset)
199 int linecnt, charcnt, inheader;
202 if ((fi = fopen(name, "r")) == NULL)
204 (void)fseek(fi, offset, L_SET);
206 * Print the first 7 lines or 560 characters of the new mail
207 * (whichever comes first). Skip header crap other than
208 * From, Subject, To, and Date.
213 while (fgets(line, sizeof (line), fi) != NULL) {
215 if (line[0] == '\n') {
219 if (line[0] == ' ' || line[0] == '\t' ||
220 strncmp(line, "From:", 5) &&
221 strncmp(line, "Subject:", 8))
224 if (cp = index(line, '\n'))
226 fprintf(tp, "%s%s\n", line, cr);
227 charcnt -= strlen(line);
228 if (--linecnt <= 0 || charcnt <= 0) {
229 fprintf(tp, "...more...%s\n", cr);
233 fprintf(tp, "----%s\n", cr);