File indexing completed on 2023-10-01 08:39:32
0001 /************************************************************************** 0002 * Copyright (C) 2009-2011 Matthias Fuchs <mat69@gmx.net> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU General Public License as published by * 0006 * the Free Software Foundation; either version 2 of the License, or * 0007 * (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the * 0016 * Free Software Foundation, Inc., * 0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * 0018 ***************************************************************************/ 0019 0020 #include "verificationthread.h" 0021 #include "verifier.h" 0022 0023 #include "kget_debug.h" 0024 #include <QDebug> 0025 0026 #include <QFile> 0027 0028 VerificationThread::VerificationThread(QObject *parent) 0029 : QThread(parent) 0030 , m_abort(false) 0031 , m_length(0) 0032 , m_type(Nothing) 0033 { 0034 } 0035 0036 VerificationThread::~VerificationThread() 0037 { 0038 m_mutex.lock(); 0039 m_abort = true; 0040 m_mutex.unlock(); 0041 0042 wait(); 0043 } 0044 0045 void VerificationThread::verify(const QString &type, const QString &checksum, const QUrl &file) 0046 { 0047 QMutexLocker locker(&m_mutex); 0048 m_types.append(type); 0049 m_checksums.append(checksum); 0050 m_files.append(file); 0051 m_type = Verify; 0052 0053 if (!isRunning()) { 0054 start(); 0055 } 0056 } 0057 0058 void VerificationThread::findBrokenPieces(const QString &type, const QList<QString> checksums, KIO::filesize_t length, const QUrl &file) 0059 { 0060 QMutexLocker locker(&m_mutex); 0061 m_types.clear(); 0062 m_types.append(type); 0063 m_checksums = checksums; 0064 m_files.clear(); 0065 m_files.append(file); 0066 m_length = length; 0067 m_type = BrokenPieces; 0068 0069 if (!isRunning()) { 0070 start(); 0071 } 0072 } 0073 0074 void VerificationThread::run() 0075 { 0076 if (m_type == Nothing) { 0077 return; 0078 } 0079 0080 if (m_type == Verify) { 0081 doVerify(); 0082 } else if (m_type == BrokenPieces) { 0083 doBrokenPieces(); 0084 } 0085 } 0086 0087 void VerificationThread::doVerify() 0088 { 0089 m_mutex.lock(); 0090 bool run = m_files.count(); 0091 m_mutex.unlock(); 0092 0093 while (run && !m_abort) { 0094 m_mutex.lock(); 0095 const QString type = m_types.takeFirst(); 0096 const QString checksum = m_checksums.takeFirst(); 0097 const QUrl url = m_files.takeFirst(); 0098 m_mutex.unlock(); 0099 0100 if (type.isEmpty() || checksum.isEmpty()) { 0101 m_mutex.lock(); 0102 run = m_files.count(); 0103 m_mutex.unlock(); 0104 continue; 0105 } 0106 0107 const QString hash = Verifier::checksum(url, type, &m_abort); 0108 qCDebug(KGET_DEBUG) << "Type:" << type << "Calculated checksum:" << hash << "Entered checksum:" << checksum; 0109 const bool fileVerified = (hash == checksum); 0110 0111 if (m_abort) { 0112 return; 0113 } 0114 0115 m_mutex.lock(); 0116 if (!m_abort) { 0117 Q_EMIT verified(type, fileVerified, url); 0118 Q_EMIT verified(fileVerified); 0119 } 0120 run = m_files.count(); 0121 m_mutex.unlock(); 0122 } 0123 } 0124 0125 void VerificationThread::doBrokenPieces() 0126 { 0127 m_mutex.lock(); 0128 const QString type = m_types.takeFirst(); 0129 const QStringList checksums = m_checksums; 0130 m_checksums.clear(); 0131 const QUrl url = m_files.takeFirst(); 0132 const KIO::filesize_t length = m_length; 0133 m_mutex.unlock(); 0134 0135 QList<KIO::fileoffset_t> broken; 0136 0137 const QString filePath = url.toLocalFile(); 0138 if (QFile::exists(filePath)) { 0139 QFile file(filePath); 0140 if (!file.open(QIODevice::ReadOnly)) { 0141 Q_EMIT brokenPieces(broken, length); 0142 return; 0143 } 0144 0145 const KIO::filesize_t fileSize = file.size(); 0146 if (!length || !fileSize) { 0147 Q_EMIT brokenPieces(broken, length); 0148 return; 0149 } 0150 0151 const QStringList fileChecksums = Verifier::partialChecksums(url, type, length, &m_abort).checksums(); 0152 if (m_abort) { 0153 Q_EMIT brokenPieces(broken, length); 0154 return; 0155 } 0156 0157 if (fileChecksums.size() != checksums.size()) { 0158 qCDebug(KGET_DEBUG) << "Number of checksums differs!"; 0159 Q_EMIT brokenPieces(broken, length); 0160 return; 0161 } 0162 0163 for (int i = 0; i < checksums.size(); ++i) { 0164 if (fileChecksums.at(i) != checksums.at(i)) { 0165 const int brokenStart = length * i; 0166 qCDebug(KGET_DEBUG) << url << "broken segment" << i << "start" << brokenStart << "length" << length; 0167 broken.append(brokenStart); 0168 } 0169 } 0170 } 0171 0172 Q_EMIT brokenPieces(broken, length); 0173 } 0174 0175 #include "moc_verificationthread.cpp"