diff options
| author | EuAndreh <eu@euandre.org> | 2026-04-29 09:53:20 -0300 |
|---|---|---|
| committer | EuAndreh <eu@euandre.org> | 2026-04-29 09:53:20 -0300 |
| commit | aa8959a93ee4f79b747b792361ca8208fa8d80ca (patch) | |
| tree | 9b66925291d6cbe51580dd7a91793814ada1cc16 /src/papod.clj | |
| parent | Wire account-registration before-connect and email-required configs (diff) | |
| download | papod-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.clj | 42 |
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) |
