...
 
Commits (4)
  • Rob Swindell's avatar
    Add smb_msg_type() and smb_msg_count() for index-based msg counting. · a3e430e0
    Rob Swindell authored
    In support of message bases with vote-messages and poll-closures:
    
    smb_msg_type() returns an enum smb_msg_type inferred from the combination
    of attribute flags specified (should match msghdr_t.type).
    
    smb_msg_count() calculates the number of message index records of the
    specified type(s) (a bit-field) by reading the message base index file. This
    value should only used for info/display purposes, so no locking is performed
    to return the result as fast as possible.
    
    This allows an accurate number of "posts" (posted *messages*) to be queried
    and displayed to a user when appropriate (e.g. instead of
    smb.status.total_msgs or just the size of the index file divided by the size
    of an index record). In that case, since vote messages and poll closures
    aren't displayed as messages to users, exclude those from the count to reduce
    confusion. For message bases that don't support voting, this scheme is not
    necessary.
    a3e430e0
  • Rob Swindell's avatar
    Use smb_msg_type() to include poll messages in total message count. · c018dfb8
    Rob Swindell authored
    Don't exclude polls form the message count used for max_msgs enforcement
    during maintenance.
    c018dfb8
  • Rob Swindell's avatar
    Use smb_msg_type() to double-check the header type against attribute flags. · 17b7aee1
    Rob Swindell authored
    The inferred message type should match the stored message type. Confirm that.
    17b7aee1
  • Rob Swindell's avatar
    For subs that allow voting, getposts() will exclude vote messages from total. · 39a77d9a
    Rob Swindell authored
    Vote messages and poll closures are not displayed to users as messages, so
    exclude them from the total "posts" returned from getposts(). This uses
    the new smb_msg_count() function which is slower than simply checking the
    size of the index file (*.sid) and dividing by the index record size. So
    for sub-boards that don't support voting, use the old/faster scheme.
    39a77d9a
......@@ -158,7 +158,7 @@ int main(int argc, char **argv)
,hasherr,badhash
,acthdrblocks,actdatblocks
,dfieldlength,dfieldoffset
,dupenum,dupenumhdr,dupeoff,attr,actalloc
,dupenum,dupenumhdr,dupeoff,attr,actalloc,types
,datactalloc,misnumbered,timeerr,idxofferr,idxerr
,subjcrc,fromcrc,tocrc
,intransit,unvalidated
......@@ -349,6 +349,7 @@ int main(int argc, char **argv)
}
headers=deleted=orphan=dupenumhdr=attr=zeronum=timeerr=lockerr=hdrerr=0;
types = 0;
subjcrc=fromcrc=tocrc=0;
hdrnumerr=hdrlenerr=0;
actalloc=datactalloc=deldatblocks=delhdrblocks=xlaterr=0;
......@@ -471,6 +472,13 @@ int main(int argc, char **argv)
}
}
if(msg.hdr.type != smb_msg_type(msg.hdr.attr)) {
fprintf(stderr,"%sMessage type mismatch (%d, expected %d)\n"
,beep, msg.hdr.type, smb_msg_type(msg.hdr.attr));
msgerr=TRUE;
types++;
}
if(!(smb.status.attr&SMB_EMAIL) && chkhash) {
/* Look-up the message hashes */
hashes=smb_msghashes(&msg,(uchar*)body,SMB_HASH_SOURCE_DUPE);
......@@ -1015,6 +1023,10 @@ int main(int argc, char **argv)
printf("%-35.35s (!): %lu\n"
,"Mismatched Header Lengths"
,hdrlenerr);
if(types)
printf("%-35.35s (!): %lu\n"
,"Mismatched Attribute/MsgTypes"
,types);
#define INDXERR "Index/Header Mismatch: "
if(attr)
printf("%-35.35s (!): %lu\n"
......
......@@ -79,14 +79,25 @@ long DLLCALL getfiles(scfg_t* cfg, uint dirnum)
/****************************************************************************/
ulong DLLCALL getposts(scfg_t* cfg, uint subnum)
{
char str[128];
ulong l;
sprintf(str,"%s%s.sid",cfg->sub[subnum]->data_dir,cfg->sub[subnum]->code);
l=(long)flength(str);
if((long)l==-1)
return(0);
return(l/sizeof(idxrec_t));
if(cfg->sub[subnum]->misc & SUB_NOVOTING) {
char path[MAX_PATH + 1];
off_t l;
SAFEPRINTF2(path, "%s%s.sid", cfg->sub[subnum]->data_dir, cfg->sub[subnum]->code);
l = flength(path);
if(l < sizeof(idxrec_t))
return 0;
return l / sizeof(idxrec_t);
}
smb_t smb = {{0}};
SAFEPRINTF2(smb.file, "%s%s", cfg->sub[subnum]->data_dir, cfg->sub[subnum]->code);
smb.retry_time = cfg->smb_retry_time;
smb.subnum = subnum;
if(smb_open_index(&smb) != SMB_SUCCESS)
return 0;
size_t result = smb_msg_count(&smb, (1 << SMB_MSG_TYPE_NORMAL) | (1 << SMB_MSG_TYPE_POLL));
smb_close(&smb);
return result;
}
BOOL inc_sys_upload_stats(scfg_t* cfg, ulong files, ulong bytes)
......
......@@ -779,7 +779,8 @@ void maint(void)
printf("Scanning for read messages to be killed...\n");
uint32_t total_msgs = 0;
for(m=f=0;m<l;m++) {
if(!(idx[m].attr&(MSG_POLL|MSG_VOTE)))
enum smb_msg_type type = smb_msg_type(idx[m].attr);
if(type == SMB_MSG_TYPE_NORMAL || type == SMB_MSG_TYPE_POLL)
total_msgs++;
// printf("\r%2lu%%",m ? (long)(100.0/((float)l/m)) : 0);
if(idx[m].attr&(MSG_PERMANENT|MSG_DELETE))
......
......@@ -365,6 +365,8 @@ typedef struct _PACK { /* Time with time-zone */
} when_t;
typedef uint16_t smb_msg_attr_t;
typedef struct _PACK { /* Index record */
union {
......@@ -378,7 +380,7 @@ typedef struct _PACK { /* Index record */
uint32_t remsg; /* number of message this vote is in response to */
};
};
uint16_t attr; /* attributes (read, permanent, etc.) */
smb_msg_attr_t attr; /* attributes (read, permanent, etc.) */
uint32_t offset; /* byte-offset of msghdr in header file */
uint32_t number; /* number of message (1 based) */
uint32_t time; /* time/date message was imported/posted */
......
......@@ -2141,4 +2141,46 @@ uint32_t SMBCALL smb_last_in_thread(smb_t* smb, smbmsg_t* remsg)
return smb_last_in_branch(smb, &msg);
}
SMBEXPORT enum smb_msg_type smb_msg_type(smb_msg_attr_t attr)
{
switch (attr&MSG_POLL_VOTE_MASK) {
case 0:
return SMB_MSG_TYPE_NORMAL;
case MSG_POLL:
return SMB_MSG_TYPE_POLL;
case MSG_POLL_CLOSURE:
return SMB_MSG_TYPE_POLL_CLOSURE;
default:
return SMB_MSG_TYPE_BALLOT;
}
}
// Return count of messages of the desired types (bit-mask), as read from index
// Does so as fast as possible, without locking
SMBEXPORT size_t SMBCALL smb_msg_count(smb_t* smb, unsigned types)
{
off_t index_length = filelength(fileno(smb->sid_fp));
if(index_length < sizeof(idxrec_t))
return 0;
uint32_t total = index_length / sizeof(idxrec_t);
if(total < 1)
return 0;
idxrec_t* idx;
if((idx = calloc(total, sizeof(*idx))) == NULL)
return 0;
rewind(smb->sid_fp);
size_t result = fread(idx, sizeof(*idx), total, smb->sid_fp);
size_t count = 0;
for(size_t i = 0; i < result; i++) {
if(types & (1 << smb_msg_type(idx[i].attr)))
count++;
}
free(idx);
return count;
}
/* End of SMBLIB.C */
......@@ -190,6 +190,8 @@ SMBEXPORT uint32_t SMBCALL smb_next_in_thread(smb_t*, smbmsg_t*, msghdr_t*);
SMBEXPORT uint32_t SMBCALL smb_last_in_branch(smb_t*, smbmsg_t*);
SMBEXPORT uint32_t SMBCALL smb_last_in_thread(smb_t*, smbmsg_t*);
SMBEXPORT BOOL SMBCALL smb_msg_is_utf8(const smbmsg_t*);
SMBEXPORT size_t SMBCALL smb_msg_count(smb_t*, unsigned types);
SMBEXPORT enum smb_msg_type smb_msg_type(smb_msg_attr_t);
/* smbadd.c */
SMBEXPORT int SMBCALL smb_addmsg(smb_t* smb, smbmsg_t* msg, int storage, long dupechk_hashes
......