From c93e22956c150a6584b17c904b7d8bef496e8d91 Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Mon, 30 Aug 2004 10:18:26 +0000
Subject: [PATCH] Added "update" mode to smb_hashmsg(), used by fixsmb to force
 smb_findhash() to mark found hashes and only write the not-found hashes to
 disk, rather than not writing *any* hashes (when any match) because the
 message is a "dupe". When update is false, the behavior is the same as
 before.

---
 src/sbbs3/fixsmb.c   |  4 +--
 src/smblib/smbdefs.h | 11 ++++++---
 src/smblib/smblib.c  | 58 ++++++++++++++++++++++++++++++--------------
 src/smblib/smblib.h  |  2 +-
 4 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/src/sbbs3/fixsmb.c b/src/sbbs3/fixsmb.c
index 532fe107e3..6e973a1f99 100644
--- a/src/sbbs3/fixsmb.c
+++ b/src/sbbs3/fixsmb.c
@@ -213,8 +213,8 @@ int main(int argc, char **argv)
 			text=NULL;
 		else
 			text=smb_getmsgtxt(&smb,&msg,GETMSGTXT_BODY_ONLY);
-		i=smb_hashmsg(&smb,&msg,text);
-		if(i!=SMB_SUCCESS && i!=SMB_DUPE_MSG)
+		i=smb_hashmsg(&smb,&msg,text,TRUE /* update */);
+		if(i!=SMB_SUCCESS)
 			printf("!ERROR %d hashing message\n", i);
 		if(text!=NULL)
 			free(text);
diff --git a/src/smblib/smbdefs.h b/src/smblib/smbdefs.h
index ed6a2bfdd7..4166b027f8 100644
--- a/src/smblib/smbdefs.h
+++ b/src/smblib/smbdefs.h
@@ -458,10 +458,15 @@ typedef struct _PACK {		/* Index record */
 #define SMB_HASH_CRC16		(1<<0)	/* CRC-16 hash is valid				*/
 #define SMB_HASH_CRC32		(1<<1)	/* CRC-32 hash is valid				*/
 #define SMB_HASH_MD5		(1<<2)	/* MD5 digest is valid				*/
-#define SMB_HASH_MASK		0x0f	/* which hashes are valid			*/
-#define SMB_HASH_UPPERCASE	(1<<4)	/* Convert a-z to A-Z first			*/
-#define SMB_HASH_LOWERCASE	(1<<5)	/* Convert A-Z to a-z first			*/
+#define SMB_HASH_MASK		(SMB_HASH_CRC16|SMB_HASH_CRC32|SMB_HASH_MD5)
+
+#define SMB_HASH_MARK		(1<<3)	/* Used by smb_findhash()			*/
+#define SMB_HASH_MARKED		(1<<4)	/* Used by smb_findhash()			*/
+#define SMB_HASH_MARK_MASK	(SMB_HASH_MARK|SMB_HASH_MARKED)
+
 #define SMB_HASH_STRIP_WSP	(1<<6)	/* Strip white-space chars first	*/
+#define SMB_HASH_LOWERCASE	(1<<7)	/* Convert A-Z to a-z first			*/
+#define SMB_HASH_PROC_MASK	(SMB_HASH_STRIP_WSP|SMB_HASH_LOWERCASE)
 
 typedef struct _PACK {
 
diff --git a/src/smblib/smblib.c b/src/smblib/smblib.c
index 6b5c5bd6b3..22cb127535 100644
--- a/src/smblib/smblib.c
+++ b/src/smblib/smblib.c
@@ -2363,14 +2363,15 @@ int SMBCALL smb_updatethread(smb_t* smb, smbmsg_t* remsg, ulong newmsgnum)
 /**************************/
 
 /* If return value is SMB_ERROR_NOT_FOUND, hash file is left open */
-int SMBCALL smb_findhash(smb_t* smb, hash_t** compare, hash_t* found)
+int SMBCALL smb_findhash(smb_t* smb, hash_t** compare, hash_t* found_hash)
 {
 	int		retval;
+	BOOL	found=FALSE;
 	size_t	c;
 	hash_t	hash;
 
-	if(found!=NULL)
-		memset(found,0,sizeof(hash_t));
+	if(found_hash!=NULL)
+		memset(found_hash,0,sizeof(hash_t));
 
 	if((retval=smb_open_hash(smb))!=SMB_SUCCESS)
 		return(retval);
@@ -2390,10 +2391,10 @@ int SMBCALL smb_findhash(smb_t* smb, hash_t** compare, hash_t* found)
 
 				if(compare[c]->source!=hash.source)	
 					continue;	/* wrong source */
+				if((compare[c]->flags&SMB_HASH_PROC_MASK)!=(hash.flags&SMB_HASH_PROC_MASK))
+					continue;	/* wrong pre-process flags */
 				if((compare[c]->flags&hash.flags&SMB_HASH_MASK)==0)	
 					continue;	/* no matching hashes */
-				if((compare[c]->flags&~SMB_HASH_MASK)!=(hash.flags&~SMB_HASH_MASK))
-					continue;	/* wrong pre-process flags */
 				if(compare[c]->flags&hash.flags&SMB_HASH_CRC16 
 					&& compare[c]->crc16!=hash.crc16)
 					continue;	/* wrong crc-16 */
@@ -2403,15 +2404,27 @@ int SMBCALL smb_findhash(smb_t* smb, hash_t** compare, hash_t* found)
 				if(compare[c]->flags&hash.flags&SMB_HASH_MD5 
 					&& memcmp(compare[c]->md5,hash.md5,sizeof(hash.md5)))
 					continue;	/* wrong crc-16 */
-
+				
 				/* successful match! */
-				if(found!=NULL)
-					memcpy(found,&hash,sizeof(hash));
+				break;	/* can't match more than one, so stop comparing */
+			}
 
-				smb_close_hash(smb);
+			if(compare[c]==NULL)
+				continue;	/* no match */
 
-				return(SMB_SUCCESS);
-			}
+			found=TRUE;
+
+			if(found_hash!=NULL)
+				memcpy(found_hash,&hash,sizeof(hash));
+
+			if(!(compare[c]->flags&SMB_HASH_MARK))
+				break;
+
+			compare[c]->flags|=SMB_HASH_MARKED;
+		}
+		if(found) {
+			smb_close_hash(smb);
+			return(SMB_SUCCESS);
 		}
 	}
 
@@ -2421,8 +2434,8 @@ int SMBCALL smb_findhash(smb_t* smb, hash_t** compare, hash_t* found)
 
 int SMBCALL smb_addhashes(smb_t* smb, hash_t** hashes)
 {
-	int			retval;
-	size_t		h;
+	int		retval;
+	size_t	h;
 
 	if((retval=smb_open_hash(smb))!=SMB_SUCCESS)
 		return(retval);
@@ -2430,7 +2443,13 @@ int SMBCALL smb_addhashes(smb_t* smb, hash_t** hashes)
 	if(hashes!=NULL) {
 
 		fseek(smb->hash_fp,0,SEEK_END);
+
 		for(h=0;hashes[h]!=NULL;h++) {
+
+			/* skip hashes marked by smb_findhash() */
+			if(hashes[h]->flags&SMB_HASH_MARKED)	
+				continue;	
+		
 			if(smb_fwrite(smb,hashes[h],sizeof(hash_t),smb->hash_fp)!=sizeof(hash_t))
 				return(SMB_ERR_WRITE);
 		}
@@ -2489,11 +2508,9 @@ hash_t* SMBCALL smb_hashstr(ulong msgnum, ulong t, unsigned source, unsigned fla
 	uchar*	p=str;
 	hash_t*	hash;
 
-	if(flags&~SMB_HASH_MASK) {	/* string pre-processing */
+	if(flags&SMB_HASH_PROC_MASK) {	/* string pre-processing */
 		if((p=strdup(str))==NULL)
 			return(NULL);
-		if(flags&SMB_HASH_UPPERCASE)
-			strupr(p);
 		if(flags&SMB_HASH_LOWERCASE)
 			strlwr(p);
 		if(flags&SMB_HASH_STRIP_WSP)
@@ -2542,7 +2559,7 @@ hash_t** SMBCALL smb_msghashes(smb_t* smb, smbmsg_t* msg, uchar* text)
 }
 
 /* Calculates and stores the hashes for a single message					*/
-int SMBCALL smb_hashmsg(smb_t* smb, smbmsg_t* msg, uchar* text)
+int SMBCALL smb_hashmsg(smb_t* smb, smbmsg_t* msg, uchar* text, BOOL update)
 {
 	size_t		n;
 	int			retval=SMB_SUCCESS;
@@ -2550,7 +2567,12 @@ int SMBCALL smb_hashmsg(smb_t* smb, smbmsg_t* msg, uchar* text)
 
 	hashes=smb_msghashes(smb,msg,text);
 
-	if(smb_findhash(smb, hashes, NULL)==SMB_SUCCESS)
+	if(update) {
+		for(n=0;hashes[n]!=NULL;n++)
+			hashes[n]->flags|=SMB_HASH_MARK;
+	}
+
+	if(smb_findhash(smb, hashes, NULL)==SMB_SUCCESS && !update)
 		retval=SMB_DUPE_MSG;
 	else
 		retval=smb_addhashes(smb,hashes);
diff --git a/src/smblib/smblib.h b/src/smblib/smblib.h
index c70bbbd72c..ff13bddcdf 100644
--- a/src/smblib/smblib.h
+++ b/src/smblib/smblib.h
@@ -163,7 +163,7 @@ SMBEXPORT int		SMBCALL smb_updatethread(smb_t* smb, smbmsg_t* remsg, ulong newms
 
 /* hash-related functions */
 SMBEXPORT int		SMBCALL smb_findhash(smb_t* smb, hash_t** compare_list, hash_t* found);
-SMBEXPORT int		SMBCALL smb_hashmsg(smb_t* smb, smbmsg_t* msg, uchar* text);
+SMBEXPORT int		SMBCALL smb_hashmsg(smb_t* smb, smbmsg_t* msg, uchar* text, BOOL update);
 SMBEXPORT hash_t*	SMBCALL	smb_hash(ulong msgnum, ulong time, unsigned source, unsigned flags, uchar* data, size_t length);
 SMBEXPORT hash_t*	SMBCALL	smb_hashstr(ulong msgnum, ulong time, unsigned source, unsigned flags, uchar* str);
 SMBEXPORT hash_t**	SMBCALL smb_msghashes(smb_t* smb, smbmsg_t* msg, uchar* text);
-- 
GitLab