home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / uk-sendmail2.1 / Support / uumailclean.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-11  |  7.3 KB  |  385 lines

  1. #include "uucp.h"
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #ifdef    BSD42
  5. #include <sys/dir.h>
  6. #endif    BSD42
  7. #ifdef    NDIR
  8. #include <ndir.h>
  9. #endif    NDIR
  10. #ifdef    LIBNDIR
  11. #include "LIBNDIR/ndir.h"
  12. #endif    LIBNDIR
  13.  
  14. /*
  15.  *  uumailclean  -  this program searches through the uucp spool directory
  16.  *    looking for mail files.  Files which have been around for longer
  17.  *    than "failtime" hours will be returned to the sender.  If a file
  18.  *    has been around longer than "warntime" hours, then a warning
  19.  *    message is sent (once) to the sender.
  20.  *
  21.  *    If you use L.dirs to specify subdirectories, then failtime and
  22.  *    warntime can be specified as 3rd and 4th arguments to the directory
  23.  *    entries respectively: e.g.   "C. 336 168 72"
  24.  *    By default, these times are 1 week and 3 days.
  25.  *
  26.  *    Written by Jim Crammond        <jim@cs.hw.ac.uk>    3/86
  27.  */
  28.  
  29. #define FAILTIME 168    /* default hours before returning the mail */
  30. #define WARNTIME 72    /* default hours before sending a warning */
  31.  
  32. #define WARNFILE UUCPDIR/uucp/warnlist.mail"
  33.  
  34. int    warntime, failtime;
  35.  
  36. main(argc, argv)
  37. char *argv[];
  38. {
  39. #ifdef    SUBCS
  40.     FILE *fdirs;
  41. #endif    SUBCS
  42.     char file[NAMESIZE];
  43.     char cdir[ MAXFULLNAME ];
  44.     char *flds[10];
  45.     int nflds, ret;
  46.     int orig_uid = getuid();
  47.  
  48.     strcpy(Progname, "uumailclean");
  49.     uucpname(Myname);
  50.     chkdebug(orig_uid);
  51.  
  52.     /* cd to spool */
  53.     ASSERT(subchdir(Spool) != -1, "cannot chdir to ", Spool, 0 );
  54.  
  55.     init_warnedlist(WARNFILE);
  56.  
  57. #ifdef SUBCS
  58.     fdirs=fopen(DIRFILE,"r");
  59.     ASSERT(fdirs != NULL, "uumailclean cannot open", DIRFILE, 0);
  60.  
  61.     while (cfgets(cdir, sizeof(cdir), fdirs) != NULL)
  62.     {    nflds = getargs( cdir, flds );
  63.         ASSERT(nflds >= 1, "BAD entry in", DIRFILE, 0);
  64.  
  65.         /* only interested in command files */
  66.         if (flds[0][0] != CMDPRE)
  67.             continue;
  68.  
  69.         failtime = (nflds > 2) ? atoi(flds[2]) : FAILTIME;
  70.         warntime = (nflds > 3) ? atoi(flds[3]) : WARNTIME;
  71.  
  72.         checkfiles(flds[0]);
  73.     }
  74. #else    SUBCS
  75.     failtime = FAILTIME;
  76.     warntime = WARNTIME;
  77.  
  78.     checkfiles(".");
  79. #endif    SUBCS
  80.  
  81.     exit(0);
  82. }
  83.  
  84.  
  85. /*
  86.  *  checkfiles  -  scan a directory looking for "old" control files.
  87.  *           For each one found, call fail or warn as appropriate.
  88.  */
  89. checkfiles(dir)
  90. char    *dir;
  91. {
  92.     DIR *dirp;
  93.     char    file[NAMESIZE];
  94.     struct    stat stbuf;
  95.     time_t    now;
  96.     int    hours;
  97.  
  98.     time(&now);
  99.  
  100.     DEBUG(5, "checkfiles(%s)\n", dir);
  101.     if ((dirp = opendir(dir)) == NULL)
  102.     {    printf("directory unreadable\n");
  103.         return;
  104.     }
  105.  
  106.     while (gnamef(dirp, file))
  107.     {    if (file[0] != CMDPRE)
  108.             continue;
  109.  
  110.         if (stat(subfile(file), &stbuf) == -1)
  111.         {    DEBUG(4, "stat on %s failed\n", file);
  112.             continue;
  113.         }
  114.  
  115.         if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
  116.             continue;
  117.  
  118.         hours = (int) (now - stbuf.st_mtime) / 3600;
  119.         if (hours >= failtime)
  120.             fail(file, hours);
  121.         else if (hours >= warntime)
  122.             warn(file, hours);
  123.     }
  124. }
  125.  
  126.  
  127. /*
  128.  *  fail  -  send a failure message to the sender and delete the mail.
  129.  */
  130. fail(cmdfile, hours)
  131. char    *cmdfile;
  132. int    hours;
  133. {
  134.     char    dfile[NAMESIZE], xfile[NAMESIZE];
  135.     char    host[NAMESIZE];
  136.     char    *from, **to;
  137.     char    *sender(), **recipients();
  138.  
  139.     DEBUG(4, "fail called on %s\n", cmdfile);
  140.     getfnames(cmdfile, dfile, xfile);
  141.  
  142.     if ((to = recipients(xfile)) == NULL)
  143.         return;
  144.     if ((from = sender(dfile)) == NULL)
  145.         return;
  146.     strcpy(host, &cmdfile[2]);
  147.     host[ strlen(cmdfile)-7 ] = '\0';
  148.  
  149.     sendfailure(from, to, host, hours, dfile);
  150.  
  151.     unlink(subfile(cmdfile));
  152.     unlink(subfile(dfile));
  153.     unlink(subfile(xfile));
  154.  
  155.     return;
  156. }
  157.  
  158.  
  159. /*
  160.  *  warn  -  send a warning message to the sender and add the control file
  161.  *         to the list of files for which warnings have been sent.
  162.  */
  163. warn(cmdfile, hours)
  164. char    *cmdfile;
  165. int    hours;
  166. {
  167.     char    dfile[NAMESIZE], xfile[NAMESIZE];
  168.     char    host[NAMESIZE];
  169.     char    *from, **to;
  170.     char    *sender(), **recipients();
  171.  
  172.     if (in_warnedlist(cmdfile))
  173.         return;
  174.  
  175.     DEBUG(4, "warn called on %s\n", cmdfile);
  176.     getfnames(cmdfile, dfile, xfile);
  177.  
  178.     if ((to = recipients(xfile)) == NULL)
  179.         return;
  180.     if ((from = sender(dfile)) == NULL)
  181.         return;
  182.     strcpy(host, &cmdfile[2]);
  183.     host[ strlen(cmdfile)-7 ] = '\0';
  184.  
  185.     sendwarning(from, to, host, hours, failtime, dfile);
  186.  
  187.     add_warnedlist(cmdfile);
  188.  
  189.     return;
  190. }
  191.  
  192. /*
  193.  *  getfnames  -  read the control file to find the data and execute files
  194.  *          which contain the message and list of recipients.
  195.  *          dfile is set to the datafile, xfile to the execute file.
  196.  */
  197. getfnames(cmdfile, dfile, xfile)
  198. char    *cmdfile;
  199. char    *dfile;
  200. char    *xfile;
  201. {
  202.     FILE    *fp;
  203.     char    dline[100], xline[100];
  204.     char    *wrkvec[10];
  205.  
  206.     if ((fp = fopen(subfile(cmdfile), "r")) == NULL)
  207.         return;
  208.  
  209.     if (fgets(dline, 100, fp) == NULL || fgets(xline, 100, fp) == NULL)
  210.     {    fclose(fp);
  211.         return;
  212.     }
  213.  
  214.     if (getargs(dline, wrkvec) <= QF_INDEX)
  215.     {    fclose(fp);
  216.         return;
  217.     }
  218.     strcpy(dfile, wrkvec[ QF_INDEX ]);
  219.  
  220.     if (getargs(xline, wrkvec) < QF_INDEX)
  221.     {    fclose(fp);
  222.         return;
  223.     }
  224.     strcpy(xfile, wrkvec[ QF_INDEX ]);
  225.  
  226.     fclose(fp);
  227. }
  228.  
  229. /*
  230.  *  recipients -  returns a list of recipients that the mail was intended
  231.  *          for, or NULL if the execute file is not a mail file.
  232.  */
  233. char    **
  234. recipients(xfile)
  235. char    *xfile;
  236. {
  237.     static    char rbuf[BUFSIZ];
  238.     static    char *tobuf[1000];    /* see uuxqt */
  239.     FILE    *fp;
  240.     char    *p, **t;
  241.  
  242.     if ((fp = fopen(subfile(xfile), "r")) == NULL)
  243.         return(NULL);
  244.  
  245.     while (fgets(rbuf, BUFSIZ, fp) != NULL)
  246.     {    if (rbuf[0] == X_CMD)
  247.         {    if (strncmp(rbuf, "C rmail ", 8) == SAME)
  248.             {    fclose(fp);
  249.  
  250.                 /* turn into an array of addresses */
  251.                 for (p = &rbuf[8], t=tobuf; *p;)
  252.                 {    while (*p == ' ' || *p == '\n')
  253.                         *p++ = '\0';
  254.                     *t = p;
  255.                     while (*p && *p != ' ' && *p != '\n')
  256.                         p++;
  257.                     if (*t != p)
  258.                         t++;
  259.                 }
  260.                 *t = NULL;
  261.                 return(tobuf);
  262.             }
  263.         }
  264.     }
  265.  
  266.     fclose(fp);
  267.     return(NULL);
  268. }
  269.  
  270. /*
  271.  *  sender  -  returns the sender address from the uucp from line,
  272.  *           or NULL if not found.
  273.  */
  274. char    *
  275. sender(dfile)
  276. char    *dfile;
  277. {
  278.     static    char sender[BUFSIZ];
  279.     char    buf[BUFSIZ];
  280.     FILE    *fp;
  281.  
  282.     if ((fp = fopen(subfile(dfile), "r")) == NULL)
  283.         return(NULL);
  284.  
  285.     if (fgets(buf, BUFSIZ, fp) == NULL)
  286.         return(NULL);
  287.  
  288.     if (sscanf(buf, "From %s", sender) == 1)
  289.     {    fclose(fp);
  290.         return(sender);
  291.     }
  292.  
  293.     fclose(fp);
  294.     return(NULL);
  295. }
  296.  
  297.  
  298. /*
  299.  *  exists  -  returns 1 if "file" exists, else 0.
  300.  */
  301. exists(file)
  302. char    *file;
  303. {
  304.     return( access(subfile(file),0) == 0 );
  305. }
  306.  
  307.  
  308. /*
  309.  *  print_message  -  print the message in "dfile" on the stream "outp".
  310.  *              If the edited flag is set, then only print some
  311.  *              interesting headers and the first few lines of the body.
  312.  */
  313. print_message(dfile, outp, edited)
  314. char    *dfile;
  315. FILE    *outp;
  316. int    edited;
  317. {
  318.     FILE    *dfp;
  319.     char    buf[BUFSIZ];
  320.     int    iflg, linecount;
  321.  
  322.     if ((dfp = fopen(subfile(dfile), "r")) == NULL)
  323.         return;
  324.  
  325.     /* skip unix from line */
  326.     fgets(buf, BUFSIZ, dfp);
  327.  
  328.     /* print header */
  329.     iflg = 0;
  330.     while (fgets(buf, BUFSIZ, dfp) != NULL && buf[0] != '\n')
  331.     {    if (edited)
  332.         {    if (buf[0] == '\t' || buf[0] == ' ')
  333.             {    if (iflg)
  334.                     fputs(buf, outp);
  335.                 continue;
  336.             }
  337.  
  338.             if (!interested(buf))
  339.             {    iflg = 0;
  340.                 continue;
  341.             }
  342.             iflg = 1;
  343.         }
  344.         fputs(buf, outp);
  345.     }
  346.     putc('\n', outp);
  347.  
  348.     /* print body */
  349.     linecount = 0;
  350.     while (fgets(buf, BUFSIZ, dfp) != NULL)
  351.     {    if (edited && ++linecount > 5)
  352.         {    fprintf(outp, ".....\n");
  353.             break;
  354.         }
  355.         fputs(buf, outp);
  356.     }
  357.     fclose(dfp);
  358. }
  359.  
  360. static char    *headers[] = { "From:", "Date:", "To:", "Cc:", "Subject:", 0 };
  361.  
  362. /*
  363.  *  interested  -  determine whether "hdr" is considered interesting
  364.  *           and thus should be printed in edited mode.
  365.  */
  366. interested(hdr)
  367. char    *hdr;
  368. {
  369.     char    **hp = headers;
  370.  
  371.     while (*hp)
  372.     {    if (strncmp(hdr, *hp, strlen(*hp)) == SAME)
  373.             return(1);
  374.         hp++;
  375.     }
  376.     return(0);
  377. }
  378.  
  379.  
  380. cleanup(code)
  381. int code;
  382. {
  383.     exit(code);
  384. }
  385.