Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commit b14e9904 authored by rswindell's avatar rswindell

Added new sub-scan mode: SCAN_POLLS (used to scan sub-boards for posted polls)

Introduced a better progress indicator (similar to poll results), using the
backfill() method. 2 new attr.cfg fields allow the progress indicator colors to
be configured separately from poll results (though they default to the same
white on magenta). This new progress indicator is used when loading msg ptrs
and scanning for votes. I will be using it while performing other searches
(e.g. file libraries/dirs) as well.
parent c8e1925b
......@@ -576,6 +576,7 @@ var SCAN_TOYOU =(1<<3); /* Display messages to you only */
var SCAN_FIND =(1<<4); /* Find text in messages */
var SCAN_UNREAD =(1<<5); /* Display un-read messages to you only */
var SCAN_MSGSONLY =(1<<6); /* Do not do a new file scan even if the */
var SCAN_POLLS =(1<<7); /* Scan for polls only (no messages) */
/* user enabled Automatic New File Scan */
/********************************************/
......
......@@ -619,23 +619,37 @@ bool sbbs_t::msgabort()
return(false);
}
int sbbs_t::backfill(const char* str, float pct)
int sbbs_t::backfill(const char* instr, float pct, int full_attr, int empty_attr)
{
uint8_t atr;
int atr;
int save_atr = curatr;
int len;
if(!term_supports(ANSI))
return bputs(str);
char* str = strip_ctrl(instr, NULL);
len = strlen(str);
for(int i=0; i<len; i++) {
if(((float)(i+1) / len)*100.0 <= pct)
atr = cfg.color[clr_backfill];
else
atr = cfg.color[clr_unfill];
if(curatr != atr) attr(atr);
outchar(str[i]);
if(!term_supports(ANSI))
bputs(str);
else {
for(int i=0; i<len; i++) {
if(((float)(i+1) / len)*100.0 <= pct)
atr = full_attr;
else
atr = empty_attr;
if(curatr != atr) attr(atr);
outchar(str[i]);
}
attr(save_atr);
}
attr(LIGHTGRAY);
free(str);
return len;
}
void sbbs_t::progress(const char* text, int count, int total)
{
char str[128];
if(text == NULL) text = "";
float pct = ((float)count/total)*100.0F;
SAFEPRINTF2(str, "[ %-8s %4.1f%% ]", text, pct);
cursor_left(backfill(str, pct, cfg.color[clr_progress_full], cfg.color[clr_progress_empty]));
}
/* data_ovl.cpp */
/* Synchronet hi-level data access routines */
/* $Id$ */
......@@ -37,6 +35,12 @@
#include "sbbs.h"
static void ProgressLoadingMsgPtrs(void* cbdata, int count, int total)
{
sbbs_t* sbbs = ((sbbs_t*)cbdata);
sbbs->progress(sbbs->text[LoadingMsgPtrs], count, total);
}
/****************************************************************************/
/* Fills the 'ptr' element of the each element of the cfg.sub[] array of sub_t */
/* and the sub_cfg and sub_ptr global variables */
......@@ -46,8 +50,7 @@ void sbbs_t::getmsgptrs()
{
if(!useron.number)
return;
bputs(text[LoadingMsgPtrs]);
::getmsgptrs(&cfg,&useron,subscan);
::getmsgptrs(&cfg,&useron,subscan,ProgressLoadingMsgPtrs,this);
bputs(text[LoadedMsgPtrs]);
}
......
......@@ -237,11 +237,11 @@ void sbbs_t::show_msg(smbmsg_t* msg, long mode, post_t* post)
if(results_visible) {
safe_snprintf(str, sizeof(str), text[PollAnswerFmt]
,width, width, answer, post->votes[answers], pct);
backfill(str, pct);
backfill(str, pct, cfg.color[clr_votes_full], cfg.color[clr_votes_empty]);
if(msg->user_voted&(1<<answers))
bputs(text[PollAnswerChecked]);
} else {
attr(cfg.color[clr_unfill]);
attr(cfg.color[clr_votes_empty]);
bputs(answer);
}
CRLF;
......
......@@ -331,7 +331,8 @@ BOOL read_attr_cfg(scfg_t* cfg, char* error)
}
/* Setup default colors here: */
memset(cfg->color,LIGHTGRAY|HIGH,MIN_COLORS);
cfg->color[clr_backfill] = WHITE|BG_MAGENTA;
cfg->color[clr_votes_full] = WHITE|BG_MAGENTA;
cfg->color[clr_progress_full] = CYAN|HIGH|BG_BLUE;
for(cfg->total_colors=0;!feof(instream) && !ferror(instream);cfg->total_colors++) {
if(readline(&offset,str,4,instream)==NULL)
break;
......
......@@ -196,7 +196,6 @@ void sbbs_t::msghdr(smbmsg_t* msg)
/****************************************************************************/
post_t * sbbs_t::loadposts(uint32_t *posts, uint subnum, ulong ptr, long mode, ulong *unvalidated_num, uint32_t* visible)
{
char name[128];
ushort aliascrc,namecrc,sysop;
int i,skip;
ulong l=0,total,alloc_len;
......@@ -222,12 +221,8 @@ post_t * sbbs_t::loadposts(uint32_t *posts, uint subnum, ulong ptr, long mode, u
return(NULL);
}
strcpy(name,useron.name);
strlwr(name);
namecrc=crc16(name,0);
strcpy(name,useron.alias);
strlwr(name);
aliascrc=crc16(name,0);
namecrc=smb_name_crc(useron.name);
aliascrc=smb_name_crc(useron.alias);
sysop=crc16("sysop",0);
rewind(smb.sid_fp);
......@@ -251,6 +246,9 @@ post_t * sbbs_t::loadposts(uint32_t *posts, uint subnum, ulong ptr, long mode, u
if(idx.number==0) /* invalid message number, ignore */
continue;
if(mode&LP_NOMSGS && (idx.attr&MSG_POLL_VOTE_MASK) == 0)
continue;
if(idx.attr&MSG_DELETE) { /* Pre-flagged */
if(mode&LP_REP) /* Don't include deleted msgs in REP pkt */
continue;
......@@ -457,7 +455,7 @@ int sbbs_t::scanposts(uint subnum, long mode, const char *find)
if(mode&(SCAN_NEW|SCAN_TOYOU))
bprintf(text[NScanStatusFmt]
,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname,0L,0L);
else
else if(!(mode&SCAN_POLLS))
bprintf(text[NoMsgsOnSub]
,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->sname);
return(0);
......@@ -492,6 +490,8 @@ int sbbs_t::scanposts(uint subnum, long mode, const char *find)
lp|=LP_UNREAD;
if(!(cfg.sub[subnum]->misc&SUB_NOVOTING))
lp|=LP_POLLS;
if(mode&SCAN_POLLS)
lp|=LP_NOMSGS;
post=loadposts(&smb.msgs,subnum,0,lp,&unvalidated);
if(mode&SCAN_NEW) { /* Scanning for new messages */
for(smb.curmsg=0;smb.curmsg<smb.msgs;smb.curmsg++)
......@@ -516,11 +516,12 @@ int sbbs_t::scanposts(uint subnum, long mode, const char *find)
}
}
else {
cleartoeol();
if(mode&SCAN_TOYOU)
bprintf(text[NScanStatusFmt]
,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname,smb.msgs,msgs);
if(!smb.msgs) {
if(!(mode&SCAN_TOYOU))
if(!(mode&SCAN_TOYOU|SCAN_POLLS))
bprintf(text[NoMsgsOnSub]
,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->sname);
smb_close(&smb);
......@@ -533,7 +534,7 @@ int sbbs_t::scanposts(uint subnum, long mode, const char *find)
domsg=1;
smb.curmsg=0;
}
else if(mode&SCAN_TOYOU)
else if(mode&(SCAN_TOYOU|SCAN_POLLS))
smb.curmsg=0;
else {
for(smb.curmsg=0;smb.curmsg<smb.msgs;smb.curmsg++)
......@@ -1381,7 +1382,7 @@ int sbbs_t::scanposts(uint subnum, long mode, const char *find)
if(post)
free(post);
if(!quit
&& !(org_mode&(SCAN_CONST|SCAN_TOYOU|SCAN_FIND)) && !(cfg.sub[subnum]->misc&SUB_PONLY)
&& !(org_mode&(SCAN_CONST|SCAN_TOYOU|SCAN_FIND|SCAN_POLLS)) && !(cfg.sub[subnum]->misc&SUB_PONLY)
&& reads && chk_ar(cfg.sub[subnum]->post_ar,&useron,&client) && text[Post][0]
&& !(useron.rest&FLAG('P'))) {
sprintf(str,text[Post],cfg.grp[cfg.sub[subnum]->grp]->sname
......
......@@ -673,7 +673,8 @@ public:
void cursor_left(int count=1);
void cursor_right(int count=1);
long term_supports(long cmp_flags=0);
int backfill(const char* str, float pct);
int backfill(const char* str, float pct, int full_attr, int empty_attr);
void progress(const char* str, int count, int total);
/* getstr.cpp */
size_t getstr_offset;
......
......@@ -332,8 +332,10 @@ enum {
,clr_chatremote
,clr_multichat
,clr_external
,clr_backfill
,clr_unfill
,clr_votes_full
,clr_votes_empty
,clr_progress_full
,clr_progress_empty
,MIN_COLORS
};
......@@ -746,6 +748,7 @@ typedef enum { /* Values for xtrn_t.event */
#define LP_REP (1<<4) /* Packing REP packet */
#define LP_POLLS (1<<5) /* Include polls */
#define LP_VOTES (1<<6) /* Include votes */
#define LP_NOMSGS (1<<7) /* Don't include regular messages */
/* Bits in the mode of loadmail() */
#define LM_UNREAD (1<<0) /* Include un-read mail only */
......@@ -817,14 +820,15 @@ enum XFER_TYPE { /* Values for type in xfer_prot_select() */
#define LOL_SIZE 81 /* Length of each logon list entry */
/* Bits in mode of scanposts() function */
#define SCAN_CONST (1<<0) /* Continuous message scanning */
#define SCAN_NEW (1<<1) /* New scanning */
#define SCAN_BACK (1<<2) /* Scan the last message if no new */
#define SCAN_TOYOU (1<<3) /* Scan for messages to you */
#define SCAN_FIND (1<<4) /* Scan for text in messages */
#define SCAN_UNREAD (1<<5) /* Display un-read messages only */
#define SCAN_CONST (1<<0) /* Continuous message scanning */
#define SCAN_NEW (1<<1) /* New scanning */
#define SCAN_BACK (1<<2) /* Scan the last message if no new */
#define SCAN_TOYOU (1<<3) /* Scan for messages to you */
#define SCAN_FIND (1<<4) /* Scan for text in messages */
#define SCAN_UNREAD (1<<5) /* Display un-read messages only */
#define SCAN_MSGSONLY (1<<6) /* Do not do a new file scan even if the
* user enabled Automatic New File Scan */
#define SCAN_POLLS (1<<7) /* Scan for polls (only) */
/* Bits in misc of chan_t */
#define CHAN_PW (1<<0) /* Can be password protected */
......
......@@ -118,15 +118,21 @@ void sbbs_t::scansubs(long mode)
menu("msgscan");
}
for(i=0;i<usrsubs[curgrp] && !msgabort();i++) {
if(((mode&SCAN_NEW &&
(subscan[usrsub[curgrp][i]].cfg&SUB_CFG_NSCAN
|| cfg.sub[usrsub[curgrp][i]]->misc&SUB_FORCED))
|| (mode&SCAN_TOYOU && subscan[usrsub[curgrp][i]].cfg&SUB_CFG_SSCAN)
|| mode&SCAN_FIND)) {
if(scanposts(usrsub[curgrp][i],mode,str))
break;
subs_scanned++;
}
if((mode&SCAN_NEW) && !(subscan[usrsub[curgrp][i]].cfg&SUB_CFG_NSCAN) && !(cfg.sub[usrsub[curgrp][i]]->misc&SUB_FORCED))
continue;
if((mode&SCAN_TOYOU) && !(subscan[usrsub[curgrp][i]].cfg&SUB_CFG_SSCAN))
continue;
if((mode&SCAN_POLLS) && cfg.sub[usrsub[curgrp][i]]->misc&SUB_NOVOTING)
continue;
if(mode&SCAN_POLLS)
progress("Scanning", i, usrsubs[curgrp]);
if(scanposts(usrsub[curgrp][i],mode,str))
break;
subs_scanned++;
}
if(mode&SCAN_POLLS) {
progress("Done", subs_scanned, usrsubs[curgrp]);
cleartoeol();
}
bputs(text[MessageScan]);
if(i==usrsubs[curgrp]) bprintf(text[MessageScanComplete],subs_scanned);
......@@ -146,6 +152,8 @@ void sbbs_t::scanallsubs(long mode)
char tmp[512];
uint i,j,found=0;
ulong subs_scanned=0;
uint* sub;
ulong total_subs=0;
bool subj_only=false;
if(cfg.scansubs_mod[0] && !scansubs_inside) {
......@@ -201,22 +209,35 @@ void sbbs_t::scanallsubs(long mode)
if(useron.misc&(RIP|WIP|HTML) && !(useron.misc&EXPERT)) {
menu("msgscan");
}
for(i=0;i<usrgrps;i++) {
for(j=0;j<usrsubs[i] && !msgabort();j++) {
if(((mode&SCAN_NEW && subscan[usrsub[i][j]].cfg&SUB_CFG_NSCAN)
|| cfg.sub[usrsub[i][j]]->misc&SUB_FORCED
|| mode&SCAN_FIND
|| (mode&SCAN_TOYOU && subscan[usrsub[i][j]].cfg&SUB_CFG_SSCAN))) {
if(scanposts(usrsub[i][j],mode,str))
break;
subs_scanned++;
}
if((sub = (uint*)malloc(sizeof(uint) * cfg.total_subs)) == NULL) {
errormsg(WHERE, ERR_ALLOC, "subs", sizeof(uint)*cfg.total_subs);
return;
}
for(i=0; i<usrgrps; i++)
for(j=0; j<usrsubs[i]; j++) {
if((mode&SCAN_NEW) && !(subscan[usrsub[i][j]].cfg&SUB_CFG_NSCAN) && !(cfg.sub[usrsub[i][j]]->misc&SUB_FORCED))
continue;
if((mode&SCAN_TOYOU) && !(subscan[usrsub[i][j]].cfg&SUB_CFG_SSCAN))
continue;
if((mode&SCAN_POLLS) && cfg.sub[usrsub[i][j]]->misc&SUB_NOVOTING)
continue;
sub[total_subs++] = usrsub[i][j];
}
if(j<usrsubs[i])
break;
for(i=0; i<total_subs && !msgabort(); i++) {
if(mode&SCAN_POLLS)
progress("Scanning", i, total_subs);
if(scanposts(sub[i],mode,str))
break;
}
subs_scanned = i;
free(sub);
if(mode&SCAN_POLLS) {
progress("Done", subs_scanned, total_subs);
cleartoeol();
}
bputs(text[MessageScan]);
if(i<usrgrps) {
if(subs_scanned<total_subs) {
bputs(text[MessageScanAborted]);
return;
}
......
......@@ -429,7 +429,7 @@ js_login(JSContext *cx, uintN argc, jsval *arglist)
lprintf(LOG_CRIT,"!MALLOC FAILURE");
}
if(client->subscan!=NULL) {
getmsgptrs(&scfg,&client->user,client->subscan);
getmsgptrs(&scfg,&client->user,client->subscan,NULL,NULL);
}
JS_RESUMEREQUEST(cx, rc);
......
......@@ -2991,7 +2991,7 @@ ulong DLLCALL loginBanned(scfg_t* cfg, link_list_t* list, SOCKET sock, const cha
/****************************************************************************/
/* Message-new-scan pointer/configuration functions */
/****************************************************************************/
BOOL DLLCALL getmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan)
BOOL DLLCALL getmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan, void (*progress)(void*, int, int), void* cbdata)
{
char path[MAX_PATH+1];
uint i;
......@@ -3015,17 +3015,19 @@ BOOL DLLCALL getmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan)
return 0;
if(user->rest&FLAG('G'))
return initmsgptrs(cfg, subscan, cfg->guest_msgscan_init);
return initmsgptrs(cfg, subscan, cfg->guest_msgscan_init, progress, cbdata);
SAFEPRINTF2(path,"%suser/ptrs/%4.4u.ixb", cfg->data_dir, user->number);
if((stream=fnopen(&file,path,O_RDONLY))==NULL) {
if(fexist(path))
return(FALSE); /* file exists, but couldn't be opened? */
return initmsgptrs(cfg, subscan, cfg->new_msgscan_init);
return initmsgptrs(cfg, subscan, cfg->new_msgscan_init, progress, cbdata);
}
length=(long)filelength(file);
for(i=0;i<cfg->total_subs;i++) {
if(progress != NULL)
progress(cbdata, i, cfg->total_subs);
if(length>=(cfg->sub[i]->ptridx+1)*10L) {
fseek(stream,(long)cfg->sub[i]->ptridx*10L,SEEK_SET);
fread(&subscan[i].ptr,sizeof(subscan[i].ptr),1,stream);
......@@ -3102,7 +3104,7 @@ BOOL DLLCALL putmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan)
/* Initialize new-msg-scan pointers (e.g. for new users) */
/* If 'days' is specified as 0, just set pointer to last message (faster) */
/****************************************************************************/
BOOL DLLCALL initmsgptrs(scfg_t* cfg, subscan_t* subscan, unsigned days)
BOOL DLLCALL initmsgptrs(scfg_t* cfg, subscan_t* subscan, unsigned days, void (*progress)(void*, int, int), void* cbdata)
{
uint i;
smb_t smb;
......@@ -3110,6 +3112,8 @@ BOOL DLLCALL initmsgptrs(scfg_t* cfg, subscan_t* subscan, unsigned days)
time_t t = time(NULL) - (days * 24 * 60 * 60);
for(i=0;i<cfg->total_subs;i++) {
if(progress != NULL)
progress(cbdata, i, cfg->total_subs);
if(days == 0) {
/* This value will be "fixed" (changed to the last msg) when saving */
subscan[i].ptr = ~0;
......
......@@ -125,10 +125,10 @@ DLLEXPORT BOOL DLLCALL filter_ip(scfg_t*, const char* prot, const char* reason,
,const char* ip_addr, const char* username, const char* fname);
/* New-message-scan pointer functions: */
DLLEXPORT BOOL DLLCALL getmsgptrs(scfg_t*, user_t*, subscan_t*);
DLLEXPORT BOOL DLLCALL getmsgptrs(scfg_t*, user_t*, subscan_t*, void (*progress)(void*, int, int), void* cbdata);
DLLEXPORT BOOL DLLCALL putmsgptrs(scfg_t*, user_t*, subscan_t*);
DLLEXPORT BOOL DLLCALL fixmsgptrs(scfg_t*, subscan_t*);
DLLEXPORT BOOL DLLCALL initmsgptrs(scfg_t*, subscan_t*, unsigned days);
DLLEXPORT BOOL DLLCALL initmsgptrs(scfg_t*, subscan_t*, unsigned days, void (*progress)(void*, int, int), void* cbdata);
/* New atomic numeric user field adjustment functions: */
......
......@@ -1524,7 +1524,7 @@ void http_logon(http_session_t * session, user_t *usr)
lprintf(LOG_DEBUG,"%04d HTTP Logon (user #%d)",session->socket,session->user.number);
if(session->subscan!=NULL)
getmsgptrs(&scfg,&session->user,session->subscan);
getmsgptrs(&scfg,&session->user,session->subscan,NULL,NULL);
session->logon_time=time(NULL);
if(session->user.number==0)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment