104 lines
2.6 KiB
C++
104 lines
2.6 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "UnsyncCmdVerify.h"
|
|
#include "UnsyncFile.h"
|
|
#include "UnsyncLog.h"
|
|
#include "UnsyncManifest.h"
|
|
#include "UnsyncSerialization.h"
|
|
|
|
namespace unsync {
|
|
|
|
int32
|
|
CmdVerify(const FCmdVerifyOptions& Options)
|
|
{
|
|
FPath Root = Options.Input;
|
|
FPath ManifestRoot = Root / ".unsync";
|
|
FPath DirectoryManifestPath = ManifestRoot / "manifest.bin";
|
|
FDirectoryManifest DirectoryManifest;
|
|
|
|
UNSYNC_LOG(L"Validating manifest for directory '%ls'", Root.wstring().c_str());
|
|
UNSYNC_LOG_INDENT;
|
|
|
|
if (!PathExists(DirectoryManifestPath))
|
|
{
|
|
UNSYNC_ERROR(L"Directory does not have a manifest file");
|
|
return -1;
|
|
}
|
|
|
|
const bool bExistingManifestLoaded = LoadDirectoryManifest(DirectoryManifest, Root, DirectoryManifestPath);
|
|
if (!bExistingManifestLoaded)
|
|
{
|
|
UNSYNC_ERROR(L"Failed to load manifest file '%ls'", DirectoryManifestPath.wstring().c_str());
|
|
return -1;
|
|
}
|
|
|
|
const EStrongHashAlgorithmID StrongHashAlgorithmId = DirectoryManifest.Algorithm.StrongHashAlgorithmId;
|
|
|
|
bool bDirectoryValid = true;
|
|
|
|
for (const auto& FileIt : DirectoryManifest.Files)
|
|
{
|
|
const std::wstring& FileName = FileIt.first;
|
|
const FFileManifest& FileManifest = FileIt.second;
|
|
|
|
UNSYNC_VERBOSE(L"Verifying file '%ls'", FileName.c_str());
|
|
|
|
const FFileAttributes FileAttrib = GetFileAttrib(FileManifest.CurrentPath);
|
|
if (!FileAttrib.bValid)
|
|
{
|
|
bDirectoryValid = false;
|
|
UNSYNC_ERROR(L"File '%ls' does not exist", FileName.c_str());
|
|
continue;
|
|
}
|
|
|
|
if (FileAttrib.Size != FileManifest.Size)
|
|
{
|
|
bDirectoryValid = false;
|
|
UNSYNC_ERROR(L"File '%ls' size mismatch. Expected %llu, actual %llu.",
|
|
FileName.c_str(),
|
|
llu(FileManifest.Size),
|
|
llu(FileAttrib.Size));
|
|
continue;
|
|
}
|
|
|
|
if (FileAttrib.Mtime != FileManifest.Mtime)
|
|
{
|
|
bDirectoryValid = false;
|
|
UNSYNC_ERROR(L"File '%ls' timestamp mismatch. Expected %llu, actual %llu.",
|
|
FileName.c_str(),
|
|
llu(FileManifest.Mtime),
|
|
llu(FileAttrib.Mtime));
|
|
continue;
|
|
}
|
|
|
|
FNativeFile File(FileManifest.CurrentPath, EFileMode::ReadOnlyUnbuffered);
|
|
if (!File.IsValid())
|
|
{
|
|
bDirectoryValid = false;
|
|
UNSYNC_ERROR(L"Failed to open file '%ls'. Error code: %d", FileName.c_str(), File.GetError());
|
|
continue;
|
|
}
|
|
|
|
const bool bFileValid = ValidateTarget(File, FileManifest.Blocks, StrongHashAlgorithmId);
|
|
|
|
if (!bFileValid)
|
|
{
|
|
UNSYNC_ERROR(L"Validation failed for file '%ls'", FileName.c_str());
|
|
bDirectoryValid = false;
|
|
}
|
|
}
|
|
|
|
if (bDirectoryValid)
|
|
{
|
|
UNSYNC_LOG(L"Directory manifest is valid");
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
UNSYNC_LOG(L"Directory manifest is invalid");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
} // namespace unsync
|