diff options
| author | EuAndreh <eu@euandre.org> | 2026-04-26 09:41:03 -0300 |
|---|---|---|
| committer | EuAndreh <eu@euandre.org> | 2026-04-26 09:41:03 -0300 |
| commit | 89d992d23218553e84361cbb2d0b0ff18063c675 (patch) | |
| tree | 109ab78414916d0b8b9bb174e9356cd07064be36 /src | |
| parent | Add PAPOD_PASSWORD authentication via PASS (diff) | |
| download | papod-89d992d23218553e84361cbb2d0b0ff18063c675.tar.gz papod-89d992d23218553e84361cbb2d0b0ff18063c675.tar.xz | |
Add WHOX support and WHOWAS wildcard masks
WHOX: parse %fields[,token] in WHO command second arg, emit RPL_WHOSPCRPL
(354) with fields in canonical order (tcuihsnfdlaor). Add WHOX to
ISUPPORT.
WHOWAS: support wildcards (* and ?) in target. End-of-WHOWAS reply
now uses the matched nick instead of the original mask, matching
common IRC server behavior.
Diffstat (limited to 'src')
| -rw-r--r-- | src/papod.clj | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/src/papod.clj b/src/papod.clj index 33296eb..82bd7ce 100644 --- a/src/papod.clj +++ b/src/papod.clj @@ -994,7 +994,7 @@ " STATUSMSG=@+" " TARGMAX=KICK:1,LIST:,WHOIS:1,PRIVMSG:4,NAMES:" " TOPICLEN=390 USERLEN=18" - " UTF8ONLY" + " UTF8ONLY WHOX" " :are supported by this server")) (numeric-reply client "422" ":MOTD File is missing")] @@ -3241,6 +3241,12 @@ mp? (contains? (or (:caps @client) #{}) "multi-prefix") + whox (when-let [arg (second params)] + (when (and (string? arg) + (string/starts-with? arg "%")) + (let [body (subs arg 1) + [fs t] (string/split body #"," 2)] + {:fields (set fs) :token t}))) who-reply (fn [chan-name mn m] (let [ca (:client-atom m) @@ -3265,11 +3271,33 @@ voc? "+")) uname (or (:username (:user st)) mn) rname (or (:realname (:user st)) mn)] - (numeric-reply client "352" - (str chan-name " " uname - " localhost " +server-name+ - " " mn " " flag - " :0 " rname))))] + (if whox + (let [fs (:fields whox) + parts (cond-> [] + (fs \t) (conj (or (:token whox) "0")) + (fs \c) (conj (or chan-name "*")) + (fs \u) (conj uname) + (fs \i) (conj "255.255.255.255") + (fs \h) (conj "localhost") + (fs \s) (conj +server-name+) + (fs \n) (conj mn) + (fs \f) (conj flag) + (fs \d) (conj "0") + (fs \l) (conj "0") + (fs \a) (conj "0") + (fs \o) (conj "0")) + base (string/join " " parts)] + (numeric-reply client "354" + (if (fs \r) + (if (seq parts) + (str base " :" rname) + (str ":" rname)) + base))) + (numeric-reply client "352" + (str chan-name " " uname + " localhost " +server-name+ + " " mn " " flag + " :0 " rname)))))] (cond (nil? target) [(numeric-reply client "315" @@ -3407,10 +3435,26 @@ t-lower (string/lower-case target) hist (when (:whowas components) @(:whowas components)) + wild? (some #{\* \?} target) + pat (when wild? + (re-pattern + (str "^" + (->> t-lower + (map (fn [c] + (case c + \* ".*" + \? "." + (java.util.regex.Pattern/quote + (str c))))) + (apply str)) + "$"))) matches0 (when hist (filter - #(= (string/lower-case (:nick %)) - t-lower) + (fn [e] + (let [nl (string/lower-case (:nick e))] + (if pat + (boolean (re-matches pat nl)) + (= nl t-lower)))) hist)) matches (cond (or (nil? limit) (zero? limit)) @@ -3433,7 +3477,7 @@ " :papod"))]) matches)) (conj (numeric-reply client "369" - (str target + (str (:nick (first matches)) " :End of WHOWAS")))) [(numeric-reply client "406" (str target " :There was no such nickname")) |
