diff --git a/src/smblib/smblib.c b/src/smblib/smblib.c
index 508fd8ede6687b1ca34a3f6e57415395a44a3b4b..bc4dae2271e62cbcaa85cf6cfcde4c89b5728042 100644
--- a/src/smblib/smblib.c
+++ b/src/smblib/smblib.c
@@ -1217,7 +1217,9 @@ int SMBCALL smb_addcrc(smb_t* smb, ulong crc)
 {
 	char	str[128];
 	int 	file;
+	int		wr;
 	long	length;
+	long	newlen;
 	ulong	l,*buf;
 	time_t	start=0;
 
@@ -1250,48 +1252,52 @@ int SMBCALL smb_addcrc(smb_t* smb, ulong crc)
 		sprintf(smb->last_error,"invalid file length: %ld", length);
 		return(SMB_ERR_FILE_LEN); 
 	}
+
 	if((buf=(ulong*)MALLOC(length))==NULL) {
 		close(file);
 		sprintf(smb->last_error
 			,"malloc failure of %ld bytes"
-			,smb->status.max_crcs*4);
+			,length);
 		return(SMB_ERR_MEM); 
 	}
-	if((ulong)length>=smb->status.max_crcs*4L) { /* Reached or exceeds max crcs */
-		read(file,buf,smb->status.max_crcs*4);
-		for(l=0;l<smb->status.max_crcs;l++)
-			if(crc==buf[l])
-				break;
-		if(l<smb->status.max_crcs) {				/* Dupe CRC found */
-			close(file);
-			FREE(buf);
-			sprintf(smb->last_error
-				,"duplicate message detected");
-			return(SMB_DUPE_MSG);
-		}
-		chsize(file,0L);				/* truncate it */
-		lseek(file,0L,SEEK_SET);
-		write(file,buf+4,(smb->status.max_crcs-1)*4); 
-	}
 
-	else if(length/4) { 					/* Less than max crcs */
-		read(file,buf,length);
-		for(l=0;l<(ulong)(length/4);l++)
-			if(crc==buf[l])
-				break;
-		if(l<(ulong)(length/4L)) {					/* Dupe CRC found */
-			close(file);
-			FREE(buf);
-			sprintf(smb->last_error
-				,"duplicate message detected");
-			return(SMB_DUPE_MSG);
-		} 
+	if(read(file,buf,length)!=length) {
+		close(file);
+		FREE(buf);
+		sprintf(smb->last_error
+			,"%d (%s) reading %u bytes"
+			,errno,STRERROR(errno),length);
+		return(SMB_ERR_READ);
 	}
 
-	lseek(file,0L,SEEK_END);
-	write(file,&crc,sizeof(crc)); 			   /* Write to the end */
+	for(l=0;l<length/sizeof(long);l++)
+		if(crc==buf[l])
+			break;
+	if(l<length/sizeof(long)) {					/* Dupe CRC found */
+		close(file);
+		FREE(buf);
+		sprintf(smb->last_error
+			,"duplicate message detected");
+		return(SMB_DUPE_MSG);
+	} 
+
+	if(length>=(long)(smb->status.max_crcs*sizeof(long))) {
+		newlen=(smb->status.max_crcs-1)*sizeof(long);
+		chsize(file,0);	/* truncate it */
+		lseek(file,0L,SEEK_SET);
+		write(file,buf+(length-newlen),newlen); 
+	}
+	wr=write(file,&crc,sizeof(crc));	/* Write to the end */
 	FREE(buf);
 	close(file);
+
+	if(wr!=sizeof(crc)) {	
+		sprintf(smb->last_error
+			,"%d (%s) writing %u bytes"
+			,errno,STRERROR(errno),sizeof(crc));
+		return(SMB_ERR_WRITE);
+	}
+
 	return(SMB_SUCCESS);
 }
 
@@ -1588,7 +1594,7 @@ long SMBCALL smb_allocdat(smb_t* smb, ulong length, ushort headers)
 	j=0;	/* j is consecutive unused block counter */
 	fflush(smb->sda_fp);
 	rewind(smb->sda_fp);
-	while(!feof(smb->sda_fp)) {
+	while(!feof(smb->sda_fp) && offset>=0) {
 		if(!fread(&i,2,1,smb->sda_fp))
 			break;
 		offset+=SDT_BLOCK_LEN;
@@ -1599,6 +1605,10 @@ long SMBCALL smb_allocdat(smb_t* smb, ulong length, ushort headers)
 			break; 
 		} 
 	}
+	if((long)offset<0) {
+		sprintf(smb->last_error,"invalid data offset: %lu",offset);
+		return(SMB_ERR_DAT_OFFSET);
+	}
 	clearerr(smb->sda_fp);
 	if(fseek(smb->sda_fp,(offset/SDT_BLOCK_LEN)*2L,SEEK_SET)) {
 		return(SMB_ERR_SEEK);
@@ -1632,6 +1642,10 @@ long SMBCALL smb_fallocdat(smb_t* smb, ulong length, ushort headers)
 		return(SMB_ERR_SEEK);
 	}
 	offset=(ftell(smb->sda_fp)/2L)*SDT_BLOCK_LEN;
+	if((long)offset<0) {
+		sprintf(smb->last_error,"invalid data offset: %lu",offset);
+		return(SMB_ERR_DAT_OFFSET);
+	}
 	for(l=0;l<blocks;l++)
 		if(!fwrite(&headers,2,1,smb->sda_fp))
 			break;
@@ -1938,11 +1952,20 @@ long SMBCALL smb_hallocdat(smb_t* smb)
 		return(SMB_ERR_NOT_OPEN);
 	}
 	fflush(smb->sdt_fp);
+	l=filelength(fileno(smb->sdt_fp));
+	if(l<0) {
+		sprintf(smb->last_error,"invalid file length: %lu",(ulong)l);
+		return(SMB_ERR_FILE_LEN);
+	}
 	if(fseek(smb->sdt_fp,0L,SEEK_END))
 		return(SMB_ERR_SEEK);
 	l=ftell(smb->sdt_fp);
-	if(l<=0)
-		return(l);
+	if(l<0) {
+		sprintf(smb->last_error,"invalid file offset: %ld",l);
+		return(SMB_ERR_DAT_OFFSET);
+	}
+	if(l==0)
+		return(0);
 	while(l%SDT_BLOCK_LEN)					/* Make sure even block boundry */
 		l++;
 	return(l);