|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
// Utility.cc
|
|
|
|
|
|
//
|
|
|
|
|
|
// Utility functions for BuildDistribution.
|
|
|
|
|
|
//
|
|
|
|
|
|
// (C) Copyright 2010 ARM Research Labs, LLC See
|
|
|
|
|
|
// www.armresearch.com for the copyright terms.
|
|
|
|
|
|
//
|
|
|
|
|
|
// $Id$
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
|
#include <tchar.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
#include <sstream>
|
|
|
|
|
|
#include <iterator>
|
|
|
|
|
|
|
|
|
|
|
|
#include "Utility.h"
|
|
|
|
|
|
|
|
|
|
|
|
static DWORD LastError = 0; // Last value from GetLastError(). Needed because
|
|
|
|
|
|
// GetLastError() doesn't return the correct value
|
|
|
|
|
|
// after an exception is thrown.
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
OutputUsage(std::string DefaultTempPath) {
|
|
|
|
|
|
std::cout <<
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"Usage:\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
" BuildDistribution -d DistPath -t TempPath\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
" where DistPath is the path of the distribution\n"
|
|
|
|
|
|
" (e.g. SNFMultiSDK_Windows_3.1, and TempPath is the name of the\n"
|
|
|
|
|
|
" directory to use for temporary storage. TempPath must exist.\n"
|
|
|
|
|
|
" The default value of TempPath is '" << DefaultTempPath << "'.\n"
|
|
|
|
|
|
;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
OutputHelp() {
|
|
|
|
|
|
std::cout <<
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"The program does the following:\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
" 1) For each directory DIR that appears in DistPath and also in\n"
|
|
|
|
|
|
" DistPath\\..:\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
" a) Delete the contents of DistPath/DIR, except for .svn.\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
" b) Copy the contents of DistPath\\..\\DIR to DistPath\\DIR, except\n"
|
|
|
|
|
|
" for .svn.\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
" 2) Create a temporary directory TempPath/DistName, where DistName is\n"
|
|
|
|
|
|
" the directory name of DistPath (e.g. if DistName is\n"
|
|
|
|
|
|
" c:\\dir1\\dir2\\SNFMultiSDK_Windows_3.1, then DistName is\n"
|
|
|
|
|
|
" SNFMultiSDK_Windows_3.1).\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
" 3) For each directory DIR that appears in DistPath and also in\n"
|
|
|
|
|
|
" DistPath\\..:\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
" a) Copy all files from DistPath/DIR to TempPath/DistName, except\n"
|
|
|
|
|
|
" for .svn.\n\n"
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
OutputErrorMessage(std::string Message) {
|
|
|
|
|
|
LPVOID lpMsgBuf;
|
|
|
|
|
|
|
|
|
|
|
|
if (LastError != 0) {
|
|
|
|
|
|
|
|
|
|
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
|
|
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
|
|
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
|
|
|
NULL,
|
|
|
|
|
|
LastError,
|
|
|
|
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
|
|
|
|
(LPTSTR) &lpMsgBuf,
|
|
|
|
|
|
0,
|
|
|
|
|
|
NULL);
|
|
|
|
|
|
std::cerr << Message << ": " << (LPCSTR) lpMsgBuf;
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
|
|
std::cerr << Message << "\n";
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Case-insensitive search for a specified string in a container of strings.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \param[in] Needle is the string to search for.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \param[in] Haystack is the container of strings to search.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \returns true if Needle is in Haystack (case-insensitive
|
|
|
|
|
|
// comparison), false otherwise.
|
|
|
|
|
|
//
|
|
|
|
|
|
bool IsInContainer(std::string Needle, StringContainer Haystack);
|
|
|
|
|
|
|
|
|
|
|
|
/// Get a list of directories in a specified path.
|
|
|
|
|
|
//
|
|
|
|
|
|
// This function returns a list of directories in the specified path,
|
|
|
|
|
|
// excluding a specified list of names.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \param[in] DistPath is the path to search.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \param[in] ExcludeName contains the names to exclude.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \returns a list of directory names in the specified path, excluding
|
|
|
|
|
|
// names in ExcludeNames.
|
|
|
|
|
|
//
|
|
|
|
|
|
StringContainer GetDirectoryList(std::string DistPath,
|
|
|
|
|
|
StringContainer ExcludeName);
|
|
|
|
|
|
|
|
|
|
|
|
/// Get a list of files in a specified path.
|
|
|
|
|
|
//
|
|
|
|
|
|
// This function returns a list of files in the specified path,
|
|
|
|
|
|
// excluding a specified list of names.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \param[in] DistPath is the path to search.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \param[in] ExcludeName contains the names to exclude.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \returns a list of file names in the specified path,
|
|
|
|
|
|
// excluding names in ExcludeNames.
|
|
|
|
|
|
//
|
|
|
|
|
|
StringContainer GetFileList(std::string DistPath,
|
|
|
|
|
|
StringContainer ExcludeName);
|
|
|
|
|
|
|
|
|
|
|
|
/// Update the files in one directory.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \param[in] SourceDir is the name of the directory that contains the
|
|
|
|
|
|
// files to copy from.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \param[in] DestDir is the name of the directory to clear and copy
|
|
|
|
|
|
// files to.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \param[in] ExcludeName contains the names of the files to not
|
|
|
|
|
|
// delete or copy.
|
|
|
|
|
|
//
|
|
|
|
|
|
// This function:
|
|
|
|
|
|
//
|
|
|
|
|
|
// 1) Deletes the files in DestDir, except for ExcludeName and directories.
|
|
|
|
|
|
//
|
|
|
|
|
|
// 2) If a directory in exists in both SourceDir and DestDir, then
|
|
|
|
|
|
// update that directory by invoking UpdateCommonDirectories().
|
|
|
|
|
|
//
|
|
|
|
|
|
// 3) If a directory exists in DestDir but not in SourceDir, delete
|
|
|
|
|
|
// that directory and all it's contents.
|
|
|
|
|
|
//
|
|
|
|
|
|
// 4) Copy the non-directory files SourceDir to DestDir, except for
|
|
|
|
|
|
// ExcludeName.
|
|
|
|
|
|
//
|
|
|
|
|
|
void UpdateOneDirectory(std::string SourceDir,
|
|
|
|
|
|
std::string DestDir,
|
|
|
|
|
|
StringContainer ExcludeName);
|
|
|
|
|
|
|
|
|
|
|
|
/// Delete a directory and all it's contents.
|
|
|
|
|
|
//
|
|
|
|
|
|
// This function recursively deletes the contents of a directory, and
|
|
|
|
|
|
// then deletes the directory.
|
|
|
|
|
|
//
|
|
|
|
|
|
// \param[in] Path is the path to delete.
|
|
|
|
|
|
//
|
|
|
|
|
|
void DeletePath(std::string Path);
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
GetDirectoryNames(std::string &InputDistPath,
|
|
|
|
|
|
std::string &DistSourcePath,
|
|
|
|
|
|
std::string &DistParentPath,
|
|
|
|
|
|
std::string &DistName) {
|
|
|
|
|
|
|
|
|
|
|
|
DWORD RetVal = 0;
|
|
|
|
|
|
TCHAR PathPart[MAX_PATH];
|
|
|
|
|
|
LPTSTR FilePart = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
RetVal = GetFullPathName(InputDistPath.c_str(), // Get the path name for the source.
|
|
|
|
|
|
MAX_PATH,
|
|
|
|
|
|
PathPart,
|
|
|
|
|
|
&FilePart);
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
if (0 == RetVal) {
|
|
|
|
|
|
|
|
|
|
|
|
throw(std::invalid_argument("Error determining directory names"));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
DistSourcePath = PathPart;
|
|
|
|
|
|
|
|
|
|
|
|
if ( (NULL != FilePart) && (0 != *FilePart) ) { // Extract the distribution name
|
|
|
|
|
|
// (last component of the source path.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DistName = FilePart;
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
|
|
throw(std::invalid_argument("Unable to determine distribution name"));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string::size_type DistNameIndex; // Get the parent directory of the
|
|
|
|
|
|
// source directory.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DistNameIndex = DistSourcePath.rfind("\\");
|
|
|
|
|
|
if (std::string::npos == DistNameIndex) {
|
|
|
|
|
|
|
|
|
|
|
|
throw(std::invalid_argument("Unable to determine the name of the "
|
|
|
|
|
|
"distribution parent directory"));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DistParentPath = DistSourcePath.substr(0, DistNameIndex);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
|
IsInContainer(std::string Needle, StringContainer Haystack) {
|
|
|
|
|
|
|
|
|
|
|
|
std::transform(Needle.begin(), Needle.end(), Needle.begin(), ::toupper);
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer::iterator iFile;
|
|
|
|
|
|
|
|
|
|
|
|
for (iFile = Haystack.begin(); iFile != Haystack.end(); iFile++) { // Check each file in the container.
|
|
|
|
|
|
|
|
|
|
|
|
std::transform(iFile->begin(), iFile->end(), iFile->begin(), ::toupper);
|
|
|
|
|
|
if (*iFile == Needle) {
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer
|
|
|
|
|
|
GetDirectoryList(std::string DistPath, StringContainer ExcludeName) {
|
|
|
|
|
|
|
|
|
|
|
|
DistPath += "\\*.*"; // Create filter string.
|
|
|
|
|
|
|
|
|
|
|
|
WIN32_FIND_DATA FileData;
|
|
|
|
|
|
HANDLE ListHandle;
|
|
|
|
|
|
std::string FileName;
|
|
|
|
|
|
|
|
|
|
|
|
ListHandle = FindFirstFile(DistPath.c_str(),
|
|
|
|
|
|
&FileData);
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer DirName; // Container to hold directory
|
|
|
|
|
|
// names of the distribution.
|
|
|
|
|
|
|
|
|
|
|
|
if ( (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && // Is this a directory...
|
|
|
|
|
|
|
|
|
|
|
|
(! IsInContainer(FileData.cFileName, ExcludeName)) ) { // ...and not an excluded file?
|
|
|
|
|
|
|
|
|
|
|
|
DirName.push_back(FileData.cFileName); // Yes. Save the name.
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
|
|
|
|
|
|
if (FindNextFile(ListHandle, &FileData)) {
|
|
|
|
|
|
|
|
|
|
|
|
if ( (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && // Is this a directory...
|
|
|
|
|
|
|
|
|
|
|
|
(! IsInContainer(FileData.cFileName, ExcludeName)) ) { // ...and not an excluded file?
|
|
|
|
|
|
|
|
|
|
|
|
DirName.push_back(FileData.cFileName); // Yes. Save the name.
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
if (ERROR_NO_MORE_FILES == LastError) {
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
std::ostringstream temp;
|
|
|
|
|
|
|
|
|
|
|
|
temp << "Error determining directory list of '"
|
|
|
|
|
|
<< DistPath << "'";
|
|
|
|
|
|
throw(std::runtime_error(temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (FindClose(ListHandle) == 0) {
|
|
|
|
|
|
std::ostringstream Temp;
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "***Error closing handle for " << DistPath;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return DirName;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer
|
|
|
|
|
|
GetFileList(std::string DirPath, StringContainer ExcludeName) {
|
|
|
|
|
|
|
|
|
|
|
|
std::string DirPathFilter;
|
|
|
|
|
|
|
|
|
|
|
|
DirPathFilter = DirPath + "\\*.*"; // Create filter string.
|
|
|
|
|
|
|
|
|
|
|
|
WIN32_FIND_DATA FileData;
|
|
|
|
|
|
HANDLE ListHandle;
|
|
|
|
|
|
|
|
|
|
|
|
ListHandle = FindFirstFile(DirPathFilter.c_str(),
|
|
|
|
|
|
&FileData);
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer FileNameList; // Container to hold file names.
|
|
|
|
|
|
std::string FileName;
|
|
|
|
|
|
|
|
|
|
|
|
if ( !(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && // Is this not a directory...
|
|
|
|
|
|
|
|
|
|
|
|
(! IsInContainer(FileData.cFileName, ExcludeName)) ) { // ...and not an excluded file?
|
|
|
|
|
|
|
|
|
|
|
|
FileNameList.push_back(FileData.cFileName); // Yes. Save the name.
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
|
|
|
|
|
|
if (FindNextFile(ListHandle, &FileData)) {
|
|
|
|
|
|
|
|
|
|
|
|
if ( !(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && // Is this not a directory...
|
|
|
|
|
|
|
|
|
|
|
|
(! IsInContainer(FileData.cFileName, ExcludeName)) ) { // ...and not an excluded file?
|
|
|
|
|
|
|
|
|
|
|
|
FileNameList.push_back(FileData.cFileName); // Yes. Save the name.
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
if (ERROR_NO_MORE_FILES == LastError) {
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
std::ostringstream temp;
|
|
|
|
|
|
|
|
|
|
|
|
temp << "Error determining directory list of '"
|
|
|
|
|
|
<< DirPath << "'";
|
|
|
|
|
|
throw(std::runtime_error(temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (FindClose(ListHandle) == 0) {
|
|
|
|
|
|
std::ostringstream Temp;
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "***Error closing handle for " << DirPath;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return FileNameList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
UpdateOneDirectory(std::string SourceDir,
|
|
|
|
|
|
std::string DestDir,
|
|
|
|
|
|
StringContainer ExcludeName) {
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer DestDirFileList; // Files in DestDir.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DestDirFileList = GetFileList(DestDir, ExcludeName);
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer::iterator iFile;
|
|
|
|
|
|
std::string FileToDelete;
|
|
|
|
|
|
|
|
|
|
|
|
for (iFile = DestDirFileList.begin(); // Remove the files.
|
|
|
|
|
|
iFile != DestDirFileList.end();
|
|
|
|
|
|
iFile++) {
|
|
|
|
|
|
|
|
|
|
|
|
if (! IsInContainer(*iFile, ExcludeName)) { // Check if this file is in ExcludeName.
|
|
|
|
|
|
|
|
|
|
|
|
FileToDelete = DestDir + "\\"; // It is not. Delete it.
|
|
|
|
|
|
FileToDelete += *iFile;
|
|
|
|
|
|
if (DeleteFile(FileToDelete.c_str()) == 0) {
|
|
|
|
|
|
std::ostringstream Temp;
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "***Error deleting " << FileToDelete;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer SourceDirFileList; // Files in SourceDir.
|
|
|
|
|
|
std::string SourceFile, DestFile;
|
|
|
|
|
|
|
|
|
|
|
|
SourceDirFileList = GetFileList(SourceDir, ExcludeName);
|
|
|
|
|
|
for (iFile = SourceDirFileList.begin(); // Copy the files from SourceDir.
|
|
|
|
|
|
iFile != SourceDirFileList.end();
|
|
|
|
|
|
iFile++) {
|
|
|
|
|
|
|
|
|
|
|
|
if (! IsInContainer(*iFile, ExcludeName)) { // Check if this file is in ExcludeName.
|
|
|
|
|
|
|
|
|
|
|
|
SourceFile = SourceDir + "\\"; // It is not. Copy it.
|
|
|
|
|
|
SourceFile += *iFile;
|
|
|
|
|
|
DestFile = DestDir + "\\";
|
|
|
|
|
|
DestFile += *iFile;
|
|
|
|
|
|
if (CopyFile(SourceFile.c_str(), DestFile.c_str(), true) == 0) {
|
|
|
|
|
|
std::ostringstream Temp;
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "Error copying " << SourceFile << " to " << DestFile;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer SourceDirDirList, DestDirDirList;
|
|
|
|
|
|
std::string SourceUpdateDir, DestUpdateDir;
|
|
|
|
|
|
StringContainer SourceDirExtraDirList, DestDirExtraDirList;
|
|
|
|
|
|
|
|
|
|
|
|
SourceDirDirList = GetDirectoryList(SourceDir, ExcludeName);
|
|
|
|
|
|
DestDirDirList = GetDirectoryList(DestDir, ExcludeName);
|
|
|
|
|
|
|
|
|
|
|
|
for (iFile = DestDirDirList.begin(); // Check that all directories in
|
|
|
|
|
|
iFile != DestDirDirList.end(); // the destination directory are
|
|
|
|
|
|
iFile++) { // also in the source directory.
|
|
|
|
|
|
|
|
|
|
|
|
if (! IsInContainer(*iFile, SourceDirDirList)) { // Not in source directory?
|
|
|
|
|
|
|
|
|
|
|
|
DestDirExtraDirList.push_back(*iFile); // It is not. This is an error.
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (iFile = SourceDirDirList.begin(); // Check that all directories in
|
|
|
|
|
|
iFile != SourceDirDirList.end(); // the source directory are also
|
|
|
|
|
|
iFile++) { // in the destination directory.
|
|
|
|
|
|
|
|
|
|
|
|
if (! IsInContainer(*iFile, DestDirDirList)) { // Not in source directory?
|
|
|
|
|
|
|
|
|
|
|
|
SourceDirExtraDirList.push_back(*iFile); // It is not. This is an error.
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!SourceDirExtraDirList.empty() || !DestDirExtraDirList.empty()) { // Check for error.
|
|
|
|
|
|
std::ostringstream Temp;
|
|
|
|
|
|
|
|
|
|
|
|
if (!SourceDirExtraDirList.empty()) { // Extra directories in source.
|
|
|
|
|
|
|
|
|
|
|
|
Temp << "***Error--There were directories in " << SourceDir
|
|
|
|
|
|
<< " that are not in " << DestDir << ":\n\t";
|
|
|
|
|
|
|
|
|
|
|
|
std::copy(SourceDirExtraDirList.begin(),
|
|
|
|
|
|
SourceDirExtraDirList.end(),
|
|
|
|
|
|
std::ostream_iterator<std::string>(Temp, "\n\t"));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!DestDirExtraDirList.empty()) { // Extra directories in destination.
|
|
|
|
|
|
|
|
|
|
|
|
Temp << "***Error--There were directories in " << DestDir
|
|
|
|
|
|
<< " that are not in " << SourceDir << ":\n\t";
|
|
|
|
|
|
std::copy(DestDirExtraDirList.begin(),
|
|
|
|
|
|
DestDirExtraDirList.end(),
|
|
|
|
|
|
std::ostream_iterator<std::string>(Temp, "\n\t"));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (iFile = DestDirDirList.begin(); // Update each directory.
|
|
|
|
|
|
iFile != DestDirDirList.end();
|
|
|
|
|
|
iFile++) {
|
|
|
|
|
|
|
|
|
|
|
|
SourceUpdateDir = SourceDir + "\\";
|
|
|
|
|
|
SourceUpdateDir += *iFile;
|
|
|
|
|
|
DestUpdateDir = DestDir + "\\";
|
|
|
|
|
|
DestUpdateDir += *iFile;
|
|
|
|
|
|
UpdateOneDirectory(SourceUpdateDir, DestUpdateDir, ExcludeName);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
UpdateCommonDirectories(std::string DistPath, std::string DistParentPath,
|
|
|
|
|
|
StringContainer ExcludeName) {
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer DistDirList, DistParentDirList;
|
|
|
|
|
|
|
|
|
|
|
|
DistDirList = GetDirectoryList(DistPath, ExcludeName); // Distribution directory names.
|
|
|
|
|
|
DistParentDirList = GetDirectoryList(DistParentPath, ExcludeName); // Parent of distribution directory names.
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
// DEBUG.
|
|
|
|
|
|
std::cout << "Directory list of distribution--\n";
|
|
|
|
|
|
std::copy(DistDirList.begin(),
|
|
|
|
|
|
DistDirList.end(),
|
|
|
|
|
|
std::ostream_iterator<std::string>(std::cout, "\n"));
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "\nDirectory list of distribution parent--\n";
|
|
|
|
|
|
std::copy(DistParentDirList.begin(),
|
|
|
|
|
|
DistParentDirList.end(),
|
|
|
|
|
|
std::ostream_iterator<std::string>(std::cout, "\n"));
|
|
|
|
|
|
// END OF DEBUG.
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer::iterator iDistDir; // Update direcotries with the same name.
|
|
|
|
|
|
|
|
|
|
|
|
for (iDistDir = DistDirList.begin();
|
|
|
|
|
|
iDistDir != DistDirList.end();
|
|
|
|
|
|
iDistDir++) {
|
|
|
|
|
|
std::string SourceDir, DestDir;
|
|
|
|
|
|
|
|
|
|
|
|
if (IsInContainer(*iDistDir, DistParentDirList)) { // Check if this is a common directory.
|
|
|
|
|
|
|
|
|
|
|
|
SourceDir = DistParentPath + "\\"; // This is a common directory.
|
|
|
|
|
|
SourceDir += *iDistDir;
|
|
|
|
|
|
DestDir = DistPath + "\\";
|
|
|
|
|
|
DestDir += *iDistDir;
|
|
|
|
|
|
UpdateOneDirectory(SourceDir, DestDir, ExcludeName);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
PrepareTempDir(std::string TempPath) {
|
|
|
|
|
|
|
|
|
|
|
|
WIN32_FIND_DATA FileData;
|
|
|
|
|
|
DWORD LastError;
|
|
|
|
|
|
HANDLE DirHandle;
|
|
|
|
|
|
std::ostringstream Temp;
|
|
|
|
|
|
|
|
|
|
|
|
DirHandle = FindFirstFile(TempPath.c_str(), &FileData); // Check whether the directory exists.
|
|
|
|
|
|
if (INVALID_HANDLE_VALUE == DirHandle) { // Directory doesn't exist.
|
|
|
|
|
|
|
|
|
|
|
|
if (!CreateDirectory(TempPath.c_str(), NULL)) {
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "***Error creating the temporary directory " << TempPath;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If the path is a file, delete it and create a new directory.
|
|
|
|
|
|
if ( !(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
|
|
|
|
|
|
|
|
|
|
|
if (CloseHandle(DirHandle) != 0) {
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "***Error closing handle for " << TempPath;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (DeleteFile(TempPath.c_str()) != 0) {
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "***Error deleting " << TempPath;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PrepareTempDir(TempPath);
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (CloseHandle(DirHandle) != 0) {
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "***Error closing handle for " << TempPath;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DeletePath(TempPath); // TempPath is a directory. Delete it.
|
|
|
|
|
|
PrepareTempDir(TempPath); // Create an empty directory.
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
DeletePath(std::string Path) {
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer DirList, FileList, ExcludeName;
|
|
|
|
|
|
StringContainer::iterator iName;
|
|
|
|
|
|
std::string NameToDelete;
|
|
|
|
|
|
|
|
|
|
|
|
ExcludeName.push_back(".");
|
|
|
|
|
|
ExcludeName.push_back("..");
|
|
|
|
|
|
|
|
|
|
|
|
DirList = GetDirectoryList(Path, ExcludeName);
|
|
|
|
|
|
FileList = GetFileList(Path, ExcludeName);
|
|
|
|
|
|
|
|
|
|
|
|
for (iName = FileList.begin(); // Delete each file.
|
|
|
|
|
|
iName != FileList.end();
|
|
|
|
|
|
iName++) {
|
|
|
|
|
|
|
|
|
|
|
|
NameToDelete = Path + "\\";
|
|
|
|
|
|
NameToDelete += *iName;
|
|
|
|
|
|
if (DeleteFile(NameToDelete.c_str()) == 0) {
|
|
|
|
|
|
std::ostringstream Temp;
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "***Error deleting " << NameToDelete << " in " << Path;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (iName = DirList.begin(); // Delete each directory.
|
|
|
|
|
|
iName != DirList.end();
|
|
|
|
|
|
iName++) {
|
|
|
|
|
|
|
|
|
|
|
|
NameToDelete = Path + "\\";
|
|
|
|
|
|
NameToDelete += *iName;
|
|
|
|
|
|
DeletePath(NameToDelete);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (RemoveDirectory(Path.c_str()) == 0) {
|
|
|
|
|
|
std::ostringstream Temp;
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "***Error removing directory " << Path;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
CopyDirectory(std::string SourcePath, std::string DestPath, StringContainer ExcludeName) {
|
|
|
|
|
|
|
|
|
|
|
|
StringContainer DirList, FileList;
|
|
|
|
|
|
StringContainer::iterator iName;
|
|
|
|
|
|
std::string SourceName, DestName;
|
|
|
|
|
|
BOOL FailIfExists = true;
|
|
|
|
|
|
|
|
|
|
|
|
DirList = GetDirectoryList(SourcePath, ExcludeName);
|
|
|
|
|
|
FileList = GetFileList(SourcePath, ExcludeName);
|
|
|
|
|
|
|
|
|
|
|
|
for (iName = FileList.begin(); // Copy each file.
|
|
|
|
|
|
iName != FileList.end();
|
|
|
|
|
|
iName++) {
|
|
|
|
|
|
|
|
|
|
|
|
SourceName = SourcePath + "\\";
|
|
|
|
|
|
SourceName += *iName;
|
|
|
|
|
|
DestName = DestPath + "\\";
|
|
|
|
|
|
DestName += *iName;
|
|
|
|
|
|
if (!CopyFile(SourceName.c_str(), DestName.c_str(), FailIfExists)) {
|
|
|
|
|
|
std::ostringstream Temp;
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "Error copying " << *iName << " to " << DestPath;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (iName = DirList.begin(); // Copy each directory.
|
|
|
|
|
|
iName != DirList.end();
|
|
|
|
|
|
iName++) {
|
|
|
|
|
|
|
|
|
|
|
|
SourceName = SourcePath + "\\";
|
|
|
|
|
|
SourceName += *iName;
|
|
|
|
|
|
DestName = DestPath + "\\";
|
|
|
|
|
|
DestName += *iName;
|
|
|
|
|
|
|
|
|
|
|
|
if (!CreateDirectory(DestName.c_str(), NULL)) { // Create the directory.
|
|
|
|
|
|
std::ostringstream Temp;
|
|
|
|
|
|
|
|
|
|
|
|
LastError = GetLastError();
|
|
|
|
|
|
Temp << "***Error creating the temporary directory " << DestName;
|
|
|
|
|
|
throw(std::runtime_error(Temp.str()));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CopyDirectory(SourceName, DestName, ExcludeName);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|