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 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.
  11:  */
  12: 
  13: #if !defined(lint) && defined(DOSCCS)
  14: char copyright[] =
  15: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  16:  All rights reserved.\n";
  17: 
  18: static char sccsid[] = "@(#)comsat.c	5.11.2 (2.11BSD) 1999/9/15";
  19: #endif
  20: 
  21: #include <unistd.h>
  22: #include <stdlib.h>
  23: #include <sys/param.h>
  24: #include <sys/socket.h>
  25: #include <sys/stat.h>
  26: #include <sys/file.h>
  27: #include <sys/wait.h>
  28: 
  29: #include <netinet/in.h>
  30: 
  31: #include <stdio.h>
  32: #include <sgtty.h>
  33: #include <utmp.h>
  34: #include <signal.h>
  35: #include <errno.h>
  36: #include <netdb.h>
  37: #include <syslog.h>
  38: #include <strings.h>
  39: #include <time.h>
  40: 
  41: /*
  42:  * comsat
  43:  */
  44: int debug = 0;
  45: #define dsyslog if (debug) syslog
  46: 
  47: #define MAXIDLE 120
  48: 
  49: char    hostname[MAXHOSTNAMELEN];
  50: struct  utmp *utmp = NULL;
  51: time_t  lastmsgtime;
  52: int nutmp, uf;
  53: 
  54: main(argc, argv)
  55:     int argc;
  56:     char **argv;
  57: {
  58:     register int cc;
  59:     char msgbuf[100];
  60:     struct sockaddr_in from;
  61:     int fromlen, reapchildren(), onalrm();
  62:     sigset_t set, oset;
  63: 
  64:     /* verify proper invocation */
  65:     fromlen = sizeof (from);
  66:     if (getsockname(0, &from, &fromlen) < 0) {
  67:         fprintf(stderr, "%s: ", argv[0]);
  68:         perror("getsockname");
  69:         exit(1);
  70:     }
  71:     openlog("comsat", LOG_PID, LOG_DAEMON);
  72:     if (chdir("/usr/spool/mail")) {
  73:         syslog(LOG_ERR, "chdir: /usr/spool/mail: %m");
  74:         exit(1);
  75:     }
  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);
  79:         exit(1);
  80:     }
  81:     (void)time(&lastmsgtime);
  82:     (void)gethostname(hostname, sizeof (hostname));
  83:     onalrm();
  84:     (void)signal(SIGALRM, onalrm);
  85:     (void)signal(SIGTTOU, SIG_IGN);
  86:     (void)signal(SIGCHLD, reapchildren);
  87:     for (;;) {
  88:         cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
  89:         if (cc <= 0) {
  90:             sleep(1);
  91:             continue;
  92:         }
  93:         if (!nutmp)     /* no one has logged in yet */
  94:             continue;
  95:         sigemptyset(&set);
  96:         sigaddset(&set, SIGALRM);
  97:         sigprocmask(SIG_BLOCK, &set, &oset);
  98:         msgbuf[cc] = 0;
  99:         (void)time(&lastmsgtime);
 100:         mailfor(msgbuf);
 101:         sigprocmask(SIG_SETMASK, &oset, NULL);
 102:     }
 103: }
 104: 
 105: reapchildren()
 106: {
 107:     while (wait4(-1, NULL, WNOHANG, NULL) > 0)
 108:         ;
 109: }
 110: 
 111: onalrm()
 112: {
 113:     static u_int utmpsize;      /* last malloced size for utmp */
 114:     static u_int utmpmtime;     /* last modification time for utmp */
 115:     struct stat statbf;
 116: 
 117:     if (time((time_t *)NULL) - lastmsgtime >= MAXIDLE)
 118:         exit(0);
 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);
 125:             if (utmp)
 126:                 utmp = (struct utmp *)realloc((char *)utmp, utmpsize);
 127:             else
 128:                 utmp = (struct utmp *)malloc(utmpsize);
 129:             if (!utmp) {
 130:                 syslog(LOG_ERR, "malloc failed");
 131:                 exit(1);
 132:             }
 133:         }
 134:         (void)lseek(uf, 0L, L_SET);
 135:         nutmp = read(uf, utmp, (int)statbf.st_size)/sizeof(struct utmp);
 136:     }
 137: }
 138: 
 139: mailfor(name)
 140:     char *name;
 141: {
 142:     register struct utmp *utp = &utmp[nutmp];
 143:     register char *cp;
 144:     off_t offset;
 145: 
 146:     if (!(cp = index(name, '@')))
 147:         return;
 148:     *cp = '\0';
 149:     offset = atol(cp + 1);
 150:     while (--utp >= utmp)
 151:         if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
 152:             notify(utp, offset);
 153: }
 154: 
 155: static char *cr;
 156: 
 157: notify(utp, offset)
 158:     register struct utmp *utp;
 159:     off_t offset;
 160: {
 161:     static char tty[20] = "/dev/";
 162:     struct sgttyb gttybuf;
 163:     FILE *tp;
 164:     char name[sizeof (utmp[0].ut_name) + 1];
 165:     struct stat stb;
 166: 
 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);
 170:         return;
 171:     }
 172:     dsyslog(LOG_DEBUG, "notify %s on %s\n", utp->ut_name, tty);
 173:     if (fork())
 174:         return;
 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);
 179:         _exit(-1);
 180:     }
 181:     (void)ioctl(fileno(tp), TIOCGETP, &gttybuf);
 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);
 188:     fclose(tp);
 189:     _exit(0);
 190: }
 191: 
 192: jkfprintf(tp, name, offset)
 193:     register FILE *tp;
 194:     char name[];
 195:     off_t offset;
 196: {
 197:     register char *cp;
 198:     register FILE *fi;
 199:     int linecnt, charcnt, inheader;
 200:     char line[BUFSIZ];
 201: 
 202:     if ((fi = fopen(name, "r")) == NULL)
 203:         return;
 204:     (void)fseek(fi, offset, L_SET);
 205:     /*
 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.
 209: 	 */
 210:     linecnt = 7;
 211:     charcnt = 560;
 212:     inheader = 1;
 213:     while (fgets(line, sizeof (line), fi) != NULL) {
 214:         if (inheader) {
 215:             if (line[0] == '\n') {
 216:                 inheader = 0;
 217:                 continue;
 218:             }
 219:             if (line[0] == ' ' || line[0] == '\t' ||
 220:                 strncmp(line, "From:", 5) &&
 221:                 strncmp(line, "Subject:", 8))
 222:                 continue;
 223:         }
 224:         if (cp = index(line, '\n'))
 225:             *cp = '\0';
 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);
 230:             return;
 231:         }
 232:     }
 233:     fprintf(tp, "----%s\n", cr);
 234: }

Defined functions

jkfprintf defined in line 192; used 1 times
mailfor defined in line 139; used 1 times
main defined in line 54; never used
notify defined in line 157; used 1 times
onalrm defined in line 111; used 3 times
reapchildren defined in line 105; used 2 times

Defined variables

copyright defined in line 14; never used
cr defined in line 155; used 7 times
debug defined in line 44; used 1 times
  • in line 45
hostname defined in line 49; used 4 times
lastmsgtime defined in line 51; used 3 times
nutmp defined in line 52; used 3 times
sccsid defined in line 18; never used
uf defined in line 52; used 4 times
utmp defined in line 50; used 10 times

Defined macros

MAXIDLE defined in line 47; used 1 times
dsyslog defined in line 45; used 3 times
Last modified: 1999-09-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3575
Valid CSS Valid XHTML 1.0 Strict