void Reconstructor::reconstructSession(Session *s) { // We get one monolithic file from a session. If we have the torrent file // we can break it up, otherwise the user will have to do it manually, as we // don't have that information. File file; Torrent *torrent = NULL; // Hold the torrent for this session if we have it ip_piece_map_t pieces = s->getPieces(); std::map<std::string, Peer> peers = s->getPeers(); std::map<std::string, Peer>::iterator it; std::vector<unsigned int>::iterator uit; char hash_string[42]; unsigned char temp_hash[20]; // std::cout.rdbuf((*(this->ohandle)).rdbuf()); // Output statistics // Make it easier to differentiate between different sessions in output std::cout << "****************************************" << std::endl; std::cout << "Processing a new BitTorrent session" << std::endl; std::cout << "SHA-1 Info Hash: " << std::endl << "\t"; const char *h = s->getHash().data(); for (int i = 0; i < 20; i++) printf("%x", (unsigned char)h[i]); std::cout << std::endl; // Build up our file from the session pieces ip_piece_map_t::iterator m, me; std::vector<Piece*>::iterator p, pe; for (m = pieces.begin(), me = pieces.end(); m != me; ++m) { for (p = m->second.begin(), pe = m->second.end(); p != pe; ++p) { if (not (*p)->isValid()) { assert(0 && "Should never have an invalid piece here"); } file.addPiece(*p); } } std::cout << "Peers: " << std::endl; //output ip:port for each peer for (it = peers.begin(); it != peers.end(); it++) { //Only print out active peers if (it->second.active) { std::cout << "\t" << it->second.ip << ":" << it->second.port << std::endl; } } //output upload statistics(if any) for (uit = s->getUploadedIndices().begin(); uit != s->getUploadedIndices().end(); uit++) { std::cout << "Uploaded part of piece index " << *uit << std::endl; } std::vector<Torrent*>::iterator i, ie; for (i = this->m_torrents.begin(), ie = this->m_torrents.end(); i != ie; ++i) { // if ((*i)->info_hash() == s->getHash().data()) { if (compare_sha1s((const unsigned char *)(*i)->info_hash().data(), (const unsigned char *)s->getHash().data())) { torrent = *i; } } file.reconstructFile(torrent); if (torrent == NULL) { // We still want to output, just no verification. Refactor this ASAP // Name the file after its checksum const unsigned char *data = (const unsigned char*) file.contents().data(); SHA1(data, file.contents().length(), temp_hash); //FIXME This is disgusting snprintf(hash_string, 42, "%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x", (unsigned char)temp_hash[0], (unsigned char)temp_hash[1], (unsigned char)temp_hash[2], (unsigned char)temp_hash[3], (unsigned char)temp_hash[4], (unsigned char)temp_hash[5], (unsigned char)temp_hash[6], (unsigned char)temp_hash[7], (unsigned char)temp_hash[8], (unsigned char)temp_hash[9], (unsigned char)temp_hash[10], (unsigned char)temp_hash[11], (unsigned char)temp_hash[12], (unsigned char)temp_hash[13], (unsigned char)temp_hash[14], (unsigned char)temp_hash[15], (unsigned char)temp_hash[16], (unsigned char)temp_hash[17], (unsigned char)temp_hash[18], (unsigned char)temp_hash[19]); file.name(hash_string); std::cout << "Output filename: " << hash_string << std::endl; // We get file. How are you gentlemen? Output me to your base. std::cout << "Reconstructed file size: " << file.writeFile(0, std::string::npos) << " bytes." << std::endl; return; } // Break up files here unsigned int file_offset = 0; std::vector<unsigned int> v = torrent->file_lengths(); for (unsigned int i=0; i < v.size(); ++i) { std::string curr_file = file.contents().substr(file_offset, v.at(i)); // Name the file after its checksum const unsigned char *data = (const unsigned char*) curr_file.data(); SHA1(data, curr_file.length(), temp_hash); //FIXME This is disgusting snprintf(hash_string, 42, "%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x", (unsigned char)temp_hash[0], (unsigned char)temp_hash[1], (unsigned char)temp_hash[2], (unsigned char)temp_hash[3], (unsigned char)temp_hash[4], (unsigned char)temp_hash[5], (unsigned char)temp_hash[6], (unsigned char)temp_hash[7], (unsigned char)temp_hash[8], (unsigned char)temp_hash[9], (unsigned char)temp_hash[10], (unsigned char)temp_hash[11], (unsigned char)temp_hash[12], (unsigned char)temp_hash[13], (unsigned char)temp_hash[14], (unsigned char)temp_hash[15], (unsigned char)temp_hash[16], (unsigned char)temp_hash[17], (unsigned char)temp_hash[18], (unsigned char)temp_hash[19]); file.name(hash_string); std::cout << "Output filename: " << hash_string << std::endl; // We get file. How are you gentlemen? Output me to your base. std::cout << "Reconstructed file size: " << file.writeFile(file_offset, v.at(i)) << " bytes." << std::endl; file_offset += v.at(i); } }