logging: rework _output() function

This patch reworks _output() to handle snprintf() return value
appropriately and to use one single buffer to build the logging
string, instead of four.
diff --git a/src/logging.c b/src/logging.c
index 7fabfcb..526b39e 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -143,29 +143,19 @@
 		    unsigned int level, char *file, int line, int cont,
 		    const char *format, va_list ap)
 {
-	char col[30];
-	char sub[30];
-	char tim[30];
 	char buf[4096];
-	char final[4096];
-
-	/* prepare the data */
-	col[0] = '\0';
-	sub[0] = '\0';
-	tim[0] = '\0';
-	buf[0] = '\0';
+	int ret, len = 0, offset = 0, rem = sizeof(buf);
 
 	/* are we using color */
 	if (target->use_color) {
 		const char *c = color(subsys);
 		if (c) {
-			snprintf(col, sizeof(col), "%s", color(subsys));
-			col[sizeof(col)-1] = '\0';
+			ret = snprintf(buf + offset, rem, "%s", color(subsys));
+			if (ret < 0)
+				goto err;
+			OSMO_SNPRINTF_RET(ret, rem, offset, len);
 		}
 	}
-	vsnprintf(buf, sizeof(buf), format, ap);
-	buf[sizeof(buf)-1] = '\0';
-
 	if (!cont) {
 		if (target->print_timestamp) {
 			char *timestr;
@@ -173,17 +163,30 @@
 			tm = time(NULL);
 			timestr = ctime(&tm);
 			timestr[strlen(timestr)-1] = '\0';
-			snprintf(tim, sizeof(tim), "%s ", timestr);
-			tim[sizeof(tim)-1] = '\0';
+			ret = snprintf(buf + offset, rem, "%s ", timestr);
+			if (ret < 0)
+				goto err;
+			OSMO_SNPRINTF_RET(ret, rem, offset, len);
 		}
-		snprintf(sub, sizeof(sub), "<%4.4x> %s:%d ", subsys, file, line);
-		sub[sizeof(sub)-1] = '\0';
+		ret = snprintf(buf + offset, rem, "<%4.4x> %s:%d ",
+				subsys, file, line);
+		if (ret < 0)
+			goto err;
+		OSMO_SNPRINTF_RET(ret, rem, offset, len);
 	}
+	ret = vsnprintf(buf + offset, rem, format, ap);
+	if (ret < 0)
+		goto err;
+	OSMO_SNPRINTF_RET(ret, rem, offset, len);
 
-	snprintf(final, sizeof(final), "%s%s%s%s%s", col, tim, sub, buf,
-		 target->use_color ? "\033[0;m" : "");
-	final[sizeof(final)-1] = '\0';
-	target->output(target, level, final);
+	ret = snprintf(buf + offset, rem, "%s",
+			target->use_color ? "\033[0;m" : "");
+	if (ret < 0)
+		goto err;
+	OSMO_SNPRINTF_RET(ret, rem, offset, len);
+err:
+	buf[sizeof(buf)-1] = '\0';
+	target->output(target, level, buf);
 }