diff options
Diffstat (limited to 'lisp/net/rcirc.el')
-rw-r--r-- | lisp/net/rcirc.el | 109 |
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)) |