Current section

Files

Jump to
gsmtp src smtp.erl
Raw

src/smtp.erl

-module(smtp).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([send/3]).
-export_type([error/0]).
-type error() :: {tcp_error, mug:error()} |
missing_server_code_error |
{invalid_server_code_error, binary(), integer()}.
-file("/home/andre/Code/gleam/gsmtp/src/smtp.gleam", 15).
-spec check_server_code(integer(), bitstring()) -> {ok, nil} | {error, error()}.
check_server_code(Expected_code, Response) ->
_assert_subject = gleam@bit_array:to_string(Response),
{ok, Response_str} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"smtp"/utf8>>,
function => <<"check_server_code"/utf8>>,
line => 16})
end,
gleam@result:'try'(
begin
_pipe = gleam@string:split_once(Response_str, <<" "/utf8>>),
gleam@result:map_error(
_pipe,
fun(_) -> missing_server_code_error end
)
end,
fun(_use0) ->
{Server_code, _} = _use0,
gleam@result:'try'(
begin
_pipe@1 = gleam_stdlib:parse_int(Server_code),
gleam@result:map_error(
_pipe@1,
fun(_) ->
{invalid_server_code_error,
Server_code,
Expected_code}
end
)
end,
fun(Parsed_code) -> case Parsed_code =:= Expected_code of
true ->
{ok, nil};
false ->
{error,
{invalid_server_code_error,
Server_code,
Expected_code}}
end end
)
end
).
-file("/home/andre/Code/gleam/gsmtp/src/smtp.gleam", 48).
-spec tcp_send(mug:socket(), binary()) -> {ok, nil} | {error, error()}.
tcp_send(Socket, Message) ->
_pipe = mug:send(Socket, <<Message/binary>>),
gleam@result:map_error(_pipe, fun(Field@0) -> {tcp_error, Field@0} end).
-file("/home/andre/Code/gleam/gsmtp/src/smtp.gleam", 53).
-spec tcp_receive(mug:socket(), integer()) -> {ok, bitstring()} |
{error, error()}.
tcp_receive(Socket, Timeout) ->
gleam@result:'try'(
begin
_pipe = mug:'receive'(Socket, Timeout),
gleam@result:map_error(
_pipe,
fun(Field@0) -> {tcp_error, Field@0} end
)
end,
fun(Packet) ->
_assert_subject = gleam@bit_array:to_string(Packet),
{ok, Packet_str} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"smtp"/utf8>>,
function => <<"tcp_receive"/utf8>>,
line => 59})
end,
logging:log(debug, <<"SERVER: "/utf8, Packet_str/binary>>),
{ok, Packet}
end
).
-file("/home/andre/Code/gleam/gsmtp/src/smtp.gleam", 36).
-spec cmd(mug:socket(), integer(), binary()) -> {ok, bitstring()} |
{error, error()}.
cmd(Socket, Expected_code, Message) ->
logging:log(
debug,
<<<<"CLIENT: "/utf8, Message/binary>>/binary, "\r\n"/utf8>>
),
gleam@result:'try'(
tcp_send(Socket, <<Message/binary, "\r\n"/utf8>>),
fun(_) ->
gleam@result:'try'(
tcp_receive(Socket, 500),
fun(Packet) ->
gleam@result:'try'(
check_server_code(Expected_code, Packet),
fun(_) -> {ok, Packet} end
)
end
)
end
).
-file("/home/andre/Code/gleam/gsmtp/src/smtp.gleam", 65).
-spec tcp_connect(binary(), integer(), integer()) -> {ok, mug:socket()} |
{error, error()}.
tcp_connect(Host, Port, Timeout) ->
_pipe = mug:new(Host, Port),
_pipe@1 = mug:timeout(_pipe, Timeout),
_pipe@2 = mug:connect(_pipe@1),
gleam@result:map_error(_pipe@2, fun(Field@0) -> {tcp_error, Field@0} end).
-file("/home/andre/Code/gleam/gsmtp/src/smtp.gleam", 72).
-spec log_sending_info(binary(), integer(), builder:message()) -> nil.
log_sending_info(Host, Port, Message) ->
logging:log(info, <<"SENDING MAIL"/utf8>>),
logging:log(
info,
<<<<<<"HOST: "/utf8, Host/binary>>/binary, ":"/utf8>>/binary,
(begin
_pipe = Port,
erlang:integer_to_binary(_pipe)
end)/binary>>
),
logging:log(info, <<"FROM: "/utf8, (erlang:element(2, Message))/binary>>),
logging:log(
info,
<<"TO: "/utf8,
(gleam@string:join(erlang:element(3, Message), <<", "/utf8>>))/binary>>
),
logging:log(info, <<"SUBJECT: "/utf8, (erlang:element(4, Message))/binary>>),
logging:log(info, <<"BODY: "/utf8, (erlang:element(5, Message))/binary>>).
-file("/home/andre/Code/gleam/gsmtp/src/smtp.gleam", 81).
-spec setup_data(builder:message()) -> binary().
setup_data(Message) ->
_pipe = <<""/utf8>>,
_pipe@1 = gleam@string:append(
_pipe,
<<<<"Subject: "/utf8, (erlang:element(4, Message))/binary>>/binary,
"\r\n"/utf8>>
),
_pipe@2 = gleam@string:append(
_pipe@1,
<<<<"From: <"/utf8, (erlang:element(2, Message))/binary>>/binary,
">\r\n"/utf8>>
),
_pipe@3 = gleam@string:append(
_pipe@2,
<<<<"To: <"/utf8,
(gleam@string:join(erlang:element(3, Message), <<","/utf8>>))/binary>>/binary,
">\r\n"/utf8>>
),
_pipe@4 = gleam@string:append(_pipe@3, <<"\r\n"/utf8>>),
_pipe@5 = gleam@string:append(_pipe@4, erlang:element(5, Message)),
gleam@string:append(_pipe@5, <<"\r\n."/utf8>>).
-file("/home/andre/Code/gleam/gsmtp/src/smtp.gleam", 91).
-spec send(binary(), integer(), builder:message()) -> {ok, nil} |
{error, error()}.
send(Host, Port, Message) ->
log_sending_info(Host, Port, Message),
Timeout = 500,
gleam@result:'try'(
tcp_connect(Host, Port, Timeout),
fun(Socket) ->
gleam@result:'try'(
tcp_receive(Socket, Timeout),
fun(_) ->
gleam@result:'try'(
cmd(Socket, 250, <<"HELO localhost"/utf8>>),
fun(_) ->
gleam@result:'try'(
cmd(
Socket,
250,
<<<<"MAIL FROM:<"/utf8,
(erlang:element(2, Message))/binary>>/binary,
">"/utf8>>
),
fun(_) ->
gleam@result:'try'(
cmd(
Socket,
250,
<<<<"RCPT TO:<"/utf8,
(gleam@string:join(
erlang:element(
3,
Message
),
<<","/utf8>>
))/binary>>/binary,
">"/utf8>>
),
fun(_) ->
gleam@result:'try'(
cmd(
Socket,
354,
<<"DATA"/utf8>>
),
fun(_) ->
gleam@result:'try'(
cmd(
Socket,
250,
setup_data(Message)
),
fun(_) ->
gleam@result:'try'(
cmd(
Socket,
221,
<<"QUIT"/utf8>>
),
fun(_) ->
{ok, nil}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).