From 2c8faee73585adbab9f97d041e18ede6c5b0eb53 Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Sun, 2 Oct 2005 23:28:57 +0000
Subject: [PATCH] Created smb_updatemsg() - used to safely update the header
 and index records of a message. smb_putmsg() now calls smb_init_idx()
 automatically to initialize or re-synchronize the index fields with the
 header fields - no longer need to call smb_init_idx() from smb_addmsg() and
 other places (e.g. fixsmb). Moved smb_init_idx() from smbhash.c to smblib.c.

---
 src/smblib/smbadd.c  |  1 -
 src/smblib/smbhash.c | 20 --------------
 src/smblib/smblib.c  | 65 ++++++++++++++++++++++++++++++++++++++++----
 src/smblib/smblib.h  |  5 ++--
 4 files changed, 62 insertions(+), 29 deletions(-)

diff --git a/src/smblib/smbadd.c b/src/smblib/smbadd.c
index f856fbf76f..ab14819990 100644
--- a/src/smblib/smbadd.c
+++ b/src/smblib/smbadd.c
@@ -248,7 +248,6 @@ int SMBCALL smb_addmsg(smb_t* smb, smbmsg_t* msg, int storage, long dupechk_hash
 		}
 		if(msg->hdr.when_written.time==0)	/* Uninitialized */
 			msg->hdr.when_written = msg->hdr.when_imported;
-		smb_init_idx(smb,msg);
 
 		/* Look-up thread_back if RFC822 Reply-ID was specified */
 		if(msg->hdr.thread_back==0 && msg->reply_id!=NULL) {
diff --git a/src/smblib/smbhash.c b/src/smblib/smbhash.c
index a2d4a56854..4628fe0e14 100644
--- a/src/smblib/smbhash.c
+++ b/src/smblib/smbhash.c
@@ -372,23 +372,3 @@ ushort SMBCALL smb_name_crc(const char* name)
 
 	return(crc);
 }
-
-int SMBCALL smb_init_idx(smb_t* smb, smbmsg_t* msg)
-{
-	msg->idx.subj=smb_subject_crc(msg->subj);
-	if(smb->status.attr&SMB_EMAIL) {
-		if(msg->to_ext)
-			msg->idx.to=atoi(msg->to_ext);
-		else
-			msg->idx.to=0;
-		if(msg->from_ext)
-			msg->idx.from=atoi(msg->from_ext);
-		else
-			msg->idx.from=0; 
-	} else {
-		msg->idx.to=smb_name_crc(msg->to);
-		msg->idx.from=smb_name_crc(msg->from);
-	}
-
-	return(SMB_SUCCESS);
-}
diff --git a/src/smblib/smblib.c b/src/smblib/smblib.c
index 24506c17e9..bc3b68cda4 100644
--- a/src/smblib/smblib.c
+++ b/src/smblib/smblib.c
@@ -353,7 +353,7 @@ int SMBCALL smb_locksmbhdr(smb_t* smb)
 			SLEEP(smb->retry_delay);
 		}
 	}
-	safe_snprintf(smb->last_error,sizeof(smb->last_error),"timeout locking header");
+	safe_snprintf(smb->last_error,sizeof(smb->last_error),"timeout locking message base");
 	return(SMB_ERR_TIMEOUT);
 }
 
@@ -1395,7 +1395,7 @@ int SMBCALL smb_addmsghdr(smb_t* smb, smbmsg_t* msg, int storage)
 		smb_unlocksmbhdr(smb);
 		return(i);
 	}
-	msg->idx.number=msg->hdr.number=smb->status.last_msg+1;
+	msg->hdr.number=smb->status.last_msg+1;
 
 	/* This is *not* a dupe-check */
 	if(!(msg->flags&MSG_FLAG_HASHED) /* not already hashed */
@@ -1426,8 +1426,6 @@ int SMBCALL smb_addmsghdr(smb_t* smb, smbmsg_t* msg, int storage)
 	}
 
 	msg->idx.offset=smb->status.header_offset+l;
-	msg->idx.time=msg->hdr.when_imported.time;
-	msg->idx.attr=msg->hdr.attr;
 	msg->offset=smb->status.total_msgs;
 	i=smb_putmsg(smb,msg);
 	if(i==SMB_SUCCESS) {
@@ -1439,6 +1437,29 @@ int SMBCALL smb_addmsghdr(smb_t* smb, smbmsg_t* msg, int storage)
 	return(i);
 }
 
+/****************************************************************************/
+/* Safely updates existing index and header records for msg					*/
+/* Nothing should be locked prior to calling this function and nothing		*/
+/* should (normally) be locked when it exits								*/
+/****************************************************************************/
+int SMBCALL smb_updatemsg(smb_t* smb, smbmsg_t* msg)
+{
+	int retval;
+
+	/* Insure no one else can be changing the index at this time */
+	if((retval=smb_locksmbhdr(smb))!=SMB_SUCCESS)
+		return(retval);
+	/* Get the current index record offset (for later update by smb_putmsgidx) */
+	if((retval=smb_getmsgidx(smb, msg))==SMB_SUCCESS) {
+		/* Don't let any one else read or write this header while we're updating it */
+		if((retval=smb_lockmsghdr(smb,msg))==SMB_SUCCESS) {
+			retval=smb_putmsg(smb,msg);
+			smb_unlockmsghdr(smb,msg);
+		}
+	}
+	smb_unlocksmbhdr(smb);
+	return(retval);
+}
 
 /****************************************************************************/
 /* Writes both header and index information for msg 'msg'                   */
@@ -1447,12 +1468,44 @@ int SMBCALL smb_putmsg(smb_t* smb, smbmsg_t* msg)
 {
 	int i;
 
-	i=smb_putmsghdr(smb,msg);
-	if(i)
+	smb_init_idx(smb,msg);
+
+	if((i=smb_putmsghdr(smb,msg))!=SMB_SUCCESS)
 		return(i);
+
 	return(smb_putmsgidx(smb,msg));
 }
 
+/****************************************************************************/
+/* Initializes/re-synchronizes all the fields of the message index record	*/
+/* with the values from the message header (except for the header offset)	*/
+/****************************************************************************/
+int SMBCALL smb_init_idx(smb_t* smb, smbmsg_t* msg)
+{
+	msg->idx.subj=smb_subject_crc(msg->subj);
+
+	if(smb->status.attr&SMB_EMAIL) {
+		if(msg->to_ext)
+			msg->idx.to=atoi(msg->to_ext);
+		else
+			msg->idx.to=0;
+		if(msg->from_ext)
+			msg->idx.from=atoi(msg->from_ext);
+		else
+			msg->idx.from=0; 
+	} else {
+		msg->idx.to=smb_name_crc(msg->to);
+		msg->idx.from=smb_name_crc(msg->from);
+	}
+
+	/* Make sure these index/header fields are always *nsync */
+	msg->idx.number	= msg->hdr.number;
+	msg->idx.attr	= msg->hdr.attr;	
+	msg->idx.time	= msg->hdr.when_imported.time;
+
+	return(SMB_SUCCESS);
+}
+
 /****************************************************************************/
 /* Writes index information for 'msg'                                       */
 /* msg->idx 																*/
diff --git a/src/smblib/smblib.h b/src/smblib/smblib.h
index bf99e69d82..01dd7a1995 100644
--- a/src/smblib/smblib.h
+++ b/src/smblib/smblib.h
@@ -8,7 +8,7 @@
  * @format.tab-size 4		(Plain Text/Source Code File Header)			*
  * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
  *																			*
- * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html		*
+ * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html		*
  *																			*
  * This library is free software; you can redistribute it and/or			*
  * modify it under the terms of the GNU Lesser General Public License		*
@@ -145,7 +145,9 @@ SMBEXPORT ulong		SMBCALL smb_datblocks(ulong length);
 SMBEXPORT int		SMBCALL	smb_copymsgmem(smb_t* smb, smbmsg_t* destmsg, smbmsg_t* srcmsg);
 SMBEXPORT int		SMBCALL smb_tzutc(short timezone);
 SMBEXPORT int		SMBCALL smb_updatethread(smb_t* smb, smbmsg_t* remsg, ulong newmsgnum);
+SMBEXPORT int		SMBCALL smb_updatemsg(smb_t* smb, smbmsg_t* msg);
 SMBEXPORT BOOL		SMBCALL smb_valid_hdr_offset(smb_t* smb, ulong offset);
+SMBEXPORT int		SMBCALL smb_init_idx(smb_t* smb, smbmsg_t* msg);
 
 /* smbadd.c */
 SMBEXPORT int		SMBCALL smb_addmsg(smb_t* smb, smbmsg_t* msg, int storage, long dupechk_hashes
@@ -179,7 +181,6 @@ SMBEXPORT hash_t**	SMBCALL smb_msghashes(smbmsg_t* msg, const uchar* text);
 SMBEXPORT int		SMBCALL smb_addhashes(smb_t* smb, hash_t** hash_list, BOOL skip_marked);
 SMBEXPORT ushort	SMBCALL smb_name_crc(const char* name);
 SMBEXPORT ushort	SMBCALL smb_subject_crc(const char *subj);
-SMBEXPORT int		SMBCALL smb_init_idx(smb_t* smb, smbmsg_t* msg);
 
 /* Fast look-up functions (using hashes) */
 SMBEXPORT int 		SMBCALL smb_getmsgidx_by_hash(smb_t* smb, smbmsg_t* msg, unsigned source
-- 
GitLab