[cl-irc-devel] [PATCH] Register current user nickname on rpl_welcome

Julien Danjou julien at danjou.info
Wed Dec 19 16:13:56 UTC 2012


Currently, the user nickname is recorded in the connection object when
`connect' is called. Unfortunately, if it happens that the nickname used to
connect is already taken, err_nicknameinuse is received and the connection
is not established (yet).

The thing to do to handle this, is to issue a `nick' command in
err_nicknameinuse to pick a different nickname.

The problem is that such a case, even if a NICK request was sent (and might
or not be successful), there's no NICK reply sent by the server, because all
of this happens before the welcome message has been sent. Therefore, the
connection object as a wrong value for the user nickname (the one issued the
first time, not the one actually negotiated).

Consequently, functions such as `self-message-p' don't work correctly, and
everything is just mess and chaos.

To fix this, this patch stop registering the nickname at `connect' time, but
does it as soon as the welcome message is received. That way, it is sure
that the connection stores the real nickname, not the one asked for the
first time.

Signed-off-by: Julien Danjou <julien at danjou.info>
---
 command.lisp  |  7 +------
 event.lisp    | 13 +++++++++++++
 protocol.lisp |  1 +
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/command.lisp b/command.lisp
index c0277fc..aac445b 100644
--- a/command.lisp
+++ b/command.lisp
@@ -296,13 +296,8 @@ connect to.  `connection-security' determines which port number is found.
                                       :socket socket
                                       :network-stream stream
                                       :client-stream logging-stream
-                                      :server-name server))
-         (user (make-user connection
-                          :nickname nickname
-                          :username username
-                          :realname realname)))
+                                      :server-name server)))
     #+sbcl (setf (sb-bsd-sockets::sockopt-keep-alive (usocket:socket socket)) t)
-    (setf (user connection) user)
     (unless (null password)
       (pass connection password))
     (nick connection nickname)
diff --git a/event.lisp b/event.lisp
index 3b99d4a..eb97fc9 100644
--- a/event.lisp
+++ b/event.lisp
@@ -141,6 +141,19 @@ objects in sync."))
               (username user) username
               (hostname user) hostname)))))
 
+(defmethod default-hook ((message irc-rpl_welcome-message))
+  (with-slots
+      (connection host user arguments)
+      message
+    (destructuring-bind
+        (nickname welcome-message)
+        arguments
+      (setf (user connection)
+            (make-user connection
+                       :nickname nickname
+                       :hostname host
+                       :username user)))))
+
 (defmethod default-hook ((message irc-rpl_list-message))
   (destructuring-bind
       (channel count topic)
diff --git a/protocol.lisp b/protocol.lisp
index b464697..1c2ec19 100644
--- a/protocol.lisp
+++ b/protocol.lisp
@@ -246,6 +246,7 @@ connection.")
                      irc-rpl_topic-message
                      irc-rpl_namreply-message
                      irc-rpl_endofnames-message
+                     irc-rpl_welcome-message
                      irc-ping-message
                      irc-join-message
                      irc-topic-message
-- 
1.8.1.rc0





More information about the cl-irc-devel mailing list