+
+ case LOGMODE_NULL:
+ default:
+ break;
+ }
+
+ if(umbilical && do_detach) {
+ format_pretty(pretty, sizeof(pretty), priority, message, umbilical_colorize, &pretty_colorized);
+
+ if(write(umbilical, pretty, strlen(pretty)) == -1 || write(umbilical, "\n", 1) == -1) {
+ // Other end broken, nothing we can do about it.
+ }
+ }
+ }
+
+ if(logcontrol) {
+ suppress = true;
+ logcontrol = false;
+
+ size_t msglen = strlen(pretty);
+
+ for list_each(connection_t, c, &connection_list) {
+ if(!c->status.log) {
+ continue;
+ }
+
+ logcontrol = true;
+
+ if(level > (c->log_level != DEBUG_UNSET ? c->log_level : debug_level)) {
+ continue;
+ }
+
+ if(format_pretty(pretty, sizeof(pretty), priority, message, c->status.log_color, &pretty_colorized)) {
+ msglen = strlen(pretty);
+ }
+
+ if(send_request(c, "%d %d %lu", CONTROL, REQ_LOG, (unsigned long)msglen)) {
+ send_meta(c, pretty, msglen);
+ }
+ }
+
+ suppress = false;
+ }
+}
+
+void logger(debug_t level, int priority, const char *format, ...) {
+ va_list ap;
+ char message[1024] = "";
+
+ if(!should_log(level)) {
+ return;
+ }
+
+ va_start(ap, format);
+ int len = vsnprintf(message, sizeof(message), format, ap);
+ message[sizeof(message) - 1] = 0;
+ va_end(ap);
+
+ if(len > 0 && (size_t)len < sizeof(message) - 1 && 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) ATTR_FORMAT(printf, 3, 0);
+static void sptps_logger(sptps_t *s, int s_errno, const char *format, va_list ap) {
+ (void)s_errno;
+ char message[1024];
+ size_t msglen = sizeof(message);
+
+ if(!should_log(DEBUG_TRAFFIC)) {
+ return;
+ }
+
+ int len = vsnprintf(message, msglen, format, ap);
+ message[sizeof(message) - 1] = 0;
+
+ if(len > 0 && (size_t)len < sizeof(message) - 1) {
+ 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);
+ }