#!/usr/bin/perl -w
#---------#---------#---------#---------#---------#---------#---------#---------
#
# title
#   recursively delete old files using using File::Find
# author
#   idc@planetlarg.net 23 April 2001
# description
#  Take the name of a directory and a number of days.
#  Delete any files in the directory that were last modified more than that
#  number of days ago. A recursive search is performed, so
#  matching files in subdirectories are also deleted.
#
#  This is the equivalent of this "find" command
#     find /DIRECTORY/FILE* -mtime +DAYS -exec rm {} \;
#  In other words, this script does the same job but with a great deal
#  more effort. Only use this script if you are adding extra functionality
#  like creating a log of files deleted. Otherwise, type "man find" and get
#  reading.
#
# modifications
#
#---------#---------#---------#---------#---------#---------#---------#---------
# setup
   use 5.005;
   use strict;
# command line options
   use Getopt::Std;
      # The command line options we are looking for are
      #   -m   integer. last modified this number of days ago
      #   -d   string. directory to search
      #   -v   verbose
   use vars qw($opt_m $opt_d $opt_v);
   my $options_ok;
   $options_ok = getopts('m:d:v');
      # Check for options we don't want
   print "missing arguments or unkown options encountered. \n" unless $options_ok;
      # Check for the options we require
   print "-d  is missing. \n" unless $opt_d;
   print "-m  is missing. \n" unless $opt_m;
      # print a usage message if there is a problem with the options
   &usage() if not($opt_d and $opt_m);

#---------#---------#---------#---------#---------#---------#---------#---------
# main

# Traverse desired filesystems
   use File::Find;
   find (\&wanted, $opt_d);

   exit;

#---------#---------#---------#---------#---------#---------#---------#---------
# subs
#   all subroutines go below here.


# subroutine
#  wanted
# description
#  Delete each file that has been found.
#  Print a warning if something goes wrong.
#  Print what's happening if verbose flag is set
#  If the file is a link, act like the shell "rm" command:
#  remove the link itself, not what it points to.
#
#  This is the product of the find2perl program.
#  It contains several shortcuts, like these:
#  -M    the number of days ago the file was last modified eg. 0.000335648148148148
#  _     the special file handle, meaning the last file examined
#  &&    short circuit for "if true, then ..."
#
sub wanted {

   return if m/^\.\.?$/;   # skip this and parent entries "." and ".."
   if (int(-M _) > $opt_m) {
      print "   deleting $_ \n" if $opt_v;
      if (unlink($_)) {
      } else {
         warn "$_: $!\n";
      }
   } else {
      print "   ignoring $_ \n" if $opt_v;
   }
}

# subroutine
#   usage
# description
#   describe how this script should be used.
#   This is one way of producing a set of instructions, using simple indentation.
#   For more complex document, use mark-up. See the perldoc section below.
#
sub usage {

   use Text::Wrap;
   $Text::Wrap::columns = 60;
   my $pre1             = "   ";
   my $pre2             = "   ";
   my $name             = "$0 - Delete old files.";
   my $synopsis         = "$0  -m DAYS -d /PATH/TO/SEARCH -v";
   my $description      = <<EOD;
Take the name of a directory and a number of days.
Delete any files in the directory that were last modified more than that
number of days ago.
A recursive search is performed, so
matching files in subdirectories are also deleted.
Globbing wildcards such as "*" are not allowed.

EOD
   my $examples         = <<EOE;
This command:
$pre1$0  -m 7 -d /tmp
deletes all files from the /tmp directory that
- are owned by you,
- have not been modified in the last 7 days
EOE
   my $options         = <<EOO;
-m NUMBER   number of days to check against the file's last modified date.
-v          verbose  print the action for each file
-d          directory to recursively search
EOO

   print
               "NAME \n",
               wrap ($pre1, $pre2, $name), "\n",
               "SYNOPSIS \n",
               wrap ($pre1, $pre2, $synopsis), "\n",
               "DESCRIPTION \n",
               fill ($pre1, $pre2, $description), "\n",
               "OPTIONS \n",
               wrap ($pre1, $pre2, $options), "\n",
               "EXAMPLES \n",
               wrap ($pre1, $pre2, $examples), "\n",
   ;
   exit 1;
}
#---------#---------#---------#---------#---------#---------#---------#---------


__END__

documentation

The "__END__" string is a token. It is the logical end of program text.
You can put anything you want after this token, such as an
instruction manual page; it will be ignored by the compiler.

