X-Git-Url: https://feistymeow.org/gitweb/?a=blobdiff_plain;f=octopi%2Flibrary%2Ftentacles%2Ffile_transfer_tentacle.cpp;fp=octopi%2Flibrary%2Ftentacles%2Ffile_transfer_tentacle.cpp;h=60bb2d6fc7a3533f84bae5f64a0471445d9007da;hb=c93ddbe5db0e3295f90f12685f96d86a060f4cd0;hp=50cc5114b5ea97b1499d48e30d10417d868d6434;hpb=73cd7fe4642606a3f691122bc92ff342cdfedca5;p=feisty_meow.git diff --git a/octopi/library/tentacles/file_transfer_tentacle.cpp b/octopi/library/tentacles/file_transfer_tentacle.cpp index 50cc5114..60bb2d6f 100644 --- a/octopi/library/tentacles/file_transfer_tentacle.cpp +++ b/octopi/library/tentacles/file_transfer_tentacle.cpp @@ -47,7 +47,7 @@ const int FTT_CLEANING_INTERVAL = 30 * SECOND_ms; const int TRANSFER_TIMEOUT = 10 * MINUTE_ms; // if it hasn't been touched in this long, it's out of there. -#define DEBUG_FILE_TRANSFER_TENTACLE +//#define DEBUG_FILE_TRANSFER_TENTACLE // uncomment for noisier version. #undef LOG @@ -460,6 +460,100 @@ outcome file_transfer_tentacle::reconstitute(const string_array &classifier, // the "handle_" and "conclude_" methods are thread-safe because the mutex is locked before // their invocations. +basis::outcome file_transfer_tentacle::handle_build_target_tree_request(file_transfer_infoton &req, + const octopus_request_id &item_id) +{ + FUNCDEF("handle_build_target_tree_request"); + + // get the mapping from the specified location on this side. + filename splitting(req._src_root); + string_array pieces; + bool rooted; + splitting.separate(rooted, pieces); + astring source_mapping = pieces[0]; + + // patch the name up to find the sub_path for the source. + filename source_start; + pieces.zap(0, 0); + source_start.join(rooted, pieces); + + // locate the allowed transfer depot for the mapping they provided. + file_transfer_record *mapping_record = _correspondences->find_mapping(source_mapping); + if (!mapping_record) { + LOG(astring("could not find source mapping of ") + source_mapping); + return NOT_FOUND; + } + + // unpack the tree that they sent us which describes their local area. + directory_tree *dest_tree = new directory_tree; + if (!dest_tree->unpack(req._packed_data)) { + LOG(astring("could not unpack requester's directory tree")); + WHACK(dest_tree); + return GARBAGE; + } + + string_array requested_names; + if (!requested_names.unpack(req._packed_data)) { + LOG(astring("could not unpack requester's filename includes")); + WHACK(dest_tree); + return GARBAGE; + } + + // look up to see if this is about something that has already been seen. + // we don't want to add a new transfer record if they're already working on + // this. that also lets them do a new tree compare to restart the transfer. + file_transfer_record *the_rec = _transfers->find(item_id._entity, + req._src_root, req._dest_root); + if (!the_rec) { + // there was no existing record; we'll create a new one. + the_rec = new file_transfer_record; + the_rec->_ent = item_id._entity; + the_rec->_src_root = req._src_root; + the_rec->_dest_root = req._dest_root; + _transfers->append(the_rec); + } else { + // record some activity on this record. + the_rec->_done = false; + the_rec->_last_active.reset(); + } + + // create any directories that are missing at this point. + basis::outcome result = dest_tree->make_directories(req._dest_root); + if (result != common::OKAY) { + LOG("ERROR: got bad result from make_directories!"); + } + + req._packed_data.reset(); // clear out existing stuff before cloning. + file_transfer_infoton *reply = dynamic_cast(req.clone()); + + reply->_request = false; // it's a response now. + reply->_success = result; + store_product(reply, item_id); + // send back the comparison list. + + return OKAY; +} + +basis::outcome file_transfer_tentacle::handle_build_target_tree_response(file_transfer_infoton &resp, + const octopus_request_id &item_id) +{ +//go to next step, tree comparison. +//look at the handle tree compare response for help though. + FUNCDEF("handle_build_target_tree_response"); + file_transfer_record *the_rec = _transfers->find(item_id._entity, + resp._src_root, resp._dest_root); + if (!the_rec) { + LOG(astring("could not find the record for this transfer: item=") + + item_id.text_form() + " src=" + resp._src_root + " dest=" + + resp._dest_root); + return NOT_FOUND; // not registered, so reject it. + } + + the_rec->_last_active.reset(); // record some activity on this record. + + return resp._success; +} + outcome file_transfer_tentacle::handle_tree_compare_request (file_transfer_infoton &req, const octopus_request_id &item_id) { @@ -542,7 +636,6 @@ outcome file_transfer_tentacle::handle_tree_compare_request filename req_curr(requested_names[j]); if (req_curr.compare_suffix(diff_curr)) { found = true; -//LOG(astring("will use: ") + req_curr); break; } } @@ -559,13 +652,9 @@ outcome file_transfer_tentacle::handle_tree_compare_request // before the client starts the transfer. reply->_request = false; // it's a response now. -LOG("storing product from transfer processing"); store_product(reply, item_id); // send back the comparison list. -LOG("now showing bin before return:"); -LOG(get_storage()->text_form()); - return OKAY; } @@ -705,7 +794,7 @@ outcome file_transfer_tentacle::handle_storage_response astring full_file = resp._dest_root + filename::default_separator() + recorded_info->secondary(); -LOG(astring("telling it to write to fullfile: ") + full_file); +//LOG(astring("telling it to write to fullfile: ") + full_file); outcome ret = heavy_file_operations::write_file_chunk(full_file, found._byte_start, to_write); @@ -798,6 +887,10 @@ outcome file_transfer_tentacle::consume(infoton &to_chow, AUTO_LOCK; // protect our lists while we're working on them. switch (inf->_command) { + case file_transfer_infoton::BUILD_TARGET_TREE: { + if (inf->_request) return handle_build_target_tree_request(*inf, item_id); + else return handle_build_target_tree_response(*inf, item_id); + } case file_transfer_infoton::TREE_COMPARISON: { if (inf->_request) return handle_tree_compare_request(*inf, item_id); else return handle_tree_compare_response(*inf, item_id);