86 std::string::size_type idx;
88 TRY_nomem(es =
"Invalid archive-path keyword: \"");
92 if (a_str.size() == 0) {
95 if (a_str[0] ==
'"') {
96 if (a_str.size() < 3) {
99 if (a_str[a_str.size()-1] !=
'"') {
102 TRY_nomem(str = a_str.substr(1,a_str.size()-2));
105 while (idx != std::string::npos) {
106 if ((idx > 0) && (str[idx-1] !=
'\\'))
108 idx = str.find(
'"',idx+1);
111 idx = str.find(
"\\\"");
112 while (idx != std::string::npos) {
114 idx = str.find(
"\\\"");
122 if (str ==
"jobname") {
125 else if (str ==
"groupname") {
128 else if (str ==
"hostname") {
131 else if (str ==
"pathname") {
134 else if (str ==
"permutation") {
159 std::string::size_type idx;
179 for (idx = 0; idx !=
m_literal.size(); idx++) {
260 for (li = a_class.begin(); li != a_class.end(); li++) {
277 std::string::size_type idx;
280 if (a_str.size() == 0)
286 if (str[str.size()-1] ==
'/')
287 str.erase(str.size()-1,1);
289 while (str.size() > 0) {
291 if (idx == std::string::npos) {
315 for (li = begin(); li != end(); li++) {
328 if (
this != &a_class) {
427 if (
this == &a_class)
442 std::string code_str;
443 std::string action_str;
446 std::string::size_type idx;
448 TRY_nomem(es =
"Invalid rsync-behavior value: \"");
454 while (isdigit(action_str[idx]) || (action_str[idx] ==
'*'))
456 TRY_nomem(code_str = action_str.substr(0,idx));
457 action_str.erase(0,idx);
458 if (code_str.size() == 0)
462 while ((action_str[idx] ==
' ') || (action_str[idx] ==
'\t'))
464 action_str.erase(0,idx);
466 if (action_str[0] !=
'=')
468 action_str.erase(0,1);
471 while ((action_str[idx] ==
' ') || (action_str[idx] ==
'\t'))
473 action_str.erase(0,idx);
479 if (
estring(action_str).lower() ==
"ok")
481 else if (
estring(action_str).lower() ==
"fail")
483 else if (
estring(action_str).lower() ==
"retry")
485 else if (
estring(action_str).lower() ==
"retry-without-hardlinks")
487 else if (
estring(action_str).lower() ==
"ok")
502 return(
m_map.find(a_code)->second);
514 return(
m_map[a_code]);
645 archive_path::const_iterator capi;
650 TRY_nomem(es =
"archive-path references jobname, ");
654 if (path.size() != 0) {
661 TRY_nomem(es =
"archive-path references groupname, ");
662 TRY_nomem(es +=
"but groupname is empty");
665 if (path.size() != 0) {
672 TRY_nomem(es =
"archive-path references hostname, ");
673 TRY_nomem(es +=
"but hostname is empty");
676 if (path.size() != 0) {
682 if (a_path.size() == 0) {
683 TRY_nomem(es =
"archive-path references path name, ");
684 TRY_nomem(es +=
"but path name is empty");
687 if (path.size() != 0) {
693 if (a_path.size() == 0) {
694 TRY_nomem(es =
"archive-path references path name, ");
695 TRY_nomem(es +=
"but path name is empty");
698 if (path.size() != 0) {
704 if (capi->value().size() == 0) {
705 TRY_nomem(es =
"archive-path references literal string, ");
706 TRY_nomem(es +=
"but literal string value is empty");
709 if (path.size() != 0) {
719 while ((path.size() > 0) && (path[path.size()-1] !=
'/'))
720 path.erase(path.size()-1);
746 if ((a_path.size() > 0) && (a_path[0] !=
'/'))
766 std::string common_path;
767 paths_type::size_type pidx;
768 std::string::size_type sidx;
769 std::string::size_type max_sidx;
774 max_sidx =
paths[0].size();
775 for (pidx = 0; pidx <
paths.size(); pidx++) {
776 if (max_sidx >
paths[pidx].size()) {
777 max_sidx =
paths[pidx].size();
781 for (sidx = 0; sidx < max_sidx; sidx++) {
782 for (pidx = 0; (same && (pidx <
paths.size())); pidx++) {
791 if (common_path[0] ==
'/')
792 common_path.erase(0,1);
793 if ((common_path.size() > 0) && (common_path[common_path.size()-1] ==
'/'))
794 common_path.erase(common_path.size()-1);
804 archive_path::const_iterator capi;
809 TRY_nomem(es =
"archive-path references jobname, ");
813 if (path.size() != 0) {
820 TRY_nomem(es =
"archive-path references groupname, ");
821 TRY_nomem(es +=
"but groupname is empty");
824 if (path.size() != 0) {
831 TRY_nomem(es =
"archive-path references hostname, ");
832 TRY_nomem(es +=
"but hostname is empty");
835 if (path.size() != 0) {
841 if (path.size() == 0) {
846 if (path.size() == 0) {
851 if (capi->value().size() == 0) {
852 TRY_nomem(es =
"archive-path references literal string, ");
853 TRY_nomem(es +=
"but literal string value is empty");
856 if (path.size() != 0) {
865 if (path.size() == 0) {
875 std::vector<std::string> argv;
878 while (opts.size() != 0) {
881 while ((opts.size() != 0) && (opts[0] !=
' ') && (opts[0] !=
'\t')) {
887 while ((opts.size() != 0) && (opts[0] !=
'\'')) {
891 if (opts[0] ==
'\'') {
897 while ((opts.size() != 0) && (opts[0] !=
'"')) {
898 if ((opts.size() >= 2) && (opts[0] ==
'\\') && (opts[1] ==
'"')) {
907 if (opts[0] ==
'"') {
912 if ((opts.size() >= 2) && (opts[1] ==
' ')) {
916 else if ((opts.size() >= 2) && (opts[1] ==
't')) {
935 while ((opts.size() > 0) && ((opts[0] ==
' ') || (opts[0] ==
'\t'))) {
947 std::vector<std::string> argv;
950 while (opts.size() != 0) {
953 while ((opts.size() != 0) && (opts[0] !=
' ') && (opts[0] !=
'\t')) {
959 while ((opts.size() != 0) && (opts[0] !=
'\'')) {
963 if (opts[0] ==
'\'') {
969 while ((opts.size() != 0) && (opts[0] !=
'"')) {
970 if ((opts.size() >= 2) && (opts[0] ==
'\\') && (opts[1] ==
'"')) {
979 if (opts[0] ==
'"') {
984 if ((opts.size() >= 2) && (opts[1] ==
' ')) {
988 else if ((opts.size() >= 2) && (opts[1] ==
't')) {
1005 argv.push_back(str);
1007 while ((opts.size() > 0) && ((opts[0] ==
' ') || (opts[0] ==
'\t'))) {
1019 std::string this_path;
1020 std::string that_path;
1021 paths_type::const_iterator cpi;
1022 configuration_manager::jobs_type::const_iterator cji;
1023 paths_type::const_iterator cjapi;
1034 TRY_nomem(es =
"rsync-connection-type references hostname, ");
1035 TRY_nomem(es +=
"but hostname is empty");
1049 TRY_nomem(es =
"rsync-connection-type is remote-rsync-local-dir, ");
1050 TRY_nomem(es +=
"but exclude files have been specified");
1055 TRY_nomem(es =
"rsync-connection-type is remote-rsync-local-dir, ");
1056 TRY_nomem(es +=
"but include files have been specified");
1064 TRY_nomem(es =
"rsync-remote-module specifies a module, but ");
1065 TRY_nomem(es =
"rsync-connection-type is not server");
1069 if (
paths.size() == 0) {
1070 throw(
ERROR(0,
"No paths defined for this job"));
1073 for (cpi =
paths.begin() ; cpi !=
paths.end(); cpi++) {
1083 cjapi = cji->paths.begin();
1084 cjapi != cji->paths.end();
1088 TRY_nomem(that_path = cji->generate_archive_path(*cjapi));
1090 if (this_path == that_path) {
1093 TRY_nomem(es =
"Duplicate archive-path values detected");
1099 TRY_nomem(es =
"Previously defined at ");
1109 (this_path.size() < that_path.size())
1110 && (this_path == that_path.substr(0,this_path.size()))
1112 (that_path[this_path.size()] ==
'/')
1113 || (this_path.size() == 0)
1119 TRY_nomem(es =
"Overlapping archive-path values detected");
1121 TRY_nomem(es =
"Defined archive-path: \"");
1125 TRY_nomem(es =
"Is in a parent directory of another job's previously defined archive-path");
1137 (this_path.size() > that_path.size())
1138 && (this_path.substr(0,that_path.size()) == that_path)
1140 (this_path[that_path.size()] ==
'/')
1141 || (that_path.size() == 0)
1147 TRY_nomem(es =
"Overlapping archive-path values detected");
1149 TRY_nomem(es =
"Defined archive-path: \"");
1153 TRY_nomem(es =
"Is in a subdirectory of another job's previously defined archive-path");
1212 INTERNAL_ERROR(0,
"Attempt to allocate multiple configuration managers")
1225 cfgfiles_type::const_iterator cfi;
1226 bool use_custom_timestamp =
false;
1229 for (c = 1; c < argc; c++) {
1238 if (opt ==
"--archive") {
1241 else if (opt ==
"--relink") {
1244 else if (opt ==
"--help") {
1247 else if (opt ==
"--version") {
1250 else if (opt ==
"--check-config") {
1253 else if (opt ==
"--no-default-config") {
1256 else if (opt ==
"--config") {
1258 directory::const_iterator cdi;
1260 TRY_nomem(es =
"Error finding configuration file(s) ");
1261 TRY_nomem(es +=
"matching command line argument [");
1280 if (dir.size() == 0) {
1281 TRY_nomem(es =
"No configuration file(s) found matching ");
1282 TRY_nomem(es +=
"command line argument [");
1290 for (cdi = dir.begin(); cdi != dir.end(); cdi++) {
1296 else if (opt ==
"--job") {
1298 directory::const_iterator cdi;
1300 TRY_nomem(es =
"Error finding job file(s) ");
1301 TRY_nomem(es +=
"matching command line argument [");
1318 if (dir.size() == 0) {
1319 TRY_nomem(es =
"No job file(s) found matching ");
1320 TRY_nomem(es +=
"command line argument [");
1328 for (cdi = dir.begin(); cdi != dir.end(); cdi++) {
1334 else if (opt ==
"--timestamp") {
1335 TRY_nomem(es =
"From command line argument ");
1338 use_custom_timestamp =
true;
1343 TRY_nomem(es =
"Unknown command line option: \"");
1368 throw(
ERROR(0,
"No configuration file(s) read"));
1371 if (use_custom_timestamp) {
1386 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1391 throw(
ERROR(0,
"log-dir not set"));
1393 TRY_nomem(es =
"Invalid log-dir value: \"");
1401 TRY_nomem(es =
"Invalid rsync-local-path value: \"");
1409 TRY_nomem(es =
"Invalid delete-command-path value: \"");
1430 throw(
ERROR(0,
"No vaults defined"));
1436 if (
jobs().size() > 0) {
1437 jobs_type::const_iterator cji;
1439 for (cji =
jobs().begin(); cji !=
jobs().end(); cji++) {
1440 if (cji->generate_job_id().size() == 0) {
1443 TRY_nomem(es =
"Empty ID generated by job at ");
1450 "Use 'jobname' to assign a descriptive name to this job");
1469 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1478 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1493 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1508 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1517 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1526 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1535 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1544 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1553 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1562 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1571 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1580 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1589 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1598 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1607 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1616 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1625 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1634 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1643 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1652 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1661 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1670 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1679 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1688 throw(
INTERNAL_ERROR(0,
"Configuration manager is not initialized"));
1700 in.open(a_path.c_str());
1701 if (!in.is_open()) {
1702 TRY_nomem(es =
"Could not open configuration file: \"");
1705 throw(
ERROR(errno,es));
1722 in.open(a_path.c_str());
1723 if (!in.is_open()) {
1724 TRY_nomem(es =
"Could not open job file: \"");
1727 throw(
ERROR(errno,es));
1732 job_parser(&njob, a_path, line, in,
"",
false);
1744 std::string& a_keyword,
1745 std::string& a_value
1757 while ((a_in) && ((ch ==
' ') || (ch ==
'\t'))) {
1761 while ((a_in) && ((ch !=
' ') && (ch !=
'\t') && (ch !=
'\n'))) {
1769 if (a_keyword.size() == 0)
1773 if (a_keyword[0] ==
'#') {
1775 while ((a_in) && (ch !=
'\n')) {
1789 while ((a_in) && ((ch ==
' ') || (ch ==
'\t'))) {
1800 while ((a_in) && (ch !=
'\n')) {
1815 if (rpath.find_last_of(
'/') != std::string::npos)
1816 rpath.erase(rpath.find_last_of(
'/'));
1818 if (rpath.size() == 0) {
1823 if (rpath[rpath.size()-1] !=
'/') {
1838 if (rpath.find_last_of(
'/') != std::string::npos)
1839 rpath.erase(0,rpath.find_last_of(
'/'));
1848 const std::string& a_path,
1882 in.open(a_path.c_str());
1883 if (!in.is_open()) {
1884 TRY_nomem(es =
"Could not open configuraiton file: \"");
1887 throw(
ERROR(errno,es));
1903 in.open(a_path.c_str());
1904 if (!in.is_open()) {
1905 TRY_nomem(es =
"Could not open job file: \"");
1908 throw(
ERROR(errno,es));
1911 job_parser(&a_job, a_path, line, in,
"",
false);
1924 std::string keyword;
1944 if (keyword.size() == 0)
1946 if (keyword[0] ==
'#')
1950 if (keyword ==
"<default>") {
1953 else if (keyword ==
"include") {
1956 else if (keyword ==
"include-job") {
1959 else if (keyword ==
"<job>") {
1962 else if (keyword ==
"link-catalog-dir") {
1965 else if (keyword ==
"log-dir") {
1968 else if (keyword ==
"delete-old-log-files") {
1971 else if (keyword ==
"delete-old-report-files") {
1974 else if (keyword ==
"logging-level") {
1977 else if (keyword ==
"error-logging-level") {
1980 else if (keyword ==
"rsync-local-path") {
1983 else if (keyword ==
"delete-command-path") {
1986 else if (keyword ==
"ssh-local-path") {
1989 else if (keyword ==
"rsync-parallel") {
1992 else if (keyword ==
"io-poll-interval") {
1995 else if (keyword ==
"timestamp-resolution") {
1998 else if (keyword ==
"vault") {
2009 else if (keyword ==
"vault-overflow-behavior") {
2012 else if (keyword ==
"vault-overflow-blocks") {
2015 else if (keyword ==
"vault-overflow-inodes") {
2018 else if (keyword ==
"vault-selection-behavior") {
2021 else if (keyword ==
"vault-locking") {
2027 TRY_nomem(es =
"Unknown command in global context: \"");
2049 std::string delimiter;
2050 std::string default_config_path;
2051 uint16 default_config_line;
2071 directory::const_iterator cdi;
2075 if (a_value.size() == 0) {
2076 TRY_nomem(es =
"Invalid include path: \"");
2082 if (a_value[0] !=
'/') {
2088 TRY_nomem(es =
"No configuration file(s) found: \"");
2092 if (dir.size() == 0)
2095 for (cdi = dir.begin(); cdi != dir.end(); cdi++) {
2096 if (dir.size() > 1) {
2097 TRY_nomem(es =
"For files found matching: \"");
2124 directory::const_iterator cdi;
2128 if (a_value.size() == 0) {
2129 TRY_nomem(es =
"Invalid include-job path: \"");
2135 if (a_value[0] !=
'/') {
2141 TRY_nomem(es =
"No job file(s) found: \"");
2145 if (dir.size() == 0)
2148 for (cdi = dir.begin(); cdi != dir.end(); cdi++) {
2153 if (dir.size() > 1) {
2154 TRY_nomem(es =
"For files found matching: \"");
2180 std::string delimiter;
2181 std::string config_path;
2206 TRY_nomem(es =
"Invalid link-catalog-dir path: \"");
2219 TRY_nomem(es =
"Invalid log-dir path: \"");
2232 TRY_nomem(es =
"Invalid delete-old-log-files value: \"");
2267 TRY_nomem(es =
"Invalid delete-old-report-files value: \"");
2302 TRY_nomem(es =
"Invalid logging-level value: \"");
2306 if (str ==
"manager") {
2309 else if (str ==
"child") {
2312 else if (str ==
"rsync") {
2326 TRY_nomem(es =
"Invalid error-logging-level value: \"");
2330 if (str ==
"manager") {
2333 else if (str ==
"child") {
2336 else if (str ==
"rsync") {
2350 TRY_nomem(es =
"Invalid rsync-local-path value: \"");
2363 TRY_nomem(es =
"Invalid delete-command-path value: \"");
2376 TRY_nomem(es =
"Invalid ssh-local-path value: \"");
2389 TRY_nomem(es =
"Invalid rsync-parallel value: \"");
2404 TRY_nomem(es =
"Invalid io-poll-interval value: \"");
2419 TRY_nomem(es =
"Invalid timestamp-resolution: \"");
2423 if (str ==
"year") {
2426 else if (str ==
"month") {
2429 else if (str ==
"day") {
2432 else if (str ==
"hour") {
2435 else if (str ==
"minute") {
2438 else if (str ==
"second") {
2451 directory::const_iterator cdi;
2454 error partial_vault_error =
ERROR(0,
"One or more vault paths were found to be invalid:");
2456 TRY_nomem(es =
"Invalid vault path: \"");
2460 if (a_value.size() == 0)
2465 if (dir.size() == 0) {
2469 for (cdi = dir.begin(); cdi != dir.end(); cdi++) {
2470 if (!is_dir(*cdi)) {
2479 TRY_nomem(es =
"No read access to path: \"");
2486 TRY_nomem(es =
"No write access to path: \"");
2493 TRY_nomem(es =
"No execution access to path: \"");
2502 if (partial_vault_error.size() > 1) {
2503 TRY_nomem(es =
"For paths found matching: \"");
2507 throw(partial_vault_error);
2517 TRY_nomem(es =
"Invalid vault-overflow-behavior value: \"");
2521 if (str ==
"quit") {
2524 else if (str ==
"delete-oldest") {
2527 else if (str ==
"delete-until-free") {
2541 TRY_nomem(es =
"Invalid vault-overflow-blocks value: \"");
2556 TRY_nomem(es =
"Invalid vault-overflow-inodes value: \"");
2571 TRY_nomem(es =
"Invalid vault-selection-behavior value: \"");
2575 if (str ==
"max-free") {
2578 else if (str ==
"round-robin") {
2592 TRY_nomem(es =
"Invalid vault-locking value: \"");
2626 const std::string& a_path,
2629 const std::string& a_block_delimiter,
2630 const bool a_default_context =
false
2665 in.open(a_path.c_str());
2666 if (!in.is_open()) {
2667 TRY_nomem(es =
"Could not open job file: \"");
2670 throw(
ERROR(errno,es));
2682 std::string keyword;
2703 TRY_nomem(es =
"Unexpected end of file, expected \"");
2706 throw(
ERROR(errno,es));
2709 if (keyword.size() == 0)
2711 if (keyword[0] ==
'#')
2718 else if (keyword ==
"archive-path") {
2721 else if (keyword ==
"clear") {
2724 else if (keyword ==
"exclude-from") {
2727 else if (keyword ==
"include-from") {
2730 else if (keyword ==
"groupname") {
2733 else if (keyword ==
"hostname") {
2736 else if (keyword ==
"include") {
2739 else if ((keyword ==
"jobname") && (*
m_delimiter ==
"</job>")) {
2742 else if (keyword ==
"path") {
2745 else if (keyword ==
"rsync-behavior") {
2748 else if (keyword ==
"rsync-connection-type") {
2751 else if (keyword ==
"rsync-hardlink") {
2754 else if (keyword ==
"rsync-multi-hardlink") {
2757 else if (keyword ==
"rsync-multi-hardlink-max") {
2760 else if (keyword ==
"rsync-options") {
2763 else if (keyword ==
"ssh-options") {
2766 else if (keyword ==
"<rsync-options>") {
2769 else if (keyword ==
"<ssh-options>") {
2772 else if (keyword ==
"rsync-remote-user") {
2775 else if (keyword ==
"rsync-remote-path") {
2778 else if (keyword ==
"rsync-remote-port") {
2781 else if (keyword ==
"rsync-remote-module") {
2784 else if (keyword ==
"rsync-retry-count") {
2787 else if (keyword ==
"rsync-retry-delay") {
2790 else if (keyword ==
"rsync-timeout") {
2810 if ((*m_delimiter).size() == 0)
2828 TRY_nomem(es =
"Invalid archive-path value");
2829 TRY((*m_job).archive_path = a_value,es);
2838 TRY_nomem(es =
"Invalid clear value: \"");
2842 if (str ==
"archive-path") {
2845 else if (str ==
"exclude-from") {
2848 else if (str ==
"groupname") {
2851 else if (str ==
"hostname") {
2854 else if (str ==
"include-from") {
2857 else if ((str ==
"jobname") && (*
m_delimiter ==
"</job>")) {
2860 else if (str ==
"paths") {
2863 else if (str ==
"rsync-behavior") {
2866 else if (str ==
"rsync-options") {
2869 else if (str ==
"ssh-options") {
2872 else if (str ==
"rsync-remote-user") {
2875 else if (str ==
"rsync-remotr-port") {
2878 else if (str ==
"rsync-remote-module") {
2881 else if (str ==
"rsync-remote-path") {
2894 directory::const_iterator cdi;
2898 if (a_value.size() == 0) {
2899 TRY_nomem(es =
"Invalid exclude-from path: \"");
2905 if (a_value[0] !=
'/') {
2911 TRY_nomem(es =
"No exclude-from file(s) found: \"");
2915 if (dir.size() == 0)
2918 for (cdi = dir.begin(); cdi != dir.end(); cdi++) {
2919 TRY_nomem((*m_job).excludes.push_back(*cdi));
2928 directory::const_iterator cdi;
2932 if (a_value.size() == 0) {
2933 TRY_nomem(es =
"Invalid include-from path: \"");
2939 if (a_value[0] !=
'/') {
2945 TRY_nomem(es =
"No include-from file(s) found: \"");
2949 if (dir.size() == 0)
2952 for (cdi = dir.begin(); cdi != dir.end(); cdi++) {
2953 TRY_nomem((*m_job).includes.push_back(*cdi));
2960 TRY_nomem((*m_job).groupname = a_value);
2974 directory::const_iterator cdi;
2978 if (a_value.size() == 0) {
2979 TRY_nomem(es =
"Invalid include path: \"");
2985 if (a_value[0] !=
'/') {
2991 TRY_nomem(es =
"No configuration file(s) found: \"");
2995 if (dir.size() == 0)
2998 for (cdi = dir.begin(); cdi != dir.end(); cdi++) {
2999 if (dir.size() > 1) {
3000 TRY_nomem(es =
"For files found matching: \"");
3031 TRY_nomem((*m_job).paths.push_back(a_value));
3040 TRY_nomem(es =
"Invalid rsync-behavior value: \"");
3044 if (str ==
"clear") {
3045 (*m_job).rsync_behavior.clear();
3047 else if (str ==
"reset") {
3048 (*m_job).rsync_behavior.reset();
3051 (*m_job).rsync_behavior.assign(a_value);
3060 TRY_nomem(es =
"Invalid rsync-connection-type value: \"");
3064 if (str ==
"local") {
3067 else if (str ==
"remote") {
3070 else if (str ==
"server") {
3073 else if (str ==
"remote-rsync-local-dir") {
3087 TRY_nomem(es =
"Invalid rsync-hardlink value: \"");
3099 (*m_job).rsync_hardlink =
true;
3109 (*m_job).rsync_hardlink =
false;
3122 TRY_nomem(es =
"Invalid rsync-multi-hardlink value: \"");
3134 (*m_job).rsync_multi_hardlink =
true;
3135 (*m_job).rsync_hardlink =
true;
3145 (*m_job).rsync_multi_hardlink =
false;
3158 TRY_nomem(es =
"Invalid rsync-multi-hardlink-max value: \"");
3164 (*m_job).rsync_multi_hardlink_max = num;
3171 TRY_nomem((*m_job).rsync_options = a_value);
3174 if ((*m_job).rsync_options.size() != 0) {
3175 TRY_nomem((*m_job).rsync_options +=
" ");
3177 TRY_nomem((*m_job).rsync_options += a_value);
3185 TRY_nomem((*m_job).ssh_options = a_value);
3188 if ((*m_job).ssh_options.size() != 0) {
3191 TRY_nomem((*m_job).ssh_options += a_value);
3200 std::string rsync_options;
3209 while ((ch ==
' ') || (ch ==
'\t'))
3211 while (((*
m_in)) && (ch !=
'\n')) {
3216 if ((!(*
m_in)) && (value !=
"</rsync-options>")) {
3217 TRY_nomem(es =
"Unexpected end of file, expected ");
3218 TRY_nomem(es +=
"\"</rsync-options>\" here");
3219 throw(
ERROR(errno,es));
3222 if (value.size() == 0)
3224 if (value[0] ==
'#')
3227 if (value ==
"</rsync-options>") {
3232 if (rsync_options.size() != 0) {
3244 std::string ssh_options;
3253 while ((ch ==
' ') || (ch ==
'\t'))
3255 while (((*
m_in)) && (ch !=
'\n')) {
3260 if ((!(*
m_in)) && (value !=
"</ssh-options>")) {
3261 TRY_nomem(es =
"Unexpected end of file, expected ");
3262 TRY_nomem(es +=
"\"</ssh-options>\" here");
3263 throw(
ERROR(errno,es));
3266 if (value.size() == 0)
3268 if (value[0] ==
'#')
3271 if (value ==
"</ssh-options>") {
3276 if (ssh_options.size() != 0) {
3286 TRY_nomem((*m_job).rsync_remote_user = a_value);
3292 TRY_nomem((*m_job).rsync_remote_path = a_value);
3302 TRY_nomem(es =
"Invalid rsync-remote-port value: \"");
3307 (*m_job).rsync_remote_port = num;
3313 TRY_nomem((*m_job).rsync_remote_module = a_value);
3323 TRY_nomem(es =
"Invalid rsync-retry-count value: \"");
3328 (*m_job).rsync_retry_count = num;
3338 TRY_nomem(es =
"Invalid rsync-retry-delay value: \"");
3343 (*m_job).rsync_retry_delay = num;
3353 TRY_nomem(es =
"Invalid rsync-timeout value: \"");
3358 (*m_job).rsync_timeout = num;
void init(int argc, char const *argv[])
Initialize the configuration manager from rvm's command line options.
uint16 rsync_multi_hardlink_max
std::string reform_path(const std::string &a_path)
Reformat a path to remove double slashes.
rsync_connection_type rsync_connection
void assign(const job &a_job)
Assign values from another job instance.
void parse_exclude_from(const std::string &a_value)
Parse an "exclude-from" command.
const std::string location(void)
Generate a string showing the current location within a configuration file of the parser...
void path(const std::string a_path)
Retrieve information about a pathname.
void parse_rsync_retry_delay(const std::string &a_value)
Parse an "rsync-retry-delay" command.
const std::string & rsync_local_path(void) const
Return the rsync-local-path.
overflow_type m_vault_overflow_behavior
const type & path(const std::string &a_path)
Retrieve a list of paths that match the wildcard path given.
void reset(void)
Clear all values and set some sane default actions.
void check(void)
Perform sanity checks for the configuration settings of this job.
const std::string generate_job_id(void) const
Generate a unique ID string for this job.
const uint16 & vault_overflow_blocks(void) const
Return the vault-overflow-blocks.
void read_job(const std::string &a_path, job &a_job)
Read a job configuration file, used by the "include-job" command.
void parse_path(const std::string &a_value)
Parse a "path" command.
An extended string class.
bool m_delete_old_log_files
configuration_manager()
C'tor.
std::vector< job > jobs_type
uint16 m_io_poll_interval
const value_type operator[](const uint16 a_code) const
Return the action to be taken for a given exit code.
void clear(void)
Reset to a default value.
void parse_clear(const std::string &a_value)
Parse a "clear" command.
Hold configuration data for a single job.
void parse_hostname(const std::string &a_value)
Parse a "hostname" command.
bool executable(const std::string &a_path)
Return true if the file or directory exists and is executable.
const char * get_error_str(const int a_err)
void clear(void)
Clear values.
const value_type default_value(void) const
Return the default action.
void parse(void)
Job context parser.
const std::string * m_path
const std::string & value(void) const
Retrieve the current literal value.
std::vector< std::string > m_vaults
const bool delete_old_log_files(void) const
Return the value of delete-old-log-files.
void push_back(const error_instance &a_e)
void parse_ssh_options_context(const std::string &a_value)
Parse an ssh-options context.
const std::string generate_source_path(const std::string &a_path) const
Generate the source path to be passed to rsync on the command line.
void parse(void)
Global context parser.
void parse_include(const std::string &a_value)
Parse an "include" command.
class rsync_behavior rsync_behavior
const uint16 & io_poll_interval(void) const
Return the number of seconds to sleep between polling for I/O.
void parse_include_job(const std::string &a_value)
Parse an "include-job" command.
void parse_archive_path(const std::string &a_value)
Parse an "archive-path" command.
friend class global_parser
A configuration manager support class: Used to parse a configuration file from the perspective of a j...
const std::string parse_dirname(const std::string &a_path)
Given a path, strip off the basename – like the dirname UNIX command.
const map_type & map_value(void) const
Return an std::map of exit codes to actions.
bool writable(const std::string &a_path)
Return true if the file or directory exists and is writable.
const std::string location(void)
Construct a string with the current location of the parser in a configuration file.
const class timestamp & timestamp(void) const
Return the timestamp of this instance of rvm.
const std::string & log_dir(void) const
Return the log-dir path.
const action_type action(void) const
Return the action rvm is to take.
const uint16 & rsync_parallel(void) const
Return the rsync-parallel.
void parse_delete_old_report_files(const std::string &a_value)
Parse a "delete-old-report-files" command.
const bool delete_old_report_files(void) const
Return the value of delete-old-report-files.
std::string rsync_remote_module
uint16 m_vault_overflow_blocks
void parse_rsync_remote_user(const std::string &a_value)
Parse a "remote-user" command.
void parse_rsync_remote_port(const std::string &a_value)
Parse an "rsync-remote-port" command.
class archive_path archive_path
void default_logdir(const std::string &a_path)
Return the default log-dir.
archive_path_element()
C'tor.
void parse_rsync_multi_hardlink(const std::string &a_value)
Parse an "rsync-multi-hardlink" command.
std::string default_config_path
const uint16 & vault_overflow_inodes(void) const
Return the vault-overflow-inodes.
void parse_vault_overflow_blocks(const std::string &a_value)
Parse a "vault-overflow-blocks" command.
void parse_job(const std::string &a_value)
Parse a job context.
void parse_rsync_connection_type(const std::string &a_value)
Parse an "rsync-connection-type" command.
const vaults_type & vaults(void) const
Return the vaults.
const selection_type & vault_selection_behavior(void) const
Return the vault-selection-behavior.
bool readable(const std::string &a_path)
Return true if the file or directory exists and is readable.
std::pair< cfgfile_type, std::string > cfgfile_element
const std::string common_pathname(void) const
Find the common pathname among all job paths (may be an empty string)
void parse_include(const std::string &a_value)
Parse an "include" command.
void parse_rsync_options_context(const std::string &a_value)
Parse an rsync-options context.
A configuration manager support class: Used to specify a single subdirectory in a path of subdirector...
logging_type m_logging_level
void parse_rsync_hardlink(const std::string &a_value)
Parse an "rsync-hardlink" command.
void parse_delete_command_path(const std::string &a_value)
Parse an "delete-command-path" command.
Retrieve a list of pathnames that match a given wildcard path.
void parse_rsync_behavior(const std::string &a_value)
Parse an "rsync-behavior" command.
void assign(const archive_path &a_class)
Assign an archive-path list from another archive_path instance.
void clear(void)
Reset configuration to default settings.
#define TRY_instead(code, es)
void parse_timestamp_resolution(const std::string &a_value)
Parse a "timestamp-resolution" command.
void parse_rsync_retry_count(const std::string &a_value)
Parse an "rsync-retry-count" command.
const timestamp::resolution_type timestamp_resolution(void) const
Return the timestamp-resolution.
void parse_vault_overflow_behavior(const std::string &a_value)
Parse a "vault-overflow-behavior" command.
void parse_rsync_multi_hardlink_max(const std::string &a_value)
Parse an "rsync-multi-hardlink-max" command.
void parse_rsync_remote_module(const std::string &a_value)
Parse an "rsync-remote-module" command.
const std::string str(void) const
Reconstruct a string from an archive-path list.
void parse_delete_old_log_files(const std::string &a_value)
Parse a "delete-old-log-files" command.
void parse_include_from(const std::string &a_value)
Parse an "include-from" command.
std::string rsync_remote_user
std::string m_default_file
global_parser(const std::string &a_path, uint16 &a_line, std::istream &a_in)
C'tor.
void assign(const timestamp &a_t)
Set the timestamp to the value of another timestamp.
uint16 m_vault_overflow_inodes
A configuration manager support class: Used to specify a unique subdirectory in the archive for each ...
void parse_line(std::istream &a_in, std::string &a_keyword, std::string &a_value)
Parse a keyword/value pair read from a configuration file.
static const uint16 default_behavior
Default behavior.
const std::string generate_archive_path(const std::string &a_path) const
Generate the archive-path subdirectory for this job.
void parse_rsync_timeout(const std::string &a_value)
Parse an "rsync-timeout" command.
void parse_logging_level(const std::string &a_value)
Parse a "loging-level" command.
class timestamp m_timestamp
void read_config(const std::string &a_path)
Read a configuration file, used by the "include" command.
void parse_rsync_remote_path(const std::string &a_value)
Parse an "rsync-remote-path" command.
selection_type m_vault_selection_behavior
void parse_vault_selection_behavior(const std::string &a_value)
Parse a "vault-selection-behavior" command.
bool m_delete_old_report_files
const bool initialized(void) const
Return the initialized state of the configuration manager.
void parse_link_catalog_dir(const std::string &a_value)
Parse a "link-catalog-dir" command.
const type & path(const std::string a_path, const std::string a_filter="*")
Return a vector of strings of a list of files in a subdirectory.
const std::string * m_path
void read_config(const std::string &a_path)
Read a configuration file.
uint16 default_config_line
#define INTERNAL_ERROR(e, s)
std::string rsync_remote_path
std::vector< std::string > vaults_type
void resolution(resolution_type a_r)
Set the timestamp resolution.
void parse_vault_overflow_inodes(const std::string &a_value)
Parse a "vault-overflow-inodes" command.
configuration_manager config
The global configuration manager instance.
void set(void)
Set the timestamp to the current time and date.
estring & lower(void)
Convert all characters to lowercase.
const std::string & link_catalog_dir(void) const
Return the link-catalog-dir path.
void read_job(const std::string &a_path)
Read a job configuration file.
const bool same(std::string s1, std::string s2)
void parse_vault_locking(const std::string &a_value)
Parse a "vault-locking" command.
void parse_vault(const std::string &a_value)
Parse a "vault" command.
void parse_io_poll_interval(const std::string &a_value)
Parse "io-poll-interval" command.
Retrieve information about a file or directory.
void parse_rsync_options(const std::string &a_value)
Parse an "rsync-options" command.
void parse_error_logging_level(const std::string &a_value)
Parse a "error-loging-level" command.
const job & default_job(void) const
Return the default job configuration.
std::string permute_path(const std::string &a_path)
Reformat a path to remove the begining and trailing slashes, and replace all other slashes with under...
void parse_rsync_local_path(const std::string &a_value)
Parse an "rsync-local-path" command.
const bool use_default(void) const
Return whether or not rvm is to try to read it's default configuration file.
void parse_groupname(const std::string &a_value)
Parse a "groupname" command.
A configuration manager support class: Used to map rsync exit codes to actions for rvm to take...
void parse_jobname(const std::string &a_value)
Parse a "jobname" command.
void read_job(const std::string &a_path)
Read a job configuration file, used by the "include" command.
void parse_ssh_options(const std::string &a_value)
Parse an "ssh-options" command.
Keep up with configuration settings for RVM and it's jobs.
#define ERROR_INSTANCE(s)
const std::vector< std::string > generate_ssh_options_vector(void) const
Generate ssh command line options.
const jobs_type & jobs(void) const
Return a list of jobs.
void parse_ssh_local_path(const std::string &a_value)
Parse an "ssh-local-path" command.
void parse_default(const std::string &a_value)
Parse a default job context.
std::string m_link_catalog_dir
void clear(void)
Clear all values and set the default to "retry".
const std::string parse_basename(const std::string &a_path)
Given a path, strip off the directory – like the basename UNIX commane.
job & operator=(const job &a_job)
Assignment.
const element_type & type(void) const
Retrieve the current type.
const std::string str(void) const
Generate a string.
const std::vector< std::string > generate_rsync_options_vector(void) const
Generate rsync command line options.
logging_type m_error_logging_level
const std::string & delete_command_path(void) const
Return the delete-command-path.
const overflow_type & vault_overflow_behavior(void) const
Return the vault-overflow-behavior.
rsync_behavior & operator=(const rsync_behavior &a_class)
Assignment.
const std::string str(void) const
Construct a string of the current value.
archive_path & operator=(const archive_path &a_class)
Assignment.
const bool vault_locking(void) const
Return the vault-locking selection.
void assign(const archive_path_element &a_class)
Assign the value from another archive_path_element instance.
std::map< uint16, value_type > map_type
void reset(void)
Reset to a default value.
Retrieve a list of files in a subdirectory that match a given wildcard filename.
const logging_type & error_logging_level(void) const
Return the error-logging-level.
job_parser(job *a_job, const std::string &a_path, uint16 &a_line, std::istream &a_in, const std::string &a_block_delimiter, const bool a_default_context)
C'tor.
void parse_rsync_parallel(const std::string &a_value)
Parse an "rsync-parallel" command.
const logging_type & logging_level(void) const
Return the logging-level.
bool rsync_multi_hardlink
const std::string & ssh_local_path(void) const
Return the ssh-local-path.
std::string m_ssh_local_path
void assign(const uint16 a_code, const value_type a_action)
Assign an action to be taken for a specific exit code.
void push_back(const archive_path &a_class)
Add elements to the path list from another archive_path instance.
const std::string & default_file(void) const
Return the default configuration filename.
void check(void) const
Perform sanity checks on configuration settings.
void parse_log_dir(const std::string &a_value)
Parse a "log-dir" command.
const std::string * m_delimiter
archive_path_element & operator=(const archive_path_element &a_class)
Assignment.
std::string m_delete_command_path
std::string m_rsync_local_path
std::string rsync_options