/// <summary> /// Verify the checksums of files listed in the Database /// </summary> /// <param name="ignoreChecksum">Ignore checksum changes</param> /// <param name="ignoreMissing">Ignore missing files</param> /// <param name="showNew">Show new files</param> /// <returns>Number of bad files found, or -1 for other error</returns> public VerifyChecksumsResult VerifyChecksums(bool ignoreChecksum, bool ignoreMissing, bool showNew) { if (_filesToCheck == null) { throw new InvalidOperationException("You must scan files before verifying checksums"); } if (!FileUtils.DirectoryExistsLong(_basePath)) { return(new VerifyChecksumsResult(false, null)); } _reporter.VerifyingChecksums(_db.FileCount()); // keep track of files we checked Hashtable checkedFiles = new Hashtable(); // list of bad files _badFiles = new List <BadFile>(); // verify the checksums of all of the files in the DB int fileChecked = 0; // save then cd to basepath string previousDirectory = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(_basePath); foreach (FileChecksum fc in _db.Files) { fileChecked++; // display progress _reporter.VerifyingFile(fileChecked, _db.FileCount(), fc.ResolvedFileName); // keep trace of files we looked at checkedFiles.Add(fc.ResolvedFileName, 1); // determine if the file is missing from the dist if (!FileUtils.ExistsLong(fc.FilePath)) { if (!ignoreMissing) { _badFiles.Add(new BadFile() { FileName = fc.ResolvedFileName, BadFileType = BadFileType.Missing }); } continue; } if (!ignoreChecksum) { // verify the checksum from the disk FileChecksum fileChecksum = new FileChecksum(fc.FilePath, _basePath, _pathType, _checksumType); // if the checksum is bad, add bad files if (fc.Checksum != fileChecksum.Checksum) { _badFiles.Add(new BadFile() { FileName = fc.ResolvedFileName, BadFileType = BadFileType.DifferentChecksum, ChecksumDisk = fileChecksum.Checksum, ChecksumDatabase = fc.Checksum }); continue; } } } // notify the user of new files if (showNew) { foreach (string file in _filesToCheck) { // change file name via PathType string fileName = FileChecksum.GetFileName(file, _basePath, _pathType); if (!checkedFiles.ContainsKey(fileName)) { _badFiles.Add(new BadFile() { FileName = fileName, BadFileType = BadFileType.New, }); } } } ReadOnlyCollection <BadFile> badFiles = _badFiles.AsReadOnly(); _reporter.VerifyingChecksumsCompleted(badFiles); // cd back to previous directory Directory.SetCurrentDirectory(previousDirectory); return(new VerifyChecksumsResult(badFiles.Count == 0, badFiles)); }
/// <summary> /// Updates checksums and finds new files /// </summary> /// <param name="ignoreNew">Ignore new files</param> /// <param name="removeMissing">Remove missing files</param> /// <param name="pretend">Don't save changes to the database</param> /// <param name="updateExisting">Update existing files's checksums</param> /// <returns>True on success</returns> public UpdateChecksumsResult UpdateChecksums(bool ignoreNew, bool removeMissing, bool pretend, bool updateExisting = false) { int filesUpdated = 0; if (_filesToCheck == null) { throw new InvalidOperationException("You must scan files before updating checksums"); } _reporter.UpdatingChecksums(_db.FileCount()); // if updating existing checksums, do that first if (updateExisting) { foreach (FileChecksum fc in _db.Files) { if (FileUtils.ExistsLong(fc.FilePath)) { // build a list of files to remove first // add file to database if (_db.UpdateFile(fc.FilePath, _basePath, _pathType, _checksumType)) { _reporter.UpdatedFile(fc.FilePath); filesUpdated++; } } } } // if adding new files, find those missing in the XML DB if (!ignoreNew) { foreach (string fileName in _filesToCheck) { string fileNameToCheck = FileChecksum.GetFileName(fileName, _basePath, _pathType); if (!_db.HasFile(fileNameToCheck)) { _reporter.AddingFile(fileNameToCheck); // add file to database string checksum = _db.AddFile(fileName, _basePath, _pathType, _checksumType); _reporter.AddingFileCompleted(fileNameToCheck, checksum); filesUpdated++; } } } // determine if there are any files in the DB but not on the disk if (removeMissing) { List <string> filesToRemove = new List <string>(); foreach (FileChecksum fc in _db.Files) { if (!FileUtils.ExistsLong(fc.FilePath)) { // build a list of files to remove first filesToRemove.Add(fc.ResolvedFileName); _reporter.RemovedFile(fc.FilePath); filesUpdated++; } } // now actually remove the files foreach (string fileToRemove in filesToRemove) { _db.RemoveFile(fileToRemove); } } // write out XML unless we're in pretend mode if (!pretend) { if (_db.HasChanges()) { _reporter.WritingDatabase(_xmlDatabasePath); _db.Write(); _reporter.WritingDatabaseCompleted(); } else { _reporter.UpdatingChecksumsCompleted(false); } } return(new UpdateChecksumsResult(true, filesUpdated)); }