echo daemon works well enough
This commit is contained in:
@@ -7,3 +7,15 @@
|
|||||||
- client connects to server
|
- client connects to server
|
||||||
- server writes back "hello"
|
- server writes back "hello"
|
||||||
- server closes connection
|
- server closes connection
|
||||||
|
|
||||||
|
- x01-noisy-hello:
|
||||||
|
- was going to be hello world over noise
|
||||||
|
- abandoned
|
||||||
|
|
||||||
|
- `x02-_`:
|
||||||
|
- skipped because the `2` key on my laptop doesn't work
|
||||||
|
|
||||||
|
- x03-echo:
|
||||||
|
- telnet echo server
|
||||||
|
- budget version of zx template "traditional erlang service
|
||||||
|
application"
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
% @doc echo server client
|
|
||||||
-module(echoc).
|
|
||||||
|
|
||||||
-export([main/0]).
|
|
||||||
|
|
||||||
main() ->
|
|
||||||
io:format("you can't help people who won't help themselves.~n", []).
|
|
||||||
@@ -1,265 +0,0 @@
|
|||||||
%% @doc
|
|
||||||
%% super simple telnet echo server daemon
|
|
||||||
%%
|
|
||||||
%% no noise yet
|
|
||||||
%%
|
|
||||||
%% pimps and hos model (from trash talk template):
|
|
||||||
%%
|
|
||||||
%% ```
|
|
||||||
%% t_sup
|
|
||||||
%% |
|
|
||||||
%% t_clients
|
|
||||||
%% |
|
|
||||||
%% +--- t_client_man pimp
|
|
||||||
%% |
|
|
||||||
%% +--- t_client_sup bottom bitch
|
|
||||||
%% |
|
|
||||||
%% +--- <0.1.0> (t_client) ho
|
|
||||||
%% +--- <0.2.0> (t_client) ho
|
|
||||||
%% +--- <0.3.0> (t_client) ho
|
|
||||||
%% '''
|
|
||||||
%%
|
|
||||||
%% each ho:
|
|
||||||
%%
|
|
||||||
%% <ul>
|
|
||||||
%% <li>Takes listen socket as arg</li>
|
|
||||||
%% <li>spawns next ho</li>
|
|
||||||
%% </ul>
|
|
||||||
%%
|
|
||||||
%% ```
|
|
||||||
%% start(ListenSocket) ->
|
|
||||||
%% t_client_sup:start_acceptor(ListenSocket).
|
|
||||||
%%
|
|
||||||
%% start_link(ListenSocket) ->
|
|
||||||
%% proc_lib:start_link(?MODULE, init, [self(), ListenSocket]).
|
|
||||||
%%
|
|
||||||
%% init(Parent, ListenSocket) ->
|
|
||||||
%% ok = io:format("~p Listening.~n", [self()]),
|
|
||||||
%% Debug = sys:debug_options([]),
|
|
||||||
%% ok = proc_lib:init_ack(Parent, {ok, self()}),
|
|
||||||
%% listen(Parent, Debug, ListenSocket).
|
|
||||||
|
|
||||||
|
|
||||||
%%
|
|
||||||
%% listen(Parent, Debug, ListenSocket) ->
|
|
||||||
%% case gen_tcp:accept(ListenSocket) of
|
|
||||||
%% {ok, Socket} ->
|
|
||||||
%% {ok, _} = start(ListenSocket),
|
|
||||||
%% {ok, Peer} = inet:peername(Socket),
|
|
||||||
%% ok = io:format("~p Connection accepted from: ~p~n", [self(), Peer]),
|
|
||||||
%% ok = t_client_man:enroll(),
|
|
||||||
%% State = #s{socket = Socket},
|
|
||||||
%% loop(Parent, Debug, State);
|
|
||||||
%% {error, closed} ->
|
|
||||||
%% ok = io:format("~p Retiring: Listen socket closed.~n", [self()]),
|
|
||||||
%% exit(normal)
|
|
||||||
%% end.
|
|
||||||
%% '''
|
|
||||||
%%
|
|
||||||
%% @end
|
|
||||||
-module(echod).
|
|
||||||
|
|
||||||
-include("./ansi.hrl").
|
|
||||||
-export([main/0]).
|
|
||||||
|
|
||||||
|
|
||||||
%% pimp state
|
|
||||||
-record(ps,
|
|
||||||
{lsock = none :: gen_tcp:socket(),
|
|
||||||
hos = [] :: [{pid(), reference()}],
|
|
||||||
ho_names = init_ho_names() :: [string()]}).
|
|
||||||
|
|
||||||
-type pimp_state() :: #ps{}.
|
|
||||||
|
|
||||||
|
|
||||||
%% ho state
|
|
||||||
-record(hs,
|
|
||||||
{name = none :: string(),
|
|
||||||
daddy = none :: pid(),
|
|
||||||
vagene = none :: gen_tcp:socket()}).
|
|
||||||
|
|
||||||
-type ho_state() :: #hs{}.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-spec main() -> no_return().
|
|
||||||
%% @doc
|
|
||||||
%% run the echo server daemon
|
|
||||||
|
|
||||||
main() ->
|
|
||||||
%% show the splash screen nigga
|
|
||||||
ok = splash(),
|
|
||||||
case gen_tcp:listen(6969, [binary, {packet, line}, {active, once}]) of
|
|
||||||
{ok, LSock} ->
|
|
||||||
%% we out here
|
|
||||||
%% we not wuz sockitz nigga
|
|
||||||
%% we **be** sockets
|
|
||||||
%% nigga
|
|
||||||
ok = pimp_logfln("Butters iz in the hizzouse: ~tp", [self()]),
|
|
||||||
pimp_loop(#ps{lsock = LSock});
|
|
||||||
{error, closed} ->
|
|
||||||
%% dont be pimp
|
|
||||||
io:format("PIMP ERROR: ~tp~n", [Error])
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-spec splash() -> ok.
|
|
||||||
%% @private
|
|
||||||
%% show splash screen
|
|
||||||
|
|
||||||
splash() ->
|
|
||||||
SplashStr = """
|
|
||||||
RBX example 2 telnet echo server daemon
|
|
||||||
"one" part of the many-to-one
|
|
||||||
""",
|
|
||||||
io:format("~s~n", [SplashStr]).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-spec pimp_loop(PimpState) -> NoReturn when
|
|
||||||
PimpState :: pimp_state(),
|
|
||||||
NoReturn :: no_return().
|
|
||||||
%% @private
|
|
||||||
%% runs in context of main
|
|
||||||
|
|
||||||
pimp_loop(PS = #ps{lsock = LSock, hos = Hos, ho_names = Names}) ->
|
|
||||||
%% blocks until client connects
|
|
||||||
case gen_tcp:accept(LSock) of
|
|
||||||
{ok, ASock} ->
|
|
||||||
{HoName, NewNames} = recycle_ho_names(Names),
|
|
||||||
InitHoState = #hs{name = HoName,
|
|
||||||
daddy = self(),
|
|
||||||
vagene = ASock},
|
|
||||||
SpawnHo = fun() -> do_be_ho(InitHoState) end,
|
|
||||||
NewHo = {_Pid, _Ref} = erlang:spawn_monitor(SpawnHo),
|
|
||||||
NewPimpState = PS#ps{hos = [NewHo | Hos],
|
|
||||||
ho_names = NewNames},
|
|
||||||
pimp_loop(NewPimpState);
|
|
||||||
{echo, From, Data} ->
|
|
||||||
echo_except(From, Data, Hos),
|
|
||||||
pimp_loop(PS);
|
|
||||||
{'DOWN', Ref, process, Pid, Info} ->
|
|
||||||
ok = pimp_logfln("ho down: ~tp; reason: ~tw", [Pid, Info]),
|
|
||||||
NewHos = lists:delete({Pid, Ref}, Hos),
|
|
||||||
NewPS = PS#ps{hos = NewHos},
|
|
||||||
pimp_loop(NewPS);
|
|
||||||
Bad ->
|
|
||||||
pimp_logfln("bad msg: ~tw", [Bad]),
|
|
||||||
pimp_logln("liquidating the hos"),
|
|
||||||
liquidate_hos(Hos),
|
|
||||||
gen_tcp:close(LSock)
|
|
||||||
end.
|
|
||||||
|
|
||||||
liquidate_hos([{HoPid, _HoRef} | Hos]) ->
|
|
||||||
pimp_logfln("liquidating ~tp", [HoPid]),
|
|
||||||
exit(HoPid, kill),
|
|
||||||
liquidate_hos(Hos);
|
|
||||||
liquidate_hos([]) ->
|
|
||||||
pimp_logln("it's done").
|
|
||||||
|
|
||||||
|
|
||||||
% skip if equal
|
|
||||||
echo_except(SrcPid, Data, [{SrcPid, _Ref} | Rest]) ->
|
|
||||||
echo_except(SrcPid, Data, Rest);
|
|
||||||
echo_except(SrcPid, Data, [{Pid, _Ref} | Rest]) ->
|
|
||||||
Pid ! {echo, Data},
|
|
||||||
echo_except(SrcPid, Data, Rest);
|
|
||||||
echo_except(_, _, []) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
|
|
||||||
-spec spawn_ho(HoState) ->
|
|
||||||
|
|
||||||
|
|
||||||
-spec do_be_ho(HoState) -> NoReturn when
|
|
||||||
HoState :: ho_state(),
|
|
||||||
NoReturn :: no_return().
|
|
||||||
%% @doc
|
|
||||||
%% ain't no rest for the wicked
|
|
||||||
|
|
||||||
do_be_ho(HS = #hs{name = Name, daddy = Daddy, vagene = ASock}) ->
|
|
||||||
Msg = io:format("HI! I'm ~ts. What's your name?\r\n", [Name]),
|
|
||||||
ok = ho_send(ASock, Msg),
|
|
||||||
receive
|
|
||||||
{tcp, ASock, Data} ->
|
|
||||||
ho_rcvd(Data),
|
|
||||||
Daddy ! {echo, self(), Data},
|
|
||||||
do_be_ho(HS);
|
|
||||||
{echo, Data} ->
|
|
||||||
ho_send(ASock, Data),
|
|
||||||
do_be_ho(HS);
|
|
||||||
{tcp_closed, ASock} ->
|
|
||||||
exit(its_fine)
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
pimp_logfln(MsgStr, Args) ->
|
|
||||||
pimp_logln(io_lib:format(MsgStr, Args)).
|
|
||||||
|
|
||||||
pimp_logln(MsgStr) ->
|
|
||||||
PimpPfx = io_lib:format("pimp ~tp :: ", [self()]),
|
|
||||||
Msg = [?ANSI_BOLD([PimpPfx, MsgStr, "\n"])],
|
|
||||||
ok = io:put_chars(Msg),
|
|
||||||
ok.
|
|
||||||
|
|
||||||
|
|
||||||
ho_rcvd(MsgStr) ->
|
|
||||||
ok = io:format("ho ~tp << ~tw~n", [self(), MsgStr]),
|
|
||||||
ok.
|
|
||||||
|
|
||||||
ho_send(Socket, Msg) ->
|
|
||||||
ok = io:format("ho ~tp >> ~tw~n", [self(), Msg]),
|
|
||||||
ok = gen_tcp:send(Socket, Msg),
|
|
||||||
ok.
|
|
||||||
|
|
||||||
|
|
||||||
init_ho_names() ->
|
|
||||||
["Crystal",
|
|
||||||
"Tiffany",
|
|
||||||
"Amber",
|
|
||||||
"Brandy",
|
|
||||||
"Lola",
|
|
||||||
"Angel",
|
|
||||||
"Ginger",
|
|
||||||
"Candy",
|
|
||||||
"Charity",
|
|
||||||
"Anastasia",
|
|
||||||
"Cherry",
|
|
||||||
"Kitty",
|
|
||||||
"Jade",
|
|
||||||
"Destiny",
|
|
||||||
"Devon",
|
|
||||||
"Chastity",
|
|
||||||
"Raven",
|
|
||||||
"Scarlett",
|
|
||||||
"Bambi",
|
|
||||||
"Star",
|
|
||||||
"Paris",
|
|
||||||
"Dallas",
|
|
||||||
"Diamond",
|
|
||||||
"Skye",
|
|
||||||
"Trinity",
|
|
||||||
"Tawny",
|
|
||||||
"Layla",
|
|
||||||
"Lexie",
|
|
||||||
"Roxy",
|
|
||||||
"Porsche",
|
|
||||||
"Nevaeh",
|
|
||||||
"Ashlynn",
|
|
||||||
"Aspen",
|
|
||||||
"Chyna",
|
|
||||||
"Lexus",
|
|
||||||
"Unique",
|
|
||||||
"Chardonnay",
|
|
||||||
"Houston",
|
|
||||||
"London",
|
|
||||||
"Coco",
|
|
||||||
"Luscious",
|
|
||||||
"Delight",
|
|
||||||
"Capri",
|
|
||||||
"Trixie",
|
|
||||||
"Cinnamon"].
|
|
||||||
|
|
||||||
recycle_ho_names([N | Ns]) ->
|
|
||||||
{N, Ns ++ [N]}.
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
% @doc echo server client
|
||||||
|
-module(echoc).
|
||||||
|
|
||||||
|
-export([main/0]).
|
||||||
|
|
||||||
|
main() ->
|
||||||
|
{ok, Socket} = gen_tcp:connect("localhost", 6969, [binary, {packet, 0}]),
|
||||||
|
loop(Socket).
|
||||||
|
|
||||||
|
|
||||||
|
loop(Socket) ->
|
||||||
|
ok = inet:setopts(Socket, [{active, once}]),
|
||||||
|
receive
|
||||||
|
{tcp, Socket, Bytes} ->
|
||||||
|
ok = io:format("< ~tp~n", [Bytes]),
|
||||||
|
loop(Socket);
|
||||||
|
{tcp_closed, Socket} ->
|
||||||
|
ok = io:format("connection terminated~n", []),
|
||||||
|
exit(normal)
|
||||||
|
end.
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
%% @doc
|
||||||
|
%% super simple telnet echo server daemon
|
||||||
|
%%
|
||||||
|
%% no noise yet
|
||||||
|
%%
|
||||||
|
%% pimps and hos model (from trash talk template):
|
||||||
|
%%
|
||||||
|
%% ```
|
||||||
|
%% t_sup
|
||||||
|
%% |
|
||||||
|
%% t_clients
|
||||||
|
%% |
|
||||||
|
%% +--- t_client_man pimp
|
||||||
|
%% |
|
||||||
|
%% +--- t_client_sup bottom bitch
|
||||||
|
%% |
|
||||||
|
%% +--- <0.1.0> (t_client) ho
|
||||||
|
%% +--- <0.2.0> (t_client) ho
|
||||||
|
%% +--- <0.3.0> (t_client) ho
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% each ho:
|
||||||
|
%%
|
||||||
|
%% <ul>
|
||||||
|
%% <li>Takes listen socket as arg</li>
|
||||||
|
%% <li>spawns next ho</li>
|
||||||
|
%% </ul>
|
||||||
|
%%
|
||||||
|
%% ```
|
||||||
|
%% start(ListenSocket) ->
|
||||||
|
%% t_client_sup:start_acceptor(ListenSocket).
|
||||||
|
%%
|
||||||
|
%% start_link(ListenSocket) ->
|
||||||
|
%% proc_lib:start_link(?MODULE, init, [self(), ListenSocket]).
|
||||||
|
%%
|
||||||
|
%% init(Parent, ListenSocket) ->
|
||||||
|
%% ok = io:format("~p Listening.~n", [self()]),
|
||||||
|
%% Debug = sys:debug_options([]),
|
||||||
|
%% ok = proc_lib:init_ack(Parent, {ok, self()}),
|
||||||
|
%% listen(Parent, Debug, ListenSocket).
|
||||||
|
%%
|
||||||
|
%% listen(Parent, Debug, ListenSocket) ->
|
||||||
|
%% case gen_tcp:accept(ListenSocket) of
|
||||||
|
%% {ok, Socket} ->
|
||||||
|
%% {ok, _} = start(ListenSocket),
|
||||||
|
%% {ok, Peer} = inet:peername(Socket),
|
||||||
|
%% ok = io:format("~p Connection accepted from: ~p~n", [self(), Peer]),
|
||||||
|
%% ok = t_client_man:enroll(),
|
||||||
|
%% State = #s{socket = Socket},
|
||||||
|
%% loop(Parent, Debug, State);
|
||||||
|
%% {error, closed} ->
|
||||||
|
%% ok = io:format("~p Retiring: Listen socket closed.~n", [self()]),
|
||||||
|
%% exit(normal)
|
||||||
|
%% end.
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% @end
|
||||||
|
-module(echod).
|
||||||
|
|
||||||
|
-include("./ansi.hrl").
|
||||||
|
-export([main/0]).
|
||||||
|
|
||||||
|
|
||||||
|
% ho from pimp pov
|
||||||
|
-record(pho,
|
||||||
|
{pid :: pid(),
|
||||||
|
ref :: reference(),
|
||||||
|
name :: string()}).
|
||||||
|
|
||||||
|
%% pimp state
|
||||||
|
-record(ps,
|
||||||
|
{lsock = none :: gen_tcp:socket(),
|
||||||
|
hos = [] :: [#pho{}],
|
||||||
|
ho_names = init_ho_names() :: [string()]}).
|
||||||
|
|
||||||
|
|
||||||
|
%% ho state
|
||||||
|
-record(hs,
|
||||||
|
{name = none :: string(),
|
||||||
|
daddy = none :: pid(),
|
||||||
|
asock = none :: gen_tcp:socket()}).
|
||||||
|
|
||||||
|
|
||||||
|
main() ->
|
||||||
|
io:format("RBX example 2 telnet echo server daemon~n"
|
||||||
|
"`one' part of the many-to-one relationship~n",
|
||||||
|
[]),
|
||||||
|
p_init().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
% pimp process startup
|
||||||
|
p_init() ->
|
||||||
|
p_logln("pimp startup (p_init)"),
|
||||||
|
Port = 6969,
|
||||||
|
Opts = [binary, {packet, line}, {active, once}],
|
||||||
|
case gen_tcp:listen(Port, Opts) of
|
||||||
|
{ok, LSock} ->
|
||||||
|
ok = p_logfln("pimp starting: ~tp", [self()]),
|
||||||
|
PS_I = #ps{lsock = LSock},
|
||||||
|
PS_II = p_spawn_ho(PS_I),
|
||||||
|
p_loop(PS_II);
|
||||||
|
{error, closed} ->
|
||||||
|
%% dont be pimp
|
||||||
|
p_logln("listen socket closed")
|
||||||
|
end.
|
||||||
|
|
||||||
|
p_loop(PS = #ps{hos = Hos}) ->
|
||||||
|
receive
|
||||||
|
{ho, _HoPid, taken} ->
|
||||||
|
NewPS = p_spawn_ho(PS),
|
||||||
|
p_loop(NewPS);
|
||||||
|
{ho, HoPid, sent, Data} ->
|
||||||
|
HoName = p_ho_name(HoPid, PS),
|
||||||
|
SendMessage = io_lib:format("~ts :: ~ts\r\n", [HoName, Data]),
|
||||||
|
ok = p_echo_except(HoPid, HoName, SendMessage, Hos),
|
||||||
|
p_loop(PS);
|
||||||
|
Down = {'DOWN', _, _, _, _} ->
|
||||||
|
NewPS = p_ho_down(Down, PS),
|
||||||
|
p_loop(NewPS);
|
||||||
|
Unknown ->
|
||||||
|
ok = p_logfln("unknown message: ~tw", [Unknown]),
|
||||||
|
p_loop(PS)
|
||||||
|
end.
|
||||||
|
|
||||||
|
% given pid of ho, get her name
|
||||||
|
p_ho_name(HoPid, #ps{hos = Hos}) ->
|
||||||
|
case lists:keyfind(HoPid, #pho.pid, Hos) of
|
||||||
|
#pho{name = Name} -> Name;
|
||||||
|
false -> "JaneDoe"
|
||||||
|
end.
|
||||||
|
|
||||||
|
% pimp spawns new ho
|
||||||
|
p_spawn_ho(PS = #ps{lsock = LSock, hos = Hos, ho_names = Names}) ->
|
||||||
|
% new name for ho, initial ho state
|
||||||
|
{N, NewNames} = recycle(Names),
|
||||||
|
InitHS = #hs{name = N, daddy = self()},
|
||||||
|
% spawn the new ho
|
||||||
|
ok = p_logfln("spawning new ho: ~ts", [N]),
|
||||||
|
SpawnHo = fun() -> h_init(LSock, InitHS) end,
|
||||||
|
{HPid, HRef} = erlang:spawn_monitor(SpawnHo),
|
||||||
|
% new ho record from Pimp POV
|
||||||
|
NewHo = #pho{pid = HPid, ref = HRef, name = N},
|
||||||
|
ok = p_logfln("spawned new ho: ~tw", [NewHo]),
|
||||||
|
NewPS = PS#ps{hos = [NewHo | Hos], ho_names = NewNames},
|
||||||
|
NewPS.
|
||||||
|
|
||||||
|
% ho down, remove her from roster
|
||||||
|
p_ho_down({'DOWN', _Ref, process, Pid, Info}, PS = #ps{hos = Hos}) ->
|
||||||
|
ok = p_logfln("ho down: ~tp; reason: ~tw", [Pid, Info]),
|
||||||
|
NewHos = lists:keydelete(Pid, #pho.pid, Hos),
|
||||||
|
NewPS = PS#ps{hos = NewHos},
|
||||||
|
NewPS.
|
||||||
|
|
||||||
|
|
||||||
|
% echo message from one ho to all the rest
|
||||||
|
% skip if equal
|
||||||
|
p_echo_except(SrcPid, SrcName, Data, [#pho{pid = SrcPid} | Rest]) ->
|
||||||
|
p_echo_except(SrcPid, SrcName, Data, Rest);
|
||||||
|
p_echo_except(SrcPid, SrcName, Data, [#pho{pid = DstPid} | Rest]) ->
|
||||||
|
DstPid ! {pimp, send, Data},
|
||||||
|
p_echo_except(SrcPid, SrcName, Data, Rest);
|
||||||
|
p_echo_except(_, _, _, []) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%% runs in ho context
|
||||||
|
h_init(LSock, HS = #hs{name = Name, daddy = Daddy, asock = none}) ->
|
||||||
|
h_logln(Name, "h_init"),
|
||||||
|
% this is key: accept needs to run in ho context, otherwise she
|
||||||
|
% doesn't own the acceptor socket
|
||||||
|
%
|
||||||
|
% blocks until client connects
|
||||||
|
case gen_tcp:accept(LSock) of
|
||||||
|
{ok, ASock} ->
|
||||||
|
h_logln(Name, "taken"),
|
||||||
|
% tell daddy to spawn the next ho
|
||||||
|
Daddy ! {ho, self(), taken},
|
||||||
|
Welcome = io_lib:format("HI! I'm ~ts. What's your name?\r\n",
|
||||||
|
[Name]),
|
||||||
|
ok = h_send(Name, ASock, Welcome),
|
||||||
|
HS_II = HS#hs{asock = ASock},
|
||||||
|
h_loop(HS_II);
|
||||||
|
{error, closed} ->
|
||||||
|
h_logln(Name, "didn't get taken")
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
h_loop(HS = #hs{name = Name, daddy = Daddy, asock = ASock}) ->
|
||||||
|
ok = inet:setopts(ASock, [{active, once}]),
|
||||||
|
receive
|
||||||
|
{tcp, ASock, Data} ->
|
||||||
|
Data_II = string:chomp(Data),
|
||||||
|
ok = h_rcvd(Name, Data_II),
|
||||||
|
Daddy ! {ho, self(), sent, Data_II},
|
||||||
|
h_loop(HS);
|
||||||
|
{pimp, send, Data} ->
|
||||||
|
ok = h_send(Name, ASock, Data),
|
||||||
|
h_loop(HS);
|
||||||
|
{tcp_closed, ASock} ->
|
||||||
|
exit(its_fine);
|
||||||
|
Unknown ->
|
||||||
|
ok = h_logfln(Name, "unknown message: ~tw", [Unknown]),
|
||||||
|
h_loop(HS)
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
% pimp log in bold
|
||||||
|
p_logln(LogStr) ->
|
||||||
|
Msg = io_lib:format("!! Daddy :: ~ts~n", [LogStr]),
|
||||||
|
PimpChars = ?ANSI_BOLD([Msg]),
|
||||||
|
io:put_chars(PimpChars).
|
||||||
|
|
||||||
|
p_logfln(LogStr, Args) ->
|
||||||
|
p_logln(io_lib:format(LogStr, Args)).
|
||||||
|
|
||||||
|
|
||||||
|
% ho log dimmed
|
||||||
|
h_logln(HoName, LogStr) ->
|
||||||
|
FMsg = io_lib:format("!! ~ts :: ~ts~n", [HoName, LogStr]),
|
||||||
|
HoChars = ?ANSI_DIM([FMsg]),
|
||||||
|
io:put_chars(HoChars).
|
||||||
|
|
||||||
|
h_logfln(HoName, MsgStr, Args) ->
|
||||||
|
h_logln(HoName, io_lib:format(MsgStr, Args)).
|
||||||
|
|
||||||
|
% normal: john messages
|
||||||
|
h_rcvd(Name, MsgStr) ->
|
||||||
|
Msg = io_lib:format("<< ~ts :: ~ts~n", [Name, MsgStr]),
|
||||||
|
io:put_chars(Msg).
|
||||||
|
|
||||||
|
h_send(Name, Socket, Msg) ->
|
||||||
|
ok = io:format(">> ~ts :: ~ts~n", [Name, Msg]),
|
||||||
|
gen_tcp:send(Socket, Msg).
|
||||||
|
|
||||||
|
|
||||||
|
init_ho_names() ->
|
||||||
|
["Crystal", "Tiffany", "Amber", "Brandy", "Lola", "Angel",
|
||||||
|
"Ginger", "Candy", "Charity", "Anastasia", "Cherry", "Kitty",
|
||||||
|
"Jade", "Destiny", "Devon", "Chastity", "Raven", "Scarlett",
|
||||||
|
"Bambi", "Star", "Paris", "Dallas", "Diamond", "Skye",
|
||||||
|
"Trinity", "Tawny", "Layla", "Lexie", "Roxy", "Porsche",
|
||||||
|
"Nevaeh", "Ashlynn", "Aspen", "Chyna", "Lexus", "Unique",
|
||||||
|
"Chardonnay", "Houston", "London", "Coco", "Luscious",
|
||||||
|
"Delight", "Capri", "Trixie", "Cinnamon"].
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
recycle([N | Ns]) ->
|
||||||
|
{N, Ns ++ [N]}.
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
Alexander
|
||||||
|
Anthony
|
||||||
|
Asher
|
||||||
|
Beau
|
||||||
|
Benjamin
|
||||||
|
Bennett
|
||||||
|
Caleb
|
||||||
|
Carter
|
||||||
|
Charles
|
||||||
|
Cooper
|
||||||
|
Daniel
|
||||||
|
David
|
||||||
|
Dylan
|
||||||
|
Elias
|
||||||
|
Elijah
|
||||||
|
Ethan
|
||||||
|
Ezekiel
|
||||||
|
Ezra
|
||||||
|
Gabriel
|
||||||
|
Grayson
|
||||||
|
Henry
|
||||||
|
Hudson
|
||||||
|
Isaac
|
||||||
|
Isaiah
|
||||||
|
Jack
|
||||||
|
Jackson
|
||||||
|
Jacob
|
||||||
|
James
|
||||||
|
John
|
||||||
|
Joseph
|
||||||
|
Josiah
|
||||||
|
Julian
|
||||||
|
Leo
|
||||||
|
Levi
|
||||||
|
Liam
|
||||||
|
Logan
|
||||||
|
Luca
|
||||||
|
Lucas
|
||||||
|
Luke
|
||||||
|
Mason
|
||||||
|
Mateo
|
||||||
|
Matthew
|
||||||
|
Maverick
|
||||||
|
Michael
|
||||||
|
Miles
|
||||||
|
Noah
|
||||||
|
Oliver
|
||||||
|
Owen
|
||||||
|
Roman
|
||||||
|
Rowan
|
||||||
|
Samuel
|
||||||
|
Santiago
|
||||||
|
Sebastian
|
||||||
|
Theodore
|
||||||
|
Thiago
|
||||||
|
Thomas
|
||||||
|
Waylon
|
||||||
|
Wesley
|
||||||
|
Weston
|
||||||
|
William
|
||||||
|
Wyatt
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
liquidate_hos([{HoPid, _HoRef} | Hos]) ->
|
||||||
|
p_logfln("liquidating ~tp", [HoPid]),
|
||||||
|
exit(HoPid, kill),
|
||||||
|
liquidate_hos(Hos);
|
||||||
|
liquidate_hos([]) ->
|
||||||
|
p_logln("it's done").
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user