From 4da7d24988ae096d757021eb8ed9d014990de16e Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Sat, 11 Mar 2023 09:25:24 -0800 Subject: [PATCH] Add MOTD command to ERC * lisp/erc/erc-backend.el (erc-server-402, erc-server-402-functions): Add new response handler and hook. * lisp/erc/erc.el (erc-cmd-MOTD): New function to shield erc-network from handling post-connection MOTD replies. Thanks to Emanuel Berg for reporting this (bug#62151). (erc-message-english-s402): Define new ERR_NOSUCHSERVER message template. * test/lisp/erc/erc-scenarios-base-misc-regressions.el: New file. * test/lisp/erc/resources/base/commands/motd.eld: New file. --- lisp/erc/erc-backend.el | 7 ++- lisp/erc/erc.el | 17 +++++++ .../erc-scenarios-base-misc-regressions.el | 44 +++++++++++++++++ .../lisp/erc/resources/base/commands/motd.eld | 48 +++++++++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 test/lisp/erc/resources/base/commands/motd.eld diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 567443f5329..bf3c2b5b308 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -2236,6 +2236,11 @@ See `erc-display-server-message'." nil (erc-display-message parsed '(notice error) 'active 's401 ?n nick/channel))) +(define-erc-response-handler (402) + "No such server." nil + (erc-display-message parsed '(notice error) 'active + 's402 ?c (cadr (erc-response.command-args parsed)))) + (define-erc-response-handler (403) "No such channel." nil (erc-display-message parsed '(notice error) 'active @@ -2383,7 +2388,7 @@ See `erc-display-error-notice'." nil ;; (define-erc-response-handler (323 364 365 381 382 392 393 394 395 ;; 200 201 202 203 204 205 206 208 209 211 212 213 ;; 214 215 216 217 218 219 241 242 243 244 249 261 -;; 262 302 342 351 402 407 409 411 413 414 415 +;; 262 302 342 351 407 409 411 413 414 415 ;; 423 424 436 441 443 444 467 471 472 473 KILL) ;; nil nil ;; (ignore proc parsed)) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index f76c770f585..66bc4985027 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -4051,6 +4051,22 @@ means that the user has a +o flag in the channel's access list)." (t (erc-server-send "TIME")))) (defalias 'erc-cmd-DATE #'erc-cmd-TIME) +(defun erc-cmd-MOTD (&optional target) + "Ask server to send the current MOTD. +Some IRCds simply ignore TARGET." + (letrec ((oneoff (lambda (proc parsed) + (with-current-buffer (erc-server-buffer) + (cl-assert (eq (current-buffer) (process-buffer proc))) + (remove-hook 'erc-server-402-functions h402 t) + (remove-hook 'erc-server-376-functions h376 t) + (remove-hook 'erc-server-422-functions h422 t)) + (erc-server-MOTD proc parsed) + t)) + (h402 (erc-once-with-server-event 402 oneoff)) + (h376 (erc-once-with-server-event 376 oneoff)) + (h422 (erc-once-with-server-event 422 oneoff))) + (erc-server-send (concat "MOTD" (and target " ") target)))) + (defun erc-cmd-TOPIC (topic) "Set or request the topic for a channel. LINE has the format: \"#CHANNEL TOPIC\", \"#CHANNEL\", \"TOPIC\" @@ -7136,6 +7152,7 @@ All windows are opened in the current frame." (s379 . "%c: Forwarded to %f") (s391 . "The time at %s is %t") (s401 . "%n: No such nick/channel") + (s402 . "%c: No such server") (s403 . "%c: No such channel") (s404 . "%c: Cannot send to channel") (s405 . "%c: You have joined too many channels") diff --git a/test/lisp/erc/erc-scenarios-base-misc-regressions.el b/test/lisp/erc/erc-scenarios-base-misc-regressions.el index 16b2cb355d1..c1915d088a0 100644 --- a/test/lisp/erc/erc-scenarios-base-misc-regressions.el +++ b/test/lisp/erc/erc-scenarios-base-misc-regressions.el @@ -124,4 +124,48 @@ Originally from scenario rebuffed/gapless as explained in Bug#48598: (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan")) (erc-d-t-search-for 10 "and be prosperous"))))) +;; This defends against a partial regression in which an /MOTD caused +;; 376 and 422 handlers in erc-networks to run. + +(ert-deftest erc-cmd-MOTD () + :tags '(:expensive-test) + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "base/commands") + (erc-server-flood-penalty 0.1) + (dumb-server (erc-d-run "localhost" t 'motd)) + (port (process-contact dumb-server :service)) + (expect (erc-d-t-make-expecter))) + + (ert-info ("Connect to server") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "tester" + :full-name "tester") + (funcall expect 10 "This is the default Ergo MOTD") + (funcall expect 10 "debug mode"))) + + (ert-info ("Send plain MOTD") + (with-current-buffer "foonet" + (erc-cmd-MOTD) + (funcall expect -0.2 "Unexpected state detected") + (funcall expect 10 "This is the default Ergo MOTD"))) + + (ert-info ("Send MOTD with known target") + (with-current-buffer "foonet" + (erc-scenarios-common-say "/MOTD irc1.foonet.org") + (funcall expect -0.2 "Unexpected state detected") + (funcall expect 10 "This is the default Ergo MOTD"))) + + (ert-info ("Send MOTD with erroneous target") + (with-current-buffer "foonet" + (erc-scenarios-common-say "/MOTD fake.foonet.org") + (funcall expect -0.2 "Unexpected state detected") + (funcall expect 10 "No such server") + ;; Message may show up before the handler runs. + (erc-d-t-wait-for 10 + (not (local-variable-p 'erc-server-402-functions))) + (should-not (local-variable-p 'erc-server-376-functions)) + (should-not (local-variable-p 'erc-server-422-functions)) + (erc-cmd-QUIT ""))))) + ;;; erc-scenarios-base-misc-regressions.el ends here diff --git a/test/lisp/erc/resources/base/commands/motd.eld b/test/lisp/erc/resources/base/commands/motd.eld new file mode 100644 index 00000000000..6d10ee122e2 --- /dev/null +++ b/test/lisp/erc/resources/base/commands/motd.eld @@ -0,0 +1,48 @@ +;; -*- mode: lisp-data; -*- +((nick 10 "NICK tester")) +((user 10 "USER user 0 * :tester") + (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester") + (0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1") + (0.01 ":irc.foonet.org 003 tester :This server was created Sun, 12 Mar 2023 02:30:29 UTC") + (0.00 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv") + (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=1000 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server") + (0.01 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server") + (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=1000 :are supported by this server") + (0.00 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)") + (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online") + (0.00 ":irc.foonet.org 253 tester 0 :unregistered connections") + (0.00 ":irc.foonet.org 254 tester 1 :channels formed") + (0.00 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers") + (0.00 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3") + (0.00 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3") + (0.00 ":irc.foonet.org 375 tester :- irc.foonet.org Message of the day - ") + (0.00 ":irc.foonet.org 372 tester :- This is the default Ergo MOTD.") + (0.01 ":irc.foonet.org 372 tester :- ") + (0.02 ":irc.foonet.org 372 tester :- For more information on using these, see MOTDFORMATTING.md") + (0.00 ":irc.foonet.org 376 tester :End of MOTD command")) + +((mode 10 "MODE tester +i") + (0.00 ":irc.foonet.org 221 tester +i") + (0.00 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.") + (0.05 ":irc.foonet.org 221 tester +i")) + +((motd-1 10 "MOTD") + (0.08 ":irc.foonet.org 375 tester :- irc.foonet.org Message of the day - ") + (0.02 ":irc.foonet.org 372 tester :- This is the default Ergo MOTD.") + (0.01 ":irc.foonet.org 372 tester :- ") + (0.00 ":irc.foonet.org 372 tester :- For more information on using these, see MOTDFORMATTING.md") + (0.00 ":irc.foonet.org 376 tester :End of MOTD command")) + +((motd-2 10 "MOTD irc1.foonet.org") + (0.08 ":irc1.foonet.org 375 tester :- irc1.foonet.org Message of the day - ") + (0.02 ":irc1.foonet.org 372 tester :- This is the default Ergo MOTD.") + (0.01 ":irc1.foonet.org 372 tester :- ") + (0.00 ":irc1.foonet.org 372 tester :- For more information on using these, see MOTDFORMATTING.md") + (0.00 ":irc1.foonet.org 376 tester :End of MOTD command")) + +((motd-3 10 "MOTD fake.foonet.org") + (0.00 ":irc.foonet.org 402 tester fake.foonet.org :No such server")) + +((quit 10 "QUIT :\2ERC\2") + (0.07 ":tester!~u@h3f95zveyc38a.irc QUIT :Quit: \2ERC\2 5.5 (IRC client for GNU Emacs 30.0.50)") + (0.01 "ERROR :Quit: \2ERC\2 5.5 (IRC client for GNU Emacs 30.0.50)")) -- 2.39.2