1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: char copyright[] =
   9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: #endif not lint
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)comsat.c	5.5 (Berkeley) 10/24/85";
  15: #endif not lint
  16: 
  17: #include <sys/types.h>
  18: #include <sys/socket.h>
  19: #include <sys/stat.h>
  20: #include <sys/wait.h>
  21: #include <sys/file.h>
  22: 
  23: #include <netinet/in.h>
  24: 
  25: #include <stdio.h>
  26: #include <sgtty.h>
  27: #include <utmp.h>
  28: #include <signal.h>
  29: #include <errno.h>
  30: #include <netdb.h>
  31: #include <syslog.h>
  32: 
  33: /*
  34:  * comsat
  35:  */
  36: int debug = 0;
  37: #define dprintf if (debug) printf
  38: 
  39: struct  sockaddr_in sin = { AF_INET };
  40: extern  errno;
  41: 
  42: char    hostname[32];
  43: struct  utmp *utmp = NULL;
  44: int nutmp;
  45: int uf;
  46: unsigned utmpmtime = 0;         /* last modification time for utmp */
  47: unsigned utmpsize = 0;          /* last malloced size for utmp */
  48: int onalrm();
  49: int reapchildren();
  50: long    lastmsgtime;
  51: char    *malloc(), *realloc();
  52: 
  53: #define MAXIDLE 120
  54: #define NAMLEN (sizeof (uts[0].ut_name) + 1)
  55: 
  56: main(argc, argv)
  57:     int argc;
  58:     char *argv[];
  59: {
  60:     register int cc;
  61:     char buf[BUFSIZ];
  62:     char msgbuf[100];
  63:     struct sockaddr_in from;
  64:     int fromlen;
  65: 
  66:     /* verify proper invocation */
  67:     fromlen = sizeof (from);
  68:     if (getsockname(0, &from, &fromlen) < 0) {
  69:         fprintf(stderr, "%s: ", argv[0]);
  70:         perror("getsockname");
  71:         _exit(1);
  72:     }
  73:     chdir("/usr/spool/mail");
  74:     if ((uf = open("/etc/utmp",0)) < 0) {
  75:         openlog("comsat", 0, LOG_DAEMON);
  76:         syslog(LOG_ERR, "/etc/utmp: %m");
  77:         (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
  78:         exit(1);
  79:     }
  80:     lastmsgtime = time(0);
  81:     gethostname(hostname, sizeof (hostname));
  82:     onalrm();
  83:     signal(SIGALRM, onalrm);
  84:     signal(SIGTTOU, SIG_IGN);
  85:     signal(SIGCHLD, reapchildren);
  86:     for (;;) {
  87:         cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
  88:         if (cc <= 0) {
  89:             if (errno != EINTR)
  90:                 sleep(1);
  91:             errno = 0;
  92:             continue;
  93:         }
  94:         sigblock(sigmask(SIGALRM));
  95:         msgbuf[cc] = 0;
  96:         lastmsgtime = time(0);
  97:         mailfor(msgbuf);
  98:         sigsetmask(0);
  99:     }
 100: }
 101: 
 102: reapchildren()
 103: {
 104: 
 105:     while (wait3((struct wait *)0, WNOHANG, (struct rusage *)0) > 0)
 106:         ;
 107: }
 108: 
 109: onalrm()
 110: {
 111:     struct stat statbf;
 112: 
 113:     if (time(0) - lastmsgtime >= MAXIDLE)
 114:         exit(0);
 115:     dprintf("alarm\n");
 116:     alarm(15);
 117:     fstat(uf, &statbf);
 118:     if (statbf.st_mtime > utmpmtime) {
 119:         dprintf(" changed\n");
 120:         utmpmtime = statbf.st_mtime;
 121:         if (statbf.st_size > utmpsize) {
 122:             utmpsize = statbf.st_size + 10 * sizeof(struct utmp);
 123:             if (utmp)
 124:                 utmp = (struct utmp *)realloc(utmp, utmpsize);
 125:             else
 126:                 utmp = (struct utmp *)malloc(utmpsize);
 127:             if (! utmp) {
 128:                 dprintf("malloc failed\n");
 129:                 exit(1);
 130:             }
 131:         }
 132:         lseek(uf, 0, 0);
 133:         nutmp = read(uf,utmp,statbf.st_size)/sizeof(struct utmp);
 134:     } else
 135:         dprintf(" ok\n");
 136: }
 137: 
 138: mailfor(name)
 139:     char *name;
 140: {
 141:     register struct utmp *utp = &utmp[nutmp];
 142:     register char *cp;
 143:     char *rindex();
 144:     int offset;
 145: 
 146:     dprintf("mailfor %s\n", name);
 147:     cp = name;
 148:     while (*cp && *cp != '@')
 149:         cp++;
 150:     if (*cp == 0) {
 151:         dprintf("bad format\n");
 152:         return;
 153:     }
 154:     *cp = 0;
 155:     offset = atoi(cp+1);
 156:     while (--utp >= utmp)
 157:         if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
 158:             notify(utp, offset);
 159: }
 160: 
 161: char    *cr;
 162: 
 163: notify(utp, offset)
 164:     register struct utmp *utp;
 165: {
 166:     FILE *tp;
 167:     struct sgttyb gttybuf;
 168:     char tty[20], name[sizeof (utmp[0].ut_name) + 1];
 169:     struct stat stb;
 170: 
 171:     strcpy(tty, "/dev/");
 172:     strncat(tty, utp->ut_line, sizeof(utp->ut_line));
 173:     dprintf("notify %s on %s\n", utp->ut_name, tty);
 174:     if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) {
 175:         dprintf("wrong mode\n");
 176:         return;
 177:     }
 178:     if (fork())
 179:         return;
 180:     signal(SIGALRM, SIG_DFL);
 181:     alarm(30);
 182:     if ((tp = fopen(tty,"w")) == 0) {
 183:         dprintf("fopen failed\n");
 184:         exit(-1);
 185:     }
 186:     ioctl(fileno(tp), TIOCGETP, &gttybuf);
 187:     cr = (gttybuf.sg_flags&CRMOD) && !(gttybuf.sg_flags&RAW) ? "" : "\r";
 188:     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",
 191:         cr, name, sizeof (hostname), hostname, cr);
 192:     fprintf(tp,"----%s\n", cr);
 193:     jkfprintf(tp, name, offset);
 194:     exit(0);
 195: }
 196: 
 197: jkfprintf(tp, name, offset)
 198:     register FILE *tp;
 199: {
 200:     register FILE *fi;
 201:     register int linecnt, charcnt;
 202:     char line[BUFSIZ];
 203:     int inheader;
 204: 
 205:     dprintf("HERE %s's mail starting at %d\n",
 206:         name, offset);
 207:     if ((fi = fopen(name,"r")) == NULL) {
 208:         dprintf("Cant read the mail\n");
 209:         return;
 210:     }
 211:     fseek(fi, offset, L_SET);
 212:     /*
 213: 	 * Print the first 7 lines or 560 characters of the new mail
 214: 	 * (whichever comes first).  Skip header crap other than
 215: 	 * From, Subject, To, and Date.
 216: 	 */
 217:     linecnt = 7;
 218:     charcnt = 560;
 219:     inheader = 1;
 220:     while (fgets(line, sizeof (line), fi) != NULL) {
 221:         register char *cp;
 222:         char *index();
 223:         int cnt;
 224: 
 225:         if (linecnt <= 0 || charcnt <= 0) {
 226:             fprintf(tp,"...more...%s\n", cr);
 227:             return;
 228:         }
 229:         if (strncmp(line, "From ", 5) == 0)
 230:             continue;
 231:         if (inheader && (line[0] == ' ' || line[0] == '\t'))
 232:             continue;
 233:         cp = index(line, ':');
 234:         if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp))
 235:             inheader = 0;
 236:         else
 237:             cnt = cp - line;
 238:         if (inheader &&
 239:             strncmp(line, "Date", cnt) &&
 240:             strncmp(line, "From", cnt) &&
 241:             strncmp(line, "Subject", cnt) &&
 242:             strncmp(line, "To", cnt))
 243:             continue;
 244:         cp = index(line, '\n');
 245:         if (cp)
 246:             *cp = '\0';
 247:         fprintf(tp,"%s%s\n", line, cr);
 248:         linecnt--, charcnt -= strlen(line);
 249:     }
 250:     fprintf(tp,"----%s\n", cr);
 251: }

Defined functions

jkfprintf defined in line 197; used 1 times
mailfor defined in line 138; used 1 times
  • in line 97
main defined in line 56; never used
notify defined in line 163; used 1 times
onalrm defined in line 109; used 3 times
reapchildren defined in line 102; used 2 times

Defined variables

copyright defined in line 8; never used
cr defined in line 161; used 7 times
debug defined in line 36; used 1 times
  • in line 37
hostname defined in line 42; used 4 times
lastmsgtime defined in line 50; used 3 times
nutmp defined in line 44; used 2 times
sccsid defined in line 14; never used
sin defined in line 39; never used
uf defined in line 45; used 4 times
utmp defined in line 43; used 10 times
utmpmtime defined in line 46; used 2 times
utmpsize defined in line 47; used 4 times

Defined macros

MAXIDLE defined in line 53; used 1 times
NAMLEN defined in line 54; never used
dprintf defined in line 37; used 11 times
Last modified: 1985-11-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1940
Valid CSS Valid XHTML 1.0 Strict