bool CAeonView::InitRows (const CString &sRecoveryFilespec, int *retiRowsRecovered, CString *retsError) // InitRows // // Initializes the rows structure. { ASSERT(m_pRows == NULL); return LoadRecoveryFile(sRecoveryFilespec, &m_pRows, retiRowsRecovered, retsError); }
bool Par1Repairer::LoadOtherRecoveryFiles(string filename) { // Split the original PAR filename into path and name parts string path; string name; DiskFile::SplitFilename(filename, path, name); // Find the file extension string::size_type where = name.find_last_of('.'); if (where != string::npos) { // remove it name = name.substr(0, where); } // Search for additional PAR files string wildcard = name + ".???"; list<string> *files = new list<string>; DiskFile::FindFiles(files, path, wildcard, false); for (list<string>::const_iterator s=files->begin(); s!=files->end(); ++s) { string filename = *s; // Find the file extension where = filename.find_last_of('.'); if (where != string::npos) { string tail = filename.substr(where+1); // Check the the file extension is the correct form if ((tail[0] == 'P' || tail[0] == 'p') && ( ((tail[1] == 'A' || tail[1] == 'a') && (tail[2] == 'R' || tail[2] == 'r')) || (isdigit(tail[1]) && isdigit(tail[2])) )) { LoadRecoveryFile(filename); } } } delete files; return true; }
// Load packets from any other PAR files whose names are given on the command line bool Par1Repairer::LoadExtraRecoveryFiles(const list<CommandLine::ExtraFile> &extrafiles) { for (ExtraFileIterator i=extrafiles.begin(); i!=extrafiles.end(); i++) { string filename = i->FileName(); // Find the file extension string::size_type where = filename.find_last_of('.'); if (where != string::npos) { string tail = filename.substr(where+1); // Check the the file extension is the correct form if ((tail[0] == 'P' || tail[0] == 'p') && ( ((tail[1] == 'A' || tail[1] == 'a') && (tail[2] == 'R' || tail[2] == 'r')) || (isdigit(tail[1]) && isdigit(tail[2])) )) { LoadRecoveryFile(filename); } } } return true; }
Result Par1Repairer::Process(const CommandLine &commandline, bool dorepair) { // How noisy should we be noiselevel = commandline.GetNoiseLevel(); // Do we want to purge par files on success ? bool purgefiles = commandline.GetPurgeFiles(); // Get filesnames from the command line string par1filename = commandline.GetParFilename(); const list<CommandLine::ExtraFile> &extrafiles = commandline.GetExtraFiles(); // Determine the searchpath from the location of the main PAR file string name; DiskFile::SplitFilename(par1filename, searchpath, name); // Load the main PAR file if (!LoadRecoveryFile(searchpath + name)) return eLogicError; // Load other PAR files related to the main PAR file if (!LoadOtherRecoveryFiles(par1filename)) return eLogicError; // Load any extra PAR files specified on the command line if (!LoadExtraRecoveryFiles(extrafiles)) return eLogicError; if (noiselevel > CommandLine::nlQuiet) cout << endl << "Verifying source files:" << endl << endl; // Check for the existence of and verify each of the source files if (!VerifySourceFiles()) return eFileIOError; if (completefilecount<sourcefiles.size()) { if (noiselevel > CommandLine::nlQuiet) cout << endl << "Scanning extra files:" << endl << endl; // Check any other files specified on the command line to see if they are // actually copies of the source files that have the wrong filename if (!VerifyExtraFiles(extrafiles)) return eLogicError; } // Find out how much data we have found UpdateVerificationResults(); if (noiselevel > CommandLine::nlSilent) cout << endl; // Check the verification results and report the details if (!CheckVerificationResults()) return eRepairNotPossible; // Are any of the files incomplete if (completefilecount<sourcefiles.size()) { // Do we want to carry out a repair if (dorepair) { if (noiselevel > CommandLine::nlSilent) cout << endl; // Rename any damaged or missnamed target files. if (!RenameTargetFiles()) return eFileIOError; // Are we still missing any files if (completefilecount<sourcefiles.size()) { // Work out which files are being repaired, create them, and allocate // target DataBlocks to them, and remember them for later verification. if (!CreateTargetFiles()) return eFileIOError; // Work out which data blocks are available, which need to be recreated, // and compute the appropriate Reed Solomon matrix. if (!ComputeRSmatrix()) { // Delete all of the partly reconstructed files DeleteIncompleteTargetFiles(); return eFileIOError; } // Allocate memory buffers for reading and writing data to disk. if (!AllocateBuffers(commandline.GetMemoryLimit())) { // Delete all of the partly reconstructed files DeleteIncompleteTargetFiles(); return eMemoryError; } if (noiselevel > CommandLine::nlSilent) cout << endl; // Set the total amount of data to be processed. progress = 0; totaldata = blocksize * sourcefiles.size() * verifylist.size(); // Start at an offset of 0 within a block. u64 blockoffset = 0; while (blockoffset < blocksize) { // Continue until the end of the block. // Work out how much data to process this time. size_t blocklength = (size_t)min((u64)chunksize, blocksize-blockoffset); // Read source data, process it through the RS matrix and write it to disk. if (!ProcessData(blockoffset, blocklength)) { // Delete all of the partly reconstructed files DeleteIncompleteTargetFiles(); return eFileIOError; } // Advance to the need offset within each block blockoffset += blocklength; } if (noiselevel > CommandLine::nlSilent) cout << endl << "Verifying repaired files:" << endl << endl; // Verify that all of the reconstructed target files are now correct if (!VerifyTargetFiles()) { // Delete all of the partly reconstructed files DeleteIncompleteTargetFiles(); return eFileIOError; } } // Are all of the target files now complete? if (completefilecount<sourcefiles.size()) { cerr << "Repair Failed." << endl; return eRepairFailed; } else { if (noiselevel > CommandLine::nlSilent) cout << endl << "Repair complete." << endl; } } else { return eRepairPossible; } } if (purgefiles == true) { RemoveBackupFiles(); RemoveParFiles(); } return eSuccess; }