Added alias say
[clearscm.git] / bin / cleantmp.pl
1 #!/usr/bin/env perl
2 use strict;
3 use warnings;
4 use v5.22;
5
6 =pod
7
8 =head1 NAME $RCSfile: cleantmp.pl,v $
9
10 Keep /tmp clean based on filesets
11
12 =head1 VERSION
13
14 =over
15
16 =item Author
17
18 Andrew DeFaria <Andrew@DeFaria.com>
19
20 =item Revision
21
22 $Revision: 1.0 $
23
24 =item Created:
25
26 Wed Feb 21 20:43:58 PST 2018
27
28 =item Modified:
29
30 $Date: $
31
32 =back
33
34 =head1 SYNOPSIS
35
36  Usage: cleantmp.pl [-u|sage] [-h|elp] [-v|erbose] [-d|ebug]
37                     [-t|mp <dir>] [-c|onf <file>] [-l|ogpath <path>]
38                     [-s|leep <secs>]
39
40  Where:
41    -u|sage           Print this usage
42    -h|elp            Detailed help
43    -v|erbose:        Verbose mode
44    -d|ebug:          Print debug messages
45    -t|mp <dir>:      Tmp directory to monitor (Default: /tmp)
46    -c|onf <file>:    Config file holding patterns to match (Default: 
47                      .../etc/cleantmp.conf)
48    -l|ogpath <path>: Path to logfile (Default: /var/log)
49    -a|ppend:         Append to logfile (Default: Noappend)
50    -da|emon          Run in daemon mode (Default: -daemon)
51    -s|leep <secs>:   How many seconds to sleep between polls (Default: 60)
52
53 =head1 DESCRIPTION
54
55 This script will run in the background and keep /tmp clean. It will read in a 
56 list of Perl regexs from the config file. When new files are created in tmp they
57 will be compared against the list of regexs and if there's a match the file or
58 directory will be removed. 
59
60 The sleep parameter tells us how long to wait before polling for changes again
61
62 =cut
63
64 use FindBin;
65 use Getopt::Long;
66 use Pod::Usage;
67 use File::Monitor;
68 use File::Spec;
69 use File::Path qw/remove_tree/;
70
71 use lib "$FindBin::Bin/../lib";
72
73 use Display;
74 use Logger;
75 use Utils;
76
77 my ($script) = ($FindBin::Script =~ /^(.*)\.pl/);
78 my $log;
79
80 local $0 = $script;
81
82 my %opts = (
83   usage   => sub { pod2usage },
84   help    => sub { pod2usage(-verbose => 2)},
85   verbose => sub { set_verbose },
86   debug   => sub { set_debug },
87   daemon  => 1,
88   tmp     => File::Spec->tmpdir(),
89   conf    => "$FindBin::Bin/../etc/$script.conf",
90   logpath => '/var/local/log',
91   sleep   => 60,
92 );
93
94 sub loadConfig() {
95   my @patterns;
96
97   open my $patterns, '<', $opts{conf}
98     or $log->err("Unable to open $opts{conf} - $!", 1);
99
100   while (<$patterns>) {
101     next if /^\s*#/; # Skip comments
102
103     chomp;
104
105     push @patterns, $_;
106   } # while
107
108   close $patterns;
109
110   return @patterns;
111 } # loadConfig
112
113 sub FileCreated {
114   my ($name, $event, $change) = @_;
115
116   opendir my $dir, $opts{tmp}
117     or $log->err("Unable to open $opts{tmp} - $!", 1);
118
119   while (my $createdFile = readdir $dir) {
120     next if $createdFile =~ /^\./; # Skip all hidden files
121
122     for my $pattern (loadConfig) {
123       debug "Processing pattern $pattern";
124
125       if ($createdFile =~ /$pattern/) {
126         debug "Matched $createdFile to $pattern";
127
128         if (-d "$opts{tmp}/$createdFile") {
129           remove_tree ("$opts{tmp}/$createdFile", {error => \my $err});
130
131           if (@$err) {
132             for my $diag (@$err) {
133               my ($file, $message) = %$diag;
134
135               if ($file eq '') {
136                 $log->err("General error: $message");
137               } else {
138                 $log->err("Unable to delete $file: $message");
139               } # if
140             } # for
141           } else {
142             $log->msg("$opts{tmp}/$createdFile removed");
143           } # if
144         } else {
145           unless (unlink "$opts{tmp}/$createdFile") {
146             $log->err("Unable to remove $opts{tmp}/$createdFile - $!");
147           } else {
148             $log->msg("$opts{tmp}/$createdFile removed");
149           } # if
150         } # if
151
152         last;
153       } # if
154     } # for
155   } # while
156
157   return;
158 } # FileCreated
159
160 $SIG{USR1} = \&FileCreated;
161
162 ## Main
163 GetOptions (
164   \%opts,
165   'usage',
166   'help',
167   'verbose',
168   'debug',
169   'daemon!',
170   'tmp=s',
171   'logpath=s',
172   'conf=s',
173   'sleep=i',
174   'append',
175 ) or pod2usage;
176
177 $log = Logger->new(
178   path        => $opts{logpath},
179   timestamped => 1,
180   append      => $opts{append},
181 );
182
183 $log->msg("Starting $FindBin::Script");
184
185 # First run through whatever junk is in /tmp
186 for (glob "$opts{tmp}/*") {
187   FileCreated($_);
188 } # for
189
190 my $monitor = File::Monitor->new;
191
192 $monitor->watch({
193   name     => $opts{tmp},
194   files    => 1,
195   callback => {files_created => \&FileCreated}
196 });
197
198 set_debug if $DB::OUT;
199
200 if ($opts{daemon}) {
201   # Perl complains if we reference $DB::OUT only once
202   no warnings;
203   EnterDaemonMode unless defined $DB::OUT or get_debug;
204   use warnings;
205 } # if
206
207 while () {
208   $monitor->scan;
209
210   sleep $opts{sleep};
211 } # while
212