diff --git a/src/sbbs3/email.cpp b/src/sbbs3/email.cpp
index 55c8b7bfea195105e587ff3ed0011dd18cbcc31f..b502ac671eb2f4a04d9b79db0d98f8160e429831 100644
--- a/src/sbbs3/email.cpp
+++ b/src/sbbs3/email.cpp
@@ -218,7 +218,7 @@ bool sbbs_t::email(int usernumber, char *top, char *subj, long mode)
 	setvbuf(instream,NULL,_IOFBF,2*1024);
 	smb_fseek(smb.sdt_fp,offset,SEEK_SET);
 	xlat=XLAT_NONE;
-	smb_fwrite(&xlat,2,smb.sdt_fp);
+	smb_fwrite(&smb,&xlat,2,smb.sdt_fp);
 	x=SDT_BLOCK_LEN-2;				/* Don't read/write more than 255 */
 	while(!feof(instream)) {
 		memset(buf,0,x);
@@ -230,7 +230,7 @@ bool sbbs_t::email(int usernumber, char *top, char *subj, long mode)
 		if(cfg.mail_maxcrcs) {
 			for(i=0;i<j;i++)
 				crc=ucrc32(buf[i],crc); }
-		smb_fwrite(buf,j,smb.sdt_fp);
+		smb_fwrite(&smb,buf,j,smb.sdt_fp);
 		x=SDT_BLOCK_LEN; }
 	smb_fflush(smb.sdt_fp);
 	fclose(instream);
diff --git a/src/sbbs3/fido.cpp b/src/sbbs3/fido.cpp
index bee2e66c1bd11c7da376f09533ab05fb9a60b02a..91c6fdc885ec6b7155b3265df74ea7ffd63637c3 100644
--- a/src/sbbs3/fido.cpp
+++ b/src/sbbs3/fido.cpp
@@ -672,13 +672,13 @@ void sbbs_t::qwktonetmail(FILE *rep, char *block, char *into, uchar fromhub)
 
 		smb_fseek(smb.sdt_fp,offset,SEEK_SET);
 		xlat=XLAT_NONE;
-		smb_fwrite(&xlat,2,smb.sdt_fp);
+		smb_fwrite(&smb,&xlat,2,smb.sdt_fp);
 		m=2;
 		for(;l<n*QWK_BLOCK_LEN && m<length;l++) {
 			if(qwkbuf[l]==0 || qwkbuf[l]==LF)
 				continue;
 			if(qwkbuf[l]==QWK_NEWLINE) {
-				smb_fwrite(crlf,2,smb.sdt_fp);
+				smb_fwrite(&smb,crlf,2,smb.sdt_fp);
 				m+=2;
 				continue; }
 			smb_fputc(qwkbuf[l],smb.sdt_fp);
diff --git a/src/sbbs3/getmail.c b/src/sbbs3/getmail.c
index f91f53ba97c0061e31ab6eb2fe76761f3952fb3e..53c61fcc97d43fd7d11ec7ada05a97e9c224b5af 100644
--- a/src/sbbs3/getmail.c
+++ b/src/sbbs3/getmail.c
@@ -62,7 +62,7 @@ int DLLCALL getmail(scfg_t* cfg, int usernumber, BOOL sent)
 	if(smb_open(&smb)!=0) 
 		return(0); 
 	while(!smb_feof(smb.sid_fp)) {
-		if(smb_fread(&idx,sizeof(idx),smb.sid_fp) != sizeof(idx))
+		if(smb_fread(&smb,&idx,sizeof(idx),smb.sid_fp) != sizeof(idx))
 			break;
 		if(idx.number==0)	/* invalid message number, ignore */
 			continue;
@@ -139,7 +139,7 @@ mail_t* DLLCALL loadmail(smb_t* smb, ulong* msgs, uint usernumber
 
 	smb_rewind(smb->sid_fp);
 	while(!smb_feof(smb->sid_fp)) {
-		if(smb_fread(&idx,sizeof(idx),smb->sid_fp) != sizeof(idx))
+		if(smb_fread(smb,&idx,sizeof(idx),smb->sid_fp) != sizeof(idx))
 			break;
 		if(idx.number==0)	/* invalid message number, ignore */
 			continue;
diff --git a/src/sbbs3/mail.cpp b/src/sbbs3/mail.cpp
index ad962041e5a2e29efa6d67d0e2538566cebe2158..44f0d3365ea0a7c75343f8208d24cc0c8a2b68ad 100644
--- a/src/sbbs3/mail.cpp
+++ b/src/sbbs3/mail.cpp
@@ -67,7 +67,7 @@ int sbbs_t::delmail(uint usernumber, int which)
 		return(i); }
 	smb_rewind(smb.sid_fp);
 	for(l=0;l<smb.status.total_msgs;) {
-		if(!smb_fread(&msg.idx,sizeof(idxrec_t),smb.sid_fp))
+		if(!smb_fread(&smb,&msg.idx,sizeof(idxrec_t),smb.sid_fp))
 			break;
 		if(which==MAIL_ALL && !(msg.idx.attr&MSG_PERMANENT)
 			&& smb.status.max_age && now>msg.idx.time
@@ -100,7 +100,7 @@ int sbbs_t::delmail(uint usernumber, int which)
 	smb_rewind(smb.sid_fp);
 	smb_fsetlength(smb.sid_fp,0);
 	for(i=0;i<l;i++)
-		smb_fwrite(&idxbuf[i],sizeof(idxrec_t),smb.sid_fp);
+		smb_fwrite(&smb,&idxbuf[i],sizeof(idxrec_t),smb.sid_fp);
 	LFREE(idxbuf);
 	smb.status.total_msgs=l;
 	smb_putstatus(&smb);
diff --git a/src/sbbs3/mailsrvr.c b/src/sbbs3/mailsrvr.c
index eac8c2426952b45c70a5a3d4294b2612efea4d45..0944533647fb9477365eb0b4a35c86d0588184ef 100644
--- a/src/sbbs3/mailsrvr.c
+++ b/src/sbbs3/mailsrvr.c
@@ -3313,7 +3313,7 @@ static void sendmail_thread(void* arg)
 			smb_freemsgmem(&msg);
 
 			smb_fseek(smb.sid_fp, offset*sizeof(msg.idx), SEEK_SET);
-			if(smb_fread(&msg.idx, sizeof(msg.idx), smb.sid_fp) != sizeof(msg.idx))
+			if(smb_fread(&smb, &msg.idx, sizeof(msg.idx), smb.sid_fp) != sizeof(msg.idx))
 				break;
 			if(msg.idx.attr&MSG_DELETE)	/* Marked for deletion */
 				continue;
diff --git a/src/sbbs3/postmsg.cpp b/src/sbbs3/postmsg.cpp
index 97bb20a624fc0d20f310f0b74448bdc3334f8f09..3def10ffb2dd75e484b92e30980029f0fd3cf028 100644
--- a/src/sbbs3/postmsg.cpp
+++ b/src/sbbs3/postmsg.cpp
@@ -557,16 +557,16 @@ extern "C" int DLLCALL savemsg(scfg_t* cfg, smb_t* smb, smbmsg_t* msg, char* msg
 	xlatlen=0;
 	if(lzh) {
 		xlat=XLAT_LZH;
-		smb_fwrite(&xlat,sizeof(xlat),smb->sdt_fp);
+		smb_fwrite(smb,&xlat,sizeof(xlat),smb->sdt_fp);
 		xlatlen+=sizeof(xlat);
 	}
 	xlat=XLAT_NONE;
-	smb_fwrite(&xlat,sizeof(xlat),smb->sdt_fp);
+	smb_fwrite(smb,&xlat,sizeof(xlat),smb->sdt_fp);
 	xlatlen+=sizeof(xlat);
 
-	smb_fwrite(msgbuf,length-xlatlen,smb->sdt_fp);
+	smb_fwrite(smb,msgbuf,length-xlatlen,smb->sdt_fp);
 	for(l=length;l%SDT_BLOCK_LEN;l++)
-		smb_fwrite(&pad,1,smb->sdt_fp);
+		smb_fwrite(smb,&pad,1,smb->sdt_fp);
 
 	fflush(smb->sdt_fp);
 
diff --git a/src/sbbs3/readmsgs.cpp b/src/sbbs3/readmsgs.cpp
index cef0e4406d70fef50e56e7dc5896b6abcdfd0185..b52cd695a16f50ff1bca271bb23965c1a33b7411 100644
--- a/src/sbbs3/readmsgs.cpp
+++ b/src/sbbs3/readmsgs.cpp
@@ -210,7 +210,7 @@ post_t HUGE16 * sbbs_t::loadposts(long *posts, uint subnum, ulong ptr, long mode
 	}
 	while(!feof(smb.sid_fp)) {
 		skip=0;
-		if(smb_fread(&idx,sizeof(idx),smb.sid_fp) != sizeof(idx))
+		if(smb_fread(&smb, &idx,sizeof(idx),smb.sid_fp) != sizeof(idx))
 			break;
 
 		if(idx.number==0)	/* invalid message number, ignore */
diff --git a/src/sbbs3/sbbsecho.c b/src/sbbs3/sbbsecho.c
index d2e48d16a30385f55603b89f637393e7b113f814..a191a0bfa40398aeb4f676a6ef347d3670d16ace 100644
--- a/src/sbbs3/sbbsecho.c
+++ b/src/sbbs3/sbbsecho.c
@@ -2012,7 +2012,7 @@ ulong loadmsgs(post_t HUGE16 **post, ulong ptr)
 
 	fseek(smb[cur_smb].sid_fp,0L,SEEK_SET);
 	while(!feof(smb[cur_smb].sid_fp)) {
-		if(smb_fread(&idx,sizeof(idx),smb[cur_smb].sid_fp) != sizeof(idx))
+		if(smb_fread(&smb[cur_smb], &idx,sizeof(idx),smb[cur_smb].sid_fp) != sizeof(idx))
 			break;
 
 		if(idx.number==0)	/* invalid message number, ignore */
diff --git a/src/sbbs3/smbutil.c b/src/sbbs3/smbutil.c
index 6c44463fefa4157adce417ccb9cf20b002e6ae47..a04c121751c4334fa377bdb81ccd8bfe15c2ed60 100644
--- a/src/sbbs3/smbutil.c
+++ b/src/sbbs3/smbutil.c
@@ -190,10 +190,10 @@ void postmsg(char type, char* to, char* to_number, char* to_address,
 
 	fseek(smb.sdt_fp,offset,SEEK_SET);
 	xlat=XLAT_NONE;
-	smb_fwrite(&xlat,sizeof(xlat),smb.sdt_fp);
-	smb_fwrite(msgtxt,msgtxtlen,smb.sdt_fp);
+	smb_fwrite(&smb,&xlat,sizeof(xlat),smb.sdt_fp);
+	smb_fwrite(&smb,msgtxt,msgtxtlen,smb.sdt_fp);
 	for(l=length;l%SDT_BLOCK_LEN;l++)
-		smb_fwrite(&pad,1,smb.sdt_fp);
+		smb_fwrite(&smb,&pad,sizeof(pad),smb.sdt_fp);
 	fflush(smb.sdt_fp);
 
 	memset(&msg,0,sizeof(smbmsg_t));
diff --git a/src/smblib/smblib.c b/src/smblib/smblib.c
index 35a7bd051d5eb636e2d1a7a86f7072e562e2b431..89c95b65beb6b4d22eb56455a8a276a8ce858d0a 100644
--- a/src/smblib/smblib.c
+++ b/src/smblib/smblib.c
@@ -129,7 +129,7 @@ int SMBCALL smb_open(smb_t* smb)
 			return(SMB_ERR_LOCK); 
 		}
 		memset(&hdr,0,sizeof(smbhdr_t));
-		if(fread(&hdr,sizeof(smbhdr_t),1,smb->shd_fp)!=1) {
+		if(smb_fread(smb,&hdr,sizeof(smbhdr_t),smb->shd_fp)!=sizeof(smbhdr_t)) {
 			sprintf(smb->last_error,"%d (%s) reading header"
 				,errno,STRERROR(errno));
 			smb_close(smb);
@@ -147,8 +147,7 @@ int SMBCALL smb_open(smb_t* smb)
 			smb_close(smb);
 			return(SMB_ERR_HDR_VER); 
 		}
-		if(fread(&(smb->status),1,sizeof(smbstatus_t),smb->shd_fp)
-			!=sizeof(smbstatus_t)) {
+		if(smb_fread(smb,&(smb->status),sizeof(smbstatus_t),smb->shd_fp)!=sizeof(smbstatus_t)) {
 			sprintf(smb->last_error,"%d (%s) reading status"
 				,errno,STRERROR(errno));
 			smb_close(smb);
@@ -497,7 +496,7 @@ int SMBCALL smb_getstatus(smb_t* smb)
 			,errno,STRERROR(errno),sizeof(smbhdr_t));
 		return(SMB_ERR_SEEK);
 	}
-	i=fread(&(smb->status),1,sizeof(smbstatus_t),smb->shd_fp);
+	i=smb_fread(smb,&(smb->status),sizeof(smbstatus_t),smb->shd_fp);
 	setvbuf(smb->shd_fp,smb->shd_buf,_IOFBF,SHD_BLOCK_LEN);
 	if(i==sizeof(smbstatus_t))
 		return(SMB_SUCCESS);
@@ -620,7 +619,7 @@ int SMBCALL smb_getmsgidx(smb_t* smb, smbmsg_t* msg)
 				,msg->offset*sizeof(idxrec_t));
 			return(SMB_ERR_SEEK);
 		}
-		if(!fread(&msg->idx,sizeof(idxrec_t),1,smb->sid_fp)) {
+		if(smb_fread(smb,&msg->idx,sizeof(idxrec_t),smb->sid_fp)!=sizeof(idxrec_t)) {
 			sprintf(smb->last_error,"%d (%s) reading index at offset %lu (byte %lu)"
 				,errno,STRERROR(errno),msg->offset,msg->offset*sizeof(idxrec_t));
 			return(SMB_ERR_READ);
@@ -643,7 +642,7 @@ int SMBCALL smb_getmsgidx(smb_t* smb, smbmsg_t* msg)
 				,l,l*sizeof(idxrec_t));
 			return(SMB_ERR_SEEK);
 		}
-		if(!fread(&idx,sizeof(idxrec_t),1,smb->sid_fp)) {
+		if(smb_fread(smb,&idx,sizeof(idxrec_t),smb->sid_fp)!=sizeof(idxrec_t)) {
 			sprintf(smb->last_error,"%d (%s) reading index at offset %lu (byte %lu)"
 				,errno,STRERROR(errno),l,l*sizeof(idxrec_t));
 			return(SMB_ERR_READ);
@@ -685,7 +684,7 @@ int SMBCALL smb_getfirstidx(smb_t* smb, idxrec_t *idx)
 			,errno,STRERROR(errno));
 		return(SMB_ERR_SEEK);
 	}
-	if(!fread(idx,sizeof(idxrec_t),1,smb->sid_fp)) {
+	if(smb_fread(smb,idx,sizeof(idxrec_t),smb->sid_fp)!=sizeof(idxrec_t)) {
 		sprintf(smb->last_error,"%d (%s) reading first index"
 			,errno,STRERROR(errno));
 		return(SMB_ERR_READ);
@@ -716,7 +715,7 @@ int SMBCALL smb_getlastidx(smb_t* smb, idxrec_t *idx)
 			,(unsigned)(length-sizeof(idxrec_t)));
 		return(SMB_ERR_SEEK);
 	}
-	if(!fread(idx,sizeof(idxrec_t),1,smb->sid_fp)) {
+	if(smb_fread(smb,idx,sizeof(idxrec_t),smb->sid_fp)!=sizeof(idxrec_t)) {
 		sprintf(smb->last_error,"%d (%s) reading last index",errno,STRERROR(errno));
 		return(SMB_ERR_READ);
 	}
@@ -951,7 +950,7 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg)
 	memset(msg,0,sizeof(smbmsg_t));
 	msg->idx=idx;
 	msg->offset=offset;
-	if(!fread(&msg->hdr,sizeof(msghdr_t),1,smb->shd_fp)) {
+	if(smb_fread(smb,&msg->hdr,sizeof(msghdr_t),smb->shd_fp)!=sizeof(msghdr_t)) {
 		sprintf(smb->last_error,"%d (%s) reading msg header"
 			,errno,STRERROR(errno));
 		return(SMB_ERR_READ);
@@ -976,7 +975,7 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg)
 	}
 	i=0;
 	while(i<msg->hdr.total_dfields && l<msg->hdr.length) {
-		if(!fread(&msg->dfield[i],sizeof(dfield_t),1,smb->shd_fp)) {
+		if(smb_fread(smb,&msg->dfield[i],sizeof(dfield_t),smb->shd_fp)!=sizeof(dfield_t)) {
 			smb_freemsgmem(msg);
 			sprintf(smb->last_error,"%d (%s) reading data field %d"
 				,errno,STRERROR(errno),i);
@@ -1010,7 +1009,7 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg)
 		}
 		msg->hfield=vp;
 		msg->total_hfields++;
-		if(!fread(&msg->hfield[i],sizeof(hfield_t),1,smb->shd_fp)) {
+		if(smb_fread(smb,&msg->hfield[i],sizeof(hfield_t),smb->shd_fp)!=sizeof(hfield_t)) {
 			smb_freemsgmem(msg);
 			sprintf(smb->last_error,"%d (%s) reading header field"
 				,errno,STRERROR(errno));
@@ -1027,7 +1026,7 @@ int SMBCALL smb_getmsghdr(smb_t* smb, smbmsg_t* msg)
 		}
 		memset(msg->hfield_dat[i],0,msg->hfield[i].length+1);  /* init to NULL */
 		if(msg->hfield[i].length
-			&& !fread(msg->hfield_dat[i],msg->hfield[i].length,1,smb->shd_fp)) {
+			&& smb_fread(smb,msg->hfield_dat[i],msg->hfield[i].length,smb->shd_fp)!=msg->hfield[i].length) {
 			smb_freemsgmem(msg);
 			sprintf(smb->last_error,"%d (%s) reading header field data"
 				,errno,STRERROR(errno));
@@ -1692,7 +1691,7 @@ long SMBCALL smb_allocdat(smb_t* smb, ulong length, ushort refs)
 	fflush(smb->sda_fp);
 	rewind(smb->sda_fp);
 	while(!feof(smb->sda_fp) && offset>=0) {
-		if(!fread(&i,2,1,smb->sda_fp))
+		if(smb_fread(smb,&i,sizeof(i),smb->sda_fp)!=sizeof(i))
 			break;
 		offset+=SDT_BLOCK_LEN;
 		if(!i) j++;
@@ -1789,7 +1788,7 @@ int SMBCALL smb_freemsgdat(smb_t* smb, ulong offset, ulong length, ushort refs)
 			retval=SMB_ERR_SEEK;
 			break;
 		}
-		if(!fread(&i,2,1,smb->sda_fp)) {
+		if(smb_fread(smb,&i,sizeof(i),smb->sda_fp)!=sizeof(i)) {
 			sprintf(smb->last_error,"%d (%s) reading allocation bytes"
 				,errno,STRERROR(errno));
 			retval=SMB_ERR_READ;
@@ -1837,7 +1836,7 @@ int SMBCALL smb_incdat(smb_t* smb, ulong offset, ulong length, ushort refs)
 		if(fseek(smb->sda_fp,((offset/SDT_BLOCK_LEN)+l)*2L,SEEK_SET)) {
 			return(SMB_ERR_SEEK);
 		}
-		if(!fread(&i,2,1,smb->sda_fp)) {
+		if(smb_fread(smb,&i,sizeof(i),smb->sda_fp)!=sizeof(i)) {
 			sprintf(smb->last_error,"%d (%s) reading allocation record"
 				,errno,STRERROR(errno));
 			return(SMB_ERR_READ);
@@ -1970,7 +1969,7 @@ long SMBCALL smb_allochdr(smb_t* smb, ulong length)
 	fflush(smb->sha_fp);
 	rewind(smb->sha_fp);
 	while(!feof(smb->sha_fp)) {
-		if(!fread(&c,1,1,smb->sha_fp)) 
+		if(smb_fread(smb,&c,sizeof(c),smb->sha_fp)!=sizeof(c)) 
 			break;
 		offset+=SHD_BLOCK_LEN;
 		if(!c) i++;
@@ -2137,36 +2136,29 @@ void SMBCALL smb_clearerr(FILE* fp)
 	clearerr(fp);
 }
 
-long SMBCALL smb_fread(void HUGE16* buf, long bytes, FILE* fp)
+size_t SMBCALL smb_fread(smb_t* smb, void* buf, size_t bytes, FILE* fp)
 {
-#ifdef __FLAT__
-	return(fread(buf,1,bytes,fp));
-#else
-	long count;
+	size_t ret=0;
+	time_t start=0;
 
-	for(count=bytes;count>0x7fff;count-=0x7fff,(char*)buf+=0x7fff)
-		if(fread((char*)buf,1,0x7fff,fp)!=0x7fff)
-			return(bytes-count);
-	if(fread((char*)buf,1,(size_t)count,fp)!=(size_t)count)
-		return(bytes-count);
-	return(bytes);
-#endif
+	while(1) {
+		if((ret=fread(buf,sizeof(char),bytes,fp))==bytes)
+			return(ret);
+		if(errno!=EDEADLOCK)
+			return(ret);
+		if(!start)
+			start=time(NULL);
+		else
+			if(time(NULL)-start>=(time_t)smb->retry_time)
+				break;
+		SLEEP(smb->retry_delay);
+	}
+	return(ret);
 }
 
-long SMBCALL smb_fwrite(void HUGE16* buf, long bytes, FILE* fp)
+size_t SMBCALL smb_fwrite(smb_t* smb, void* buf, size_t bytes, FILE* fp)
 {
-#ifdef __FLAT__
 	return(fwrite(buf,1,bytes,fp));
-#else
-	long count;
-
-	for(count=bytes;count>0x7fff;count-=0x7fff,(char*)buf+=0x7fff)
-		if(fwrite((char*)buf,1,0x7fff,fp)!=0x7fff)
-			return(bytes-count);
-	if(fwrite((char*)buf,1,(size_t)count,fp)!=(size_t)count)
-		return(bytes-count);
-	return(bytes);
-#endif
 }
 
 /************************************************************************/
diff --git a/src/smblib/smblib.h b/src/smblib/smblib.h
index 04e1152ce6fe3b6756c25cd6320368718c712698..d43ef2bce1a5cdddbfb58ddcb7c66caee1e4bd78 100644
--- a/src/smblib/smblib.h
+++ b/src/smblib/smblib.h
@@ -164,8 +164,8 @@ SMBEXPORT int 		SMBCALL smb_fgetc(FILE* fp);
 SMBEXPORT int 		SMBCALL smb_fputc(int ch, FILE* fp);
 SMBEXPORT int 		SMBCALL smb_fseek(FILE* fp, long offset, int whence);
 SMBEXPORT long		SMBCALL smb_ftell(FILE* fp);
-SMBEXPORT long		SMBCALL smb_fread(void HUGE16* buf, long bytes, FILE* fp);
-SMBEXPORT long		SMBCALL smb_fwrite(void HUGE16* buf, long bytes, FILE* fp);
+SMBEXPORT size_t	SMBCALL smb_fread(smb_t*, void* buf, size_t bytes, FILE* fp);
+SMBEXPORT size_t	SMBCALL smb_fwrite(smb_t*, void* buf, size_t bytes, FILE* fp);
 SMBEXPORT long		SMBCALL smb_fgetlength(FILE* fp);
 SMBEXPORT int 		SMBCALL smb_fsetlength(FILE* fp, long length);
 SMBEXPORT void		SMBCALL smb_rewind(FILE* fp);
diff --git a/src/smblib/smbtxt.c b/src/smblib/smbtxt.c
index 760067b5c161f0422d3b1f1145d9d96ded8151ea..1edb8400e84000903c88d7700002f34629cce72a 100644
--- a/src/smblib/smbtxt.c
+++ b/src/smblib/smbtxt.c
@@ -117,7 +117,7 @@ char* SMBCALL smb_getmsgtxt(smb_t* smb, smbmsg_t* msg, ulong mode)
 					,length);
 				return(buf);
 			}
-			smb_fread(lzhbuf,length,smb->sdt_fp);
+			smb_fread(smb,lzhbuf,length,smb->sdt_fp);
 			lzhlen=*(long*)lzhbuf;
 			if((p=(char*)REALLOC(buf,l+lzhlen+3L))==NULL) {
 				sprintf(smb->last_error