Created
September 16, 2016 22:35
-
-
Save DreamVB/dd2b6977c4d0ba47e09d1fbc5fedfeec to your computer and use it in GitHub Desktop.
Backup Files and Folders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
bBackup folder copy | |
Version 4 | |
By Ben a.k.a DreamVB | |
*/ | |
#include <iostream> | |
#include <Windows.h> | |
#include <string> | |
#include <algorithm> | |
#include <conio.h> | |
using namespace std; | |
using std::cout; | |
using std::endl; | |
int Copyed = 0; | |
int Skipped = 0; | |
// | |
bool OverReadOnly = false; | |
bool bCopyFiles = true; | |
bool NoMsg = false; | |
bool ShowFullName = false; | |
bool ShowStatusInfo = false; | |
bool ShowStartMsg = false; | |
bool SetAchiveOnlyAttr = false; | |
string sStatusA = ""; | |
string sStatusB = ""; | |
string LCase(string src) | |
{ | |
string Temp = src; | |
std::transform(Temp.begin(), Temp.end(), Temp.begin(), ::tolower); | |
return Temp; | |
} | |
string FixPath(string src){ | |
if (src[src.length() - 1] != '\\'){ | |
return src + "\\"; | |
} | |
return src; | |
} | |
bool FileExists(string filename){ | |
//Check if a file was found. | |
if (GetFileAttributesA(filename.c_str()) == INVALID_FILE_ATTRIBUTES){ | |
return false; | |
} | |
return true; | |
} | |
bool DirExists(string filename){ | |
if ((GetFileAttributesA(filename.c_str()) != FILE_ATTRIBUTE_DIRECTORY)){ | |
return false; | |
} | |
return true; | |
} | |
void MyCreateDir(string PathName){ | |
int i = 0; | |
int j = 0; | |
string sPart = ""; | |
string sDir = ""; | |
//Append end backslash. | |
if (!PathName[PathName.length() - 1] != '\\'){ | |
PathName += "\\"; | |
} | |
// | |
while (i < PathName.length()){ | |
if (PathName[i] == '\\'){ | |
//The path to create | |
sDir += sPart + "\\"; | |
//Check for folder. | |
if ((GetFileAttributesA(sDir.c_str()) & FILE_ATTRIBUTE_DIRECTORY)){ | |
//Create folder | |
CreateDirectoryA(sDir.c_str(), NULL); | |
} | |
//Clear parts. | |
sPart.clear(); | |
} | |
else{ | |
//Split the string by backslash | |
sPart += PathName[i]; | |
} | |
//INC counter | |
i++; | |
} | |
sPart.clear(); | |
sDir.clear(); | |
} | |
void DirTree(string Path, string lzDestPath, string FileType, bool AllDirs){ | |
HANDLE f = 0; | |
WIN32_FIND_DATAA wfd; | |
string lzPath = ""; | |
string lzCopyTo = ""; | |
string NewPath = ""; | |
string lzSrcFile = ""; | |
string lzDestFile = ""; | |
string Temp = ""; | |
string fExt = ""; | |
int pos = string::npos; | |
//Append backslash to path. | |
lzPath = FixPath(Path); | |
//Find first file. | |
f = FindFirstFileA((lzPath + "*.*").c_str(), &wfd); | |
//Check for inaild path. | |
if (f == INVALID_HANDLE_VALUE){ | |
cout << "Folder or files not found." << endl << lzPath.c_str() << endl; | |
FindClose(f); | |
exit(1); | |
} | |
//Gets the list of files | |
do{ | |
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){ | |
//Build file path | |
if (wfd.cFileName[0] != 46){ | |
NewPath = FixPath(lzPath + wfd.cFileName); | |
//Scan all sub folders. | |
if (AllDirs){ | |
if (DirExists(NewPath)){ | |
DirTree(NewPath, lzDestPath, FileType, AllDirs); | |
} | |
} | |
} | |
} | |
else{ | |
if (FileType.length() != 0){ | |
fExt = LCase(wfd.cFileName); | |
pos = fExt.find_last_of('.'); | |
if (pos != string::npos){ | |
fExt.erase(0, pos); | |
if (fExt == FileType){ | |
//Set src filename | |
lzSrcFile = lzPath + wfd.cFileName; | |
} | |
} | |
} | |
else{ | |
//Set src filename | |
lzSrcFile = lzPath + wfd.cFileName; | |
} | |
//Test if we have a filename. | |
if (lzSrcFile.length() != 0){ | |
//Set dest filename | |
Temp = lzSrcFile; | |
pos = Temp.find_first_of('\\'); | |
if (pos != string::npos){ | |
Temp.erase(0, pos + 1); | |
} | |
//Set dest filename | |
lzDestFile = lzDestPath + Temp; | |
//Extract the dest full path. | |
pos = lzDestFile.find_last_of('\\'); | |
if (pos != string::npos){ | |
lzCopyTo = lzDestFile.substr(0, pos); | |
} | |
//Create destination folders | |
if (!DirExists(lzCopyTo)){ | |
MyCreateDir(lzCopyTo); | |
} | |
//Check if copying files | |
if (bCopyFiles){ | |
//Check if writeing over old file. | |
if (OverReadOnly){ | |
if (FileExists(lzDestFile)){ | |
//Remove all file attrib and set to normal | |
SetFileAttributesA(lzDestFile.c_str(), FILE_ATTRIBUTE_NORMAL); | |
} | |
} | |
//Copy the src file over to the folder. | |
if (!CopyFileA(lzSrcFile.c_str(), lzDestFile.c_str(), false)) { | |
if (!NoMsg){ | |
if (ShowFullName){ | |
cout << lzDestFile.c_str() << sStatusB << endl; | |
} | |
else{ | |
cout << wfd.cFileName << sStatusB << endl; | |
} | |
Skipped++; | |
} | |
} | |
else{ | |
if (!NoMsg){ | |
if (ShowFullName){ | |
cout << lzDestFile.c_str() << sStatusA << endl; | |
} | |
else{ | |
cout << wfd.cFileName << sStatusA << endl; | |
} | |
Copyed++; | |
} | |
//Set file attrib to achive | |
if (SetAchiveOnlyAttr){ | |
SetFileAttributesA(lzDestFile.c_str(), FILE_ATTRIBUTE_ARCHIVE); | |
} | |
} | |
lzSrcFile.clear(); | |
Temp.clear(); | |
} | |
} | |
} | |
} while (FindNextFileA(f, &wfd) != 0); | |
//Close file | |
FindClose(f); | |
} | |
int main(int argc, char *argv[]){ | |
string Temp = ""; | |
string DeskFolder = ""; | |
string fExt = ""; | |
string Flags = ""; | |
bool ScanAllDirs = false; | |
int pos = string::npos; | |
int i = 3; | |
//Check for help switch | |
if (argc == 2){ | |
Flags = argv[1]; | |
//If help switch display online help | |
if (Flags == "/?"){ | |
cout << "Backup Folders version 3.1" << endl << endl; | |
cout << argv[0] << " <source> <destination> [/A] [/C] [/D] [/F] [/I] [/Q] [/R] [/S] [/W]" << endl << endl; | |
cout << " source Specifies the folder with the file(s) to copy." << endl; | |
cout << " destination Specifies were the file(s) should be copied to." << endl; | |
cout << " /A Sets the destination files(a) to achive attribute." << endl; | |
cout << " /D When set only folders structures are created." << endl; | |
cout << " /F When set displays the full filename being copied." << endl; | |
cout << " /I When set file status is shown." << endl; | |
cout << " /Q When set no messages are displayed while copying." << endl; | |
cout << " /R Writes over files that are read-only." << endl; | |
cout << " /S When set all sub folders are included in backup." << endl; | |
cout << " /W Displays a message and waits for a key press." << endl; | |
cout << endl; | |
exit(1); | |
} | |
exit(1); | |
} | |
// | |
//Check argv | |
if (argc < 3){ | |
cout << "Usage: " << argv[0] << " <source> <destination> [options]" << endl << endl; | |
cout << "For more information see " << argv[0] << " /?" << endl; | |
exit(1); | |
} | |
//Get other args | |
while (i < argc){ | |
Flags = LCase(argv[i]); | |
//All files attributes are set to achive when set | |
if (Flags == "/a"){ | |
SetAchiveOnlyAttr = true; | |
} | |
//If set all sub folders are scanned. | |
if (Flags == "/s"){ | |
ScanAllDirs = true; | |
} | |
//Ovwerwrite read only files. | |
if (Flags == "/r"){ | |
OverReadOnly = true; | |
} | |
//if set no on-screen messages are shown | |
if (Flags == "/q"){ | |
NoMsg = true; | |
} | |
//When set only folder structure is created. | |
if (Flags == "/d"){ | |
bCopyFiles = false; | |
} | |
//Displays full filenames | |
if (Flags == "/f"){ | |
ShowFullName = true; | |
} | |
//Display file status if set | |
if (Flags == "/i"){ | |
ShowStatusInfo = true; | |
} | |
//Display a message before copying if set | |
if (Flags == "/w"){ | |
ShowStartMsg = true; | |
} | |
//INC counter | |
i++; | |
} | |
cout << "The copy process is about to begin press any key to continue."; | |
if (ShowStartMsg){ | |
while (1){ | |
if (kbhit()){ | |
break; | |
} | |
} | |
} | |
if (ShowStatusInfo){ | |
sStatusA = "....OK"; | |
sStatusB = "....Skipped"; | |
} | |
//Source folder | |
Temp = argv[1]; | |
//Destination folder | |
DeskFolder = FixPath(argv[2]); | |
pos = Temp.find('*'); | |
if (pos != string::npos){ | |
fExt = LCase(Temp.substr(pos + 1)); | |
if (fExt == ".*"){ | |
fExt = ""; | |
} | |
//Fix the path | |
Temp.erase(pos); | |
} | |
//Call DirTree procedure | |
DirTree(Temp, DeskFolder, fExt, ScanAllDirs); | |
if (!NoMsg){ | |
//Display results | |
cout << endl; | |
cout << "Copyed : " << Copyed << endl; | |
cout << "Skipped : " << Skipped << endl; | |
} | |
return EXIT_SUCCESS; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment