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"); }
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); }
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); }
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); }
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); }
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); }
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(); } } }
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); }
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 }
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); }
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; }
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; }
/* 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 */ }