#!/usr/bin/ruby # # pdumpfs-clean: cleanup old backup directory for pdumpfs # # Usage: # pdumpfs-clean # # Copyright(C) 2003 Taku YASUI , All rights reserved. # This is free software with ABSOLUTELY NO WARRANTY. # # You can redistribute it and/or modify it under the terms of # the GNU General Public License version 2. # # 2003-06-18: # Modified by akira yamada . require 'getoptlong' require 'date' require 'find' VERS = '$Id: pdumpfs-clean,v 1.2 2003/06/15 07:46:52 tach Exp $'.sub(/^.*,v ([\d\.]+) .*$/, "\\1") + ' + ay0' def parse_options options = Hash.new parser = GetoptLong.new parser.set_options(['--help', '-h', GetoptLong::NO_ARGUMENT], ['--no-act', '-n', GetoptLong::NO_ARGUMENT], ['--verbose', '-v', GetoptLong::NO_ARGUMENT], ['--version', '-V', GetoptLong::NO_ARGUMENT], ['--keep', '-k', GetoptLong::REQUIRED_ARGUMENT]) parser.each_option {|name, arg| options[name.sub(/^--/, "")] = arg } show_version if options['version'] show_usage if options['help'] or ARGV[0].nil? return options end def parse_keep(keep) return {'year' => 2, 'month' => 6, 'week' => 6, 'day' => 7} unless keep ch_tables = { 'year' => /(\d+)Y/i, 'month' => /(\d+)M/i, 'week' => /(\d+)W/i, 'day' => /(\d+)D/i } ret = {} ch_tables.each do |key, regex| if regex =~ keep ret[key] = $1.to_i ret[key] -= 1 else ret[key] = 0 end end ret end def create_keeprange(keep) from = Date.today to = from.dup from = Date.new(from.year - keep['year'], from.month, from.day) from = from << keep['month'] from = from -= keep['week']*7 + keep['day'] from .. to end def each_subdir(base, patt) Dir.foreach(base) do |x| next unless patt =~ x p = File.join(base, x) next unless FileTest.directory?(p) yield(p, x) end end def pdumpfs_dirs(dir) each_subdir(dir, /^\d{4}$/o) do |yp, yb| year = yb.to_i each_subdir(yp, /^\d{2}$/o) do |mp, mb| month = mb.to_i each_subdir(mp, /^\d{2}$/o) do |dp, db| day = db.to_i begin date = Date.new(year, month, day) rescue ArgumentError date = nil end yield(dp, mp, yp, date) if date end end end end def rm_rf(dir, verbose = false, no_act = true) print "Deleting #{dir} ... " if verbose unless no_act Find.find(dir) do |f| next if f == dir next if f == '.' next if f == '..' if !FileTest.symlink?(f) && FileTest.directory?(f) rm_rf(f, false, no_act) begin Dir.rmdir(f) rescue => e STDERR.puts e end else begin File.delete(f) rescue => e STDERR.puts e end end end begin Dir.rmdir(dir) rescue => e STDERR.puts e end end print "done.\n" if verbose end def rmdir(dir, verbose = false, no_act = true) print "Deleting #{dir} ..." if verbose begin Dir.rmdir(dir) unless no_act rescue => e $stderr.puts e end print " done.\n" if verbose end def show_usage print <<_EOT Usage: pdumpfs-clean [OPTIONS] directories... OPTIONS: --help, -h: Show this help --keep KEEPARGS, -k: use KEEPARGS to decide delete directories --no-act, -n: run command but don't do it --verbose, -v: Verbose output --version, -V: Show software version KEEPARGS: [digitY][digitM][digitW][digitD] ex: --keep 2Y6M6W7D (2years, 6months, 6weeks, 7days, default) _EOT exit end def show_version print <<_EOT pdumpfs-clean version #{VERS} Copyright (C) 2003 Taku YASUI This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. _EOT exit end def main opts = parse_options keep_range = create_keeprange(parse_keep(opts['keep'])) keeped = [] ARGV.each do |basedir| pdumpfs_dirs(basedir) do |date_path, month_path, year_path, date| if keep_range === date keeped.push(date_path) else rm_rf(date_path, opts['verbose'], opts['no-act']) rmdir(month_path) if File.stat(month_path).nlink <= 2 rmdir(year_path) if File.stat(year_path).nlink <= 2 end end if opts['verbose'] puts "Keep dirs:" keeped.each do |dir| puts dir end end end end main if __FILE__ == $0