+ if(logcontrol) {
+ suppress = true;
+ logcontrol = false;
+ for list_each(connection_t, c, connection_list) {
+ if(!c->status.log)
+ continue;
+ logcontrol = true;
+ if(level > (c->outcompression >= 0 ? c->outcompression : debug_level))
+ continue;
+ int len = strlen(message);
+ if(send_request(c, "%d %d %d", CONTROL, REQ_LOG, len))
+ send_meta(c, message, len);
+ }
+ suppress = false;
+ }
+}
+
+void logger(int level, int priority, const char *format, ...) {
+ va_list ap;
+ char message[1024] = "";
+
+ va_start(ap, format);
+ int len = vsnprintf(message, sizeof message, format, ap);
+ va_end(ap);
+
+ if(len > 0 && len < sizeof message && message[len - 1] == '\n')
+ message[len - 1] = 0;
+
+ real_logger(level, priority, message);
+}
+
+static void sptps_logger(sptps_t *s, int s_errno, const char *format, va_list ap) {
+ char message[1024] = "";
+ size_t msglen = sizeof message;
+
+ int len = vsnprintf(message, msglen, format, ap);
+ if(len > 0 && len < sizeof message) {
+ if(message[len - 1] == '\n')
+ message[--len] = 0;
+
+ // WARNING: s->handle can point to a connection_t or a node_t,
+ // but both types have the name and hostname fields at the same offsets.
+ connection_t *c = s->handle;
+ if(c)
+ snprintf(message + len, sizeof message - len, " from %s (%s)", c->name, c->hostname);
+ }
+
+ real_logger(DEBUG_ALWAYS, LOG_ERR, message);
+}
+
+void openlogger(const char *ident, logmode_t mode) {