Skip to content
Snippets Groups Projects
msg_id.c 7.49 KiB
Newer Older
/* Synchronet Message-ID generation routines */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
rswindell's avatar
rswindell committed
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
 *																			*
 * This program is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU General Public License				*
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

#include "msg_id.h"
#include "smblib.h"
#include "git_branch.h"
#include "git_hash.h"
static ulong msg_number(smbmsg_t* msg)
{
	if(msg->idx.number)
		return(msg->idx.number);
	return(msg->hdr.number);
}

uint32_t get_new_msg_number(smb_t* smb)
{
	bool locked = smb->locked;

	if(!locked && smb_locksmbhdr(smb) != SMB_SUCCESS)
		return 0;

	if(smb_getstatus(smb)!=SMB_SUCCESS)
		return 0;

	if(!locked) smb_unlocksmbhdr(smb);
	return smb->status.last_msg + 1;
}

static ulong msg_time(smbmsg_t* msg)
{
	if(msg->idx.time)
		return(msg->idx.time);
	return(msg->hdr.when_imported.time);
}

static ulong msgid_serialno(smbmsg_t* msg)
{
	return (msg_time(msg)-1000000000) + msg_number(msg);
}

/****************************************************************************/
/* Returns a FidoNet (FTS-9) message-ID										*/
/* Returns NULL if the message is from FidoNet and doesn't have a MSGID		*/
/* Pass NULL for msgid if (single-threaded) caller wishes to use static buf	*/
/****************************************************************************/
char* ftn_msgid(sub_t *sub, smbmsg_t* msg, char* msgid, size_t maxlen)
	
	if(msgid == NULL) {
		msgid = msgidbuf;
		maxlen = sizeof(msgidbuf);
rswindell's avatar
rswindell committed
	}
	if(msg->ftn_msgid!=NULL && *msg->ftn_msgid!=0)
		return msg->ftn_msgid;

	if(msg->from_net.type == NET_FIDO)	// Don't generate a message-ID for imported FTN messages
		return NULL;
rswindell's avatar
rswindell committed
	safe_snprintf(msgid,maxlen
		,smb_faddrtoa(&sub->faddr, faddrbuf)
}

/****************************************************************************/
/* Return a general purpose (RFC-822) message-ID							*/
/****************************************************************************/
char* get_msgid(scfg_t* cfg, int subnum, smbmsg_t* msg, char* msgid, size_t maxlen)
rswindell's avatar
rswindell committed
	char*	host;
rswindell's avatar
rswindell committed
	if(msg->id!=NULL && *msg->id!=0) {
		strncpy(msgid,msg->id,maxlen);
rswindell's avatar
rswindell committed
	}

	/* Try *really* hard to get a hostname from the configuration data */
	host=cfg->sys_inetaddr;
	if(!host[0]) {
		host=cfg->sys_id;
		if(!host[0]) {
			host=cfg->sys_name;
			if(!host[0]) {
				host=cfg->sys_op;
			}
		}
	}
	if(!subnum_is_valid(cfg, subnum))
rswindell's avatar
rswindell committed
		safe_snprintf(msgid,maxlen
rswindell's avatar
rswindell committed
			,host);
rswindell's avatar
rswindell committed
		safe_snprintf(msgid,maxlen
			,"<%08lX.%lu.%s@%s>"
			,cfg->sub[subnum]->code
rswindell's avatar
rswindell committed
			,host);
/****************************************************************************/
/* Get (or generate) the original message-ID for a reply message			*/
/* Returns NULL if not a valid reply message								*/
/****************************************************************************/
char* get_replyid(scfg_t* cfg, smb_t* smb, smbmsg_t* msg, char* msgid, size_t maxlen)
rswindell's avatar
rswindell committed
{
	smbmsg_t remsg;

	if(msg->reply_id)
		return msg->reply_id;
	if(msg->hdr.thread_back == 0)
		return NULL;

	memset(&remsg, 0, sizeof(remsg));
	remsg.hdr.number=msg->hdr.thread_back;
	if(smb_getmsgidx(smb, &remsg) != SMB_SUCCESS)
		return NULL;
	if(smb_getmsghdr(smb, &remsg) != SMB_SUCCESS)
		return NULL;
	get_msgid(cfg, smb->subnum, &remsg, msgid, maxlen);
rswindell's avatar
rswindell committed
	smb_freemsgmem(&remsg);

}

/****************************************************************************/
/* Add auto-generated message-IDs to a message, if doesn't already have		*/
/* The message base (smb) must be already opened							*/
/****************************************************************************/
bool add_msg_ids(scfg_t* cfg, smb_t* smb, smbmsg_t* msg, smbmsg_t* remsg)
	if(msg->hdr.number == 0)
		msg->hdr.number = get_new_msg_number(smb);

 	/* Generate FidoNet (FTS-9) MSGID (for messages posted to FTN sub-boards only) */
 	if(msg->ftn_msgid == NULL) {
		if(smb->subnum == INVALID_SUB && msg->to_net.type == NET_FIDO) {
			safe_snprintf(msg_id, sizeof(msg_id)
				,smb_faddrtoa(nearest_sysfaddr(cfg, msg->to_net.addr), faddrbuf)
				,msgid_serialno(msg)
				);
			if(smb_hfield_str(msg, FIDOMSGID, msg_id) != SMB_SUCCESS)
		else if(subnum_is_valid(cfg, smb->subnum) && cfg->sub[smb->subnum]->misc&SUB_FIDO) {
			if(ftn_msgid(cfg->sub[smb->subnum], msg, msg_id, sizeof(msg_id)) != NULL) {
				if(smb_hfield_str(msg, FIDOMSGID, msg_id) != SMB_SUCCESS)
 	}

	/* Generate Internet MSG-ID (for all messages) */
	if(msg->id == NULL) {
 		get_msgid(cfg, smb->subnum, msg, msg_id, sizeof(msg_id));
 		if(smb_hfield_str(msg, RFC822MSGID, msg_id) != SMB_SUCCESS)
	}

	/* Generate Reply-IDs (when appropriate) */
	if(remsg != NULL) {
		if(add_reply_ids(cfg, smb, msg, remsg) != true)
			return false;
	}

	/* Generate FidoNet Program Identifier */
 	if(msg->ftn_pid == NULL) {
		if(smb_hfield_str(msg, FIDOPID, msg_program_id(msg_id, sizeof(msg_id))) != true)
			return false;
	return true;	// Success
}

/****************************************************************************/
/* Adds reply-IDs and does some reply/thread-linkage to a new message		*/
/* Migrated from sbbs_t::postmsg()											*/
/* The message base (smb) must be already opened successfully				*/
/****************************************************************************/
bool add_reply_ids(scfg_t* cfg, smb_t* smb, smbmsg_t* msg, smbmsg_t* remsg)
{
	char* p;
	char replyid[256];

	msg->hdr.thread_back = remsg->hdr.number;	/* needed for threading backward */

	if((msg->hdr.thread_id = remsg->hdr.thread_id) == 0)
		msg->hdr.thread_id = remsg->hdr.number;

	/* Add RFC-822 Reply-ID (generate if necessary) */
	if((p = get_replyid(cfg, smb, msg, replyid, sizeof(replyid))) != NULL) {
		if(smb_hfield_str(msg, RFC822REPLYID, p) != SMB_SUCCESS)
	}

	/* Add FidoNet Reply if original message has FidoNet MSGID */
	if(remsg->ftn_msgid != NULL) {
		if(smb_hfield_str(msg, FIDOREPLYID, remsg->ftn_msgid) != SMB_SUCCESS)
	return true;	// Success
}

/****************************************************************************/
/* FTN-compliant "Program Identifier"/PID									*/
/****************************************************************************/
char* msg_program_id(char* pid, size_t maxlen)
{
	char compiler[64];

	DESCRIBE_COMPILER(compiler);
	snprintf(pid, maxlen, "%.10s %s%c-%s %s/%s %.11s %s"
		,VERSION_NOTICE,VERSION,REVISION,PLATFORM_DESC