Bug fix for irc.floofy-skirts.org: don't JOIN channels until we know we're connected.
authorMatt Mullins <mmullins@mmlx.us>
Sun, 22 May 2011 05:11:54 +0000 (00:11 -0500)
committerMatt Mullins <mmullins@mmlx.us>
Sun, 22 May 2011 05:11:54 +0000 (00:11 -0500)
irc/irc_conn.erl

index 7e64770..8a062c6 100644 (file)
@@ -19,6 +19,7 @@
 
 -record(irc_state, {instance,      % instance name
                     config,        % initial configuration params
+                    joined = false,% indicates whether we have joined the channels
                     socket,
                     buffer = ""    % for the TCP session
                    }).
@@ -27,14 +28,13 @@ start_link(Instance, Config) ->
     gen_server:start_link(?MODULE,
         {Instance, Config}, []).
 
-init({Instance, Config = {Host, Port, Nick, Realname, Channels}}) ->
+init({Instance, Config = {Host, Port, Nick, Realname, _Channels}}) ->
     {ok, Socket} = gen_tcp:connect(Host, Port, [list]),
     send_command(#irc_command{command = "NICK", middles = [Nick]}),
     send_command(#irc_command{command = "USER",
                               middles = ["user", "host", "server"],
                               trailing = Realname
                              }),
-    lists:foreach(fun join_channel/1, Channels),
     State = #irc_state{instance = Instance,
                        config = Config,
                        socket = Socket
@@ -53,17 +53,17 @@ handle_cast({send_command, Command}, State) ->
 %% Handle incoming data
 handle_info({tcp, _Socket, Data}, State = #irc_state{ socket = _Socket }) ->
     Buf1 = State#irc_state.buffer ++ Data,
-    Buf2 = case parse_lines(Buf1) of
+    NewState = case parse_lines(Buf1) of
         {ok, Lines, Rem} ->
-            lists:foreach(fun do_line/1, Lines),
-            Rem;
+            State1 = lists:foldl(fun do_line/2, State, Lines),
+            State1#irc_state{buffer = Rem};
         none ->
-            Buf1
+            State#irc_state{buffer = Buf1}
         end,
-    {noreply, State#irc_state{buffer = Buf2}}.
+    {noreply, NewState}.
 
 %% @doc Handles a line received from the IRC server.
-do_line(Line) ->
+do_line(Line, State) ->
     Command = irc_util:list_to_command(Line),
     case Command#irc_command.command of
         "PING" ->
@@ -71,10 +71,18 @@ do_line(Line) ->
             % return the command to the IRC server with a PONG
             % leaving the rest of the line (usually a timestamp) alone
             NewCommand = Command#irc_command{prefix = none, command = "PONG"},
-            send_command(NewCommand);
+            send_command(NewCommand),
+            State;
+        "376" when State#irc_state.joined == false -> 
+            % end of MOTD, which should normally be sent on connect
+            error_logger:info_msg("Joining my channels now.", []),
+            {_, _, _, _, Channels} = State#irc_state.config,
+            lists:foreach(fun join_channel/1, Channels),
+            State#irc_state{joined = true};
         _ ->
             % for now, just know that it happened
-            error_logger:info_msg("Received a line ~p~n", [Line])
+            error_logger:info_msg("Received a line ~p~n", [Line]),
+            State
     end.
 
 terminate(_Reason, _State) ->