anchor.diff:  chomp(Str) ->
       string:strip(string:strip(Str, both, $\n), both, $\r).
   
  -% User format: {nick, username, fullname, hostname, usermask, sendpid, channels}
  -
   server(Sock) ->
  -    register_user(Sock),
  +    put(lines, []),
       rec_loop(Sock).
   
   check_nick(Nick) ->
  
positive.code: % Define the Mnesia record
  -record(osp_table, {key, val}).
  
  %% @doc Returns the IP protocol for the servlet
  proto() ->    
      tcp.
  
negative.code: 	    false
      end.
  
  get_line(Sock) ->
      case get(lines) of
  	[] ->
  	    Line = erlang:binary_to_list(recv(Sock, 0)),
  	    [Ret | Rest] = string:tokens(Line, "\r\n"),
  	    put(lines, Rest),
  	    Ret;
  	[Ret | Rest] ->
  	    put(lines, Rest),
  	    Ret
      end.
  
  % User format: {nick, username, fullname, hostname, usermask, sendpid, channels}
  
  rec_loop(Sock) ->
      {ok, Hostname} = inet:gethostname(),
      Line = get_line(Sock),
      [Cmd | Args] = string:tokens(Line, " "),
      UCmd = string:to_lower(Cmd),
      case UCmd of
  	"nick" ->
  	    [Nick1] = Args,
  	    Nick = chomp(Nick1),
  	    case check_nick(Nick) of
  		true ->
  		    case lists:keyfind(erlang:list_to_atom(Nick), 1, retrieve(users)) of
  			false ->
  			    case get(uinfo) of
  				{_ONick, undefined, undefined, undefined, undefined, undefined, []} ->
  				    put(uinfo, {Nick, undefined, undefined, undefined, undefined, undefined, []});
  				undefined ->
  				    put(uinfo, {Nick, undefined, undefined, undefined, undefined, undefined, []});
  				{undefined, Username, Fullname, Host, Usermask, undefined, []} ->
  				    put(nick, Nick),
  				    new_user({Nick, Username, Fullname, Host, Usermask, undefined, []}, Sock)
  			    end;
  			_ ->
  			    send(Sock, ":" ++ Hostname ++ " 433 * " ++ Nick ++ " :Nickname name already in use\r\n")
  		    end;
  		false ->
  		    send(Sock, ":" ++ Hostname ++ " 432 " ++ Nick ++ " :Invalid Nickname\r\n")
  	    end;
  	"user" ->
  	    [Login, Mask, _ | RealName] = Args,
  	    {tcp, S} = Sock,
  	    {ok, {Address, _}} = inet:peername(S),
  	    {ok, Hostent} = inet:gethostbyaddr(Address),
  	    case Hostent#hostent.h_name of
  		HN when is_atom(HN) ->
  		    RHost = erlang:atom_to_list(HN);
  		HN2 ->
  		    RHost = HN2
  	    end,
  	    Fullname = string:strip(string:join(RealName, " "), left, $:),
  	    case get(uinfo) of
  		{undefined, _OUsername, _OFullname, _OHost, _OUsermask, undefined, []} ->
  		    put(uinfo, {undefined, Login, Fullname, RHost, Mask, undefined, []});
  		undefined ->
  		    put(uinfo, {undefined, Login, Fullname, RHost, Mask, undefined, []});
  		{Nick, undefined, undefined, undefined, undefined, undefined, []} ->
  		    put(nick, Nick),
  		    new_user({Nick, Login, Fullname, RHost, Mask, undefined, []}, Sock)
  	    end;
  	"join" ->
  	    {N, L, F, H, M, Pid, UChans} = retrieve(erlang:list_to_atom("user_" ++ get(nick))),
  	    case Args of
  		[Chans, Keys] ->
  		    Chanlist = string:tokens(Chans, ","),
  		    Keylist = string:tokens(Keys, ",");
  		[Chans] ->
  		    Chanlist = string:tokens(Chans, ","),
  		    Keylist = []
  	    end,
  	    Func = fun(Chan) -> %% @todo Check for channel key
  			send(N, Chan, channel, "JOIN :" ++ Chan ++ "\r\n"),
  			case retrieve(erlang:list_to_atom("channel_" ++ Chan)) of
  			    undefined ->
  				store(channels, retrieve(channels) ++ [Chan]),
  				store(erlang:list_to_atom("channel_" ++ Chan), {[{"n"}, {"t"}], [{Pid}]});
  			    {Modes, Pids} ->
  				store(erlang:list_to_atom("channel_" ++ Chan), {Modes, Pids ++ [{Pid}]})
  			end
  		end,
  	    lists:foreach(Func, Chanlist),
  	    store(erlang:list_to_atom("user_" ++ get(nick)), {N, L, F, H, M, Pid, UChans ++ Chanlist});
  	"quit" ->
  	    case Args of
  		[] ->
  		    Msg = " :Quit\r\n";
  		_ ->
  		    Msg = string:join(Args, " ")
  	    end,
  	    case get(nick) of
  		undefined ->
  		    ok;
  		_ ->
  		    store(users, lists:keydelete(erlang:list_to_atom(get(nick)), 1, retrieve(users))),
  		    {Nick, _Login, _Fullname, _Hostname, _UMask, Pid, Channels} = retrieve(erlang:list_to_atom("user_" ++ get(nick))),
  		    F = fun(Channel) ->
  				{Modes, Pids} = retrieve(erlang:list_to_atom("channel_" ++ Channel)),
  				store(erlang:list_to_atom("channel_" ++ Channel), {Modes, lists:keydelete(Pid, 1, Pids)}),
  				send(Nick, Channel, channel, "QUIT " ++ Msg)
  			end,
  		    lists:foreach(F, Channels),
  		    store(erlang:list_to_atom("user_" ++ Nick), []),
  		    Pid ! {quit}
  	    end,
  	    put(uinfo, undefined),
  	    exit(quit);
  	"privmsg" ->
  	    Nick = get(nick),
  	    if
  		Nick =:= undefined ->
  		    send(Sock, ":" ++ Hostname ++ " 451 PRIVMSG :Not registered\r\n");
  		true ->
  		    [Tar | MsgL] = Args,
  		    Msg = string:join(MsgL, " "),
  		    case Tar of
  			[$# | _] ->
  			    send(get(nick), Tar, channel, "PRIVMSG " ++ Msg ++ "\r\n");
  			_ ->
  			    send(get(nick), Tar, user, "PRIVMSG " ++ Msg ++ "\r\n")
  		    end
  	    end;
  	Other ->
  	    Nick = get(nick),
  	    if 
  		Nick =:= undefined ->
  		    send(Sock, ":" ++ Hostname ++ " 451 PRIVMSG :Not registered\r\n");
  		true ->
  		    send(Sock, ":" ++ Hostname ++ " 421 " ++ string:to_upper(Other) ++ " :Unknown command\r\n")
  	    end
      end,
      rec_loop(Sock).
  
  new_user({Nick, Username, Fullname, Hostname, Usermask, undefined, []}, Sock) ->
      {ok, SHostname} = inet:gethostname(),
      store(users, retrieve(users) ++ [{erlang:list_to_atom(Nick)}]),
      Pid = spawn_link(fun() -> send_loop(Sock) end),
      send(Sock, ":" ++ SHostname ++ " 001 " ++ Nick ++ " :Welcome to the " ++ ?NETWORK ++ " " ++ Nick ++ "!" ++ Username ++ "@" ++ Hostname ++ "\r\n"),
      send(Sock, ":" ++ SHostname ++ " 002 " ++ Nick ++ " :Your host is " ++ SHostname ++ ", running ospIRCD version 0.1!\r\n"),
      send(Sock, ":" ++ SHostname ++ " 003 " ++ Nick ++ " :This server created Dec. 27, 2009\r\n"),
      store(erlang:list_to_atom("user_" ++ Nick), {Nick, Username, Fullname, Hostname, Usermask, Pid, []}).
  
  
  send(From, To, channel, Msg) when is_pid(From) ->
      CInfo = retrieve(erlang:list_to_atom("channel_" ++ To)),
      case CInfo of 
  	undefined ->
  	    ok;
  	{_Modes, Pids} ->
  	    F = fun({Pid}) ->
  			if
  			    Pid == From ->
  				ok;
  			    true ->
  				Pid ! {msg, Msg}
  			end
  		end,
  	    lists:foreach(F, Pids)
      end;
  send(From, To, user, Msg) when is_pid(From) ->
      UInfo = retrieve(erlang:list_to_atom("user_" ++ To)),
      case UInfo of
  	undefined ->
  	    ok;
  	{_Nick, _Login, _Fullname, _Hostname, _UMask, Pid, _Channels} ->   
  	    Pid ! {msg, Msg}
      end;
  send(From, To, Type, Msg) ->
      {Nick, Login, _Fullname, Hostname, _UMask, Pid, _Channels} = retrieve(erlang:list_to_atom("user_" ++ From)),
      send(Pid, To, Type, ":" ++ Nick ++ "!" ++ Login ++ "@" ++ Hostname ++ " " ++ Msg).
  
  %% @doc Provides a loop to send data to the client
  send_loop(Sock) ->
  