• R/O
  • SSH
  • HTTPS

backup-svn: Commit


Commit MetaInfo

Revision10 (tree)
Time2020-01-19 15:32:50
Authorgottfried

Log Message

Create tag for version 1.0

Change Summary

Incremental Difference

--- tags/backup-svn 1.0/backup-svn/BackupSVN.cpp (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/BackupSVN.cpp (revision 10)
@@ -0,0 +1,201 @@
1+
2+#include "BackupSVN.h"
3+#include "IniFile.h"
4+#include "StringTools.h"
5+#include "System.h"
6+#include <iostream>
7+#include <cstdio>
8+#include <cstdint>
9+
10+#define WIN32_LEAN_AND_MEAN
11+#define NOMINMAX
12+#include <Windows.h>
13+
14+using namespace std;
15+
16+
17+cBackupSVN::cBackupSVN(const wchar_t *svnadminpath, const wchar_t *repopath) :
18+ mSvnAdminPath(svnadminpath),
19+ mSvnRepoPath(repopath)
20+{
21+}
22+
23+
24+cBackupSVN::~cBackupSVN()
25+{
26+}
27+
28+int cBackupSVN::run()
29+{
30+ // first read all subdirs
31+ scanRepos();
32+
33+ // then check repository and dump if changed:
34+ int result = checkRepos();
35+
36+ //if all ok, then return 0
37+ return result;
38+}
39+
40+
41+void cBackupSVN::scanRepos()
42+{
43+ mRepolist.clear();
44+
45+ std::wstring pattern(L"*");
46+ WIN32_FIND_DATAW data;
47+ HANDLE hFind;
48+
49+ hFind = FindFirstFileW(pattern.c_str(), &data);
50+ if(hFind != INVALID_HANDLE_VALUE)
51+ {
52+ do
53+ {
54+ if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
55+ {
56+ std::wstring filename = data.cFileName;
57+ if(filename != L"." && filename != L"..")
58+ {
59+ mRepolist.push_back(filename);
60+ }
61+ }
62+ } while(FindNextFileW(hFind, &data) != 0);
63+
64+ FindClose(hFind);
65+ }
66+}
67+
68+int cBackupSVN::checkRepos()
69+{
70+ wstring svnadmin = mSvnAdminPath.c_str();
71+ if(svnadmin.length())
72+ svnadmin += L'/';
73+ svnadmin += L"svnadmin";
74+
75+ // check repository with:
76+ /*
77+ > "svnadmin.exe" info <repopath>
78+ Path: <repopath>
79+ UUID: ########-####-####-####-############
80+ Revisions: 0001
81+ Repository Format: 5
82+ Compatible With Version: 1.10.0
83+ Repository Capability: mergeinfo
84+ Filesystem Type: fsfs
85+ Filesystem Format: 8
86+ FSFS Sharded: yes
87+ FSFS Shard Size: 1000
88+ FSFS Shards Packed: 0/1
89+ FSFS Logical Addressing: yes
90+ Configuration File: <repopath>\db\fsfs.conf
91+ */
92+
93+ int errors = 0;
94+ for(vector<wstring>::const_iterator it = mRepolist.cbegin(); it != mRepolist.cend(); ++it)
95+ {
96+ const wstring &repo = *it;
97+
98+ wstring svnadmininfo = L"\"" + svnadmin + L"\"";
99+ svnadmininfo += L" info ";
100+ svnadmininfo += L"\"" + repo + L"\"";
101+
102+ string svnadminOutput;
103+ errors += cSystem::execCmd(svnadmininfo.c_str(), svnadminOutput);
104+
105+ size_t pos = svnadminOutput.find("Revisions");
106+ if(pos != string::npos)
107+ {
108+ int revision = atoi(svnadminOutput.substr(pos + 10).c_str());
109+
110+ int storedRevision = cIniFile::getInt(L"REVISIONS", repo.c_str(), 0);
111+
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+ }
127+ }
128+
129+ return errors;
130+}
131+
132+bool cBackupSVN::dumpRepos(const wchar_t *svnadmin, const wchar_t *repo)
133+{
134+ wstring backupPath = cIniFile::getString(L"BACKUP", L"PATH", L"");
135+ if(backupPath.length())
136+ backupPath += L'/';
137+ backupPath += repo;
138+
139+ wstring svnAdminDump = L"\"" + wstring(svnadmin) + L"\"";
140+ svnAdminDump += L" dump ";
141+ svnAdminDump += L"\"" + wstring(repo) + L"\"";
142+
143+ wstring outputFile = backupPath + L".dump";
144+
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+ }
155+
156+ string svnadminErrorOutput;
157+ int result = cSystem::execCmd(svnAdminDump.c_str(), outputFile.c_str(), svnadminErrorOutput);
158+
159+ return result == 0;
160+}
161+
162+
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)
169+ {
170+ string filepath;
171+ string oldname;
172+ string newname;
173+
174+ filepath = cStringTools::convertToString(dumpfile);
175+ for(int i = rotates; i >= 0; i--)
176+ {
177+ oldname = filepath;
178+ if(i != 0)
179+ {
180+ char numbuf[20];
181+ sprintf_s(numbuf, ".%d", i);
182+ oldname += numbuf;
183+ }
184+
185+ if(newname.length())
186+ {
187+ result = remove(newname.c_str());
188+ result = rename(oldname.c_str(), newname.c_str());
189+ }
190+
191+ newname = oldname;
192+ }
193+ }
194+ else
195+ {
196+ // no rotate - delete file only
197+ string file = cStringTools::convertToString(dumpfile);
198+ result = remove(file.c_str());
199+ }
200+}
201+
--- tags/backup-svn 1.0/backup-svn/BackupSVN.h (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/BackupSVN.h (revision 10)
@@ -0,0 +1,24 @@
1+#pragma once
2+
3+#include <string>
4+#include <vector>
5+
6+class cBackupSVN
7+{
8+public:
9+ cBackupSVN(const wchar_t *svnadminpath, const wchar_t *repopath);
10+ ~cBackupSVN();
11+
12+ int run();
13+
14+private:
15+ std::wstring mSvnAdminPath;
16+ std::wstring mSvnRepoPath;
17+ std::vector<std::wstring> mRepolist;
18+
19+ void scanRepos();
20+ int checkRepos();
21+ bool dumpRepos(const wchar_t *svnadmin, const wchar_t *repo);
22+ void rotateDump(const wchar_t *dumpfile);
23+};
24+
--- tags/backup-svn 1.0/backup-svn/INSTALL.txt (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/INSTALL.txt (revision 10)
@@ -0,0 +1,16 @@
1+
2+Copy files to your Repository directory
3+
4+open system configuration - Windows task planner
5+and create a new task
6+Name: SVN Backup
7+Action:
8+ start programm
9+ <Path>\backup-svn.exe
10+ <Path>
11+
12+<Path> is the path of your repository
13+
14+
15+svnadmin, version 1.9.7 does not get the "Revisions" number.
16+For this you must use a newer version
\ No newline at end of file
--- tags/backup-svn 1.0/backup-svn/IniFile.cpp (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/IniFile.cpp (revision 10)
@@ -0,0 +1,82 @@
1+
2+#include "IniFile.h"
3+#include "StringTools.h"
4+#include <cstdio>
5+
6+#define WIN32_LEAN_AND_MEAN
7+#define NOMINMAX
8+#include <Windows.h>
9+
10+using namespace std;
11+
12+std::string cIniFile::mFile;
13+std::wstring cIniFile::mwFile;
14+
15+cIniFile::cIniFile()
16+{
17+}
18+
19+
20+cIniFile::~cIniFile()
21+{
22+}
23+
24+
25+bool cIniFile::Init(const char *filename)
26+{
27+ // check if file exists
28+#pragma warning( push )
29+#pragma warning (disable : 4996) //error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
30+ FILE *fp = fopen(filename, "r");
31+ if(fp)
32+ {
33+ fclose(fp);
34+#pragma warning( pop )
35+
36+ mFile = filename;
37+
38+ // Converts the path to wide characters
39+ mwFile = cStringTools::convertToWString(mFile.c_str());
40+ return true;
41+ }
42+
43+ return false;
44+}
45+
46+std::string cIniFile::getString(const char *selection, const char *key, const char *strDefault)
47+{
48+ if(!mFile.length())
49+ return strDefault;
50+
51+ char result[500];
52+
53+ GetPrivateProfileStringA(selection, key, strDefault, result, sizeof(result), mFile.c_str());
54+ return result;
55+}
56+
57+std::wstring cIniFile::getString(const wchar_t *selection, const wchar_t *key, const wchar_t *strDefault)
58+{
59+ if(!mwFile.length())
60+ return strDefault;
61+
62+ wchar_t result[500];
63+
64+ GetPrivateProfileStringW(selection, key, strDefault, result, 500, mwFile.c_str());
65+ //WritePrivateProfileStringW(selection, key, strDefault, mwFile.c_str());
66+ return result;
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+}
--- tags/backup-svn 1.0/backup-svn/IniFile.h (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/IniFile.h (revision 10)
@@ -0,0 +1,27 @@
1+#pragma once
2+
3+#include <string>
4+
5+class cIniFile
6+{
7+public:
8+ cIniFile();
9+ ~cIniFile();
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+ */
15+ static bool Init(const char *filename);
16+
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"");
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+
23+private:
24+ static std::string mFile;
25+ static std::wstring mwFile;
26+};
27+
--- tags/backup-svn 1.0/backup-svn/StringTools.cpp (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/StringTools.cpp (revision 10)
@@ -0,0 +1,46 @@
1+#include "StringTools.h"
2+
3+#include <cassert>
4+
5+#define WIN32_LEAN_AND_MEAN
6+#define NOMINMAX
7+#include <Windows.h>
8+
9+using namespace std;
10+
11+
12+cStringTools::cStringTools()
13+{
14+}
15+
16+
17+cStringTools::~cStringTools()
18+{
19+}
20+
21+
22+std::wstring cStringTools::convertToWString(const char *str)
23+{
24+ // Converts to wide characters
25+ size_t len = strlen(str) + 1;
26+
27+ wchar_t *converted = new wchar_t[len];
28+ MultiByteToWideChar(0, 0, str, len, converted, len);
29+ wstring retval = converted;
30+ delete[] converted;
31+
32+ return retval;
33+}
34+
35+std::string cStringTools::convertToString(const wchar_t *wstr)
36+{
37+ size_t len = wcslen(wstr) * 4 + 1;
38+
39+ char *converted = new char[len];
40+ char DefChar = ' ';
41+ WideCharToMultiByte(CP_ACP, 0, wstr, len, converted, len, &DefChar, NULL);
42+ string retval = converted;
43+ delete[] converted;
44+
45+ return retval;
46+}
--- tags/backup-svn 1.0/backup-svn/StringTools.h (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/StringTools.h (revision 10)
@@ -0,0 +1,15 @@
1+#pragma once
2+
3+#include <string>
4+
5+
6+class cStringTools
7+{
8+public:
9+ cStringTools();
10+ ~cStringTools();
11+
12+ static std::wstring convertToWString(const char *str);
13+ static std::string convertToString(const wchar_t *wstr);
14+};
15+
--- tags/backup-svn 1.0/backup-svn/System.cpp (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/System.cpp (revision 10)
@@ -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+}
--- tags/backup-svn 1.0/backup-svn/System.h (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/System.h (revision 10)
@@ -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+
--- tags/backup-svn 1.0/backup-svn/backup-svn.ini (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/backup-svn.ini (revision 10)
@@ -0,0 +1,28 @@
1+##
2+## This is a example ini file to configure the backup of your repositories
3+##
4+
5+[FILES]
6+# Path where svnadmin found
7+# if no SVNADMIN_PATH is set, the svnadmin is get from default %PATH%
8+# use one of the following.
9+#SVNADMIN_PATH=C:\cygwin64\bin
10+#SVNADMIN_PATH=C:\cygwin\bin
11+#SVNADMIN_PATH=C:\Program Files (x86)\VisualSVN Server\bin
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=D:\Backup\Repositories
19+#Network path
20+#PATH=\\<servername>\backup\Repositories
21+
22+# rotate to keep old backups
23+ROTATE=3
24+
25+
26+# here the revisions stored
27+# when revision isn't changed, we do not create a dump
28+[REVISIONS]
--- tags/backup-svn 1.0/backup-svn/main.cpp (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/main.cpp (revision 10)
@@ -0,0 +1,63 @@
1+
2+#include "stdafx.h"
3+
4+#include "IniFile.h"
5+#include "BackupSVN.h"
6+#include "StringTools.h"
7+#include <direct.h> // _getcwd
8+#include <iostream>
9+
10+using namespace std;
11+
12+
13+int main(int argc, char *argv[])
14+{
15+ std::string app_path;
16+ std::string curr_path;
17+ std::string ini_file;
18+
19+ // Get the current working directory:
20+ {
21+ char *buffer = _getcwd(NULL, 0);
22+ if(!buffer)
23+ perror("_getcwd error");
24+ else
25+ {
26+ curr_path = buffer;
27+ free(buffer);
28+ }
29+ }
30+
31+ // check if we run program from full path
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())
40+ app_path = curr_path;
41+
42+
43+ ini_file = app_path + "/" + "backup-svn.ini";
44+ if(!cIniFile::Init(ini_file.c_str()))
45+ {
46+ ini_file = curr_path + "/" + "backup-svn.ini";
47+ if(!cIniFile::Init(ini_file.c_str()))
48+ cerr << "No INI file found!" << endl;
49+ }
50+
51+ // Converts the path to wide characters
52+ wstring wcurr_path = cStringTools::convertToWString(curr_path.c_str());
53+
54+ //Get path for svnadmin
55+ std::wstring program_wpath = cIniFile::getString(L"FILES", L"SVNADMIN_PATH", L"");
56+ //std::string program_path = cIniFile::getString( "FILES", "SVNADMIN_PATH", "");
57+
58+ cBackupSVN backup(program_wpath.c_str(), wcurr_path.c_str());
59+ int result = backup.run();
60+
61+ return result;
62+}
63+
--- tags/backup-svn 1.0/backup-svn/stdafx.cpp (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/stdafx.cpp (revision 10)
@@ -0,0 +1,8 @@
1+// stdafx.cpp : Quelldatei, die nur die Standard-Includes einbindet.
2+// backup-svn.pch ist der vorkompilierte Header.
3+// stdafx.obj enthält die vorkompilierten Typinformationen.
4+
5+#include "stdafx.h"
6+
7+// TODO: Auf zusätzliche Header verweisen, die in STDAFX.H
8+// und nicht in dieser Datei erforderlich sind.
--- tags/backup-svn 1.0/backup-svn/stdafx.h (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/stdafx.h (revision 10)
@@ -0,0 +1,15 @@
1+// stdafx.h: Includedatei für Standardsystem-Includedateien
2+// oder häufig verwendete projektspezifische Includedateien,
3+// die nur in unregelmäßigen Abständen geändert werden.
4+//
5+
6+#pragma once
7+
8+#include "targetver.h"
9+
10+#include <stdio.h>
11+#include <tchar.h>
12+
13+
14+
15+// TODO: Hier auf zusätzliche Header, die das Programm erfordert, verweisen.
--- tags/backup-svn 1.0/backup-svn/targetver.h (nonexistent)
+++ tags/backup-svn 1.0/backup-svn/targetver.h (revision 10)
@@ -0,0 +1,8 @@
1+#pragma once
2+
3+// Durch Einbeziehen von"SDKDDKVer.h" wird die höchste verfügbare Windows-Plattform definiert.
4+
5+// Wenn Sie die Anwendung für eine frühere Windows-Plattform erstellen möchten, schließen Sie "WinSDKVer.h" ein, und
6+// legen Sie das _WIN32_WINNT-Makro auf die zu unterstützende Plattform fest, bevor Sie "SDKDDKVer.h" einschließen.
7+
8+#include <SDKDDKVer.h>
Show on old repository browser