diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c
index d0d94550c0fb9acfabe7cc993a94ce4254817d47..7edcd6f6c6c31be0dd71c7efcd3f872ec87b2027 100644
--- a/src/sbbs3/ftpsrvr.c
+++ b/src/sbbs3/ftpsrvr.c
@@ -302,6 +302,7 @@ static int sockprintf(SOCKET sock, CRYPT_SESSION sess, char *fmt, ...)
 	char	sbuf[1024];
 	fd_set	socket_set;
 	struct timeval tv;
+	char	estr[SSL_ESTR_LEN];
 
     va_start(argptr,fmt);
     len=vsnprintf(sbuf,maxlen=sizeof(sbuf)-2,fmt,argptr);
@@ -344,13 +345,15 @@ static int sockprintf(SOCKET sock, CRYPT_SESSION sess, char *fmt, ...)
 			if (result == CRYPT_OK)
 				sent += tls_sent;
 			else {
-				lprintf(LOG_DEBUG, "pushData returned %d\n", result);
-				if (result != -25)
-				return 0;
+				get_crypt_error_string(result, sess, estr, "sending data");
+				lprintf(LOG_DEBUG, "%04d !ERROR %s", sock, estr);
+				if (result != CRYPT_ERROR_TIMEOUT)
+					return 0;
 			}
 			result = cryptFlushData(sess);
 			if (result != CRYPT_OK) {
-				lprintf(LOG_DEBUG, "cryptFlushData() returned %d\n", result);
+				get_crypt_error_string(result, sess, estr, "flushing data");
+				lprintf(LOG_DEBUG, "%04d error %s", sock, estr);
 				return 0;
 			}
 		}
@@ -1163,6 +1166,7 @@ static int sock_recvbyte(SOCKET sock, CRYPT_SESSION sess, char *buf, time_t *las
 	struct	timeval	tv;
 	int ret;
 	int i;
+	char estr[SSL_ESTR_LEN];
 
 	if(ftp_set==NULL || terminate_server) {
 		sockprintf(sock,sess,"421 Server downed, aborting.");
@@ -1171,7 +1175,10 @@ static int sock_recvbyte(SOCKET sock, CRYPT_SESSION sess, char *buf, time_t *las
 	}
 	if (sess > -1) {
 		/* Try a read with no timeout first. */
-		cryptSetAttribute(sess, CRYPT_OPTION_NET_READTIMEOUT, 0);
+		if ((ret = cryptSetAttribute(sess, CRYPT_OPTION_NET_READTIMEOUT, 0)) != CRYPT_OK) {
+				get_crypt_error_string(ret, sess, estr, "setting read timeout");
+				lprintf(LOG_DEBUG, "%04d !ERROR %s", sock, estr);
+		}
 		while (1) {
 			ret = cryptPopData(sess, buf, 1, &len);
 			/* Successive reads will be with the full timeout after a select() */
@@ -1180,12 +1187,14 @@ static int sock_recvbyte(SOCKET sock, CRYPT_SESSION sess, char *buf, time_t *las
 				case CRYPT_OK:
 					break;
 				case CRYPT_ERROR_TIMEOUT:
-					lprintf(LOG_WARNING,"%04d !TIMEOUT in sock_recvbyte (%u seconds):  INACTIVE SOCKET",sock,startup->max_inactivity);
+					get_crypt_error_string(ret, sess, estr, "popping data");
+					lprintf(LOG_WARNING, "%04d !TIMEOUT %s (%u seconds)", sock, estr, startup->max_inactivity);
 					return -1;
 				case CRYPT_ERROR_COMPLETE:
 					return 0;
 				default:
-					lprintf(LOG_WARNING,"%04d !Cryptlib error in sock_recvbyte:  %d",sock,ret);
+					get_crypt_error_string(ret, sess, estr, "popping data");
+					lprintf(LOG_WARNING, "%04d !ERROR %s", sock, estr);
 					if (ret < -1)
 						return ret;
 					return -2;
@@ -1357,6 +1366,7 @@ static void send_thread(void* arg)
 	socklen_t	addr_len;
 	fd_set		socket_set;
 	struct timeval tv;
+	char		estr[SSL_ESTR_LEN];
 
 	xfer=*(xfer_t*)arg;
 	free(arg);
@@ -1449,13 +1459,15 @@ static void send_thread(void* arg)
 		if (*xfer.data_sess != -1) {
 			int status = cryptPushData(*xfer.data_sess, buf, rd, &wr);
 			if (status != CRYPT_OK) {
-				lprintf(LOG_DEBUG, "PushData() returned %d\n", status);
+				get_crypt_error_string(status, *xfer.data_sess, estr, "pushing data");
+				lprintf(LOG_DEBUG, "%04d !ERROR %s", *xfer.data_sock, estr);
 				wr = -1;
 			}
 			else {
 				status = cryptFlushData(*xfer.data_sess);
 				if (status != CRYPT_OK) {
-					lprintf(LOG_DEBUG, "cryptFlushData() returned %d\n", status);
+					get_crypt_error_string(status, *xfer.data_sess, estr, "flushing data");
+					lprintf(LOG_DEBUG, "%04d !ERROR %s", *xfer.data_sock, estr);
 					wr = -1;
 				}
 			}
@@ -1633,6 +1645,7 @@ static void receive_thread(void* arg)
 	fd_set		socket_set;
 	struct timeval tv;
 	CRYPT_SESSION	sess = -1;
+	char		estr[SSL_ESTR_LEN];
 
 	xfer=*(xfer_t*)arg;
 	free(arg);
@@ -1721,8 +1734,11 @@ static void receive_thread(void* arg)
 #endif
 		if (*xfer.data_sess != -1) {
 			int status = cryptPopData(*xfer.data_sess, buf, sizeof(buf), &rd);
-			if (status != CRYPT_OK)
+			if (status != CRYPT_OK) {
+				get_crypt_error_string(status, *xfer.data_sess, estr, "flushing data");
+				lprintf(LOG_DEBUG, "%04d !ERROR %s", *xfer.data_sock, estr);
 				rd = -1;
+			}
 		}
 		else {
 			rd=recv(*xfer.data_sock,buf,sizeof(buf),0);
@@ -1912,30 +1928,33 @@ static BOOL start_tls(SOCKET *sock, CRYPT_SESSION *sess, BOOL resp)
 	BOOL nodelay;
 	ulong nb;
 	int status;
-	char *estr;
+	char estr[SSL_ESTR_LEN];
 
-	if (get_ssl_cert(&scfg, NULL) == -1) {
-		lprintf(LOG_ERR, "Unable to get certificate");
+	if (get_ssl_cert(&scfg, estr) == -1) {
+		lprintf(LOG_ERR, "Unable to get certificate %s", estr);
 		if (resp)
 			sockprintf(*sock, *sess, "431 TLS not available");
 		return FALSE;
 	}
-	if (cryptCreateSession(sess, CRYPT_UNUSED, CRYPT_SESSION_SSL_SERVER) != CRYPT_OK) {
-		lprintf(LOG_ERR, "Unable to create TLS session");
+	if ((status = cryptCreateSession(sess, CRYPT_UNUSED, CRYPT_SESSION_SSL_SERVER)) != CRYPT_OK) {
+		get_crypt_error_string(status, CRYPT_UNUSED, estr, "creating session");
+		lprintf(LOG_ERR, "%04d FTP ERROR %s", *sock, estr);
 		if (resp)
 			sockprintf(*sock, *sess, "431 TLS not available");
 		return FALSE;
 	}
-	if (cryptSetAttribute(*sess, CRYPT_SESSINFO_SSL_OPTIONS, CRYPT_SSLOPTION_DISABLE_CERTVERIFY) != CRYPT_OK) {
-		lprintf(LOG_ERR, "Unable to disable certificate verification");
+	if ((status = cryptSetAttribute(*sess, CRYPT_SESSINFO_SSL_OPTIONS, CRYPT_SSLOPTION_DISABLE_CERTVERIFY)) != CRYPT_OK) {
+		get_crypt_error_string(status, *sess, estr, "disabling certificate verification");
+		lprintf(LOG_ERR, "%04d FTP ERROR %s", *sock, estr);
 		cryptDestroySession(*sess);
 		*sess = -1;
 		if(resp)
 			sockprintf(*sock, *sess, "431 TLS not available");
 		return FALSE;
 	}
-	if (cryptSetAttribute(*sess, CRYPT_SESSINFO_PRIVATEKEY, scfg.tls_certificate) != CRYPT_OK) {
-		lprintf(LOG_ERR, "Unable to set private key");
+	if ((status=cryptSetAttribute(*sess, CRYPT_SESSINFO_PRIVATEKEY, scfg.tls_certificate)) != CRYPT_OK) {
+		get_crypt_error_string(status, *sess, estr, "setting private key");
+		lprintf(LOG_ERR, "%04d FTP ERROR %s", *sock, estr);
 		cryptDestroySession(*sess);
 		*sess = -1;
 		if (resp)
@@ -1946,8 +1965,9 @@ static BOOL start_tls(SOCKET *sock, CRYPT_SESSION *sess, BOOL resp)
 	setsockopt(*sock,IPPROTO_TCP,TCP_NODELAY,(char*)&nodelay,sizeof(nodelay));
 	nb=0;
 	ioctlsocket(*sock,FIONBIO,&nb);
-	if (cryptSetAttribute(*sess, CRYPT_SESSINFO_NETWORKSOCKET, *sock) != CRYPT_OK) {
-		lprintf(LOG_ERR, "Unable to set network socket");
+	if ((status = cryptSetAttribute(*sess, CRYPT_SESSINFO_NETWORKSOCKET, *sock)) != CRYPT_OK) {
+		get_crypt_error_string(status, *sess, estr, "setting network socket");
+		lprintf(LOG_ERR, "%04d FTP ERROR %s", *sock, estr);
 		cryptDestroySession(*sess);
 		*sess = -1;
 		if (resp)
@@ -1957,14 +1977,14 @@ static BOOL start_tls(SOCKET *sock, CRYPT_SESSION *sess, BOOL resp)
 	if (resp)
 		sockprintf(*sock, -1, "234 Ready to start TLS");
 	if ((status = cryptSetAttribute(*sess, CRYPT_SESSINFO_ACTIVE, 1)) != CRYPT_OK) {
-		estr = get_crypt_error(*sess);
-		lprintf(LOG_ERR, "Unable to set session active (%d:%s)", status, estr);
-		free_crypt_attrstr(estr);
+		get_crypt_error_string(status, *sess, estr, "setting session active");
+		lprintf(LOG_ERR, "%04d FTP ERROR %s", *sock, estr);
 		return TRUE;
 	}
 	if (startup->max_inactivity) {
-		if (cryptSetAttribute(*sess, CRYPT_OPTION_NET_READTIMEOUT, startup->max_inactivity) != CRYPT_OK) {
-			lprintf(LOG_ERR, "Unable to set max inactivity");
+		if ((status = cryptSetAttribute(*sess, CRYPT_OPTION_NET_READTIMEOUT, startup->max_inactivity)) != CRYPT_OK) {
+			get_crypt_error_string(status, *sess, estr, "setting read timeout");
+			lprintf(LOG_ERR, "%04d FTP ERROR %s", *sock, estr);
 			return TRUE;
 		}
 	}
diff --git a/src/sbbs3/ssl.c b/src/sbbs3/ssl.c
index 8a8ef73fb6718e0ce857742f41d6b06b8f26676f..6e66543ce59705fc34ffb6a38f8afaa714a50ebf 100644
--- a/src/sbbs3/ssl.c
+++ b/src/sbbs3/ssl.c
@@ -32,135 +32,138 @@ char* DLLCALL get_crypt_error(CRYPT_HANDLE sess)
 	return get_crypt_attribute(sess, CRYPT_ATTRIBUTE_ERRORMESSAGE);
 }
 
-bool get_crypt_error_string(int status, CRYPT_HANDLE sess, char estr[SSL_ESTR_LEN], char *file, int line)
+bool DLLCALL get_crypt_error_string(int status, CRYPT_HANDLE sess, char estr[SSL_ESTR_LEN], const char *action)
 {
-	char	*emsg;
+	char	*emsg = NULL;
 
 	if (cryptStatusOK(status))
 		return true;
 
-	emsg = get_crypt_error(sess);
-	if (emsg == NULL) {
-		switch(status) {
-			case CRYPT_ERROR_PARAM1:
-				emsg = strdup("Bad argument, parameter 1");
-				break;
-			case CRYPT_ERROR_PARAM2:
-				emsg = strdup("Bad argument, parameter 2");
-				break;
-			case CRYPT_ERROR_PARAM3:
-				emsg = strdup("Bad argument, parameter 3");
-				break;
-			case CRYPT_ERROR_PARAM4:
-				emsg = strdup("Bad argument, parameter 4");
-				break;
-			case CRYPT_ERROR_PARAM5:
-				emsg = strdup("Bad argument, parameter 5");
-				break;
-			case CRYPT_ERROR_PARAM6:
-				emsg = strdup("Bad argument, parameter 6");
-				break;
-			case CRYPT_ERROR_PARAM7:
-				emsg = strdup("Bad argument, parameter 7");
-				break;
+	if (estr) {
+		if (sess != CRYPT_UNUSED)
+			emsg = get_crypt_error(sess);
+		if (emsg == NULL) {
+			switch(status) {
+				case CRYPT_ERROR_PARAM1:
+					emsg = strdup("Bad argument, parameter 1");
+					break;
+				case CRYPT_ERROR_PARAM2:
+					emsg = strdup("Bad argument, parameter 2");
+					break;
+				case CRYPT_ERROR_PARAM3:
+					emsg = strdup("Bad argument, parameter 3");
+					break;
+				case CRYPT_ERROR_PARAM4:
+					emsg = strdup("Bad argument, parameter 4");
+					break;
+				case CRYPT_ERROR_PARAM5:
+					emsg = strdup("Bad argument, parameter 5");
+					break;
+				case CRYPT_ERROR_PARAM6:
+					emsg = strdup("Bad argument, parameter 6");
+					break;
+				case CRYPT_ERROR_PARAM7:
+					emsg = strdup("Bad argument, parameter 7");
+					break;
 
-			/* Errors due to insufficient resources */
+				/* Errors due to insufficient resources */
 
-			case CRYPT_ERROR_MEMORY:
-				emsg = strdup("Out of memory");
-				break;
-			case CRYPT_ERROR_NOTINITED:
-				emsg = strdup("Data has not been initialised");
-				break;
-			case CRYPT_ERROR_INITED:
-				emsg = strdup("Data has already been init'd");
-				break;
-			case CRYPT_ERROR_NOSECURE:
-				emsg = strdup("Opn.not avail.at requested sec.level");
-				break;
-			case CRYPT_ERROR_RANDOM:
-				emsg = strdup("No reliable random data available");
-				break;
-			case CRYPT_ERROR_FAILED:
-				emsg = strdup("Operation failed");
-				break;
-			case CRYPT_ERROR_INTERNAL:
-				emsg = strdup("Internal consistency check failed");
-				break;
+				case CRYPT_ERROR_MEMORY:
+					emsg = strdup("Out of memory");
+					break;
+				case CRYPT_ERROR_NOTINITED:
+					emsg = strdup("Data has not been initialised");
+					break;
+				case CRYPT_ERROR_INITED:
+					emsg = strdup("Data has already been init'd");
+					break;
+				case CRYPT_ERROR_NOSECURE:
+					emsg = strdup("Opn.not avail.at requested sec.level");
+					break;
+				case CRYPT_ERROR_RANDOM:
+					emsg = strdup("No reliable random data available");
+					break;
+				case CRYPT_ERROR_FAILED:
+					emsg = strdup("Operation failed");
+					break;
+				case CRYPT_ERROR_INTERNAL:
+					emsg = strdup("Internal consistency check failed");
+					break;
 
-			/* Security violations */
+				/* Security violations */
 
-			case CRYPT_ERROR_NOTAVAIL:
-				emsg = strdup("This type of opn.not available");
-				break;
-			case CRYPT_ERROR_PERMISSION:
-				emsg = strdup("No permiss.to perform this operation");
-				break;
-			case CRYPT_ERROR_WRONGKEY:
-				emsg = strdup("Incorrect key used to decrypt data");
-				break;
-			case CRYPT_ERROR_INCOMPLETE:
-				emsg = strdup("Operation incomplete/still in progress");
-				break;
-			case CRYPT_ERROR_COMPLETE:
-				emsg = strdup("Operation complete/can't continue");
-				break;
-			case CRYPT_ERROR_TIMEOUT:
-				emsg = strdup("Operation timed out before completion");
-				break;
-			case CRYPT_ERROR_INVALID:
-				emsg = strdup("Invalid/inconsistent information");
-				break;
-			case CRYPT_ERROR_SIGNALLED:
-				emsg = strdup("Resource destroyed by extnl.event");
-				break;
-			   
-			/* High-level function errors */
+				case CRYPT_ERROR_NOTAVAIL:
+					emsg = strdup("This type of opn.not available");
+					break;
+				case CRYPT_ERROR_PERMISSION:
+					emsg = strdup("No permiss.to perform this operation");
+					break;
+				case CRYPT_ERROR_WRONGKEY:
+					emsg = strdup("Incorrect key used to decrypt data");
+					break;
+				case CRYPT_ERROR_INCOMPLETE:
+					emsg = strdup("Operation incomplete/still in progress");
+					break;
+				case CRYPT_ERROR_COMPLETE:
+					emsg = strdup("Operation complete/can't continue");
+					break;
+				case CRYPT_ERROR_TIMEOUT:
+					emsg = strdup("Operation timed out before completion");
+					break;
+				case CRYPT_ERROR_INVALID:
+					emsg = strdup("Invalid/inconsistent information");
+					break;
+				case CRYPT_ERROR_SIGNALLED:
+					emsg = strdup("Resource destroyed by extnl.event");
+					break;
 
-			case CRYPT_ERROR_OVERFLOW:
-				emsg = strdup("Resources/space exhausted");
-				break;
-			case CRYPT_ERROR_UNDERFLOW:
-				emsg = strdup("Not enough data available");
-				break;
-			case CRYPT_ERROR_BADDATA:
-				emsg = strdup("Bad/unrecognised data format");
-				break;
-			case CRYPT_ERROR_SIGNATURE:
-				emsg = strdup("Signature/integrity check failed");
-				break;
+				/* High-level function errors */
 
-			/* Data access function errors */
+				case CRYPT_ERROR_OVERFLOW:
+					emsg = strdup("Resources/space exhausted");
+					break;
+				case CRYPT_ERROR_UNDERFLOW:
+					emsg = strdup("Not enough data available");
+					break;
+				case CRYPT_ERROR_BADDATA:
+					emsg = strdup("Bad/unrecognised data format");
+					break;
+				case CRYPT_ERROR_SIGNATURE:
+					emsg = strdup("Signature/integrity check failed");
+					break;
 
-			case CRYPT_ERROR_OPEN:
-				emsg = strdup("Cannot open object");
-				break;
-			case CRYPT_ERROR_READ:
-				emsg = strdup("Cannot read item from object");
-				break;
-			case CRYPT_ERROR_WRITE:
-				emsg = strdup("Cannot write item to object");
-				break;
-			case CRYPT_ERROR_NOTFOUND:
-				emsg = strdup("Requested item not found in object");
-				break;
-			case CRYPT_ERROR_DUPLICATE:
-				emsg = strdup("Item already present in object");
-				break;
+				/* Data access function errors */
 
-			/* Data enveloping errors */
+				case CRYPT_ERROR_OPEN:
+					emsg = strdup("Cannot open object");
+					break;
+				case CRYPT_ERROR_READ:
+					emsg = strdup("Cannot read item from object");
+					break;
+				case CRYPT_ERROR_WRITE:
+					emsg = strdup("Cannot write item to object");
+					break;
+				case CRYPT_ERROR_NOTFOUND:
+					emsg = strdup("Requested item not found in object");
+					break;
+				case CRYPT_ERROR_DUPLICATE:
+					emsg = strdup("Item already present in object");
+					break;
 
-			case CRYPT_ENVELOPE_RESOURCE:
-				emsg = strdup("Need resource to proceed");
-				break;
+				/* Data enveloping errors */
+
+				case CRYPT_ENVELOPE_RESOURCE:
+					emsg = strdup("Need resource to proceed");
+					break;
+			}
 		}
+		if (emsg) {
+			safe_snprintf(estr, SSL_ESTR_LEN, "'%s' (%d) %s", emsg, status, action);
+			free_crypt_attrstr(emsg);
+		}
+		else
+			safe_snprintf(estr, SSL_ESTR_LEN, "(%d) %s", status, action);
 	}
-	if (emsg) {
-		safe_snprintf(estr, SSL_ESTR_LEN, "cryptlib error %d at %s:%d (%s)", status, file, line, emsg);
-		free_crypt_attrstr(emsg);
-	}
-	else
-		safe_snprintf(estr, SSL_ESTR_LEN, "cryptlib error %d at %s:%d", status, file, line);
 	return false;
 }
 
@@ -201,7 +204,7 @@ bool DLLCALL is_crypt_initialized(void)
 	return cryptlib_initialized;
 }
 
-#define DO(x)	get_crypt_error_string(x, ssl_context, estr, __FILE__, __LINE__)
+#define DO(action, handle, x)	get_crypt_error_string(x, handle, estr, action)
 
 CRYPT_CONTEXT DLLCALL get_ssl_cert(scfg_t *cfg, char estr[SSL_ESTR_LEN])
 {
@@ -222,56 +225,54 @@ CRYPT_CONTEXT DLLCALL get_ssl_cert(scfg_t *cfg, char estr[SSL_ESTR_LEN])
 	/* Get the certificate... first try loading it from a file... */
 	SAFEPRINTF2(str,"%s%s",cfg->ctrl_dir,"ssl.cert");
 	if(cryptStatusOK(cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, str, CRYPT_KEYOPT_READONLY))) {
-		if(!DO(cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, "ssl_cert", cfg->sys_pass))) {
+		if(!DO("getting private key", ssl_keyset, cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, "ssl_cert", cfg->sys_pass))) {
 			pthread_mutex_unlock(&ssl_cert_mutex);
 			return -1;
 		}
 	}
 	else {
 		/* Couldn't do that... create a new context and use the cert from there... */
-		if(!cryptStatusOK(i=cryptCreateContext(&ssl_context, CRYPT_UNUSED, CRYPT_ALGO_RSA))) {
+		if(!DO("creating SSL context", CRYPT_UNUSED, cryptStatusOK(i=cryptCreateContext(&ssl_context, CRYPT_UNUSED, CRYPT_ALGO_RSA)))) {
 			pthread_mutex_unlock(&ssl_cert_mutex);
-			if (estr)
-				sprintf(estr, "cryptlib error %d creating SSL context",i);
 			return -1;
 		}
-		if(!DO(cryptSetAttributeString(ssl_context, CRYPT_CTXINFO_LABEL, "ssl_cert", 8)))
+		if(!DO("setting label", ssl_context, cryptSetAttributeString(ssl_context, CRYPT_CTXINFO_LABEL, "ssl_cert", 8)))
 			goto failure_return_1;
-		if(!DO(cryptGenerateKey(ssl_context)))
+		if(!DO("generating key", ssl_context, cryptGenerateKey(ssl_context)))
 			goto failure_return_1;
-		if(!DO(cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, str, CRYPT_KEYOPT_CREATE)))
+		if(!DO("opening keyset", CRYPT_UNUSED, cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, str, CRYPT_KEYOPT_CREATE)))
 			goto failure_return_1;
-		if(!DO(cryptAddPrivateKey(ssl_keyset, ssl_context, cfg->sys_pass)))
+		if(!DO("adding private key", ssl_keyset, cryptAddPrivateKey(ssl_keyset, ssl_context, cfg->sys_pass)))
 			goto failure_return_2;
-		if(!DO(cryptCreateCert(&ssl_cert, CRYPT_UNUSED, CRYPT_CERTTYPE_CERTIFICATE)))
+		if(!DO("creating certificate", CRYPT_UNUSED, cryptCreateCert(&ssl_cert, CRYPT_UNUSED, CRYPT_CERTTYPE_CERTIFICATE)))
 			goto failure_return_2;
-		if(!DO(cryptSetAttribute(ssl_cert, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, ssl_context)))
+		if(!DO("setting public key", ssl_cert, cryptSetAttribute(ssl_cert, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, ssl_context)))
 			goto failure_return_3;
-		if(!DO(cryptSetAttribute(ssl_cert, CRYPT_CERTINFO_SELFSIGNED, 1)))
+		if(!DO("signing certificate", ssl_cert, cryptSetAttribute(ssl_cert, CRYPT_CERTINFO_SELFSIGNED, 1)))
 			goto failure_return_3;
-		if(!DO(cryptSetAttribute(ssl_cert, CRYPT_OPTION_CERT_VALIDITY, 3650)))
+		if(!DO("verifying certificate", ssl_cert, cryptSetAttribute(ssl_cert, CRYPT_OPTION_CERT_VALIDITY, 3650)))
 			goto failure_return_3;
-		if(!DO(cryptSetAttributeString(ssl_cert, CRYPT_CERTINFO_COUNTRYNAME, "ZZ", 2)))
+		if(!DO("setting country name", ssl_cert, cryptSetAttributeString(ssl_cert, CRYPT_CERTINFO_COUNTRYNAME, "ZZ", 2)))
 			goto failure_return_3;
-		if(!DO(cryptSetAttributeString(ssl_cert, CRYPT_CERTINFO_ORGANIZATIONNAME, cfg->sys_name, strlen(cfg->sys_name))))
+		if(!DO("setting orginization name", ssl_cert, cryptSetAttributeString(ssl_cert, CRYPT_CERTINFO_ORGANIZATIONNAME, cfg->sys_name, strlen(cfg->sys_name))))
 			goto failure_return_3;
-		if(!DO(cryptSetAttributeString(ssl_cert, CRYPT_CERTINFO_DNSNAME, cfg->sys_inetaddr, strlen(cfg->sys_inetaddr))))
+		if(!DO("setting DNS name", ssl_cert, cryptSetAttributeString(ssl_cert, CRYPT_CERTINFO_DNSNAME, cfg->sys_inetaddr, strlen(cfg->sys_inetaddr))))
 			goto failure_return_3;
-		if(!DO(cryptSetAttributeString(ssl_cert, CRYPT_CERTINFO_COMMONNAME, cfg->sys_inetaddr, strlen(cfg->sys_inetaddr))))
+		if(!DO("setting Common Name", ssl_cert, cryptSetAttributeString(ssl_cert, CRYPT_CERTINFO_COMMONNAME, cfg->sys_inetaddr, strlen(cfg->sys_inetaddr))))
 			goto failure_return_3;
 		sprintf(sysop_email, "sysop@%s", cfg->sys_inetaddr);
-		if(!DO(cryptSetAttributeString(ssl_cert, CRYPT_CERTINFO_RFC822NAME, sysop_email, strlen(sysop_email))))
+		if(!DO("setting email", ssl_cert, cryptSetAttributeString(ssl_cert, CRYPT_CERTINFO_RFC822NAME, sysop_email, strlen(sysop_email))))
 			goto failure_return_3;
-		if(!DO(cryptSignCert(ssl_cert, ssl_context)))
+		if(!DO("signing certificate", ssl_cert, cryptSignCert(ssl_cert, ssl_context)))
 			goto failure_return_3;
-		if(!DO(cryptAddPublicKey(ssl_keyset, ssl_cert)))
+		if(!DO("adding public key", ssl_keyset, cryptAddPublicKey(ssl_keyset, ssl_cert)))
 			goto failure_return_3;
 		cryptDestroyCert(ssl_cert);
 		cryptKeysetClose(ssl_keyset);
 		cryptDestroyContext(ssl_context);
 		// Finally, load it from the file.
 		if(cryptStatusOK(cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, str, CRYPT_KEYOPT_READONLY))) {
-			if(!DO(cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, "ssl_cert", cfg->sys_pass))) {
+			if(!DO("getting private key", ssl_keyset, cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, "ssl_cert", cfg->sys_pass))) {
 				ssl_context = -1;
 			}
 		}
diff --git a/src/sbbs3/ssl.h b/src/sbbs3/ssl.h
index afa9f552f5e16175cfa3a2def38a7c956faafb3d..9f1efc981f152a791836167f281c7531c2e1fe6b 100644
--- a/src/sbbs3/ssl.h
+++ b/src/sbbs3/ssl.h
@@ -40,7 +40,7 @@ DLLEXPORT char* DLLCALL get_crypt_error(CRYPT_HANDLE sess);
 DLLEXPORT CRYPT_CONTEXT DLLCALL get_ssl_cert(scfg_t *cfg, char estr[SSL_ESTR_LEN]);
 DLLEXPORT int DLLCALL do_cryptInit(void);
 DLLEXPORT bool DLLCALL is_crypt_initialized(void);
-DLLEXPORT bool DLLCALL get_crypt_error_string(int status, CRYPT_HANDLE sess, char estr[SSL_ESTR_LEN], char *file, int line)
+DLLEXPORT bool DLLCALL get_crypt_error_string(int status, CRYPT_HANDLE sess, char estr[SSL_ESTR_LEN], const char *action);
 
 #if defined(__cplusplus)
 }