1: /*
   2:  * fancied up comsat program.....
   3:  */
   4: 
   5: #ifndef lint
   6: static char *rcsid_comsat_c = "$Header: comsat.c,v 10.3 86/02/01 15:18:47 tony Rel $";
   7: #endif	lint
   8: 
   9: #define XWIND
  10: #define SHORTSWEET
  11: 
  12: #ifndef lint
  13: static  char sccsid[] = "@(#)comsat.c	4.12 (Berkeley) 8/1/84";
  14: #endif
  15: 
  16: #ifndef XWIND
  17: #include <sys/types.h>
  18: #include <sys/socket.h>
  19: #else
  20: #include <X/Xlib.h>
  21: #include <ttyent.h>
  22: #include <pwd.h>
  23: char *indexs();
  24: extern char **environ;
  25: #endif
  26: #include <sys/stat.h>
  27: #include <sys/wait.h>
  28: #include <sys/file.h>
  29: 
  30: #include <netinet/in.h>
  31: 
  32: #include <stdio.h>
  33: #include <sgtty.h>
  34: #include <utmp.h>
  35: #include <signal.h>
  36: #include <errno.h>
  37: #include <netdb.h>
  38: #include <syslog.h>
  39: 
  40: char *index(), *rindex();
  41: 
  42: /*
  43:  * comsat
  44:  */
  45: int debug = 0;
  46: #define dprintf if (debug) printf
  47: 
  48: #define MAXUTMP 100     /* down from init */
  49: 
  50: struct  sockaddr_in sin = { AF_INET };
  51: extern  errno;
  52: 
  53: char    hostname[32];
  54: struct  utmp utmp[100];
  55: int nutmp;
  56: int uf;
  57: unsigned utmpmtime;         /* last modification time for utmp */
  58: int onalrm();
  59: int reapchildren();
  60: long    lastmsgtime;
  61: 
  62: #define MAXIDLE 120
  63: #define NAMLEN (sizeof (uts[0].ut_name) + 1)
  64: 
  65: main(argc, argv)
  66:     int argc;
  67:     char *argv[];
  68: {
  69:     register int cc;
  70:     char buf[BUFSIZ];
  71:     char msgbuf[100];
  72:     struct sockaddr_in from;
  73:     int fromlen;
  74: 
  75:     /* verify proper invocation */
  76:     fromlen = sizeof (from);
  77:     if (getsockname(0, &from, &fromlen) < 0) {
  78:         fprintf(stderr, "%s: ", argv[0]);
  79:         perror("getsockname");
  80:         _exit(1);
  81:     }
  82:     chdir("/usr/spool/mail");
  83:     if ((uf = open("/etc/utmp",0)) < 0) {
  84:         openlog("comsat", 0, 0);
  85:         syslog(LOG_ERR, "/etc/utmp: %m");
  86:         (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
  87:         exit(1);
  88:     }
  89:     lastmsgtime = time(0);
  90:     gethostname(hostname, sizeof (hostname));
  91:     onalrm();
  92:     signal(SIGALRM, onalrm);
  93:     signal(SIGTTOU, SIG_IGN);
  94:     signal(SIGCHLD, reapchildren);
  95:     for (;;) {
  96:         cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
  97:         if (cc <= 0) {
  98:             if (errno != EINTR)
  99:                 sleep(1);
 100:             errno = 0;
 101:             continue;
 102:         }
 103:         sigblock(1<<SIGALRM);
 104:         msgbuf[cc] = 0;
 105:         lastmsgtime = time(0);
 106:         mailfor(msgbuf);
 107:         sigsetmask(0);
 108:     }
 109: }
 110: 
 111: reapchildren()
 112: {
 113: 
 114:     while (wait3((struct wait *)0, WNOHANG, (struct rusage *)0) > 0)
 115:         ;
 116: }
 117: 
 118: onalrm()
 119: {
 120:     struct stat statbf;
 121:     struct utmp *utp;
 122: 
 123:     if (time(0) - lastmsgtime >= MAXIDLE)
 124:         exit(0);
 125:     dprintf("alarm\n");
 126:     alarm(15);
 127:     fstat(uf, &statbf);
 128:     if (statbf.st_mtime > utmpmtime) {
 129:         dprintf(" changed\n");
 130:         utmpmtime = statbf.st_mtime;
 131:         lseek(uf, 0, 0);
 132:         nutmp = read(uf,utmp,sizeof(utmp))/sizeof(struct utmp);
 133:     } else
 134:         dprintf(" ok\n");
 135: }
 136: 
 137: mailfor(name)
 138:     char *name;
 139: {
 140:     register struct utmp *utp = &utmp[nutmp];
 141:     register char *cp;
 142:     int offset;
 143: 
 144:     dprintf("mailfor %s\n", name);
 145:     cp = name;
 146:     while (*cp && *cp != '@')
 147:         cp++;
 148:     if (*cp == 0) {
 149:         dprintf("bad format\n");
 150:         return;
 151:     }
 152:     *cp = 0;
 153:     offset = atoi(cp+1);
 154:     while (--utp >= utmp)
 155:         if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
 156:             notify(utp, offset);
 157: }
 158: 
 159: char    *cr;
 160: 
 161: notify(utp, offset)
 162:     register struct utmp *utp;
 163: {
 164:     int fd, flags, n, err, msglen;
 165:     struct sgttyb gttybuf;
 166:     char tty[sizeof (utmp[0].ut_line) + 6], msgbuf[BUFSIZ];
 167:     char name[sizeof (utmp[0].ut_name) + 1];
 168:     struct stat stb;
 169: #ifdef XWIND
 170:     struct ttyent *te;
 171:     char *s;
 172:     char dname[260];
 173: #endif
 174: 
 175:     strcpy(tty, "/dev/");
 176:     strncat(tty, utp->ut_line, sizeof(utp->ut_line));
 177:     dprintf("notify %s on %s\n", utp->ut_name, tty);
 178:     if (stat(tty, &stb) == 0 && (stb.st_mode & 0100) == 0) {
 179:         dprintf("wrong mode\n");
 180:         return;
 181:     }
 182:     strncpy(name, utp->ut_name, sizeof (utp->ut_name));
 183:     name[sizeof (name) - 1] = '\0';
 184: #ifdef XWIND
 185:     te = getttynam(tty+5);
 186:     if ((s = indexs(te->ty_getty, "xterm")) &&
 187:         (s = indexs(s, " -L ")) &&
 188:         (s = index(s, ':'))) {
 189:         while (*(--s) != ' ') ;
 190:         s++;
 191:         if (*s == ':') {
 192:             gethostname(dname, sizeof (dname));
 193:             strcat(dname, s);
 194:         } else
 195:             strcpy(dname, s);
 196:         Xprintf(msgbuf, name, offset);
 197:         if (fork())
 198:             return;
 199:         Xnotify(name, dname, msgbuf);
 200:     }
 201: #endif
 202:     if ((fd = open(tty, O_WRONLY|O_NDELAY)) < 0) {
 203:         dprintf("%s: open failed\n", tty);
 204:         return;
 205:     }
 206:     if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
 207:         dprintf("fcntl(F_GETFL) failed %d\n", errno);
 208:         return;
 209:     }
 210:     ioctl(fd, TIOCGETP, &gttybuf);
 211:     cr = (gttybuf.sg_flags & CRMOD) ? "" : "\r";
 212: #ifdef SHORTSWEET
 213:     sprintf(msgbuf, "%s\n\007New mail from ", cr);
 214: #else
 215:     sprintf(msgbuf, "%s\n\007New mail for %s@%s\007 has arrived:%s\n",
 216:         cr, name, hostname, cr);
 217: #endif
 218:     jkfprintf(msgbuf+strlen(msgbuf), name, offset);
 219:     if (fcntl(fd, F_SETFL, flags | FNDELAY) == -1)
 220:         goto oldway;
 221:     msglen = strlen(msgbuf);
 222:     n = write(fd, msgbuf, msglen);
 223:     err = errno;
 224:     (void) fcntl(fd, F_SETFL, flags);
 225:     (void) close(fd);
 226:     if (n == msglen)
 227:         return;
 228:     if (err != EWOULDBLOCK) {
 229:         dprintf("write failed %d\n", errno);
 230:         return;
 231:     }
 232: oldway:
 233:     if (fork()) {
 234:         (void) close(fd);
 235:         return;
 236:     }
 237:     signal(SIGALRM, SIG_DFL);
 238:     alarm(30);
 239:     (void) write(fd, msgbuf, msglen);
 240:     exit(0);
 241: }
 242: 
 243: #ifdef SHORTSWEET
 244: jkfprintf(mp, name, offset)
 245:     register char *mp;
 246: {
 247:     register FILE *fi;
 248:     char line[BUFSIZ];
 249: 
 250:     dprintf("HERE %s's mail starting at %d\n", name, offset);
 251: 
 252:     if ((fi = fopen(name, "r")) == NULL) {
 253:         dprintf("Cant read the mail\n");
 254:         return;
 255:     }
 256:     fseek(fi, offset, L_SET);
 257:     /*
 258:          * put the contents of the From: line into mp buffer
 259: 	 */
 260:     while (fgets(line, sizeof (line), fi) != NULL) {
 261:             register char *cp;
 262: 
 263:                 if (strncmp (line, "From:", 5) != 0)
 264:             continue;
 265:         cp = index(line, '\n');
 266:         if (cp)
 267:             *cp = '\0';
 268:                 for (cp = line+5; (*cp == ' ' || *cp == '\t'); cp++);
 269:         sprintf(mp, "%s%s\n", cp, cr);
 270:                 return;
 271:     }
 272:         /* didn't find the From: line */
 273:         sprintf (mp, "???%s\n", cr);
 274: }
 275: #else
 276: jkfprintf(mp, name, offset)
 277:     register char *mp;
 278: {
 279:     register FILE *fi;
 280:     register int linecnt, charcnt;
 281:     char line[BUFSIZ];
 282:     int inheader;
 283: 
 284:     dprintf("HERE %s's mail starting at %d\n", name, offset);
 285: 
 286:     if ((fi = fopen(name, "r")) == NULL) {
 287:         dprintf("Cant read the mail\n");
 288:         return;
 289:     }
 290:     fseek(fi, offset, L_SET);
 291:     /*
 292: 	 * Print the first 7 lines or 560 characters of the new mail
 293: 	 * (whichever comes first).  Skip header crap other than
 294: 	 * From, Subject, To, and Date.
 295: 	 */
 296:     linecnt = 7;
 297:     charcnt = 560;
 298:     inheader = 1;
 299:     while (fgets(line, sizeof (line), fi) != NULL) {
 300:         register char *cp;
 301:         int cnt;
 302: 
 303:         if (linecnt <= 0 || charcnt <= 0) {
 304:             sprintf(mp, "...more...%s\n", cr);
 305:             mp += strlen(mp);
 306:             return;
 307:         }
 308:         if (strncmp(line, "From ", 5) == 0)
 309:             continue;
 310:         if (inheader && (line[0] == ' ' || line[0] == '\t'))
 311:             continue;
 312:         cp = index(line, ':');
 313:         if (cp == 0 || (index(line, ' ') && index(line, ' ') < cp))
 314:             inheader = 0;
 315:         else
 316:             cnt = cp - line;
 317:         if (inheader &&
 318:             strncmp(line, "Date", cnt) &&
 319:             strncmp(line, "From", cnt) &&
 320:             strncmp(line, "Subject", cnt) &&
 321:             strncmp(line, "To", cnt))
 322:             continue;
 323:         cp = index(line, '\n');
 324:         if (cp)
 325:             *cp = '\0';
 326:         sprintf(mp, "%s%s\n", line, cr);
 327:         mp += strlen(mp);
 328:         linecnt--, charcnt -= strlen(line);
 329:     }
 330:     sprintf(mp, "----%s\n", cr);
 331:     mp += strlen(mp);
 332: }
 333: #endif
 334: 
 335: #ifdef XWIND
 336: char *indexs(s1, s2)
 337:     register char *s1, *s2;
 338: {
 339:     register int z = strlen(s2);
 340:     while (*s1 && strncmp(s1, s2, z))
 341:         s1++;
 342:     return(s1);
 343: }
 344: 
 345: Xprintf(mp, name, offset)
 346:     register char *mp;
 347: {
 348:     register FILE *fi;
 349:     char line[BUFSIZ];
 350: 
 351:     dprintf("HERE %s's mail starting at %d\n", name, offset);
 352: 
 353:     sprintf(mp, "You have new mail.");
 354:     if ((fi = fopen(name, "r")) == NULL) {
 355:         dprintf("Cant read the mail\n");
 356:         return;
 357:     }
 358:     fseek(fi, offset, L_SET);
 359:     /*
 360:          * put the contents of the From: line into mp buffer
 361: 	 */
 362:     while (fgets(line, sizeof (line), fi) != NULL) {
 363:             register char *cp;
 364: 
 365:                 if (strncmp (line, "From:", 5) != 0)
 366:             continue;
 367:         cp = index(line, '\n');
 368:         if (cp)
 369:             *cp = '\0';
 370:                 for (cp = line+5; (*cp == ' ' || *cp == '\t'); cp++);
 371:         sprintf(mp, "Mail from %s", cp);
 372:         break;
 373:     }
 374:     fclose(fi);
 375: }
 376: 
 377: short cursor[] = {0x0000, 0x7ffe, 0x4fc2, 0x4ffe, 0x7ffe,
 378:           0x7ffe, 0x781e, 0x7ffe , 0x7ffe, 0x0000};
 379: 
 380: Xnotify (name, dname, notice)
 381:     char *name;
 382:     char *dname;
 383:     char *notice;
 384: {
 385:     struct passwd *pwent;
 386:     char *envbuf[2];
 387:     char homebuf[280];
 388:     Display *dpy;
 389:     WindowInfo winfo;
 390:     FontInfo finfo;
 391:     Font font;
 392:     int width, height;
 393:     Window w;
 394:     XEvent rep;
 395:     int timeout = 0;
 396:     int reverse = 0;
 397:     int bwidth = 2;
 398:     int inner = 2;
 399:     int vertical = 2;
 400:     int volume = 0;
 401:     int forepix = BlackPixel;
 402:     int backpix = WhitePixel;
 403:     int brdrpix = BlackPixel;
 404:     int mouspix = BlackPixel;
 405:     char *option;
 406:     char *font_name = "8x13";
 407:     char *fore_color = NULL;
 408:     char *back_color = NULL;
 409:     char *brdr_color = NULL;
 410:     char *mous_color = NULL;
 411:     Color cdef;
 412: 
 413:     if (!XOpenDisplay(dname))
 414:         exit(0);
 415:     if (pwent = getpwnam(name)) {
 416:         strcpy(homebuf, "HOME=");
 417:         strcat(homebuf, pwent->pw_dir);
 418:         envbuf[0] = homebuf;
 419:         envbuf[1] = NULL;
 420:         environ = envbuf;
 421:         if (option = XGetDefault("biff", "BodyFont"))
 422:             font_name = option;
 423:         fore_color = XGetDefault("biff", "Foreground");
 424:         back_color = XGetDefault("biff", "Background");
 425:         brdr_color = XGetDefault("biff", "Border");
 426:         mous_color = XGetDefault("biff", "Mouse");
 427:         if (option = XGetDefault("biff", "BorderWidth"))
 428:             bwidth = atoi(option);
 429:         if (option = XGetDefault("biff", "InternalBorder"))
 430:             inner = atoi(option);
 431:         if (option = XGetDefault("biff", "Timeout"))
 432:             timeout = atoi(option);
 433:         if (option = XGetDefault("biff", "Volume"))
 434:             volume = atoi(option);
 435:         if (option = XGetDefault("biff", "Offset"))
 436:             vertical = atoi(option);
 437:         if ((option = XGetDefault("biff", "ReverseVideo")) &&
 438:             strcmp(option, "on") == 0)
 439:             reverse = 1;
 440:     }
 441:     if (reverse) {
 442:         brdrpix = backpix;
 443:         backpix = forepix;
 444:         forepix = brdrpix;
 445:         mouspix = forepix;
 446:     }
 447: 
 448:     if ((font = XGetFont(font_name)) == NULL)
 449:         exit(0);
 450:     if (DisplayCells() > 2) {
 451:         if (back_color && XParseColor(back_color, &cdef) &&
 452:             XGetHardwareColor(&cdef))
 453:             backpix = cdef.pixel;
 454:         if (fore_color && XParseColor(fore_color, &cdef) &&
 455:             XGetHardwareColor(&cdef))
 456:             forepix = cdef.pixel;
 457:         if (brdr_color && XParseColor(brdr_color, &cdef) &&
 458:             XGetHardwareColor(&cdef))
 459:             brdrpix = cdef.pixel;
 460:         if (mous_color && XParseColor(mous_color, &cdef) &&
 461:             XGetHardwareColor(&cdef))
 462:             mouspix = cdef.pixel;
 463:     }
 464:     XQueryFont(font, &finfo);
 465:     XQueryWindow (RootWindow, &winfo);
 466:     width = XQueryWidth (notice, font) + (inner << 1);
 467:     height = finfo.height + (inner << 1);
 468:     if (vertical < 0)
 469:         vertical += winfo.height - height - (bwidth << 1);
 470:     w = XCreateWindow(RootWindow, (winfo.width - width - (bwidth << 1)) / 2,
 471:               vertical, width, height, bwidth,
 472:               XMakeTile(brdrpix), XMakeTile(backpix));
 473:     XStoreName(w, notice);
 474:     XSelectInput(w, ButtonPressed|ButtonReleased|ExposeWindow);
 475:     XDefineCursor(w, XCreateCursor(16, 10, cursor, NULL, 7, 5,
 476:                        mouspix, backpix, GXcopy));
 477:     XMapWindow(w);
 478:     XFeep(volume);
 479:     if (timeout > 0) {
 480:         signal(SIGALRM, exit);
 481:         alarm(timeout * 60);
 482:     }
 483:     if (inner) inner--;
 484:     while (1) {
 485:         XText(w, inner, inner, notice, strlen(notice),
 486:             font, forepix, backpix);
 487:         XNextEvent(&rep);
 488:         if (rep.type == ButtonPressed)
 489:             exit(0);
 490:     }
 491: }
 492: #endif

Defined functions

Xnotify defined in line 380; used 1 times
Xprintf defined in line 345; used 1 times
indexs defined in line 336; used 3 times
jkfprintf defined in line 276; used 1 times
mailfor defined in line 137; used 1 times
main defined in line 65; never used
notify defined in line 161; used 1 times
onalrm defined in line 118; used 3 times
reapchildren defined in line 111; used 2 times

Defined variables

cr defined in line 159; used 9 times
cursor defined in line 377; used 1 times
debug defined in line 45; used 1 times
  • in line 46
hostname defined in line 53; used 3 times
lastmsgtime defined in line 60; used 3 times
nutmp defined in line 55; used 2 times
rcsid_comsat_c defined in line 6; never used
sccsid defined in line 13; never used
sin defined in line 50; never used
uf defined in line 56; used 4 times
utmp defined in line 54; used 7 times
utmpmtime defined in line 57; used 2 times

Defined macros

MAXIDLE defined in line 62; used 1 times
MAXUTMP defined in line 48; never used
NAMLEN defined in line 63; never used
SHORTSWEET defined in line 10; used 2 times
XWIND defined in line 9; used 4 times
dprintf defined in line 46; used 16 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2136
Valid CSS Valid XHTML 1.0 Strict