Update CMakeLists.txt - play with openssl
[novacoin.git] / src / qt / qtipcserver.cpp
1 // Copyright (c) 2009-2012 The Bitcoin developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include <boost/version.hpp>
6 #if defined(WIN32) && BOOST_VERSION <= 104900
7 #define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME
8 #define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
9 #endif
10
11 #include "qtipcserver.h"
12 #include "guiconstants.h"
13 #include "interface.h"
14 #include "util.h"
15
16 #include <boost/algorithm/string/predicate.hpp>
17 #include <boost/date_time/posix_time/posix_time.hpp>
18 #include <boost/interprocess/ipc/message_queue.hpp>
19 #include <boost/version.hpp>
20
21 #ifndef _MSC_VER
22 #if defined(WIN32) && (!defined(BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME) || !defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)) && BOOST_VERSION <= 104900
23 #warning Compiling without BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME and BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME uncommented in boost/interprocess/detail/tmp_dir_helpers.hpp or using a boost version before 1.49 may have unintended results see svn.boost.org/trac/boost/ticket/5392
24 #endif
25 #endif
26
27 #if defined __APPLE__ || defined __FreeBSD__
28 // URI handling not implemented on OSX yet
29
30 void ipcScanRelay(int argc, char *argv[]) { }
31 void ipcInit(int argc, char *argv[]) { }
32
33 #else
34
35 static void ipcThread2(void* pArg);
36
37 static bool ipcScanCmd(int argc, char *argv[], bool fRelay)
38 {
39     // Check for URI in argv
40     bool fSent = false;
41     for (int i = 1; i < argc; i++)
42     {
43         if (boost::algorithm::istarts_with(argv[i], "novacoin:"))
44         {
45             const char *strURI = argv[i];
46             try {
47                 boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME);
48                 if (mq.try_send(strURI, strlen(strURI), 0))
49                     fSent = true;
50                 else if (fRelay)
51                     break;
52             }
53             catch (const boost::interprocess::interprocess_exception &ex) {
54                 // don't log the "file not found" exception, because that's normal for
55                 // the first start of the first instance
56                 if (ex.get_error_code() != boost::interprocess::not_found_error || !fRelay)
57                 {
58                     printf("main() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what());
59                     break;
60                 }
61             }
62         }
63     }
64     return fSent;
65 }
66
67 void ipcScanRelay(int argc, char *argv[])
68 {
69     if (ipcScanCmd(argc, argv, true))
70         exit(0);
71 }
72
73 static void ipcThread(void* pArg)
74 {
75     // Make this thread recognisable as the GUI-IPC thread
76     RenameThread("novacoin-gui-ipc");
77         
78     try
79     {
80         ipcThread2(pArg);
81     }
82     catch (std::exception& e) {
83         PrintExceptionContinue(&e, "ipcThread()");
84     } catch (...) {
85         PrintExceptionContinue(NULL, "ipcThread()");
86     }
87     printf("ipcThread exited\n");
88 }
89
90 static void ipcThread2(void* pArg)
91 {
92     printf("ipcThread started\n");
93
94     auto mq = (boost::interprocess::message_queue*)pArg;
95     char buffer[MAX_URI_LENGTH + 1] = "";
96     size_t nSize = 0;
97     unsigned int nPriority = 0;
98
99     for ( ; ; )
100     {
101         auto d = boost::posix_time::microsec_clock::universal_time() + boost::posix_time::millisec(100);
102         if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d))
103         {
104             uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize));
105             Sleep(1000);
106         }
107
108         if (fShutdown)
109             break;
110     }
111
112     // Remove message queue
113     boost::interprocess::message_queue::remove(BITCOINURI_QUEUE_NAME);
114     // Cleanup allocated memory
115     delete mq;
116 }
117
118 void ipcInit(int argc, char *argv[])
119 {
120     boost::interprocess::message_queue* mq = nullptr;
121     char buffer[MAX_URI_LENGTH + 1] = "";
122     size_t nSize = 0;
123     unsigned int nPriority = 0;
124
125     try {
126         mq = new boost::interprocess::message_queue(boost::interprocess::open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);
127
128         // Make sure we don't lose any bitcoin: URIs
129         for (int i = 0; i < 2; i++)
130         {
131             auto d = boost::posix_time::microsec_clock::universal_time() + boost::posix_time::millisec(1);
132             if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d))
133             {
134                 uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize));
135             }
136             else
137                 break;
138         }
139
140         // Make sure only one bitcoin instance is listening
141         boost::interprocess::message_queue::remove(BITCOINURI_QUEUE_NAME);
142         delete mq;
143
144         mq = new boost::interprocess::message_queue(boost::interprocess::open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);
145     }
146     catch (const boost::interprocess::interprocess_exception &ex) {
147         printf("ipcInit() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what());
148         return;
149     }
150
151     if (!NewThread(ipcThread, mq))
152     {
153         delete mq;
154         return;
155     }
156
157     ipcScanCmd(argc, argv, false);
158 }
159
160 #endif