home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / UUCPbb_2_1_src.lzh / UUCPBB21 / uuclean.c < prev    next >
Text File  |  1994-09-25  |  18KB  |  623 lines

  1. /*  uuclean.c   The program cleans the UUCP spool directories.
  2.     Copyright (C) 1990, 1993  Mark Griffith and Bob Billson
  3.  
  4.     This file is part of the OS-9 UUCP package, UUCPbb.
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.     The author of UUCPbb, Bob Billson, can be contacted at:
  21.     bob@kc2wz.bubble.org  or  uunet!kc2wz!bob  or  by snail mail:
  22.     21 Bates Way, Westfield, NJ 07090
  23. */
  24.  
  25. /* Looks in the spool directory for any files that are older then the
  26.    specified number of days (default 7).  Deletes those that are and mails the
  27.    owner telling him of this action.
  28.  
  29.    Deletes the oldest log file and rotates the rest.
  30.  
  31.    Allows only the superuser (uid 0) to use the utility to prevent
  32.    unauthorized users from deleting files.
  33.  
  34.    Thanks to Mark for his okey dokey to modify and use his program in the
  35.    UUCPbb package.  --Bob Billson (REB) */
  36.  
  37. #define MAIN                                      /* Added -- REB */
  38.  
  39. #include "uucp.h"
  40. #include <modes.h>
  41. #include <time.h>
  42. #include <ctype.h>
  43. #include <direct.h>
  44. #ifndef _OSK
  45. #include <utime.h>
  46. #include "dir_6809.h"
  47. #else
  48. #include <dir.h>
  49. #endif
  50.  
  51. #define DEFDAYS   7                          /* default oldest file days */
  52. #define WORDSIZE  4                          /* added --REB */
  53.  
  54. extern QQ unsigned myuid;
  55. extern QQ char *nodename, *sitename;
  56. extern QQ flag fsactive;
  57. extern char user[];
  58.  
  59. /* array of log filenames to move in the log directory */
  60. QQ char *uul[] = { "uulog.7",
  61.                    "uulog.6",
  62.                    "uulog.5",
  63.                    "uulog.4",
  64.                    "uulog.3",
  65.                    "uulog.2",
  66.                    "uulog.1",
  67.                    "uulog",
  68.                  };
  69.  
  70. QQ char *fsl[] = { "fileserv.7",
  71.                    "fileserv.6",
  72.                    "fileserv.5",
  73.                    "fileserv.4",
  74.                    "fileserv.3",
  75.                    "fileserv.2",
  76.                    "fileserv.1",
  77.                    "fileserv",
  78.                  };
  79.  
  80. /* Variable declarations */
  81. QQ flag verbose = FALSE;                       /* verbose off */
  82. QQ flag debug = FALSE;                         /* debug off */
  83. QQ flag cplogs = TRUE;                         /* copy log files by default */
  84. QQ int pn;
  85. QQ char *def_dir;
  86. QQ FILE *fd;
  87. QQ FILE *log;
  88. long num_days;
  89. char def_date[6], timestr[21], tempstr[128];
  90. char xtype[2], datafile[80];
  91.  
  92. /* Structures */
  93. struct fildes fdbuf;                        /* file descriptor buffer */
  94.  
  95. /* Function declarations */
  96. void mail_owner();
  97. void mvlogs();
  98.  
  99. main (argc, argv)
  100. int argc;
  101. char *argv[];
  102. {
  103.      char dirname[100];
  104.      int option;
  105.      DIR *dir;                          /* these two structures are already */
  106.      struct direct *pdir;               /* defined in dir.h.  Added --REB */
  107.  
  108.      /* initialize variables */
  109.      num_days = DEFDAYS;                     /* default number of days */
  110.      log = stderr;                           /* don't log error -- REB */
  111.      def_dir = NULL;
  112.  
  113.      if (getuid() != 0)
  114.           fatal ("you are not the superuser!");
  115.  
  116.      if (getparam() == FALSE)
  117.           exit (0);
  118.  
  119.      if ((logdir = getenv ("LOGDIR")) != NULL)
  120.           logdir = strdup (logdir);
  121.      else
  122.           logdir = LOGDIR;
  123.  
  124.      strcpy (user, "uucp");
  125.  
  126.      /*  Process any command line arguments */
  127.      while ((option = getopt (argc, argv, "vxln:d:?")) != EOF)
  128.           switch (tolower (option))
  129.             {
  130.                case 'v':
  131.                     verbose = TRUE;
  132.                     break;
  133.  
  134.                case 'x':
  135.                     verbose = TRUE;
  136.                     debug = TRUE;
  137.                     break;
  138.  
  139.                case 'l':
  140.                     cplogs = FALSE;
  141.                     break;
  142.  
  143.                case 'n':
  144.                     num_days = abs (atoi (optarg));
  145.                     break;
  146.  
  147.                case 'd':
  148.                     free (def_dir);
  149.  
  150.                     if ((def_dir = strdup (optarg)) == NULL)
  151.                          fatal ("can't dup -d <directory>");
  152.                     break;
  153.  
  154.                case '?':
  155.                     usage();
  156.                     break;
  157.             }
  158.  
  159.      /* default to spool directory if we weren't told to use another --REB */
  160.      if (def_dir == NULL)
  161.           if ((def_dir = getdirs ("spooldir")) == NULL)
  162.                fatal ("spooldir not in Parameters");
  163.  
  164.      /*  Calculate the time */
  165.      rtime (num_days, def_date);
  166.  
  167.      if (verbose)
  168.           printf ("\nRemove all files before: %s\n", timestr);
  169.  
  170.      if ((dir = opendir (def_dir)) == NULL)  
  171.        {
  172.           sprintf (tempstr, "cannot open %s\n", def_dir);
  173.           fatal (tempstr);
  174.        }
  175.  
  176.      /* loop through each directory in UUCP spool directory -- REB */
  177.      while ((pdir = readdir (dir)) != NULL) 
  178.        {
  179.           if (pdir->d_name[0] == '.')
  180.                continue;
  181.  
  182.           sprintf (dirname, "%s/%s", def_dir, pdir->d_name);
  183.  
  184.           /* change to the spool directory for the next remote */
  185.           if (chdir (dirname) == ERROR)
  186.                fprintf (stderr, "can't change to directory '%s'\n", dirname);
  187.  
  188.           if (verbose)
  189.                printf ("\nChanged to directory '%s'\n", dirname);
  190.  
  191.           /* clean up this spool directory */
  192.           rmspooled (dirname);
  193.  
  194.           /* backup one directory level and go for the next one */
  195.           chdir ("..");
  196.        }
  197.      free (def_dir);
  198.      closedir (dir);
  199.  
  200.      /* Copy the log files unless -l option is used.  Rotate the uulog files.
  201.         Also the FileServ log files if the fileserver is active */
  202.  
  203.      if (cplogs)
  204.        {
  205.           mvlogs (TRUE);              /* rotate uulog files */
  206.  
  207.           if (fsactive)
  208.                mvlogs (FALSE);        /* rotate FileServ */
  209.        }
  210.      exit (0);
  211. }
  212.  
  213.  
  214.  
  215. /* Go through the spool directory.  Open each file and check its last modified
  216.    date with the default date.  If the file is older, delete it.  Mail the
  217.    owner if the file is a C. work file. */
  218.  
  219. int rmspooled (dirname)
  220. char *dirname;
  221. {
  222.      char filename[100], dfile[11];
  223.      DIR *dir;                        /* these two structures are already */
  224.      struct direct *pdir;                             /* defined in DIR.H */
  225.      flag got_data_file;
  226.      char *words[WORDSIZE];                                 /* REB */
  227.  
  228.      if ((dir = opendir (dirname)) == NULL)  
  229.        {
  230.           sprintf (tempstr,"cannot open %s\n", dirname);
  231.           fatal (tempstr);
  232.        }
  233.      sprintf (dfile, "D.%s", nodename);
  234.  
  235.      while ((pdir = readdir (dir)) != NULL)
  236.        {
  237.           if (pdir->d_name[0] == '.')
  238.                continue;
  239.  
  240.           strcpy (filename, pdir->d_name);
  241.  
  242.           if (verbose)
  243.                printf ("\nFound file '%s'\n", filename);
  244.  
  245.           if ((pn = open (filename, 1)) == ERROR)
  246.             {
  247.                if (verbose)
  248.                     printf ("cannot open '%s'\n", filename);
  249.  
  250.                continue;
  251.             }
  252.  
  253.           if ((_gs_gfd (pn, &fdbuf, sizeof (fdbuf))) == ERROR)
  254.             {
  255.                 close (pn);
  256.  
  257.                 if (verbose)
  258.                      puts ("Error getting file descriptor");
  259.  
  260.                 continue;
  261.             }
  262.  
  263.           if (verbose)
  264.                printf ("Date of this file is: %02d/%02d/%02d %02d:%02d\n",
  265.                        fdbuf.fd_date[1], fdbuf.fd_date[2],
  266.                        fdbuf.fd_date[0], fdbuf.fd_date[3],
  267.                        fdbuf.fd_date[4]);
  268.  
  269.           /* If this is a D.<ournode> data file return it to sender */
  270.           if (strnucmp (filename, dfile, strlen (dfile)) == 0)
  271.             {
  272.                strcpy (datafile, filename);
  273.                got_data_file = TRUE;
  274.  
  275.                if (verbose)
  276.                     printf ("Got data file '%s\n", datafile);
  277.             }
  278.           else
  279.                got_data_file = FALSE;
  280.  
  281.           close (pn);
  282.  
  283.           if (strncmp (fdbuf.fd_date, def_date, 5) <= 0)
  284.             {
  285.                if (got_data_file)
  286.                     mail_owner();
  287.  
  288.                if (verbose)
  289.                     printf ("%s ....\n", debug ? "would be deleted"
  290.                                                : "deleting");
  291.                if (!debug)
  292.                     unlink (filename);
  293.             }
  294.           else
  295.                if (verbose)
  296.                     puts ("Not old enough to kill!");
  297.        }
  298.      closedir (dir);
  299. }
  300.  
  301.  
  302.  
  303. /* Rtime is a function which returns a date relative to the current date and
  304.    time. It expects an OFFSET, which is an integer in units of days (+ or -)
  305.    from today.  DATEBUFF is the location in which to return the new relative
  306.    date.
  307.  
  308.    Provided by Pete Lyall - CIS 76703,4230
  309.  
  310.    Slightly modified by Mark Griffith to return a time the number of days less
  311.    than the current time as passed in offset. */
  312.  
  313. rtime (offset, datebuff)
  314. long offset;
  315. struct sgtbuf *datebuff;
  316. {
  317.      long systime;
  318.      struct tm *utimeptr;
  319.  
  320.      systime = time ((char *)0);                    /* get current time */
  321.  
  322.      /* substract the offset in hours */
  323.      systime -= offset*24L*60L*60L;                 /* changed [MDG] */
  324.      utimeptr = localtime(&systime);
  325.  
  326.      datebuff->t_year   = utimeptr->tm_year;
  327. #ifdef _OSK
  328.      datebuff->t_month  = utimeptr->tm_mon + 1;     /* OSK is different!!! */
  329. #else
  330. # ifndef NEWCLIB                                 /* early Kreider CLIB.L    */
  331.      datebuff->t_month  = utimeptr->tm_mon;      /* does it one way, newer  */
  332. # else                                           /* versions (1990) does it */
  333.      datebuff->t_month  = utimeptr->tm_mon + 1;  /* like OSK...confused??   */
  334. # endif                                          /* me, too --REB           */
  335. #endif
  336.      datebuff->t_day    = utimeptr->tm_mday;
  337.      datebuff->t_hour   = utimeptr->tm_hour;
  338.      datebuff->t_minute = utimeptr->tm_min;
  339.      datebuff->t_second = utimeptr->tm_sec;
  340.  
  341.      /* Setup a string with the date in it for possible printing.
  342.         Added [MDG] */
  343.  
  344.      sprintf (timestr,"%02d/%02d/%02d %02d:%02d:%02d",
  345.                       datebuff->t_month, datebuff->t_day, datebuff->t_year,
  346.                       datebuff->t_hour, datebuff->t_minute,
  347.                       datebuff->t_second);
  348. /*   return (datebuff); */
  349. }
  350.  
  351.  
  352.  
  353. /* attempt to return the undeliverable mail to the sender. */
  354.  
  355. void mail_owner()
  356. {
  357.      char line[256], tmpfile[80], rtrnto[128], origto[128];
  358.      FILE *msgfd;
  359.      register char *lp;
  360.      flag header;
  361.      unsigned tmpuid;
  362.      char *p;
  363.  
  364.      if ((fd = fopen (datafile, "r")) == NULL)
  365.           return;
  366.  
  367.      extractadrs (rtrnto, origto);
  368.  
  369.      if (*rtrnto == '\0')
  370.        {
  371.           fclose (fd);
  372.           return;
  373.        }
  374.  
  375.      if (verbose)
  376.           printf ("would return mail for: %s\nback to: %s\n", origto, rtrnto);
  377.  
  378.      if (debug)
  379.        {
  380.           fclose (fd);
  381.           return;
  382.        }
  383.  
  384.      /* create the return message */
  385.      maketemp (tmpfile, '1', FALSE);
  386.  
  387.      if ((msgfd = fopen (tmpfile, "w")) == NULL)
  388.        {
  389.           fclose (fd);
  390.           return;
  391.        }
  392.  
  393.      /* daemon is the one sending the mail */
  394.      setuser ("daemon");
  395.      tmpuid = getuid();
  396.      chown (tmpfile, tmpuid);
  397.      asetuid (0);
  398.  
  399.      /* assemble the returned message */
  400.      fprintf (msgfd, "From MAILER-DAEMON %s\n", date822());
  401.      fprintf (msgfd, "Date: %s\n", date822());
  402.      fprintf (msgfd, "From: Mail Delivery Subsystem <MAILER-DAEMON@%s>\n",
  403.                      sitename);
  404.  
  405.      fprintf (msgfd, "Reply-To: nobody@%s\n", sitename);
  406.      fprintf (msgfd, "To: %s\n", rtrnto);
  407.      fprintf (msgfd,
  408.               "Subject: Returned mail: Cannot send message for %d day%s\n\n",
  409.               (int) num_days, (int) num_days > 1 ? "s" : "");
  410.  
  411.      fprintf (msgfd,
  412.               "After %d day%s, your message to the following person:\n\n",
  413.               (int) num_days, (int) num_days > 1 ? "s" : "");
  414.  
  415.      fprintf (msgfd, "    %s\n\n", origto);
  416.      fputs ("could not be delivered.  No further attempts will be made.\n\n",
  417.              msgfd);
  418.  
  419.      fputs ("        Sincerely,\n", msgfd);
  420.      fprintf (msgfd, "        %s!uucp\n\n", nodename);
  421.      fputs ("   ----- Unsent message follows -----\n", msgfd);
  422.  
  423.      /* now tack on the unsent message */
  424.      rewind (fd);
  425.      lp = line;
  426.  
  427.      while (mfgets (lp, sizeof (line), fd) != NULL)
  428.           if (*lp != '\0')
  429.                fprintf (msgfd, "%s\n", lp);
  430.           else
  431.                putc ('\n', msgfd);
  432.  
  433.      fclose (fd);
  434.      fclose (msgfd);
  435.  
  436.      /* send it back */
  437.      sprintf (tempstr, "rmail %s %s", tmpfile, rtrnto);
  438.  
  439.      if (docmd_na (tempstr) != 0)
  440.                fputs ("uuclean: unable to fork RMAIL\n", stderr);
  441.  
  442.      unlink (tmpfile);
  443. }
  444.  
  445.  
  446.  
  447. /* extract the To: and From: addresses of mail to return. --REB */
  448.  
  449. int extractadrs (origfrom, origto)
  450. char *origfrom, *origto;
  451. {
  452.      char replyto[128], resentfrm[128], resentrply[128], line[256];
  453.      char rtrnto[128];
  454.      register char *lp;
  455.      flag header;
  456.      unsigned tmpuid;
  457.      char *p;
  458.  
  459.      *resentfrm =  '\0';
  460.      *resentrply = '\0';
  461.  
  462.      /* be sure this are all cleared out -- REB */
  463.      memset (replyto, '\0', sizeof (replyto));
  464.      memset (rtrnto, '\0', sizeof (rtrnto));
  465.  
  466.      /* start reading lines looking for "From:" or "Reply-to:" */
  467.      header = TRUE;
  468.      lp = line;
  469.  
  470.      /* Are we still in the header?  If so, look at line */
  471.      while (header)
  472.           if (mfgets (line, sizeof (line), fd) != NULL)
  473.             {
  474.                if (*lp == '\0')
  475.                  {
  476.                     header = FALSE;
  477.                     continue;
  478.                  }
  479.  
  480.                /* Be paranoid and extract From return path this will be
  481.                   overwritten by From: or Reply-to:, if found. */
  482.  
  483.                if (strncmp (lp, ">From ", 6) == 0
  484.                     ||  strnucmp (lp, "From ", 5) == 0)
  485.                  {
  486.                     strcpy (tempstr, skipspace (lp+5));
  487.  
  488.                     for (p = tempstr; !isspace (*p) && *p != '\0'; p++)
  489.                          ;
  490.  
  491.                     *p = '\0';
  492.                     strcpy (rtrnto, tempstr);
  493.                  }
  494.  
  495.                /* extract From: return path */
  496.                if (*lp == 'F'  &&  strnucmp (lp, "From: ", 6) == 0)
  497.                      strcpy (rtrnto, getval (line));
  498.  
  499.                /* Reply-To, Resent-Reply-To, Resent-From: fields */
  500.                if (*lp == 'R')
  501.                  {
  502.                     /* extract Reply-To: return path */
  503.                     if (strnucmp (lp, "Reply-To: ", 10) == 0)
  504.                          strcpy (replyto, getval (line));
  505.  
  506.                     /* extract Resent-From: path */
  507.                     else if (strnucmp (lp, "Resent-From: ", 13) == 0)
  508.                          strcpy (resentfrm, getval (line));
  509.  
  510.                     /* extract Resent-Reply-To: path */
  511.                     else if (strnucmp (lp, "Resent-Reply-To: ", 17) == 0)
  512.                          strcpy (resentrply, getval (line));
  513.                  }
  514.  
  515.                if (*lp == 'T'  &&  strnucmp (lp, "To: ", 4) == 0)
  516.                     strcpy (origto, getval (line));
  517.             }
  518.           else
  519.             {
  520.                /* header ended prematurely */
  521.                *origfrom = '\0';
  522.                return (0);
  523.             }
  524.  
  525.      /*      Resent-Reply-To: supercedes From: in determining return path
  526.         -or- Resent-From:     supercedes From: in determining return path
  527.         -or- Reply-To:        supercedes From: in determining return path  */
  528.  
  529.      if (*resentrply != '\0')
  530.           strcpy (rtrnto, resentrply);
  531.      else if (*resentfrm != '\0')
  532.           strcpy (rtrnto, resentfrm);
  533.      else if (*replyto != '\0')
  534.           strcpy (rtrnto, replyto);
  535.  
  536.      strcpy (origfrom, rtrnto);
  537. }
  538.  
  539.  
  540.  
  541. /* Rotate old uulog or FileServ files deleting the oldest */
  542.  
  543. void mvlogs (uulogs)
  544. flag uulogs;
  545. {
  546.      int i;
  547.  
  548.      if (chdir (logdir) == ERROR)            /* change to the log directory */
  549.           return;
  550.  
  551.      if (verbose)
  552.           printf ("\nDeleting %s\n", uul[0]);
  553.  
  554.      if (!debug)
  555.           if (uulogs)                             /* delete oldest log file */
  556.                unlink (uul[0]);                   /* uulog files */
  557.           else
  558.                unlink (fsl[0]);                   /* FileServ files */
  559.  
  560.      for (i = 0; i < 7; i++)
  561.        {
  562.           if (verbose)
  563.                printf ("Renaming %s to %s\n",
  564.                        uulogs ? uul[i + 1] : fsl[i + 1],
  565.                        uulogs ? uul[i]     : fsl[i]);
  566.  
  567.           if (!debug)
  568.             {
  569.                sprintf (tempstr, "rename %s %s",
  570.                         uulogs ? uul[i + 1] : fsl[i + 1],
  571.                         uulogs ? uul[i]     : fsl[i]);
  572.  
  573.                docmd_na (tempstr);
  574.             }
  575.        }
  576.  
  577.      if (!debug)
  578.        {
  579.           /* create new log file ignoring errors */
  580.           if (uulogs)
  581.                fd = fopen (uul[7], "w");
  582.           else
  583.                fd = fopen (fsl[7], "w");
  584.  
  585.           fclose (fd);
  586.        }
  587. }
  588.  
  589.  
  590.  
  591. int fatal (msg)
  592. char *msg;
  593. {
  594.      fprintf (stderr, "uuclean: %s", msg);
  595.  
  596.      if (errno != 0)
  597.           fprintf (stderr, "...error %d", errno);
  598.  
  599.      putc ('\n', stderr);
  600.      exit (0);
  601. }
  602.  
  603.  
  604.  
  605. int usage()
  606. {
  607.      fputs ("\nuuclean: removed old UUCP files, rotate UUCP and FileServ log files\n",
  608.             stderr);
  609.      fputs ("Usage: uuclean [opts]\n\n", stderr);
  610.      fprintf (stderr,
  611.                "Opts:   -nX     Remove those files over X days old (default is %d)\n",
  612.                DEFDAYS);
  613.      fputs ("        -ddir   Use this directory name\n", stderr);
  614.      fputs ("        -v      Set verbose option on\n", stderr);
  615.      fputs ("        -l      Do not rotate log files\n", stderr);
  616.      fputs ("        -x      Set debug option on (files are not touched)\n\n",
  617.             stderr);
  618.      fprintf (stderr, "v%s (%s) This is free software released under the GNU General Public\n",
  619.                       version, VERDATE);
  620.      fputs ("License.  Please send suggestions/bug reports to:  bob@kc2wz.bubble.org\n", stderr);
  621.      exit (0);
  622. }
  623.