summaryrefslogtreecommitdiff
path: root/common/kicad_curl
diff options
context:
space:
mode:
authorsaurabhb172020-02-26 16:20:48 +0530
committerGitHub2020-02-26 16:20:48 +0530
commitb77f5d9d8097c38159c6f60917995d6af13bbe1c (patch)
tree1392c90227aeea231c1d86371131e04c40382918 /common/kicad_curl
parentdadc4d490966a24efe15b5cc533ef8695986048a (diff)
parent003d02608917e7a69d1a98438837e94ccf68352a (diff)
downloadKiCad-eSim-b77f5d9d8097c38159c6f60917995d6af13bbe1c.tar.gz
KiCad-eSim-b77f5d9d8097c38159c6f60917995d6af13bbe1c.tar.bz2
KiCad-eSim-b77f5d9d8097c38159c6f60917995d6af13bbe1c.zip
Merge pull request #4 from FOSSEE/develop
merging dev into master
Diffstat (limited to 'common/kicad_curl')
-rw-r--r--common/kicad_curl/kicad_curl.cpp224
-rw-r--r--common/kicad_curl/kicad_curl_easy.cpp94
2 files changed, 318 insertions, 0 deletions
diff --git a/common/kicad_curl/kicad_curl.cpp b/common/kicad_curl/kicad_curl.cpp
new file mode 100644
index 0000000..fb4413c
--- /dev/null
+++ b/common/kicad_curl/kicad_curl.cpp
@@ -0,0 +1,224 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Mark Roszko <mark.roszko@gmail.com>
+ * Copyright (C) 2016 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * 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; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * 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, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+// kicad_curl.h must be included before wx headers, to avoid
+// conflicts for some defines, at least on Windows
+#include <kicad_curl/kicad_curl.h>
+
+#include <wx/log.h>
+#include <wx/dynlib.h>
+
+#include <macros.h>
+#include <fctsys.h>
+#include <ki_mutex.h> // MUTEX and MUTLOCK
+#include <richio.h>
+
+
+
+// These are even more private than class members, and since there is only
+// one instance of KICAD_CURL ever, these statics are hidden here to simplify the
+// client (API) header file.
+static volatile bool s_initialized;
+
+static MUTEX s_lock; // for s_initialized
+
+// Assume that on these platforms libcurl uses OpenSSL
+#if defined(__linux__) || defined(__MINGW32__)
+
+#include <openssl/crypto.h>
+
+static MUTEX* s_crypto_locks;
+
+static void lock_callback( int mode, int type, const char* file, int line )
+{
+ (void)file;
+ (void)line;
+
+ wxASSERT( s_crypto_locks && unsigned( type ) < unsigned( CRYPTO_num_locks() ) );
+
+ //DBG( printf( "%s: mode=0x%x type=%d file=%s line=%d\n", __func__, mode, type, file, line );)
+
+ if( mode & CRYPTO_LOCK )
+ {
+ s_crypto_locks[ type ].lock();
+ }
+ else
+ {
+ s_crypto_locks[ type ].unlock();
+ }
+}
+
+
+static void init_locks()
+{
+ s_crypto_locks = new MUTEX[ CRYPTO_num_locks() ];
+
+ // From http://linux.die.net/man/3/crypto_set_id_callback:
+
+ /*
+
+ OpenSSL can safely be used in multi-threaded applications provided that at
+ least two callback functions are set, locking_function and threadid_func.
+
+ locking_function(int mode, int n, const char *file, int line) is needed to
+ perform locking on shared data structures. (Note that OpenSSL uses a number
+ of global data structures that will be implicitly shared whenever multiple
+ threads use OpenSSL.) Multi-threaded applications will crash at random if it
+ is not set.
+
+ threadid_func( CRYPTO_THREADID *id) is needed to record the
+ currently-executing thread's identifier into id. The implementation of this
+ callback should not fill in id directly, but should use
+ CRYPTO_THREADID_set_numeric() if thread IDs are numeric, or
+ CRYPTO_THREADID_set_pointer() if they are pointer-based. If the application
+ does not register such a callback using CRYPTO_THREADID_set_callback(), then
+ a default implementation is used - on Windows and BeOS this uses the
+ system's default thread identifying APIs, and on all other platforms it uses
+ the address of errno. The latter is satisfactory for thread-safety if and
+ only if the platform has a thread-local error number facility.
+
+ Dick: "sounds like CRYPTO_THREADID_set_callback() is not mandatory on our
+ 2 OpenSSL platforms."
+
+ */
+
+ CRYPTO_set_locking_callback( &lock_callback );
+}
+
+
+static void kill_locks()
+{
+ CRYPTO_set_locking_callback( NULL );
+
+ delete[] s_crypto_locks;
+
+ s_crypto_locks = NULL;
+}
+
+#else
+
+inline void init_locks() { /* dummy */ }
+inline void kill_locks() { /* dummy */ }
+
+#endif
+
+/// At process termination, using atexit() keeps the CURL stuff out of the
+/// singletops and PGM_BASE.
+static void at_terminate()
+{
+ KICAD_CURL::Cleanup();
+}
+
+
+void KICAD_CURL::Init()
+{
+ // We test s_initialized twice in an effort to avoid
+ // unnecessarily locking s_lock. This understands that the common case
+ // will not need to lock.
+ if( !s_initialized )
+ {
+ MUTLOCK lock( s_lock );
+
+ if( !s_initialized )
+ {
+ if( curl_global_init( CURL_GLOBAL_ALL ) != CURLE_OK )
+ {
+ THROW_IO_ERROR( "curl_global_init() failed." );
+ }
+
+ init_locks();
+
+ wxLogDebug( "Using %s", GetVersion() );
+
+ s_initialized = true;
+ }
+ }
+}
+
+
+void KICAD_CURL::Cleanup()
+{
+ /*
+
+ Calling MUTLOCK() from a static destructor will typically be bad, since the
+ s_lock may already have been statically destroyed itself leading to a boost
+ exception. (Remember C++ does not provide certain sequencing of static
+ destructor invocation.)
+
+ To prevent this we test s_initialized twice, which ensures that the MUTLOCK
+ is only instantiated on the first call, which should be from
+ PGM_BASE::destroy() which is first called earlier than static destruction.
+ Then when called again from the actual PGM_BASE::~PGM_BASE() function,
+ MUTLOCK will not be instantiated because s_initialized will be false.
+
+ */
+
+ if( s_initialized )
+ {
+ MUTLOCK lock( s_lock );
+
+ if( s_initialized )
+ {
+ curl_global_cleanup();
+
+ kill_locks();
+
+ atexit( &at_terminate );
+
+ s_initialized = false;
+ }
+ }
+}
+
+
+std::string KICAD_CURL::GetSimpleVersion()
+{
+ if( !s_initialized )
+ Init();
+
+ curl_version_info_data* info = curl_version_info( CURLVERSION_NOW );
+
+ std::string res;
+
+ if( info->version )
+ {
+ res += "libcurl version: " + std::string( info->version );
+ }
+
+ res += " (";
+
+ if( info->features & CURL_VERSION_SSL )
+ {
+ res += "with SSL - ";
+ res += std::string( info->ssl_version );
+ }
+ else
+ {
+ res += "without SSL";
+ }
+ res += ")";
+
+ return res;
+}
diff --git a/common/kicad_curl/kicad_curl_easy.cpp b/common/kicad_curl/kicad_curl_easy.cpp
new file mode 100644
index 0000000..1e84afe
--- /dev/null
+++ b/common/kicad_curl/kicad_curl_easy.cpp
@@ -0,0 +1,94 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Mark Roszko <mark.roszko@gmail.com>
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * 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; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * 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, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <kicad_curl/kicad_curl_easy.h>
+
+#include <cstddef>
+#include <exception>
+#include <stdarg.h>
+#include <sstream>
+#include <richio.h>
+
+
+static size_t write_callback( void* contents, size_t size, size_t nmemb, void* userp )
+{
+ size_t realsize = size * nmemb;
+
+ std::string* p = (std::string*) userp;
+
+ p->append( (const char*) contents, realsize );
+
+ return realsize;
+}
+
+
+KICAD_CURL_EASY::KICAD_CURL_EASY() :
+ m_headers( NULL )
+{
+ // Call KICAD_CURL::Init() from in here everytime, but only the first time
+ // will incur any overhead. This strategy ensures that libcurl is never loaded
+ // unless it is needed.
+
+ KICAD_CURL::Init();
+
+ m_CURL = curl_easy_init();
+
+ if( !m_CURL )
+ {
+ THROW_IO_ERROR( "Unable to initialize CURL session" );
+ }
+
+ curl_easy_setopt( m_CURL, CURLOPT_WRITEFUNCTION, write_callback );
+ curl_easy_setopt( m_CURL, CURLOPT_WRITEDATA, (void*) &m_buffer );
+}
+
+
+KICAD_CURL_EASY::~KICAD_CURL_EASY()
+{
+ if( m_headers )
+ curl_slist_free_all( m_headers );
+
+ curl_easy_cleanup( m_CURL );
+}
+
+
+void KICAD_CURL_EASY::Perform()
+{
+ if( m_headers )
+ {
+ curl_easy_setopt( m_CURL, CURLOPT_HTTPHEADER, m_headers );
+ }
+
+ // bonus: retain worst case memory allocation, should re-use occur
+ m_buffer.clear();
+
+ CURLcode res = curl_easy_perform( m_CURL );
+
+ if( res != CURLE_OK )
+ {
+ std::string msg = StrPrintf( "curl_easy_perform()=%d: %s",
+ res, GetErrorText( res ).c_str() );
+ THROW_IO_ERROR( msg );
+ }
+}