--- sbbs/src/smblib/smbhash.c 2018/04/24 16:41:24 1.1 +++ sbbs/src/smblib/smbhash.c 2018/04/24 16:45:14 1.1.1.2 @@ -2,13 +2,13 @@ /* Synchronet message base (SMB) hash-related functions */ -/* $Id: smbhash.c,v 1.1 2018/04/24 16:41:24 root Exp $ */ +/* $Id: smbhash.c,v 1.1.1.2 2018/04/24 16:45:14 root Exp $ */ /**************************************************************************** * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2009 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 * @@ -43,7 +43,7 @@ #include "crc32.h" #include "genwrap.h" -/* If return value is SMB_ERROR_NOT_FOUND, hash file is left open */ +/* If return value is SMB_ERR_NOT_FOUND, hash file is left open */ int SMBCALL smb_findhash(smb_t* smb, hash_t** compare, hash_t* found_hash, long source_mask, BOOL mark) { @@ -60,9 +60,10 @@ int SMBCALL smb_findhash(smb_t* smb, has COUNT_LIST_ITEMS(compare, count); - if(count) { + if(count && source_mask!=SMB_HASH_SOURCE_NONE) { rewind(smb->hash_fp); + clearerr(smb->hash_fp); while(!feof(smb->hash_fp)) { if(smb_fread(smb,&hash,sizeof(hash),smb->hash_fp)!=sizeof(hash)) break; @@ -81,19 +82,19 @@ int SMBCALL smb_findhash(smb_t* smb, has continue; /* wrong source length */ if(compare[c]->flags&SMB_HASH_MARKED) continue; /* already marked */ - if((compare[c]->flags&SMB_HASH_PROC_MASK)!=(hash.flags&SMB_HASH_PROC_MASK)) + if((compare[c]->flags&SMB_HASH_PROC_COMP_MASK)!=(hash.flags&SMB_HASH_PROC_COMP_MASK)) continue; /* wrong pre-process flags */ if((compare[c]->flags&hash.flags&SMB_HASH_MASK)==0) continue; /* no matching hashes */ - if(compare[c]->flags&hash.flags&SMB_HASH_CRC16 + if((compare[c]->flags&hash.flags&SMB_HASH_CRC16) && compare[c]->crc16!=hash.crc16) continue; /* wrong crc-16 */ - if(compare[c]->flags&hash.flags&SMB_HASH_CRC32 + if((compare[c]->flags&hash.flags&SMB_HASH_CRC32) && compare[c]->crc32!=hash.crc32) continue; /* wrong crc-32 */ - if(compare[c]->flags&hash.flags&SMB_HASH_MD5 + if((compare[c]->flags&hash.flags&SMB_HASH_MD5) && memcmp(compare[c]->md5,hash.md5,sizeof(hash.md5))) - continue; /* wrong crc-16 */ + continue; /* wrong MD5 */ /* successful match! */ break; /* can't match more than one, so stop comparing */ @@ -166,6 +167,22 @@ static char* strip_chars(uchar* dst, con return((char *)dst); } +static char* strip_ctrla(uchar* dst, const uchar* src) +{ + while(*src) { + if(*src==CTRL_A) { + src++; + if(*src) + src++; + } + else + *(dst++)=*(src++); + } + *dst=0; + + return((char *)dst); +} + /* Allocates and calculates hashes of data (based on flags) */ /* Returns NULL on failure */ hash_t* SMBCALL smb_hash(ulong msgnum, ulong t, unsigned source, unsigned flags @@ -173,6 +190,9 @@ hash_t* SMBCALL smb_hash(ulong msgnum, u { hash_t* hash; + if(length==0) /* Don't hash 0-length sources (e.g. empty/blank message bodies) */ + return(NULL); + if((hash=(hash_t*)malloc(sizeof(hash_t)))==NULL) return(NULL); @@ -204,8 +224,10 @@ hash_t* SMBCALL smb_hashstr(ulong msgnum if(flags&SMB_HASH_PROC_MASK) { /* string pre-processing */ if((p=strdup(str))==NULL) return(NULL); + if(flags&SMB_HASH_STRIP_CTRL_A) + strip_ctrla(p,p); if(flags&SMB_HASH_STRIP_WSP) - strip_chars(p,str," \t\r\n"); + strip_chars(p,p," \t\r\n"); if(flags&SMB_HASH_LOWERCASE) strlwr(p); } @@ -218,9 +240,9 @@ hash_t* SMBCALL smb_hashstr(ulong msgnum return(hash); } -/* Allocatese and calculates all hashes for a single message */ +/* Allocates and calculates all hashes for a single message */ /* Returns NULL on failure */ -hash_t** SMBCALL smb_msghashes(smbmsg_t* msg, const uchar* body) +hash_t** SMBCALL smb_msghashes(smbmsg_t* msg, const uchar* body, long source_mask) { size_t h=0; uchar flags=SMB_HASH_CRC16|SMB_HASH_CRC32|SMB_HASH_MD5; @@ -233,22 +255,44 @@ hash_t** SMBCALL smb_msghashes(smbmsg_t* memset(hashes, 0, sizeof(hash_t*)*(SMB_HASH_SOURCE_TYPES+1)); - if(msg->id!=NULL && + if(msg->id!=NULL && (source_mask&(1<hdr.number, t, SMB_HASH_SOURCE_MSG_ID, flags, msg->id))!=NULL) hashes[h++]=hash; - if(msg->ftn_msgid!=NULL && + if(msg->ftn_msgid!=NULL && (source_mask&(1<hdr.number, t, SMB_HASH_SOURCE_FTN_ID, flags, msg->ftn_msgid))!=NULL) hashes[h++]=hash; - flags|=SMB_HASH_STRIP_WSP; - if(body!=NULL && - (hash=smb_hashstr(msg->hdr.number, t, SMB_HASH_SOURCE_BODY, flags, body))!=NULL) + if(body!=NULL && (source_mask&(1<hdr.number, t, SMB_HASH_SOURCE_BODY, flags|SMB_HASH_STRIP_WSP|SMB_HASH_STRIP_CTRL_A, body))!=NULL) hashes[h++]=hash; + if(msg->subj!=NULL && (source_mask&(1<subj; + while(*p) { + char* tp=strchr(p,':'); + char* sp=strchr(p,' '); + if(tp!=NULL && (sp==NULL || tphdr.number, t, SMB_HASH_SOURCE_SUBJECT, flags, p))!=NULL) + hashes[h++]=hash; + } + return(hashes); } +void SMBCALL smb_freehashes(hash_t** hashes) +{ + size_t n; + + FREE_LIST(hashes,n); +} + /* Calculates and stores the hashes for a single message */ int SMBCALL smb_hashmsg(smb_t* smb, smbmsg_t* msg, const uchar* text, BOOL update) { @@ -257,12 +301,12 @@ int SMBCALL smb_hashmsg(smb_t* smb, smbm hash_t found; hash_t** hashes; /* This is a NULL-terminated list of hashes */ - if(smb->status.attr&SMB_EMAIL) + if(smb->status.attr&(SMB_EMAIL|SMB_NOHASH)) return(SMB_SUCCESS); - hashes=smb_msghashes(msg,text); + hashes=smb_msghashes(msg,text,SMB_HASH_SOURCE_DUPE); - if(smb_findhash(smb, hashes, &found, SMB_HASH_SOURCE_ALL, update)==SMB_SUCCESS && !update) { + if(smb_findhash(smb, hashes, &found, SMB_HASH_SOURCE_DUPE, update)==SMB_SUCCESS && !update) { retval=SMB_DUPE_MSG; safe_snprintf(smb->last_error,sizeof(smb->last_error) ,"duplicate %s: %s found in message #%lu" @@ -331,13 +375,13 @@ int SMBCALL smb_getmsghdr_by_hash(smb_t* return(retval); } -ushort SMBCALL smb_subject_crc(const char* subj) +uint16_t SMBCALL smb_subject_crc(const char* subj) { char* str; - ushort crc; + uint16_t crc; if(subj==NULL) - return(0xffff); + return(0); while(!strnicmp(subj,"RE:",3)) { subj+=3; @@ -355,13 +399,13 @@ ushort SMBCALL smb_subject_crc(const cha return(crc); } -ushort SMBCALL smb_name_crc(const char* name) +uint16_t SMBCALL smb_name_crc(const char* name) { char* str; - ushort crc; + uint16_t crc; if(name==NULL) - return(0xffff); + return(0); if((str=strdup(name))==NULL) return(0xffff);