restart xmpp server after error or ping-timeout
[svn42.git] / go / r3-netstatus / r3xmppbot / r3xmppbot.go
index 141e541..6740a84 100644 (file)
@@ -11,18 +11,6 @@ import (
     "path"
 )
 
-//~ type StdLogger struct {
-//~ }
-
-//~ func (s *StdLogger) Log(v ...interface{}) {
-        //~ log.Println(v...)
-//~ }
-
-//~ func (s *StdLogger) Logf(fmt string, v ...interface{}) {
-        //~ log.Printf(fmt, v...)
-//~ }
-
-
 func (botdata *XmppBot) makeXMPPMessage(to string, message interface{}, subject interface{}) *xmpp.Message {
     xmppmsgheader := xmpp.Header{To: to,
                                                             From: botdata.my_jid_,
@@ -171,26 +159,21 @@ func (data RealraumXmppNotifierConfig) loadFrom(filepath string) () {
     }
 }
 
-
-func init() {
-        //~ logger := &StdLogger{}
-        //~ xmpp.Debug = logger
-        //~ xmpp.Info = logger
-        //~ xmpp.Warn = logger
-}
-
 func (botdata *XmppBot) handleEventsforXMPP(xmppout chan <- xmpp.Stanza, presence_events <- chan interface{}, jabber_events <- chan JabberEvent) {
     var last_status_msg *string
 
     defer func() {
         if x := recover(); x != nil {
             Syslog_.Printf("handleEventsforXMPP: run time panic: %v", x)
+            //FIXME: signal that xmpp bot has crashed
         }
+        for _ = range(jabber_events) {}    //cleanout jabber_events queue
     }()
 
        for {
                select {
-               case pe := <-presence_events:
+               case pe, pe_still_open := <-presence_events:
+            if ! pe_still_open { return }
             Debug_.Printf("handleEventsforXMPP<-presence_events: %T %+v", pe, pe)
             switch pec := pe.(type) {
                 case xmpp.Stanza:
@@ -216,19 +199,21 @@ func (botdata *XmppBot) handleEventsforXMPP(xmppout chan <- xmpp.Stanza, presenc
                         }
                     }
                 default:
-                    break
+                    Debug_.Println("handleEventsforXMPP<-presence_events: unknown type received: quitting")
+                    return
                 }
 
-               case je := <-jabber_events:
+               case je, je_still_open := <-jabber_events:
+            if ! je_still_open { return }
             Debug_.Printf("handleEventsforXMPP<-jabber_events: %T %+v", je, je)
             simple_jid := removeJIDResource(je.JID)
             jid_data, jid_in_map := botdata.realraum_jids_[simple_jid]
-            
+
             //send status if requested, even if user never changed any settings and thus is not in map
             if last_status_msg != nil && je.StatusNow {
                 xmppout <-  botdata.makeXMPPMessage(je.JID, last_status_msg, nil)
             }
-            
+
             if jid_in_map {
                 //if R3OnlineOnlyWithRecapInfo, we want a status update when coming online
                 if last_status_msg != nil && ! jid_data.Online && je.Online && jid_data.Wants == R3OnlineOnlyWithRecapInfo {
@@ -269,6 +254,9 @@ func (botdata *XmppBot) handleIncomingMessageDialog(inmsg xmpp.Message, xmppout
     if inmsg.Body == nil || inmsg.GetHeader() == nil {
         return
     }
+    if inmsg.Type == "error" || inmsg.Error != nil {
+        Syslog_.Printf("XMPP Message Error: %s", inmsg.Error.Error())
+    }
     bodytext :=inmsg.Body.Chardata
     if botdata.isAuthenticated(inmsg.GetHeader().From) {
         switch bodytext {
@@ -323,8 +311,8 @@ func (botdata *XmppBot) handleIncomingXMPPStanzas(xmppin <- chan xmpp.Stanza, xm
     defer func() {
         if x := recover(); x != nil {
             Syslog_.Printf("handleIncomingXMPPStanzas: run time panic: %v", x)
-            close(jabber_events)
         }
+        close(jabber_events)
     }()
 
     var incoming_stanza interface{}
@@ -333,8 +321,9 @@ func (botdata *XmppBot) handleIncomingXMPPStanzas(xmppin <- chan xmpp.Stanza, xm
             case *xmpp.Message:
                 botdata.handleIncomingMessageDialog(*stanza, xmppout, jabber_events)
             case *xmpp.Presence:
-                if stanza.GetHeader() == nil {
-                    continue
+                if stanza.GetHeader() == nil { continue }
+                if stanza.Type == "error" || stanza.Error != nil {
+                    Syslog_.Printf("XMPP Presence Error: %s", stanza.Error.Error())
                 }
                 switch stanza.GetHeader().Type {
                     case "subscribe":
@@ -352,13 +341,22 @@ func (botdata *XmppBot) handleIncomingXMPPStanzas(xmppin <- chan xmpp.Stanza, xm
                         jabber_events <- JabberEvent{stanza.GetHeader().From, true, R3NoChange, false}
                 }
             case *xmpp.Iq:
-                if stanza.GetHeader() == nil {
-                    continue
+                if stanza.GetHeader() == nil { continue }
+                if stanza.Type == "error" || stanza.Error != nil {
+                    Syslog_.Printf("XMPP Iq Error: %s", stanza.Error.Error())
                 }
+                if HandleServerToClientPing(stanza, xmppout) {continue} //if true then routine handled it and we can continue
+                Debug_.Printf("Unhandled Iq: %s", stanza)
         }
     }
 }
 
+func init() {
+    //~ xmpp.Debug = &XMPPDebugLogger{}
+    xmpp.Info = &XMPPDebugLogger{}
+    xmpp.Warn = &XMPPLogger{}
+}
+
 func NewStartedBot(loginjid, loginpwd, password, state_save_dir string, insecuretls bool) (*XmppBot, chan interface{}, error) {
     var err error
     botdata := new(XmppBot)
@@ -373,11 +371,6 @@ func NewStartedBot(loginjid, loginpwd, password, state_save_dir string, insecure
 
     botdata.config_file_ = path.Join(state_save_dir, "r3xmpp."+removeJIDResource(loginjid)+".json")
 
-    //~ logger := &StdLogger{}
-    //~ xmpp.Debug = logger
-    //~ xmpp.Info = logger
-    //~ xmpp.Warn = logger
-
     xmpp.TlsConfig = tls.Config{InsecureSkipVerify: insecuretls}
     botdata.realraum_jids_.loadFrom(botdata.config_file_)
 
@@ -418,6 +411,7 @@ func NewStartedBot(loginjid, loginpwd, password, state_save_dir string, insecure
 }
 
 func (botdata *XmppBot) StopBot() {
+    Syslog_.Println("Stopping XMPP Bot")
     if botdata.xmppclient_ != nil {
         close(botdata.xmppclient_.Out)
     }
@@ -425,4 +419,7 @@ func (botdata *XmppBot) StopBot() {
         *botdata.presence_events_ <- false
         close(*botdata.presence_events_)
     }
+    botdata.config_file_ = ""
+    botdata.realraum_jids_ = nil
+    botdata.xmppclient_ = nil
 }