1 #ifndef __rconfig_h__
2 #define __rconfig_h__
3 
4 #include <iostream>
5 #include <fstream>
6 #include <string>
7 #include <vector>
8 #include <map>
9 
10 #include "asserts.h"
11 #include "types.h"
12 #include "tstamp.h"
13 
14 //----------------------------------------------------------------------------
15 
16 class parser;
17 class parse_job;
18 
19 /** A configuration manager support class:
20 	Used to specify a single subdirectory in a path of subdirectory names for a
21 	unique path under the archive directory for each job
22 	*/
23 class archive_path_element
24 {
25 public:
26 	enum element_type {
27 		jobname,
28 		groupname,
29 		hostname,
30 		pathname,
31 		permutation,
32 		literal
33 	};
34 
35 	void clear(void);
36 
37 	archive_path_element();
38 	archive_path_element(const archive_path_element& a_class);
39 	archive_path_element(const element_type& a_enum);
40 	archive_path_element(const std::string& a_str);
41 
42 	void assign(const archive_path_element& a_class);
43 	void assign(const element_type& a_enum);
44 	void assign(const std::string& a_str);
45 
46 	const element_type& type(void) const;
47 	const std::string& value(void) const;
48 	const std::string str(void) const;
49 
50 	archive_path_element& operator=(const archive_path_element& a_class);
51 	archive_path_element& operator=(const element_type a_enum);
52 	archive_path_element& operator=(const std::string& a_str);
53 
54 private:
55 	element_type m_type;
56 	std::string m_literal;
57 };
58 
59 /** A configuration manager support class:
60 	Used to specify a unique subdirectory in the archive for each job (made up
61 	of archive_path_element's)
62  */
63 class archive_path : public std::vector<archive_path_element>
64 {
65 public:
66 	typedef std::vector<archive_path_element> type;
67 
68 	void reset(void);
69 
70 	archive_path();
71 	archive_path(const archive_path& a_class);
72 	archive_path(const archive_path_element& a_class);
73 	archive_path(const std::string& a_class);
74 
75 	void push_back(const archive_path& a_class);
76 	void push_back(const archive_path_element& a_class);
77 	void push_back(const std::string& a_str);
78 
79 	void assign(const archive_path& a_class);
80 	void assign(const archive_path_element& a_class);
81 	void assign(const std::string& a_str);
82 
83 	const std::string str(void) const;
84 
85 	archive_path& operator=(const archive_path& a_class);
86 	archive_path& operator=(const archive_path_element& a_class);
87 	archive_path& operator=(const std::string& a_str);
88 
89 private:
90 };
91 
92 /** A configuration manager support class:
93 	Used to map rsync exit codes to actions for rvm to take
94  */
95 class rsync_behavior
96 {
97 public:
98 	enum behavior_type {
99 		quit,
100 		fail,
101 		retry,
102 		retry_without_hardlinks,
103 		ok
104 	};
105 	typedef behavior_type value_type;
106 	typedef std::map<uint16, value_type> map_type;
107 	static const uint16 default_behavior = ((uint16)-1);
108 
109 	void clear(void);
110 	void reset(void);
111 
112 	rsync_behavior();
113 	rsync_behavior(const rsync_behavior& a_class);
114 
115 	void assign(const uint16 a_code, const value_type a_action);
116 	void assign(const rsync_behavior& a_class);
117 	void assign(const std::string& a_str);
118 
119 	const value_type operator[](const uint16 a_code) const;
120 	value_type& operator[](const uint16 a_code);
121 	rsync_behavior& operator=(const rsync_behavior& a_class);
122 	rsync_behavior& operator=(const value_type a_enum);
123 	rsync_behavior& operator=(const std::string& a_str);
124 
125 	const value_type default_value(void) const;
126 	const map_type& map_value(void) const;
127 
128 private:
129 	map_type m_map;
130 	value_type m_default;
131 };
132 
133 class configuration_manager;
134 
135 /** Hold configuration data for a single job */
136 class job
137 {
138 public:
139 	enum rsync_connection_type {
140 		connection_remote,
141 		connection_local,
142 		connection_server,
143 		connection_ssh_local
144 	};
145 	enum rsync_behavior_type {
146 		behavior_ok,
147 		behavior_fail,
148 		behavior_retry,
149 		behavior_retry_without_hardlinks
150 	};
151 	typedef std::vector<std::string> excludes_type;
152 	typedef std::vector<std::string> includes_type;
153 	typedef std::vector<std::string> paths_type;
154 
155 	job();
156 	job(const job& a_job);
157 
158 	void clear(void);
159 	void assign(const job& a_job);
160 
161 	job& operator=(const job& a_job);
162 
163 	std::string default_config_path;
164 	uint16 default_config_line;
165 	std::string config_path;
166 	uint16 config_line;
167 	class archive_path archive_path;
168 	excludes_type excludes;
169 	includes_type includes;
170 	std::string groupname;
171 	std::string hostname;
172 	std::string jobname;
173 	paths_type paths;
174 	class rsync_behavior rsync_behavior;
175 	rsync_connection_type rsync_connection;
176 	bool rsync_hardlink;
177 	bool rsync_multi_hardlink;
178 	uint16 rsync_multi_hardlink_max;
179 	std::string rsync_options;
180 	std::string ssh_options;
181 	std::string rsync_remote_user;
182 	std::string rsync_remote_path;
183 	std::string rsync_remote_module;
184 	uint16 rsync_remote_port;
185 	uint16 rsync_retry_count;
186 	uint16 rsync_retry_delay;
187 	uint16 rsync_timeout;
188 
189 	const std::string generate_archive_path(const std::string& a_path) const;
190 	const std::string generate_source_path(const std::string& a_path) const;
191 	const std::string generate_job_id(void) const;
192 	const std::vector<std::string> generate_rsync_options_vector(void) const;
193 	const std::vector<std::string> generate_ssh_options_vector(void) const;
194 	const std::string common_pathname(void) const;
195 	void check(void);
196 
197 private:
198 
199 	friend class parser;
200 };
201 
202 /** Keep up with configuration settings for RVM and it's jobs */
203 class configuration_manager
204 {
205 public:
206 	enum action_type {
207 		action_help,
208 		action_version,
209 		action_archive,
210 		action_relink,
211 		action_check_config
212 	};
213 	enum cfgfile_type {
214 		config_file,
215 		job_file,
216 	};
217 	enum overflow_type {
218 		overflow_quit,
219 		overflow_delete_oldest,
220 		overflow_delete_until_free
221 	};
222 	enum selection_type {
223 		selection_round_robin,
224 		selection_max_free
225 	};
226 	enum logging_type {
227 		logging_manager,
228 		logging_child,
229 		logging_rsync
230 	};
231 	typedef std::pair<cfgfile_type, std::string> cfgfile_element;
232 	typedef class std::vector<cfgfile_element> cfgfiles_type;
233 	typedef std::vector<job> jobs_type;
234 	typedef std::vector<std::string> vaults_type;
235 
236 	void clear(void);
237 
238 	configuration_manager();
239 
240 	void init(int argc, char const *argv[]);
241 	void check(void) const;
242 	const bool initialized(void) const;
243 
244 	const action_type action(void) const;
245 	const bool use_default(void) const;
246 	void default_file(const std::string& a_path);
247 	const std::string& default_file(void) const;
248 	void default_logdir(const std::string& a_path);
249 	const class timestamp& timestamp(void) const;
250 	const std::string& link_catalog_dir(void) const;
251 	const std::string& log_dir(void) const;
252 	const bool delete_old_log_files(void) const;
253 	const bool delete_old_report_files(void) const;
254 	const std::string& rsync_local_path(void) const;
255 	const std::string& delete_command_path(void) const;
256 	const std::string& ssh_local_path(void) const;
257 	const uint16& rsync_parallel(void) const;
258 	const uint16& io_poll_interval(void) const;
259 	const timestamp::resolution_type timestamp_resolution(void) const;
260 	const vaults_type& vaults(void) const;
261 	const overflow_type& vault_overflow_behavior(void) const;
262 	const uint16& vault_overflow_blocks(void) const;
263 	const uint16& vault_overflow_inodes(void) const;
264 	const selection_type& vault_selection_behavior(void) const;
265 	const bool vault_locking(void) const;
266 	const job& default_job(void) const;
267 	const jobs_type& jobs(void) const;
268 	const logging_type& logging_level(void) const;
269 	const logging_type& error_logging_level(void) const;
270 
271 private:
272 	bool m_initialized;
273 	uint16 m_configs_read;
274 	std::string m_default_file;
275 	action_type m_action;
276 	bool m_default;
277 	class timestamp m_timestamp;
278 	cfgfiles_type m_cfgfiles;
279 	std::string m_link_catalog_dir;
280 	std::string m_log_dir;
281 	std::string m_rsync_local_path;
282 	std::string m_delete_command_path;
283 	std::string m_ssh_local_path;
284 	uint16 m_rsync_parallel;
285 	uint16 m_io_poll_interval;
286 	std::vector<std::string> m_vaults;
287 	overflow_type m_vault_overflow_behavior;
288 	uint16 m_vault_overflow_blocks;
289 	uint16 m_vault_overflow_inodes;
290 	selection_type m_vault_selection_behavior;
291 	bool m_vault_locking;
292 	bool m_delete_old_log_files;
293 	bool m_delete_old_report_files;
294 	job m_default_job;
295 	jobs_type m_jobs;
296 	logging_type m_logging_level;
297 	logging_type m_error_logging_level;
298 
299 	friend class global_parser;
300 	friend class job_parser;
301 
302 	void read_config(const std::string& a_path);
303 	void read_job(const std::string& a_path);
304 };
305 
306 void parse_line(
307 	std::istream& a_in,
308 	std::string& a_keyword,
309 	std::string& a_value
310 	);
311 
312 /** A configuration manager support class:
313 	Used to parse a configuration file from the perspective of a global context
314  */
315 class global_parser
316 {
317 public:
318 	global_parser(
319 		const std::string& a_path,
320 		uint16& a_line,
321 		std::istream& a_in
322 		);
323 
324 private:
325 	const std::string* m_path;
326 	std::istream* m_in;
327 	uint16* m_line;
328 
329 	const std::string location(void);
330 	void read_config(const std::string& a_path);
331 	void read_job(const std::string& a_path, job& a_job);
332 
333 	void parse(void);
334 	void parse_default(const std::string& a_value);
335 	void parse_include(const std::string& a_value);
336 	void parse_include_job(const std::string& a_value);
337 	void parse_job(const std::string& a_value);
338 	void parse_link_catalog_dir(const std::string& a_value);
339 	void parse_log_dir(const std::string& a_value);
340 	void parse_delete_old_log_files(const std::string& a_value);
341 	void parse_delete_old_report_files(const std::string& a_value);
342 	void parse_logging_level(const std::string& a_value);
343 	void parse_error_logging_level(const std::string& a_value);
344 	void parse_rsync_local_path(const std::string& a_value);
345 	void parse_delete_command_path(const std::string& a_value);
346 	void parse_ssh_local_path(const std::string& a_value);
347 	void parse_rsync_parallel(const std::string& a_value);
348 	void parse_io_poll_interval(const std::string& a_value);
349 	void parse_timestamp_resolution(const std::string& a_value);
350 	void parse_vault(const std::string& a_value);
351 	void parse_vault_overflow_behavior(const std::string& a_value);
352 	void parse_vault_overflow_blocks(const std::string& a_value);
353 	void parse_vault_overflow_inodes(const std::string& a_value);
354 	void parse_vault_selection_behavior(const std::string& a_value);
355 	void parse_vault_locking(const std::string& a_value);
356 };
357 
358 /** A configuration manager support class:
359 	Used to parse a configuration file from the perspective of a job context
360  */
361 class job_parser
362 {
363 public:
364 	job_parser(
365 		job * a_job,
366 		const std::string& a_path,
367 		uint16& a_line,
368 		std::istream& a_in,
369 		const std::string& a_block_delimiter,
370 		const bool a_default_context
371 		);
372 
373 private:
374 	job* m_job;
375 	const std::string* m_path;
376 	std::istream* m_in;
377 	uint16* m_line;
378 	const std::string* m_delimiter;
379 	bool m_default_context;
380 
381 	const std::string location(void);
382 	void read_job(const std::string& a_path);
383 
384 	void parse(void);
385 	void parse_archive_path(const std::string& a_value);
386 	void parse_clear(const std::string& a_value);
387 	void parse_exclude_from(const std::string& a_value);
388 	void parse_include_from(const std::string& a_value);
389 	void parse_groupname(const std::string& a_value);
390 	void parse_hostname(const std::string& a_value);
391 	void parse_include(const std::string& a_value);
392 	void parse_jobname(const std::string& a_value);
393 	void parse_path(const std::string& a_value);
394 	void parse_rsync_behavior(const std::string& a_value);
395 	void parse_rsync_connection_type(const std::string& a_value);
396 	void parse_rsync_hardlink(const std::string& a_value);
397 	void parse_rsync_multi_hardlink(const std::string& a_value);
398 	void parse_rsync_multi_hardlink_max(const std::string& a_value);
399 	void parse_rsync_options(const std::string& a_value);
400 	void parse_ssh_options(const std::string& a_value);
401 	void parse_rsync_options_context(const std::string& a_value);
402 	void parse_ssh_options_context(const std::string& a_value);
403 	void parse_rsync_remote_user(const std::string& a_value);
404 	void parse_rsync_remote_path(const std::string& a_value);
405 	void parse_rsync_remote_port(const std::string& a_value);
406 	void parse_rsync_remote_module(const std::string& a_value);
407 	void parse_rsync_retry_count(const std::string& a_value);
408 	void parse_rsync_retry_delay(const std::string& a_value);
409 	void parse_rsync_timeout(const std::string& a_value);
410 };
411 
412 extern configuration_manager config;
413 
414 #endif
415