|
|
@ -57,6 +57,7 @@ static map<std::string, bool> m_specialResources; |
|
|
|
enum ExpireResType { SimpleNoExpire, NumberedNoExpire, PostNoExpireRecent }; |
|
|
|
enum ExpireResType { SimpleNoExpire, NumberedNoExpire, PostNoExpireRecent }; |
|
|
|
static map<std::string, ExpireResType> m_noExpireResources; |
|
|
|
static map<std::string, ExpireResType> m_noExpireResources; |
|
|
|
static map<std::string, torrent_handle> m_userTorrent; |
|
|
|
static map<std::string, torrent_handle> m_userTorrent; |
|
|
|
|
|
|
|
static map<std::string, torrent_handle> m_peekTorrent; |
|
|
|
static boost::scoped_ptr<CLevelDB> m_swarmDb; |
|
|
|
static boost::scoped_ptr<CLevelDB> m_swarmDb; |
|
|
|
static int m_threadsToJoin; |
|
|
|
static int m_threadsToJoin; |
|
|
|
|
|
|
|
|
|
|
@ -147,6 +148,14 @@ torrent_handle startTorrentUser(std::string const &username, bool following, int |
|
|
|
torrent_handle h; |
|
|
|
torrent_handle h; |
|
|
|
|
|
|
|
|
|
|
|
LOCK(cs_twister); |
|
|
|
LOCK(cs_twister); |
|
|
|
|
|
|
|
if( m_peekTorrent.count(username) ) { |
|
|
|
|
|
|
|
/* multiple paralel peek piece operations per torrent not
|
|
|
|
|
|
|
|
* currently supported. return invalid handle for subsequent |
|
|
|
|
|
|
|
* requests, until current operation completes and torrent |
|
|
|
|
|
|
|
* is freed. */ |
|
|
|
|
|
|
|
return torrent_handle(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if( !m_userTorrent.count(username) || peek_single_piece >= 0 ) { |
|
|
|
if( !m_userTorrent.count(username) || peek_single_piece >= 0 ) { |
|
|
|
sha1_hash ih = dhtTargetHash(username, "tracker", "m"); |
|
|
|
sha1_hash ih = dhtTargetHash(username, "tracker", "m"); |
|
|
|
|
|
|
|
|
|
|
@ -166,8 +175,10 @@ torrent_handle startTorrentUser(std::string const &username, bool following, int |
|
|
|
load_file(filename.c_str(), tparams.resume_data); |
|
|
|
load_file(filename.c_str(), tparams.resume_data); |
|
|
|
|
|
|
|
|
|
|
|
h = ses->add_torrent(tparams); |
|
|
|
h = ses->add_torrent(tparams); |
|
|
|
if( peek_single_piece == -1 ) { |
|
|
|
if( peek_single_piece < 0 ) { |
|
|
|
m_userTorrent[username] = h; |
|
|
|
m_userTorrent[username] = h; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
m_peekTorrent[username] = h; |
|
|
|
} |
|
|
|
} |
|
|
|
if( !following ) { |
|
|
|
if( !following ) { |
|
|
|
h.auto_managed(true); |
|
|
|
h.auto_managed(true); |
|
|
@ -898,19 +909,26 @@ void ThreadSessionAlerts() |
|
|
|
|
|
|
|
|
|
|
|
save_resume_data_alert const* rda = alert_cast<save_resume_data_alert>(*i); |
|
|
|
save_resume_data_alert const* rda = alert_cast<save_resume_data_alert>(*i); |
|
|
|
if (rda) { |
|
|
|
if (rda) { |
|
|
|
num_outstanding_resume_data--; |
|
|
|
if (rda->resume_data) { |
|
|
|
if (!rda->resume_data) continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
torrent_handle h = rda->handle; |
|
|
|
torrent_handle h = rda->handle; |
|
|
|
torrent_status st = h.status(torrent_handle::query_save_path); |
|
|
|
torrent_status st = h.status(torrent_handle::query_save_path); |
|
|
|
std::vector<char> out; |
|
|
|
std::vector<char> out; |
|
|
|
bencode(std::back_inserter(out), *rda->resume_data); |
|
|
|
bencode(std::back_inserter(out), *rda->resume_data); |
|
|
|
save_file(combine_path(st.save_path, to_hex(st.info_hash.to_string()) + ".resume"), out); |
|
|
|
save_file(combine_path(st.save_path, to_hex(st.info_hash.to_string()) + ".resume"), out); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (alert_cast<save_resume_data_failed_alert>(*i)) |
|
|
|
save_resume_data_failed_alert const *rdfa = alert_cast<save_resume_data_failed_alert>(*i); |
|
|
|
|
|
|
|
if (rda || rdfa) |
|
|
|
{ |
|
|
|
{ |
|
|
|
--num_outstanding_resume_data; |
|
|
|
torrent_handle h = (rda) ? rda->handle : rdfa->handle; |
|
|
|
|
|
|
|
torrent_status st = h.status(); |
|
|
|
|
|
|
|
LOCK(cs_twister); |
|
|
|
|
|
|
|
num_outstanding_resume_data--; |
|
|
|
|
|
|
|
if(m_peekTorrent.count(st.name) && st.paused) { |
|
|
|
|
|
|
|
m_peekTorrent.erase(st.name); |
|
|
|
|
|
|
|
ses->remove_torrent(h); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
external_ip_alert const* ei = alert_cast<external_ip_alert>(*i); |
|
|
|
external_ip_alert const* ei = alert_cast<external_ip_alert>(*i); |
|
|
@ -2350,7 +2368,9 @@ Value newdirectmsg(const Array& params, bool fHelp) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
torrent_handle h = startTorrentUser(strFrom, true); |
|
|
|
torrent_handle h = startTorrentUser(strFrom, true); |
|
|
|
|
|
|
|
if( h.is_valid() ) { |
|
|
|
h.add_piece(k++,buf.data(),buf.size()); |
|
|
|
h.add_piece(k++,buf.data(),buf.size()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
hexcapePost(v); |
|
|
|
hexcapePost(v); |
|
|
|
ret = entryToJson(v); |
|
|
|
ret = entryToJson(v); |
|
|
@ -3861,8 +3881,10 @@ static void signAndAddDM(const std::string &strFrom, int k, const entry *dm) |
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMS,errmsg); |
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMS,errmsg); |
|
|
|
|
|
|
|
|
|
|
|
torrent_handle h = startTorrentUser(strFrom, true); |
|
|
|
torrent_handle h = startTorrentUser(strFrom, true); |
|
|
|
|
|
|
|
if( h.is_valid() ) { |
|
|
|
h.add_piece(k++,buf.data(),buf.size()); |
|
|
|
h.add_piece(k++,buf.data(),buf.size()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Value newgroupinvite(const Array& params, bool fHelp) |
|
|
|
Value newgroupinvite(const Array& params, bool fHelp) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -4102,7 +4124,7 @@ Value peekpost(const Array& params, bool fHelp) |
|
|
|
h = startTorrentUser(strUsername,true,k); |
|
|
|
h = startTorrentUser(strUsername,true,k); |
|
|
|
|
|
|
|
|
|
|
|
// this loop receives alerts from both dht network and torrent peek extension
|
|
|
|
// this loop receives alerts from both dht network and torrent peek extension
|
|
|
|
while( am.wait_for_alert(timeToWait) ) { |
|
|
|
while( h.is_valid() && am.wait_for_alert(timeToWait) ) { |
|
|
|
std::auto_ptr<alert> a(am.get()); |
|
|
|
std::auto_ptr<alert> a(am.get()); |
|
|
|
|
|
|
|
|
|
|
|
dht_reply_data_alert const* rd = alert_cast<dht_reply_data_alert>(&(*a)); |
|
|
|
dht_reply_data_alert const* rd = alert_cast<dht_reply_data_alert>(&(*a)); |
|
|
@ -4126,8 +4148,12 @@ Value peekpost(const Array& params, bool fHelp) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if( h.is_valid() ) |
|
|
|
if( h.is_valid() ) { |
|
|
|
ses->remove_torrent(h); |
|
|
|
LOCK(cs_twister); |
|
|
|
|
|
|
|
h.pause(); |
|
|
|
|
|
|
|
h.save_resume_data(); |
|
|
|
|
|
|
|
num_outstanding_resume_data++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if( !DhtProxy::fEnabled ) { |
|
|
|
if( !DhtProxy::fEnabled ) { |
|
|
|
dhtgetMapRemove(ih,&am); |
|
|
|
dhtgetMapRemove(ih,&am); |
|
|
@ -4152,7 +4178,11 @@ Value peekpost(const Array& params, bool fHelp) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
if(h.is_valid()) { |
|
|
|
throw JSONRPCError(RPC_TIMEOUT, "timeout or post not found"); |
|
|
|
throw JSONRPCError(RPC_TIMEOUT, "timeout or post not found"); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
throw JSONRPCError(RPC_RESOURCE_BUSY_TRY_AGAIN, "resource busy, try again"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|