create dumps working now
@@ -2,7 +2,10 @@ | ||
2 | 2 | #include "BackupSVN.h" |
3 | 3 | #include "IniFile.h" |
4 | 4 | #include "StringTools.h" |
5 | +#include "System.h" | |
5 | 6 | #include <iostream> |
7 | +#include <cstdio> | |
8 | +#include <cstdint> | |
6 | 9 | |
7 | 10 | #define WIN32_LEAN_AND_MEAN |
8 | 11 | #define NOMINMAX |
@@ -87,7 +90,7 @@ | ||
87 | 90 | Configuration File: <repopath>\db\fsfs.conf |
88 | 91 | */ |
89 | 92 | |
90 | - int result = 0; | |
93 | + int errors = 0; | |
91 | 94 | for(vector<wstring>::const_iterator it = mRepolist.cbegin(); it != mRepolist.cend(); ++it) |
92 | 95 | { |
93 | 96 | const wstring &repo = *it; |
@@ -96,88 +99,103 @@ | ||
96 | 99 | svnadmininfo += L" info "; |
97 | 100 | svnadmininfo += L"\"" + repo + L"\""; |
98 | 101 | |
99 | - string strResult = execCmd(svnadmininfo.c_str()); | |
102 | + string svnadminOutput; | |
103 | + errors += cSystem::execCmd(svnadmininfo.c_str(), svnadminOutput); | |
100 | 104 | |
105 | + size_t pos = svnadminOutput.find("Revisions"); | |
106 | + if(pos != string::npos) | |
107 | + { | |
108 | + int revision = atoi(svnadminOutput.substr(pos + 10).c_str()); | |
101 | 109 | |
102 | - cout << strResult << endl; | |
110 | + int storedRevision = cIniFile::getInt(L"REVISIONS", repo.c_str(), 0); | |
103 | 111 | |
104 | - // TODO: if version changed: | |
105 | - //dumpRepos(svnadmin.c_str(), repo.c_str()); | |
112 | + if( revision != storedRevision) | |
113 | + { | |
114 | + if(dumpRepos(svnadmin.c_str(), repo.c_str())) | |
115 | + { | |
116 | + // TODO: compress the dump file | |
117 | + | |
118 | + // Write revisions, when dump created without error | |
119 | + cIniFile::writeInt(L"REVISIONS", repo.c_str(), revision); | |
120 | + } | |
121 | + else | |
122 | + { | |
123 | + errors++; | |
124 | + } | |
125 | + } | |
126 | + } | |
106 | 127 | } |
107 | 128 | |
108 | - return result; | |
129 | + return errors; | |
109 | 130 | } |
110 | 131 | |
111 | -void cBackupSVN::dumpRepos(const wchar_t *svnadmin, const wchar_t *repo) | |
132 | +bool cBackupSVN::dumpRepos(const wchar_t *svnadmin, const wchar_t *repo) | |
112 | 133 | { |
113 | -} | |
134 | + wstring backupPath = cIniFile::getString(L"BACKUP", L"PATH", L""); | |
135 | + if(backupPath.length()) | |
136 | + backupPath += L'/'; | |
137 | + backupPath += repo; | |
114 | 138 | |
139 | + wstring svnAdminDump = L"\"" + wstring(svnadmin) + L"\""; | |
140 | + svnAdminDump += L" dump "; | |
141 | + svnAdminDump += L"\"" + wstring(repo) + L"\""; | |
115 | 142 | |
143 | + wstring outputFile = backupPath + L".dump"; | |
116 | 144 | |
117 | -string cBackupSVN::execCmd(const wchar_t *cmd) | |
118 | -{ | |
119 | - string strResult; | |
120 | - HANDLE hPipeRead, hPipeWrite; | |
145 | + // check if file exists | |
146 | + // Open for read (will fail if file "crt_fopen_s.c" does not exist) | |
147 | + FILE *fp; | |
148 | + errno_t err = _wfopen_s(&fp, outputFile.c_str(), L"r"); | |
149 | + if(!err) | |
150 | + { | |
151 | + fclose(fp); | |
152 | + fp = 0; | |
153 | + rotateDump(outputFile.c_str()); | |
154 | + } | |
121 | 155 | |
122 | - SECURITY_ATTRIBUTES saAttr ={sizeof(SECURITY_ATTRIBUTES)}; | |
123 | - saAttr.bInheritHandle = TRUE; // Pipe handles are inherited by child process. | |
124 | - saAttr.lpSecurityDescriptor = NULL; | |
156 | + string svnadminErrorOutput; | |
157 | + int result = cSystem::execCmd(svnAdminDump.c_str(), outputFile.c_str(), svnadminErrorOutput); | |
125 | 158 | |
126 | - // Create a pipe to get results from child's stdout. | |
127 | - if(!CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0)) | |
128 | - return strResult; | |
159 | + return result == 0; | |
160 | +} | |
129 | 161 | |
130 | - STARTUPINFOW si ={sizeof(STARTUPINFOW)}; | |
131 | - si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; | |
132 | - si.hStdOutput = hPipeWrite; | |
133 | - si.hStdError = hPipeWrite; | |
134 | - si.wShowWindow = SW_HIDE; // Prevents cmd window from flashing. | |
135 | - // Requires STARTF_USESHOWWINDOW in dwFlags. | |
136 | 162 | |
137 | - PROCESS_INFORMATION pi ={0}; | |
138 | - | |
139 | - BOOL fSuccess = CreateProcessW(NULL, (LPWSTR)cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); | |
140 | - if(! fSuccess) | |
163 | +void cBackupSVN::rotateDump(const wchar_t *dumpfile) | |
164 | +{ | |
165 | + int result; | |
166 | + | |
167 | + int rotates = cIniFile::getInt(L"BACKUP", L"ROTATE", 0); | |
168 | + if(rotates) | |
141 | 169 | { |
142 | - CloseHandle(hPipeWrite); | |
143 | - CloseHandle(hPipeRead); | |
144 | - return strResult; | |
145 | - } | |
170 | + string filepath; | |
171 | + string oldname; | |
172 | + string newname; | |
146 | 173 | |
147 | - bool bProcessEnded = false; | |
148 | - for(; !bProcessEnded;) | |
149 | - { | |
150 | - // Give some timeslice (50 ms), so we won't waste 100% CPU. | |
151 | - bProcessEnded = WaitForSingleObject(pi.hProcess, 50) == WAIT_OBJECT_0; | |
152 | - | |
153 | - // Even if process exited - we continue reading, if | |
154 | - // there is some data available over pipe. | |
155 | - for(;;) | |
174 | + filepath = cStringTools::convertToString(dumpfile); | |
175 | + for(int i = rotates; i >= 0; i--) | |
156 | 176 | { |
157 | - char buf[1024]; | |
158 | - DWORD dwRead = 0; | |
159 | - DWORD dwAvail = 0; | |
177 | + oldname = filepath; | |
178 | + if(i != 0) | |
179 | + { | |
180 | + char numbuf[20]; | |
181 | + sprintf_s(numbuf, ".%d", i); | |
182 | + oldname += numbuf; | |
183 | + } | |
160 | 184 | |
161 | - if(!::PeekNamedPipe(hPipeRead, NULL, 0, NULL, &dwAvail, NULL)) | |
162 | - break; | |
185 | + if(newname.length()) | |
186 | + { | |
187 | + result = remove(newname.c_str()); | |
188 | + result = rename(oldname.c_str(), newname.c_str()); | |
189 | + } | |
163 | 190 | |
164 | - if(!dwAvail) // No data available, return | |
165 | - break; | |
166 | - | |
167 | - DWORD readlength = sizeof(buf) - 1; | |
168 | - if(readlength > dwAvail) | |
169 | - readlength = dwAvail; | |
170 | - if(!::ReadFile(hPipeRead, buf, readlength, &dwRead, NULL) || !dwRead) | |
171 | - break; // Error, the child process might ended | |
172 | - | |
173 | - buf[dwRead] = 0; | |
174 | - strResult += buf; | |
191 | + newname = oldname; | |
175 | 192 | } |
176 | - } //for | |
193 | + } | |
194 | + else | |
195 | + { | |
196 | + // no rotate - delete file only | |
197 | + string file = cStringTools::convertToString(dumpfile); | |
198 | + result = remove(file.c_str()); | |
199 | + } | |
200 | +} | |
177 | 201 | |
178 | - CloseHandle(hPipeWrite); | |
179 | - CloseHandle(hPipeRead); | |
180 | - CloseHandle(pi.hProcess); | |
181 | - CloseHandle(pi.hThread); | |
182 | - return strResult; | |
183 | -} |
@@ -18,8 +18,7 @@ | ||
18 | 18 | |
19 | 19 | void scanRepos(); |
20 | 20 | int checkRepos(); |
21 | - void dumpRepos(const wchar_t *svnadmin, const wchar_t *repo); | |
22 | - | |
23 | - std::string execCmd(const wchar_t *cmd); | |
21 | + bool dumpRepos(const wchar_t *svnadmin, const wchar_t *repo); | |
22 | + void rotateDump(const wchar_t *dumpfile); | |
24 | 23 | }; |
25 | 24 |
@@ -9,20 +9,20 @@ | ||
9 | 9 | |
10 | 10 | using namespace std; |
11 | 11 | |
12 | -std::string IniFile::mFile; | |
13 | -std::wstring IniFile::mwFile; | |
12 | +std::string cIniFile::mFile; | |
13 | +std::wstring cIniFile::mwFile; | |
14 | 14 | |
15 | -IniFile::IniFile() | |
15 | +cIniFile::cIniFile() | |
16 | 16 | { |
17 | 17 | } |
18 | 18 | |
19 | 19 | |
20 | -IniFile::~IniFile() | |
20 | +cIniFile::~cIniFile() | |
21 | 21 | { |
22 | 22 | } |
23 | 23 | |
24 | 24 | |
25 | -bool IniFile::Init(const char *filename) | |
25 | +bool cIniFile::Init(const char *filename) | |
26 | 26 | { |
27 | 27 | // check if file exists |
28 | 28 | #pragma warning( push ) |
@@ -43,7 +43,7 @@ | ||
43 | 43 | return false; |
44 | 44 | } |
45 | 45 | |
46 | -std::string IniFile::getString(const char *selection, const char *key, const char *strDefault) | |
46 | +std::string cIniFile::getString(const char *selection, const char *key, const char *strDefault) | |
47 | 47 | { |
48 | 48 | if(!mFile.length()) |
49 | 49 | return strDefault; |
@@ -54,7 +54,7 @@ | ||
54 | 54 | return result; |
55 | 55 | } |
56 | 56 | |
57 | -std::wstring IniFile::getString(const wchar_t *selection, const wchar_t *key, const wchar_t *strDefault) | |
57 | +std::wstring cIniFile::getString(const wchar_t *selection, const wchar_t *key, const wchar_t *strDefault) | |
58 | 58 | { |
59 | 59 | if(!mwFile.length()) |
60 | 60 | return strDefault; |
@@ -65,3 +65,18 @@ | ||
65 | 65 | //WritePrivateProfileStringW(selection, key, strDefault, mwFile.c_str()); |
66 | 66 | return result; |
67 | 67 | } |
68 | + | |
69 | + | |
70 | +int cIniFile::getInt(const wchar_t *selection, const wchar_t *key, int default) | |
71 | +{ | |
72 | + int result = GetPrivateProfileIntW(selection, key, default, mwFile.c_str()); | |
73 | + | |
74 | + return result; | |
75 | +} | |
76 | + | |
77 | +void cIniFile::writeInt(const wchar_t *selection, const wchar_t *key, int value) | |
78 | +{ | |
79 | + wchar_t buf[50]; | |
80 | + wsprintfW(buf, L"%d", value); | |
81 | + WritePrivateProfileStringW(selection, key, buf, mwFile.c_str()); | |
82 | +} |
@@ -2,17 +2,24 @@ | ||
2 | 2 | |
3 | 3 | #include <string> |
4 | 4 | |
5 | -class IniFile | |
5 | +class cIniFile | |
6 | 6 | { |
7 | 7 | public: |
8 | - IniFile(); | |
9 | - ~IniFile(); | |
8 | + cIniFile(); | |
9 | + ~cIniFile(); | |
10 | 10 | |
11 | + /* | |
12 | + * Use absolute path for ini file. | |
13 | + * otherwise the ini file is stored in C:\Windows path, where we do not have rights to write file | |
14 | + */ | |
11 | 15 | static bool Init(const char *filename); |
12 | 16 | |
13 | - static std::string getString(const char *selection, const char *key, const char *strDefault); | |
14 | - static std::wstring getString(const wchar_t *selection, const wchar_t *key, const wchar_t *strDefault); | |
17 | + static std::string getString(const char *selection, const char *key, const char *strDefault = ""); | |
18 | + static std::wstring getString(const wchar_t *selection, const wchar_t *key, const wchar_t *strDefault = L""); | |
15 | 19 | |
20 | + static int getInt(const wchar_t *selection, const wchar_t *key, int default = 0); | |
21 | + static void writeInt(const wchar_t *selection, const wchar_t *key, int value); | |
22 | + | |
16 | 23 | private: |
17 | 24 | static std::string mFile; |
18 | 25 | static std::wstring mwFile; |
@@ -0,0 +1,222 @@ | ||
1 | +#include "System.h" | |
2 | + | |
3 | +#define WIN32_LEAN_AND_MEAN | |
4 | +#define NOMINMAX | |
5 | +#include <Windows.h> | |
6 | + | |
7 | +#include <iostream> | |
8 | +#include <cstdint> | |
9 | + | |
10 | +using namespace std; | |
11 | + | |
12 | + | |
13 | +cSystem::cSystem() | |
14 | +{ | |
15 | +} | |
16 | + | |
17 | + | |
18 | +cSystem::~cSystem() | |
19 | +{ | |
20 | +} | |
21 | + | |
22 | +int cSystem::execCmd(const wchar_t *cmd, std::string &out) | |
23 | +{ | |
24 | + HANDLE hPipeRead, hPipeWrite; | |
25 | + | |
26 | + out.clear(); | |
27 | + wcout << L"RUN> "<< cmd << endl; | |
28 | + | |
29 | + SECURITY_ATTRIBUTES saAttr = {sizeof(SECURITY_ATTRIBUTES)}; | |
30 | + saAttr.bInheritHandle = TRUE; // Pipe handles are inherited by child process. | |
31 | + saAttr.lpSecurityDescriptor = NULL; | |
32 | + | |
33 | + // Create a pipe to get results from child's stdout. | |
34 | + if(!CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0)) | |
35 | + return -1; | |
36 | + | |
37 | + STARTUPINFOW si = {sizeof(STARTUPINFOW)}; | |
38 | + si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; | |
39 | + si.hStdOutput = hPipeWrite; | |
40 | + si.hStdError = hPipeWrite; | |
41 | + si.wShowWindow = SW_HIDE; // Prevents cmd window from flashing. | |
42 | + // Requires STARTF_USESHOWWINDOW in dwFlags. | |
43 | + | |
44 | + PROCESS_INFORMATION pi = {0}; | |
45 | + | |
46 | + BOOL success = CreateProcessW(NULL, (LPWSTR)cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); | |
47 | + if(!success) | |
48 | + { | |
49 | + CloseHandle(hPipeWrite); | |
50 | + CloseHandle(hPipeRead); | |
51 | + return -1; | |
52 | + } | |
53 | + | |
54 | + uint32_t bProcessEnded = 0; | |
55 | + for(; !bProcessEnded;) | |
56 | + { | |
57 | + // Give some timeslice (50 ms), so we won't waste 100% CPU. | |
58 | + bProcessEnded = WaitForSingleObject(pi.hProcess, 50) == WAIT_OBJECT_0; | |
59 | + | |
60 | + // Even if process exited - we continue reading, if | |
61 | + // there is some data available over pipe. | |
62 | + for(;;) | |
63 | + { | |
64 | + char buf[1024]; | |
65 | + DWORD dwRead = 0; | |
66 | + DWORD dwAvail = 0; | |
67 | + | |
68 | + if(!PeekNamedPipe(hPipeRead, NULL, 0, NULL, &dwAvail, NULL)) | |
69 | + break; | |
70 | + | |
71 | + // No data available? | |
72 | + if(!dwAvail) | |
73 | + break; | |
74 | + | |
75 | + if(!ReadFile(hPipeRead, buf, sizeof(buf) - 1, &dwRead, NULL) || !dwRead) | |
76 | + break; // Error, the child process might ended | |
77 | + | |
78 | + string cmdOutput = string(buf, static_cast<size_t>(dwRead)); | |
79 | + cout << cmdOutput; | |
80 | + out += cmdOutput; | |
81 | + } | |
82 | + } | |
83 | + | |
84 | + DWORD exit_code = (DWORD)-1; | |
85 | + BOOL result = GetExitCodeProcess(pi.hProcess, &exit_code); | |
86 | + if(!result) | |
87 | + std::cerr << "GetExitCodeProcess() failure: " << GetLastError() << "\n"; | |
88 | + | |
89 | + CloseHandle(hPipeWrite); | |
90 | + CloseHandle(hPipeRead); | |
91 | + CloseHandle(pi.hProcess); | |
92 | + CloseHandle(pi.hThread); | |
93 | + return exit_code; | |
94 | +} | |
95 | + | |
96 | +int cSystem::execCmd(const wchar_t *cmd, const wchar_t *stdout_file, std::string &outErr) | |
97 | +{ | |
98 | + HANDLE hPipeRead, hPipeWrite; | |
99 | + HANDLE hStdOut; | |
100 | + | |
101 | + outErr.clear(); | |
102 | + wcout << L"RUN> "<< cmd << endl; | |
103 | + | |
104 | + SECURITY_ATTRIBUTES saAttr = {sizeof(SECURITY_ATTRIBUTES)}; | |
105 | + saAttr.bInheritHandle = TRUE; // Pipe handles are inherited by child process. | |
106 | + saAttr.lpSecurityDescriptor = NULL; | |
107 | + | |
108 | + // Create a pipe to get results from child's stderr. | |
109 | + if(!CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0)) | |
110 | + return -1; | |
111 | + | |
112 | + SECURITY_ATTRIBUTES sa; | |
113 | + sa.nLength = sizeof(sa); | |
114 | + sa.bInheritHandle = TRUE; | |
115 | + sa.lpSecurityDescriptor = NULL; | |
116 | + | |
117 | + // Create a file to save results from childs stdout. | |
118 | + hStdOut = CreateFileW(stdout_file, // name of the write | |
119 | + GENERIC_WRITE, // open for writing | |
120 | + FILE_SHARE_WRITE|FILE_SHARE_READ, // share mode | |
121 | + &sa, // default security | |
122 | + CREATE_NEW, // create new file | |
123 | + FILE_ATTRIBUTE_NORMAL, // normal file | |
124 | + NULL); // no attr. template | |
125 | + if(hStdOut == INVALID_HANDLE_VALUE) | |
126 | + { | |
127 | + std::wcerr << L"CreateFile() failure: " << outputError() << endl; | |
128 | + CloseHandle(hPipeWrite); | |
129 | + CloseHandle(hPipeRead); | |
130 | + return -1; | |
131 | + } | |
132 | + | |
133 | + STARTUPINFOW si = {sizeof(STARTUPINFOW)}; | |
134 | + si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; | |
135 | + si.hStdOutput = hStdOut; | |
136 | + si.hStdError = hPipeWrite; | |
137 | + si.wShowWindow = SW_HIDE; // Prevents cmd window from flashing. | |
138 | + // Requires STARTF_USESHOWWINDOW in dwFlags. | |
139 | + | |
140 | + PROCESS_INFORMATION pi = {0}; | |
141 | + | |
142 | + BOOL success = CreateProcessW(NULL, (LPWSTR)cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); | |
143 | + if(!success) | |
144 | + { | |
145 | + CloseHandle(hStdOut); | |
146 | + CloseHandle(hPipeWrite); | |
147 | + CloseHandle(hPipeRead); | |
148 | + return -1; | |
149 | + } | |
150 | + | |
151 | + uint32_t bProcessEnded = 0; | |
152 | + for(; !bProcessEnded;) | |
153 | + { | |
154 | + // Give some timeslice (50 ms), so we won't waste 100% CPU. | |
155 | + bProcessEnded = WaitForSingleObject(pi.hProcess, 50) == WAIT_OBJECT_0; | |
156 | + | |
157 | + // Even if process exited - we continue reading, if | |
158 | + // there is some data available over pipe. | |
159 | + for(;;) | |
160 | + { | |
161 | + char buf[1024]; | |
162 | + DWORD dwRead = 0; | |
163 | + DWORD dwAvail = 0; | |
164 | + | |
165 | + if(!PeekNamedPipe(hPipeRead, NULL, 0, NULL, &dwAvail, NULL)) | |
166 | + break; | |
167 | + | |
168 | + // No data available? | |
169 | + if(!dwAvail) | |
170 | + break; | |
171 | + | |
172 | + if(!ReadFile(hPipeRead, buf, sizeof(buf) - 1, &dwRead, NULL) || !dwRead) | |
173 | + break; // Error, the child process might ended | |
174 | + | |
175 | + string cmdOutput = string(buf, static_cast<size_t>(dwRead)); | |
176 | + cout << cmdOutput; | |
177 | + outErr += cmdOutput; | |
178 | + } | |
179 | + } | |
180 | + | |
181 | + DWORD exit_code = (DWORD)-1; | |
182 | + BOOL result = GetExitCodeProcess(pi.hProcess, &exit_code); | |
183 | + if(!result) | |
184 | + std::wcerr << L"GetExitCodeProcess() failure: " << outputError() << endl; | |
185 | + | |
186 | + CloseHandle(hStdOut); | |
187 | + CloseHandle(hPipeWrite); | |
188 | + CloseHandle(hPipeRead); | |
189 | + CloseHandle(pi.hProcess); | |
190 | + CloseHandle(pi.hThread); | |
191 | + return exit_code; | |
192 | +} | |
193 | + | |
194 | + | |
195 | +std::wstring cSystem::outputError() | |
196 | +{ | |
197 | + wstring output; | |
198 | + LPVOID lpMsgBuf; | |
199 | + DWORD last_error = GetLastError(); | |
200 | + | |
201 | + FormatMessageW( | |
202 | + FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
203 | + FORMAT_MESSAGE_FROM_SYSTEM | | |
204 | + FORMAT_MESSAGE_IGNORE_INSERTS, | |
205 | + NULL, | |
206 | + last_error, | |
207 | + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
208 | + (LPTSTR)&lpMsgBuf, | |
209 | + 0, NULL); | |
210 | + | |
211 | + // Display the error message and exit the process | |
212 | + wchar_t numbuf[50]; | |
213 | + wsprintfW(numbuf, L"%d: ", last_error); | |
214 | + output = numbuf; | |
215 | + output += static_cast<wchar_t*>(lpMsgBuf); | |
216 | + | |
217 | + LocalFree(lpMsgBuf); | |
218 | + | |
219 | + //MessageBoxW(NULL, output.c_str(), TEXT("Error"), MB_OK); | |
220 | + | |
221 | + return output; | |
222 | +} |
@@ -0,0 +1,25 @@ | ||
1 | +#pragma once | |
2 | + | |
3 | +#include <string> | |
4 | + | |
5 | + | |
6 | +class cSystem | |
7 | +{ | |
8 | +public: | |
9 | + cSystem(); | |
10 | + ~cSystem(); | |
11 | + | |
12 | + /** | |
13 | + * execute command and store output (sdtout, stderr) to [out] | |
14 | + */ | |
15 | + static int execCmd(const wchar_t *cmd, std::string &out); | |
16 | + /** | |
17 | + * execute command | |
18 | + * store stdout to a file, write stderr to outErr | |
19 | + */ | |
20 | + static int execCmd(const wchar_t *cmd, const wchar_t *stdout_file, std::string &outErr); | |
21 | + | |
22 | +private: | |
23 | + static std::wstring outputError(); | |
24 | +}; | |
25 | + |
@@ -10,3 +10,17 @@ | ||
10 | 10 | #SVNADMIN_PATH=C:\cygwin\bin |
11 | 11 | #SVNADMIN_PATH=C:\Program Files (x86)\VisualSVN Server\bin |
12 | 12 | SVNADMIN_PATH=C:\Program Files\TortoiseSVN\bin |
13 | + | |
14 | + | |
15 | +[BACKUP] | |
16 | +# Path where the backup files created | |
17 | +# When no path is given, the backup stored in current working directory | |
18 | +PATH= | |
19 | + | |
20 | +# rotate to keep old backups | |
21 | +ROTATE=3 | |
22 | + | |
23 | + | |
24 | +# here the revisions stored | |
25 | +# when revision isn't changed, we do not create a dump | |
26 | +[REVISIONS] |
@@ -29,19 +29,22 @@ | ||
29 | 29 | } |
30 | 30 | |
31 | 31 | // check if we run program from full path |
32 | - std::string filepath = argv[0]; | |
33 | - size_t pos = filepath.find_last_of("/\\"); | |
34 | - if(pos != std::string::npos) | |
35 | - app_path = std::string(filepath.c_str(), pos); | |
36 | - else | |
32 | + if(argc > 0) | |
33 | + { | |
34 | + std::string filepath = argv[0]; | |
35 | + size_t pos = filepath.find_last_of("/\\"); | |
36 | + if(pos != std::string::npos) | |
37 | + app_path = std::string(filepath.c_str(), pos); | |
38 | + } | |
39 | + if(!app_path.length()) | |
37 | 40 | app_path = curr_path; |
38 | 41 | |
39 | 42 | |
40 | 43 | ini_file = app_path + "/" + "backup-svn.ini"; |
41 | - if(!IniFile::Init(ini_file.c_str())) | |
44 | + if(!cIniFile::Init(ini_file.c_str())) | |
42 | 45 | { |
43 | 46 | ini_file = curr_path + "/" + "backup-svn.ini"; |
44 | - if(!IniFile::Init(ini_file.c_str())) | |
47 | + if(!cIniFile::Init(ini_file.c_str())) | |
45 | 48 | cerr << "No INI file found!" << endl; |
46 | 49 | } |
47 | 50 |
@@ -49,8 +52,8 @@ | ||
49 | 52 | wstring wcurr_path = cStringTools::convertToWString(curr_path.c_str()); |
50 | 53 | |
51 | 54 | //Get path for svnadmin |
52 | - std::wstring program_wpath = IniFile::getString(L"FILES", L"SVNADMIN_PATH", L""); | |
53 | - //std::string program_path = IniFile::getString( "FILES", "SVNADMIN_PATH", ""); | |
55 | + std::wstring program_wpath = cIniFile::getString(L"FILES", L"SVNADMIN_PATH", L""); | |
56 | + //std::string program_path = cIniFile::getString( "FILES", "SVNADMIN_PATH", ""); | |
54 | 57 | |
55 | 58 | cBackupSVN backup(program_wpath.c_str(), wcurr_path.c_str()); |
56 | 59 | int result = backup.run(); |