4d69f8fb67ab2df8a7615e4601b01e8228617a84
[mailshears.git] / bin / mailshears
1 #!/usr/bin/ruby -wU
2 #
3 # mailshears, to prune unused mail directories.
4 #
5
6 # Define a usage string using the program name.
7 exe = File.basename($PROGRAM_NAME)
8 usage = "#{exe} [prune | rm <target> | mv <src> <dst>]"
9
10 # Defaults
11 mode_name = 'prune'
12 mode = :prune
13
14 # Now, if a mode was supplied, it should be in ARGV[0].
15 if ARGV.length() > 0
16 mode_names = ['prune', 'rm', 'mv']
17 if mode_names.include?(ARGV.first().downcase()) then
18 # Peel the mode name off the head of the list.
19 mode_name = ARGV.shift()
20 end
21 end
22
23 if mode_name == 'rm' then
24 mode = :rm
25 elsif mode_name == 'mv' then
26 mode = :mv
27 end
28
29 # Need this before referencing ExitCodes.
30 require 'mailshears'
31
32 # Since we removed both the executable name and the mode name (if it
33 # existed) from ARGV, what remains should be the required
34 # arguments.
35 if (mode == :prune and (ARGV.length() != 0)) or
36 (mode == :rm and (ARGV.length() < 1)) or
37 (mode == :mv and (ARGV.length() != 2)) then
38 puts "ERROR: missing (or extra) command-line arguments."
39 puts "Usage: #{usage}"
40 Kernel.exit(ExitCodes::BAD_COMMAND_LINE)
41 end
42
43 cfg = Configuration.new()
44
45 # Load each of the plugins that we'll need.
46 cfg.plugins.each do |plugin_file|
47 require "#{mode_name}/plugins/#{plugin_file}"
48 end
49
50 # And the runners.
51 require "#{mode_name}/#{mode_name}_runner"
52 require "#{mode_name}/#{mode_name}_dummy_runner"
53
54 def make_header(plugin_name)
55 # The header that we output before the list of domains/users.
56 # Just the path of this script, the current time, and the plugin name.
57 exe = File.basename($PROGRAM_NAME)
58 header = "#{exe}, "
59
60 current_time = Time.now()
61 if current_time.respond_to?(:iso8601)
62 # Somehow this method is missing on some machines.
63 header += current_time.iso8601.to_s
64 else
65 # Fall back to whatever this looks like.
66 header += current_time.to_s
67 end
68
69 header += ' (Plugin: ' + plugin_name + ")\n"
70 header += '-' * header.size # Underline the header.
71
72 return header
73 end
74
75
76 plugin_module = nil
77
78 if mode == :rm then
79 plugin_module = RmPlugin
80 elsif mode == :mv then
81 plugin_module = MvPlugin
82 else
83 # Safe, catch-all default
84 plugin_module = PrunePlugin
85 end
86
87
88 # Buffer the output so that we can avoid printing the informational
89 # header when no plugins produce output.
90 require 'stringio'
91 output_buffer = StringIO.new()
92 $stdout = output_buffer
93
94 begin
95 plugin_module.run(cfg, *ARGV)
96 ensure
97 # Now restore stdout, and print the header plus whatever the plugins
98 # produced if they produced anything. If they didn't produce any
99 # output, then we avoid printing the header.
100 #
101 # This gets wrapped in an "ensure" block because otherwise, if
102 # plugin_module.run() crashes, the traceback will get stored in
103 # output_buffer and never get printed.
104 $stdout = STDOUT
105 if output_buffer.size > 0 then
106 puts make_header(plugin_module.to_s())
107 puts output_buffer.string()
108 end
109 end