class Autodrop
Constants
- CONF_DEFAULTS
- CONF_KEYS
- VERSION
Public Class Methods
loadconf(file)
click to toggle source
# File autodrop, line 60 def self.loadconf file conf = YAML.load File.read file raise "wrong format" unless conf.is_a? Hash conf = CONF_DEFAULTS.merge conf badkw = conf.keys - CONF_KEYS raise "unknown keywords - #{badkw.join ","}" unless badkw.empty? [ KW_COUNT, KW_DURATION ].each { |k| unless conf[k].is_a? Integer raise "integer required - #{k}: #{conf[k].inspect}" end } [ KW_DROP_COMMAND, KW_INPUT, KW_LOG, KW_PIDFILE ].each { |k| unless conf[k].is_a? String raise "string required - #{k}: #{conf[k].inspect}" end } conf[KW_DROP_COMMAND] = conf[KW_DROP_COMMAND].split conf[KW_PATTERNS].map! { |item| unless [ String, Regexp ].include? item.class raise "string or regexp required - #{item.inspect}" end Regexp.new item } conf end
Public Instance Methods
run(config)
click to toggle source
# File autodrop, line 111 def run config @logger = nil case config[KW_LOG] when "syslog" @logger = SyslogLogger.new when "stdout" @logger = StdoutLogger.new else begin @logger = FileLogger.new config[KW_LOG] rescue warn "autodrop: can not open - #{config[KW_LOG]}" exit 1 end end if config[KW_DAEMON] if Process.respond_to? :daemon Process.daemon else exit if fork Process.setsid exit if fork Dir.chdir "/" STDIN.reopen "/dev/null" STDOUT.reopen "/dev/null" STDERR.reopen "/dev/null" end File.write config[KW_PIDFILE], Process.pid end trap("SIGINT") { terminate "SIGINT" } trap("SIGTERM") { terminate "SIGTERM" } trap("SIGHUP") { terminate "SIGHUP" } @logger.log "start watching - #{config[KW_INPUT]}" unless File.ftype(config[KW_INPUT]) == "fifo" raise "not a named pipe - #{config[KW_INPUT]}" end fifofp = File.open config[KW_INPUT], File::RDWR @dogs = {} loop { ready = select [fifofp] next unless ready addr = nil line = ready[0][0].gets config[KW_PATTERNS].each { |pat| if line =~ pat addr = $1 break end } next unless addr dog = @dogs[addr] if dog dog.count += 1 dog.expire = Time.now + dog.duration @logger.log "#{dog.addr} bark! (#{dog.count})" if config[KW_VERBOSE] next end dog = Dog.new addr, config Thread.new(dog) { |dog| begin @dogs[dog.addr] = dog @logger.log "#{dog.addr} bark! (#{dog.count})" if config[KW_VERBOSE] loop { break if Time.now >= dog.expire if dog.count >= dog.count_max @logger.log "#{dog.addr} DROP" out = IO.popen(dog.drop_command, "r+", :err => [ :child, :out ]) { |io| buf = [] while l = io.gets buf.push l.chomp end buf } st = $?.exitstatus if st != 0 @logger.log "DROP fail. command exit status #{st}" out.each { |l| @logger.log "|#{l}" } end break end # @logger.log "#{dog.addr} grrr" if config[KW_VERBOSE] sleep 1 } rescue => ex @logger.log "error in worker" @logger.log "|#{ex}" ex.backtrace.each { |l| @logger.log "|#{l}" } ensure @dogs.delete dog.addr @logger.log "#{dog.addr} leave" if config[KW_VERBOSE] end } } rescue => ex @logger.log ex.message ex.backtrace.each { |l| @logger.log "|#{l}" } terminate "error", 1 ensure File.unlink config[KW_PIDFILE] rescue nil end
Private Instance Methods
terminate(whymsg, status = 0)
click to toggle source
# File autodrop, line 90 def terminate whymsg, status = 0 @logger.log "terminate (#{whymsg})" exit status end