← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2320: Readd sfv check

 

------------------------------------------------------------
revno: 2320
committer: eMTee <emtee11@xxxxxxxxx>
branch nick: dcplusplus
timestamp: Fri 2010-12-03 14:59:16 +0100
message:
  Readd sfv check
modified:
  changelog.txt
  dcpp/Download.cpp
  dcpp/Download.h
  dcpp/DownloadManager.cpp
  dcpp/DownloadManager.h
  dcpp/FinishedManager.cpp
  dcpp/FinishedManager.h
  dcpp/QueueManager.cpp
  dcpp/QueueManager.h
  dcpp/QueueManagerListener.h
  help/settings_logs.html
  win32/TransferView.cpp
  win32/TransferView.h


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt	2010-12-03 11:29:33 +0000
+++ changelog.txt	2010-12-03 13:59:16 +0000
@@ -43,6 +43,7 @@
 * [L#610466] Fix share files instantly when unfinished folder and download target is not on the same drive (emtee)
 * [L#300728] Fix infinitive recursion when sharing a directory with broken name on unix (thanks alexander sashnov)
 * [L#250149] Retry on more possible Coral errors (emtee)
+* [L#260748] Really readded sfv check (was broken since segmented downloading introduced) (emtee)
 
 -- 0.770 2010-07-05 --
 * [L#550300] Catch more potential file corruptions (thanks bigmuscle)

=== modified file 'dcpp/Download.cpp'
--- dcpp/Download.cpp	2010-02-11 21:44:13 +0000
+++ dcpp/Download.cpp	2010-12-03 13:59:16 +0000
@@ -90,7 +90,6 @@
 void Download::getParams(const UserConnection& aSource, StringMap& params) {
 	Transfer::getParams(aSource, params);
 	params["target"] = getPath();
-	params["sfv"] = Util::toString(isSet(Download::FLAG_CRC32_OK) ? 1 : 0);
 }
 
 } // namespace dcpp

=== modified file 'dcpp/Download.h'
--- dcpp/Download.h	2008-08-14 21:28:47 +0000
+++ dcpp/Download.h	2010-12-03 13:59:16 +0000
@@ -17,11 +17,9 @@
 public:
 	enum {
 		FLAG_ZDOWNLOAD = 1 << 1,
-		FLAG_CALC_CRC32 = 1 << 2,
-		FLAG_CRC32_OK = 1 << 3,
-		FLAG_TREE_TRIED = 1 << 5,
-		FLAG_TTH_CHECK = 1 << 6,
-		FLAG_XML_BZ_LIST = 1 << 7
+		FLAG_TREE_TRIED = 1 << 2,
+		FLAG_TTH_CHECK = 1 << 3,
+		FLAG_XML_BZ_LIST = 1 << 4
 	};
 
 	Download(UserConnection& conn, QueueItem& qi, const string& path, bool supportsTrees) throw();

=== modified file 'dcpp/DownloadManager.cpp'
--- dcpp/DownloadManager.cpp	2010-08-27 13:47:33 +0000
+++ dcpp/DownloadManager.cpp	2010-12-03 13:59:16 +0000
@@ -24,7 +24,6 @@
 #include "QueueManager.h"
 #include "Download.h"
 #include "LogManager.h"
-#include "SFVReader.h"
 #include "User.h"
 #include "File.h"
 #include "FilteredFile.h"
@@ -336,13 +335,6 @@
 
 		dcdebug("Download finished: %s, size " I64_FMT ", downloaded " I64_FMT "\n", d->getPath().c_str(), d->getSize(), d->getPos());
 
-#if PORT_ME
-		// This should be done when the file is done, not the chunk...
-		if(BOOLSETTING(SFV_CHECK) && d->getType() == Transfer::TYPE_FILE) {
-			if(!checkSfv(aSource, d))
-				return;
-		}
-#endif
 		if(BOOLSETTING(LOG_DOWNLOADS) && (BOOLSETTING(LOG_FILELIST_TRANSFERS) || d->getType() == Transfer::TYPE_FILE)) {
 			logDownload(aSource, d);
 		}
@@ -355,49 +347,6 @@
 	checkDownloads(aSource);
 }
 
-uint32_t DownloadManager::calcCrc32(const string& file) throw(FileException) {
-	File ff(file, File::READ, File::OPEN);
-	CalcInputStream<CRC32Filter, false> f(&ff);
-
-	const size_t BUF_SIZE = 1024*1024;
-	boost::scoped_array<uint8_t> b(new uint8_t[BUF_SIZE]);
-	size_t n = BUF_SIZE;
-	while(f.read(&b[0], n) > 0)
-		;		// Keep on looping...
-
-	return f.getFilter().getValue();
-}
-
-bool DownloadManager::checkSfv(UserConnection* aSource, Download* d) {
-	SFVReader sfv(d->getPath());
-	if(sfv.hasCRC()) {
-		bool crcMatch = false;
-		try {
-			crcMatch = (calcCrc32(d->getDownloadTarget()) == sfv.getCRC());
-		} catch(const FileException& ) {
-			// Couldn't read the file to get the CRC(!!!)
-		}
-
-		if(!crcMatch) {
-			File::deleteFile(d->getDownloadTarget());
-			dcdebug("DownloadManager: CRC32 mismatch for %s\n", d->getPath().c_str());
-			LogManager::getInstance()->message(_("CRC32 inconsistency (SFV-Check)") + ' ' + Util::addBrackets(d->getPath()));
-			removeDownload(d);
-			fire(DownloadManagerListener::Failed(), d, _("CRC32 inconsistency (SFV-Check)"));
-
-			QueueManager::getInstance()->removeSource(d->getPath(), aSource->getUser(), QueueItem::Source::FLAG_CRC_WARN, false);
-			QueueManager::getInstance()->putDownload(d, false);
-
-			checkDownloads(aSource);
-			return false;
-		}
-
-		d->setFlag(Download::FLAG_CRC32_OK);
-
-		dcdebug("DownloadManager: CRC32 match for %s\n", d->getPath().c_str());
-	}
-	return true;
-}
 
 int64_t DownloadManager::getRunningAverage() {
 	Lock l(cs);

=== modified file 'dcpp/DownloadManager.h'
--- dcpp/DownloadManager.h	2010-08-27 13:47:33 +0000
+++ dcpp/DownloadManager.h	2010-12-03 13:59:16 +0000
@@ -69,8 +69,6 @@
 	void noSlots(UserConnection* aSource);
 
 	void logDownload(UserConnection* aSource, Download* d);
-	uint32_t calcCrc32(const string& file) throw(FileException);
-	bool checkSfv(UserConnection* aSource, Download* d);
 	int64_t getResumePos(const string& file, const TigerTree& tt, int64_t startPos);
 
 	void failDownload(UserConnection* aSource, const string& reason);

=== modified file 'dcpp/FinishedManager.cpp'
--- dcpp/FinishedManager.cpp	2010-10-02 22:00:14 +0000
+++ dcpp/FinishedManager.cpp	2010-12-03 13:59:16 +0000
@@ -34,11 +34,13 @@
 FinishedManager::FinishedManager() {
 	DownloadManager::getInstance()->addListener(this);
 	UploadManager::getInstance()->addListener(this);
+	QueueManager::getInstance()->addListener(this);
 }
 
 FinishedManager::~FinishedManager() throw() {
 	DownloadManager::getInstance()->removeListener(this);
 	UploadManager::getInstance()->removeListener(this);
+	QueueManager::getInstance()->removeListener(this);
 
 	clearDLs();
 	clearULs();
@@ -150,7 +152,7 @@
 				fire(FinishedManagerListener::AddedFile(), upload, file, p);
 			} else {
 				it->second->update(
-					t->getPos(),
+					crc32Checked ? 0 : t->getPos(), // in case of a successful crc check at the end we want to update the status only
 					milliSeconds,
 					time,
 					crc32Checked,
@@ -186,13 +188,17 @@
 	}
 }
 
+void FinishedManager::on(QueueManagerListener::CRCChecked, Download* d) throw() {
+	onComplete(d, false, /*crc32Checked*/true);
+}
+
 void FinishedManager::on(DownloadManagerListener::Complete, Download* d) throw() {
-	onComplete(d, false, d->isSet(Download::FLAG_CRC32_OK));
+	onComplete(d, false);
 }
 
 void FinishedManager::on(DownloadManagerListener::Failed, Download* d, const string&) throw() {
 	if(d->getPos() > 0)
-		onComplete(d, false, d->isSet(Download::FLAG_CRC32_OK));
+		onComplete(d, false);
 }
 
 void FinishedManager::on(UploadManagerListener::Complete, Upload* u) throw() {

=== modified file 'dcpp/FinishedManager.h'
--- dcpp/FinishedManager.h	2010-02-11 21:44:13 +0000
+++ dcpp/FinishedManager.h	2010-12-03 13:59:16 +0000
@@ -21,6 +21,7 @@
 
 #include "DownloadManagerListener.h"
 #include "UploadManagerListener.h"
+#include "QueueManagerListener.h"
 
 #include "Speaker.h"
 #include "CriticalSection.h"
@@ -32,7 +33,7 @@
 namespace dcpp {
 
 class FinishedManager : public Singleton<FinishedManager>,
-	public Speaker<FinishedManagerListener>, private DownloadManagerListener, private UploadManagerListener
+	public Speaker<FinishedManagerListener>, private DownloadManagerListener, private UploadManagerListener, private QueueManagerListener
 {
 public:
 	typedef unordered_map<string, FinishedFileItemPtr> MapByFile;
@@ -67,6 +68,8 @@
 
 	virtual void on(UploadManagerListener::Complete, Upload* u) throw();
 	virtual void on(UploadManagerListener::Failed, Upload* u, const string&) throw();
+	
+	virtual void on(QueueManagerListener::CRCChecked, Download* d) throw();
 };
 
 } // namespace dcpp

=== modified file 'dcpp/QueueManager.cpp'
--- dcpp/QueueManager.cpp	2010-12-01 18:49:09 +0000
+++ dcpp/QueueManager.cpp	2010-12-03 13:59:16 +0000
@@ -37,6 +37,8 @@
 #include "version.h"
 #include "SearchResult.h"
 #include "MerkleCheckOutputStream.h"
+#include "SFVReader.h"
+#include "FilteredFile.h"
 
 #include <climits>
 
@@ -1140,6 +1142,10 @@
 							q->addSegment(Segment(0, q->getSize()));
 						} else if(aDownload->getType() == Transfer::TYPE_FILE) {
 							q->addSegment(aDownload->getSegment());
+
+							if (q->isFinished() && BOOLSETTING(SFV_CHECK)) {
+								checkSfv(q, aDownload);
+							}
 						}
 
 						if(aDownload->getType() != Transfer::TYPE_FILE || q->isFinished()) {
@@ -1310,23 +1316,12 @@
 			return;
 		}
 
-		if(reason == QueueItem::Source::FLAG_CRC_WARN) {
-			// Already flagged?
-			QueueItem::SourceIter s = q->getSource(aUser);
-			if(s->isSet(QueueItem::Source::FLAG_CRC_WARN)) {
-				reason = QueueItem::Source::FLAG_CRC_FAILED;
-			} else {
-				s->setFlag(reason);
-				return;
-			}
-		}
-
 		if(q->isRunning() && userQueue.getRunning(aUser) == q) {
 			isRunning = true;
 			userQueue.removeDownload(q, aUser);
 			fire(QueueManagerListener::StatusUpdated(), q);
+		}
 
-		}
 		if(!q->isFinished()) {
 			userQueue.remove(q, aUser);
 		}
@@ -1715,4 +1710,54 @@
 	}
 }
 
+void QueueManager::checkSfv(QueueItem* qi, Download* d) {
+	SFVReader sfv(qi->getTarget());
+
+	if(sfv.hasCRC()) {
+		bool crcMatch = false;
+		try {
+			crcMatch = (calcCrc32(qi->getTempTarget()) == sfv.getCRC());
+		} catch(const FileException& ) {
+			// Couldn't read the file to get the CRC(!!!)
+		}
+
+		if(!crcMatch) {
+			/// @todo There is a slight chance that something happens with a file while it's being saved to disk 
+			/// maybe calculate tth along with crc and if tth is ok and crc is not flag the file as bad at once
+			/// if tth mismatches (possible disk error) then repair / redownload the file
+
+			File::deleteFile(qi->getTempTarget());
+			qi->resetDownloaded();
+			dcdebug("QueueManager: CRC32 mismatch for %s\n", qi->getTarget().c_str());
+			LogManager::getInstance()->message(_("CRC32 inconsistency (SFV-Check)") + ' ' + Util::addBrackets(qi->getTarget()));
+
+			setPriority(qi->getTarget(), QueueItem::PAUSED);
+
+			QueueItem::SourceList sources = qi->getSources();
+			for(QueueItem::SourceConstIter i = sources.begin(); i != sources.end(); ++i) {
+				removeSource(qi->getTarget(), i->getUser(), QueueItem::Source::FLAG_CRC_FAILED, false);
+			}
+
+			fire(QueueManagerListener::CRCFailed(), d, _("CRC32 inconsistency (SFV-Check)"));
+			return;
+		}
+
+		dcdebug("QueueManager: CRC32 match for %s\n", qi->getTarget().c_str());
+		fire(QueueManagerListener::CRCChecked(), d);
+	}
+}
+
+uint32_t QueueManager::calcCrc32(const string& file) throw(FileException) {
+	File ff(file, File::READ, File::OPEN);
+	CalcInputStream<CRC32Filter, false> f(&ff);
+
+	const size_t BUF_SIZE = 1024*1024;
+	boost::scoped_array<uint8_t> b(new uint8_t[BUF_SIZE]);
+	size_t n = BUF_SIZE;
+	while(f.read(&b[0], n) > 0)
+		;		// Keep on looping...
+
+	return f.getFilter().getValue();
+}
+
 } // namespace dcpp

=== modified file 'dcpp/QueueManager.h'
--- dcpp/QueueManager.h	2010-08-31 13:29:04 +0000
+++ dcpp/QueueManager.h	2010-12-03 13:59:16 +0000
@@ -258,6 +258,9 @@
 
 	string getListPath(const HintedUser& user);
 
+	void checkSfv(QueueItem* qi, Download* d);
+	uint32_t calcCrc32(const string& file) throw(FileException);
+
 	// TimerManagerListener
 	virtual void on(TimerManagerListener::Second, uint64_t aTick) throw();
 	virtual void on(TimerManagerListener::Minute, uint64_t aTick) throw();

=== modified file 'dcpp/QueueManagerListener.h'
--- dcpp/QueueManagerListener.h	2010-12-01 18:49:09 +0000
+++ dcpp/QueueManagerListener.h	2010-12-03 13:59:16 +0000
@@ -47,6 +47,9 @@
 
 	typedef X<15> FileMoved;
 
+	typedef X<16> CRCFailed;
+	typedef X<17> CRCChecked;
+
 	virtual void on(Added, QueueItem*) throw() { }
 	virtual void on(Finished, QueueItem*, const string&, int64_t) throw() { }
 	virtual void on(Removed, QueueItem*) throw() { }
@@ -65,6 +68,9 @@
 	virtual void on(RecheckDone, const string&) throw() { }
 
 	virtual void on(FileMoved, const string&) throw() { }
+
+	virtual void on(CRCFailed, Download*, const string&) throw() { }
+	virtual void on(CRCChecked, Download*) throw() { } 
 };
 
 } // namespace dcpp

=== modified file 'help/settings_logs.html'
--- help/settings_logs.html	2009-11-18 14:36:17 +0000
+++ help/settings_logs.html	2010-12-03 13:59:16 +0000
@@ -51,8 +51,9 @@
   <div>%[fileSIactualshort] - Actual uploaded bytes, short and including units</div>
   <div>%[speed] - Speed of the transfer</div>
   <div>%[time] - Elapsed time of the transfer</div>
-  <div>%[sfv] - Whether the file was checked against a SFV file (0 = no, 1 =
-yes).</div>
+  <!-- Readd this when we'll have real finished files log
+  <div>%[sfv] - Whether the file was checked against a SFV file (0 = no, 1 = yes).</div>
+  -->
   <div>%[tth] - Base32 representation of the tiger tree root hash</div>
   <div>Only for Download log: %[target] - Local path and filename</div>
   <div>Only for Upload log: %[source] - Local path for the upload.</div>

=== modified file 'win32/TransferView.cpp'
--- win32/TransferView.cpp	2010-12-01 17:58:05 +0000
+++ win32/TransferView.cpp	2010-12-03 13:59:16 +0000
@@ -827,7 +827,15 @@
 }
 
 void TransferView::on(DownloadManagerListener::Failed, Download* d, const string& aReason) throw() {
-	UpdateInfo* ui = new UpdateInfo(d->getHintedUser(), true, true);
+	onFailed(d, aReason);
+}
+
+void TransferView::on(QueueManagerListener::CRCFailed, Download* d, const string& aReason) throw() {
+	onFailed(d, aReason);
+}
+
+void TransferView::onFailed(Download* d, const string& aReason) {
+ 	UpdateInfo* ui = new UpdateInfo(d->getHintedUser(), true, true);
 	ui->setStatus(ConnectionInfo::STATUS_WAITING);
 	ui->setStatusString(Text::toT(aReason));
 

=== modified file 'win32/TransferView.h'
--- win32/TransferView.h	2010-12-01 17:58:05 +0000
+++ win32/TransferView.h	2010-12-03 13:59:16 +0000
@@ -292,9 +292,11 @@
 
 	virtual void on(QueueManagerListener::StatusUpdated, QueueItem*) throw();
 	virtual void on(QueueManagerListener::Removed, QueueItem*) throw();
+	virtual void on(QueueManagerListener::CRCFailed, Download* aDownload, const string& aReason) throw();
 
 	void onTransferTick(Transfer* aTransfer, bool isDownload);
 	void onTransferComplete(Transfer* aTransfer, bool isDownload);
+	void onFailed(Download* aDownload, const string& aReason);
 	void starting(UpdateInfo* ui, Transfer* t);
 
 	LRESULT handleCustomDraw(WPARAM wParam, LPARAM lParam);