Provide the proper bounce error message on failed deliveries.
This may not be the best solution - the error message buffer has now
turned dynamic, but the only alternative I see is to make it a static
array in net.c... and I'm not quite sure if I want to do that just now.

--- a/dma.c
+++ b/dma.c
@@ -438,7 +438,7 @@
 }
 
 static void
-bounce(struct qitem *it, const char *reason)
+bounce(struct qitem *it, char *reason)
 {
 	struct queue bounceq;
 	struct qitem *bit;
@@ -597,6 +597,7 @@
 		VERSION, hostname(),
 		it->addr,
 		reason);
+	free(reason);
 	if (error < 0)
 		goto fail;
 	if (fflush(bit->queuef) != 0)
@@ -632,7 +633,7 @@
 }
 
 static int
-deliver_local(struct qitem *it, const char **errmsg)
+deliver_local(struct qitem *it, char **errmsg)
 {
 	char fn[PATH_MAX+1];
 	char line[1000];
@@ -680,7 +681,7 @@
 		if (linelen == 0 || line[linelen - 1] != '\n') {
 			syslog(LOG_CRIT, "%s: local delivery failed: corrupted queue file",
 			       it->queueid);
-			*errmsg = "corrupted queue file";
+			*errmsg = strdup("corrupted queue file");
 			error = -1;
 			goto chop;
 		}
@@ -717,7 +718,7 @@
 {
 	int error;
 	unsigned int backoff = MIN_RETRY;
-	const char *errmsg = "unknown bounce reason";
+	char *errmsg = strdup("unknown bounce reason");
 	struct timeval now;
 	struct stat st;
 
@@ -748,12 +749,9 @@
 		}
 		if (gettimeofday(&now, NULL) == 0 &&
 		    (now.tv_sec - st.st_mtimespec.tv_sec > MAX_TIMEOUT)) {
-			char *msg;
-
-			if (asprintf(&msg,
+			asprintf(&errmsg,
 				 "Could not deliver for the last %d seconds. Giving up.",
-				 MAX_TIMEOUT) > 0)
-				errmsg = msg;
+				 MAX_TIMEOUT);
 			goto bounce;
 		}
 		sleep(backoff);
--- a/dma.h
+++ b/dma.h
@@ -163,7 +163,7 @@
 /* net.c */
 extern int read_remote(int, int, char *);
 extern ssize_t send_remote_command(int, const char*, ...);
-extern int deliver_remote(struct qitem *, const char **);
+extern int deliver_remote(struct qitem *, char **);
 
 /* base64.c */
 extern int base64_encode(const void *, int, char **);
--- a/net.c
+++ b/net.c
@@ -314,7 +314,7 @@
 }
 
 int
-deliver_remote(struct qitem *it, const char **errmsg)
+deliver_remote(struct qitem *it, char **errmsg)
 {
 	struct authuser *a;
 	char *host, line[1000];
@@ -323,11 +323,14 @@
 
 	host = strrchr(it->addr, '@');
 	/* Should not happen */
-	if (host == NULL)
+	if (host == NULL) {
+		asprintf(errmsg, "Internal error: badly formed address %s",
+		    it->addr);
 		return(-1);
-	else
+	} else {
 		/* Step over the @ */
 		host++;
+	}
 
 	/* Smarthost support? */
 	if (config->smarthost != NULL && strlen(config->smarthost) > 0) {
@@ -370,6 +373,8 @@
 		if (read_remote(fd, 0, NULL) != 2) {
 			syslog(LOG_ERR, "%s: remote delivery deferred: "
 			       " EHLO failed: %s", it->queueid, neterr);
+			asprintf(errmsg, "%s did not like our EHLO:\n%s",
+			    host, neterr);
 			return (-1);
 		}
 	}
@@ -379,6 +384,8 @@
 		if (read_remote(fd, 0, NULL) != 2) {
 			syslog(LOG_ERR, "%s: remote delivery deferred: "
 			       " EHLO failed: %s", it->queueid, neterr);
+			asprintf(errmsg, "%s did not like our EHLO:\n%s",
+			    host, neterr);
 			return (-1);
 		}
 	}
@@ -405,6 +412,7 @@
 		if (error < 0) {
 			syslog(LOG_ERR, "%s: remote delivery failed:"
 					" SMTP login failed: %m", it->queueid);
+			asprintf(errmsg, "SMTP login to %s failed", host);
 			return (-1);
 		}
 		/* SMTP login is not available, so try without */
@@ -418,6 +426,8 @@
 	if (res == 5) { \
 		syslog(LOG_ERR, "%s: remote delivery failed: " \
 		       c " failed: %s", it->queueid, neterr); \
+		asprintf(errmsg, "%s did not like our " c ":\n%s", \
+		    host, neterr); \
 		return (-1); \
 	} else if (res != exp) { \
 		syslog(LOG_ERR, "%s: remote delivery deferred: " \
@@ -447,7 +457,7 @@
 		if (linelen == 0 || line[linelen - 1] != '\n') {
 			syslog(LOG_CRIT, "%s: remote delivery failed:"
 				"corrupted queue file", it->queueid);
-			*errmsg = "corrupted queue file";
+			*errmsg = strdup("corrupted queue file");
 			error = -1;
 			goto out;
 		}
