/// <summary> /// Verify command line arguments /// </summary> /// <returns>True if arguments are verified</returns> public static bool VerifyArguments() { // // Command Line: action // if (_action == ProgramAction.Invalid) { Usage("You must either run the -update or -verify action"); return(false); } // // Command Line: match // if (_matchPattern.Contains("*") || _matchPattern.Contains("?")) { // if the match is a path, split into path and file match if (_matchPattern.Contains(@"\")) { _basePath = _matchPattern.Substring(0, _matchPattern.LastIndexOf(@"\", StringComparison.OrdinalIgnoreCase)); _matchPattern = _matchPattern.Substring(_matchPattern.LastIndexOf(@"\", StringComparison.OrdinalIgnoreCase) + 1); } _matchType = MatchType.Wildcard; } else if (FileUtils.ExistsLong(_matchPattern)) { _matchType = MatchType.File; } else if (FileUtils.DirectoryExistsLong(_matchPattern)) { _matchType = MatchType.Directory; } else { Usage("File or directory does not exist: " + _matchPattern); return(false); } // // Command Line: recursion // // means we're doing directory match if (_recurse) { _matchType = MatchType.Directory; } // // Command Line: XML db // // verify we can open it first if (String.IsNullOrEmpty(_xmlFileName)) { Usage("Must specify the XML DB file"); return(false); } FileStream file; if (_action == ProgramAction.Update) { try { // only complain if the file exists but we can't read it if (FileUtils.ExistsLong(_xmlFileName)) { file = File.OpenRead(_xmlFileName); file.Close(); } } catch (IOException) { Console.WriteLine("Cannot open XML DB: {0}", _xmlFileName); return(false); } } else if (_action == ProgramAction.Verify) { // complain if the file doesn't exist or we can't read it try { file = File.OpenRead(_xmlFileName); file.Close(); } catch (IOException) { Console.WriteLine("Cannot open XML DB: {0}", _xmlFileName); return(false); } } // // -basePath // _basePath = _basePath.TrimEnd('\\'); if (!FileUtils.DirectoryExistsLong(_basePath)) { Console.WriteLine("Base path {0} does not exist", _basePath); return(false); } FileInfo basePathInfo = new FileInfo(_basePath); _basePath = basePathInfo.FullName; return(true); }
/// <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> /// Loads a Database from a XML file /// </summary> /// <param name="fileName">XML file name</param> /// <param name="basePath">Base path</param> /// <param name="pathType">Path type</param> /// <returns>New Database</returns> public static Database FromFile(string fileName, string basePath, PathType pathType) { // ensure file exists first if (!FileUtils.ExistsLong(fileName)) { // otherwise, return a new empty Database return(new Database(fileName)); } // ready serializer XmlSerializerNamespaces serializerNameSpace = new XmlSerializerNamespaces(); serializerNameSpace.Add(String.Empty, String.Empty); XmlSerializer serializer = new XmlSerializer(typeof(DatabaseFile)); // load all elements from the XML DatabaseFile databaseFile = null; using (StreamReader reader = new StreamReader(fileName)) { try { databaseFile = (DatabaseFile)serializer.Deserialize(reader); } catch (XmlException) { // let callers handle error } catch (InvalidOperationException) { // let callers handle error } } if (databaseFile == null) { return(null); } Database db = new Database() { XmlFileName = fileName }; // initialize all elements into the hash table foreach (FileChecksum fileChecksum in databaseFile.Files) { if (String.IsNullOrEmpty(fileChecksum.ResolvedFileName) || String.IsNullOrEmpty(fileChecksum.Checksum)) { // skip bad entries continue; } // FilePath fileChecksum.InitFromXml(basePath, pathType); // add to the database's lookup table db._fileLookup.Add(fileChecksum.ResolvedFileName, fileChecksum); } return(db); }
/// <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)); }