1 #ifndef FILE_TRANSFER_TENTACLE_CLASS
2 #define FILE_TRANSFER_TENTACLE_CLASS
4 /*****************************************************************************\
6 * Name : file_transfer_tentacle *
7 * Author : Chris Koeritz *
9 *******************************************************************************
10 * Copyright (c) 2005-$now By Author. This program is free software; you can *
11 * redistribute it and/or modify it under the terms of the GNU General Public *
12 * License as published by the Free Software Foundation; either version 2 of *
13 * the License or (at your option) any later version. This is online at: *
14 * http://www.fsf.org/copyleft/gpl.html *
15 * Please send any updates to: fred@gruntose.com *
16 \*****************************************************************************/
18 #include "file_transfer_infoton.h"
20 #include <basis/mutex.h>
21 #include <filesystem/directory_tree.h>
22 #include <filesystem/filename_list.h>
23 #include <octopus/tentacle_helper.h>
24 #include <timely/time_stamp.h>
28 class file_transfer_cleaner;
29 class file_transfer_status;
31 //! Manages the transferrence of directory trees from one place to another.
33 Note: this is a fairly heavy-weight header due to the inclusion of the
34 file transfer infoton header. It is better to forward declare the
35 objects in both file transfer headers when using the types in other
39 class file_transfer_tentacle
40 : public tentacle_helper<file_transfer_infoton>
44 ONLY_REPORT_DIFFS = 0x1, //!< no actual file transfer, just reports.
45 COMPARE_SIZE_AND_TIME = 0x2, //!< uses size and time to see differences.
46 COMPARE_CONTENT_SAMPLE = 0x4, //!< samples parts of file for comparison.
47 COMPARE_ALL = 0x6 //!< compares all of the file size, file time, and contents.
51 file_transfer_tentacle(int maximum_transfer, transfer_modes mode_of_transfer);
52 //!< constructs a tentacle for either transfers or comparisons.
53 /*!< the "maximum_transfer" is the largest chunk of data we will try to
54 sling across the network at a time. the "mode_of_transfer" selects how
55 to perform the operation. if "ONLY_REPORT_DIFFS" is set, then there
56 will only be a report of differences and no files will be copied. if
57 COMPARE_SIZE_AND_TIME is set, then the comparison will use the file's
58 size and its access time for determining if it has changed. if the
59 COMPARE_CONTENT_SAMPLE flag is set, then the file will be sampled at some
60 key locations and that will decide differences. the comparison modes
61 can be mixed together. if there are no comparison modes, then the files
62 will always be copied. */
64 virtual ~file_transfer_tentacle();
66 DEFINE_CLASS_NAME("file_transfer_tentacle");
68 basis::astring text_form() const;
69 //!< returns a string representing the current state of transfers.
71 filesystem::directory_tree *lock_directory(const basis::astring &source_mapping);
72 //!< provides a view of the tentacle's current state.
73 void unlock_directory();
74 //!< unlock MUST be called when one is done looking at the tree.
76 // these methods are for the "server" side--the side that has files to offer.
78 basis::outcome add_correspondence(const basis::astring &source_mapping,
79 const basis::astring &source_root, int refresh_interval);
80 //!< adds a file transfer correspondence.
81 /*!< this is a "source_mapping" which is a short string that is made
82 available to the other side for transfer requests. when they specify the
83 "source_mapping", it will be translated on this side to the "source_root",
84 which must be a valid filesystem path. the "refresh_interval" dictates
85 how frequently, in milliseconds, the source will be scanned to update the
86 internal directory tree. this is done the first time the "source_mapping"
87 is set up also. if a previous identical "source_mapping" existed, then it
88 is removed and replaced with the information from the new invocation. */
90 basis::outcome remove_correspondence(const basis::astring &source_mapping);
91 //!< takes out the "source_mapping" which was previously added.
92 /*!< this keeps any transfers from occurring on that name, and will cause
93 aborted transfers if any were still ongoing. */
95 basis::outcome refresh_now(const basis::astring &source_mapping);
96 //!< refreshes the "source_mapping" right now, regardless of the interval.
97 /*!< the mapping must already have been created with add_correspondence().
100 bool add_path(const basis::astring &source_mapping, const basis::astring &new_path);
101 //!< inserts the "new_path" into a registered correspondence.
102 /*!< the "source_mapping" must already be registered. */
104 bool remove_path(const basis::astring &source_mapping, const basis::astring &old_path);
105 //!< deletes the "old_path" out of an existing correspondence.
107 // these methods are for the client side--the side that wants to get files.
109 basis::outcome register_file_transfer(const octopus_entity &ent,
110 const basis::astring &src_root, const basis::astring &dest_root,
111 const structures::string_array &include);
112 //!< records a transfer that is going to commence.
113 /*!< the side that wishes to download files must invoke this before
114 starting the transfer. if the "include" list is not empty, then only
115 those files will be transferred. they have to match the suffix of the
116 files that would have been transferred and wildcards are not currently
119 basis::outcome cancel_file_transfer(const octopus_entity &ent,
120 const basis::astring &src_root, const basis::astring &dest_root);
121 //!< tosses a previously registered file transfer.
122 /*!< this will be done automatically after a time-out period, but it is
123 better to clean it up as soon as one is finished with the transfer. */
125 bool status(const octopus_entity &ent, const basis::astring &src,
126 const basis::astring &dest, double &total_size, int &total_files,
127 double ¤t_size, int ¤t_files, bool &done,
128 timely::time_stamp &last_active);
129 //!< locates the transfer specified and returns information about it.
130 /*!< the transfer is designated by the "ent", "src" and "dest" parameters
131 and returns the current progress. files refers to how many files are
132 being transferred and size refers to their combined weight in bytes. the
133 "done" flag is set if the transfer seems finished. note that this will
134 not set any values until the first reply comes back from the server. */
136 bool get_differences(const octopus_entity &ent, const basis::astring &src,
137 const basis::astring &dest, filesystem::filename_list &diffs);
138 //!< accesses the list of difference for an ongoing transfer.
139 /*!< the progress is stored in "diffs". */
141 // required tentacle methods...
143 virtual basis::outcome reconstitute(const structures::string_array &classifier,
144 basis::byte_array &packed_form, infoton * &reformed);
145 //!< recreates a "reformed" infoton from its packed form.
146 /*!< this requires the "classifier" and packed infoton data in
147 "packed_form". this will only succeed if the classifier's first name
148 is understood here. */
150 virtual basis::outcome consume(infoton &to_chow, const octopus_request_id &item_id,
151 basis::byte_array &transformed);
152 //!< processes the "to_chow" infoton as a file transfer request.
154 virtual void expunge(const octopus_entity &to_remove);
155 //!< throws out any transfers occurring for the entity "to_remove".
157 // internal use only.
159 void periodic_actions(); //!< drops timed out transfers.
162 int _maximum_transfer; //!< largest chunk to send at a time.
163 file_transfer_status *_transfers; //!< our record of ongoing transfers.
164 file_transfer_status *_correspondences; //!< the synonyms for mapping.
165 basis::mutex *_lock; //!< protects our lists.
166 file_transfer_cleaner *_cleaner; //!< cleans up dead transfers.
167 int _mode; //!< how will the comparison be done?
169 // these process the request and response infotons that are passed to us.
170 basis::outcome handle_build_target_tree_request(file_transfer_infoton &req,
171 const octopus_request_id &item_id);
172 basis::outcome handle_build_target_tree_response(file_transfer_infoton &resp,
173 const octopus_request_id &item_id);
174 basis::outcome handle_tree_compare_request(file_transfer_infoton &req,
175 const octopus_request_id &item_id);
176 basis::outcome handle_tree_compare_response(file_transfer_infoton &resp,
177 const octopus_request_id &item_id);
178 basis::outcome handle_storage_request(file_transfer_infoton &req,
179 const octopus_request_id &item_id);
180 basis::outcome handle_storage_response(file_transfer_infoton &resp,
181 const octopus_request_id &item_id);
182 basis::outcome conclude_storage_request(file_transfer_infoton &req,
183 const octopus_request_id &item_id);
184 basis::outcome conclude_storage_response(file_transfer_infoton &resp,
185 const octopus_request_id &item_id);