recursive_file_copy.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "file_transfer_infoton.h"
00016 #include "file_transfer_tentacle.h"
00017 #include "recursive_file_copy.h"
00018
00019 #include <application/application_shell.h>
00020 #include <basis/guards.h>
00021 #include <filesystem/directory.h>
00022 #include <filesystem/directory_tree.h>
00023 #include <filesystem/filename.h>
00024 #include <filesystem/filename_list.h>
00025 #include <filesystem/heavy_file_ops.h>
00026 #include <filesystem/huge_file.h>
00027 #include <loggers/program_wide_logger.h>
00028 #include <octopus/entity_defs.h>
00029 #include <octopus/octopus.h>
00030 #include <structures/static_memory_gremlin.h>
00031 #include <textual/string_manipulation.h>
00032
00033 using namespace application;
00034 using namespace basis;
00035 using namespace filesystem;
00036 using namespace loggers;
00037 using namespace structures;
00038 using namespace textual;
00039
00040 namespace octopi {
00041
00042 #define FAKE_HOSTNAME "internal_fake_host"
00043
00044 #undef LOG
00045 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
00046 #undef BASE_LOG
00047 #define BASE_LOG(s) EMERGENCY_LOG(program_wide_logger::get(), s)
00048
00049 const int MAX_CHUNK_RFC_COPY_HIER = 1 * MEGABYTE;
00050
00051
00052 recursive_file_copy::~recursive_file_copy() {}
00053
00054 const char *recursive_file_copy::outcome_name(const outcome &to_name)
00055 { return common::outcome_name(to_name); }
00056
00057 #define RETURN_ERROR_RFC(msg, err) { \
00058 LOG(msg); \
00059 return err; \
00060 }
00061
00062 outcome recursive_file_copy::copy_hierarchy(int transfer_mode,
00063 const astring &source_dir, const astring &target_dir,
00064 const string_array &includes, const astring &source_start)
00065 {
00066 FUNCDEF("copy_hierarchy");
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 astring source_root = "snootums";
00078 if (source_start.t()) {
00079 source_root += filename::default_separator() + source_start;
00080 }
00081
00082 octopus ring_leader(FAKE_HOSTNAME, 10 * MEGABYTE);
00083 file_transfer_tentacle *tran = new file_transfer_tentacle
00084 (MAX_CHUNK_RFC_COPY_HIER, (file_transfer_tentacle::transfer_modes)transfer_mode);
00085 ring_leader.add_tentacle(tran);
00086
00087 outcome add_ret = tran->add_correspondence("snootums", source_dir,
00088 10 * MINUTE_ms);
00089 if (add_ret != tentacle::OKAY)
00090 RETURN_ERROR_RFC("failed to add the correspondence", NOT_FOUND);
00091
00092 file_transfer_infoton *initiate = new file_transfer_infoton;
00093 initiate->_request = true;
00094 initiate->_command = file_transfer_infoton::TREE_COMPARISON;
00095 initiate->_src_root = source_root;
00096 initiate->_dest_root = target_dir;
00097 directory_tree target_area(target_dir);
00098
00099 target_area.calculate( !(transfer_mode & file_transfer_tentacle::COMPARE_CONTENT_SAMPLE) );
00100 initiate->package_tree_info(target_area, includes);
00101
00102 octopus_entity ent = ring_leader.issue_identity();
00103 octopus_request_id req_id(ent, 1);
00104 outcome start_ret = ring_leader.evaluate(initiate, req_id);
00105 if (start_ret != tentacle::OKAY)
00106 RETURN_ERROR_RFC("failed to start the comparison", NONE_READY);
00107
00108 file_transfer_infoton *reply_from_init
00109 = (file_transfer_infoton *)ring_leader.acquire_specific_result(req_id);
00110 if (!reply_from_init)
00111 RETURN_ERROR_RFC("no response to tree compare start", NONE_READY);
00112
00113 filename_list diffs;
00114 byte_array pack_copy = reply_from_init->_packed_data;
00115 if (!diffs.unpack(pack_copy)) {
00116 RETURN_ERROR_RFC("could not unpack filename list!", GARBAGE);
00117 }
00118
00119
00120 octopus client_spider(FAKE_HOSTNAME, 10 * MEGABYTE);
00121 file_transfer_tentacle *tran2 = new file_transfer_tentacle
00122 (MAX_CHUNK_RFC_COPY_HIER, (file_transfer_tentacle::transfer_modes)transfer_mode);
00123 tran2->register_file_transfer(ent, source_root, target_dir, includes);
00124 client_spider.add_tentacle(tran2);
00125
00126 octopus_request_id resp_id(ent, 2);
00127 outcome ini_resp_ret = client_spider.evaluate(reply_from_init, resp_id);
00128 if (ini_resp_ret != tentacle::OKAY)
00129 RETURN_ERROR_RFC("failed to process the start response!", FAILURE);
00130
00131 infoton *junk = client_spider.acquire_specific_result(resp_id);
00132 if (junk)
00133 RETURN_ERROR_RFC("got a response we shouldn't have!", FAILURE);
00134
00135 astring current_file;
00136
00137 int iter = 0;
00138 while (true) {
00139
00140
00141
00142 file_transfer_infoton *ongoing = new file_transfer_infoton;
00143 ongoing->_request = true;
00144 ongoing->_command = file_transfer_infoton::PLACE_FILE_CHUNKS;
00145 ongoing->_src_root = source_root;
00146 ongoing->_dest_root = target_dir;
00147
00148 octopus_request_id chunk_id(ent, iter + 10);
00149 outcome place_ret = ring_leader.evaluate(ongoing, chunk_id);
00150 if (place_ret != tentacle::OKAY)
00151 RETURN_ERROR_RFC("failed to run ongoing transfer", FAILURE);
00152
00153 file_transfer_infoton *reply = (file_transfer_infoton *)ring_leader
00154 .acquire_specific_result(chunk_id);
00155 if (!reply)
00156 RETURN_ERROR_RFC("failed to get ongoing transfer reply", NONE_READY);
00157
00158 if (!reply->_packed_data.length()) {
00159 BASE_LOG(astring("finished transfer from \"") + source_dir
00160 + "\" to \"" + target_dir + "\"");
00161 break;
00162 }
00163
00164 byte_array copy = reply->_packed_data;
00165 while (copy.length()) {
00166 file_time empty;
00167 file_transfer_header head(empty);
00168 if (!head.unpack(copy))
00169 RETURN_ERROR_RFC("failed to unpack header", GARBAGE);
00170
00171 if (copy.length() < head._length)
00172 RETURN_ERROR_RFC("not enough length in array", GARBAGE);
00173
00174 copy.zap(0, head._length - 1);
00175
00176
00177
00178 BASE_LOG(head.readable_text_form());
00179 }
00180 if (copy.length())
00181 RETURN_ERROR_RFC("still had data in array", GARBAGE);
00182
00183 octopus_request_id resp_id(ent, iter + 11);
00184 outcome resp_ret = client_spider.evaluate(reply, resp_id);
00185 if (resp_ret != tentacle::OKAY)
00186 RETURN_ERROR_RFC("failed to process the transfer reply!", FAILURE);
00187 }
00188
00189 return OKAY;
00190 }
00191
00192 }
00193
00194