summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhref <href@random.sh>2021-01-09 15:58:59 +0100
committerhref <href@random.sh>2021-01-09 19:59:44 +0100
commitc8e512baf5c28696cf3935ce148083cedb9ca4c8 (patch)
tree8a1babc86e813acd5e456ad0f88e3a11f4673bd8
parentOld WIP commit - STS, ... (diff)
Some fixes
-rw-r--r--lib/irc/connection.ex63
-rw-r--r--lib/irc/parser/line.ex11
-rw-r--r--lib/irc/shout.ex6
3 files changed, 54 insertions, 26 deletions
diff --git a/lib/irc/connection.ex b/lib/irc/connection.ex
index 7b82cea..23eee3f 100644
--- a/lib/irc/connection.ex
+++ b/lib/irc/connection.ex
@@ -340,7 +340,7 @@ defmodule Irc.Connection do
{:ok, args} <- process_args(args),
backoff <- :backoff.init(backoff_min, backoff_max)
do
- {tls, sts, port} = case {args.sts, Irc.STS.lookup(args.host, args.port)} do
+ {tls, sts, port} = case {args.sts, Irc.STS.lookup(args.host)} do
{true, {:ok, port}} -> {true, true, port}
_ -> {args.tls, false, args.port}
end
@@ -429,13 +429,15 @@ defmodule Irc.Connection do
end
# multiline capab
- def cap_ls(:info, {_, _, %Line{command: "CAP", args: [_, "LS", "*", rest]}}, data) do
+ def cap_ls(:info, {_, _, %Line{command: "CAP", args: [_, "LS", "*", rest]} = line}, data) do
+ Logger.debug "#{inspect(data)} <<< #{inspect(line)}"
capabs = Map.merge(data.server_capabs, Parser.Capabs.parse(rest))
{:keep_state, %State{data | server_capabs: capabs, cap_302: true}, {:state_timeout, @reply_timeout, nil}}
end
# end of multiline or no multiline indicator
- def cap_ls(:info, {_, _, %Line{command: "CAP", args: [_, "LS", rest]}}, data) do
+ def cap_ls(:info, {_, _, %Line{command: "CAP", args: [_, "LS", rest]} = line}, data) do
+ Logger.debug "#{inspect(data)} <<< #{inspect(line)}"
capabs = Map.merge(data.server_capabs, Parser.Capabs.parse(rest))
if data.cap_302 do
{:next_state, :cap_sts, %State{data | server_capabs: capabs}, @internal}
@@ -461,7 +463,7 @@ defmodule Irc.Connection do
@doc false
def cap_sts(:internal, _, data = %{args: %{sts: true}, sts: false, port: current_port,
server_capabs: %{"sts" => policy = %{"port" => sts_port}}}) when current_port != sts_port do
- socksend(data, Line.new("QUIT", ["Following STS policy."]))
+ socksend(data, Line.new("QUIT", ["Reconnecting following STS policy."]))
ConnectionSocket.close(data.socket)
{:next_state, :connect, %State{data | sts: true, port: sts_port, tls: true, socket: nil}, @internal}
end
@@ -497,7 +499,8 @@ defmodule Irc.Connection do
{:next_state, :reg_nick, data, @internal}
end
- def reg_pass(:info, {_, _, %Line{command: err_PASSWDMISMATCH()}}, data) do
+ def reg_pass(:info, {_, _, %Line{command: err_PASSWDMISMATCH()}} = line, data) do
+ Logger.debug "#{inspect(data)} <<< #{inspect(line)}"
{:next_state, :error, {:invalid_password, data.args.pass}}
end
@@ -519,12 +522,14 @@ defmodule Irc.Connection do
end
end
- def reg_nick(:info, {_, _, %Line{command: cmd}}, data) when cmd in [err_NICKNAMEINUSE(), err_NICKCOLLISION() ]do
+ def reg_nick(:info, {_, _, %Line{command: cmd}} = line, data) when cmd in [err_NICKNAMEINUSE(), err_NICKCOLLISION() ]do
+ Logger.debug "#{inspect(data)} <<< #{inspect(line)}"
new_nick = data.args.nick <> to_string(:random.uniform(9999))
{:keep_state, data, {:next_event, :internal, new_nick}}
end
def reg_nick(:info, {_, _, line = %Line{command: cmd}}, data) when cmd in [err_ERRONEUSNICKNAME(), err_NONICKNAMEGIVEN()] do
+ Logger.debug "#{inspect(data)} <<< #{inspect(line)}"
{:next_state, :error, data, {:next_event, :internal, {:invalid_nickname, data.args.nick, line}}}
end
@@ -564,9 +569,11 @@ defmodule Irc.Connection do
req = Enum.filter(client_capabs, fn(capab) -> Map.has_key?(server_capabs, capab) end)
|> Enum.uniq()
|> Enum.join(" ")
- case socksend(data, Line.new("CAP", args: ["REQ", req])) do
- :ok -> {:next_state, :cap_wait_ack, data}
- error -> to_disconnected(error, data)
+ case socksend(data, Line.new("CAP", ["REQ", req])) do
+ :ok ->
+ {:next_state, :cap_wait_ack, data}
+ error ->
+ to_disconnected(error, data)
end
end
@@ -583,12 +590,14 @@ defmodule Irc.Connection do
# FIXME: Support multiline ACK/NACK ???
# TODO: VERIFY SPEC CONFORMITY
- def cap_wait_ack(:info, {_, _, %Line{command: "CAP", args: [_, "ACK", capabs]}}, data) do
+ def cap_wait_ack(:info, {_, _, %Line{command: "CAP", args: [_, "ACK", capabs]} = line}, data) do
+ Logger.debug "#{inspect(data)} <<< #{inspect(line)}"
capabs = String.split(capabs, " ")
{:keep_state, %State{data | capabs: capabs}, {:next_event, :internal, :end}}
end
- def cap_wait_ack(:info, {_, _, %Line{command: "CAP", args: [_, "NACK", capabs]}}, data) do
+ def cap_wait_ack(:info, {_, _, %Line{command: "CAP", args: [_, "NACK", capabs]} = line}, data) do
+ Logger.debug "#{inspect(data)} <<< #{inspect(line)}"
capabs = String.split(capabs, " ")
{:keep_state, %State{data | capabs: data.capabs -- capabs}, {:next_event, :internal, :end}}
end
@@ -612,12 +621,14 @@ defmodule Irc.Connection do
end
def welcome(:info, {_, _, l = %Line{command: rpl_WELCOME(), source: source, args: [nick, _]}}, data) do
+ Logger.debug "#{inspect(data)} <<< #{inspect(l)}"
{:keep_state, %State{data | nick: nick, welcome: [l | data.welcome], server: source}, {:state_timeout, @reply_timeout, nil}}
end
@welcome_numeric [rpl_WELCOME, rpl_YOURHOST, rpl_CREATED, rpl_MYINFO, rpl_ISUPPORT]
def welcome(:info, {_, _, l = %Line{command: rpl_MYINFO(), source: source, args: [_, _, version, umodes, cmodes | rest]}}, data) do
+ Logger.debug "#{inspect(data)} <<< #{inspect(l)}"
cmodes_with_params = case rest do
[] -> nil
[c] -> c
@@ -627,7 +638,8 @@ defmodule Irc.Connection do
{:keep_state, data, {:state_timeout, @reply_timeout, nil}}
end
- def welcome(:info, {_, _, %Line{command: rpl_ISUPPORT(), args: [_ | isupport]}}, data) do
+ def welcome(:info, {_, _, %Line{command: rpl_ISUPPORT(), args: [_ | isupport]} = line}, data) do
+ Logger.debug "#{inspect(data)} <<< #{inspect(line)}"
supports = Irc.Parser.Isupport.parse(isupport, data.isupport)
{:keep_state, %State{data | isupport: supports}, {:state_timeout, @reply_timeout, nil}}
end
@@ -652,20 +664,23 @@ defmodule Irc.Connection do
{:keep_state_and_data, {:state_timeout, @reply_timeout, nil}}
end
- def motd(:info, {_, _, %Line{command: err_NOMOTD()}}, data) do
+ def motd(:info, {_, _, %Line{command: err_NOMOTD()} = line}, data) do
+ Logger.debug "#{inspect(data)} <<< #{inspect(line)}"
{:next_state, :registered, %State{data | motd: []}}
end
- def motd(:info, {_, _, %Line{command: rpl_MOTDSTART(), args: [_, line]}}, data) do
+ def motd(:info, {_, _, %Line{command: rpl_MOTDSTART(), args: [_, line]} = line}, data) do
+ Logger.debug "#{inspect(data)} <<< #{inspect(line)}"
{:keep_state, %State{data | motd: [line]}, {:state_timeout, @reply_timeout, nil}}
end
- def motd(:info, {_, _, %Line{command: rpl_MOTD(), args: [_, line]}}, data) do
- {:keep_state, %State{data | motd: [line | data.motd]}, {:state_timeout, @reply_timeout, nil}}
+ def motd(:info, {_, _, %Line{command: rpl_MOTD(), args: [_, motd_line]} = line}, data) do
+ {:keep_state, %State{data | motd: [motd_line | data.motd]}, {:state_timeout, @reply_timeout, nil}}
end
- def motd(:info, {_, _, %Line{command: rpl_ENDOFMOTD(), args: [_, line]}}, data) do
- {:next_state, :registered, %State{data | motd: List.reverse([line | data.motd])}}
+ def motd(:info, {_, _, %Line{command: rpl_ENDOFMOTD(), args: [_, motd_line]} = line}, data) do
+ Logger.debug "#{inspect(data)} <<< #{inspect(line)}"
+ {:next_state, :registered, %State{data | motd: Enum.reverse([motd_line | data.motd])}}
end
def motd(:state_timeout, _, data) do
@@ -728,7 +743,7 @@ defmodule Irc.Connection do
end
def registered(:state_timeout, :ping, data) do
- case socksend(data, [?P, ?I, ?N, ?G, 0x20, String.to_charlist(data.server)]) do
+ case socksend(data, [?P, ?I, ?N, ?G, 0x20, String.to_charlist(data.server.server)]) do
:ok -> {:keep_state_and_data, @conn_pong_timeout}
error -> to_disconnected(error, data)
end
@@ -763,7 +778,7 @@ defmodule Irc.Connection do
to_disconnected({:irc_error, Enum.join(args, " ")}, data)
end
- def process_line(%Line{command: "PONG", args: [server | _]}, data = %{server: server}) do
+ def process_line(%Line{command: "PONG", source: server}, data = %{server: server}) do
{:keep_state_and_data, @conn_ping_timeout}
end
@@ -964,8 +979,8 @@ defmodule Irc.Connection do
@doc false
def terminate(reason, state, data) do
- if state.socket do
- ConnectionSocket.close(state.socket)
+ if data.socket do
+ ConnectionSocket.close(data.socket)
end
unless data.errored do
send(data.process, {:irc_conn_error, self(), :down})
@@ -1019,6 +1034,8 @@ defmodule Irc.Connection do
capabs = Map.get(args, :capabs) || []
reconnect = Map.get(args, :reconnect, true)
batch = Map.get(args, :batch, true)
+ sasl = Map.get(args, :sasl, false)
+ echo = Map.get(args, :echo, true)
connect_opts = Map.get(args, :connect_opts) || []
with \
@@ -1038,6 +1055,8 @@ defmodule Irc.Connection do
pass: pass,
reconnect: reconnect,
batch: batch,
+ sasl: sasl,
+ echo: echo,
connect_opts: connect_opts,
connect_timeout: connect_timeout
}}
diff --git a/lib/irc/parser/line.ex b/lib/irc/parser/line.ex
index 5aa5a9b..48ddd9c 100644
--- a/lib/irc/parser/line.ex
+++ b/lib/irc/parser/line.ex
@@ -242,5 +242,14 @@ defmodule Irc.Parser.Line do
end
end
-end
+ defimpl Inspect, for: __MODULE__ do
+ @moduledoc false
+ import Inspect.Algebra
+ def inspect(struct, _opts) do
+ tags = Enum.map(struct.tags, fn({k, v}) -> concat([k, "=", v]) end) |> Enum.join(",")
+ Enum.join(["#IRC.Line<", struct.source, " ", struct.command, " ", inspect(struct.args), " (", tags, ")>"], "")
+ end
+ end
+
+end
diff --git a/lib/irc/shout.ex b/lib/irc/shout.ex
index 8a3966b..912517c 100644
--- a/lib/irc/shout.ex
+++ b/lib/irc/shout.ex
@@ -12,9 +12,9 @@ defmodule Irc.Shout do
def do_shout({:ok, conn}, target, message, opts) do
mon = Process.monitor(conn)
result = with \
- {:ok, _info} <- Connection.await_up(conn, Keyword.get(opts, :await_up_timeout)),
- :ok <- join(conn, target),
- :ok <- Connection.sendline(conn, ['PRIVMSG ', target, ' :', message])
+ {_, {:ok, _info}} <- {:await_up, Connection.await_up(conn, Keyword.get(opts, :await_up_timeout))},
+ {_, :ok} <- {:join, join(conn, target)},
+ {_, :ok} <- {:send, Connection.sendline(conn, ['PRIVMSG ', target, ' :', message])}
do
:ok
else