diff --git a/torrent_client/README.txt b/torrent_client/README.txt index 4ba055e6d..36979df2a 100644 --- a/torrent_client/README.txt +++ b/torrent_client/README.txt @@ -6,16 +6,17 @@ This directory holds a simple torrent client in Erlang. In building this, the major challenge is to keep the project under 500 lines, since we're building it almost from first principles. Right -now it is ~750 lines (of which ~150 are blank or comments); I'll +now it is ~690 lines (of which ~140 are blank or comments); I'll rework the code and the requirements to fit. The easiest way to get Erlang, is to download it from www.erlang-solutions.org. Don't use the Erlang distributed with Ubuntu. compile: + ./rebar get-deps ./rebar compile run: - erl -pa ebin + erl -pa ebin -pa deps/gproc/ebin 1> torrent_file:download("../path/to.torrent") diff --git a/torrent_client/rebar.config b/torrent_client/rebar.config new file mode 100644 index 000000000..e6e9bbd74 --- /dev/null +++ b/torrent_client/rebar.config @@ -0,0 +1,6 @@ + + +{deps, [ +% {nat_upnp, ".*", {git, "git://github.com/benoitc/nat_upnp", {branch, "master"}}}, + {gproc, ".*", {git, "git://github.com/uwiger/gproc", {branch, "master"}}} +]}. diff --git a/torrent_client/src/torrent_client.erl b/torrent_client/src/torrent_client.erl index 317c3e066..6ac309484 100644 --- a/torrent_client/src/torrent_client.erl +++ b/torrent_client/src/torrent_client.erl @@ -14,14 +14,14 @@ start() -> application:start(torrent_client). start_link() -> - ok = application:ensure_started(inets), - ok = application:ensure_started(crypto), + ok = application:ensure_started(inets), + ok = application:ensure_started(crypto), + ok = application:ensure_started(gproc), proc_lib:start_link(?MODULE, init, [self()]). init(Caller) -> erlang:register(torrent_client, self()), - ets:new(torrent_owners, [public,named_table]), ets:new(torrent_stats, [public,named_table]), Rand = crypto:rand_bytes(12), diff --git a/torrent_client/src/torrent_file.erl b/torrent_client/src/torrent_file.erl index df2b2a687..3ba6cf7be 100644 --- a/torrent_client/src/torrent_file.erl +++ b/torrent_client/src/torrent_file.erl @@ -5,7 +5,7 @@ -behavior(gen_server). -export([init/1,terminate/2,handle_call/3,handle_cast/2,handle_info/2]). --export([download/1,downloaded/2,find/1,piece_offset/2,piece_sha/2,piece_length/2]). +-export([download/1,downloaded/2,piece_offset/2,piece_sha/2,piece_length/2]). -export([verify_piece/3]). -record(state, { info :: #info{}, @@ -21,26 +21,20 @@ download(TorrentFile) -> ok = application:ensure_started(torrent_client), Info = read_torrent_file(TorrentFile), - case torrent_file:find(Info#info.info_hash) of - {ok, PID} -> + case gproc:lookup_pids({n,l,Info#info.info_hash}) of + [PID] -> {ok, PID}; - false -> + [] -> gen_server:start_link(?MODULE, [Info], []) end. -find(InfoHash) -> - case ets:lookup(torrent_owners, InfoHash) of - [{InfoHash,PID}] -> {ok, PID}; - [] -> false - end. - downloaded(PID, Index) -> gen_server:cast(PID, {downloaded, Index}). init([Info]) -> % erlang:process_flag(trap_exit, true), + gproc:add_local_name(Info#info.info_hash), Blocks = ets:new(torrent_blocks, [public,ordered_set]), - true = ets:insert(torrent_owners, {Info#info.info_hash, self()}), true = ets:insert(torrent_stats, {Info#info.info_hash, 0, 0}), {ok, State=#state{ missing=Missing }} = init_download_file(#state{ info=Info, blocks=Blocks }), case Missing of @@ -49,7 +43,6 @@ init([Info]) -> end. terminate(_Reason, #state{ info=Info }) -> - ets:delete(torrent_owners, Info#info.info_hash), ok. handle_call(_Call,_,State) -> {stop, {error, unexpected_call, _Call}, State}.