diff --git a/ChangeLog b/ChangeLog index 25fbed08..8d686da0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-07-13 Tatsuhiro Tsujikawa + + Added the ability to save signature when download is completed if + signature is available. The filename of signature file is the path to + download file followed by ".sig". If it already exists, then signature + will not be saved. + * src/RequestGroupMan.cc + * src/Signature.cc + * test/SignatureTest.cc + 2008-07-12 Tatsuhiro Tsujikawa Updated the descriptions for --bt-seed-unverified. diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc index a8dd8e05..0f2f40fe 100644 --- a/src/RequestGroupMan.cc +++ b/src/RequestGroupMan.cc @@ -42,6 +42,7 @@ #include "message.h" #include "a2functional.h" #include "DownloadResult.h" +#include "DownloadContext.h" #include #include #include @@ -111,6 +112,23 @@ private: std::deque >& _reservedGroups; std::deque >& _downloadResults; Logger* _logger; + + void saveSignature(const SharedHandle& group) + { + SharedHandle sig = + group->getDownloadContext()->getSignature(); + if(!sig.isNull() && !sig->getBody().empty()) { + // filename of signature file is the path to download file followed by + // ".sig". + std::string signatureFile = group->getFilePath()+".sig"; + if(sig->save(signatureFile)) { + _logger->notice("Saved signature as %s", signatureFile.c_str()); + } else { + _logger->notice("Saving signature as %s failed. Maybe file" + " already exists.", signatureFile.c_str()); + } + } + } public: ProcessStoppedRequestGroup (std::deque >& reservedGroups, @@ -128,6 +146,7 @@ public: group->reportDownloadFinished(); if(group->allDownloadFinished()) { group->getProgressInfoFile()->removeFile(); + saveSignature(group); } else { group->getProgressInfoFile()->save(); } @@ -148,7 +167,6 @@ public: _downloadResults.push_back(group->createDownloadResult()); } } - }; class FindStoppedRequestGroup { diff --git a/src/Signature.cc b/src/Signature.cc index 5672034e..2b3c2d4c 100644 --- a/src/Signature.cc +++ b/src/Signature.cc @@ -33,6 +33,8 @@ */ /* copyright --> */ #include "Signature.h" +#include "File.h" +#include namespace aria2 { @@ -72,8 +74,18 @@ const std::string& Signature::getBody() const bool Signature::save(const std::string& filepath) const { - // TODO not yet implemented - return false; + if(File(filepath).exists()) { + return false; + } + std::ofstream out(filepath.c_str()); + try { + out.exceptions(std::ios::failbit); + out << _body; + out.close(); + return true; + } catch(const std::ios::failure& exception) { + return false; + } } } // namespace aria2 diff --git a/test/Makefile.am b/test/Makefile.am index dac85bc9..f5d27299 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -52,7 +52,8 @@ aria2c_SOURCES = AllTest.cc\ StringFormatTest.cc\ ExceptionTest.cc\ DownloadHandlerFactoryTest.cc\ - ChunkedDecoderTest.cc + ChunkedDecoderTest.cc\ + SignatureTest.cc if HAVE_LIBZ aria2c_SOURCES += GZipDecoderTest.cc diff --git a/test/Makefile.in b/test/Makefile.in index 36719ab8..487120c6 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -188,7 +188,7 @@ am__aria2c_SOURCES_DIST = AllTest.cc SocketCoreTest.cc \ MultiFileAllocationIteratorTest.cc FixedNumberRandomizer.h \ ProtocolDetectorTest.cc StringFormatTest.cc ExceptionTest.cc \ DownloadHandlerFactoryTest.cc ChunkedDecoderTest.cc \ - GZipDecoderTest.cc MessageDigestHelperTest.cc \ + SignatureTest.cc GZipDecoderTest.cc MessageDigestHelperTest.cc \ IteratableChunkChecksumValidatorTest.cc \ IteratableChecksumValidatorTest.cc BtAllowedFastMessageTest.cc \ BtBitfieldMessageTest.cc BtCancelMessageTest.cc \ @@ -352,8 +352,9 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) SocketCoreTest.$(OBJEXT) \ MultiFileAllocationIteratorTest.$(OBJEXT) \ ProtocolDetectorTest.$(OBJEXT) StringFormatTest.$(OBJEXT) \ ExceptionTest.$(OBJEXT) DownloadHandlerFactoryTest.$(OBJEXT) \ - ChunkedDecoderTest.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ - $(am__objects_3) $(am__objects_4) + ChunkedDecoderTest.$(OBJEXT) SignatureTest.$(OBJEXT) \ + $(am__objects_1) $(am__objects_2) $(am__objects_3) \ + $(am__objects_4) aria2c_OBJECTS = $(am_aria2c_OBJECTS) am__DEPENDENCIES_1 = aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1) @@ -568,8 +569,8 @@ aria2c_SOURCES = AllTest.cc SocketCoreTest.cc array_funTest.cc \ MultiFileAllocationIteratorTest.cc FixedNumberRandomizer.h \ ProtocolDetectorTest.cc StringFormatTest.cc ExceptionTest.cc \ DownloadHandlerFactoryTest.cc ChunkedDecoderTest.cc \ - $(am__append_1) $(am__append_2) $(am__append_3) \ - $(am__append_4) + SignatureTest.cc $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) #aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64 #aria2c_LDFLAGS = ${CPPUNIT_LIBS} @@ -774,6 +775,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SequenceTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShareRatioSeedCriteriaTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SharedHandleTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SignatureTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SingleFileAllocationIteratorTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SingleFileDownloadContextTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SingletonHolderTest.Po@am__quote@ diff --git a/test/SignatureTest.cc b/test/SignatureTest.cc new file mode 100644 index 00000000..03a90898 --- /dev/null +++ b/test/SignatureTest.cc @@ -0,0 +1,45 @@ +#include "Signature.h" +#include "Exception.h" +#include "File.h" +#include +#include + +namespace aria2 { + +class SignatureTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(SignatureTest); + CPPUNIT_TEST(testSave); + CPPUNIT_TEST_SUITE_END(); +public: + void setUp() {} + + void tearDown() {} + + void testSave(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(SignatureTest); + +void SignatureTest::testSave() +{ + Signature sig; + sig.setBody("SIGNATURE"); + std::string filepath = "/tmp/aria2_SignatureTest_testSave"; + File outfile(filepath); + if(outfile.exists()) { + outfile.remove(); + } + CPPUNIT_ASSERT(sig.save(filepath)); + { + std::ifstream in(filepath.c_str()); + std::string fileContent; + in >> fileContent; + CPPUNIT_ASSERT_EQUAL(sig.getBody(), fileContent); + } + // second attempt to save will fail because file already exists. + CPPUNIT_ASSERT(!sig.save(filepath)); +} + +} // namespace aria2