From cfca4513e49d52b1ac3be469f42892aa7f258e74 Mon Sep 17 00:00:00 2001 From: Massimo Gengarelli Date: Tue, 1 May 2012 17:24:27 +0200 Subject: [PATCH 1/3] Major refactor Since we've decided to keep the two projects separated it's necessary that if some one wants to clone the repository he has a clear idea of what's going on here: in src/lib folder there are the three main components of the library libgrive (drive, protocol and util); while in the src/cli folder there's the command line interface tool that uses the library. The CLI is called in the same way as the library (grive). In this way, we can keep multiple clients using the same library in just one repo.. --- CMakeLists.txt | 80 ++++-------------------------- src/CMakeLists.txt | 4 ++ src/cli/CMakeLists.txt | 14 ++++++ src/{ => cli}/main.cc | 0 src/lib/CMakeLists.txt | 46 +++++++++++++++++ src/{ => lib}/drive/Collection.cc | 0 src/{ => lib}/drive/Collection.hh | 0 src/{ => lib}/drive/Drive.cc | 0 src/{ => lib}/drive/Drive.hh | 0 src/{ => lib}/protocol/Download.cc | 0 src/{ => lib}/protocol/Download.hh | 0 src/{ => lib}/protocol/HTTP.cc | 0 src/{ => lib}/protocol/HTTP.hh | 0 src/{ => lib}/protocol/Json.cc | 0 src/{ => lib}/protocol/Json.hh | 0 src/{ => lib}/protocol/OAuth2.cc | 0 src/{ => lib}/protocol/OAuth2.hh | 0 src/{ => lib}/util/Crypt.cc | 0 src/{ => lib}/util/Crypt.hh | 0 src/{ => lib}/util/DateTime.cc | 0 src/{ => lib}/util/DateTime.hh | 0 src/{ => lib}/util/Function.hh | 0 src/{ => lib}/util/OS.cc | 0 src/{ => lib}/util/OS.hh | 0 src/{ => lib}/util/Path.cc | 0 src/{ => lib}/util/Path.hh | 0 test/CMakeLists.txt | 14 ++++++ 27 files changed, 87 insertions(+), 71 deletions(-) create mode 100644 src/CMakeLists.txt create mode 100644 src/cli/CMakeLists.txt rename src/{ => cli}/main.cc (100%) create mode 100644 src/lib/CMakeLists.txt rename src/{ => lib}/drive/Collection.cc (100%) rename src/{ => lib}/drive/Collection.hh (100%) rename src/{ => lib}/drive/Drive.cc (100%) rename src/{ => lib}/drive/Drive.hh (100%) rename src/{ => lib}/protocol/Download.cc (100%) rename src/{ => lib}/protocol/Download.hh (100%) rename src/{ => lib}/protocol/HTTP.cc (100%) rename src/{ => lib}/protocol/HTTP.hh (100%) rename src/{ => lib}/protocol/Json.cc (100%) rename src/{ => lib}/protocol/Json.hh (100%) rename src/{ => lib}/protocol/OAuth2.cc (100%) rename src/{ => lib}/protocol/OAuth2.hh (100%) rename src/{ => lib}/util/Crypt.cc (100%) rename src/{ => lib}/util/Crypt.hh (100%) rename src/{ => lib}/util/DateTime.cc (100%) rename src/{ => lib}/util/DateTime.hh (100%) rename src/{ => lib}/util/Function.hh (100%) rename src/{ => lib}/util/OS.cc (100%) rename src/{ => lib}/util/OS.hh (100%) rename src/{ => lib}/util/Path.cc (100%) rename src/{ => lib}/util/Path.hh (100%) create mode 100644 test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 09aa10b..e01806c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,78 +9,16 @@ find_package(JSONC REQUIRED) find_package(CURL REQUIRED) find_package(CppUnit) +# Common include +include_directories( ${grive_SOURCE_DIR}/src/lib + ${OPT_INCS} +) + +add_subdirectory(src) + IF ( CPPUNIT_FOUND ) + message("-- Building unitary tests along with the library and the binary") set( OPT_INCS ${CPPUNIT_INCLUDE_DIR} ) + add_subdirectory(test) ENDIF ( CPPUNIT_FOUND ) -include_directories( - ${grive_SOURCE_DIR}/src - ${OPT_INCS} -) - -file(GLOB DRIVE_HEADERS - ${grive_SOURCE_DIR}/src/drive/*.hh -) - -file (GLOB PROTOCOL_HEADERS - ${grive_SOURCE_DIR}/src/protocol/*.hh -) - -file (GLOB UTIL_HEADERS - ${grive_SOURCE_DIR}/src/util/*.hh -) - -add_library( fgrive SHARED - src/drive/Collection.cc - src/drive/Drive.cc - src/protocol/Download.cc - src/protocol/HTTP.cc - src/protocol/Json.cc - src/protocol/OAuth2.cc - src/util/Crypt.cc - src/util/DateTime.cc - src/util/OS.cc - src/util/Path.cc -) - -add_executable( grive - src/main.cc -) - -target_link_libraries( fgrive - ${CURL_LIBRARIES} - ${JSONC_LIBRARY} - ${OPENSSL_LIBRARIES} -) - -target_link_libraries( grive - fgrive -) - -set_target_properties(fgrive PROPERTIES - SOVERSION 0 VERSION 0.0.1 -) - -IF ( CPPUNIT_FOUND ) - add_executable( unittest - test/UnitTest.cc - test/util/DateTimeTest.cc - test/util/FunctionTest.cc - test/util/PathTest.cc - ) - - target_link_libraries( unittest - fgrive - ${CPPUNIT_LIBRARY} - ) - else ( CPPUNIT_FOUND ) - message( STATUS "skip building unittest" ) -endif ( CPPUNIT_FOUND ) - - -## Install targets -install(TARGETS fgrive LIBRARY DESTINATION lib) -install(TARGETS grive RUNTIME DESTINATION bin) -install(FILES ${DRIVE_HEADERS} DESTINATION include/grive/drive) -install(FILES ${PROTOCOL_HEADERS} DESTINATION include/grive/protocol) -install(FILES ${UTIL_HEADERS} DESTINATION include/grive/util) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..7b3f05d --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,4 @@ +# Keep the order right + +add_subdirectory(lib) +add_subdirectory(cli) \ No newline at end of file diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt new file mode 100644 index 0000000..1e7d682 --- /dev/null +++ b/src/cli/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( grive_executable + main.cc +) + +target_link_libraries( grive_executable + grive +) + +set_target_properties( grive_executable + PROPERTIES OUTPUT_NAME grive +) + +install(TARGETS grive_executable RUNTIME DESTINATION bin) \ No newline at end of file diff --git a/src/main.cc b/src/cli/main.cc similarity index 100% rename from src/main.cc rename to src/cli/main.cc diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt new file mode 100644 index 0000000..f75c64e --- /dev/null +++ b/src/lib/CMakeLists.txt @@ -0,0 +1,46 @@ +# lib subproject + +file(GLOB DRIVE_SOURCES + drive/*.cc +) + +file(GLOB PROTOCOL_SOURCES + protocol/*.cc +) + +file(GLOB UTIL_SOURCES + util/*.cc +) + +file(GLOB DRIVE_HEADERS + drive/*.hh +) + +file (GLOB PROTOCOL_HEADERS + protocol/*.hh +) + +file (GLOB UTIL_HEADERS + util/*.hh +) + +add_library( grive SHARED + ${DRIVE_SOURCES} + ${PROTOCOL_SOURCES} + ${UTIL_SOURCES} +) + +target_link_libraries( grive + ${CURL_LIBRARIES} + ${JSONC_LIBRARY} + ${OPENSSL_LIBRARIES} +) + +set_target_properties(grive PROPERTIES + SOVERSION 0 VERSION 0.0.1 +) + +install(TARGETS grive LIBRARY DESTINATION lib) +install(FILES ${DRIVE_HEADERS} DESTINATION include/grive/drive) +install(FILES ${PROTOCOL_HEADERS} DESTINATION include/grive/protocol) +install(FILES ${UTIL_HEADERS} DESTINATION include/grive/util) \ No newline at end of file diff --git a/src/drive/Collection.cc b/src/lib/drive/Collection.cc similarity index 100% rename from src/drive/Collection.cc rename to src/lib/drive/Collection.cc diff --git a/src/drive/Collection.hh b/src/lib/drive/Collection.hh similarity index 100% rename from src/drive/Collection.hh rename to src/lib/drive/Collection.hh diff --git a/src/drive/Drive.cc b/src/lib/drive/Drive.cc similarity index 100% rename from src/drive/Drive.cc rename to src/lib/drive/Drive.cc diff --git a/src/drive/Drive.hh b/src/lib/drive/Drive.hh similarity index 100% rename from src/drive/Drive.hh rename to src/lib/drive/Drive.hh diff --git a/src/protocol/Download.cc b/src/lib/protocol/Download.cc similarity index 100% rename from src/protocol/Download.cc rename to src/lib/protocol/Download.cc diff --git a/src/protocol/Download.hh b/src/lib/protocol/Download.hh similarity index 100% rename from src/protocol/Download.hh rename to src/lib/protocol/Download.hh diff --git a/src/protocol/HTTP.cc b/src/lib/protocol/HTTP.cc similarity index 100% rename from src/protocol/HTTP.cc rename to src/lib/protocol/HTTP.cc diff --git a/src/protocol/HTTP.hh b/src/lib/protocol/HTTP.hh similarity index 100% rename from src/protocol/HTTP.hh rename to src/lib/protocol/HTTP.hh diff --git a/src/protocol/Json.cc b/src/lib/protocol/Json.cc similarity index 100% rename from src/protocol/Json.cc rename to src/lib/protocol/Json.cc diff --git a/src/protocol/Json.hh b/src/lib/protocol/Json.hh similarity index 100% rename from src/protocol/Json.hh rename to src/lib/protocol/Json.hh diff --git a/src/protocol/OAuth2.cc b/src/lib/protocol/OAuth2.cc similarity index 100% rename from src/protocol/OAuth2.cc rename to src/lib/protocol/OAuth2.cc diff --git a/src/protocol/OAuth2.hh b/src/lib/protocol/OAuth2.hh similarity index 100% rename from src/protocol/OAuth2.hh rename to src/lib/protocol/OAuth2.hh diff --git a/src/util/Crypt.cc b/src/lib/util/Crypt.cc similarity index 100% rename from src/util/Crypt.cc rename to src/lib/util/Crypt.cc diff --git a/src/util/Crypt.hh b/src/lib/util/Crypt.hh similarity index 100% rename from src/util/Crypt.hh rename to src/lib/util/Crypt.hh diff --git a/src/util/DateTime.cc b/src/lib/util/DateTime.cc similarity index 100% rename from src/util/DateTime.cc rename to src/lib/util/DateTime.cc diff --git a/src/util/DateTime.hh b/src/lib/util/DateTime.hh similarity index 100% rename from src/util/DateTime.hh rename to src/lib/util/DateTime.hh diff --git a/src/util/Function.hh b/src/lib/util/Function.hh similarity index 100% rename from src/util/Function.hh rename to src/lib/util/Function.hh diff --git a/src/util/OS.cc b/src/lib/util/OS.cc similarity index 100% rename from src/util/OS.cc rename to src/lib/util/OS.cc diff --git a/src/util/OS.hh b/src/lib/util/OS.hh similarity index 100% rename from src/util/OS.hh rename to src/lib/util/OS.hh diff --git a/src/util/Path.cc b/src/lib/util/Path.cc similarity index 100% rename from src/util/Path.cc rename to src/lib/util/Path.cc diff --git a/src/util/Path.hh b/src/lib/util/Path.hh similarity index 100% rename from src/util/Path.hh rename to src/lib/util/Path.hh diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..8670329 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,14 @@ +# test subfolder + +file(GLOB UTIL_TESTS util/*.cc) + + +add_executable( unittest + UnitTest.cc + ${UTIL_TESTS} +) + +target_link_libraries(unittest + grive + ${CPPUNIT_LIBRARY} +) From 95133eff57efb462ae4d4cbdb27bc37a000345d2 Mon Sep 17 00:00:00 2001 From: Massimo Gengarelli Date: Tue, 1 May 2012 19:44:22 +0200 Subject: [PATCH 2/3] Added a Signal Handler In order to prevent the user to ^C while downloading a file (thus, risking to have an incoherent situation and prevent a bad behaviour of grive), it's necessary to register some signals. These two classes provide a wrapper around the C function signal, with facilities to register and unregister signals.. --- src/lib/util/SignalHandler.cc | 100 +++++++++++++++++++++++++++++++++ src/lib/util/SignalHandler.hh | 62 ++++++++++++++++++++ test/UnitTest.cc | 2 + test/util/SignalHandlerTest.cc | 51 +++++++++++++++++ test/util/SignalHandlerTest.hh | 41 ++++++++++++++ 5 files changed, 256 insertions(+) create mode 100644 src/lib/util/SignalHandler.cc create mode 100644 src/lib/util/SignalHandler.hh create mode 100644 test/util/SignalHandlerTest.cc create mode 100644 test/util/SignalHandlerTest.hh diff --git a/src/lib/util/SignalHandler.cc b/src/lib/util/SignalHandler.cc new file mode 100644 index 0000000..43328ee --- /dev/null +++ b/src/lib/util/SignalHandler.cc @@ -0,0 +1,100 @@ +/* + grive: an GPL program to sync a local directory with Google Drive + Copyright (C) 2012 Wan Wai Ho + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation version 2 + of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + + +#include "SignalHandler.hh" +#include +#include +#include +#include +#include + +namespace gr { + +SignalError::SignalError( const std::string& message ) : + std::runtime_error( message ) +{ +} + +SignalError::~SignalError() throw () +{ + +} + +SignalHandler::SignalHandler() +{ + +} + +SignalHandler::SignalHandler( const SignalHandler& right ) +{ + +} + +SignalHandler& SignalHandler::operator ==( const SignalHandler& right ) +{ + return (*this); +} + +SignalHandler::~SignalHandler() +{ + +} + +SignalHandler& SignalHandler::GetInstance() +{ + static SignalHandler _instance; + return _instance; +} + +void SignalHandler::UnregisterSignal( unsigned int signumber ) +{ + m_signals[signumber] = 0 ; + + // Restore the old signal + signal( ( int ) signumber, m_signalsOld[signumber] ); +} + +void SignalHandler::RegisterSignal( unsigned int signumber, Callback callback ) +{ + signals_t::const_iterator anIterator ; + for (anIterator = m_signals.begin(); anIterator != m_signals.end(); ++anIterator) + { + if (anIterator->first == signumber) + { + if (anIterator->second != 0) + { + std::ostringstream oss; + oss << "Signal " << signumber << " already has a callback!"; + throw SignalError( oss.str() ); ; + } + } + } + + m_signals[signumber] = callback ; + + if ( ( m_signalsOld[signumber] = signal( ( int ) signumber, m_signals[signumber] ) ) == SIG_ERR ) { + throw SignalError( " Error while registering the signal! " ) ; + } +} + +} + + + diff --git a/src/lib/util/SignalHandler.hh b/src/lib/util/SignalHandler.hh new file mode 100644 index 0000000..2ef0867 --- /dev/null +++ b/src/lib/util/SignalHandler.hh @@ -0,0 +1,62 @@ +/* + grive: an GPL program to sync a local directory with Google Drive + Copyright (C) 2012 Wan Wai Ho + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation version 2 + of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include +#include +#include + +namespace gr { + +class SignalError : public std::runtime_error +{ +public : + SignalError( const std::string& message ) ; + virtual ~SignalError() throw () ; +}; + +class SignalFunctor +{ +public : + SignalFunctor() ; + virtual ~SignalFunctor() ; + static void Callback( int signumber ) ; +}; + +class SignalHandler +{ + typedef void (*Callback)(int); + typedef std::map signals_t ; + +public : + virtual ~SignalHandler() ; + void RegisterSignal ( unsigned int signumber, Callback callback ) ; + void UnregisterSignal( unsigned int signumber ); + static SignalHandler& GetInstance() ; +private : + SignalHandler() ; + SignalHandler( const SignalHandler& right ) ; + SignalHandler& operator==( const SignalHandler& right ) ; + + signals_t m_signals; + signals_t m_signalsOld; +}; + +} diff --git a/test/UnitTest.cc b/test/UnitTest.cc index 3343354..4670ced 100644 --- a/test/UnitTest.cc +++ b/test/UnitTest.cc @@ -22,6 +22,7 @@ #include "util/DateTimeTest.hh" #include "util/FunctionTest.hh" #include "util/PathTest.hh" +#include "util/SignalHandlerTest.hh" int main( int argc, char **argv ) { @@ -31,6 +32,7 @@ int main( int argc, char **argv ) runner.addTest( DateTimeTest::suite( ) ) ; runner.addTest( FunctionTest::suite( ) ) ; runner.addTest( PathTest::suite( ) ) ; + runner.addTest( SignalHandlerTest::suite( ) ) ; runner.run(); return 0 ; diff --git a/test/util/SignalHandlerTest.cc b/test/util/SignalHandlerTest.cc new file mode 100644 index 0000000..c7110d7 --- /dev/null +++ b/test/util/SignalHandlerTest.cc @@ -0,0 +1,51 @@ +/* + grive: an GPL program to sync a local directory with Google Drive + Copyright (C) 2012 Wan Wai Ho + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation version 2 + of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "SignalHandlerTest.hh" + +#include "util/SignalHandler.hh" + +#include + +void test_callback( int ) +{ + +} + +namespace grut { + +using namespace gr ; + +SignalHandlerTest::SignalHandlerTest( ) +{ +} + +void SignalHandlerTest::TestMultipleSignals( ) +{ + SignalHandler::GetInstance().RegisterSignal( SIGINT, &test_callback ); + CPPUNIT_ASSERT_THROW( + SignalHandler::GetInstance().RegisterSignal( SIGINT, &test_callback ), + SignalError); + + SignalHandler::GetInstance().UnregisterSignal( SIGINT ); + CPPUNIT_ASSERT_NO_THROW( + SignalHandler::GetInstance().RegisterSignal( SIGINT, &test_callback )); +} + +} diff --git a/test/util/SignalHandlerTest.hh b/test/util/SignalHandlerTest.hh new file mode 100644 index 0000000..81d6232 --- /dev/null +++ b/test/util/SignalHandlerTest.hh @@ -0,0 +1,41 @@ +/* + grive: an GPL program to sync a local directory with Google Drive + Copyright (C) 2012 Wan Wai Ho + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation version 2 + of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include +#include + +namespace grut { + +class SignalHandlerTest : public CppUnit::TestFixture +{ +public : + SignalHandlerTest( ) ; + + // declare suit function + CPPUNIT_TEST_SUITE( SignalHandlerTest ) ; + CPPUNIT_TEST( TestMultipleSignals ) ; + CPPUNIT_TEST_SUITE_END(); + +private : + void TestMultipleSignals( ) ; +} ; + +} // end of namespace From 2791bbbfe8c50730f17af70d5516d022afd4f544 Mon Sep 17 00:00:00 2001 From: Massimo Gengarelli Date: Tue, 1 May 2012 19:47:25 +0200 Subject: [PATCH 3/3] Prevent the user from sending a SIGINT while downloading a file.. --- src/lib/protocol/Download.cc | 4 ++++ src/lib/protocol/HTTP.cc | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/lib/protocol/Download.cc b/src/lib/protocol/Download.cc index 1959dd3..e763e94 100644 --- a/src/lib/protocol/Download.cc +++ b/src/lib/protocol/Download.cc @@ -18,6 +18,7 @@ */ #include "Download.hh" +#include "../util/SignalHandler.hh" #include @@ -57,6 +58,9 @@ Download::~Download( ) std::string Download::Finish() const { + // Unregister the signal + SignalHandler::GetInstance().UnregisterSignal( SIGINT ) ; + std::string result ; // get the checksum and return it ; diff --git a/src/lib/protocol/HTTP.cc b/src/lib/protocol/HTTP.cc index 847a689..44a7b61 100644 --- a/src/lib/protocol/HTTP.cc +++ b/src/lib/protocol/HTTP.cc @@ -20,6 +20,7 @@ #include "HTTP.hh" #include "Download.hh" +#include "../util/SignalHandler.hh" // dependent libraries #include @@ -109,6 +110,14 @@ void DoCurl( CURL *curl ) } } +// Callback for SIGINT +void CallbackInt( int ) +{ + // TODO: instead of just disabling the signal, clean up the environment + // and exit gracefully + std::cout << " Signal disabled while downloading file..\n"; +} + } // end of local namespace namespace gr { namespace http { @@ -139,6 +148,9 @@ void GetFile( const std::string& filename, const Headers& hdr ) { + // Register the callback + SignalHandler::GetInstance().RegisterSignal( SIGINT, &CallbackInt ) ; + Download dl( filename, Download::NoChecksum() ) ; CURL *curl = InitCurl( url, 0, hdr ) ;