Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 30840d3a43
Fetching contributors…

Cannot retrieve contributors at this time

file 62 lines (56 sloc) 2.019 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
-module(server).
-include("command.hrl").
-export([start/1,
stop/1]).

-record(state,{bindings = [] :: [{string(),string()}]
}).

-spec(start([{atom(),string() | integer()}]) -> ok).
start(Options) ->
    FilesDir = proplists:get_value(files,Options),
    CommandPort = proplists:get_value(command_port,Options),
    Ref = make_ref(),
    Synchronizer = {self(),Ref},
    Pid = spawn_link(fun() -> start(Synchronizer,FilesDir,CommandPort) end),
    receive
{started,Pid,Ref} -> ok
    end.

-spec(stop(non_neg_integer()) -> ok).
stop(CommandPort) ->
    {ok,Sock} = gen_tcp:connect("localhost",CommandPort,[{active,false}]),
    gen_tcp:send(Sock,"stop"),
    {ok,"stopping"} = gen_tcp:recv(Sock,0),
    ok.

start({To,Ref},FilesDir,CommandPort) ->
    {ok,Sock} = gen_tcp:listen(CommandPort,[{active,false},{reuseaddr,true}]),
    register(server,self()),
    To ! {started,self(),Ref},
    loop(FilesDir,Sock,#state{}).

loop(_FilesDir,Sock,ServerState) ->
    {ok,Session} = gen_tcp:accept(Sock),
    case gen_tcp:recv(Session,0) of
{error,closed} ->
gen_tcp:close(Session),
loop(_FilesDir,Sock,ServerState);
{ok,"stop"} ->
gen_tcp:send(Session,"stopping"),
gen_tcp:close(Session),
gen_tcp:close(Sock);
{ok,Command} ->
Res = command:parse(Command),
{Reply,NewServerState} = perform_command(Res,ServerState),
gen_tcp:send(Session,Reply),
loop(_FilesDir,Sock,NewServerState)
    end.

perform_command(#binding{type = list},#state{bindings = []} = State) ->
    {"bindings: none",State};
perform_command(#binding{type = list},#state{bindings = Bindings} = State) ->
    {lists:foldl(
       fun({Type,File},Res) -> Res++"\n "++Type++", "++File
       end,
       "bindings:",
       Bindings),State};
perform_command(#binding{type = bind,arguments = Args},State) ->
    Type = proplists:get_value(type,Args),
    File = proplists:get_value(file,Args),
    Bindings = State#state.bindings,
    {"binding created",State#state{bindings = [{Type,File}|Bindings]}}.
Something went wrong with that request. Please try again.