1 //  This file is part of par2cmdline (a PAR 2.0 compatible file verification and
2 //  repair tool). See http://parchive.sourceforge.net for details of PAR 2.0.
3 //
4 //  Copyright (c) 2003 Peter Brian Clements
5 //
6 //  par2cmdline is free software; you can redistribute it and/or modify
7 //  it under the terms of the GNU General Public License as published by
8 //  the Free Software Foundation; either version 2 of the License, or
9 //  (at your option) any later version.
10 //
11 //  par2cmdline is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
19 
20 #ifndef __PAR2REPAIRER_H__
21 #define __PAR2REPAIRER_H__
22 
23 #include <sigc++/sigc++.h>
24 #include "parheaders.h"
25 
26 class Par2Repairer
27 {
28 public:
29   Par2Repairer(void);
30   ~Par2Repairer(void);
31 
32   Result PreProcess(const CommandLine &commandline);
33   Result Process(const CommandLine &commandline, bool dorepair);
34   sigc::signal<void, std::string> sig_filename;
35   sigc::signal<void, double> sig_progress;
36   sigc::signal<void, ParHeaders*> sig_headers;
37   sigc::signal<void, std::string, int, int> sig_done;
38 
39   // This method allows to determine whether libpar2 includes the patches
40   // ("libpar2-0.2-bugfixes.patch") submitted to libpar2 project.
41   // Use the method in configure scripts for detection.
BugfixesPatchVersion2()42   void BugfixesPatchVersion2() { }
43 
44 protected:
45   // Steps in verifying and repairing files:
46 
47   // Load packets from the specified file
48   bool LoadPacketsFromFile(string filename);
49   // Finish loading a recovery packet
50   bool LoadRecoveryPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
51   // Finish loading a file description packet
52   bool LoadDescriptionPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
53   // Finish loading a file verification packet
54   bool LoadVerificationPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
55   // Finish loading the main packet
56   bool LoadMainPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
57   // Finish loading the creator packet
58   bool LoadCreatorPacket(DiskFile *diskfile, u64 offset, PACKET_HEADER &header);
59 
60   // Load packets from other PAR2 files with names based on the original PAR2 file
61   bool LoadPacketsFromOtherFiles(string filename);
62 
63   // Load packets from any other PAR2 files whose names are given on the command line
64   bool LoadPacketsFromExtraFiles(const list<CommandLine::ExtraFile> &extrafiles);
65 
66   // Check that the packets are consistent and discard any that are not
67   bool CheckPacketConsistency(void);
68 
69   // Use the information in the main packet to get the source files
70   // into the correct order and determine their filenames
71   bool CreateSourceFileList(void);
72 
73   // Determine the total number of DataBlocks for the recoverable source files
74   // The allocate the DataBlocks and assign them to each source file
75   bool AllocateSourceBlocks(void);
76 
77   // Create a verification hash table for all files for which we have not
78   // found a complete version of the file and for which we have
79   // a verification packet
80   bool PrepareVerificationHashTable(void);
81 
82   // Compute the table for the sliding CRC computation
83   bool ComputeWindowTable(void);
84 
85   // Attempt to verify all of the source files
86   bool VerifySourceFiles(void);
87 
88   // Scan any extra files specified on the command line
89   bool VerifyExtraFiles(const list<CommandLine::ExtraFile> &extrafiles);
90 
91   // Attempt to match the data in the DiskFile with the source file
92   bool VerifyDataFile(DiskFile *diskfile, Par2RepairerSourceFile *sourcefile);
93 
94   // Perform a sliding window scan of the DiskFile looking for blocks of data that
95   // might belong to any of the source files (for which a verification packet was
96   // available). If a block of data might be from more than one source file, prefer
97   // the one specified by the "sourcefile" parameter. If the first data block
98   // found is for a different source file then "sourcefile" is changed accordingly.
99   bool ScanDataFile(DiskFile                *diskfile,   // [in]     The file being scanned
100                     Par2RepairerSourceFile* &sourcefile, // [in/out] The source file matched
101                     MatchType               &matchtype,  // [out]    The type of match
102                     MD5Hash                 &hashfull,   // [out]    The full hash of the file
103                     MD5Hash                 &hash16k,    // [out]    The hash of the first 16k
104                     u32                     &count);     // [out]    The number of blocks found
105 
106   // Find out how much data we have found
107   void UpdateVerificationResults(void);
108 
109   // Check the verification results and report the results
110   bool CheckVerificationResults(void);
111 
112   // Rename any damaged or missnamed target files.
113   bool RenameTargetFiles(void);
114 
115   // Work out which files are being repaired, create them, and allocate
116   // target DataBlocks to them, and remember them for later verification.
117   bool CreateTargetFiles(void);
118 
119   // Work out which data blocks are available, which need to be copied
120   // directly to the output, and which need to be recreated, and compute
121   // the appropriate Reed Solomon matrix.
122   bool ComputeRSmatrix(void);
123 
124   // Allocate memory buffers for reading and writing data to disk.
125   bool AllocateBuffers(size_t memorylimit);
126 
127   // Read source data, process it through the RS matrix and write it to disk.
128   bool ProcessData(u64 blockoffset, size_t blocklength);
129 
130   // Verify that all of the reconstructed target files are now correct
131   bool VerifyTargetFiles(void);
132 
133   // Delete all of the partly reconstructed files
134   bool DeleteIncompleteTargetFiles(void);
135 
136 protected:
137   ParHeaders* headers;                                 // Headers
138   bool alreadyloaded;                                // Already loaded ?
139   CommandLine::NoiseLevel   noiselevel;              // OnScreen display
140 
141   string                    searchpath;              // Where to find files on disk
142 
143   bool                      firstpacket;             // Whether or not a valid packet has been found.
144   MD5Hash                   setid;                   // The SetId extracted from the first packet.
145 
146   map<u32, RecoveryPacket*> recoverypacketmap;       // One recovery packet for each exponent value.
147   MainPacket               *mainpacket;              // One copy of the main packet.
148   CreatorPacket            *creatorpacket;           // One copy of the creator packet.
149 
150   DiskFileMap               diskFileMap;
151 
152   map<MD5Hash,Par2RepairerSourceFile*> sourcefilemap;// Map from FileId to SourceFile
153   vector<Par2RepairerSourceFile*>      sourcefiles;  // The source files
154   vector<Par2RepairerSourceFile*>      verifylist;   // Those source files that are being repaired
155 
156   u64                       blocksize;               // The block size.
157   u64                       chunksize;               // How much of a block can be processed.
158   u32                       sourceblockcount;        // The total number of blocks
159   u32                       availableblockcount;     // How many undamaged blocks have been found
160   u32                       missingblockcount;       // How many blocks are missing
161 
162   bool                      blocksallocated;         // Whether or not the DataBlocks have been allocated
163   vector<DataBlock>         sourceblocks;            // The DataBlocks that will be read from disk
164   vector<DataBlock>         targetblocks;            // The DataBlocks that will be written to disk
165 
166   u32                       windowtable[256];        // Table for sliding CRCs
167   u32                       windowmask;              // Maks for sliding CRCs
168 
169   bool                            blockverifiable;         // Whether and files can be verified at the block level
170   VerificationHashTable           verificationhashtable;   // Hash table for block verification
171   list<Par2RepairerSourceFile*>   unverifiablesourcefiles; // Files that are not block verifiable
172 
173   u32                       completefilecount;       // How many files are fully verified
174   u32                       renamedfilecount;        // How many files are verified but have the wrong name
175   u32                       damagedfilecount;        // How many files exist but are damaged
176   u32                       missingfilecount;        // How many files are completely missing
177 
178   vector<DataBlock*>        inputblocks;             // Which DataBlocks will be read from disk
179   vector<DataBlock*>        copyblocks;              // Which DataBlocks will copied back to disk
180   vector<DataBlock*>        outputblocks;            // Which DataBlocks have to calculated using RS
181 
182   ReedSolomon<Galois16>     rs;                      // The Reed Solomon matrix.
183 
184   void                     *inputbuffer;             // Buffer for reading DataBlocks (chunksize)
185   void                     *outputbuffer;            // Buffer for writing DataBlocks (chunksize * missingblockcount)
186 
187   u64                       progress;                // How much data has been processed.
188   u64                       totaldata;               // Total amount of data to be processed.
189   u64                       totalsize;               // Total data size
190 
191   bool                      cancelled;               // repair cancelled
192 };
193 
194 #endif // __PAR2REPAIRER_H__
195