+static char *
+bsd_log_string(const char *msg)
+{
+ uint32_t i, len, outlen;
+ char *out, *q;
+ uint8_t c;
+
+ if (msg == NULL) return NULL;
+
+ len = strlen(msg);
+
+ outlen = len + 1;
+ for (i = 0; i < len; i++)
+ {
+ c = msg[i];
+ if (isascii(c) && iscntrl(c) && (c != '\t')) outlen++;
+ }
+
+ out = malloc(outlen);
+ if (out == NULL) return NULL;
+
+ q = out;
+
+ for (i = 0; i < len; i++)
+ {
+ c = msg[i];
+
+ if (isascii(c) && iscntrl(c))
+ {
+ if (c == '\n')
+ {
+ *q++ = '\\';
+ *q++ = 'n';
+ }
+ else if (c == '\t')
+ {
+ *q++ = c;
+ }
+ else
+ {
+ *q++ = '^';
+ *q++ = c ^ 0100;
+ }
+ }
+ else
+ {
+ *q++ = c;
+ }
+ }
+
+ *q = '\0';
+
+ return out;
+}
+