Example #1
0
Cvirtual_binary Cbt_tracker_accounts::dump() const
{
	int cb_d = 4;
	for (const_iterator i = begin(); i != end(); i++)
		cb_d += i->pre_dump();
	Cvirtual_binary d;
	Cstream_writer w(d.write_start(cb_d));
	w.write_int(4, size());
	for (const_iterator i = begin(); i != end(); i++)
		i->dump(w);
	assert(w.w() == d.end());
	return d;

}
Example #2
0
void Cdlg_make_torrent::OnSave()
{
	if (!UpdateData())
		return;
	m_name.TrimRight(" ");
	m_tracker.TrimRight(" ");
	CFileDialog dlg(false, "torrent", m_name + ".torrent", OFN_ENABLESIZING | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST, "Torrents|*.torrent|", this);
	if (IDOK != dlg.DoModal())
		return;
	CWaitCursor wc;
	AfxGetApp()->WriteProfileString(m_strRegStore, "tracker", m_tracker);
	AfxGetApp()->WriteProfileString(m_strRegStore, "trackers", m_trackers);
	AfxGetApp()->WriteProfileInt(m_strRegStore, "use_merkle", m_use_merkle);
	int cb_piece = 1 << 20;
	if (!m_use_merkle)
	{
		long long cb_total = 0;
		for (t_map::const_iterator i = m_map.begin(); i != m_map.end(); i++)
			cb_total += i->second.size;
		cb_piece = 256 << 10;
		while (cb_total / cb_piece > 4 << 10)
			cb_piece <<= 1;
	}
	typedef std::set<std::string> t_set;
	t_set set;
	for (t_map::const_iterator i = m_map.begin(); i != m_map.end(); i++)
		set.insert(i->second.name);
	Cbvalue files;
	std::string pieces;
	Cvirtual_binary d;
	byte* w = d.write_start(cb_piece);
	for (t_set::const_iterator i = set.begin(); i != set.end(); i++)
	{
		int f = open(i->c_str(), _O_BINARY | _O_RDONLY);
		if (!f)
			continue;
		long long cb_f = 0;
		std::string merkle_hash;
		int cb_d;
		if (m_use_merkle)
		{
			typedef std::map<int, std::string> t_map;

			t_map map;
			char d[1025];
			while (cb_d = read(f, d + 1, 1024))
			{
				if (cb_d < 0)
					break;
				*d = 0;
				std::string h = Csha1(const_memory_range(d, cb_d + 1)).read();
				*d = 1;
				int i;
				for (i = 0; map.find(i) != map.end(); i++)
				{
					memcpy(d + 1, map.find(i)->second.c_str(), 20);
					memcpy(d + 21, h.c_str(), 20);
					h = Csha1(const_memory_range(d, 41)).read();
					map.erase(i);
				}
				map[i] = h;
				cb_f += cb_d;
			}
			*d = 1;
			while (map.size() > 1)
			{
				memcpy(d + 21, map.begin()->second.c_str(), 20);
				map.erase(map.begin());
				memcpy(d + 1, map.begin()->second.c_str(), 20);
				map.erase(map.begin());
				map[0] = Csha1(const_memory_range(d, 41)).read();
			}
			if (!map.empty())
				merkle_hash = map.begin()->second;
		}
		else
		{
			while (cb_d = read(f, w, d.end() - w))
			{
				if (cb_d < 0)
					break;
				w += cb_d;
				if (w == d.end())
				{
					pieces += Csha1(const_memory_range(d, w - d)).read();
					w = d.data_edit();
				}
				cb_f += cb_d;
			}
		}
		close(f);
		files.l(merkle_hash.empty()
			? Cbvalue().d(bts_length, cb_f).d(bts_path, Cbvalue().l(base_name(*i)))
			: Cbvalue().d(bts_merkle_hash, merkle_hash).d(bts_length, cb_f).d(bts_path, Cbvalue().l(base_name(*i))));
	}
	if (w != d)
		pieces += Csha1(const_memory_range(d, w - d)).read();
	Cbvalue info;
	info.d(bts_piece_length, cb_piece);
	if (!pieces.empty())
		info.d(bts_pieces, pieces);
	if (m_map.size() == 1)
	{
		if (m_use_merkle)
			info.d(bts_merkle_hash, files.l().front()[bts_merkle_hash]);
		info.d(bts_length, files.l().front()[bts_length]);
		info.d(bts_name, files.l().front()[bts_path].l().front());
	}
	else
	{
		info.d(bts_files, files);
		info.d(bts_name, static_cast<std::string>(m_name));
	}
	Cbvalue torrent;
	torrent.d(bts_announce, static_cast<std::string>(m_tracker));
	if (!m_trackers.IsEmpty())
		torrent.d(bts_announce_list, parse_trackers(static_cast<std::string>(m_trackers)));
	torrent.d(bts_info, info);
	Cvirtual_binary s = torrent.read();
	if (m_use_merkle)
		s = gzip(s);
	s.save(static_cast<std::string>(dlg.GetPathName()));
	m_torrent_fname = dlg.GetPathName();
	EndDialog(IDOK);
}
Example #3
0
bool Cbt_hasher::run(Cbt_file& f)
{
	if (m_i >= f.m_pieces.size())
		return false;
	if (!m_i)
		m_sub_file = f.m_sub_files.begin();
	Cbt_piece& piece = f.m_pieces[m_i];
	Cvirtual_binary d;
	if (m_validate)
	{
		if (f.m_merkle)
		{
			bool root_valid = m_sub_file->merkle_tree().root().string() == m_sub_file->merkle_hash();
			d.write_start(piece.size());
			piece.valid(!f.read_data(f.mcb_piece * m_i, d));
			for (const byte* r = d; r < d.end(); r += 0x8000)
			{
				std::string h = Cmerkle_tree::compute_root(const_memory_range(r, std::min(r + 0x8000, d.end())));
				if (root_valid)
				{
					if (piece.valid() && (!m_sub_file->merkle_tree().has(m_j) || h != m_sub_file->merkle_tree().get(m_j).string()))
						piece.valid(false);
				}
				else
					m_sub_file->merkle_tree().set(m_j, h);
				m_j++;
			}
		}
		else
		{
			d.write_start(piece.size());
			piece.valid(!f.read_data(f.mcb_piece * m_i, d)
				&& !memcmp(Csha1(d).read().data(), piece.m_hash, 20));
		}
	}
	if (!piece.valid())
		f.m_left += piece.size();
	int cb0 = piece.size();
	while (cb0)
	{
		int cb1 = min(cb0, m_sub_file->size() - m_offset);
		if (!piece.valid())
			m_sub_file->left(m_sub_file->left() + cb1);
		cb0 -= cb1;
		m_offset += cb1;
		if (m_offset == m_sub_file->size())
		{
			if (f.m_merkle && m_sub_file->merkle_tree().root().string() != m_sub_file->merkle_hash())
			{
				Cbt_piece* piece = &f.m_pieces.front() + m_sub_file->offset() / f.mcb_piece;
				for (int i = 0; i < m_sub_file->c_pieces(f.mcb_piece); i++)
				{
					if (piece->valid())
						f.m_left += piece->size();
					piece->valid(false);
					piece++;
				}
				m_sub_file->left(m_sub_file->size());
				m_sub_file->merkle_tree().invalidate();
				m_sub_file->merkle_tree().root(m_sub_file->merkle_hash());
			}
			if (!m_sub_file->left())
			{
				m_sub_file->close();
				m_sub_file->open(f.m_name, O_RDONLY);
			}
			m_j = 0;
			m_offset = 0;
			m_sub_file++;
		}
	}
	m_i++;
	return true;
}