home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume15 / ck / ck.c next >
Encoding:
C/C++ Source or Header  |  1988-05-30  |  4.5 KB  |  200 lines

  1. /**************************************************************************
  2.  *      ck{,d}: an incoming mail monitor.
  3.  *      Copyright (c) 1988 Wayne Mesard                                   *
  4.  *                                                                        *
  5.  *      This is free software.  It may be reproduced, retransmitted,      *
  6.  *      redistributed and otherwise propogated at will, provided that     *
  7.  *      this notice remains intact and in place.                          *
  8.  *                                                                        *
  9.  *      Direct all bug reports and comments to mesard@BBN.COM.            *
  10.  *                                                                        *
  11.  **************************************************************************/
  12.  
  13.  
  14. #include <stdio.h>
  15. #include <strings.h>
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #include <ctype.h>
  19. #include "wsm_types.h"
  20.  
  21.  
  22. main(argc, argv)
  23. int argc;
  24. char *argv[];
  25. {
  26.     extern char *getenv();
  27.     extern int atoi();
  28.     extern int getppid();    /* For parent check. */
  29.     int check_box();
  30.     time_t last_write();
  31.     
  32.     int i, c;
  33.     int interval = 120;
  34.     FILE *out_device = NULL;
  35.     boolean verbose = false;
  36.     int ppid;            /* For parent check. */
  37.     
  38.     char *ptr, mailbox[256];
  39.     time_t curr, old_mtime;
  40.  
  41.  
  42.     for (i=0; ++i<argc && argv[i][0]=='-';)
  43.     switch (argv[i][1]) {
  44.       case 'v':
  45.         verbose = true;
  46.         break;
  47.       case 'i':
  48.         interval = atoi(argv[i]+2);
  49.         break;
  50.       case 'o':
  51.             if (out_device != NULL)
  52.                 fclose(out_device);
  53.             if (i+1<argc)
  54.         if ((out_device = fopen(argv[++i], "a"))==NULL) {
  55.             perror(argv[i]+2);
  56.             exit(-1);
  57.         }
  58.             break;
  59.     }
  60.  
  61.     mailbox[0] = '\0';
  62.     if (i<argc)
  63.     strcpy(mailbox, argv[i]);
  64.  
  65.     if (mailbox[0] == '\0')
  66.     if (ptr = getenv("MAIL"))
  67.         (void) strcpy(mailbox, ptr);
  68.     else {
  69.         (void) strcpy(mailbox, getenv("HOME"));
  70.         (void) strcat(mailbox, "/mailbox");
  71.     }
  72.      
  73.     if (!strcmp("ck", argv[0]+strlen(argv[0])-2)) {
  74.     if ((c=check_box(mailbox, (out_device?out_device:stdout), verbose, false))==0)
  75.         printf("No new messages.\n");
  76.     exit(c);
  77.     }
  78.  
  79.     ppid = getppid();
  80.     if (fork())
  81.     exit(0);
  82.  
  83.     old_mtime = last_write(mailbox);
  84.     while(1) {
  85.     if (old_mtime < (curr=last_write(mailbox))) {
  86.         old_mtime = curr;
  87.         (void) check_box(mailbox, (out_device?out_device:stderr), verbose, true);
  88.     }
  89.  
  90.     sleep(interval);
  91.  
  92.     /* Check to see if parent has died (e.g., on logout).
  93.      * Commit suicide if it has.
  94.      * There must be a better way to do this! (setpgrp?)
  95.      */
  96.     if (kill(ppid, 0))
  97.         exit(0);
  98.     }
  99. }
  100.  
  101.  
  102.  
  103. time_t last_write(fn)
  104. char *fn;
  105. {
  106.   struct stat stbuf;
  107.  
  108.   stat(fn, &stbuf);
  109.   return((time_t) stbuf.st_mtime);
  110. }
  111.  
  112.  
  113. #define BUFSIZE 100
  114. #define FROM_FIELD_LEN 19
  115. #define SUBJ_FIELD_LEN 21
  116. #if (FROM_FIELD_LEN != 19 || SUBJ_FIELD_LEN != 21)
  117.     HEY! Fix the fprintf() line below.
  118. #endif
  119. #if (BUFSIZE != 100)
  120.     HEY! Fix the fscanf() line below.
  121. #endif
  122.  
  123. int check_box(fn, out_device, verbose, bell)
  124. char *fn;
  125. FILE *out_device;
  126. boolean verbose, bell;
  127. {
  128.     extern char *ctime();
  129.     void nonwhitecpy();
  130.     static char *margin =
  131.     "+---------------------------------------------+\n";
  132.     FILE *mbox;
  133.     char *devname;
  134.     char s[BUFSIZE], from_field[FROM_FIELD_LEN], 
  135.          subj_field[SUBJ_FIELD_LEN];
  136.     int headers = 0, readstat = 0;
  137.     int count = 0;
  138.  
  139.     if (mbox = fopen(fn, "r")) {
  140.     while ((readstat=fscanf(mbox, "%100[^\n]", s)) != EOF) {
  141.         (void) getc(mbox);
  142.  
  143.         if (headers) {
  144.         if (readstat==0) {
  145.             headers = 0;
  146.             if (count==0)
  147.             fprintf(out_device, "%c%s",
  148.                    (bell ? '\007' : '\0'), margin);
  149.             fprintf(out_device, "|%2d: %-18.18s{}%-20.20s |\n", 
  150.                 ++count, from_field, subj_field);
  151.         }
  152.         else if (!strncmp(s, "From:", 5))
  153.             nonwhitecpy(from_field, s+6, FROM_FIELD_LEN);
  154.  
  155.         else if (!strncmp(s, "Subject:", 8))
  156.             nonwhitecpy(subj_field, s+9, SUBJ_FIELD_LEN);
  157.         }
  158.         else if (!strncmp(s,"\001\001\001\001", 4)) {
  159.         headers = 1;
  160.         subj_field[0] = from_field[0] = '\0';
  161.         }
  162.     }
  163.     fclose(mbox);
  164.     if (count)
  165.         fprintf(out_device, margin);
  166.     }
  167.     else
  168.     verbose = true;
  169.  
  170.     if (verbose) {
  171.     struct stat stbuf;
  172.  
  173.     if (stat(fn, &stbuf))
  174.         perror(fn);
  175.     else
  176.         fprintf(out_device, 
  177.             "[%s] Size: %d chars.\nLast modified: %s", 
  178.             fn,
  179.             stbuf.st_size, 
  180.             ctime((long *)&stbuf.st_mtime));
  181.     return(-1);
  182.     }
  183.     return(count);
  184.  
  185.     
  186. }
  187.  
  188.  
  189.  
  190. void
  191. nonwhitecpy(d, s, dsize)
  192. register char *d, *s;
  193. int dsize;
  194. {
  195.     register char *dend = d+dsize;
  196.     s--;
  197.     while (isspace(*++s));
  198.     while ((*d++ = *s++) && (d<dend));
  199. }
  200.