summaryrefslogtreecommitdiff
path: root/src/papod.clj
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2026-04-29 09:53:20 -0300
committerEuAndreh <eu@euandre.org>2026-04-29 09:53:20 -0300
commitaa8959a93ee4f79b747b792361ca8208fa8d80ca (patch)
tree9b66925291d6cbe51580dd7a91793814ada1cc16 /src/papod.clj
parentWire account-registration before-connect and email-required configs (diff)
downloadpapod-aa8959a93ee4f79b747b792361ca8208fa8d80ca.tar.gz
papod-aa8959a93ee4f79b747b792361ca8208fa8d80ca.tar.xz
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 <nick> +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).
Diffstat (limited to 'src/papod.clj')
-rw-r--r--src/papod.clj42
1 files changed, 42 insertions, 0 deletions
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 <https://modern.ircdocs.horse/>"))
+ (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)