]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/ircbot.rb
New auth framework is now backwards compatible: auth <masterpassword> works again...
[user/henk/code/ruby/rbot.git] / lib / rbot / ircbot.rb
index bbb58fac0f264fe60d6392b0953985471461584e..432b61c40d4180653331bb5f5152d7ad098203e3 100644 (file)
@@ -340,6 +340,7 @@ class IrcBot
     @timer = Timer::Timer.new(1.0) # only need per-second granularity
     @save_mutex = Mutex.new
     @timer.add(@config['core.save_every']) { save } if @config['core.save_every']
+    @quit_mutex = Mutex.new
 
     @logs = Hash.new
 
@@ -407,8 +408,9 @@ class IrcBot
     }
     @client[:privmsg] = proc { |data|
       m = PrivMessage.new(self, server, data[:source], data[:target], data[:message])
-      debug "Message target is #{data[:target].inspect}"
-      debug "Bot is #{myself.inspect}"
+      # debug "Message source is #{data[:source].inspect}"
+      # debug "Message target is #{data[:target].inspect}"
+      # debug "Bot is #{myself.inspect}"
 
       # TODO use the new Netmask class
       # @config['irc.ignore_users'].each { |mask| return if Irc.netmaskmatch(mask,m.source) }
@@ -549,14 +551,12 @@ class IrcBot
   def got_sig(sig)
     debug "received #{sig}, queueing quit"
     $interrupted += 1
+    quit unless @quit_mutex.locked?
     debug "interrupted #{$interrupted} times"
-    if $interrupted >= 5
+    if $interrupted >= 3
       debug "drastic!"
       log_session_end
       exit 2
-    elsif $interrupted >= 3
-      debug "quitting"
-      quit
     end
   end
 
@@ -577,8 +577,10 @@ class IrcBot
     rescue => e
       raise e.class, "failed to connect to IRC server at #{@config['server.name']} #{@config['server.port']}: " + e
     end
+    quit if $interrupted > 0
     @socket.emergency_puts "PASS " + @config['server.password'] if @config['server.password']
     @socket.emergency_puts "NICK #{@config['irc.nick']}\nUSER #{@config['irc.user']} 4 #{@config['server.name']} :Ruby bot. (c) Tom Gilbert"
+    quit if $interrupted > 0
     start_server_pings
   end
 
@@ -591,11 +593,11 @@ class IrcBot
         @timer.start
 
         while @socket.connected?
+         quit if $interrupted > 0
           if @socket.select
             break unless reply = @socket.gets
             @client.process reply
           end
-         quit if $interrupted > 0
         end
 
       # I despair of this. Some of my users get "connection reset by peer"
@@ -604,7 +606,7 @@ class IrcBot
       rescue SystemExit
         log_session_end
         exit 0
-      rescue Errno::ETIMEDOUT, TimeoutError, SocketError => e
+      rescue Errno::ETIMEDOUT, Errno::ECONNABORTED, TimeoutError, SocketError => e
         error "network exception: #{e.class}: #{e}"
         debug e.backtrace.join("\n")
       rescue BDB::Fatal => e
@@ -780,39 +782,43 @@ class IrcBot
 
   # disconnect from the server and cleanup all plugins and modules
   def shutdown(message = nil)
-    debug "Shutting down ..."
-    ## No we don't restore them ... let everything run through
-    # begin
-    #   trap("SIGINT", "DEFAULT")
-    #   trap("SIGTERM", "DEFAULT")
-    #   trap("SIGHUP", "DEFAULT")
-    # rescue => e
-    #   debug "failed to restore signals: #{e.inspect}\nProbably running on windows?"
-    # end
-    message = @lang.get("quit") if (message.nil? || message.empty?)
-    if @socket.connected?
-      debug "Clearing socket"
-      @socket.clearq
-      debug "Sending quit message"
-      @socket.emergency_puts "QUIT :#{message}"
-      debug "Flushing socket"
-      @socket.flush
-      debug "Shutting down socket"
-      @socket.shutdown
-    end
-    debug "Logging quits"
-    server.channels.each { |ch|
-      irclog "@ quit (#{message})", ch
-    }
-    debug "Saving"
-    save
-    debug "Cleaning up"
-    @plugins.cleanup
-    # debug "Closing registries"
-    # @registry.close
-    debug "Cleaning up the db environment"
-    DBTree.cleanup_env
-    log "rbot quit (#{message})"
+    @quit_mutex.synchronize do
+      debug "Shutting down ..."
+      ## No we don't restore them ... let everything run through
+      # begin
+      #   trap("SIGINT", "DEFAULT")
+      #   trap("SIGTERM", "DEFAULT")
+      #   trap("SIGHUP", "DEFAULT")
+      # rescue => e
+      #   debug "failed to restore signals: #{e.inspect}\nProbably running on windows?"
+      # end
+      message = @lang.get("quit") if (message.nil? || message.empty?)
+      if @socket.connected?
+        debug "Clearing socket"
+        @socket.clearq
+        debug "Sending quit message"
+        @socket.emergency_puts "QUIT :#{message}"
+        debug "Flushing socket"
+        @socket.flush
+        debug "Shutting down socket"
+        @socket.shutdown
+      end
+      debug "Logging quits"
+      server.channels.each { |ch|
+        irclog "@ quit (#{message})", ch
+      }
+      debug "Saving"
+      save
+      debug "Cleaning up"
+      @save_mutex.synchronize do
+        @plugins.cleanup
+      end
+      # debug "Closing registries"
+      # @registry.close
+      debug "Cleaning up the db environment"
+      DBTree.cleanup_env
+      log "rbot quit (#{message})"
+    end
   end
 
   # message:: optional IRC quit message
@@ -845,8 +851,10 @@ class IrcBot
 
   # call the rescan method for all of the botmodules
   def rescan
-    @lang.rescan
-    @plugins.rescan
+    @save_mutex.synchronize do
+      @lang.rescan
+      @plugins.rescan
+    end
   end
 
   # channel:: channel to join
@@ -875,6 +883,11 @@ class IrcBot
       sendq "MODE #{channel} #{mode} #{target}", channel, 2
   end
 
+  # kicking a user
+  def kick(channel, user, msg)
+      sendq "KICK #{channel} #{user} :#{msg}", channel, 2
+  end
+
   # m::     message asking for help
   # topic:: optional topic help is requested for
   # respond to online help requests