void TorrentDownloader::DoWriteResumeData(boost::shared_ptr<entry> resume_data){
	syslog(LOG_DEBUG,"Do write resume data");

	if(!this->handle.is_valid()){
		syslog(LOG_NOTICE,"Handle not valid, not writing resume data");
		return;
	}

	// Find directory to write to
	string wp="/home/"+User::UIDToUser(this->user);
	string suf="/"+FtdConfig::Instance().GetStringOrDefault("torrent","resumepath","torrents/.resumedata");

	if(!Stat::DirExists(wp+suf)){
		syslog(LOG_INFO,"Creating resume data directory");
		FileUtils::MkPath(wp+suf);
		FileUtils::Chown(wp+suf,this->user,"users");
	}
	this->resumefilename=wp+suf+"/"+StringTools::GetFileName(this->torrentfilename)+".resume";
	ofstream of(this->resumefilename.c_str(),ios::trunc|ios::out);
	ostream_iterator<char> ofIt(of);
	bencode(ofIt,*resume_data);
	of.close();
	FileUtils::Chown(this->resumefilename,this->user,"users");


}
Example #2
0
void request_handler::reply_bencoded(Result& res, libtorrent::entry::dictionary_type &dict)
{
    try
    {
        std::stringstream st;
        bencode(std::ostream_iterator<char>(st), dict);
        const std::string& str = st.str();

        reply rep;

        rep.status = reply::ok;
        rep.content.append(str);
        rep.headers.resize(4);
        rep.headers[0].name = "Content-Length";
        rep.headers[0].value = boost::lexical_cast<std::string>((unsigned int)str.length());
        rep.headers[1].name = "Content-Type";
        rep.headers[1].value = "text/plain";
        rep.headers[2].name = "X-Server";
        rep.headers[2].value = _hostname;
        rep.headers[3].name = "X-CPU";
        rep.headers[3].value = string_format("%.2f", _cpu_monitor.get_cpu_percent());

        res.finished(rep);
    }
    catch (std::exception& e)
    {
        logger << "Exception preparing response: " << e.what() << std::endl;
        res.finished(reply::stock_reply(reply::internal_server_error));
    }
    catch (...)
    {
        logger << "Critical exception preparing response!" << std::endl;
        res.finished(reply::stock_reply(reply::internal_server_error));
    }
}
void save_settings::save(error_code& ec) const
{
	// back-up current settings file as .bak before saving the new one
	std::string backup = m_settings_file + ".bak";
	bool has_settings = exists(m_settings_file);
	bool has_backup = exists(backup);

	if (has_settings && has_backup)
		remove(backup, ec);

	if (has_settings)
		rename(m_settings_file, backup, ec);

	ec.clear();

	entry sett;
	m_ses.save_state(sett);

	for (std::map<std::string, int>::const_iterator i = m_ints.begin()
		, end(m_ints.end()); i != end; ++i)
	{
		sett[i->first] = i->second;
	}

	for (std::map<std::string, std::string>::const_iterator i = m_strings.begin()
		, end(m_strings.end()); i != end; ++i)
	{
		sett[i->first] = i->second;
	}
	std::vector<char> buf;
	bencode(std::back_inserter(buf), sett);
	save_file(m_settings_file, buf, ec);
}
Example #4
0
	void session::load_state(entry const& ses_state)
	{
		std::vector<char> buf;
		bencode(std::back_inserter(buf), ses_state);
		lazy_entry e;
		error_code ec;
		int ret = lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec);
		TORRENT_ASSERT(ret == 0);
		TORRENT_SYNC_CALL1(load_state, &e);
	}
Example #5
0
void item::assign(entry v, span<char const> salt
	, sequence_number const seq, public_key const& pk, secret_key const& sk)
{
	char buffer[1000];
	int bsize = bencode(buffer, v);
	TORRENT_ASSERT(bsize <= 1000);
	m_sig = sign_mutable_item(span<char const>(buffer, bsize)
		, salt, seq, pk, sk);
	m_salt.assign(salt.data(), salt.size());
	m_pk = pk;
	m_seq = seq;
	m_mutable = true;
	m_value = std::move(v);
}
Example #6
0
	void session::load_state(entry const& ses_state)
	{
		if (ses_state.type() == entry::undefined_t) return;
		std::vector<char> buf;
		bencode(std::back_inserter(buf), ses_state);
		lazy_entry e;
		error_code ec;
		int ret = lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec);
		TORRENT_ASSERT(ret == 0);
#ifndef BOOST_NO_EXCEPTIONS
		if (ret != 0) throw libtorrent_exception(ec);
#endif
		TORRENT_SYNC_CALL1(load_state, &e);
	}
Example #7
0
	void session::load_state(entry const& ses_state)
	{
		if (ses_state.type() == entry::undefined_t) return;
		std::vector<char> buf;
		bencode(std::back_inserter(buf), ses_state);
		lazy_entry e;
		error_code ec;
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
		int ret =
#endif
		lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec);

		TORRENT_ASSERT(ret == 0);
		TORRENT_SYNC_CALL1(load_state, &e);
	}
Example #8
0
void dht_tracker::put_item(entry const& data
                           , std::function<void(int)> cb)
{
    std::string flat_data;
    bencode(std::back_inserter(flat_data), data);
    sha1_hash const target = item_target_id(flat_data);

    auto ctx = std::make_shared<put_item_ctx>((TORRENT_USE_IPV6) ? 2 : 1);
    m_dht.put_item(target, data, std::bind(&put_immutable_item_callback
                                           , _1, ctx, cb));
#if TORRENT_USE_IPV6
    m_dht6.put_item(target, data, std::bind(&put_immutable_item_callback
                                            , _1, ctx, cb));
#endif
}
void TorrentDownloadManager::Shutdown(){
	this->isRunning=false;
	DirWatcher::Instance().Stop();
	FtdConfig& cfg=FtdConfig::Instance();

	if(cfg.GetBoolOrDefault("torrent","dhtsupport",false)){
		string stpath=cfg.GetStringOrDefault("general","statedir","/etc/ftd");
		if(Stat::DirExists(stpath)){
			entry e=this->s.dht_state();
			vector<char> buffer;
			bencode(std::back_inserter(buffer),e);
			fstream of(string(stpath+"/dhtstate").c_str(),fstream::out|fstream::binary);
			ostream_iterator<char> oI(of);
			copy(buffer.begin(),buffer.end(),oI);
			of.close();
		}
	}
}
Example #10
0
void item::assign(entry const& v, std::pair<char const*, int> salt
                  , boost::uint64_t seq, char const* pk, char const* sk)
{
    m_value = v;
    if (pk && sk)
    {
        char buffer[1000];
        int bsize = bencode(buffer, v);
        TORRENT_ASSERT(bsize <= 1000);
        sign_mutable_item(std::make_pair(buffer, bsize)
                          , salt, seq, pk, sk, m_sig.c_array());
        m_salt.assign(salt.first, salt.second);
        memcpy(m_pk.c_array(), pk, item_pk_len);
        m_seq = seq;
        m_mutable = true;
    }
    else
        m_mutable = false;
}
	// if the torrent already exists, this will throw duplicate_torrent
	torrent_handle session::add_torrent(
		torrent_info const& ti
		, std::string const& save_path
		, entry const& resume_data
		, storage_mode_t storage_mode
		, bool paused
		, storage_constructor_type sc)
	{
		boost::intrusive_ptr<torrent_info> tip(new torrent_info(ti));
		add_torrent_params p(sc);
		p.ti = tip;
		p.save_path = save_path;
		if (resume_data.type() != entry::undefined_t)
		{
			bencode(std::back_inserter(p.resume_data), resume_data);
		}
		p.storage_mode = storage_mode;
		p.paused = paused;
		return add_torrent(p);
	}
Example #12
0
	uTorrentParser::uTorrentParser(entry const& torrent_file)
		: torrent_info(m_info_hash)
	{
		std::vector<char> tmp;
		std::back_insert_iterator<std::vector<char> > out(tmp);
		bencode(out, torrent_file);

		lazy_entry e;
		if (tmp.size() == 0 || lazy_bdecode(&tmp[0], &tmp[0] + tmp.size(), e) != 0)
		{
#ifndef BOOST_NO_EXCEPTIONS
			throw invalid_torrent_file(errors::invalid_bencoding);
#endif
			return;
		}
		error_code ec;
#ifndef BOOST_NO_EXCEPTIONS
		if (!parse_torrent_file(e, ec))
			throw invalid_torrent_file(ec);
#else
		parse_torrent_file(e, ec);
#endif
	}
Example #13
0
	torrent_handle session::add_torrent(
		boost::intrusive_ptr<torrent_info> ti
		, std::string const& save_path
		, entry const& resume_data
		, storage_mode_t storage_mode
		, bool paused
		, storage_constructor_type sc
		, void* userdata)
	{
		add_torrent_params p(sc);
		p.ti = ti;
		p.save_path = save_path;
		std::vector<char> buf;
		if (resume_data.type() != entry::undefined_t)
		{
			bencode(std::back_inserter(buf), resume_data);
			p.resume_data = &buf;
		}
		p.storage_mode = storage_mode;
		p.paused = paused;
		p.userdata = userdata;
		return add_torrent(p);
	}
Example #14
0
bool dht_tracker::send_packet(entry& e, udp::endpoint const& addr)
{
    static char const version_str[] = {'L', 'T'
                                       , LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR
                                      };
    e["v"] = std::string(version_str, version_str + 4);

    m_send_buf.clear();
    bencode(std::back_inserter(m_send_buf), e);

    // update the quota. We won't prevent the packet to be sent if we exceed
    // the quota, we'll just (potentially) block the next incoming request.

    m_send_quota -= int(m_send_buf.size());

    error_code ec;
    m_send_fun(addr, m_send_buf, ec, 0);
    if (ec)
    {
        m_counters.inc_stats_counter(counters::dht_messages_out_dropped);
#ifndef TORRENT_DISABLE_LOGGING
        m_log->log_packet(dht_logger::outgoing_message, m_send_buf, addr);
#endif
        return false;
    }

    m_counters.inc_stats_counter(counters::dht_bytes_out, m_send_buf.size());
    // account for IP and UDP overhead
    m_counters.inc_stats_counter(counters::sent_ip_overhead_bytes
                                 , addr.address().is_v6() ? 48 : 28);
    m_counters.inc_stats_counter(counters::dht_messages_out);
#ifndef TORRENT_DISABLE_LOGGING
    m_log->log_packet(dht_logger::outgoing_message, m_send_buf, addr);
#endif
    return true;
}
Example #15
0
	bool make( std::string target_file, std::string outfile
		, ErrorHandler error_handler
		, ProgressHandler print_progress
		, std::vector<std::string> const & web_seeds, std::vector<std::string> & trackers
		, bool use_merklefile /*= false*/, std::string root_cert /*= ""*/
		, int pad_file_limit /*= -1*/, int piece_size /*= 0*/, bool inc_sha1_hash /*= true*/
		, bool dont_follow_symlinks /*= false*/ )
	{
		char const* creator_str = "libtorrent";

		int flags = 0;

#ifndef BOOST_NO_EXCEPTIONS
		try
		{
#endif
			std::string merklefile;

			if( use_merklefile )
			{
				merklefile = outfile + "_mkl";
				flags |= create_torrent::merkle;
			}

			if( inc_sha1_hash )
			{
				flags |= create_torrent::calculate_file_hashes;
			}

			if( pad_file_limit > 0 )
			{
				flags |= create_torrent::optimize;
			}

			if( dont_follow_symlinks )
			{
				flags |= create_torrent::symlinks;
			}

			if( trackers.empty() )
			{
				trackers.push_back( "udp://tracker.openbittorrent.com:80/announce" );
				trackers.push_back( "udp://tracker.publicbt.com:80/announce" );
			}

			file_storage fs;
			file_pool fp;
			std::string full_path = libtorrent::complete( target_file );

			add_files(fs, full_path, [](std::string const& f)->bool
			{
				if (filename(f)[0] == '.') return false;
				//fprintf(stderr, "%s\n", f.c_str());
				return true;
			}
			, flags);

			if (fs.num_files() == 0)
			{
				error_handler( 0, "no target files specified.\n" );
				return false;
			}

			create_torrent t(fs, piece_size, pad_file_limit, flags);

			int tracker_count = 0;

			for (auto i = trackers.begin(); i != trackers.end(); ++i)
				t.add_tracker(*i, tracker_count++);

			for (auto i = web_seeds.begin(); i != web_seeds.end(); ++i)
			{
				//if( i->find( "http" ) == 0 )
				//	t.add_http_seed(*i);
				//else
				t.add_url_seed(*i);
			}

			error_code ec;
			set_piece_hashes(t, parent_path(full_path)
				, boost::bind(print_progress, _1, t.num_pieces()), ec);

			if (ec)
			{
				error_handler( 1, ec.message().c_str() );
				return false;
			}

			t.set_creator(creator_str);

			if (!root_cert.empty())
			{
				std::vector<char> pem;
				load_file(root_cert, pem, ec, 10000);
				if (ec)
				{
					error_handler( 2, (ec.message() + ": failed to load root certificate for tracker.").c_str() );
					return false;
				}
				else
				{
					t.set_root_cert(std::string(&pem[0], pem.size()));
				}
			}

			// create the torrent and print it to stdout
			std::vector<char> torrent;
			bencode(back_inserter(torrent), t.generate());
			FILE* output = stdout;
			if (!outfile.empty())
				output = fopen(outfile.c_str(), "wb+");
			fwrite(&torrent[0], 1, torrent.size(), output);

			if (output != stdout)
				fclose(output);

			if (!merklefile.empty())
			{
				output = fopen(merklefile.c_str(), "wb+");
				int ret = fwrite(&t.merkle_tree()[0], 20, t.merkle_tree().size(), output);
				if (ret != t.merkle_tree().size() * 20)
				{
					error_handler( 3, (merklefile + " : failed to write.").c_str() );
					fclose(output);
					return false;
				}				
			}

			fclose(output);

#ifndef BOOST_NO_EXCEPTIONS
		}
		catch (std::exception& e)
		{
			error_handler( 4, e.what() );
			return false;
		}
#endif
		return true;
	}
Example #16
0
/*  AppendBinary - append the passed source file to the passed dest file
 *
 *  arguments:
 *      pSrcName          pointer to name of the source file
 *      pDestName         pointer to name of the destination file
 *      pNonTempDestName  pointer to filename to use as uuencoded name
 *
 *  return value:
 *      FALSE (0)   no errors occured during append
 *      TRUE (-1)   error during append
 *
 *  IMPORTANT:
 *      AppendBinary ( ) assumes the files pSrcName and pDestName are not
 *      currently open.
 *
 * INFORMATION:
 *
 *      If UUCODE is defined, AppendBinary() will produce
 *      an encoded output file that has the format:
 *
 *         #<begin uuencode>
 *         begin OCTAL_ATTR FILE_NAME
 *         UUENCODED_DATA
 *         end
 *         #<end uuencode>
 *
 *      where OCTAL is the file attribute, FILE_NAME is the file
 *      name (the basename of the source file, since the target file
 *      is a temporary file), and UUENCODED_DATA is the actual file
 *      data, uuencoded. If UUCODE is NOT defined, the older method
 *      of encoding the output file will produce:
 *
 *         #<binary data>
 *         BENCODED_DATA
 *         #<end>
 *
 *      where BENCODED_DATA is the actual file data, encoded.
 *
 */
FLAG PASCAL INTERNAL AppendBinary ( PSTR pSrcName, PSTR pDestName )
{

#if defined(UUCODE)

    /* NOTE: This is the post-1.10-73 version, which uses UUCODE.C
     * rather than BENCODE.C to do the binary encoding. */

    FLAG     retVal = FALSE;     /* optimistic default (no errors) */
    INT fhSrc;                   /* source file name */
    INT fhDest;                  /* destination binary file name */
    CHAR szT[80];                /* buffer for binary header/footer */
    CHAR szBasename[_MAX_FNAME]; /* component of pSrcName's filename */
    CHAR szDrive[_MAX_DRIVE];    /* component of pSrcName's filename: UNUSED */
    CHAR szDir[_MAX_DIR];        /* component of pSrcName's filename: UNUSED */
    CHAR szExtension[_MAX_EXT];  /* component of pSrcName's filename */
    static CHAR szErrCloseSrc[]   = "can't close binary source file %s\n";
    static CHAR szErrCloseDest[]  = "can't close binary target file %s\n";
    static CHAR szErrHeader[]     = "can't write header to binary target file %s\n";

    /* a few reality-checking assertions... */
    assert(("AppendBinary(): NULL source file", pSrcName != (PSTR )NULL));
    assert(("AppendBinary(): NULL target file", pDestName != (PSTR )NULL));

    /* attempt to open the source file handle */
    if ((fhSrc = open(pSrcName, O_RDONLY | O_BINARY, S_IREAD)) == -1)
    {
        perror(pSrcName);
        return (TRUE); /* return indication of failure */
    }

    /* open the destination file */
    if ((fhDest = open(pDestName, O_WRONLY | O_APPEND, S_IREAD)) == -1)
    {
        perror(pDestName);
        if (close(fhSrc) != 0)  /* close the source file */
        {
            (VOID)fprintf(stderr, szErrCloseSrc, pSrcName);
        }
        return (TRUE); /* return indication of failure */
    }

    /* write encoded "header" (wzmail+uuencode) information */
    _splitpath(pSrcName, szDrive, szDir, szBasename, szExtension);
    sprintf(szT, "%s\nbegin %o %s%s\n",
                strBEGINBINARY, 0666, szBasename, szExtension);
    if ((size_t)(write(fhDest, szT, strlen(szT))) != strlen(szT))
    {
        fprintf(stderr, szErrHeader, pDestName);
        if (close(fhSrc) != 0)  /* close the source file */
        {
            fprintf(stderr, szErrCloseSrc, pSrcName);
        }
        if (close(fhDest) != 0)  /* close the target file */
        {
            fprintf(stderr, szErrCloseDest, pDestName);
        }
        return (TRUE); /* return indication of failure */
    }

    /* uuencode the target file */
    Encode(fhSrc, fhDest); /* (see uucode.c) */

    /* write encoded "footer" (wzmail+uuencode) information */
    sprintf(szT, "end\n%s\n", strENDBINARY);
    if ((size_t)(write(fhDest, szT, strlen(szT))) != strlen(szT))
    {
        fprintf(stderr, szErrHeader, pDestName);
        retVal = TRUE; /* set failure indication */
        /* fall through to normal source/target fclosing code... */
    }

    /* close the source file */
    if (close(fhSrc) != 0)
    {
        fprintf(stderr, szErrCloseSrc, pSrcName);
        retVal = TRUE; /* set failure indication */
        /* fall through to normal target fclosing code... */
    }

    /* close the destination file */
    if (close(fhDest) != 0)
    {
        fprintf(stderr, szErrCloseDest, pDestName);
        retVal = TRUE; /* set failure indication */
        /* fall through to normal function return... */
    }

    return (retVal); /* return status code to calling function */

#else /* UUCODE */

    /* NOTE: This is the pre-1.10-73 version, which uses BENCODE.C
     * rather than UUCODE.C to do the binary encoding. */

    FLAG        retVal = TRUE;
    FILE        * fpDest = NULL;
    CHAR        line [ ENCBFSIZE + 1], encode [ ( 4 * ENCBFSIZE / 3 ) + 2 ];
    INT         hSrc;
    INT         cnt;

    hSrc = open ( pSrcName, O_RDONLY | O_BINARY, S_IREAD );
    fpDest = fopen ( pDestName, "a" );
    if ( ( hSrc != -1 ) && ( fpDest ) ) {
        fprintf ( fpDest, "\n%s\n", strBEGINBINARY );
        while ( !( eof ( hSrc ) ) ) {
            cnt = bencode ( line, encode, read ( hSrc, line, ENCBFSIZE ) );
            encode [ cnt++ ] = '\n';
            encode [ cnt ] = '\0';
            fputs ( encode, fpDest );
        }
        fprintf ( fpDest, "%s\n", strENDBINARY );
        retVal = FALSE;
    }
    if ( hSrc != -1 )
        close ( hSrc );
    if ( fpDest )
        fclose ( fpDest );

    return retVal;

#endif /* UUCODE */

}