forked from premiere/premiere-libtorrent
move create_torrent documentation into headers. deprecate API touching internal_file_entry
This commit is contained in:
parent
49aba26f5c
commit
85bb6a1839
|
@ -53,8 +53,8 @@ extensions
|
||||||
ratio rather than downloading the torrent.
|
ratio rather than downloading the torrent.
|
||||||
|
|
||||||
.. _article: utp.html
|
.. _article: utp.html
|
||||||
.. _extensions: manual.html#extensions
|
.. _extensions: manual-ref.html#extensions
|
||||||
.. _`http seeding`: manual.html#http-seeding
|
.. _`http seeding`: manual-ref.html#http-seeding
|
||||||
|
|
||||||
disk management
|
disk management
|
||||||
---------------
|
---------------
|
||||||
|
@ -72,7 +72,7 @@ disk management
|
||||||
* seed mode, where the files on disk are assumed to be complete, and each
|
* seed mode, where the files on disk are assumed to be complete, and each
|
||||||
piece's hash is verified the first time it is requested.
|
piece's hash is verified the first time it is requested.
|
||||||
|
|
||||||
.. _threads: manual.html#threads
|
.. _threads: manualref.html#threads
|
||||||
|
|
||||||
network
|
network
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -36,14 +36,15 @@ preprocess_rst = \
|
||||||
# some pre-defined sections from the main manual
|
# some pre-defined sections from the main manual
|
||||||
symbols = \
|
symbols = \
|
||||||
{
|
{
|
||||||
"queuing_": "manual.html#queuing",
|
"queuing_": "manual-ref.html#queuing",
|
||||||
"fast-resume_": "manual.html#fast-resume",
|
"fast-resume_": "manual-ref.html#fast-resume",
|
||||||
"storage-allocation_": "manual.html#storage-allocation",
|
"storage-allocation_": "manual-ref.html#storage-allocation",
|
||||||
"alerts_": "manual.html#alerts",
|
"alerts_": "manual-ref.html#alerts",
|
||||||
"upnp-and-nat-pmp_": "manual.html#upnp-and-nat-pmp",
|
"upnp-and-nat-pmp_": "manual-ref.html#upnp-and-nat-pmp",
|
||||||
"http-seeding_": "manual.html#http-seeding",
|
"http-seeding_": "manual-ref.html#http-seeding",
|
||||||
"metadata-from-peers_": "manual.html#metadata-from-peers",
|
"metadata-from-peers_": "manual-ref.html#metadata-from-peers",
|
||||||
"magnet-links_": "manual.html#magnet-links",
|
"magnet-links_": "manual-ref.html#magnet-links",
|
||||||
|
"ssl-torrents_": "manual-ref.html#ssl-torrents",
|
||||||
}
|
}
|
||||||
|
|
||||||
static_links = \
|
static_links = \
|
||||||
|
@ -469,7 +470,9 @@ for filename in files:
|
||||||
overviews[filename[11:]] = current_overview
|
overviews[filename[11:]] = current_overview
|
||||||
current_overview = ''
|
current_overview = ''
|
||||||
break
|
break
|
||||||
current_overview += l[2:] + '\n'
|
l = l[2:]
|
||||||
|
if l.startswith(' '): l = l[1:]
|
||||||
|
current_overview += l + '\n'
|
||||||
|
|
||||||
if l.startswith('//'):
|
if l.startswith('//'):
|
||||||
if verbose: print 'desc %s' % l
|
if verbose: print 'desc %s' % l
|
||||||
|
@ -611,6 +614,7 @@ for c in classes:
|
||||||
|
|
||||||
for e in c['enums']:
|
for e in c['enums']:
|
||||||
symbols[e['name']] = filename + e['name']
|
symbols[e['name']] = filename + e['name']
|
||||||
|
symbols[c['name'] + '::' + e['name']] = filename + e['name']
|
||||||
for v in e['values']:
|
for v in e['values']:
|
||||||
# symbols[v['name']] = filename + v['name']
|
# symbols[v['name']] = filename + v['name']
|
||||||
symbols[e['name'] + '::' + v['name']] = filename + v['name']
|
symbols[e['name'] + '::' + v['name']] = filename + v['name']
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
* examples_
|
* examples_
|
||||||
* `library overview`_
|
* `library overview`_
|
||||||
* `reference documentation`_
|
* `reference documentation`_
|
||||||
* `create torrents`_
|
|
||||||
* `running tests`_
|
* `running tests`_
|
||||||
* `tuning`_
|
* `tuning`_
|
||||||
* screenshot_
|
* screenshot_
|
||||||
|
@ -61,7 +60,6 @@ libtorrent
|
||||||
.. _examples: examples.html
|
.. _examples: examples.html
|
||||||
.. _`library overview`: manual-ref.html
|
.. _`library overview`: manual-ref.html
|
||||||
.. _`reference documentation`: reference.html
|
.. _`reference documentation`: reference.html
|
||||||
.. _`create torrents`: make_torrent.html
|
|
||||||
.. _`running tests`: running_tests.html
|
.. _`running tests`: running_tests.html
|
||||||
.. _`tuning`: tuning.html
|
.. _`tuning`: tuning.html
|
||||||
.. _screenshot: client_test.png
|
.. _screenshot: client_test.png
|
||||||
|
|
|
@ -360,7 +360,7 @@ the run-time equivalence.
|
||||||
The ``what()`` virtual function may simply be a string literal of the class name of
|
The ``what()`` virtual function may simply be a string literal of the class name of
|
||||||
your alert.
|
your alert.
|
||||||
|
|
||||||
For more information, see the alert section in the `main manual`_.
|
For more information, see the `alert section`_.
|
||||||
|
|
||||||
.. _`main manual`: manual.html
|
.. _`alert section`: reference-Alerts.html
|
||||||
|
|
||||||
|
|
|
@ -1,609 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
<meta name="generator" content="Docutils 0.11: http://docutils.sourceforge.net/" />
|
|
||||||
<title>creating torrents</title>
|
|
||||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
|
||||||
<script type="text/javascript">
|
|
||||||
/* <![CDATA[ */
|
|
||||||
(function() {
|
|
||||||
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
|
|
||||||
s.type = 'text/javascript';
|
|
||||||
s.async = true;
|
|
||||||
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
|
|
||||||
t.parentNode.insertBefore(s, t);
|
|
||||||
})();
|
|
||||||
/* ]]> */
|
|
||||||
</script>
|
|
||||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
|
||||||
<style type="text/css">
|
|
||||||
/* Hides from IE-mac \*/
|
|
||||||
* html pre { height: 1%; }
|
|
||||||
/* End hide from IE-mac */
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="document" id="creating-torrents">
|
|
||||||
<div id="container">
|
|
||||||
<div id="headerNav">
|
|
||||||
<ul>
|
|
||||||
<li class="first"><a href="/">Home</a></li>
|
|
||||||
<li><a href="../../products.html">Products</a></li>
|
|
||||||
<li><a href="../../contact.html">Contact</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div id="header">
|
|
||||||
<div id="orange"></div>
|
|
||||||
<div id="logo"></div>
|
|
||||||
</div>
|
|
||||||
<div id="main">
|
|
||||||
<h1 class="title">creating torrents</h1>
|
|
||||||
<table class="docinfo" frame="void" rules="none">
|
|
||||||
<col class="docinfo-name" />
|
|
||||||
<col class="docinfo-content" />
|
|
||||||
<tbody valign="top">
|
|
||||||
<tr><th class="docinfo-name">Author:</th>
|
|
||||||
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a></td></tr>
|
|
||||||
<tr><th class="docinfo-name">Version:</th>
|
|
||||||
<td>1.0.0</td></tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div class="contents topic" id="table-of-contents">
|
|
||||||
<p class="topic-title first">Table of contents</p>
|
|
||||||
<ul class="simple">
|
|
||||||
<li><a class="reference internal" href="#overview" id="id2">overview</a></li>
|
|
||||||
<li><a class="reference internal" href="#high-level-example" id="id3">high level example</a></li>
|
|
||||||
<li><a class="reference internal" href="#add-files" id="id4">add_files</a></li>
|
|
||||||
<li><a class="reference internal" href="#set-piece-hashes" id="id5">set_piece_hashes()</a></li>
|
|
||||||
<li><a class="reference internal" href="#file-storage" id="id6">file_storage</a><ul>
|
|
||||||
<li><a class="reference internal" href="#add-file" id="id7">add_file()</a></li>
|
|
||||||
<li><a class="reference internal" href="#hash-symlink-mtime-file-path-file-size-pad-file-at" id="id8">hash() symlink() mtime() file_path() file_size() pad_file_at()</a></li>
|
|
||||||
<li><a class="reference internal" href="#file-base-set-file-base" id="id9">file_base() set_file_base()</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><a class="reference internal" href="#create-torrent" id="id10">create_torrent</a><ul>
|
|
||||||
<li><a class="reference internal" href="#id1" id="id11">create_torrent()</a></li>
|
|
||||||
<li><a class="reference internal" href="#generate" id="id12">generate()</a></li>
|
|
||||||
<li><a class="reference internal" href="#set-comment" id="id13">set_comment()</a></li>
|
|
||||||
<li><a class="reference internal" href="#set-creator" id="id14">set_creator()</a></li>
|
|
||||||
<li><a class="reference internal" href="#set-hash" id="id15">set_hash()</a></li>
|
|
||||||
<li><a class="reference internal" href="#set-file-hash" id="id16">set_file_hash()</a></li>
|
|
||||||
<li><a class="reference internal" href="#add-url-seed-add-http-seed" id="id17">add_url_seed() add_http_seed()</a></li>
|
|
||||||
<li><a class="reference internal" href="#add-node" id="id18">add_node()</a></li>
|
|
||||||
<li><a class="reference internal" href="#add-tracker" id="id19">add_tracker()</a></li>
|
|
||||||
<li><a class="reference internal" href="#set-root-cert" id="id20">set_root_cert()</a></li>
|
|
||||||
<li><a class="reference internal" href="#set-priv-priv" id="id21">set_priv() priv()</a></li>
|
|
||||||
<li><a class="reference internal" href="#merkle-tree" id="id22">merkle_tree()</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="overview">
|
|
||||||
<h1>overview</h1>
|
|
||||||
<p>This section describes the functions and classes that are used
|
|
||||||
to create torrent files. It is a layered API with low level classes
|
|
||||||
and higher level convenience functions. A torrent is created in 4
|
|
||||||
steps:</p>
|
|
||||||
<ol class="arabic simple">
|
|
||||||
<li>first the files that will be part of the torrent are determined.</li>
|
|
||||||
<li>the torrent properties are set, such as tracker url, web seeds,
|
|
||||||
DHT nodes etc.</li>
|
|
||||||
<li>Read through all the files in the torrent, SHA-1 all the data
|
|
||||||
and set the piece hashes.</li>
|
|
||||||
<li>The torrent is bencoded into a file or buffer.</li>
|
|
||||||
</ol>
|
|
||||||
<p>If there are a lot of files and or deep directoy hierarchies to
|
|
||||||
traverse, step one can be time consuming.</p>
|
|
||||||
<p>Typically step 3 is by far the most time consuming step, since it
|
|
||||||
requires to read all the bytes from all the files in the torrent.</p>
|
|
||||||
<p>All of these classes and functions are declared by including
|
|
||||||
<tt class="docutils literal">libtorrent/create_torrent.hpp</tt>.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="high-level-example">
|
|
||||||
<h1>high level example</h1>
|
|
||||||
<pre class="literal-block">
|
|
||||||
file_storage fs;
|
|
||||||
|
|
||||||
// recursively adds files in directories
|
|
||||||
add_files(fs, "./my_torrent");
|
|
||||||
|
|
||||||
create_torrent t(fs);
|
|
||||||
t.add_tracker("http://my.tracker.com/announce");
|
|
||||||
t.set_creator("libtorrent example");
|
|
||||||
|
|
||||||
// reads the files and calculates the hashes
|
|
||||||
set_piece_hashes(t, ".");
|
|
||||||
|
|
||||||
ofstream out("my_torrent.torrent", std::ios_base::binary);
|
|
||||||
bencode(std::ostream_iterator<char>(out), t.generate());
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="add-files">
|
|
||||||
<h1>add_files</h1>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
template <class Pred>
|
|
||||||
void add_files(file_storage& fs, std::string const& path, Pred p
|
|
||||||
, boost::uint32_t flags = 0);
|
|
||||||
template <class Pred>
|
|
||||||
void add_files(file_storage& fs, std::wstring const& path, Pred p
|
|
||||||
, boost::uint32_t flags = 0);
|
|
||||||
|
|
||||||
void add_files(file_storage& fs, std::string const& path
|
|
||||||
, boost::uint32_t flags = 0);
|
|
||||||
void add_files(file_storage& fs, std::wstring const& path
|
|
||||||
, boost::uint32_t flags = 0);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>Adds the file specified by <tt class="docutils literal">path</tt> to the <tt class="docutils literal">file_storage</tt> object. In case <tt class="docutils literal">path</tt>
|
|
||||||
refers to a diretory, files will be added recursively from the directory.</p>
|
|
||||||
<p>If specified, the predicate <tt class="docutils literal">p</tt> is called once for every file and directory that
|
|
||||||
is encountered. files for which <tt class="docutils literal">p</tt> returns true are added, and directories for
|
|
||||||
which <tt class="docutils literal">p</tt> returns true are traversed. <tt class="docutils literal">p</tt> must have the following signature:</p>
|
|
||||||
<pre class="literal-block">
|
|
||||||
bool Pred(std::string const& p);
|
|
||||||
</pre>
|
|
||||||
<p>and for the wide string version:</p>
|
|
||||||
<pre class="literal-block">
|
|
||||||
bool Pred(std::wstring const& p);
|
|
||||||
</pre>
|
|
||||||
<p>The path that is passed in to the predicate is the full path of the file or
|
|
||||||
directory. If no predicate is specified, all files are added, and all directories
|
|
||||||
are traveresed.</p>
|
|
||||||
<p>The ".." directory is never traversed.</p>
|
|
||||||
<p>The <tt class="docutils literal">flags</tt> argument should be the same as the flags passed to the <a class="reference internal" href="#create-torrent">create_torrent</a>
|
|
||||||
constructor.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="set-piece-hashes">
|
|
||||||
<h1>set_piece_hashes()</h1>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
template <class Fun>
|
|
||||||
void set_piece_hashes(create_torrent& t, std::string const& p, Fun f);
|
|
||||||
template <class Fun>
|
|
||||||
void set_piece_hashes(create_torrent& t, std::wstring const& p, Fun f);
|
|
||||||
template <class Fun>
|
|
||||||
void set_piece_hashes(create_torrent& t, std::string const& p, Fun f
|
|
||||||
, error_code& ec);
|
|
||||||
template <class Fun>
|
|
||||||
void set_piece_hashes(create_torrent& t, std::wstring const& p, Fun f
|
|
||||||
, error_code& ec);
|
|
||||||
|
|
||||||
void set_piece_hashes(create_torrent& t, std::string const& p);
|
|
||||||
void set_piece_hashes(create_torrent& t, std::wstring const& p);
|
|
||||||
void set_piece_hashes(create_torrent& t, std::string const& p
|
|
||||||
, error_code& ec);
|
|
||||||
void set_piece_hashes(create_torrent& t, std::wstring const& p
|
|
||||||
, error_code& ec);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>This function will assume that the files added to the torrent file exists at path
|
|
||||||
<tt class="docutils literal">p</tt>, read those files and hash the content and set the hashes in the <tt class="docutils literal">create_torrent</tt>
|
|
||||||
object. The optional function <tt class="docutils literal">f</tt> is called in between every hash that is set. <tt class="docutils literal">f</tt>
|
|
||||||
must have the following signature:</p>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void Fun(int);
|
|
||||||
</pre>
|
|
||||||
<p>The overloads that don't take an <tt class="docutils literal">error_code&</tt> may throw an exception in case of a
|
|
||||||
file error, the other overloads sets the error code to reflect the error, if any.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="file-storage">
|
|
||||||
<h1>file_storage</h1>
|
|
||||||
<p>The <tt class="docutils literal">file_storage</tt> class represents a file list and the piece
|
|
||||||
size. Everything necessary to interpret a regular bittorrent storage
|
|
||||||
file structure. Its synopsis:</p>
|
|
||||||
<pre class="literal-block">
|
|
||||||
class file_storage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
bool is_valid() const;
|
|
||||||
|
|
||||||
enum flags_t
|
|
||||||
{
|
|
||||||
pad_file = 1,
|
|
||||||
attribute_hidden = 2,
|
|
||||||
attribute_executable = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
void add_file(file_entry const& e);
|
|
||||||
void add_file(std::string const& p, size_type size, int flags = 0);
|
|
||||||
void add_file(std::wstring const& p, size_type size, int flags = 0);
|
|
||||||
void rename_file(int index, std::string const& new_filename);
|
|
||||||
void rename_file(int index, std::wstring const& new_filename);
|
|
||||||
|
|
||||||
std::vector<file_slice> map_block(int piece, size_type offset
|
|
||||||
, int size) const;
|
|
||||||
peer_request map_file(int file, size_type offset, int size) const;
|
|
||||||
|
|
||||||
typedef std::vector<internal_file_entry>::const_iterator iterator;
|
|
||||||
typedef std::vector<internal_file_entry>::const_reverse_iterator reverse_iterator;
|
|
||||||
|
|
||||||
iterator begin() const;
|
|
||||||
iterator end() const;
|
|
||||||
reverse_iterator rbegin();
|
|
||||||
reverse_iterator rend() const;
|
|
||||||
int num_files() const;
|
|
||||||
|
|
||||||
file_entry at(int index) const;
|
|
||||||
|
|
||||||
size_type total_size() const;
|
|
||||||
void set_num_pieces(int n);
|
|
||||||
int num_pieces() const;
|
|
||||||
void set_piece_length(int l);
|
|
||||||
int piece_length() const;
|
|
||||||
int piece_size(int index) const;
|
|
||||||
|
|
||||||
// index accessors
|
|
||||||
sha1_hash const& hash(int index) const;
|
|
||||||
std::string const& symlink(int index) const;
|
|
||||||
time_t mtime(int index) const;
|
|
||||||
size_type file_base(int index) const;
|
|
||||||
void set_file_base(int index, size_type off);
|
|
||||||
std::string file_path(int index) const;
|
|
||||||
std::string file_name(int index) const;
|
|
||||||
size_type file_size(int index) const;
|
|
||||||
bool pad_file_at(int index) const;
|
|
||||||
size_type file_offset(int index) const;
|
|
||||||
|
|
||||||
// iterator accessors
|
|
||||||
sha1_hash hash(internal_file_entry const& fe) const;
|
|
||||||
std::string const& symlink(internal_file_entry const& fe) const;
|
|
||||||
time_t mtime(internal_file_entry const& fe) const;
|
|
||||||
int file_index(internal_file_entry const& fe) const;
|
|
||||||
size_type file_base(internal_file_entry const& fe) const;
|
|
||||||
void set_file_base(internal_file_entry const& fe, size_type off);
|
|
||||||
std::string file_path(internal_file_entry const& fe) const;
|
|
||||||
std::string file_name(internal_file_entry const& fe) const;
|
|
||||||
size_type file_size(internal_file_entry const& fe) const;
|
|
||||||
bool pad_file_at(internal_file_entry const& fe) const;
|
|
||||||
size_type file_offset(internal_file_entry const& fe) const;
|
|
||||||
|
|
||||||
void set_name(std::string const& n);
|
|
||||||
void set_name(std::wstring const& n);
|
|
||||||
const std::string& name() const;
|
|
||||||
|
|
||||||
void swap(file_storage& ti);
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
<div class="section" id="add-file">
|
|
||||||
<h2>add_file()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void add_file(file_entry const& e);
|
|
||||||
void add_file(std::string const& p, size_type size, int flags = 0);
|
|
||||||
void add_file(std::wstring const& p, size_type size, int flags = 0);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>Adds a file to the file storage. The <tt class="docutils literal">flags</tt> argument sets attributes on the file.
|
|
||||||
The file attributes is an extension and may not work in all bittorrent clients.
|
|
||||||
The possible arreibutes are:</p>
|
|
||||||
<pre class="literal-block">
|
|
||||||
pad_file
|
|
||||||
attribute_hidden
|
|
||||||
attribute_executable
|
|
||||||
</pre>
|
|
||||||
<p>If more files than one are added, certain restrictions to their paths apply.
|
|
||||||
In a multi-file file storage (torrent), all files must share the same root directory.</p>
|
|
||||||
<p>That is, the first path element of all files must be the same.
|
|
||||||
This shared path element is also set to the name of the torrent. It
|
|
||||||
can be changed by calling <tt class="docutils literal">set_name</tt>.</p>
|
|
||||||
<p>The built in functions to traverse a directory to add files will
|
|
||||||
make sure this requirement is fulfilled.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="hash-symlink-mtime-file-path-file-size-pad-file-at">
|
|
||||||
<h2>hash() symlink() mtime() file_path() file_size() pad_file_at()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
sha1_hash hash(int index) const;
|
|
||||||
std::string const& symlink(int index) const;
|
|
||||||
time_t mtime(int index) const;
|
|
||||||
std::string file_path(int index) const;
|
|
||||||
size_type file_size(int index) const;
|
|
||||||
bool pad_file_at(int index) const;
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>These functions are used to query attributes of files at
|
|
||||||
a given index.</p>
|
|
||||||
<p>The <tt class="docutils literal">file_hash()</tt> is a sha-1 hash of the file, or 0 if none was
|
|
||||||
provided in the torrent file. This can potentially be used to
|
|
||||||
join a bittorrent network with other file sharing networks.</p>
|
|
||||||
<p>The <tt class="docutils literal">mtime()</tt> is the modification time is the posix
|
|
||||||
time when a file was last modified when the torrent
|
|
||||||
was created, or 0 if it was not included in the torrent file.</p>
|
|
||||||
<p><tt class="docutils literal">file_path()</tt> returns the full path to a file.</p>
|
|
||||||
<p><tt class="docutils literal">file_size()</tt> returns the size of a file.</p>
|
|
||||||
<p><tt class="docutils literal">pad_file_at()</tt> returns true if the file at the given
|
|
||||||
index is a pad-file.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="file-base-set-file-base">
|
|
||||||
<h2>file_base() set_file_base()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
size_type file_base(int index) const;
|
|
||||||
void set_file_base(int index, size_type off);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>The file base of a file is the offset within the file on the filsystem
|
|
||||||
where it starts to write. For the most part, this is always 0. It's
|
|
||||||
possible to map several files (in the torrent) into a single file on
|
|
||||||
the filesystem by making them all point to the same filename, but with
|
|
||||||
different file bases, so that they don't overlap.
|
|
||||||
<tt class="docutils literal"><span class="pre">torrent_info::remap_files</span></tt> can be used to use a new file layout.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="create-torrent">
|
|
||||||
<h1>create_torrent</h1>
|
|
||||||
<p>The <tt class="docutils literal">create_torrent</tt> class has the following synopsis:</p>
|
|
||||||
<pre class="literal-block">
|
|
||||||
struct create_torrent
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
optimize = 1
|
|
||||||
, merkle = 2
|
|
||||||
, modification_time = 4
|
|
||||||
, symlinks = 8
|
|
||||||
, calculate_file_hashes = 16
|
|
||||||
};
|
|
||||||
create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1
|
|
||||||
, int flags = optimize, int alignment = 0x4000);
|
|
||||||
create_torrent(torrent_info const& ti);
|
|
||||||
|
|
||||||
entry generate() const;
|
|
||||||
|
|
||||||
file_storage const& files() const;
|
|
||||||
|
|
||||||
void set_comment(char const* str);
|
|
||||||
void set_creator(char const* str);
|
|
||||||
void set_hash(int index, sha1_hash const& h);
|
|
||||||
void set_file_hash(int index, sha1_hash const& h);
|
|
||||||
void add_url_seed(std::string const& url);
|
|
||||||
void add_http_seed(std::string const& url);
|
|
||||||
void add_node(std::pair<std::string, int> const& node);
|
|
||||||
void add_tracker(std::string const& url, int tier = 0);
|
|
||||||
void set_root_cert(std::string const& pem);
|
|
||||||
void set_priv(bool p);
|
|
||||||
|
|
||||||
int num_pieces() const;
|
|
||||||
int piece_length() const;
|
|
||||||
int piece_size(int i) const;
|
|
||||||
bool priv() const;
|
|
||||||
};
|
|
||||||
</pre>
|
|
||||||
<div class="section" id="id1">
|
|
||||||
<h2>create_torrent()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
enum {
|
|
||||||
optimize = 1
|
|
||||||
, merkle = 2
|
|
||||||
, modification_time = 4
|
|
||||||
, symlinks = 8
|
|
||||||
, calculate_file_hashes = 16
|
|
||||||
};
|
|
||||||
create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1
|
|
||||||
, int flags = optimize, int alignment = 0x4000);
|
|
||||||
create_torrent(torrent_info const& ti);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>The <tt class="docutils literal">piece_size</tt> is the size of each piece in bytes. It must
|
|
||||||
be a multiple of 16 kiB. If a piece size of 0 is specified, a
|
|
||||||
piece_size will be calculated such that the torrent file is roughly 40 kB.</p>
|
|
||||||
<p>If a <tt class="docutils literal">pad_size_limit</tt> is specified (other than -1), any file larger than
|
|
||||||
the specified number of bytes will be preceeded by a pad file to align it
|
|
||||||
with the start of a piece. The pad_file_limit is ignored unless the
|
|
||||||
<tt class="docutils literal">optimize</tt> flag is passed. Typically it doesn't make sense to set this
|
|
||||||
any lower than 4kiB.</p>
|
|
||||||
<p>The overload that takes a <tt class="docutils literal">torrent_info</tt> object will make a verbatim
|
|
||||||
copy of its info dictionary (to preserve the info-hash). The copy of
|
|
||||||
the info dictionary will be used by <tt class="docutils literal">generate()</tt>. This means
|
|
||||||
that none of the member functions of create_torrent that affects
|
|
||||||
the content of the info dictionary (such as <tt class="docutils literal">set_hash()</tt>), will
|
|
||||||
have any affect.</p>
|
|
||||||
<p>The <tt class="docutils literal">flags</tt> arguments specifies options for the torrent creation. It can
|
|
||||||
be any combination of the following flags:</p>
|
|
||||||
<dl class="docutils">
|
|
||||||
<dt>optimize</dt>
|
|
||||||
<dd>This will insert pad files to align the files to piece boundaries, for
|
|
||||||
optimized disk-I/O.</dd>
|
|
||||||
<dt>merkle</dt>
|
|
||||||
<dd>This will create a merkle hash tree torrent. A merkle torrent cannot
|
|
||||||
be opened in clients that don't specifically support merkle torrents.
|
|
||||||
The benefit is that the resulting torrent file will be much smaller and
|
|
||||||
not grow with more pieces. When this option is specified, it is
|
|
||||||
recommended to have a fairly small piece size, say 64 kiB.
|
|
||||||
When creating merkle torrents, the full hash tree is also generated
|
|
||||||
and should be saved off separately. It is accessed through the
|
|
||||||
<tt class="docutils literal">merkle_tree()</tt> function.</dd>
|
|
||||||
<dt>modification_time</dt>
|
|
||||||
<dd>This will include the file modification time as part of the torrent.
|
|
||||||
This is not enabled by default, as it might cause problems when you
|
|
||||||
create a torrent from separate files with the same content, hoping to
|
|
||||||
yield the same info-hash. If the files have different modification times,
|
|
||||||
with this option enabled, you would get different info-hashes for the
|
|
||||||
files.</dd>
|
|
||||||
<dt>symlink</dt>
|
|
||||||
<dd>If this flag is set, files that are symlinks get a symlink attribute
|
|
||||||
set on them and their data will not be included in the torrent. This
|
|
||||||
is useful if you need to reconstruct a file hierarchy which contains
|
|
||||||
symlinks.</dd>
|
|
||||||
<dt>calculate_file_hashes</dt>
|
|
||||||
<dd>If this is set, the <a class="reference internal" href="#set-piece-hashes">set_piece_hashes()</a> function will, as it calculates
|
|
||||||
the piece hashes, also calculate the file hashes and add those associated
|
|
||||||
with each file. Note that unless you use the <a class="reference internal" href="#set-piece-hashes">set_piece_hashes()</a> function,
|
|
||||||
this flag will have no effect.</dd>
|
|
||||||
</dl>
|
|
||||||
<p><tt class="docutils literal">alignment</tt> is used when pad files are enabled. This is the size eligible
|
|
||||||
files are aligned to. The default is the default bittorrent block size of
|
|
||||||
16 kiB. It is common to align to the piece size of the torrent.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="generate">
|
|
||||||
<h2>generate()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
entry generate() const;
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>This function will generate the .torrent file as a bencode tree. In order to
|
|
||||||
generate the flat file, use the bencode() function.</p>
|
|
||||||
<p>It may be useful to add custom entries to the torrent file before bencoding it
|
|
||||||
and saving it to disk.</p>
|
|
||||||
<p>If anything goes wrong during torrent generation, this function will return
|
|
||||||
an empty <tt class="docutils literal">entry</tt> structure. You can test for this condition by querying the
|
|
||||||
type of the entry:</p>
|
|
||||||
<pre class="literal-block">
|
|
||||||
file_storage fs;
|
|
||||||
// add file ...
|
|
||||||
create_torrent t(fs);
|
|
||||||
// add trackers and piece hashes ...
|
|
||||||
e = t.generate();
|
|
||||||
|
|
||||||
if (e.type() == entry::undefined_t)
|
|
||||||
{
|
|
||||||
// something went wrong
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
<p>For instance, you cannot generate a torrent with 0 files in it. If you don't add
|
|
||||||
any files to the <tt class="docutils literal">file_storage</tt>, torrent generation will fail.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="set-comment">
|
|
||||||
<h2>set_comment()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void set_comment(char const* str);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>Sets the comment for the torrent. The string <tt class="docutils literal">str</tt> should be utf-8 encoded.
|
|
||||||
The comment in a torrent file is optional.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="set-creator">
|
|
||||||
<h2>set_creator()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void set_creator(char const* str);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>Sets the creator of the torrent. The string <tt class="docutils literal">str</tt> should be utf-8 encoded.
|
|
||||||
This is optional.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="set-hash">
|
|
||||||
<h2>set_hash()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void set_hash(int index, sha1_hash const& h);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>This sets the SHA-1 hash for the specified piece (<tt class="docutils literal">index</tt>). You are required
|
|
||||||
to set the hash for every piece in the torrent before generating it. If you have
|
|
||||||
the files on disk, you can use the high level convenience function to do this.
|
|
||||||
See <a class="reference internal" href="#set-piece-hashes">set_piece_hashes()</a>.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="set-file-hash">
|
|
||||||
<h2>set_file_hash()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void set_file_hash(int index, sha1_hash const& h);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>This sets the sha1 hash for this file. This hash will end up under the key <tt class="docutils literal">sha1</tt>
|
|
||||||
associated with this file (for multi-file torrents) or in the root info dictionary
|
|
||||||
for single-file torrents.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="add-url-seed-add-http-seed">
|
|
||||||
<h2>add_url_seed() add_http_seed()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void add_url_seed(std::string const& url);
|
|
||||||
void add_http_seed(std::string const& url);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>This adds a url seed to the torrent. You can have any number of url seeds. For a
|
|
||||||
single file torrent, this should be an HTTP url, pointing to a file with identical
|
|
||||||
content as the file of the torrent. For a multi-file torrent, it should point to
|
|
||||||
a directory containing a directory with the same name as this torrent, and all the
|
|
||||||
files of the torrent in it.</p>
|
|
||||||
<p>The second function, <tt class="docutils literal">add_http_seed()</tt> adds an HTTP seed instead.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="add-node">
|
|
||||||
<h2>add_node()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void add_node(std::pair<std::string, int> const& node);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>This adds a DHT node to the torrent. This especially useful if you're creating a
|
|
||||||
tracker less torrent. It can be used by clients to bootstrap their DHT node from.
|
|
||||||
The node is a hostname and a port number where there is a DHT node running.
|
|
||||||
You can have any number of DHT nodes in a torrent.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="add-tracker">
|
|
||||||
<h2>add_tracker()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void add_tracker(std::string const& url, int tier = 0);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>Adds a tracker to the torrent. This is not strictly required, but most torrents
|
|
||||||
use a tracker as their main source of peers. The url should be an <a class="reference external" href="http://">http://</a> or udp://
|
|
||||||
url to a machine running a bittorrent tracker that accepts announces for this torrent's
|
|
||||||
info-hash. The tier is the fallback priority of the tracker. All trackers with tier 0 are
|
|
||||||
tried first (in any order). If all fail, trackers with tier 1 are tried. If all of those
|
|
||||||
fail, trackers with tier 2 are tried, and so on.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="set-root-cert">
|
|
||||||
<h2>set_root_cert()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void set_root_cert(std::string const& pem);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>This function sets an X.509 certificate in PEM format to the torrent. This makes the
|
|
||||||
torrent an <em>SSL torrent</em>. An SSL torrent requires that each peer has a valid certificate
|
|
||||||
signed by this root certificate. For SSL torrents, all peers are connecting over SSL
|
|
||||||
connections. For more information on SSL torrents, see the <a class="reference external" href="manual.html#ssl-torrents">manual</a>.</p>
|
|
||||||
<p>The string is not the path to the cert, it's the actual content of the certificate,
|
|
||||||
loaded into a std::string.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="set-priv-priv">
|
|
||||||
<h2>set_priv() priv()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
void set_priv(bool p);
|
|
||||||
bool priv() const;
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>Sets and queries the private flag of the torrent.</p>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="merkle-tree">
|
|
||||||
<h2>merkle_tree()</h2>
|
|
||||||
<blockquote>
|
|
||||||
<pre class="literal-block">
|
|
||||||
std::vector<sha1_hash> const& merkle_tree() const;
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>This function returns the merkle hash tree, if the torrent was created as a merkle
|
|
||||||
torrent. The tree is created by <tt class="docutils literal">generate()</tt> and won't be valid until that function
|
|
||||||
has been called. When creating a merkle tree torrent, the actual tree itself has to
|
|
||||||
be saved off separately and fed into libtorrent the first time you start seeding it,
|
|
||||||
through the <tt class="docutils literal"><span class="pre">torrent_info::set_merkle_tree()</span></tt> function. From that point onwards, the
|
|
||||||
tree will be saved in the resume data.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="footer">
|
|
||||||
<span>Copyright © 2005-2013 Rasterbar Software.</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
|
||||||
</script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
_uacct = "UA-1599045-1";
|
|
||||||
urchinTracker();
|
|
||||||
</script>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,552 +0,0 @@
|
||||||
=================
|
|
||||||
creating torrents
|
|
||||||
=================
|
|
||||||
|
|
||||||
:Author: Arvid Norberg, arvid@rasterbar.com
|
|
||||||
:Version: 1.0.0
|
|
||||||
|
|
||||||
.. contents:: Table of contents
|
|
||||||
:depth: 2
|
|
||||||
:backlinks: none
|
|
||||||
|
|
||||||
overview
|
|
||||||
========
|
|
||||||
|
|
||||||
This section describes the functions and classes that are used
|
|
||||||
to create torrent files. It is a layered API with low level classes
|
|
||||||
and higher level convenience functions. A torrent is created in 4
|
|
||||||
steps:
|
|
||||||
|
|
||||||
1. first the files that will be part of the torrent are determined.
|
|
||||||
2. the torrent properties are set, such as tracker url, web seeds,
|
|
||||||
DHT nodes etc.
|
|
||||||
3. Read through all the files in the torrent, SHA-1 all the data
|
|
||||||
and set the piece hashes.
|
|
||||||
4. The torrent is bencoded into a file or buffer.
|
|
||||||
|
|
||||||
If there are a lot of files and or deep directoy hierarchies to
|
|
||||||
traverse, step one can be time consuming.
|
|
||||||
|
|
||||||
Typically step 3 is by far the most time consuming step, since it
|
|
||||||
requires to read all the bytes from all the files in the torrent.
|
|
||||||
|
|
||||||
All of these classes and functions are declared by including
|
|
||||||
``libtorrent/create_torrent.hpp``.
|
|
||||||
|
|
||||||
high level example
|
|
||||||
==================
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
file_storage fs;
|
|
||||||
|
|
||||||
// recursively adds files in directories
|
|
||||||
add_files(fs, "./my_torrent");
|
|
||||||
|
|
||||||
create_torrent t(fs);
|
|
||||||
t.add_tracker("http://my.tracker.com/announce");
|
|
||||||
t.set_creator("libtorrent example");
|
|
||||||
|
|
||||||
// reads the files and calculates the hashes
|
|
||||||
set_piece_hashes(t, ".");
|
|
||||||
|
|
||||||
ofstream out("my_torrent.torrent", std::ios_base::binary);
|
|
||||||
bencode(std::ostream_iterator<char>(out), t.generate());
|
|
||||||
|
|
||||||
add_files
|
|
||||||
=========
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
template <class Pred>
|
|
||||||
void add_files(file_storage& fs, std::string const& path, Pred p
|
|
||||||
, boost::uint32_t flags = 0);
|
|
||||||
template <class Pred>
|
|
||||||
void add_files(file_storage& fs, std::wstring const& path, Pred p
|
|
||||||
, boost::uint32_t flags = 0);
|
|
||||||
|
|
||||||
void add_files(file_storage& fs, std::string const& path
|
|
||||||
, boost::uint32_t flags = 0);
|
|
||||||
void add_files(file_storage& fs, std::wstring const& path
|
|
||||||
, boost::uint32_t flags = 0);
|
|
||||||
|
|
||||||
Adds the file specified by ``path`` to the ``file_storage`` object. In case ``path``
|
|
||||||
refers to a diretory, files will be added recursively from the directory.
|
|
||||||
|
|
||||||
If specified, the predicate ``p`` is called once for every file and directory that
|
|
||||||
is encountered. files for which ``p`` returns true are added, and directories for
|
|
||||||
which ``p`` returns true are traversed. ``p`` must have the following signature::
|
|
||||||
|
|
||||||
bool Pred(std::string const& p);
|
|
||||||
|
|
||||||
and for the wide string version::
|
|
||||||
|
|
||||||
bool Pred(std::wstring const& p);
|
|
||||||
|
|
||||||
The path that is passed in to the predicate is the full path of the file or
|
|
||||||
directory. If no predicate is specified, all files are added, and all directories
|
|
||||||
are traveresed.
|
|
||||||
|
|
||||||
The ".." directory is never traversed.
|
|
||||||
|
|
||||||
The ``flags`` argument should be the same as the flags passed to the `create_torrent`_
|
|
||||||
constructor.
|
|
||||||
|
|
||||||
set_piece_hashes()
|
|
||||||
==================
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
template <class Fun>
|
|
||||||
void set_piece_hashes(create_torrent& t, std::string const& p, Fun f);
|
|
||||||
template <class Fun>
|
|
||||||
void set_piece_hashes(create_torrent& t, std::wstring const& p, Fun f);
|
|
||||||
template <class Fun>
|
|
||||||
void set_piece_hashes(create_torrent& t, std::string const& p, Fun f
|
|
||||||
, error_code& ec);
|
|
||||||
template <class Fun>
|
|
||||||
void set_piece_hashes(create_torrent& t, std::wstring const& p, Fun f
|
|
||||||
, error_code& ec);
|
|
||||||
|
|
||||||
void set_piece_hashes(create_torrent& t, std::string const& p);
|
|
||||||
void set_piece_hashes(create_torrent& t, std::wstring const& p);
|
|
||||||
void set_piece_hashes(create_torrent& t, std::string const& p
|
|
||||||
, error_code& ec);
|
|
||||||
void set_piece_hashes(create_torrent& t, std::wstring const& p
|
|
||||||
, error_code& ec);
|
|
||||||
|
|
||||||
This function will assume that the files added to the torrent file exists at path
|
|
||||||
``p``, read those files and hash the content and set the hashes in the ``create_torrent``
|
|
||||||
object. The optional function ``f`` is called in between every hash that is set. ``f``
|
|
||||||
must have the following signature::
|
|
||||||
|
|
||||||
void Fun(int);
|
|
||||||
|
|
||||||
The overloads that don't take an ``error_code&`` may throw an exception in case of a
|
|
||||||
file error, the other overloads sets the error code to reflect the error, if any.
|
|
||||||
|
|
||||||
file_storage
|
|
||||||
============
|
|
||||||
|
|
||||||
The ``file_storage`` class represents a file list and the piece
|
|
||||||
size. Everything necessary to interpret a regular bittorrent storage
|
|
||||||
file structure. Its synopsis::
|
|
||||||
|
|
||||||
class file_storage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
bool is_valid() const;
|
|
||||||
|
|
||||||
enum flags_t
|
|
||||||
{
|
|
||||||
pad_file = 1,
|
|
||||||
attribute_hidden = 2,
|
|
||||||
attribute_executable = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
void add_file(file_entry const& e);
|
|
||||||
void add_file(std::string const& p, size_type size, int flags = 0);
|
|
||||||
void add_file(std::wstring const& p, size_type size, int flags = 0);
|
|
||||||
void rename_file(int index, std::string const& new_filename);
|
|
||||||
void rename_file(int index, std::wstring const& new_filename);
|
|
||||||
|
|
||||||
std::vector<file_slice> map_block(int piece, size_type offset
|
|
||||||
, int size) const;
|
|
||||||
peer_request map_file(int file, size_type offset, int size) const;
|
|
||||||
|
|
||||||
typedef std::vector<internal_file_entry>::const_iterator iterator;
|
|
||||||
typedef std::vector<internal_file_entry>::const_reverse_iterator reverse_iterator;
|
|
||||||
|
|
||||||
iterator begin() const;
|
|
||||||
iterator end() const;
|
|
||||||
reverse_iterator rbegin();
|
|
||||||
reverse_iterator rend() const;
|
|
||||||
int num_files() const;
|
|
||||||
|
|
||||||
file_entry at(int index) const;
|
|
||||||
|
|
||||||
size_type total_size() const;
|
|
||||||
void set_num_pieces(int n);
|
|
||||||
int num_pieces() const;
|
|
||||||
void set_piece_length(int l);
|
|
||||||
int piece_length() const;
|
|
||||||
int piece_size(int index) const;
|
|
||||||
|
|
||||||
// index accessors
|
|
||||||
sha1_hash const& hash(int index) const;
|
|
||||||
std::string const& symlink(int index) const;
|
|
||||||
time_t mtime(int index) const;
|
|
||||||
size_type file_base(int index) const;
|
|
||||||
void set_file_base(int index, size_type off);
|
|
||||||
std::string file_path(int index) const;
|
|
||||||
std::string file_name(int index) const;
|
|
||||||
size_type file_size(int index) const;
|
|
||||||
bool pad_file_at(int index) const;
|
|
||||||
size_type file_offset(int index) const;
|
|
||||||
|
|
||||||
// iterator accessors
|
|
||||||
sha1_hash hash(internal_file_entry const& fe) const;
|
|
||||||
std::string const& symlink(internal_file_entry const& fe) const;
|
|
||||||
time_t mtime(internal_file_entry const& fe) const;
|
|
||||||
int file_index(internal_file_entry const& fe) const;
|
|
||||||
size_type file_base(internal_file_entry const& fe) const;
|
|
||||||
void set_file_base(internal_file_entry const& fe, size_type off);
|
|
||||||
std::string file_path(internal_file_entry const& fe) const;
|
|
||||||
std::string file_name(internal_file_entry const& fe) const;
|
|
||||||
size_type file_size(internal_file_entry const& fe) const;
|
|
||||||
bool pad_file_at(internal_file_entry const& fe) const;
|
|
||||||
size_type file_offset(internal_file_entry const& fe) const;
|
|
||||||
|
|
||||||
void set_name(std::string const& n);
|
|
||||||
void set_name(std::wstring const& n);
|
|
||||||
const std::string& name() const;
|
|
||||||
|
|
||||||
void swap(file_storage& ti);
|
|
||||||
}
|
|
||||||
|
|
||||||
add_file()
|
|
||||||
----------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
void add_file(file_entry const& e);
|
|
||||||
void add_file(std::string const& p, size_type size, int flags = 0);
|
|
||||||
void add_file(std::wstring const& p, size_type size, int flags = 0);
|
|
||||||
|
|
||||||
Adds a file to the file storage. The ``flags`` argument sets attributes on the file.
|
|
||||||
The file attributes is an extension and may not work in all bittorrent clients.
|
|
||||||
The possible arreibutes are::
|
|
||||||
|
|
||||||
pad_file
|
|
||||||
attribute_hidden
|
|
||||||
attribute_executable
|
|
||||||
|
|
||||||
If more files than one are added, certain restrictions to their paths apply.
|
|
||||||
In a multi-file file storage (torrent), all files must share the same root directory.
|
|
||||||
|
|
||||||
That is, the first path element of all files must be the same.
|
|
||||||
This shared path element is also set to the name of the torrent. It
|
|
||||||
can be changed by calling ``set_name``.
|
|
||||||
|
|
||||||
The built in functions to traverse a directory to add files will
|
|
||||||
make sure this requirement is fulfilled.
|
|
||||||
|
|
||||||
hash() symlink() mtime() file_path() file_size() pad_file_at()
|
|
||||||
--------------------------------------------------------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
sha1_hash hash(int index) const;
|
|
||||||
std::string const& symlink(int index) const;
|
|
||||||
time_t mtime(int index) const;
|
|
||||||
std::string file_path(int index) const;
|
|
||||||
size_type file_size(int index) const;
|
|
||||||
bool pad_file_at(int index) const;
|
|
||||||
|
|
||||||
These functions are used to query attributes of files at
|
|
||||||
a given index.
|
|
||||||
|
|
||||||
The ``file_hash()`` is a sha-1 hash of the file, or 0 if none was
|
|
||||||
provided in the torrent file. This can potentially be used to
|
|
||||||
join a bittorrent network with other file sharing networks.
|
|
||||||
|
|
||||||
The ``mtime()`` is the modification time is the posix
|
|
||||||
time when a file was last modified when the torrent
|
|
||||||
was created, or 0 if it was not included in the torrent file.
|
|
||||||
|
|
||||||
``file_path()`` returns the full path to a file.
|
|
||||||
|
|
||||||
``file_size()`` returns the size of a file.
|
|
||||||
|
|
||||||
``pad_file_at()`` returns true if the file at the given
|
|
||||||
index is a pad-file.
|
|
||||||
|
|
||||||
file_base() set_file_base()
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
size_type file_base(int index) const;
|
|
||||||
void set_file_base(int index, size_type off);
|
|
||||||
|
|
||||||
The file base of a file is the offset within the file on the filsystem
|
|
||||||
where it starts to write. For the most part, this is always 0. It's
|
|
||||||
possible to map several files (in the torrent) into a single file on
|
|
||||||
the filesystem by making them all point to the same filename, but with
|
|
||||||
different file bases, so that they don't overlap.
|
|
||||||
``torrent_info::remap_files`` can be used to use a new file layout.
|
|
||||||
|
|
||||||
create_torrent
|
|
||||||
==============
|
|
||||||
|
|
||||||
The ``create_torrent`` class has the following synopsis::
|
|
||||||
|
|
||||||
|
|
||||||
struct create_torrent
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
optimize = 1
|
|
||||||
, merkle = 2
|
|
||||||
, modification_time = 4
|
|
||||||
, symlinks = 8
|
|
||||||
, calculate_file_hashes = 16
|
|
||||||
};
|
|
||||||
create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1
|
|
||||||
, int flags = optimize, int alignment = 0x4000);
|
|
||||||
create_torrent(torrent_info const& ti);
|
|
||||||
|
|
||||||
entry generate() const;
|
|
||||||
|
|
||||||
file_storage const& files() const;
|
|
||||||
|
|
||||||
void set_comment(char const* str);
|
|
||||||
void set_creator(char const* str);
|
|
||||||
void set_hash(int index, sha1_hash const& h);
|
|
||||||
void set_file_hash(int index, sha1_hash const& h);
|
|
||||||
void add_url_seed(std::string const& url);
|
|
||||||
void add_http_seed(std::string const& url);
|
|
||||||
void add_node(std::pair<std::string, int> const& node);
|
|
||||||
void add_tracker(std::string const& url, int tier = 0);
|
|
||||||
void set_root_cert(std::string const& pem);
|
|
||||||
void set_priv(bool p);
|
|
||||||
|
|
||||||
int num_pieces() const;
|
|
||||||
int piece_length() const;
|
|
||||||
int piece_size(int i) const;
|
|
||||||
bool priv() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
create_torrent()
|
|
||||||
----------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
enum {
|
|
||||||
optimize = 1
|
|
||||||
, merkle = 2
|
|
||||||
, modification_time = 4
|
|
||||||
, symlinks = 8
|
|
||||||
, calculate_file_hashes = 16
|
|
||||||
};
|
|
||||||
create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1
|
|
||||||
, int flags = optimize, int alignment = 0x4000);
|
|
||||||
create_torrent(torrent_info const& ti);
|
|
||||||
|
|
||||||
The ``piece_size`` is the size of each piece in bytes. It must
|
|
||||||
be a multiple of 16 kiB. If a piece size of 0 is specified, a
|
|
||||||
piece_size will be calculated such that the torrent file is roughly 40 kB.
|
|
||||||
|
|
||||||
If a ``pad_size_limit`` is specified (other than -1), any file larger than
|
|
||||||
the specified number of bytes will be preceeded by a pad file to align it
|
|
||||||
with the start of a piece. The pad_file_limit is ignored unless the
|
|
||||||
``optimize`` flag is passed. Typically it doesn't make sense to set this
|
|
||||||
any lower than 4kiB.
|
|
||||||
|
|
||||||
The overload that takes a ``torrent_info`` object will make a verbatim
|
|
||||||
copy of its info dictionary (to preserve the info-hash). The copy of
|
|
||||||
the info dictionary will be used by ``generate()``. This means
|
|
||||||
that none of the member functions of create_torrent that affects
|
|
||||||
the content of the info dictionary (such as ``set_hash()``), will
|
|
||||||
have any affect.
|
|
||||||
|
|
||||||
The ``flags`` arguments specifies options for the torrent creation. It can
|
|
||||||
be any combination of the following flags:
|
|
||||||
|
|
||||||
optimize
|
|
||||||
This will insert pad files to align the files to piece boundaries, for
|
|
||||||
optimized disk-I/O.
|
|
||||||
|
|
||||||
merkle
|
|
||||||
This will create a merkle hash tree torrent. A merkle torrent cannot
|
|
||||||
be opened in clients that don't specifically support merkle torrents.
|
|
||||||
The benefit is that the resulting torrent file will be much smaller and
|
|
||||||
not grow with more pieces. When this option is specified, it is
|
|
||||||
recommended to have a fairly small piece size, say 64 kiB.
|
|
||||||
When creating merkle torrents, the full hash tree is also generated
|
|
||||||
and should be saved off separately. It is accessed through the
|
|
||||||
``merkle_tree()`` function.
|
|
||||||
|
|
||||||
modification_time
|
|
||||||
This will include the file modification time as part of the torrent.
|
|
||||||
This is not enabled by default, as it might cause problems when you
|
|
||||||
create a torrent from separate files with the same content, hoping to
|
|
||||||
yield the same info-hash. If the files have different modification times,
|
|
||||||
with this option enabled, you would get different info-hashes for the
|
|
||||||
files.
|
|
||||||
|
|
||||||
symlink
|
|
||||||
If this flag is set, files that are symlinks get a symlink attribute
|
|
||||||
set on them and their data will not be included in the torrent. This
|
|
||||||
is useful if you need to reconstruct a file hierarchy which contains
|
|
||||||
symlinks.
|
|
||||||
|
|
||||||
calculate_file_hashes
|
|
||||||
If this is set, the `set_piece_hashes()`_ function will, as it calculates
|
|
||||||
the piece hashes, also calculate the file hashes and add those associated
|
|
||||||
with each file. Note that unless you use the `set_piece_hashes()`_ function,
|
|
||||||
this flag will have no effect.
|
|
||||||
|
|
||||||
``alignment`` is used when pad files are enabled. This is the size eligible
|
|
||||||
files are aligned to. The default is the default bittorrent block size of
|
|
||||||
16 kiB. It is common to align to the piece size of the torrent.
|
|
||||||
|
|
||||||
generate()
|
|
||||||
----------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
entry generate() const;
|
|
||||||
|
|
||||||
This function will generate the .torrent file as a bencode tree. In order to
|
|
||||||
generate the flat file, use the bencode() function.
|
|
||||||
|
|
||||||
It may be useful to add custom entries to the torrent file before bencoding it
|
|
||||||
and saving it to disk.
|
|
||||||
|
|
||||||
If anything goes wrong during torrent generation, this function will return
|
|
||||||
an empty ``entry`` structure. You can test for this condition by querying the
|
|
||||||
type of the entry::
|
|
||||||
|
|
||||||
file_storage fs;
|
|
||||||
// add file ...
|
|
||||||
create_torrent t(fs);
|
|
||||||
// add trackers and piece hashes ...
|
|
||||||
e = t.generate();
|
|
||||||
|
|
||||||
if (e.type() == entry::undefined_t)
|
|
||||||
{
|
|
||||||
// something went wrong
|
|
||||||
}
|
|
||||||
|
|
||||||
For instance, you cannot generate a torrent with 0 files in it. If you don't add
|
|
||||||
any files to the ``file_storage``, torrent generation will fail.
|
|
||||||
|
|
||||||
set_comment()
|
|
||||||
-------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
void set_comment(char const* str);
|
|
||||||
|
|
||||||
Sets the comment for the torrent. The string ``str`` should be utf-8 encoded.
|
|
||||||
The comment in a torrent file is optional.
|
|
||||||
|
|
||||||
set_creator()
|
|
||||||
-------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
void set_creator(char const* str);
|
|
||||||
|
|
||||||
Sets the creator of the torrent. The string ``str`` should be utf-8 encoded.
|
|
||||||
This is optional.
|
|
||||||
|
|
||||||
set_hash()
|
|
||||||
----------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
void set_hash(int index, sha1_hash const& h);
|
|
||||||
|
|
||||||
This sets the SHA-1 hash for the specified piece (``index``). You are required
|
|
||||||
to set the hash for every piece in the torrent before generating it. If you have
|
|
||||||
the files on disk, you can use the high level convenience function to do this.
|
|
||||||
See `set_piece_hashes()`_.
|
|
||||||
|
|
||||||
set_file_hash()
|
|
||||||
---------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
void set_file_hash(int index, sha1_hash const& h);
|
|
||||||
|
|
||||||
This sets the sha1 hash for this file. This hash will end up under the key ``sha1``
|
|
||||||
associated with this file (for multi-file torrents) or in the root info dictionary
|
|
||||||
for single-file torrents.
|
|
||||||
|
|
||||||
add_url_seed() add_http_seed()
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
void add_url_seed(std::string const& url);
|
|
||||||
void add_http_seed(std::string const& url);
|
|
||||||
|
|
||||||
This adds a url seed to the torrent. You can have any number of url seeds. For a
|
|
||||||
single file torrent, this should be an HTTP url, pointing to a file with identical
|
|
||||||
content as the file of the torrent. For a multi-file torrent, it should point to
|
|
||||||
a directory containing a directory with the same name as this torrent, and all the
|
|
||||||
files of the torrent in it.
|
|
||||||
|
|
||||||
The second function, ``add_http_seed()`` adds an HTTP seed instead.
|
|
||||||
|
|
||||||
add_node()
|
|
||||||
----------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
void add_node(std::pair<std::string, int> const& node);
|
|
||||||
|
|
||||||
This adds a DHT node to the torrent. This especially useful if you're creating a
|
|
||||||
tracker less torrent. It can be used by clients to bootstrap their DHT node from.
|
|
||||||
The node is a hostname and a port number where there is a DHT node running.
|
|
||||||
You can have any number of DHT nodes in a torrent.
|
|
||||||
|
|
||||||
add_tracker()
|
|
||||||
-------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
void add_tracker(std::string const& url, int tier = 0);
|
|
||||||
|
|
||||||
Adds a tracker to the torrent. This is not strictly required, but most torrents
|
|
||||||
use a tracker as their main source of peers. The url should be an http:// or udp://
|
|
||||||
url to a machine running a bittorrent tracker that accepts announces for this torrent's
|
|
||||||
info-hash. The tier is the fallback priority of the tracker. All trackers with tier 0 are
|
|
||||||
tried first (in any order). If all fail, trackers with tier 1 are tried. If all of those
|
|
||||||
fail, trackers with tier 2 are tried, and so on.
|
|
||||||
|
|
||||||
set_root_cert()
|
|
||||||
---------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
void set_root_cert(std::string const& pem);
|
|
||||||
|
|
||||||
This function sets an X.509 certificate in PEM format to the torrent. This makes the
|
|
||||||
torrent an *SSL torrent*. An SSL torrent requires that each peer has a valid certificate
|
|
||||||
signed by this root certificate. For SSL torrents, all peers are connecting over SSL
|
|
||||||
connections. For more information on SSL torrents, see the manual_.
|
|
||||||
|
|
||||||
The string is not the path to the cert, it's the actual content of the certificate,
|
|
||||||
loaded into a std::string.
|
|
||||||
|
|
||||||
.. _manual: manual.html#ssl-torrents
|
|
||||||
|
|
||||||
set_priv() priv()
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
void set_priv(bool p);
|
|
||||||
bool priv() const;
|
|
||||||
|
|
||||||
Sets and queries the private flag of the torrent.
|
|
||||||
|
|
||||||
merkle_tree()
|
|
||||||
-------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
std::vector<sha1_hash> const& merkle_tree() const;
|
|
||||||
|
|
||||||
This function returns the merkle hash tree, if the torrent was created as a merkle
|
|
||||||
torrent. The tree is created by ``generate()`` and won't be valid until that function
|
|
||||||
has been called. When creating a merkle tree torrent, the actual tree itself has to
|
|
||||||
be saved off separately and fed into libtorrent the first time you start seeding it,
|
|
||||||
through the ``torrent_info::set_merkle_tree()`` function. From that point onwards, the
|
|
||||||
tree will be saved in the resume data.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ TARGETS = index \
|
||||||
contributing\
|
contributing\
|
||||||
examples \
|
examples \
|
||||||
extension_protocol \
|
extension_protocol \
|
||||||
make_torrent \
|
|
||||||
dht_extensions \
|
dht_extensions \
|
||||||
dht_sec \
|
dht_sec \
|
||||||
libtorrent_plugins \
|
libtorrent_plugins \
|
||||||
|
|
|
@ -77,7 +77,7 @@ using libtorrent in python
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
The python interface is nearly identical to the C++ interface. Please refer to
|
The python interface is nearly identical to the C++ interface. Please refer to
|
||||||
the `main library reference`_. The main differences are:
|
the `library reference`_. The main differences are:
|
||||||
|
|
||||||
asio::tcp::endpoint
|
asio::tcp::endpoint
|
||||||
The endpoint type is represented as a tuple of a string (as the address) and an int for
|
The endpoint type is represented as a tuple of a string (as the address) and an int for
|
||||||
|
@ -106,7 +106,7 @@ keys that are not present, are set to their default value.
|
||||||
For backwards compatibility, ``session::settings()`` still returns a ``session_settings``
|
For backwards compatibility, ``session::settings()`` still returns a ``session_settings``
|
||||||
struct. To get a python dictionary of the settings, call ``session::get_settings``.
|
struct. To get a python dictionary of the settings, call ``session::get_settings``.
|
||||||
|
|
||||||
.. _`main library reference`: manual.html
|
.. _`library reference`: reference.html
|
||||||
|
|
||||||
For an example python program, see ``client.py`` in the ``bindings/python``
|
For an example python program, see ``client.py`` in the ``bindings/python``
|
||||||
directory.
|
directory.
|
||||||
|
|
|
@ -58,46 +58,220 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// OVERVIEW
|
||||||
|
//
|
||||||
|
// This section describes the functions and classes that are used
|
||||||
|
// to create torrent files. It is a layered API with low level classes
|
||||||
|
// and higher level convenience functions. A torrent is created in 4
|
||||||
|
// steps:
|
||||||
|
//
|
||||||
|
// 1. first the files that will be part of the torrent are determined.
|
||||||
|
// 2. the torrent properties are set, such as tracker url, web seeds,
|
||||||
|
// DHT nodes etc.
|
||||||
|
// 3. Read through all the files in the torrent, SHA-1 all the data
|
||||||
|
// and set the piece hashes.
|
||||||
|
// 4. The torrent is bencoded into a file or buffer.
|
||||||
|
//
|
||||||
|
// If there are a lot of files and or deep directoy hierarchies to
|
||||||
|
// traverse, step one can be time consuming.
|
||||||
|
//
|
||||||
|
// Typically step 3 is by far the most time consuming step, since it
|
||||||
|
// requires to read all the bytes from all the files in the torrent.
|
||||||
|
//
|
||||||
|
// All of these classes and functions are declared by including
|
||||||
|
// ``libtorrent/create_torrent.hpp``.
|
||||||
|
//
|
||||||
|
// example::
|
||||||
|
//
|
||||||
|
// file_storage fs;
|
||||||
|
//
|
||||||
|
// // recursively adds files in directories
|
||||||
|
// add_files(fs, "./my_torrent");
|
||||||
|
//
|
||||||
|
// create_torrent t(fs);
|
||||||
|
// t.add_tracker("http://my.tracker.com/announce");
|
||||||
|
// t.set_creator("libtorrent example");
|
||||||
|
//
|
||||||
|
// // reads the files and calculates the hashes
|
||||||
|
// set_piece_hashes(t, ".");
|
||||||
|
//
|
||||||
|
// ofstream out("my_torrent.torrent", std::ios_base::binary);
|
||||||
|
// bencode(std::ostream_iterator<char>(out), t.generate());
|
||||||
|
//
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
class torrent_info;
|
class torrent_info;
|
||||||
|
|
||||||
|
// This class holds state for creating a torrent. After having added
|
||||||
|
// all information to it, call create_torrent::generate() to generate
|
||||||
|
// the torrent. The entry that's returned can then be bencoded into a
|
||||||
|
// .torrent file using bencode().
|
||||||
struct TORRENT_EXPORT create_torrent
|
struct TORRENT_EXPORT create_torrent
|
||||||
{
|
{
|
||||||
enum flags_t
|
enum flags_t
|
||||||
{
|
{
|
||||||
|
// This will insert pad files to align the files to piece boundaries, for
|
||||||
|
// optimized disk-I/O.
|
||||||
optimize = 1
|
optimize = 1
|
||||||
|
|
||||||
|
// This will create a merkle hash tree torrent. A merkle torrent cannot
|
||||||
|
// be opened in clients that don't specifically support merkle torrents.
|
||||||
|
// The benefit is that the resulting torrent file will be much smaller and
|
||||||
|
// not grow with more pieces. When this option is specified, it is
|
||||||
|
// recommended to have a fairly small piece size, say 64 kiB.
|
||||||
|
// When creating merkle torrents, the full hash tree is also generated
|
||||||
|
// and should be saved off separately. It is accessed through the
|
||||||
|
// create_torrent::merkle_tree() function.
|
||||||
, merkle = 2
|
, merkle = 2
|
||||||
|
|
||||||
|
// This will include the file modification time as part of the torrent.
|
||||||
|
// This is not enabled by default, as it might cause problems when you
|
||||||
|
// create a torrent from separate files with the same content, hoping to
|
||||||
|
// yield the same info-hash. If the files have different modification times,
|
||||||
|
// with this option enabled, you would get different info-hashes for the
|
||||||
|
// files.
|
||||||
, modification_time = 4
|
, modification_time = 4
|
||||||
|
|
||||||
|
// If this flag is set, files that are symlinks get a symlink attribute
|
||||||
|
// set on them and their data will not be included in the torrent. This
|
||||||
|
// is useful if you need to reconstruct a file hierarchy which contains
|
||||||
|
// symlinks.
|
||||||
, symlinks = 8
|
, symlinks = 8
|
||||||
|
|
||||||
|
// If this is set, the set_piece_hashes() function will, as it calculates
|
||||||
|
// the piece hashes, also calculate the file hashes and add those associated
|
||||||
|
// with each file. Note that unless you use the set_piece_hashes() function,
|
||||||
|
// this flag will have no effect.
|
||||||
, calculate_file_hashes = 16
|
, calculate_file_hashes = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The ``piece_size`` is the size of each piece in bytes. It must
|
||||||
|
// be a multiple of 16 kiB. If a piece size of 0 is specified, a
|
||||||
|
// piece_size will be calculated such that the torrent file is roughly 40 kB.
|
||||||
|
//
|
||||||
|
// If a ``pad_size_limit`` is specified (other than -1), any file larger than
|
||||||
|
// the specified number of bytes will be preceeded by a pad file to align it
|
||||||
|
// with the start of a piece. The pad_file_limit is ignored unless the
|
||||||
|
// ``optimize`` flag is passed. Typically it doesn't make sense to set this
|
||||||
|
// any lower than 4kiB.
|
||||||
|
//
|
||||||
|
// The overload that takes a ``torrent_info`` object will make a verbatim
|
||||||
|
// copy of its info dictionary (to preserve the info-hash). The copy of
|
||||||
|
// the info dictionary will be used by create_torrent::generate(). This means
|
||||||
|
// that none of the member functions of create_torrent that affects
|
||||||
|
// the content of the info dictionary (such as ``set_hash()``), will
|
||||||
|
// have any affect.
|
||||||
|
//
|
||||||
|
// The ``flags`` arguments specifies options for the torrent creation. It can
|
||||||
|
// be any combination of the flags defined by create_torrent::flags_t.
|
||||||
|
//
|
||||||
|
// ``alignment`` is used when pad files are enabled. This is the size eligible
|
||||||
|
// files are aligned to. The default is the default bittorrent block size of
|
||||||
|
// 16 kiB. It is common to align to the piece size of the torrent.
|
||||||
create_torrent(file_storage& fs, int piece_size = 0
|
create_torrent(file_storage& fs, int piece_size = 0
|
||||||
, int pad_file_limit = -1, int flags = optimize, int alignment = 0x4000);
|
, int pad_file_limit = -1, int flags = optimize, int alignment = 0x4000);
|
||||||
create_torrent(torrent_info const& ti);
|
create_torrent(torrent_info const& ti);
|
||||||
|
|
||||||
~create_torrent();
|
~create_torrent();
|
||||||
|
|
||||||
|
// This function will generate the .torrent file as a bencode tree. In order to
|
||||||
|
// generate the flat file, use the bencode() function.
|
||||||
|
//
|
||||||
|
// It may be useful to add custom entries to the torrent file before bencoding it
|
||||||
|
// and saving it to disk.
|
||||||
|
//
|
||||||
|
// If anything goes wrong during torrent generation, this function will return
|
||||||
|
// an empty ``entry`` structure. You can test for this condition by querying the
|
||||||
|
// type of the entry::
|
||||||
|
//
|
||||||
|
// file_storage fs;
|
||||||
|
// // add file ...
|
||||||
|
// create_torrent t(fs);
|
||||||
|
// // add trackers and piece hashes ...
|
||||||
|
// e = t.generate();
|
||||||
|
//
|
||||||
|
// if (e.type() == entry::undefined_t)
|
||||||
|
// {
|
||||||
|
// // something went wrong
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// For instance, you cannot generate a torrent with 0 files in it. If you don't add
|
||||||
|
// any files to the ``file_storage``, torrent generation will fail.
|
||||||
entry generate() const;
|
entry generate() const;
|
||||||
|
|
||||||
file_storage const& files() const { return m_files; }
|
file_storage const& files() const { return m_files; }
|
||||||
|
|
||||||
|
// Sets the comment for the torrent. The string ``str`` should be utf-8 encoded.
|
||||||
|
// The comment in a torrent file is optional.
|
||||||
void set_comment(char const* str);
|
void set_comment(char const* str);
|
||||||
|
|
||||||
|
// Sets the creator of the torrent. The string ``str`` should be utf-8 encoded.
|
||||||
|
// This is optional.
|
||||||
void set_creator(char const* str);
|
void set_creator(char const* str);
|
||||||
|
|
||||||
|
// This sets the SHA-1 hash for the specified piece (``index``). You are required
|
||||||
|
// to set the hash for every piece in the torrent before generating it. If you have
|
||||||
|
// the files on disk, you can use the high level convenience function to do this.
|
||||||
|
// See set_piece_hashes().
|
||||||
void set_hash(int index, sha1_hash const& h);
|
void set_hash(int index, sha1_hash const& h);
|
||||||
|
|
||||||
|
// This sets the sha1 hash for this file. This hash will end up under the key ``sha1``
|
||||||
|
// associated with this file (for multi-file torrents) or in the root info dictionary
|
||||||
|
// for single-file torrents.
|
||||||
void set_file_hash(int index, sha1_hash const& h);
|
void set_file_hash(int index, sha1_hash const& h);
|
||||||
|
|
||||||
|
// This adds a url seed to the torrent. You can have any number of url seeds. For a
|
||||||
|
// single file torrent, this should be an HTTP url, pointing to a file with identical
|
||||||
|
// content as the file of the torrent. For a multi-file torrent, it should point to
|
||||||
|
// a directory containing a directory with the same name as this torrent, and all the
|
||||||
|
// files of the torrent in it.
|
||||||
|
//
|
||||||
|
// The second function, ``add_http_seed()`` adds an HTTP seed instead.
|
||||||
void add_url_seed(std::string const& url);
|
void add_url_seed(std::string const& url);
|
||||||
void add_http_seed(std::string const& url);
|
void add_http_seed(std::string const& url);
|
||||||
|
|
||||||
|
// This adds a DHT node to the torrent. This especially useful if you're creating a
|
||||||
|
// tracker less torrent. It can be used by clients to bootstrap their DHT node from.
|
||||||
|
// The node is a hostname and a port number where there is a DHT node running.
|
||||||
|
// You can have any number of DHT nodes in a torrent.
|
||||||
void add_node(std::pair<std::string, int> const& node);
|
void add_node(std::pair<std::string, int> const& node);
|
||||||
|
|
||||||
|
// Adds a tracker to the torrent. This is not strictly required, but most torrents
|
||||||
|
// use a tracker as their main source of peers. The url should be an http:// or udp://
|
||||||
|
// url to a machine running a bittorrent tracker that accepts announces for this torrent's
|
||||||
|
// info-hash. The tier is the fallback priority of the tracker. All trackers with tier 0 are
|
||||||
|
// tried first (in any order). If all fail, trackers with tier 1 are tried. If all of those
|
||||||
|
// fail, trackers with tier 2 are tried, and so on.
|
||||||
void add_tracker(std::string const& url, int tier = 0);
|
void add_tracker(std::string const& url, int tier = 0);
|
||||||
|
|
||||||
|
// This function sets an X.509 certificate in PEM format to the torrent. This makes the
|
||||||
|
// torrent an *SSL torrent*. An SSL torrent requires that each peer has a valid certificate
|
||||||
|
// signed by this root certificate. For SSL torrents, all peers are connecting over SSL
|
||||||
|
// connections. For more information, see the section on ssl-torrents_.
|
||||||
|
//
|
||||||
|
// The string is not the path to the cert, it's the actual content of the certificate,
|
||||||
|
// loaded into a std::string.
|
||||||
void set_root_cert(std::string const& pem);
|
void set_root_cert(std::string const& pem);
|
||||||
|
|
||||||
|
// Sets and queries the private flag of the torrent.
|
||||||
|
// Torrents with the private flag set ask clients to not use any other
|
||||||
|
// sources than the tracker for peers, and to not advertize itself publicly,
|
||||||
|
// apart from the tracker.
|
||||||
void set_priv(bool p) { m_private = p; }
|
void set_priv(bool p) { m_private = p; }
|
||||||
|
bool priv() const { return m_private; }
|
||||||
|
|
||||||
int num_pieces() const { return m_files.num_pieces(); }
|
int num_pieces() const { return m_files.num_pieces(); }
|
||||||
int piece_length() const { return m_files.piece_length(); }
|
int piece_length() const { return m_files.piece_length(); }
|
||||||
int piece_size(int i) const { return m_files.piece_size(i); }
|
int piece_size(int i) const { return m_files.piece_size(i); }
|
||||||
bool priv() const { return m_private; }
|
|
||||||
|
|
||||||
bool should_add_file_hashes() const { return m_calculate_file_hashes; }
|
bool should_add_file_hashes() const { return m_calculate_file_hashes; }
|
||||||
|
|
||||||
|
// This function returns the merkle hash tree, if the torrent was created as a merkle
|
||||||
|
// torrent. The tree is created by ``generate()`` and won't be valid until that function
|
||||||
|
// has been called. When creating a merkle tree torrent, the actual tree itself has to
|
||||||
|
// be saved off separately and fed into libtorrent the first time you start seeding it,
|
||||||
|
// through the ``torrent_info::set_merkle_tree()`` function. From that point onwards, the
|
||||||
|
// tree will be saved in the resume data.
|
||||||
std::vector<sha1_hash> const& merkle_tree() const { return m_merkle_tree; }
|
std::vector<sha1_hash> const& merkle_tree() const { return m_merkle_tree; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -196,8 +370,24 @@ namespace libtorrent
|
||||||
, boost::uint32_t flags);
|
, boost::uint32_t flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Pred>
|
// Adds the file specified by ``path`` to the file_storage object. In case ``path``
|
||||||
void add_files(file_storage& fs, std::string const& file, Pred p, boost::uint32_t flags = 0)
|
// refers to a diretory, files will be added recursively from the directory.
|
||||||
|
//
|
||||||
|
// If specified, the predicate ``p`` is called once for every file and directory that
|
||||||
|
// is encountered. files for which ``p`` returns true are added, and directories for
|
||||||
|
// which ``p`` returns true are traversed. ``p`` must have the following signature::
|
||||||
|
//
|
||||||
|
// bool Pred(std::string const& p);
|
||||||
|
//
|
||||||
|
// The path that is passed in to the predicate is the full path of the file or
|
||||||
|
// directory. If no predicate is specified, all files are added, and all directories
|
||||||
|
// are traveresed.
|
||||||
|
//
|
||||||
|
// The ".." directory is never traversed.
|
||||||
|
//
|
||||||
|
// The ``flags`` argument should be the same as the flags passed to the `create_torrent`_
|
||||||
|
// constructor.
|
||||||
|
template <class Pred> TORRENT_EXPORT void add_files(file_storage& fs, std::string const& file, Pred p, boost::uint32_t flags = 0)
|
||||||
{
|
{
|
||||||
detail::add_files_impl(fs, parent_path(complete(file)), filename(file), p, flags);
|
detail::add_files_impl(fs, parent_path(complete(file)), filename(file), p, flags);
|
||||||
}
|
}
|
||||||
|
@ -208,6 +398,15 @@ namespace libtorrent
|
||||||
, detail::default_pred, flags);
|
, detail::default_pred, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function will assume that the files added to the torrent file exists at path
|
||||||
|
// ``p``, read those files and hash the content and set the hashes in the ``create_torrent``
|
||||||
|
// object. The optional function ``f`` is called in between every hash that is set. ``f``
|
||||||
|
// must have the following signature::
|
||||||
|
//
|
||||||
|
// void Fun(int);
|
||||||
|
//
|
||||||
|
// The overloads that don't take an ``error_code&`` may throw an exception in case of a
|
||||||
|
// file error, the other overloads sets the error code to reflect the error, if any.
|
||||||
TORRENT_EXPORT void set_piece_hashes(create_torrent& t, std::string const& p
|
TORRENT_EXPORT void set_piece_hashes(create_torrent& t, std::string const& p
|
||||||
, boost::function<void(int)> f, error_code& ec);
|
, boost::function<void(int)> f, error_code& ec);
|
||||||
inline void set_piece_hashes(create_torrent& t, std::string const& p, error_code& ec)
|
inline void set_piece_hashes(create_torrent& t, std::string const& p, error_code& ec)
|
||||||
|
|
|
@ -207,6 +207,9 @@ namespace libtorrent
|
||||||
size_type size;
|
size_type size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The ``file_storage`` class represents a file list and the piece
|
||||||
|
// size. Everything necessary to interpret a regular bittorrent storage
|
||||||
|
// file structure.
|
||||||
class TORRENT_EXPORT file_storage
|
class TORRENT_EXPORT file_storage
|
||||||
{
|
{
|
||||||
friend class torrent_info;
|
friend class torrent_info;
|
||||||
|
@ -226,8 +229,21 @@ namespace libtorrent
|
||||||
|
|
||||||
void reserve(int num_files);
|
void reserve(int num_files);
|
||||||
|
|
||||||
|
// Adds a file to the file storage. The ``flags`` argument sets attributes on the file.
|
||||||
|
// The file attributes is an extension and may not work in all bittorrent clients.
|
||||||
|
//
|
||||||
|
// For possible file attributes, see file_storage::flags_t.
|
||||||
|
//
|
||||||
|
// If more files than one are added, certain restrictions to their paths apply.
|
||||||
|
// In a multi-file file storage (torrent), all files must share the same root directory.
|
||||||
|
//
|
||||||
|
// That is, the first path element of all files must be the same.
|
||||||
|
// This shared path element is also set to the name of the torrent. It
|
||||||
|
// can be changed by calling ``set_name``.
|
||||||
|
//
|
||||||
|
// The built in functions to traverse a directory to add files will
|
||||||
|
// make sure this requirement is fulfilled.
|
||||||
void add_file(file_entry const& e, char const* filehash = 0);
|
void add_file(file_entry const& e, char const* filehash = 0);
|
||||||
|
|
||||||
void add_file(std::string const& p, size_type size, int flags = 0
|
void add_file(std::string const& p, size_type size, int flags = 0
|
||||||
, std::time_t mtime = 0, std::string const& s_p = "");
|
, std::time_t mtime = 0, std::string const& s_p = "");
|
||||||
|
|
||||||
|
@ -252,25 +268,37 @@ namespace libtorrent
|
||||||
, int size) const;
|
, int size) const;
|
||||||
peer_request map_file(int file, size_type offset, int size) const;
|
peer_request map_file(int file, size_type offset, int size) const;
|
||||||
|
|
||||||
|
#ifndef TORRENT_NO_DEPRECATE
|
||||||
|
// all functions depending on internal_file_entry
|
||||||
|
// were deprecated in 1.0. Use the variants that take an
|
||||||
|
// index instead
|
||||||
typedef std::vector<internal_file_entry>::const_iterator iterator;
|
typedef std::vector<internal_file_entry>::const_iterator iterator;
|
||||||
typedef std::vector<internal_file_entry>::const_reverse_iterator reverse_iterator;
|
typedef std::vector<internal_file_entry>::const_reverse_iterator reverse_iterator;
|
||||||
|
|
||||||
iterator file_at_offset(size_type offset) const;
|
TORRENT_DEPRECATED_PREFIX
|
||||||
iterator begin() const { return m_files.begin(); }
|
iterator file_at_offset(size_type offset) const TORRENT_DEPRECATED;
|
||||||
iterator end() const { return m_files.end(); }
|
TORRENT_DEPRECATED_PREFIX
|
||||||
reverse_iterator rbegin() const { return m_files.rbegin(); }
|
iterator begin() const TORRENT_DEPRECATED { return m_files.begin(); }
|
||||||
reverse_iterator rend() const { return m_files.rend(); }
|
TORRENT_DEPRECATED_PREFIX
|
||||||
int num_files() const
|
iterator end() const TORRENT_DEPRECATED { return m_files.end(); }
|
||||||
{ return int(m_files.size()); }
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
reverse_iterator rbegin() const TORRENT_DEPRECATED { return m_files.rbegin(); }
|
||||||
file_entry at(int index) const;
|
TORRENT_DEPRECATED_PREFIX
|
||||||
file_entry at(iterator i) const;
|
reverse_iterator rend() const TORRENT_DEPRECATED { return m_files.rend(); }
|
||||||
internal_file_entry const& internal_at(int index) const
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
internal_file_entry const& internal_at(int index) const TORRENT_DEPRECATED
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(index >= 0);
|
TORRENT_ASSERT(index >= 0);
|
||||||
TORRENT_ASSERT(index < int(m_files.size()));
|
TORRENT_ASSERT(index < int(m_files.size()));
|
||||||
return m_files[index];
|
return m_files[index];
|
||||||
}
|
}
|
||||||
|
#endif // TORRENT_NO_DEPRECATE
|
||||||
|
|
||||||
|
int num_files() const
|
||||||
|
{ return int(m_files.size()); }
|
||||||
|
|
||||||
|
file_entry at(int index) const;
|
||||||
|
file_entry at(iterator i) const;
|
||||||
|
|
||||||
size_type total_size() const { return m_total_size; }
|
size_type total_size() const { return m_total_size; }
|
||||||
void set_num_pieces(int n) { m_num_pieces = n; }
|
void set_num_pieces(int n) { m_num_pieces = n; }
|
||||||
|
@ -302,28 +330,74 @@ namespace libtorrent
|
||||||
// not add any padding
|
// not add any padding
|
||||||
void optimize(int pad_file_limit = -1, int alignment = 0x10000);
|
void optimize(int pad_file_limit = -1, int alignment = 0x10000);
|
||||||
|
|
||||||
|
// These functions are used to query attributes of files at
|
||||||
|
// a given index.
|
||||||
|
//
|
||||||
|
// The ``file_hash()`` is a sha-1 hash of the file, or 0 if none was
|
||||||
|
// provided in the torrent file. This can potentially be used to
|
||||||
|
// join a bittorrent network with other file sharing networks.
|
||||||
|
//
|
||||||
|
// The ``mtime()`` is the modification time is the posix
|
||||||
|
// time when a file was last modified when the torrent
|
||||||
|
// was created, or 0 if it was not included in the torrent file.
|
||||||
|
//
|
||||||
|
// ``file_path()`` returns the full path to a file.
|
||||||
|
//
|
||||||
|
// ``file_size()`` returns the size of a file.
|
||||||
|
//
|
||||||
|
// ``pad_file_at()`` returns true if the file at the given
|
||||||
|
// index is a pad-file.
|
||||||
|
//
|
||||||
|
// ``file_name()`` returns *just* the name of the file, whereas
|
||||||
|
// ``file_path()`` returns the path (inside the torrent file) with
|
||||||
|
// the filename appended.
|
||||||
|
//
|
||||||
|
// ``file_offset()`` returns the byte offset within the torrent file
|
||||||
|
// where this file starts. It can be used to map the file to a piece
|
||||||
|
// index (given the piece size).
|
||||||
sha1_hash hash(int index) const;
|
sha1_hash hash(int index) const;
|
||||||
std::string const& symlink(int index) const;
|
std::string const& symlink(int index) const;
|
||||||
time_t mtime(int index) const;
|
time_t mtime(int index) const;
|
||||||
size_type file_base(int index) const;
|
|
||||||
void set_file_base(int index, size_type off);
|
|
||||||
std::string file_path(int index, std::string const& save_path = "") const;
|
std::string file_path(int index, std::string const& save_path = "") const;
|
||||||
std::string file_name(int index) const;
|
std::string file_name(int index) const;
|
||||||
size_type file_size(int index) const;
|
size_type file_size(int index) const;
|
||||||
bool pad_file_at(int index) const;
|
bool pad_file_at(int index) const;
|
||||||
size_type file_offset(int index) const;
|
size_type file_offset(int index) const;
|
||||||
|
|
||||||
sha1_hash hash(internal_file_entry const& fe) const;
|
// The file base of a file is the offset within the file on the filsystem
|
||||||
std::string const& symlink(internal_file_entry const& fe) const;
|
// where it starts to write. For the most part, this is always 0. It's
|
||||||
time_t mtime(internal_file_entry const& fe) const;
|
// possible to map several files (in the torrent) into a single file on
|
||||||
int file_index(internal_file_entry const& fe) const;
|
// the filesystem by making them all point to the same filename, but with
|
||||||
size_type file_base(internal_file_entry const& fe) const;
|
// different file bases, so that they don't overlap.
|
||||||
void set_file_base(internal_file_entry const& fe, size_type off);
|
// torrent_info::remap_files() can be used to use a new file layout.
|
||||||
std::string file_path(internal_file_entry const& fe, std::string const& save_path = "") const;
|
size_type file_base(int index) const;
|
||||||
std::string file_name(internal_file_entry const& fe) const;
|
void set_file_base(int index, size_type off);
|
||||||
size_type file_size(internal_file_entry const& fe) const;
|
|
||||||
bool pad_file_at(internal_file_entry const& fe) const;
|
#ifndef TORRENT_NO_DEPRECATE
|
||||||
size_type file_offset(internal_file_entry const& fe) const;
|
// these were deprecated in 1.0. Use the versions that take an index instead
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
sha1_hash hash(internal_file_entry const& fe) const TORRENT_DEPRECATED;
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
std::string const& symlink(internal_file_entry const& fe) const TORRENT_DEPRECATED;
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
time_t mtime(internal_file_entry const& fe) const TORRENT_DEPRECATED;
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
int file_index(internal_file_entry const& fe) const TORRENT_DEPRECATED;
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
size_type file_base(internal_file_entry const& fe) const TORRENT_DEPRECATED;
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
void set_file_base(internal_file_entry const& fe, size_type off) TORRENT_DEPRECATED;
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
std::string file_path(internal_file_entry const& fe, std::string const& save_path = "") const TORRENT_DEPRECATED;
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
std::string file_name(internal_file_entry const& fe) const TORRENT_DEPRECATED;
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
size_type file_size(internal_file_entry const& fe) const TORRENT_DEPRECATED;
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
bool pad_file_at(internal_file_entry const& fe) const TORRENT_DEPRECATED;
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
size_type file_offset(internal_file_entry const& fe) const TORRENT_DEPRECATED;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined TORRENT_VERBOSE_LOGGING \
|
#if !defined TORRENT_VERBOSE_LOGGING \
|
||||||
&& !defined TORRENT_LOGGING \
|
&& !defined TORRENT_LOGGING \
|
||||||
|
|
|
@ -478,6 +478,7 @@ namespace libtorrent
|
||||||
return m_files[index].offset;
|
return m_files[index].offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TORRENT_NO_DEPRECATE
|
||||||
sha1_hash file_storage::hash(internal_file_entry const& fe) const
|
sha1_hash file_storage::hash(internal_file_entry const& fe) const
|
||||||
{
|
{
|
||||||
int index = &fe - &m_files[0];
|
int index = &fe - &m_files[0];
|
||||||
|
@ -551,6 +552,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
return fe.offset;
|
return fe.offset;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool compare_file_entry_size(internal_file_entry const& fe1, internal_file_entry const& fe2)
|
bool compare_file_entry_size(internal_file_entry const& fe1, internal_file_entry const& fe2)
|
||||||
{ return fe1.size < fe2.size; }
|
{ return fe1.size < fe2.size; }
|
||||||
|
|
Loading…
Reference in New Issue