39 using namespace basis;
40 using namespace cromp;
50 #define BASE_LOG(a) EMERGENCY_LOG(program_wide_logger::get(), astring(a))
52 #define LOG(a) CLASS_EMERGENCY_LOG(program_wide_logger::get(), astring(a))
72 virtual int execute();
76 int retrieve_info_from_server();
88 bool _leave_when_no_clients;
97 find_missing::find_missing()
102 _leave_when_no_clients(false),
115 if (args.get_value(
"port", port_text,
false))
118 if (args.find(
"exit", posn)) {
119 LOG(
"seeing the 'exit without clients' flag set.");
120 _leave_when_no_clients =
true;
124 if (args.find(
"encrypt", indy,
false)
125 || (args.find(
'e', indy,
false)) ) {
126 LOG(
"enabling encryption!");
133 if (args.find(
"client", indy,
false)) {
134 LOG(
"client role chosen.");
137 LOG(
"server role chosen.");
146 if (args.get_value(
"host", host_temp,
false)) {
148 hostname = host_temp;
149 }
else LOG(
astring(
"using host: ") + hostname);
150 strcpy(addr.
hostname, hostname.s());
154 if (!args.get_value(
"key", key,
false)) {
156 LOG(
"No keyword specified on command line.");
160 if (!args.get_value(
"root", root,
false)) {
162 LOG(
"No transfer root was specified on the command line.");
166 LOG(
"starting comparison server");
167 _server_side =
new cromp_server(cromp_server::any_address(port));
170 | file_transfer_tentacle::COMPARE_SIZE_AND_TIME
171 | file_transfer_tentacle::COMPARE_CONTENT_SAMPLE));
173 _server_side->add_tentacle(new_tent);
174 _server_side->enable_servers(_encryption);
176 LOG(
"starting comparison client");
178 if (_encryption) _client_side->enable_encryption();
180 outcome ret = _client_side->connect();
181 if (ret != cromp_client::OKAY)
183 "the server: ") + cromp_client::outcome_name(ret));
187 | file_transfer_tentacle::COMPARE_SIZE_AND_TIME
188 | file_transfer_tentacle::COMPARE_CONTENT_SAMPLE));
189 if (!args.get_value(
"source", _source,
false)) {
191 LOG(
"No source path was specified on the command line.");
194 if (!args.get_value(
"target", _target,
false)) {
196 LOG(
"No target path was specified on the command line.");
202 (_client_side->entity(), _source, _target, includes);
203 if (regis != cromp_client::OKAY)
206 _client_side->add_tentacle(new_tent);
209 _started_okay =
true;
213 find_missing::~find_missing()
225 This program can compare directory trees and report the files that are\n\
226 missing on the client's side compared to what the server is offering.\n\
227 The program can function as either the server side or the client side.\n\
228 The available flags are:\n\
230 %s --client --host srvname --port P --source key_path --target cli_dest\n\
232 The client side needs to know the server host (srvname) and the port where\n\
233 the server is listening for connections (P). The client will compare its\n\
234 local path (cli_dest) with the server's keyed path (key_path). The key\n\
235 path will begin with whatever keyword the server is offering, plus optional\n\
236 additional path components to retrieve less than the whole tree being\n\
240 %s --server --host srvname --port P --key keyname --root srv_path\n\
242 The server side needs to know what address and port to listen on (srvname\n\
243 and P). It will open a server there that provides a directory hierarchy\n\
244 starting at the root specified (srv_path). The directory tree will be known\n\
245 to clients as the key word (keyname), thus freeing the clients from needing\n\
246 to know absolute paths on the server.\n\
248 ", name.
s(), name.
s()));
253 int find_missing::retrieve_info_from_server()
255 FUNCDEF(
"retrieve_info_from_server");
259 initiate.
_command = file_transfer_infoton::TREE_COMPARISON;
263 target_area.calculate(
false);
267 outcome start_ret = _client_side->submit(initiate, cmd_id);
268 if (start_ret != tentacle::OKAY)
270 " the transfer: ") + cromp_client::outcome_name(start_ret));
274 outcome first_receipt = _client_side->acquire(start_reply_tmp, cmd_id);
275 if (first_receipt != cromp_client::OKAY)
277 + cromp_client::outcome_name(start_ret));
286 if (!diffs.
unpack(pack_copy))
288 BASE_LOG(
"Differences found between local target and server's tree:");
290 for (
int i = 0; i < diffs.
elements(); i++) {
297 int find_missing::execute()
301 if (!_started_okay)
return 32;
308 if (_server_side && !_server_side->clients() && _leave_when_no_clients
314 if (_client_side)
return retrieve_info_from_server();
318 LOG(
a_sprintf(
"There are %d clients.", _server_side->clients()));
323 time_control::sleep_ms(100);
int print_instructions(bool good, const astring &program_name)
The application_shell is a base object for console programs.
a_sprintf is a specialization of astring that provides printf style support.
Provides a dynamically resizable ASCII character string.
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
int convert(int default_value) const
Converts the string into a corresponding integer.
A very common template for a dynamic array of bytes.
Outcomes describe the state of completion for an operation.
An object that traverses directory trees and provides a view of all files.
virtual bool unpack(basis::byte_array &packed_form)
Restores the packable from the "packed_form".
Provides operations commonly needed on file names.
const basis::astring & raw() const
returns the astring that we're holding onto for the path.
filename basename() const
returns the base of the filename; no directory.
Base objects used by the file transfer tentacle to schedule transfers.
basis::abyte _command
one of the commands above.
basis::astring _src_root
the top-level directory of the source.
bool _request
if it's not a request, then it's a response.
basis::astring _dest_root
the top-level directory of the destination.
void package_tree_info(const filesystem::directory_tree &tree, const structures::string_array &includes)
prepares the packed data from the "tree" and "includes" list.
basis::byte_array _packed_data
the packed headers and file chunks.
Manages the transferrence of directory trees from one place to another.
basis::outcome add_correspondence(const basis::astring &source_mapping, const basis::astring &source_root, int refresh_interval)
adds a file transfer correspondence.
basis::outcome register_file_transfer(const octopus_entity &ent, const basis::astring &src_root, const basis::astring &dest_root, const structures::string_array &include)
records a transfer that is going to commence.
An infoton is an individual request parcel with accompanying information.
Identifies requests made on an octopus by users.
this type of address describes a destination out on the internet.
char hostname[MAXIMUM_HOSTNAME_LENGTH]
int elements() const
the maximum number of elements currently allowed in this amorph.
An array of strings with some additional helpful methods.
A simple object that wraps a templated set of strings.
Represents a point in time relative to the operating system startup time.
#define SETUP_COMBO_LOGGER
a macro that retasks the program-wide logger as a combo_logger.
#define non_continuable_error(c, f, i)
an extra piece of information used, if available, in bounds_halt below.
#define NULL_POINTER
The value representing a pointer to nothing.
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
const int COMPARATOR_PORT
const int REPORTING_INTERVAL
const int REFRESH_INTERVAL
Provides macros that implement the 'main' program of an application.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
Implements an application lock to ensure only one is running at once.
The guards collection helps in testing preconditions and reporting errors.
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
const int SECOND_ms
Number of milliseconds in a second.
const int MINUTE_ms
Number of milliseconds in a minute.
const int KILOBYTE
Number of bytes in a kilobyte.
A platform independent way to obtain the timestamp of a file.
A logger that sends to the console screen using the standard output device.
Provides access to the operating system's socket methods.
A dynamic container class that holds any kind of object via pointers.