# 2.11BSD#431 - /usr/src/libexec/comsat/comsat.c

##### Functions

    jkfprintf         X
    mailfor           X
    main              X
    notify            X
    onalrm            X
    reapchildren      X

##### Variables

    copyright         X
    debug             X
    hostname          X
    lastmsgtime       X
    nutmp             X
    uf                X
    utmp              X

##### Macros

    MAXIDLE           X
    dsyslog           X

       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

- in line 187

mailfor defined in line 139; used 1 times

- in line 100

main defined in line 54; never used
notify defined in line 157; used 1 times

- in line 152

onalrm defined in line 111; used 3 times

- in line 61, 83-84(2)

reapchildren defined in line 105; used 2 times

- in line 61, 86

#### Defined variables

copyright defined in line 14; never used
cr defined in line 155; used 7 times

- in line 182-186(4), 226-233(3)

debug defined in line 44; used 1 times

- in line 45

hostname defined in line 49; used 4 times

- in line 82(2), 186(2)

lastmsgtime defined in line 51; used 3 times

- in line 81, 99, 117

nutmp defined in line 52; used 3 times

- in line 93, 135, 142

sccsid defined in line 18; never used
uf defined in line 52; used 4 times

- in line 76, 120, 134-135(2)

utmp defined in line 50; used 10 times

- in line 125-129(5), 135, 142, 150-151(2), 164

#### Defined macros

MAXIDLE defined in line 47; used 1 times

- in line 117

dsyslog defined in line 45; used 3 times

- in line 169-172(2), 178

Last modified: 1999-09-16 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1099 |