summaryrefslogtreecommitdiff
path: root/lisp/net/rcirc.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/net/rcirc.el')
-rw-r--r--lisp/net/rcirc.el109
1 files changed, 88 insertions, 21 deletions
diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 1d419dbfa18..1e3ee91092d 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -204,12 +204,14 @@ The ARGUMENTS for each METHOD symbol are:
`nickserv': NICK PASSWORD [NICKSERV-NICK]
`chanserv': NICK CHANNEL PASSWORD
`bitlbee': NICK PASSWORD
+ `quakenet': ACCOUNT PASSWORD
Examples:
((\"freenode\" nickserv \"bob\" \"p455w0rd\")
(\"freenode\" chanserv \"bob\" \"#bobland\" \"passwd99\")
(\"bitlbee\" bitlbee \"robert\" \"sekrit\")
- (\"dal.net\" nickserv \"bob\" \"sekrit\" \"NickServ@services.dal.net\"))"
+ (\"dal.net\" nickserv \"bob\" \"sekrit\" \"NickServ@services.dal.net\")
+ (\"quakenet.org\" quakenet \"bobby\" \"sekrit\"))"
:type '(alist :key-type (string :tag "Server")
:value-type (choice (list :tag "NickServ"
(const nickserv)
@@ -223,7 +225,11 @@ Examples:
(list :tag "BitlBee"
(const bitlbee)
(string :tag "Nick")
- (string :tag "Password"))))
+ (string :tag "Password"))
+ (list :tag "QuakeNet"
+ (const quakenet)
+ (string :tag "Account")
+ (string :tag "Password"))))
:group 'rcirc)
(defcustom rcirc-auto-authenticate-flag t
@@ -232,6 +238,13 @@ See also `rcirc-authinfo'."
:type 'boolean
:group 'rcirc)
+(defcustom rcirc-authenticate-before-join t
+ "*Non-nil means authenticate to services before joining channels.
+Currently only works with NickServ on some networks."
+ :version "24.1"
+ :type 'boolean
+ :group 'rcirc)
+
(defcustom rcirc-prompt "> "
"Prompt string to use in IRC buffers.
@@ -282,6 +295,9 @@ Called with 5 arguments, PROCESS, SENDER, RESPONSE, TARGET and TEXT."
:type 'hook
:group 'rcirc)
+(defvar rcirc-authenticated-hook nil
+ "Hook run after successfully authenticated.")
+
(defcustom rcirc-always-use-server-buffer-flag nil
"Non-nil means messages without a channel target will go to the server buffer."
:type 'boolean
@@ -524,6 +540,8 @@ If ARG is non-nil, instead prompt for connection parameters."
(setq rcirc-timeout-timer nil)
(make-local-variable 'rcirc-user-disconnect)
(setq rcirc-user-disconnect nil)
+ (make-local-variable 'rcirc-user-authenticated)
+ (setq rcirc-user-authenticated nil)
(make-local-variable 'rcirc-connecting)
(setq rcirc-connecting t)
@@ -2104,7 +2122,8 @@ CHANNELS is a comma- or space-separated string of channel names."
(let* ((split-channels (split-string channels "[ ,]" t))
(buffers (mapcar (lambda (ch)
(rcirc-get-buffer-create process ch))
- split-channels)))
+ split-channels))
+ (channels (mapconcat 'identity split-channels ",")))
(rcirc-send-string process (concat "JOIN " channels))
(when (not (eq (selected-window) (minibuffer-window)))
(dolist (b buffers) ;; order the new channel buffers in the buffer list
@@ -2427,10 +2446,23 @@ keywords when no KEYWORD is given."
(setq rcirc-server-name sender)
(setq rcirc-nick (car args))
(rcirc-update-prompt)
- (when rcirc-auto-authenticate-flag (rcirc-authenticate))
+ (if rcirc-auto-authenticate-flag
+ (if rcirc-authenticate-before-join
+ (progn
+ (with-rcirc-process-buffer process
+ (add-hook 'rcirc-authenticated-hook 'rcirc-join-channels-post-auth t t))
+ (rcirc-authenticate))
+ (rcirc-authenticate)
+ (rcirc-join-channels process rcirc-startup-channels))
+ (rcirc-join-channels process rcirc-startup-channels))))
+
+(defun rcirc-join-channels-post-auth (process)
+ "Join `rcirc-startup-channels' after authenticating."
+ (with-rcirc-process-buffer process
(rcirc-join-channels process rcirc-startup-channels)))
(defun rcirc-handler-PRIVMSG (process sender args text)
+ (rcirc-check-auth-status process sender args text)
(let ((target (if (rcirc-channel-p (car args))
(car args)
sender))
@@ -2443,6 +2475,7 @@ keywords when no KEYWORD is given."
(rcirc-put-nick-channel process sender target rcirc-current-line))))
(defun rcirc-handler-NOTICE (process sender args text)
+ (rcirc-check-auth-status process sender args text)
(let ((target (car args))
(message (cadr args)))
(if (string-match "^\C-a\\(.*\\)\C-a$" message)
@@ -2460,6 +2493,33 @@ keywords when no KEYWORD is given."
sender)))
message t))))
+(defun rcirc-check-auth-status (process sender args text)
+ "Check if the user just authenticated.
+If authenticated, runs `rcirc-authenticated-hook' with PROCESS as
+the only argument."
+ (with-rcirc-process-buffer process
+ (when (and (not rcirc-user-authenticated)
+ rcirc-authenticate-before-join
+ rcirc-auto-authenticate-flag)
+ (let ((target (car args))
+ (message (cadr args)))
+ (when (or
+ (and ;; nickserv
+ (string= sender "NickServ")
+ (string= target rcirc-nick)
+ (member message
+ (list
+ (format "You are now identified for \C-b%s\C-b." rcirc-nick)
+ "Password accepted - you are now recognized."
+ )))
+ (and ;; quakenet
+ (string= sender "Q")
+ (string= target rcirc-nick)
+ (string-match message "\\`You are now logged in as .+\\.\\'")))
+ (setq rcirc-user-authenticated t)
+ (run-hook-with-args 'rcirc-authenticated-hook process)
+ (remove-hook 'rcirc-authenticated-hook 'rcirc-join-channels-post-auth t))))))
+
(defun rcirc-handler-WALLOPS (process sender args text)
(rcirc-print process sender "WALLOPS" sender (car args) t))
@@ -2704,26 +2764,33 @@ Passwords are stored in `rcirc-authinfo' (which see)."
(nick (caddr i))
(method (cadr i))
(args (cdddr i)))
- (when (and (string-match server rcirc-server)
- (string-match nick rcirc-nick))
- (cond ((equal method 'nickserv)
- (rcirc-send-privmsg
- process
+ (when (and (string-match server rcirc-server))
+ (if (and (memq method '(nickserv chanserv bitlbee))
+ (string-match nick rcirc-nick))
+ ;; the following methods rely on the user's nickname.
+ (case method
+ (nickserv
+ (rcirc-send-privmsg
+ process
(or (cadr args) "NickServ")
- (concat "identify " (car args))))
- ((equal method 'chanserv)
- (rcirc-send-privmsg
- process
+ (concat "IDENTIFY " (car args))))
+ (chanserv
+ (rcirc-send-privmsg
+ process
"ChanServ"
- (format "identify %s %s" (car args) (cadr args))))
- ((equal method 'bitlbee)
- (rcirc-send-privmsg
- process
+ (format "IDENTIFY %s %s" (car args) (cadr args))))
+ (bitlbee
+ (rcirc-send-privmsg
+ process
"&bitlbee"
- (concat "identify " (car args))))
- (t
- (message "No %S authentication method defined"
- method))))))))
+ (concat "IDENTIFY " (car args)))))
+ ;; quakenet authentication doesn't rely on the user's nickname.
+ ;; the variable `nick' here represents the Q account name.
+ (when (eq method 'quakenet)
+ (rcirc-send-privmsg
+ process
+ "Q@CServe.quakenet.org"
+ (format "AUTH %s %s" nick (car args))))))))))
(defun rcirc-handler-INVITE (process sender args text)
(rcirc-print process sender "INVITE" nil (mapconcat 'identity args " ") t))