Commit 1cac2c8a authored by Rob Swindell's avatar Rob Swindell 💬
Browse files

Support user credits and transfer stats > 4GB in total

Credits and daily free credits are accurate to the byte up to (a maximum) of 18446744073709551615 (that's 18 Exbibytes - 1).

User's upload and download byte stats are now similarly extended in maximum range, but the accuracy is only "to the byte" for values less than 10,000,000,000. Beyond that value, the accuracy declines, but is generally pretty damn accurate (to 4 decimal places beyond the nearest multiple of a power of 1024), so I don't expect that to be an issue. This method of storing upload/download byte stats allowed me to use the same 10-character user record fields in the user.dat file.

As a side-effect of this enhancements:
* User and file credit values are now expressed in multiples of powers of 1024 (e.g. 4.0G rather than 4,294,967,296).
* Free credits per day per security level has now been extended from 32 to 64-bits (to accommodate values >= 4GB).
* adjustuserrec() now longer takes the record length since we can easily determine that automatically and don't need more "sources of truth" that can be out-of-sync (e.g. the U_CDT field length going from 10 to 20 chars with this change).
* setting the stage for locale-dependent thousands-separators (e.g. space instead of comma) - currently still hard-coded to comma
* more/better support for files > 4GB in size (e.g. in the batch download queue)
* user_t ulong fields changed to either uint32_t or uint64_t - I didn't realize how many long/ulong's remained in the code (which are sometmies 32-bit, sometimes 64-bit) - ugh
* Steve's ultoac() function renamed to u32toac() and created a C++ wrapper that still uses the old name, for homage
parent da2177b7
Pipeline #2920 failed with stage
in 10 minutes and 32 seconds
......@@ -1175,12 +1175,12 @@ const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen, long* pmode, bool
}
if(!strcmp(sp,"UPBYTES")) {
safe_snprintf(str,maxlen,"%lu",useron.ulb);
safe_snprintf(str,maxlen,"%" PRIu64,useron.ulb);
return(str);
}
if(!strcmp(sp,"UPK")) {
safe_snprintf(str,maxlen,"%lu",useron.ulb/1024L);
safe_snprintf(str,maxlen,"%" PRIu64,useron.ulb/1024L);
return(str);
}
......@@ -1190,12 +1190,12 @@ const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen, long* pmode, bool
}
if(!strcmp(sp,"DLBYTES")) {
safe_snprintf(str,maxlen,"%lu",useron.dlb);
safe_snprintf(str,maxlen,"%" PRIu64,useron.dlb);
return(str);
}
if(!strcmp(sp,"DOWNK")) {
safe_snprintf(str,maxlen,"%lu",useron.dlb/1024L);
safe_snprintf(str,maxlen,"%" PRIu64,useron.dlb/1024L);
return(str);
}
......@@ -1247,37 +1247,37 @@ const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen, long* pmode, bool
/* MAXDL */
if(!strcmp(sp,"MAXDK") || !strcmp(sp,"DLKLIMIT") || !strcmp(sp,"KBLIMIT")) {
safe_snprintf(str,maxlen,"%lu",cfg.level_freecdtperday[useron.level]/1024L);
safe_snprintf(str,maxlen,"%" PRIu64,cfg.level_freecdtperday[useron.level]/1024L);
return(str);
}
if(!strcmp(sp,"DAYBYTES")) { /* amt of free cdts used today */
safe_snprintf(str,maxlen,"%lu",cfg.level_freecdtperday[useron.level]-useron.freecdt);
safe_snprintf(str,maxlen,"%" PRIu64,cfg.level_freecdtperday[useron.level]-useron.freecdt);
return(str);
}
if(!strcmp(sp,"BYTELIMIT")) {
safe_snprintf(str,maxlen,"%ld", (long)cfg.level_freecdtperday[useron.level]);
safe_snprintf(str,maxlen,"%" PRIu64, cfg.level_freecdtperday[useron.level]);
return(str);
}
if(!strcmp(sp,"KBLEFT")) {
safe_snprintf(str,maxlen,"%lu",(useron.cdt+useron.freecdt)/1024L);
safe_snprintf(str,maxlen,"%" PRIu64,(useron.cdt+useron.freecdt)/1024ULL);
return(str);
}
if(!strcmp(sp,"BYTESLEFT")) {
safe_snprintf(str,maxlen,"%lu",useron.cdt+useron.freecdt);
safe_snprintf(str,maxlen,"%" PRIu64,useron.cdt+useron.freecdt);
return(str);
}
if(strcmp(sp, "CREDITS") == 0) {
safe_snprintf(str, maxlen, "%lu", useron.cdt);
safe_snprintf(str, maxlen, "%" PRIu64, useron.cdt);
return str;
}
if(strcmp(sp, "FREECDT") == 0) {
safe_snprintf(str, maxlen, "%lu", useron.freecdt);
safe_snprintf(str, maxlen, "%" PRIu64, useron.freecdt);
return str;
}
......@@ -1716,11 +1716,11 @@ const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen, long* pmode, bool
else if(!strcmp(sp,"ULS"))
safe_snprintf(str,maxlen,"%lu", (ulong)stats.uls);
else if(!strcmp(sp,"ULB"))
safe_snprintf(str,maxlen,"%lu", (ulong)stats.ulb);
safe_snprintf(str,maxlen,"%" PRIu64, stats.ulb);
else if(!strcmp(sp,"DLS"))
safe_snprintf(str,maxlen,"%lu", (ulong)stats.dls);
else if(!strcmp(sp,"DLB"))
safe_snprintf(str,maxlen,"%lu", (ulong)stats.dlb);
safe_snprintf(str,maxlen,"%" PRIu64, stats.dlb);
else if(!strcmp(sp,"PTODAY"))
safe_snprintf(str,maxlen,"%lu", (ulong)stats.ptoday);
else if(!strcmp(sp,"ETODAY"))
......
......@@ -124,10 +124,10 @@ void sbbs_t::batchmenu()
getfiletime(&cfg, &f);
bprintf(text[DownloadQueueLstFmt],i+1
,filename
,i64toac(f.cost, tmp)
,i64toac(f.size, str)
,byte_estimate_to_str(f.cost, tmp, sizeof(tmp), 1, 1)
,byte_estimate_to_str(f.size, str, sizeof(str), 1, 1)
,cur_cps
? sectostr((uint)(f.size/(ulong)cur_cps),tmp2)
? sectostr((uint)(f.size/(uint64_t)cur_cps), tmp2)
: "??:??:??"
,datestr(f.time)
);
......@@ -136,9 +136,9 @@ void sbbs_t::batchmenu()
smb_freefilemem(&f);
}
bprintf(text[DownloadQueueTotals]
,ultoac((ulong)totalcdt,tmp),ultoac((ulong)totalsize,str),cur_cps
? sectostr((ulong)totalsize/(ulong)cur_cps,tmp2)
: "??:??:??");
,byte_estimate_to_str(totalcdt, tmp, sizeof(tmp), 1, 1)
,byte_estimate_to_str(totalsize, str, sizeof(tmp), 1, 1)
,cur_cps ? sectostr((uint)(totalsize/(uint64_t)cur_cps), tmp2) : "??:??:??");
} else
bputs(text[DownloadQueueIsEmpty]);
iniFreeStringList(filenames);
......@@ -253,7 +253,7 @@ BOOL sbbs_t::start_batch_download()
return result;
}
int64_t totalcdt = 0;
uint64_t totalcdt = 0;
for(size_t i=0; filenames[i] != NULL; ++i) {
file_t f = {{}};
if(batch_file_load(&cfg, ini, filenames[i], &f)) {
......@@ -261,9 +261,9 @@ BOOL sbbs_t::start_batch_download()
smb_freefilemem(&f);
}
}
if(totalcdt > (int64_t)(useron.cdt+useron.freecdt)) {
if(totalcdt > useron.cdt+useron.freecdt) {
bprintf(text[YouOnlyHaveNCredits]
,ultoac(useron.cdt+useron.freecdt,tmp));
,u64toac(useron.cdt+useron.freecdt,tmp));
iniFreeStringList(ini);
iniFreeStringList(filenames);
return(FALSE);
......@@ -690,7 +690,7 @@ bool sbbs_t::addtobatdl(file_t* f)
totalcost += f->cost;
if(totalcost > useron.cdt+useron.freecdt) {
bprintf(text[CantAddToQueue],f->name);
bprintf(text[YouOnlyHaveNCredits],ultoac(useron.cdt+useron.freecdt,tmp));
bprintf(text[YouOnlyHaveNCredits],u64toac(useron.cdt+useron.freecdt,tmp));
} else {
totalsize += f->size;
if(!(cfg.dir[f->dir]->misc&DIR_TFREE) && cur_cps)
......@@ -701,9 +701,10 @@ bool sbbs_t::addtobatdl(file_t* f)
} else {
if(batch_file_add(&cfg, useron.number, XFER_BATCH_DOWNLOAD, f)) {
bprintf(text[FileAddedToBatDlQueue]
,f->name, strListCount(filenames) + 1, cfg.max_batdn, i64toac(totalcost,tmp)
,i64toac(totalsize,tmp2)
,sectostr((ulong)(totalsize/MAX((ulong)cur_cps, 1)),str));
,f->name, strListCount(filenames) + 1, cfg.max_batdn
,byte_estimate_to_str(totalcost, tmp, sizeof(tmp), 1, 1)
,byte_estimate_to_str(totalsize, tmp2, sizeof(tmp2), 1, 1)
,sectostr((uint)(totalsize/MAX((uint64_t)cur_cps, 1)),str));
result = true;
}
}
......
......@@ -1666,7 +1666,7 @@ void sbbs_t::guruchat(char* line, char* gurubuf, int gurunum, char* last_answer)
break;
case 'D':
if(sys_status&SS_USERON) {
SAFECAT(theanswer,ultoac(useron.dlb,tmp));
SAFECAT(theanswer,u64toac(useron.dlb,tmp));
} else {
SAFECAT(theanswer,"0");
}
......@@ -1730,7 +1730,7 @@ void sbbs_t::guruchat(char* line, char* gurubuf, int gurunum, char* last_answer)
break;
case 'U':
if(sys_status&SS_USERON) {
SAFECAT(theanswer,ultoac(useron.ulb,tmp));
SAFECAT(theanswer,u64toac(useron.ulb,tmp));
} else {
SAFECAT(theanswer,"0");
}
......@@ -1751,7 +1751,7 @@ void sbbs_t::guruchat(char* line, char* gurubuf, int gurunum, char* last_answer)
break;
case '$': /* Credits */
if(sys_status&SS_USERON) {
SAFECAT(theanswer,ultoac(useron.cdt,tmp));
SAFECAT(theanswer,u64toac(useron.cdt,tmp));
} else {
SAFECAT(theanswer,"0");
}
......
......@@ -25,7 +25,7 @@ bool sbbs_t::ar_exp(const uchar **ptrptr, user_t* user, client_t* client)
{
bool result,_not,_or,equal;
uint i,n,artype,age;
ulong l;
uint64_t l;
struct tm tm;
const char* p;
......@@ -294,7 +294,7 @@ bool sbbs_t::ar_exp(const uchar **ptrptr, user_t* user, client_t* client)
}
break;
case AR_CREDIT:
l=(ulong)i*1024UL;
l = i * 1024UL;
if((equal && user->cdt+user->freecdt!=l)
|| (!equal && user->cdt+user->freecdt<l))
result=_not;
......@@ -303,7 +303,7 @@ bool sbbs_t::ar_exp(const uchar **ptrptr, user_t* user, client_t* client)
(*ptrptr)++;
if(!result) {
noaccess_str=text[NoAccessCredit];
noaccess_val=l;
noaccess_val=(long)l;
}
break;
case AR_NODE:
......
......@@ -225,8 +225,8 @@ ulong sbbs_t::gettimeleft(bool handle_out_of_time)
SAFEPRINTF(tmp,text[Convert100ktoNminQ],cfg.cdt_min_value);
if(yesno(tmp)) {
logline(" ","Credit to Minute Conversion");
useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,cfg.cdt_min_value);
useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,-(102400L));
useron.min=(uint32_t)adjustuserrec(&cfg,useron.number,U_MIN,cfg.cdt_min_value);
useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,-(102400LL));
SAFEPRINTF(str,"Credit Adjustment: %ld",-(102400L));
logline("$-",str);
SAFEPRINTF(str,"Minute Adjustment: %u",cfg.cdt_min_value);
......
......@@ -68,7 +68,7 @@ void sbbs_t::notdownloaded(off_t size, time_t start, time_t end)
&& end-start>=(double)(size/cur_cps)*(double)cfg.leech_pct/100.0) {
lprintf(LOG_ERR, "Node %d Possible use of leech protocol (leech=%u downloads=%u)"
,cfg.node_num, useron.leech+1,useron.dls);
useron.leech=(uchar)adjustuserrec(&cfg,useron.number,U_LEECH,2,1);
useron.leech=(uchar)adjustuserrec(&cfg,useron.number,U_LEECH,1);
}
}
......@@ -393,8 +393,8 @@ bool sbbs_t::sendfile(char* fname, char prot, const char* desc, bool autohang)
off_t length = flength(fname);
logon_dlb += length; /* Update stats */
logon_dls++;
useron.dls = (ushort)adjustuserrec(&cfg, useron.number, U_DLS, 5, 1);
useron.dlb = adjustuserrec(&cfg,useron.number, U_DLB, 10, (long)length);
useron.dls = (ushort)adjustuserrec(&cfg, useron.number, U_DLS, 1);
useron.dlb = (uint32_t)adjustuserrec(&cfg,useron.number, U_DLB, length);
char bytes[32];
ultoac((ulong)length, bytes);
bprintf(text[FileNBytesSent], getfname(fname), bytes);
......
......@@ -1433,12 +1433,12 @@ int sbbs_t::exec(csi_t *csi)
if(l<0)
subtract_cdt(&cfg,&useron,-l);
else
useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,l);
useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,l);
csi->ip+=2;
return(0);
case CS_ADJUST_USER_MINUTES:
i=*(short *)csi->ip;
useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,i);
useron.min=(uint32_t)adjustuserrec(&cfg,useron.number,U_MIN,i);
csi->ip+=2;
return(0);
case CS_GETNUM:
......
......@@ -39,11 +39,11 @@ void sbbs_t::showfileinfo(file_t* f, bool show_extdesc)
bprintf(P_TRUNCATE, text[FiFilename],f->name);
if(getfilesize(&cfg, f) >= 0)
bprintf(P_TRUNCATE, text[FiFileSize], i64toac(f->size,tmp)
bprintf(P_TRUNCATE, text[FiFileSize], u64toac(f->size,tmp)
, byte_estimate_to_str(f->size, tmp2, sizeof(tmp2), /* units: */1024, /* precision: */1));
bprintf(P_TRUNCATE, text[FiCredits]
,(cfg.dir[f->dir]->misc&DIR_FREE || !f->cost) ? "FREE" : i64toac(f->cost,tmp));
,(cfg.dir[f->dir]->misc&DIR_FREE || !f->cost) ? "FREE" : u64toac(f->cost,tmp));
if(getfilesize(&cfg, f) > 0 && (uint64_t)f->size == smb_getfilesize(&f->idx)) {
#if 0 // I don't think anyone cares about the CRC-16 checksum value of a file
if(f->file_idx.hash.flags & SMB_HASH_CRC16) {
......@@ -178,7 +178,7 @@ bool sbbs_t::removefcdt(file_t* f)
&& f->hdr.times_downloaded) /* all downloads */
cdt+=((ulong)((long)f->hdr.times_downloaded
*f->cost*(cfg.dir[f->dir]->dn_pct/100.0))/cur_cps)/60;
adjustuserrec(&cfg,u,U_MIN,10,-cdt);
adjustuserrec(&cfg,u,U_MIN,-cdt);
sprintf(str,"%lu minute",cdt);
sprintf(tmp,text[FileRemovedUserMsg]
,f->name,cdt ? str : text[No]);
......@@ -199,14 +199,14 @@ bool sbbs_t::removefcdt(file_t* f)
return false;
cdt = atol(str);
}
adjustuserrec(&cfg,u,U_CDT,10,-cdt);
adjustuserrec(&cfg,u,U_CDT,-cdt);
sprintf(tmp,text[FileRemovedUserMsg]
,f->name,cdt ? ultoac(cdt,str) : text[No]);
putsmsg(&cfg,u,tmp);
}
adjustuserrec(&cfg,u,U_ULB,10,(long)-f->size);
adjustuserrec(&cfg,u,U_ULS,5,-1);
adjustuserrec(&cfg,u,U_ULB,-f->size);
adjustuserrec(&cfg,u,U_ULS,-1);
return(true);
}
......
......@@ -1286,7 +1286,7 @@ char* cmdstr(scfg_t* cfg, user_t* user, const char* instr, const char* fpath
break;
case '$': /* Credits */
if(user!=NULL)
strncat(cmd,ultoa(user->cdt+user->freecdt,str,10), avail);
strncat(cmd,_ui64toa(user->cdt+user->freecdt,str,10), avail);
break;
case '%': /* %% for percent sign */
strncat(cmd,"%", avail);
......
......@@ -57,7 +57,7 @@ int lprintf(int level, const char *fmat, ...)
return(chcount);
}
char* byteStr(unsigned long value)
char* byteStr(uint64_t value)
{
static char tmp[128];
......@@ -109,8 +109,9 @@ int main(int argc, char **argv)
int i,j,dirnum,libnum,desc_off,lines,nots=0;
char* omode="w";
char* pattern=NULL;
ulong m,misc=0,total_cdt=0,total_files=0,dir_files;
ulong m,misc=0,total_files=0,dir_files;
uint64_t cdt;
uint64_t total_cdt=0;
long max_age=0;
FILE* out=NULL;
......@@ -450,7 +451,7 @@ int main(int argc, char **argv)
}
if(misc&TOT && !(misc&AUTO))
fprintf(out,"TOTALS\n------\n%lu credits/bytes in %lu files.\n"
fprintf(out,"TOTALS\n------\n%" PRIu64 " credits/bytes in %lu files.\n"
,total_cdt,total_files);
printf("\nDone.\n");
return(0);
......
......@@ -775,12 +775,12 @@ static void send_thread(void* arg)
l=0;
if(scfg.dir[f.dir]->misc&DIR_CDTMIN && cps) { /* Give min instead of cdt */
mod=((ulong)(l*(scfg.dir[f.dir]->dn_pct/100.0))/cps)/60;
adjustuserrec(&scfg,uploader.number,U_MIN,10,mod);
adjustuserrec(&scfg,uploader.number,U_MIN,mod);
sprintf(tmp,"%lu minute",mod);
} else {
mod=(ulong)(l*(scfg.dir[f.dir]->dn_pct/100.0));
adjustuserrec(&scfg,uploader.number,U_CDT,10,mod);
ultoac(mod,tmp);
adjustuserrec(&scfg,uploader.number,U_CDT,mod);
u32toac(mod,tmp,',');
}
if(!(scfg.dir[f.dir]->misc&DIR_QUIET)) {
const char* prefix = xfer.filepos ? "partially FTP-" : "FTP-";
......@@ -1071,11 +1071,11 @@ static void receive_thread(void* arg)
user_uploaded(&scfg, xfer.user, (!xfer.append && xfer.filepos==0) ? 1:0, total);
if(scfg.dir[f.dir]->up_pct && scfg.dir[f.dir]->misc&DIR_CDTUL) { /* credit for upload */
if(scfg.dir[f.dir]->misc&DIR_CDTMIN && cps) /* Give min instead of cdt */
xfer.user->min=adjustuserrec(&scfg,xfer.user->number,U_MIN,10
xfer.user->min=(uint32_t)adjustuserrec(&scfg,xfer.user->number,U_MIN
,((ulong)(total*(scfg.dir[f.dir]->up_pct/100.0))/cps)/60);
else
xfer.user->cdt=adjustuserrec(&scfg,xfer.user->number,U_CDT,10
,(ulong)(cdt*(scfg.dir[f.dir]->up_pct/100.0)));
xfer.user->cdt=adjustuserrec(&scfg,xfer.user->number,U_CDT
,cdt*(uint64_t)(scfg.dir[f.dir]->up_pct/100.0));
}
if(!(scfg.dir[f.dir]->misc&DIR_NOSTAT))
inc_sys_upload_stats(&scfg, 1, (ulong)total);
......
......@@ -409,17 +409,17 @@ void sbbs_t::download_msg_attachments(smb_t* smb, smbmsg_t* msg, bool del)
if(!fexistcase(fpath) && msg->idx.from)
SAFEPRINTF3(fpath,"%sfile/%04u.out/%s" /* path is path/fname */
,cfg.data_dir, msg->idx.from,tp);
long length=(long)flength(fpath);
off_t length=flength(fpath);
if(length<1)
bprintf(text[FileDoesNotExist], tp);
else if(!(useron.exempt&FLAG('T')) && cur_cps && !SYSOP
&& length/(long)cur_cps>(time_t)timeleft)
&& length/cur_cps>(time_t)timeleft)
bputs(text[NotEnoughTimeToDl]);
else {
char tmp[512];
int i;
SAFEPRINTF2(str, text[DownloadAttachedFileQ]
,getfname(fpath),ultoac(length,tmp));
,getfname(fpath),u64toac(length,tmp));
if(length>0L && text[DownloadAttachedFileQ][0] && yesno(str)) {
{ /* Remote User */
xfer_prot_menu(XFER_DOWNLOAD);
......@@ -444,11 +444,11 @@ void sbbs_t::download_msg_attachments(smb_t* smb, smbmsg_t* msg, bool del)
logon_dlb+=length; /* Update stats */
logon_dls++;
useron.dls=(ushort)adjustuserrec(&cfg,useron.number
,U_DLS,5,1);
,U_DLS,1);
useron.dlb=adjustuserrec(&cfg,useron.number
,U_DLB,10,length);
,U_DLB,length);
bprintf(text[FileNBytesSent]
,getfname(fpath),ultoac(length,tmp));
,getfname(fpath),u64toac(length,tmp));
SAFEPRINTF(str
,"downloaded attached file: %s"
,getfname(fpath));
......
......@@ -262,20 +262,25 @@ static JSBool js_user_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
val=p->user->ptoday;
break;
case USER_PROP_ULB:
val=p->user->ulb;
*vp = DOUBLE_TO_JSVAL((jsdouble)p->user->ulb);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE; /* intentional early return */
break;
case USER_PROP_ULS:
val=p->user->uls;
break;
case USER_PROP_DLB:
val=p->user->dlb;
*vp = DOUBLE_TO_JSVAL((jsdouble)p->user->dlb);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE; /* intentional early return */
break;
case USER_PROP_DLS:
val=p->user->dls;
break;
case USER_PROP_CDT:
val=p->user->cdt;
break;
*vp = DOUBLE_TO_JSVAL((jsdouble)p->user->cdt);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE; /* intentional early return */
case USER_PROP_MIN:
val=p->user->min;
break;
......@@ -327,8 +332,9 @@ static JSBool js_user_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
break;
case USER_PROP_FREECDT:
val=p->user->freecdt;
break;
*vp = DOUBLE_TO_JSVAL((jsdouble)p->user->freecdt);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE; /* intentional early return */
case USER_PROP_XEDIT:
if(p->user->xedit>0 && p->user->xedit<=scfg->total_xedits)
s=scfg->xedit[p->user->xedit-1]->code;
......@@ -722,11 +728,11 @@ static JSBool js_user_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
rc=JS_SUSPENDREQUEST(cx);
break;
case USER_PROP_CDT:
p->user->cdt=strtoul(str,NULL,0);
p->user->cdt=strtoull(str,NULL,0);
putuserrec(scfg,p->user->number,U_CDT,0,str);
break;
case USER_PROP_FREECDT:
p->user->freecdt=strtoul(str,NULL,0);
p->user->freecdt=strtoull(str,NULL,0);
putuserrec(scfg,p->user->number,U_FREECDT,0,str);
break;
case USER_PROP_MIN:
......
......@@ -940,7 +940,7 @@ int sbbs_t::listfileinfo(uint dirnum, const char *filespec, long mode)
&& f->cost>(useron.cdt+useron.freecdt)) {
SYNC;
bprintf(text[YouOnlyHaveNCredits]
,ultoac(useron.cdt+useron.freecdt,tmp));
,u64toac(useron.cdt+useron.freecdt,tmp));
mnemonics(text[QuitOrNext]);
if(getkeys("\rQ",0)=='Q') {
found=-1;
......
......@@ -241,9 +241,9 @@ bool sbbs_t::logon()
getfilesize(&cfg, &f);
bprintf(text[FileAddedToBatDlQueue]
,f.name, i + 1, cfg.max_batdn
,ultoac((ulong)f.cost,tmp)
,ultoac((ulong)f.size,tmp2)
,sectostr((ulong)f.size / (ulong)cur_cps,str));
,byte_estimate_to_str(f.cost, tmp, sizeof(tmp), 1, 1)
,byte_estimate_to_str(f.size, tmp2, sizeof(tmp2), 1, 1)
,sectostr((uint)(f.size / (uint64_t)cur_cps),str));
smb_freefilemem(&f);
} else
batch_file_remove(&cfg, useron.number, XFER_BATCH_DOWNLOAD, filename);
......
......@@ -338,9 +338,9 @@ bool sbbs_t::netmail(const char *into, const char *title, long mode, smb_t* resm
return false;
}
useron.emails = (ushort)adjustuserrec(&cfg, useron.number, U_EMAILS, 0, 1);
useron.emails = (ushort)adjustuserrec(&cfg, useron.number, U_EMAILS, 1);
logon_emails++;
useron.etoday = (ushort)adjustuserrec(&cfg, useron.number, U_ETODAY, 0, 1);
useron.etoday = (ushort)adjustuserrec(&cfg, useron.number, U_ETODAY, 1);
if(!(useron.exempt&FLAG('S')))
subtract_cdt(&cfg,&useron,cfg.netmail_cost);
......
......@@ -657,7 +657,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack)
if(!is_download_free(&cfg, f.dir, &useron, &client)) {
if(totalcdt + f.cost > (uint64_t)(useron.cdt+useron.freecdt)) {
bprintf(text[YouOnlyHaveNCredits]
,ultoac(useron.cdt+useron.freecdt,tmp));
,u64toac(useron.cdt+useron.freecdt,tmp));
batch_file_remove(&cfg, useron.number, XFER_BATCH_DOWNLOAD, filename);
continue;
}
......
......@@ -584,7 +584,7 @@ void sbbs_t::qwk_sec()
off_t l=flength(str);
bprintf(text[FiFilename], getfname(str));
bprintf(text[FiFileSize], ultoac((ulong)l,tmp)
bprintf(text[FiFileSize], u64toac(l,tmp)
, byte_estimate_to_str(l, tmp2, sizeof(tmp2), /* units: */1024, /* precision: */1));
if(l>0L && cur_cps)
......
......@@ -903,7 +903,7 @@ int sbbs_t::scanposts(uint subnum, long mode, const char *find)
if(!stricmp(cfg.sub[subnum]->misc&SUB_NAME
? useron.name : useron.alias, msg.from))
useron.posts=(ushort)adjustuserrec(&cfg,useron.number
,U_POSTS,5,-1);
,U_POSTS,-1);
}
}
smb_unlocksmbhdr(&smb);
......
......@@ -722,6 +722,8 @@ public:
bool chkpass(char *pass, user_t* user, bool unique);
char * cmdstr(const char *instr, const char *fpath, const char *fspec, char *outstr, long mode = EX_UNSPECIFIED);
char cmdstr_output[512];
char* ultoac(uint32_t, char*, char sep=',');
char* u64toac(uint64_t, char*, char sep=',');
void subinfo(uint subnum);
void dirinfo(uint dirnum);
......
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