Walks the backup tree and checks every file has a byte-identical (size + CRC32) counterpart in the restored save.
| 112 | // Walks the backup tree and checks every file has a byte-identical (size + |
| 113 | // CRC32) counterpart in the restored save. |
| 114 | void verifyTree(const std::string& srcPath, const std::string& dstPath, VerifyStats& stats, ProgressSink& sink) |
| 115 | { |
| 116 | Directory items(srcPath); |
| 117 | if (!items.good()) { |
| 118 | Logging::error("Verification: failed to list backup directory {} with result 0x{:08X}.", srcPath, (u32)items.error()); |
| 119 | stats.unreadable++; |
| 120 | return; |
| 121 | } |
| 122 | for (size_t i = 0, sz = items.size(); i < sz; i++) { |
| 123 | const std::string src = srcPath + items.entry(i); |
| 124 | const std::string dst = dstPath + items.entry(i); |
| 125 | if (items.folder(i)) { |
| 126 | if (!io::directoryExists(dst)) { |
| 127 | Logging::error("Verification: directory {} missing from restored save.", dst); |
| 128 | stats.missing++; |
| 129 | } |
| 130 | else { |
| 131 | verifyTree(src + "/", dst + "/", stats, sink); |
| 132 | } |
| 133 | } |
| 134 | else { |
| 135 | sink.startFile(items.entry(i), 0); |
| 136 | stats.checked++; |
| 137 | u64 srcSize = 0, dstSize = 0; |
| 138 | u32 srcCrc = 0, dstCrc = 0; |
| 139 | if (!fileSizeAndCrc(src, srcSize, srcCrc)) { |
| 140 | stats.unreadable++; |
| 141 | } |
| 142 | else { |
| 143 | struct stat st; |
| 144 | if (stat(dst.c_str(), &st) != 0) { |
| 145 | Logging::error("Verification: file {} missing from restored save (errno {}).", dst, errno); |
| 146 | stats.missing++; |
| 147 | } |
| 148 | else if (!fileSizeAndCrc(dst, dstSize, dstCrc)) { |
| 149 | stats.unreadable++; |
| 150 | } |
| 151 | else if (srcSize != dstSize) { |
| 152 | Logging::error("Verification: size mismatch on {}: backup {} bytes, save {} bytes.", dst, srcSize, dstSize); |
| 153 | stats.sizeMismatch++; |
| 154 | } |
| 155 | else if (srcCrc != dstCrc) { |
| 156 | Logging::error("Verification: CRC mismatch on {} ({} bytes): backup {:08X}, save {:08X}.", dst, srcSize, srcCrc, dstCrc); |
| 157 | stats.crcMismatch++; |
| 158 | } |
| 159 | } |
| 160 | sink.finishFile(); |
| 161 | } |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | // Walks the restored save and flags anything the wipe should have removed |
| 166 | // but that isn't part of the backup. |