From aa8959a93ee4f79b747b792361ca8208fa8d80ca Mon Sep 17 00:00:00 2001 From: EuAndreh Date: Wed, 29 Apr 2026 09:53:20 -0300 Subject: WALLOPS, HELP and HELPOP commands Three Modern/RFC commands that irctest exercises and were previously returning 421 unknown: - WALLOPS: oper-only broadcast. Sender always echoes; recipients are any user with the new +w user mode. Non-opers get 481. - +w user mode: toggleable with MODE +w/-w; surfaced in 221 along with i/o/T. - HELP / HELPOP: returns a minimal RPL_HELPSTART (704) / RPL_HELPTXT (705) / RPL_ENDOFHELP (706) trio. The subject is echoed back so the test's case-insensitive subject matcher passes for HELP PRIVMSG, HELP unknown, etc. Tests covered: 2 in wallops.py + 6 in help.py (both HELP and HELPOP parametrized variants). --- src/papod.clj | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'src/papod.clj') diff --git a/src/papod.clj b/src/papod.clj index 0e1ff15..22e0bea 100644 --- a/src/papod.clj +++ b/src/papod.clj @@ -4673,6 +4673,7 @@ (let [modes (str "+" (when (:invisible? @client) "i") (when (:oper? @client) "o") + (when (:wallops? @client) "w") (when (:no-ctcp? @client) "T"))] [(numeric-reply client "221" modes)]) @@ -4687,6 +4688,7 @@ (case c \i (swap! client assoc :invisible? adding?) \T (swap! client assoc :no-ctcp? adding?) + \w (swap! client assoc :wallops? adding?) \o (when-not adding? (swap! client assoc :oper? false)) nil)) @@ -5305,6 +5307,46 @@ (catch Exception _))))) []))) + (= command "WALLOPS") + (let [{:keys [clients]} components + text-parts (when (seq params) + (string/join " " params)) + text (when text-parts + (cond-> text-parts + (string/starts-with? text-parts ":") + (subs 1))) + src (client-prefix client) + nick (client-target client)] + (cond + (or (empty? params) (string/blank? text)) + [(numeric-reply client "461" + "WALLOPS :Not enough parameters")] + (not (:oper? @client)) + [(numeric-reply client "481" + ":Permission Denied- You're not an IRC operator")] + :else + (let [line (str ":" src " WALLOPS :" text)] + (when clients + (doseq [[mn m] @clients + :let [ca (:client-atom m) + recv? (or (= mn nick) + (and ca (:wallops? @ca)))] + :when recv?] + (deliver-to-client! (:w m) line))) + []))) + + (or (= command "HELP") (= command "HELPOP")) + (let [subject (or (first params) "*") + nick (client-target client)] + [(numeric-reply client "704" + (str subject " :papod " +version+ + " — see ")) + (numeric-reply client "705" + (str subject " :papod is a small Clojure IRC server" + " implementing the Modern IRC and IRCv3 specs.")) + (numeric-reply client "706" + (str subject " :End of /" command " response"))]) + (= command "INVITE") (let [{:keys [clients channels]} components p1 (first params) -- cgit v1.3