summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/papod.clj133
1 files changed, 129 insertions, 4 deletions
diff --git a/src/papod.clj b/src/papod.clj
index 35b9b49..e89f7cc 100644
--- a/src/papod.clj
+++ b/src/papod.clj
@@ -765,8 +765,9 @@
[client]
(let [nick (or (:nick @client) "*")
u (:user @client)
- user (or (:username u) nick)]
- (str nick "!" user "@localhost")))
+ user (or (:username u) nick)
+ host (or (:host @client) "localhost")]
+ (str nick "!" user "@" host)))
(defn- numeric-reply
[client code & parts]
@@ -2578,8 +2579,9 @@
(when-let [m (get @clients nick)]
(when-let [c (some-> (:client-atom m) deref)]
(let [u (:user c)
- ident (or (:username u) nick)]
- (str nick "!" ident "@localhost")))))
+ ident (or (:username u) nick)
+ host (or (:host c) "localhost")]
+ (str nick "!" ident "@" host)))))
(str nick "!" nick "@localhost")))
(defn- nick-mask-match?
@@ -5880,6 +5882,51 @@
[(numeric-reply client "391"
(str +server-name+ " :" (iso-time)))]
+ (= command "VERSION")
+ [(numeric-reply client "351"
+ (str +version+ " " +server-name+ " :papod"))
+ (numeric-reply client "005"
+ (str "ACCOUNTEXTBAN=a"
+ " AWAYLEN=200 BOT=B"
+ " CASEMAPPING=ascii"
+ " CHANLIMIT=#:100"
+ " CHANMODES=beI,k,l,Cnt"
+ " CHANNELLEN=64 CHANTYPES=#"
+ " ELIST= EXCEPTS=e"
+ " EXTBAN=~,am HOSTLEN=64"
+ " :are supported by this server"))
+ (numeric-reply client "005"
+ (str "INVEX=I KICKLEN=300"
+ " MAXLIST=b:50,e:50,I:50"
+ " MAXTARGETS=4 MODES=4"
+ " MONITOR=100 NETWORK=papod"
+ " NICKLEN=30 PREFIX=(ov)@+"
+ " STATUSMSG=@+"
+ " :are supported by this server"))
+ (numeric-reply client "005"
+ (str "TARGMAX=KICK:1,LIST:,WHOIS:1,PRIVMSG:4,NAMES:"
+ " TOPICLEN=390 USERLEN=18"
+ " UTF8ONLY WHOX"
+ " :are supported by this server"))]
+
+ (= command "ISON")
+ (let [{:keys [clients]} components
+ online (when clients
+ (for [target params
+ :when (and (string? target)
+ (seq target))
+ :let [low (string/lower-case target)
+ m (some
+ (fn [[k m]]
+ (when (= (string/lower-case k)
+ low)
+ m))
+ @clients)]
+ :when m]
+ target))]
+ [(numeric-reply client "303"
+ (str ":" (string/join " " (or online []))))])
+
(= command "OPER")
(cond
(< (count params) 2)
@@ -5962,6 +6009,84 @@
(deliver-to-client! (:w m) line)))
[])))
+ ;; CHGHOST: oper-only, mutates target's user@host and
+ ;; broadcasts ":old-prefix CHGHOST newuser newhost" to
+ ;; peers in shared chans that negotiated the chghost cap.
+ (= command "CHGHOST")
+ (let [{:keys [clients channels]} components
+ target (first params)
+ newuser (second params)
+ newhost (when (>= (count params) 3)
+ (let [h (nth params 2)]
+ (cond-> h
+ (string/starts-with? h ":")
+ (subs 1))))
+ nick (client-target client)]
+ (cond
+ (< (count params) 3)
+ [(numeric-reply client "461"
+ "CHGHOST :Not enough parameters")]
+
+ (not (:oper? @client))
+ [(numeric-reply client "481"
+ (str ":Permission Denied- You're not"
+ " an IRC operator"))]
+
+ (or (string/blank? newuser)
+ (string/blank? newhost)
+ (string/includes? newuser " ")
+ (string/includes? newhost " "))
+ [(numeric-reply client "501"
+ ":Invalid CHGHOST parameters")]
+
+ :else
+ (let [m (and clients (get @clients target))
+ ca (when m (:client-atom m))]
+ (cond
+ (not ca)
+ [(numeric-reply client "401"
+ (str target " :No such nick"))]
+
+ :else
+ (let [old-prefix
+ (let [c @ca
+ tnick (or (:nick c) target)
+ u (:user c)
+ ident (or (:username u) tnick)
+ host (or (:host c) "localhost")]
+ (str tnick "!" ident "@" host))
+ line (str ":" old-prefix
+ " CHGHOST " newuser
+ " " newhost)]
+ (swap! ca (fn [s]
+ (-> s
+ (assoc-in [:user :username]
+ newuser)
+ (assoc :host newhost))))
+ ;; Notify the target itself.
+ (deliver-to-client! (:w m) line)
+ ;; Notify peers in shared channels that
+ ;; negotiated chghost.
+ (when (and clients channels)
+ (let [seen (atom #{target})]
+ (doseq [[ch members] @channels
+ :when (contains? members target)
+ mn members
+ :when (not (contains? @seen mn))
+ :let [pm (get @clients mn)
+ pca (:client-atom pm)
+ pcaps (or (some-> pca
+ deref :caps)
+ #{})]
+ :when (and pm
+ (contains?
+ pcaps "chghost"))]
+ (deliver-to-client! (:w pm) line)
+ (swap! seen conj mn))))
+ [(numeric-reply client "396"
+ (str newuser "@" newhost
+ " :is now your visible host"))])))))
+
(or (= command "HELP") (= command "HELPOP"))
(let [subject (or (first params) "*")
nick (client-target client)]