GCC Code Coverage Report


Directory: ./
File: pdserv/src/Main.cpp
Date: 2025-08-17 04:10:43
Exec Total Coverage
Lines: 325 480 67.7%
Branches: 442 1493 29.6%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * Copyright 2010 Richard Hacker (lerichi at gmx dot net)
4 *
5 * This file is part of the pdserv library.
6 *
7 * The pdserv library is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation, either version 3 of the License, or (at
10 * your option) any later version.
11 *
12 * The pdserv library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>.
19 *
20 ****************************************************************************/
21
22 #include "config.h"
23 #include "Debug.h"
24
25 #include <cerrno>
26 #include <cstdio> // fread(), fileno()
27 #include <unistd.h> // fork(), getpid(), chdir, sysconf, close, fstat()
28 // stat()
29 #include <signal.h> // signal()
30 #include <limits.h> // _POSIX_OPEN_MAX
31 #include <sys/types.h> // umask(), fstat(), stat(), opendir()
32 #include <sys/stat.h> // umask(), fstat(), stat()
33 #include <sys/time.h> // gettimeofday()
34 #include <dirent.h> // opendir(), readdir()
35 #include <iomanip> // std::setw(), std::setfill()
36 #include <algorithm> // std::copy()
37 #include <iterator> // std::back_inserter()
38 #include <memory>
39 #include <set>
40
41 #include <pdserv.h> // pdserv_full_version
42
43 #include <log4cplus/syslogappender.h>
44 #include <log4cplus/consoleappender.h>
45 #include <log4cplus/streams.h>
46 #include <log4cplus/configurator.h>
47 #include <log4cplus/loggingmacros.h>
48 #include <log4cplus/version.h>
49
50 #include "Exceptions.h"
51 #include "Main.h"
52 #include "Task.h"
53 #include "Signal.h"
54 #include "ProcessParameter.h"
55 #include "Database.h"
56 #include "Config.h"
57 #include "Event.h"
58 #include "Session.h"
59 #include "msrproto/Server.h"
60
61 #ifndef _GNU_SOURCE
62 # define _GNU_SOURCE
63 #endif
64 #include <string.h> // basename()
65
66 #ifdef GNUTLS_FOUND
67 #include "TLS.h"
68 3 log4cplus::Logger tlsLogger;
69 #endif
70
71 #if __cplusplus < 201402L
72 namespace std {
73 template <typename T, typename... Args>
74 std::unique_ptr<T> make_unique(Args&&... args) {
75 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
76 }
77 }
78 #endif
79
80 using namespace PdServ;
81
82 /////////////////////////////////////////////////////////////////////////////
83 18 inline bool operator== (const struct timespec& t1, const struct timespec& t2)
84 {
85
3/4
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 2 times.
18 return t1.tv_sec == t2.tv_sec and t1.tv_nsec == t2.tv_nsec;
86 }
87
88 19 inline bool operator< (const struct timespec& t1, const struct timespec& t2)
89 {
90 19 return (t1.tv_sec < t2.tv_sec
91
4/6
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 18 times.
19 or (t1.tv_sec == t2.tv_sec and t1.tv_nsec < t2.tv_nsec));
92 }
93
94 /////////////////////////////////////////////////////////////////////////////
95 inline bool operator! (const struct timespec& t)
96 {
97 return !(t.tv_sec or t.tv_nsec);
98 }
99
100 /////////////////////////////////////////////////////////////////////////////
101 struct Main::EventInstance {
102 const PdServ::Event* event;
103 size_t index;
104 Event::Priority priority;
105 uint32_t seqNo;
106 struct timespec time;
107 bool state;
108
109 19 bool operator()(const EventInstance* a, const EventInstance* b) const {
110 19 return a->time < b->time
111
5/6
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1 times.
✓ Branch 5 taken 16 times.
✓ Branch 6 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16 times.
19 or (a->time == b->time and int(a->seqNo - b->seqNo) < 0);
112 }
113
114 48 operator EventData() const {
115 EventData d = {
116 48 this->event,
117 48 this->seqNo,
118 48 this->index,
119
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 this->priority,
120
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 this->state,
121 this->time
122 240 };
123 48 return d;
124 }
125
126 friend std::ostream& operator<<(std::ostream& os,
127 const EventInstance& i) {
128 os
129 << i.event
130 << ' ' << i.index
131 << ' ' << i.priority
132 << ' ' << i.seqNo
133 << ' ' << i.state;
134 return os;
135 }
136 };
137
138 namespace std {
139 std::ostream& operator<< (std::ostream& os, const timespec& ts)
140 {
141 char fill = os.fill('0');
142 std::streamsize width = os.width(9);
143 os << ts.tv_sec << '.' << ts.tv_nsec;
144 os.width(width);
145 os.fill(fill);
146 return os;
147 }
148 }
149
150 /////////////////////////////////////////////////////////////////////////////
151 157 Main::Main(const std::string& name, const std::string& version):
152 name(name), version(version),
153 parameterLog(
154 log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("parameter"))),
155 eventLog(log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("event")))
156 #ifdef GNUTLS_FOUND
157 ,
158
11/22
✓ Branch 7 taken 157 times.
✗ Branch 8 not taken.
✓ Branch 17 taken 157 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 157 times.
✗ Branch 24 not taken.
✓ Branch 28 taken 157 times.
✗ Branch 29 not taken.
✓ Branch 38 taken 157 times.
✗ Branch 39 not taken.
✓ Branch 43 taken 157 times.
✗ Branch 44 not taken.
✓ Branch 51 taken 157 times.
✗ Branch 52 not taken.
✓ Branch 55 taken 157 times.
✗ Branch 56 not taken.
✓ Branch 59 taken 157 times.
✗ Branch 60 not taken.
✓ Branch 65 taken 157 times.
✗ Branch 66 not taken.
✓ Branch 75 taken 157 times.
✗ Branch 76 not taken.
157 tlsSessionDB(&tls_mutex, TLS_DB_SIZE)
159 #endif
160 {
161 157 msrproto = 0;
162 157 }
163
164 /////////////////////////////////////////////////////////////////////////////
165 314 Main::~Main()
166 {
167 #ifdef GNUTLS_FOUND
168 157 destroyTLS();
169 #endif
170 157 for (std::set<EventInstance*>::iterator it = danglingInstances.begin();
171
1/2
✗ Branch 6 not taken.
✓ Branch 7 taken 157 times.
157 it != danglingInstances.end(); ++it)
172 delete *it;
173
174 157 for (EventInstanceMap::iterator it = eventMap.begin();
175
1/2
✗ Branch 6 not taken.
✓ Branch 7 taken 157 times.
157 it != eventMap.end(); ++it)
176 delete it->second;
177 157 }
178
179 /////////////////////////////////////////////////////////////////////////////
180 155 int Main::setupLogging(const std::string& configFile)
181 {
182 #ifdef PDS_DEBUG
183 consoleLogging();
184 #endif
185
186
1/2
✓ Branch 6 taken 155 times.
✗ Branch 7 not taken.
155 unsigned int history = config("eventhistory").toUInt(100);
187 155 eventInstance.resize(history);
188 155 eventPtr = &eventInstance[0];
189
190
2/4
✓ Branch 6 taken 155 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 155 times.
✗ Branch 11 not taken.
155 if (config("logging")) {
191 typedef std::basic_istringstream<log4cplus::tchar> tistringstream;
192 155 tistringstream is(
193
3/6
✓ Branch 5 taken 155 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 155 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 155 times.
✗ Branch 16 not taken.
310 LOG4CPLUS_STRING_TO_TSTRING(config("logging").toString()));
194
3/6
✓ Branch 2 taken 155 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 155 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 155 times.
✗ Branch 12 not taken.
155 log4cplus::PropertyConfigurator(is).configure();
195 }
196 else {
197 syslogLogging();
198 }
199
200 try
201 {
202 // Test logging setup to provoke an early exception before fork
203 155 log4cplus::Logger log =
204
2/6
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 155 times.
✗ Branch 9 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
155 log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("logging_test"));
205 LOG4CPLUS_TRACE_STR(log, LOG4CPLUS_TEXT("Logging initialized."));
206 }
207 catch (std::exception &e) {
208 log_debug("Failed to test logging: %s", e.what());
209 return -1;
210 }
211
212
11/22
✓ Branch 3 taken 155 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 155 times.
✗ Branch 8 not taken.
✓ Branch 16 taken 155 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 155 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 155 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 155 times.
✗ Branch 26 not taken.
✓ Branch 29 taken 155 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 155 times.
✗ Branch 33 not taken.
✓ Branch 36 taken 155 times.
✗ Branch 37 not taken.
✓ Branch 40 taken 155 times.
✗ Branch 41 not taken.
✓ Branch 44 taken 155 times.
✗ Branch 45 not taken.
155 LOG4CPLUS_INFO(log4cplus::Logger::getRoot(),
213 LOG4CPLUS_TEXT("Started application ")
214 << LOG4CPLUS_STRING_TO_TSTRING(name)
215 << LOG4CPLUS_TEXT(", Version ")
216 << LOG4CPLUS_STRING_TO_TSTRING(version));
217
218
9/18
✓ Branch 3 taken 155 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 155 times.
✗ Branch 8 not taken.
✓ Branch 16 taken 155 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 155 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 155 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 155 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 155 times.
✗ Branch 29 not taken.
✓ Branch 32 taken 155 times.
✗ Branch 33 not taken.
✓ Branch 36 taken 155 times.
✗ Branch 37 not taken.
155 LOG4CPLUS_INFO(log4cplus::Logger::getRoot(),
219 LOG4CPLUS_TEXT("Using PdServ version ")
220 << LOG4CPLUS_STRING_TO_TSTRING(pdserv_full_version));
221
222
1/2
✓ Branch 2 taken 155 times.
✗ Branch 3 not taken.
155 if (!configFile.empty())
223
9/18
✓ Branch 3 taken 155 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 155 times.
✗ Branch 8 not taken.
✓ Branch 16 taken 155 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 155 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 155 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 155 times.
✗ Branch 26 not taken.
✓ Branch 29 taken 155 times.
✗ Branch 30 not taken.
✓ Branch 33 taken 155 times.
✗ Branch 34 not taken.
✓ Branch 37 taken 155 times.
✗ Branch 38 not taken.
155 LOG4CPLUS_INFO(log4cplus::Logger::getRoot(),
224 LOG4CPLUS_TEXT("Using configuration: ")
225 << LOG4CPLUS_STRING_TO_TSTRING(configFile));
226
227 155 return 0;
228 }
229
230 /////////////////////////////////////////////////////////////////////////////
231 void Main::consoleLogging()
232 {
233 log4cplus::BasicConfigurator::doConfigure();
234 }
235
236 /////////////////////////////////////////////////////////////////////////////
237 void Main::syslogLogging()
238 {
239 log4cplus::helpers::Properties p;
240 p.setProperty(LOG4CPLUS_TEXT("ident"),
241 LOG4CPLUS_STRING_TO_TSTRING(name));
242 p.setProperty(LOG4CPLUS_TEXT("facility"),LOG4CPLUS_TEXT("local0"));
243
244 log4cplus::SharedAppenderPtr appender( new log4cplus::SysLogAppender(p));
245 #if LOG4CPLUS_VERSION > LOG4CPLUS_MAKE_VERSION(1,2,0)
246 appender->setLayout(std::make_unique<log4cplus::PatternLayout>(
247 LOG4CPLUS_TEXT("%-5p %c <%x>: %m")));
248 #else
249 appender->setLayout(
250 std::auto_ptr<log4cplus::Layout>(new log4cplus::PatternLayout(
251 LOG4CPLUS_TEXT("%-5p %c <%x>: %m"))));
252 #endif
253
254 log4cplus::Logger root = log4cplus::Logger::getRoot();
255 root.addAppender(appender);
256 root.setLogLevel(log4cplus::INFO_LOG_LEVEL);
257 }
258
259 /////////////////////////////////////////////////////////////////////////////
260 int Main::gettime(struct timespec* t) const
261 {
262 return localtime(t);
263 }
264
265 /////////////////////////////////////////////////////////////////////////////
266 int Main::localtime(struct timespec* t)
267 {
268 struct timeval tv;
269
270 if (::gettimeofday(&tv, 0))
271 return errno;
272 t->tv_sec = tv.tv_sec;
273 t->tv_nsec = tv.tv_usec * 1000;
274
275 return 0;
276 }
277
278 /////////////////////////////////////////////////////////////////////////////
279 154 void Main::startServers()
280 {
281
1/2
✓ Branch 2 taken 154 times.
✗ Branch 3 not taken.
308 log4cplus::Logger logger = log4cplus::Logger::getRoot();
282
283 #ifdef GNUTLS_FOUND
284
3/6
✓ Branch 7 taken 154 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 154 times.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 154 times.
154 if (const int ret = setupTLS(config("tls"), logger)) {
285 LOG4CPLUS_FATAL_STR(logger,
286 LOG4CPLUS_TEXT("Fatal TLS error."));
287 throw PdServ::Errno(ret);
288 }
289 #endif
290
291
2/4
✓ Branch 7 taken 154 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 154 times.
✗ Branch 12 not taken.
154 setupAccessControl(config("access"));
292
293
6/12
✓ Branch 3 taken 154 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 154 times.
✗ Branch 8 not taken.
✓ Branch 16 taken 154 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 154 times.
✗ Branch 19 not taken.
✓ Branch 24 taken 154 times.
✗ Branch 25 not taken.
✓ Branch 28 taken 154 times.
✗ Branch 29 not taken.
154 LOG4CPLUS_INFO_STR(log4cplus::Logger::getRoot(),
294 LOG4CPLUS_TEXT("Starting servers"));
295
296
4/6
✓ Branch 4 taken 154 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 154 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 149 times.
✓ Branch 13 taken 5 times.
159 msrproto = new MsrProto::Server(this, config("msr"));
297 149 }
298
299 /////////////////////////////////////////////////////////////////////////////
300 154 void Main::stopServers()
301 {
302
2/2
✓ Branch 3 taken 149 times.
✓ Branch 4 taken 5 times.
154 delete msrproto;
303
304 154 savePersistent();
305
306
6/12
✓ Branch 3 taken 154 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 154 times.
✗ Branch 8 not taken.
✓ Branch 16 taken 154 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 154 times.
✗ Branch 19 not taken.
✓ Branch 24 taken 154 times.
✗ Branch 25 not taken.
✓ Branch 28 taken 154 times.
✗ Branch 29 not taken.
154 LOG4CPLUS_INFO_STR(log4cplus::Logger::getRoot(),
307 LOG4CPLUS_TEXT("Shut down servers"));
308 154 }
309
310 /////////////////////////////////////////////////////////////////////////////
311 43 int Main::setValue(const ProcessParameter* p, const Session* session,
312 const char* buf, size_t offset, size_t count)
313 {
314
6/10
✗ Branch 3 not taken.
✓ Branch 4 taken 43 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 41 times.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 43 times.
43 if (!(m_write or session->loggedIn()))
315 return -EACCES;
316
317 // Ask the implementation to change value.
318 43 const char* data;
319 43 const struct timespec* time;
320
1/2
✓ Branch 6 taken 43 times.
✗ Branch 7 not taken.
43 int rv = setValue(p, buf, offset, count, &data, &time);
321
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if (rv)
322 return rv;
323
324
1/2
✓ Branch 7 taken 43 times.
✗ Branch 8 not taken.
43 msrproto->parameterChanged(p, offset, count, data, time);
325
326
1/2
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
86 PersistentMap::iterator it = persistentMap.find(p);
327 43 bool persistent = it != persistentMap.end();
328
1/2
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
43 bool log = parameterLog.isEnabledFor(log4cplus::INFO_LOG_LEVEL);
329 86 std::string logString;
330
331 // Setup logString when parameter has to be logged
332
5/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 42 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 43 times.
✗ Branch 10 not taken.
43 if ((persistent and persistentLogTraceOn) or log) {
333
1/2
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
86 std::ostringstream os;
334
2/4
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 43 times.
✗ Branch 6 not taken.
43 os.imbue(std::locale::classic());
335
1/2
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
43 os << p->path;
336
337
1/2
✓ Branch 1 taken 43 times.
✗ Branch 2 not taken.
43 os << " = ";
338
339
1/2
✓ Branch 7 taken 43 times.
✗ Branch 8 not taken.
43 static_cast<const ProcessParameter*>(p)->print(os, 0, p->memSize);
340
341
1/2
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
43 logString = os.str();
342 }
343
344 // Save persistent parameter
345
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 42 times.
43 if (persistent) {
346
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
3 PdServ::Database(persistentLog,
347
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
2 persistentConfig["database"].toString())
348
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
2 .save(p, data, time);
349
350
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
1 if (persistentLogTraceOn)
351 LOG4CPLUS_INFO_STR(persistentLogTrace,
352 LOG4CPLUS_STRING_TO_TSTRING(logString));
353
354
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (it->second) {
355 LOG4CPLUS_WARN(persistentLog,
356 LOG4CPLUS_TEXT("Persistent parameter ")
357 << LOG4CPLUS_STRING_TO_TSTRING(p->path)
358 << LOG4CPLUS_TEXT(" is coupled to signal ")
359 << LOG4CPLUS_STRING_TO_TSTRING(it->second->path)
360 << LOG4CPLUS_TEXT(
361 ". Manually setting a parameter-signal pair "
362 "saves the parameter only and removes coupling. "
363 "Restart process soon."));
364 it->second = 0;
365 }
366 }
367
368 // Log parameter change
369
1/2
✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
43 if (log) {
370
1/2
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
43 parameterLog.forcedLog(log4cplus::INFO_LOG_LEVEL,
371 LOG4CPLUS_STRING_TO_TSTRING(logString));
372 }
373
374 43 return 0;
375 }
376
377 /////////////////////////////////////////////////////////////////////////////
378 155 unsigned int Main::setupPersistent()
379 {
380 310 std::set<std::string> keys;
381
382
2/4
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 155 times.
✗ Branch 10 not taken.
155 persistentConfig = config("persistent");
383
3/4
✓ Branch 2 taken 155 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 141 times.
✓ Branch 5 taken 14 times.
155 if (not persistentConfig) {
384 141 return 0;
385 }
386
387
2/4
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
✓ Branch 9 taken 14 times.
✗ Branch 10 not taken.
28 const std::string databasePath(persistentConfig["database"].toString());
388
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 6 times.
14 if (databasePath.empty()) {
389 8 return 0;
390 }
391
392
2/4
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
6 persistentLog = log4cplus::Logger::getRoot();
393
394 // Get variable list
395
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 PdServ::Config varList(persistentConfig["variables"]);
396
8/20
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 6 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 6 times.
✓ Branch 15 taken 6 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 6 times.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 6 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
6 if (not varList or not varList[size_t(0)]) {
397 LOG4CPLUS_INFO_STR(persistentLog,
398 LOG4CPLUS_TEXT("Persistent variable list is empty"));
399 return 0;
400 }
401
402
2/4
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
6 persistentLogTraceOn = persistentConfig["trace"].toUInt();
403
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
6 if (persistentLogTraceOn)
404 persistentLogTrace =
405 log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("persistent"));
406
407
1/2
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
12 Database dataBase(persistentLog, databasePath);
408
409 // Copy signals from tasks
410 typedef std::map<std::string, const Signal*> SignalMap;
411 12 SignalMap signalMap;
412
413 typedef std::list<const Task*> TaskList;
414
1/2
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
12 TaskList task = getTasks();
415 18 for (TaskList::iterator it = task.begin();
416
2/2
✓ Branch 6 taken 12 times.
✓ Branch 7 taken 6 times.
18 it != task.end(); ++it) {
417 typedef std::list<const PdServ::Signal*> SignalList;
418
419 12 SignalList signals =
420
1/2
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
24 static_cast<const PdServ::Task*>(*it)->getSignals();
421
422 48 for (SignalList::iterator it = signals.begin();
423
2/2
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 12 times.
48 it != signals.end(); ++it)
424
1/2
✓ Branch 5 taken 36 times.
✗ Branch 6 not taken.
36 signalMap[(*it)->path] = *it;
425 }
426
427
428 // Go through the variables section of the configuration to
429 // find parameters to watch. There are 2 ways of specifying a variable
430 // 1) string only pointing to a parameter to watch
431 // 2) map with "parameter:" string pointing to a parameter to watch
432 // 2) map with "parameter" and "signal" of a pair to watch
433 // e.g.
434 // variables:
435 // - "/path/to/parameter"
436 // - parameter: "/path/to/parameter"
437 // - parameter: /path/to/integrator/offset
438 // signal: "/path/to/integrator"
439
4/6
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 6 times.
✓ Branch 11 taken 6 times.
12 for (size_t i = 0; varList[i]; ++i) {
440
2/4
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
12 const PdServ::Config& item = varList[i];
441 Parameter* param;
442 6 const Signal* signal = 0;
443
444 6 std::string path =
445
7/12
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 2 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 17 taken 6 times.
✗ Branch 18 not taken.
✓ Branch 24 taken 6 times.
✗ Branch 25 not taken.
12 (item.isMapping() ? item["parameter"] : item).toString();
446
447
1/2
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
6 param = findParameter(path);
448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!param) {
449 // Parameter does not exist
450 LOG4CPLUS_WARN(persistentLog,
451 LOG4CPLUS_TEXT("Persistent parameter ")
452 << LOG4CPLUS_STRING_TO_TSTRING(path)
453 << LOG4CPLUS_TEXT(" does not exist."));
454 continue;
455 }
456
457
2/4
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 6 times.
6 if (persistentMap.find(param) != persistentMap.end()) {
458 LOG4CPLUS_INFO(persistentLog,
459 LOG4CPLUS_TEXT("Persistent parameter ")
460 << LOG4CPLUS_STRING_TO_TSTRING(path)
461 << LOG4CPLUS_TEXT(" traced already."));
462 continue;
463 }
464
465
12/20
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 2 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✓ Branch 17 taken 2 times.
✓ Branch 19 taken 4 times.
✓ Branch 20 taken 2 times.
✓ Branch 22 taken 4 times.
✓ Branch 23 taken 2 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
6 if (item.isMapping() and item["signal"]) {
466
2/4
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
4 path = item["signal"].toString();
467
468
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (!path.empty()) {
469 // Parameter <-> Signal pair
470
2/4
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
8 SignalMap::const_iterator srcIt(signalMap.find(path));
471
472
1/2
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
4 if (srcIt == signalMap.end()) {
473 // Signal does not exist
474 LOG4CPLUS_WARN(persistentLog,
475 LOG4CPLUS_TEXT("Signal ")
476 << LOG4CPLUS_STRING_TO_TSTRING(path)
477 << LOG4CPLUS_TEXT(
478 " of persistent pair does not exist."));
479 continue;
480 }
481
1/2
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
4 signal = srcIt->second;
482 }
483 }
484
485
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 if (signal) {
486 // Check whether signal is compatable to parameter
487
2/4
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 4 times.
4 if (signal->dtype != param->dtype) {
488 // Data types do not match
489 LOG4CPLUS_WARN(persistentLog,
490 LOG4CPLUS_TEXT("Data type of signal ")
491 << LOG4CPLUS_STRING_TO_TSTRING(signal->path)
492 << LOG4CPLUS_TEXT(" and parameter ")
493 << LOG4CPLUS_STRING_TO_TSTRING(param->path)
494 << LOG4CPLUS_TEXT(" does not match"));
495 continue;
496 }
497
2/4
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
4 else if (signal->dim != param->dim) {
498 // Data dimensions do not match
499 LOG4CPLUS_WARN(persistentLog,
500 LOG4CPLUS_TEXT("Data dimension of signal ")
501 << LOG4CPLUS_STRING_TO_TSTRING(signal->path)
502 << LOG4CPLUS_TEXT(" and parameter ")
503 << LOG4CPLUS_STRING_TO_TSTRING(param->path)
504 << LOG4CPLUS_TEXT(" does not match"));
505 continue;
506 }
507 }
508
509
1/2
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 persistentMap[param] = signal;
510
1/2
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
6 keys.insert(param->path);
511
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 if (signal)
512
9/18
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 4 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 4 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✓ Branch 26 taken 4 times.
✗ Branch 27 not taken.
✓ Branch 30 taken 4 times.
✗ Branch 31 not taken.
✓ Branch 34 taken 4 times.
✗ Branch 35 not taken.
4 LOG4CPLUS_DEBUG(persistentLog,
513 LOG4CPLUS_TEXT("Added persistent parameter-signal pair: ")
514 << LOG4CPLUS_STRING_TO_TSTRING(signal->path)
515 << LOG4CPLUS_TEXT(" -> ")
516 << LOG4CPLUS_STRING_TO_TSTRING(param->path));
517 else
518
7/14
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 23 taken 2 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 2 times.
✗ Branch 28 not taken.
2 LOG4CPLUS_DEBUG(persistentLog,
519 LOG4CPLUS_TEXT("Added persistent parameter: ")
520 << LOG4CPLUS_STRING_TO_TSTRING(param->path));
521
522 // Last but not least, read peristent value from database and
523 // set parameter
524 6 const struct timespec* mtime;
525 6 const char* value;
526
3/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 2 times.
6 if (dataBase.read(param, &value, &mtime)) {
527
1/2
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
4 initializeParameter(param, value, mtime, signal);
528
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
4 if (persistentLogTraceOn) {
529 std::ostringstream os;
530 os.imbue(std::locale::classic());
531 os << param->path;
532
533 os << " = ";
534
535 param->dtype.print(os, value, value, value + param->memSize);
536
537 LOG4CPLUS_INFO_STR(persistentLogTrace,
538 LOG4CPLUS_STRING_TO_TSTRING(os.str()));
539 }
540 }
541
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 else if (signal)
542
2/4
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
1 initializeParameter(param, 0, 0, signal);
543 }
544
545 // Purge unneeded parameters from database, unless disabled by
546 // configuration
547
3/6
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
6 if (persistentConfig["cleanup"].toUInt(1))
548
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 dataBase.checkKeys(keys);
549
550
2/4
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
6 return persistentConfig["interval"].toUInt();
551 }
552
553 /////////////////////////////////////////////////////////////////////////////
554 154 void Main::savePersistent()
555 {
556
2/2
✓ Branch 2 taken 149 times.
✓ Branch 3 taken 5 times.
154 if (persistentMap.empty())
557 149 return;
558
559
4/8
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
✓ Branch 14 taken 5 times.
✗ Branch 15 not taken.
✓ Branch 18 taken 5 times.
✗ Branch 19 not taken.
5 LOG4CPLUS_INFO_STR(persistentLog,
560 LOG4CPLUS_TEXT("Saving persistent parameters"));
561
562 // Open database and return if there are problems
563 5 PdServ::Database db(persistentLog,
564
5/8
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
✓ Branch 9 taken 5 times.
✗ Branch 10 not taken.
✓ Branch 14 taken 5 times.
✗ Branch 15 not taken.
✓ Branch 23 taken 5 times.
✓ Branch 24 taken 149 times.
10 persistentConfig["database"].toString());
565
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
5 if (!db)
566 return;
567
568 // Only save signal/parameter pairs. Persistent paremters are saved as
569 // they are changed
570
1/2
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
10 for (PersistentMap::iterator it = persistentMap.begin();
571
2/2
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 5 times.
10 it != persistentMap.end(); ++it) {
572 5 const Signal* signal = it->second;
573
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if (!signal)
574 2 continue;
575
576 3 const Parameter* param = it->first;
577
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
3 char buf[param->memSize];
578 3 struct timespec time;
579
580 log_debug("Save %s", signal->path.c_str());
581
2/4
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
3 if (getPersistentSignalValue(signal, buf, &time)) {
582
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 db.save(param, buf, &time);
583
584
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
3 if (persistentLogTraceOn) {
585 std::ostringstream os;
586 os.imbue(std::locale::classic());
587 os << param->path;
588
589 os << " = ";
590
591 param->dtype.print(os, buf, buf, buf + param->memSize);
592
593 LOG4CPLUS_INFO_STR(persistentLogTrace,
594 LOG4CPLUS_STRING_TO_TSTRING(os.str()));
595 }
596
597
11/20
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 3 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 3 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 3 times.
✗ Branch 23 not taken.
✓ Branch 26 taken 3 times.
✗ Branch 27 not taken.
✓ Branch 30 taken 3 times.
✗ Branch 31 not taken.
✓ Branch 34 taken 3 times.
✗ Branch 35 not taken.
✓ Branch 39 taken 3 times.
✓ Branch 40 taken 2 times.
3 LOG4CPLUS_DEBUG(persistentLog,
598 LOG4CPLUS_TEXT("Saved persistent parameter ")
599 << LOG4CPLUS_STRING_TO_TSTRING(param->path)
600 << LOG4CPLUS_TEXT(" from signal ")
601 << LOG4CPLUS_STRING_TO_TSTRING(signal->path));
602 }
603 5 }
604 }
605
606 /////////////////////////////////////////////////////////////////////////////
607 27 void Main::newEvent(const Event* event,
608 size_t index, int i_state, const struct timespec* time)
609 {
610
1/2
✓ Branch 5 taken 27 times.
✗ Branch 6 not taken.
54 pthread::WriteLock lock(eventMutex);
611
612 27 bool state = i_state >= 0;
613
1/2
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
27 EventInstanceVector*& vec = eventMap[event];
614
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 13 times.
27 if (!vec)
615
2/4
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 14 times.
✗ Branch 10 not taken.
14 vec = new EventInstanceVector(event->nelem());
616
617
1/2
✓ Branch 3 taken 27 times.
✗ Branch 4 not taken.
27 EventInstance*& instance = vec->at(index);
618
619
3/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
27 if (!state and !instance)
620 return;
621
622 27 Event::Priority priority = state
623
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
38 ? static_cast<Event::Priority>(i_state)
624 11 : instance->priority;
625
626 // Check whether instance has been outcast from eventInstance and
627 // lives in separate memory
628
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
54 if (instance
629
3/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 16 times.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
27 and (instance < &eventInstance.front()
630
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
11 or instance > &eventInstance.back())) {
631 danglingInstances.erase(instance);
632 delete instance;
633 }
634
635 // Make sure that the event in history list has been reset.
636 // Otherwise separate it out and make it dangling
637
1/6
✗ Branch 4 not taken.
✓ Branch 5 taken 27 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
27 if (eventPtr->event and eventPtr->state) {
638 EventInstance*& instPtrRef =
639 eventMap[eventPtr->event]->at(eventPtr->index);
640 if (instPtrRef == eventPtr) {
641 instPtrRef = new EventInstance;
642 *instPtrRef = *eventPtr;
643 danglingInstances.insert(instPtrRef);
644 }
645 }
646
647 // Let instance point to new event
648
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 11 times.
27 instance = state ? eventPtr : 0;
649
650 27 eventPtr->event = event;
651 27 eventPtr->index = index;
652 27 eventPtr->priority = priority;
653 27 eventPtr->seqNo = eventSeqNo++;
654 27 eventPtr->time = *time;
655 27 eventPtr->state = state;
656
657
1/2
✗ Branch 6 not taken.
✓ Branch 7 taken 27 times.
27 if (eventPtr++ == &eventInstance.back())
658 eventPtr = &eventInstance.front();
659
660 log4cplus::LogLevel log_prio;
661
2/5
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
27 switch (priority) {
662 22 case PdServ::Event::Emergency:
663 case PdServ::Event::Alert:
664 case PdServ::Event::Critical:
665 22 log_prio = log4cplus::FATAL_LOG_LEVEL;
666 22 break;
667 case PdServ::Event::Error:
668 log_prio = log4cplus::ERROR_LOG_LEVEL;
669 break;
670 5 case PdServ::Event::Warning:
671 5 log_prio = log4cplus::WARN_LOG_LEVEL;
672 5 break;
673 case PdServ::Event::Notice:
674 case PdServ::Event::Info:
675 log_prio = log4cplus::INFO_LOG_LEVEL;
676 break;
677 case PdServ::Event::Debug:
678 default:
679 log_prio = log4cplus::DEBUG_LOG_LEVEL;
680 break;
681 }
682
683
2/4
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 27 times.
✗ Branch 8 not taken.
54 log4cplus::tostringstream os;
684
685
1/2
✓ Branch 3 taken 27 times.
✗ Branch 4 not taken.
27 os << time->tv_sec << '.'
686
4/8
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 27 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 27 times.
✗ Branch 11 not taken.
✓ Branch 17 taken 27 times.
✗ Branch 18 not taken.
27 << std::setw(6) << std::setfill('0') << time->tv_nsec/1000
687 << std::setw(0)
688
2/4
✓ Branch 3 taken 27 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 27 times.
✗ Branch 7 not taken.
27 << LOG4CPLUS_TEXT(": ");
689
690
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 16 times.
27 if (!state) {
691 11 log_prio = log4cplus::INFO_LOG_LEVEL;
692
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 os << LOG4CPLUS_TEXT("RESET ");
693 }
694
695
2/4
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 27 times.
✗ Branch 6 not taken.
27 os << '/' << LOG4CPLUS_STRING_TO_TSTRING(event->path);
696
2/2
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 10 times.
27 if (event->nelem() > 1)
697
3/6
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 17 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 17 times.
✗ Branch 12 not taken.
17 os << '[' << index << ']';
698
2/4
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
27 os << '/' << '/';
699
700
5/6
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 11 times.
✓ Branch 6 taken 16 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 11 times.
27 if (state and not event->messages[index].empty()) {
701
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 8 not taken.
16 os << ' ' << LOG4CPLUS_STRING_TO_TSTRING(event->messages[index]);
702 }
703
704
2/4
✓ Branch 5 taken 27 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 27 times.
✗ Branch 10 not taken.
27 eventLog.log(log_prio, os.str());
705 }
706
707 /////////////////////////////////////////////////////////////////////////////
708 9635 const Main::EventInstance* Main::m_getEventInstance(uint32_t seqNo) const
709 {
710 9635 size_t ptr = size_t(seqNo) - eventInstance.front().seqNo;
711 9635 size_t len = eventInstance.size();
712
713
2/2
✓ Branch 0 taken 9424 times.
✓ Branch 1 taken 211 times.
9635 if (ptr >= len)
714 9424 ptr += len;
715
716
2/2
✓ Branch 0 taken 211 times.
✓ Branch 1 taken 9424 times.
9635 return ptr < len ? &eventInstance[ptr] : 0;
717 }
718
719 /////////////////////////////////////////////////////////////////////////////
720 21 void Main::getActiveEvents(std::list<EventData>* list) const
721 {
722 42 pthread::ReadLock lock(eventMutex);
723
724 // A set of sorted instances
725 typedef std::set<const EventInstance*, EventInstance> EventDataSet;
726 42 EventDataSet set;
727
728 38 for (EventInstanceMap::const_iterator it = eventMap.begin();
729
2/2
✓ Branch 6 taken 17 times.
✓ Branch 7 taken 21 times.
38 it != eventMap.end(); ++it) {
730 17 const EventInstanceVector* vec = it->second;
731 52 for (EventInstanceVector::const_iterator it2 = vec->begin();
732
2/2
✓ Branch 6 taken 35 times.
✓ Branch 7 taken 17 times.
52 it2 != vec->end(); ++it2) {
733 35 const EventInstance* instance = *it2;
734
735
4/6
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 26 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
35 if (instance and instance->state)
736
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 set.insert(instance);
737 }
738 }
739
740 // Add last event as well
741 21 const EventInstance* last = m_getEventInstance(eventSeqNo-1);
742
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 4 times.
21 if (last)
743
1/2
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
17 set.insert(last);
744
745
2/2
✓ Branch 8 taken 18 times.
✓ Branch 9 taken 21 times.
39 for (EventDataSet::iterator it = set.begin(); it != set.end(); ++it)
746
1/2
✓ Branch 8 taken 18 times.
✗ Branch 9 not taken.
18 list->push_back(**it);
747 21 }
748
749 /////////////////////////////////////////////////////////////////////////////
750 9614 EventData Main::getEvent(uint32_t seqNo) const
751 {
752 19228 pthread::ReadLock lock(eventMutex);
753 static EventData nullEvent;
754
755 9614 const EventInstance* e = m_getEventInstance(seqNo);
756
757
5/6
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 9420 times.
✓ Branch 3 taken 30 times.
✓ Branch 4 taken 164 times.
✓ Branch 6 taken 30 times.
✗ Branch 7 not taken.
19228 return e and e->event and e->seqNo == seqNo ? *e : nullEvent;
758 }
759
760 /////////////////////////////////////////////////////////////////////////////
761 148 uint32_t Main::getCurrentEventId() const
762 {
763 296 pthread::ReadLock lock(eventMutex);
764 296 return eventSeqNo;
765 }
766
767 /////////////////////////////////////////////////////////////////////////////
768 148 void Main::prepare(Session* /*session*/) const
769 {
770 148 }
771
772 /////////////////////////////////////////////////////////////////////////////
773 148 void Main::cleanup(const Session* /*session*/) const
774 {
775 148 }
776
777 /////////////////////////////////////////////////////////////////////////////
778 /////////////////////////////////////////////////////////////////////////////
779 #ifdef GNUTLS_FOUND
780 /////////////////////////////////////////////////////////////////////////////
781 154 int Main::setupTLS(Config tlsConf, log4cplus::Logger& logger)
782 {
783 int result;
784 154 verifyClient = false;
785
786
3/4
✓ Branch 1 taken 154 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 75 times.
✓ Branch 4 taken 79 times.
154 if (!tlsConf)
787 75 return 0;
788
789
2/4
✓ Branch 3 taken 79 times.
✗ Branch 4 not taken.
✓ Branch 9 taken 79 times.
✗ Branch 10 not taken.
158 std::string cert(tlsConf["cert"].toString());
790
2/4
✓ Branch 3 taken 79 times.
✗ Branch 4 not taken.
✓ Branch 9 taken 79 times.
✗ Branch 10 not taken.
158 std::string key(tlsConf["key"].toString());
791
5/6
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 71 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 71 times.
79 if (cert.empty() or key.empty()) {
792 8 return 0;
793 }
794
795
4/8
✓ Branch 5 taken 71 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 71 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 71 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 71 times.
✗ Branch 18 not taken.
71 LOG4CPLUS_INFO_STR(logger,
796 LOG4CPLUS_TEXT("Starting TLS configuration"));
797
798
799 // GnuTLS logging facility
800
2/4
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 71 times.
✗ Branch 7 not taken.
71 int logLevel = tlsConf["loglevel"].toUInt();
801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71 times.
71 if (logLevel > 0) {
802 gnutls_global_set_log_level(logLevel);
803 gnutls_global_set_log_function([](int /*prio*/, const char *err) {
804 tlsLogger.forcedLog(
805 log4cplus::INFO_LOG_LEVEL,
806 LOG4CPLUS_C_STR_TO_TSTRING(err));
807 });
808 ::tlsLogger = logger;
809 }
810
811
1/2
✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
71 result = gnutls_global_init();
812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71 times.
71 if (result) {
813 LOG4CPLUS_FATAL(logger,
814 LOG4CPLUS_TEXT("gnutls_global_init() failed: ")
815 << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result))
816 << LOG4CPLUS_TEXT(" (")
817 << LOG4CPLUS_C_STR_TO_TSTRING(
818 gnutls_strerror_name(result))
819 << LOG4CPLUS_TEXT(")"));
820 return result;
821 }
822
823 71 gnutls_dh_params_t p = nullptr;
824
1/2
✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
71 result = gnutls_dh_params_init(&p); // Allocate memory
825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71 times.
71 if (result) {
826 LOG4CPLUS_FATAL(logger,
827 LOG4CPLUS_TEXT("gnutls_dh_params_init() failed: ")
828 << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result))
829 << LOG4CPLUS_TEXT(" (")
830 << LOG4CPLUS_C_STR_TO_TSTRING(
831 gnutls_strerror_name(result))
832 << LOG4CPLUS_TEXT(")"));
833 return result;
834 }
835 71 dh_params.reset(p);
836
837
1/2
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
142 Config dh(tlsConf["dh"]);
838
2/4
✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 71 times.
71 if (dh) {
839 FILE* fd = fopen(dh.toString().c_str(), "r");
840 struct stat sb;
841
842 if (!fd or fstat(fileno(fd), &sb)) {
843 const char* func = fd ? "fstat" : "fdopen";
844 LOG4CPLUS_WARN(logger,
845 LOG4CPLUS_C_STR_TO_TSTRING(func)
846 << LOG4CPLUS_TEXT("(")
847 << LOG4CPLUS_STRING_TO_TSTRING(dh.toString())
848 << LOG4CPLUS_TEXT(") failed: ")
849 << LOG4CPLUS_C_STR_TO_TSTRING(strerror(errno))
850 << LOG4CPLUS_TEXT(" (")
851 << errno
852 << LOG4CPLUS_TEXT(")"));
853 sb.st_size = 0;
854 }
855 else {
856 unsigned char buf[sb.st_size];
857 gnutls_datum_t params;
858 params.size = fread(buf, 1, sb.st_size, fd);
859 params.data = buf;
860
861 result = gnutls_dh_params_import_pkcs3(
862 dh_params.get(), &params, GNUTLS_X509_FMT_PEM);
863
864 if (result) {
865 LOG4CPLUS_FATAL(logger,
866 LOG4CPLUS_TEXT("gnutls_dh_params_import_pkcs3(")
867 << LOG4CPLUS_STRING_TO_TSTRING(dh.toString())
868 << LOG4CPLUS_TEXT(") failed: ")
869 << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result))
870 << LOG4CPLUS_TEXT(" (")
871 << LOG4CPLUS_C_STR_TO_TSTRING(
872 gnutls_strerror_name(result))
873 << LOG4CPLUS_TEXT(")"));
874 return result;
875 }
876 else {
877 LOG4CPLUS_INFO_STR(logger,
878 LOG4CPLUS_TEXT(
879 "Successfully loaded DH parameters from file"));
880 }
881 }
882
883 if (fd)
884 fclose(fd);
885 }
886 else {
887
2/4
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 71 times.
✗ Branch 7 not taken.
71 unsigned int bits(tlsConf["dh-bits"].toUInt(1024));
888
1/2
✓ Branch 3 taken 71 times.
✗ Branch 4 not taken.
71 result = gnutls_dh_params_generate2(dh_params.get(), bits);
889
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71 times.
71 if (result) {
890 LOG4CPLUS_FATAL(logger,
891 LOG4CPLUS_TEXT("gnutls_dh_params_generate2(")
892 << bits
893 << LOG4CPLUS_TEXT(") failed: ")
894 << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result))
895 << LOG4CPLUS_TEXT(" (")
896 << LOG4CPLUS_C_STR_TO_TSTRING(
897 gnutls_strerror_name(result))
898 << LOG4CPLUS_TEXT(")"));
899 return result;
900 }
901 else {
902
8/16
✓ Branch 5 taken 71 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 71 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 71 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 71 times.
✗ Branch 15 not taken.
✓ Branch 20 taken 71 times.
✗ Branch 21 not taken.
✓ Branch 24 taken 71 times.
✗ Branch 25 not taken.
✓ Branch 28 taken 71 times.
✗ Branch 29 not taken.
✓ Branch 32 taken 71 times.
✗ Branch 33 not taken.
71 LOG4CPLUS_INFO(logger,
903 LOG4CPLUS_TEXT(
904 "Successfully generated DH parameters with ")
905 << bits
906 << LOG4CPLUS_TEXT(" bits"));
907 }
908 }
909
910 // Set priority string
911
3/6
✓ Branch 3 taken 71 times.
✗ Branch 4 not taken.
✓ Branch 9 taken 71 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 71 times.
✗ Branch 14 not taken.
142 std::string priority(tlsConf["priority"].toString("NORMAL"));
912 71 const char* errpos = 0;
913 71 gnutls_priority_t prio = nullptr;
914
1/2
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
71 result = gnutls_priority_init(&prio, priority.c_str(), &errpos);
915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71 times.
71 if (result) {
916 LOG4CPLUS_FATAL(logger,
917 LOG4CPLUS_TEXT("gnutls_priority_init(")
918 << LOG4CPLUS_STRING_TO_TSTRING(priority)
919 << LOG4CPLUS_TEXT(") failed at position ")
920 << (errpos - priority.c_str())
921 << LOG4CPLUS_TEXT(": ")
922 << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result))
923 << LOG4CPLUS_TEXT(" (")
924 << LOG4CPLUS_C_STR_TO_TSTRING(
925 gnutls_strerror_name(result))
926 << LOG4CPLUS_TEXT(")"));
927 return result;
928 }
929 else {
930
4/8
✓ Branch 5 taken 71 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 71 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 71 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 71 times.
✗ Branch 18 not taken.
71 LOG4CPLUS_INFO_STR(logger,
931 LOG4CPLUS_TEXT("Successfully initialized priority string"));
932 71 priority_cache.reset(prio);
933 }
934
935 71 gnutls_certificate_credentials_t cc = nullptr;
936
1/2
✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
71 result = gnutls_certificate_allocate_credentials(&cc);
937
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71 times.
71 if (result) {
938 LOG4CPLUS_FATAL(logger,
939 LOG4CPLUS_TEXT(
940 "gnutls_certificate_allocate_credentials() failed: ")
941 << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result))
942 << LOG4CPLUS_TEXT(" (")
943 << LOG4CPLUS_C_STR_TO_TSTRING(
944 gnutls_strerror_name(result))
945 << LOG4CPLUS_TEXT(")"));
946 return result;
947 }
948 71 tls.reset(cc);
949
950
1/2
✓ Branch 5 taken 71 times.
✗ Branch 6 not taken.
71 gnutls_certificate_set_dh_params(tls.get(), dh_params.get());
951
952
1/2
✓ Branch 4 taken 71 times.
✗ Branch 5 not taken.
142 result = gnutls_certificate_set_x509_key_file(
953 71 tls.get(), cert.c_str(), key.c_str(), GNUTLS_X509_FMT_PEM);
954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71 times.
71 if (result) {
955 LOG4CPLUS_FATAL(logger,
956 LOG4CPLUS_TEXT("gnutls_certificate_set_x509_key_file(")
957 << LOG4CPLUS_TEXT("key=")
958 << LOG4CPLUS_STRING_TO_TSTRING(key)
959 << LOG4CPLUS_TEXT(", cert=")
960 << LOG4CPLUS_STRING_TO_TSTRING(cert)
961 << LOG4CPLUS_TEXT(") failed: ")
962 << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result))
963 << LOG4CPLUS_TEXT(" (")
964 << LOG4CPLUS_C_STR_TO_TSTRING(
965 gnutls_strerror_name(result))
966 << LOG4CPLUS_TEXT(")"));
967 tls.reset();
968 return result;
969 }
970 else {
971
4/8
✓ Branch 5 taken 71 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 71 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 71 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 71 times.
✗ Branch 18 not taken.
71 LOG4CPLUS_INFO_STR(logger,
972 LOG4CPLUS_TEXT(
973 "Successfully loaded server key and certificate"));
974 }
975
976
2/4
✓ Branch 5 taken 71 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 71 times.
✗ Branch 9 not taken.
71 parseCertConfigItem(logger, tlsConf["ca"], &Main::loadTrustFile);
977
2/4
✓ Branch 5 taken 71 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 71 times.
✗ Branch 9 not taken.
71 parseCertConfigItem(logger, tlsConf["crl"], &Main::loadCrlFile);
978
979 71 return 0;
980 }
981
982 /////////////////////////////////////////////////////////////////////////////
983 157 void Main::destroyTLS()
984 {
985 157 gnutls_global_deinit();
986 157 }
987
988 /////////////////////////////////////////////////////////////////////////////
989 28 void Main::loadTrustFile(log4cplus::Logger& logger, const char* cafile)
990 {
991 28 int result = gnutls_certificate_set_x509_trust_file(
992 56 tls.get(), cafile, GNUTLS_X509_FMT_PEM);
993
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (result > 0) {
994
4/8
✓ Branch 5 taken 28 times.
✗ Branch 6 not taken.
✓ Branch 19 taken 28 times.
✗ Branch 20 not taken.
✓ Branch 23 taken 28 times.
✗ Branch 24 not taken.
✓ Branch 33 taken 28 times.
✗ Branch 34 not taken.
28 LOG4CPLUS_INFO(logger,
995 LOG4CPLUS_TEXT("Successfully loaded ")
996 << result
997 << LOG4CPLUS_TEXT(" certificates from ")
998 << LOG4CPLUS_C_STR_TO_TSTRING(cafile));
999 }
1000 else if (result == 0) {
1001 LOG4CPLUS_WARN(logger,
1002 LOG4CPLUS_TEXT("gnutls_certificate_set_x509_trust_file(): ")
1003 << LOG4CPLUS_STRING_TO_TSTRING(cafile)
1004 << LOG4CPLUS_TEXT(" contains no certificate authorities."));
1005 throw PdServ::Errno(EINVAL);
1006 }
1007 else {
1008 LOG4CPLUS_WARN(logger,
1009 LOG4CPLUS_TEXT("gnutls_certificate_set_x509_trust_file(")
1010 << LOG4CPLUS_STRING_TO_TSTRING(cafile)
1011 << LOG4CPLUS_TEXT(") failed: ")
1012 << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result))
1013 << LOG4CPLUS_TEXT(" (")
1014 << LOG4CPLUS_C_STR_TO_TSTRING(
1015 gnutls_strerror_name(result))
1016 << LOG4CPLUS_TEXT(")"));
1017 throw PdServ::Errno(result);
1018 }
1019 28 }
1020
1021 /////////////////////////////////////////////////////////////////////////////
1022 void Main::loadCrlFile(log4cplus::Logger& logger, const char* crlfile)
1023 {
1024 struct stat sb;
1025
1026 LOG4CPLUS_DEBUG(logger,
1027 LOG4CPLUS_TEXT("Considering ")
1028 << LOG4CPLUS_C_STR_TO_TSTRING(crlfile)
1029 << LOG4CPLUS_TEXT(" as CRL file"));
1030
1031 if (stat(crlfile, &sb) or !S_ISREG(sb.st_mode) or sb.st_size == 0) {
1032 const char* name = ::basename(crlfile);
1033 if (name) {
1034 datum_string str(name);
1035
1036 blacklist.insert(str);
1037 LOG4CPLUS_INFO(logger,
1038 LOG4CPLUS_TEXT("Added Key ID ")
1039 << LOG4CPLUS_STRING_TO_TSTRING(std::string(str))
1040 << LOG4CPLUS_TEXT(" to blacklist"));
1041 }
1042 }
1043 else {
1044 int result = gnutls_certificate_set_x509_crl_file(
1045 tls.get(), crlfile, GNUTLS_X509_FMT_PEM);
1046 if (result > 0) {
1047 LOG4CPLUS_INFO(logger,
1048 LOG4CPLUS_TEXT("Successfully loaded ")
1049 << result
1050 << LOG4CPLUS_TEXT(" revoked certificates from ")
1051 << LOG4CPLUS_C_STR_TO_TSTRING(crlfile));
1052 }
1053 else if (result == 0) {
1054 LOG4CPLUS_WARN(logger,
1055 LOG4CPLUS_TEXT("gnutls_certificate_set_x509_crl_file(): ")
1056 << LOG4CPLUS_STRING_TO_TSTRING(crlfile)
1057 << LOG4CPLUS_TEXT(" contains no CRL."));
1058 throw PdServ::Errno(EINVAL);
1059 }
1060 else {
1061 LOG4CPLUS_WARN(logger,
1062 LOG4CPLUS_TEXT("gnutls_certificate_set_x509_crl_file(")
1063 << LOG4CPLUS_STRING_TO_TSTRING(crlfile)
1064 << LOG4CPLUS_TEXT(") failed: ")
1065 << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result))
1066 << LOG4CPLUS_TEXT(" (")
1067 << LOG4CPLUS_C_STR_TO_TSTRING(
1068 gnutls_strerror_name(result))
1069 << LOG4CPLUS_TEXT(")"));
1070 throw PdServ::Errno(result);
1071 }
1072 }
1073 }
1074
1075 /////////////////////////////////////////////////////////////////////////////
1076 28 void Main::parseCertConfigDir(log4cplus::Logger& logger, const char* path,
1077 void (Main::*loadFunc)(log4cplus::Logger&, const char*))
1078 {
1079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 DIR* dir = opendir(path);
1080 struct dirent* entry;
1081
1082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (dir)
1083 while ((entry = readdir(dir))) {
1084 if (entry->d_name[0] != '.') {
1085 std::string name(path);
1086 name.append(1,'/');
1087 name.append(entry->d_name);
1088 parseCertConfigDir(logger, name.c_str(), loadFunc);
1089 }
1090 }
1091 else
1092
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 28 times.
28 (this->*loadFunc)(logger, path);
1093 28 }
1094
1095 /////////////////////////////////////////////////////////////////////////////
1096 142 void Main::parseCertConfigItem(log4cplus::Logger& logger, Config config,
1097 void (Main::*loadFunc)(log4cplus::Logger&, const char*))
1098 {
1099
2/2
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 28 times.
142 if (!config)
1100 114 return;
1101
1102 28 verifyClient = true;
1103 28 gnutls_certificate_set_verify_function(
1104 28 tls.get(), Session::gnutls_verify_client);
1105
1106 28 size_t i = 0;
1107
6/8
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 56 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 28 times.
✓ Branch 8 taken 28 times.
✓ Branch 10 taken 28 times.
✓ Branch 11 taken 28 times.
84 while (Config item = config[i++])
1108
4/6
✓ Branch 8 taken 28 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 28 times.
✗ Branch 14 not taken.
✓ Branch 20 taken 28 times.
✓ Branch 21 taken 28 times.
56 parseCertConfigDir(logger, item.toString().c_str(), loadFunc);
1109 }
1110
1111 /////////////////////////////////////////////////////////////////////////////
1112 151 bool Main::tlsReady() const
1113 {
1114 151 return static_cast<bool>(tls);
1115 }
1116
1117 /////////////////////////////////////////////////////////////////////////////
1118 66 void Main::initTlsSessionData(gnutls_session_t session) const
1119 {
1120 66 gnutls_priority_set(session, priority_cache.get());
1121 66 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, tls.get());
1122
3/4
✗ Branch 3 not taken.
✓ Branch 4 taken 66 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 38 times.
66 if (verifyClient)
1123 28 gnutls_certificate_server_set_request(session, GNUTLS_CERT_REQUIRE);
1124
1125
1/2
✓ Branch 3 taken 66 times.
✗ Branch 4 not taken.
66 gnutls_db_set_retrieve_function(session, [](void *ptr,
1126 66 gnutls_datum_t key) {
1127 return reinterpret_cast<TlsSessionDB *>(ptr)->retrieve(key);
1128 66 });
1129
1/2
✓ Branch 3 taken 66 times.
✗ Branch 4 not taken.
132 gnutls_db_set_remove_function(session, [](void *ptr, gnutls_datum_t key) {
1130 return reinterpret_cast<TlsSessionDB *>(ptr)->erase(key);
1131 66 });
1132
1/2
✓ Branch 3 taken 66 times.
✗ Branch 4 not taken.
66 gnutls_db_set_store_function(
1133 66 session, [](void *ptr, gnutls_datum_t key, gnutls_datum_t data) {
1134 return reinterpret_cast<TlsSessionDB *>(ptr)->store(key,
1135 data);
1136 66 });
1137 66 gnutls_db_set_ptr(session, &tlsSessionDB);
1138 66 }
1139
1140 /////////////////////////////////////////////////////////////////////////////
1141
1142 #endif
1143
1144 /////////////////////////////////////////////////////////////////////////////
1145 154 void Main::setupAccessControl(const Config& config)
1146 {
1147
2/4
✓ Branch 3 taken 154 times.
✗ Branch 4 not taken.
✓ Branch 9 taken 154 times.
✗ Branch 10 not taken.
308 const std::string guest = config["guest"].toString();
1148
1149 154 m_loginMandatory = guest == "deny";
1150
4/4
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 119 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 27 times.
154 m_write = guest.empty() or guest == "write";
1151 154 }
1152
1153 /////////////////////////////////////////////////////////////////////////////
1154 751 bool Main::loginMandatory() const
1155 {
1156
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 751 times.
751 return m_loginMandatory;
1157 9 }
1158