From 1cac2c8a4ae11946e37d7e1af5a380d6bc9b4fbf Mon Sep 17 00:00:00 2001 From: Rob Swindell <rob@synchro.net> Date: Wed, 23 Mar 2022 21:07:24 -0700 Subject: [PATCH] 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 --- src/sbbs3/atcodes.cpp | 26 +++---- src/sbbs3/bat_xfer.cpp | 27 +++---- src/sbbs3/chat.cpp | 6 +- src/sbbs3/chk_ar.cpp | 6 +- src/sbbs3/data.cpp | 4 +- src/sbbs3/download.cpp | 6 +- src/sbbs3/exec.cpp | 4 +- src/sbbs3/file.cpp | 12 +-- src/sbbs3/filedat.c | 2 +- src/sbbs3/filelist.c | 7 +- src/sbbs3/ftpsrvr.c | 12 +-- src/sbbs3/getmsg.cpp | 12 +-- src/sbbs3/js_user.c | 22 ++++-- src/sbbs3/listfile.cpp | 2 +- src/sbbs3/logon.cpp | 6 +- src/sbbs3/netmail.cpp | 4 +- src/sbbs3/pack_qwk.cpp | 2 +- src/sbbs3/qwk.cpp | 2 +- src/sbbs3/readmsgs.cpp | 2 +- src/sbbs3/sbbs.h | 2 + src/sbbs3/sbbsdefs.h | 33 +++++---- src/sbbs3/scfg/scfgsys.c | 10 +-- src/sbbs3/scfgdefs.h | 2 +- src/sbbs3/scfglib1.c | 9 ++- src/sbbs3/scfgsave.c | 8 +- src/sbbs3/str.cpp | 38 ++++++---- src/sbbs3/str_util.c | 12 +-- src/sbbs3/str_util.h | 4 +- src/sbbs3/text_defaults.c | 15 ++-- src/sbbs3/uedit/uedit.c | 38 +++++----- src/sbbs3/upload.cpp | 8 +- src/sbbs3/userdat.c | 149 +++++++++++++++++++++++--------------- src/sbbs3/userdat.h | 7 +- src/sbbs3/useredit.cpp | 50 +++++++------ src/sbbs3/xtrn.cpp | 2 +- src/sbbs3/xtrn_sec.cpp | 12 +-- 36 files changed, 315 insertions(+), 248 deletions(-) diff --git a/src/sbbs3/atcodes.cpp b/src/sbbs3/atcodes.cpp index f189baee21..458bcdb35e 100644 --- a/src/sbbs3/atcodes.cpp +++ b/src/sbbs3/atcodes.cpp @@ -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")) diff --git a/src/sbbs3/bat_xfer.cpp b/src/sbbs3/bat_xfer.cpp index f34a3ef208..9ad5fba71b 100644 --- a/src/sbbs3/bat_xfer.cpp +++ b/src/sbbs3/bat_xfer.cpp @@ -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; } } diff --git a/src/sbbs3/chat.cpp b/src/sbbs3/chat.cpp index 2ffe4ca8a6..f8290fcd82 100644 --- a/src/sbbs3/chat.cpp +++ b/src/sbbs3/chat.cpp @@ -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"); } diff --git a/src/sbbs3/chk_ar.cpp b/src/sbbs3/chk_ar.cpp index 2318b03b6c..6d3433417b 100644 --- a/src/sbbs3/chk_ar.cpp +++ b/src/sbbs3/chk_ar.cpp @@ -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: diff --git a/src/sbbs3/data.cpp b/src/sbbs3/data.cpp index 18a8218540..428d74bf23 100644 --- a/src/sbbs3/data.cpp +++ b/src/sbbs3/data.cpp @@ -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); diff --git a/src/sbbs3/download.cpp b/src/sbbs3/download.cpp index 1db61078e5..669d7ce629 100644 --- a/src/sbbs3/download.cpp +++ b/src/sbbs3/download.cpp @@ -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); diff --git a/src/sbbs3/exec.cpp b/src/sbbs3/exec.cpp index 9e6f9b8f8b..6d5167c79a 100644 --- a/src/sbbs3/exec.cpp +++ b/src/sbbs3/exec.cpp @@ -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: diff --git a/src/sbbs3/file.cpp b/src/sbbs3/file.cpp index 9a2059a6cc..6483776e4b 100644 --- a/src/sbbs3/file.cpp +++ b/src/sbbs3/file.cpp @@ -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); } diff --git a/src/sbbs3/filedat.c b/src/sbbs3/filedat.c index 2721d9d61e..ae598427c2 100644 --- a/src/sbbs3/filedat.c +++ b/src/sbbs3/filedat.c @@ -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); diff --git a/src/sbbs3/filelist.c b/src/sbbs3/filelist.c index b2eadb5012..c0fa9a0e0a 100644 --- a/src/sbbs3/filelist.c +++ b/src/sbbs3/filelist.c @@ -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); diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c index 6fc323c791..17bfca6d28 100644 --- a/src/sbbs3/ftpsrvr.c +++ b/src/sbbs3/ftpsrvr.c @@ -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); diff --git a/src/sbbs3/getmsg.cpp b/src/sbbs3/getmsg.cpp index 0923a4269d..6197e69e2a 100644 --- a/src/sbbs3/getmsg.cpp +++ b/src/sbbs3/getmsg.cpp @@ -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)); diff --git a/src/sbbs3/js_user.c b/src/sbbs3/js_user.c index 4ad482bd10..6e91e515f3 100644 --- a/src/sbbs3/js_user.c +++ b/src/sbbs3/js_user.c @@ -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: diff --git a/src/sbbs3/listfile.cpp b/src/sbbs3/listfile.cpp index 8b99f3b268..552e887de5 100644 --- a/src/sbbs3/listfile.cpp +++ b/src/sbbs3/listfile.cpp @@ -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; diff --git a/src/sbbs3/logon.cpp b/src/sbbs3/logon.cpp index 626630f029..e8ef49151c 100644 --- a/src/sbbs3/logon.cpp +++ b/src/sbbs3/logon.cpp @@ -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); diff --git a/src/sbbs3/netmail.cpp b/src/sbbs3/netmail.cpp index 375fcf6081..5dcf191d3d 100644 --- a/src/sbbs3/netmail.cpp +++ b/src/sbbs3/netmail.cpp @@ -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); diff --git a/src/sbbs3/pack_qwk.cpp b/src/sbbs3/pack_qwk.cpp index 0da138a1fd..8bf391660d 100644 --- a/src/sbbs3/pack_qwk.cpp +++ b/src/sbbs3/pack_qwk.cpp @@ -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; } diff --git a/src/sbbs3/qwk.cpp b/src/sbbs3/qwk.cpp index 6a50324adc..f45336d277 100644 --- a/src/sbbs3/qwk.cpp +++ b/src/sbbs3/qwk.cpp @@ -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) diff --git a/src/sbbs3/readmsgs.cpp b/src/sbbs3/readmsgs.cpp index 13c94fa298..f52165688e 100644 --- a/src/sbbs3/readmsgs.cpp +++ b/src/sbbs3/readmsgs.cpp @@ -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); diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index dabf50743a..ef00b37610 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -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); diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h index 591f455bec..36c9f23616 100644 --- a/src/sbbs3/sbbsdefs.h +++ b/src/sbbs3/sbbsdefs.h @@ -510,13 +510,14 @@ typedef enum { /* Values for xtrn_t.event */ #define LEN_FDESC 58 /* File description (summary) */ #define LEN_EXTDESC 5000 /* Extended file description */ #define LEN_TITLE 70 /* Message title */ -#define LEN_MAIN_CMD 28 /* Unused Storage in user.dat */ +#define LEN_CDT 20 /* Maximum credit length: 18446744073709551616 */ +#define LEN_MAIN_CMD 8 /* Unused Storage in user.dat */ #define LEN_COLS 3 #define LEN_ROWS 3 #define LEN_PASS 40 #define MIN_PASS_LEN 4 #define RAND_PASS_LEN 8 -#define LEN_SCAN_CMD 35 +#define LEN_SCAN_CMD 15 #define LEN_IPADDR 45 #define LEN_CID 45 /* Caller ID (phone number) */ #define LEN_ARSTR 40 /* Max length of Access Requirement string */ @@ -565,8 +566,8 @@ typedef enum { /* Values for xtrn_t.event */ #define U_ULS U_ULB+10 #define U_DLB U_ULS+5 #define U_DLS U_DLB+10 -#define U_CDT U_DLS+5 -#define U_MIN U_CDT+10 +#define U_OLDCDT U_DLS+5 +#define U_MIN U_OLDCDT+10 #define U_LEVEL U_MIN+10+2 /* Offset to Security Level */ #define U_FLAGS1 U_LEVEL+2 /* Offset to Flags */ @@ -583,12 +584,14 @@ typedef enum { /* Values for xtrn_t.event */ #define U_CURXTRN U_CURSUB+16 /* Current xtrn (internal code) */ #define U_ROWS U_CURXTRN+8+2 #define U_COLS U_ROWS+LEN_ROWS -#define U_MAIN_CMD U_COLS+LEN_COLS /* unused */ +#define U_CDT U_COLS+LEN_COLS /* unused */ +#define U_MAIN_CMD U_CDT+LEN_CDT #define U_PASS U_MAIN_CMD+LEN_MAIN_CMD -#define U_SCAN_CMD U_PASS+LEN_PASS+2 /* unused */ -#define U_IPADDR U_SCAN_CMD+LEN_SCAN_CMD /* unused */ -#define U_FREECDT U_IPADDR+LEN_IPADDR+2 -#define U_FLAGS3 U_FREECDT+10 /* Flag set #3 */ +#define U_FREECDT U_PASS+LEN_PASS+2 +#define U_SCAN_CMD U_FREECDT+LEN_CDT /* unused */ +#define U_IPADDR U_SCAN_CMD+LEN_SCAN_CMD +#define U_OLDFREECDT U_IPADDR+LEN_IPADDR+2 /* unused */ +#define U_FLAGS3 U_OLDFREECDT+10 /* Flag set #3 */ #define U_FLAGS4 U_FLAGS3+8 /* Flag set #4 */ #define U_XEDIT U_FLAGS4+8 /* External editor (code */ #define U_SHELL U_XEDIT+8 /* Command shell (code */ @@ -1007,7 +1010,7 @@ typedef struct { /* Users information */ int rows, /* Rows on terminal (0 = auto-detect) */ cols; /* Columns on terminal (0 = auto-detect) */ - ulong misc, /* Misc. bits - ANSI, Deleted etc. */ + uint32_t misc, /* Misc. bits - ANSI, Deleted etc. */ qwk, /* QWK settings */ chat, /* Chat defaults */ flags1, /* Flag set #1 */ @@ -1016,11 +1019,11 @@ typedef struct { /* Users information */ flags4, /* Flag set #4 */ exempt, /* Exemption Flags */ rest, /* Restriction Flags */ - ulb, /* Total bytes uploaded */ - dlb, /* Total bytes downloaded */ - cdt, /* Credits */ - min, /* Minutes */ - freecdt; /* Free credits (renewed daily) */ + min; /* Minutes */ + uint64_t cdt; /* Credits */ + uint64_t freecdt; /* Free credits (renewed daily) */ + uint64_t ulb; /* Total bytes uploaded */ + uint64_t dlb; /* Total bytes downloaded */ time32_t firston, /* Date/Time first called */ laston, /* Last logoff date/time */ expire, /* Expiration date */ diff --git a/src/sbbs3/scfg/scfgsys.c b/src/sbbs3/scfg/scfgsys.c index 6d35ada31d..88a1501432 100644 --- a/src/sbbs3/scfg/scfgsys.c +++ b/src/sbbs3/scfg/scfgsys.c @@ -891,9 +891,9 @@ void sys_cfg(void) sprintf(opt[i++],"%-27.27s%s","Expiration Days" ,ultoa(cfg.new_expire,str,10)); - ultoac(cfg.new_cdt,str); + u32toac(cfg.new_cdt,str,','); sprintf(opt[i++],"%-27.27s%s","Credits",str); - ultoac(cfg.new_min,str); + u32toac(cfg.new_min,str,','); sprintf(opt[i++],"%-27.27s%s","Minutes",str); sprintf(opt[i++],"%-27.27s%s","Editor" ,cfg.new_xedit); @@ -1367,7 +1367,7 @@ void sys_cfg(void) ,cfg.new_sif); sprintf(opt[i++],"%-27.27s%s","Output SIF Questionnaire" ,cfg.new_sof); - ultoac(cfg.cdt_per_dollar,str); + u32toac(cfg.cdt_per_dollar,str,','); sprintf(opt[i++],"%-27.27s%s","Credits Per Dollar",str); sprintf(opt[i++],"%-27.27s%u","Minutes Per 100k Credits" ,cfg.cdt_min_value); @@ -1951,9 +1951,9 @@ void sys_cfg(void) byte_count_to_str(cfg.level_freecdtperday[i], tmp, sizeof(tmp)); if(uifc.input(WIN_MID|WIN_SAV,0,0 ,"Free Credits Awarded Per Day" - ,tmp,10 + ,tmp,19 ,K_EDIT|K_UPPER) > 0) - cfg.level_freecdtperday[i] = (int32_t)parse_byte_count(tmp, 1); + cfg.level_freecdtperday[i] = parse_byte_count(tmp, 1); break; case 7: j=0; diff --git a/src/sbbs3/scfgdefs.h b/src/sbbs3/scfgdefs.h index f86c20517b..9e6e619df2 100644 --- a/src/sbbs3/scfgdefs.h +++ b/src/sbbs3/scfgdefs.h @@ -528,7 +528,7 @@ typedef struct level_linespermsg[100], level_postsperday[100], level_emailperday[100]; - int32_t level_freecdtperday[100]; + uint64_t level_freecdtperday[100]; int32_t level_misc[100]; char expired_level; /* Expired user's ML */ uint32_t expired_flags1; /* Flags from set #1 to remove when expired */ diff --git a/src/sbbs3/scfglib1.c b/src/sbbs3/scfglib1.c index 7b98e1e3f0..9204302269 100644 --- a/src/sbbs3/scfglib1.c +++ b/src/sbbs3/scfglib1.c @@ -299,18 +299,21 @@ BOOL read_main_cfg(scfg_t* cfg, char* error, size_t maxerrlen) /***************************/ for(i=0;i<100 && !feof(instream);i++) { + uint32_t freecdt32; get_int(cfg->level_timeperday[i],instream); get_int(cfg->level_timepercall[i],instream); get_int(cfg->level_callsperday[i],instream); - get_int(cfg->level_freecdtperday[i],instream); + get_int(freecdt32,instream); get_int(cfg->level_linespermsg[i],instream); get_int(cfg->level_postsperday[i],instream); get_int(cfg->level_emailperday[i],instream); get_int(cfg->level_misc[i],instream); get_int(cfg->level_expireto[i],instream); + get_int(cfg->level_freecdtperday[i],instream); + if(freecdt32) + cfg->level_freecdtperday[i] = freecdt32; get_int(c,instream); - for(j=0;j<5;j++) - get_int(n,instream); + get_int(n,instream); } if(i!=100) { safe_snprintf(error, maxerrlen,"Insufficient User Level Information: " diff --git a/src/sbbs3/scfgsave.c b/src/sbbs3/scfgsave.c index 29d00d7ce9..e1b3b19db2 100644 --- a/src/sbbs3/scfgsave.c +++ b/src/sbbs3/scfgsave.c @@ -280,18 +280,20 @@ BOOL write_main_cfg(scfg_t* cfg, int backup_level) c=0; for(i=0;i<100 && !feof(stream);i++) { + uint32_t l = 0; put_int(cfg->level_timeperday[i],stream); put_int(cfg->level_timepercall[i],stream); put_int(cfg->level_callsperday[i],stream); - put_int(cfg->level_freecdtperday[i],stream); + put_int(l,stream); // Used to be freecdtperday (32-bit) put_int(cfg->level_linespermsg[i],stream); put_int(cfg->level_postsperday[i],stream); put_int(cfg->level_emailperday[i],stream); put_int(cfg->level_misc[i],stream); put_int(cfg->level_expireto[i],stream); + put_int(cfg->level_freecdtperday[i],stream); put_int(c,stream); - for(j=0;j<5;j++) - put_int(n,stream); } + put_int(n,stream); + } /* Command Shells */ diff --git a/src/sbbs3/str.cpp b/src/sbbs3/str.cpp index 0939273a9b..7c605ff345 100644 --- a/src/sbbs3/str.cpp +++ b/src/sbbs3/str.cpp @@ -922,12 +922,12 @@ void sbbs_t::user_info() ,getmail(&cfg,useron.number,/* Sent: */FALSE, /* SPAM: */FALSE),useron.etoday); CRLF; bprintf(text[UserUploads] - ,ultoac(useron.ulb,tmp),useron.uls); + ,byte_estimate_to_str(useron.ulb, tmp, sizeof(tmp), 1, 1),useron.uls); bprintf(text[UserDownloads] - ,ultoac(useron.dlb,tmp),useron.dls,nulstr); - bprintf(text[UserCredits],ultoac(useron.cdt,tmp) - ,ultoac(useron.freecdt,tmp2) - ,ultoac(cfg.level_freecdtperday[useron.level],str)); + ,byte_estimate_to_str(useron.dlb, tmp, sizeof(tmp), 1, 1),useron.dls,nulstr); + bprintf(text[UserCredits],byte_estimate_to_str(useron.cdt, tmp, sizeof(tmp), 1, 1) + ,byte_estimate_to_str(useron.freecdt,tmp2, sizeof(tmp2), 1, 1) + ,byte_estimate_to_str(cfg.level_freecdtperday[useron.level], str, sizeof(str), 1, 1)); bprintf(text[UserMinutes],ultoac(useron.min,tmp)); } @@ -1166,8 +1166,8 @@ void sbbs_t::time_bank(void) s=getnum(s); if(s>0) { logline(" ","Minute Bank Deposit"); - useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,s); - useron.ttoday=(ushort)adjustuserrec(&cfg,useron.number,U_TTODAY,10,s); + useron.min=(uint32_t)adjustuserrec(&cfg,useron.number,U_MIN,s); + useron.ttoday=(ushort)adjustuserrec(&cfg,useron.number,U_TTODAY,s); sprintf(str,"Minute Adjustment: %u",s*cfg.cdt_min_value); logline("*+",str); } @@ -1176,27 +1176,27 @@ void sbbs_t::time_bank(void) if(!(cfg.sys_misc&SM_NOCDTCVT)) { bprintf(text[ConversionRate],cfg.cdt_min_value); bprintf(text[UserCredits] - ,ultoac(useron.cdt,tmp) - ,ultoac(useron.freecdt,tmp2) - ,ultoac(cfg.level_freecdtperday[useron.level],str)); + ,u64toac(useron.cdt,tmp) + ,u64toac(useron.freecdt,tmp2) + ,u64toac(cfg.level_freecdtperday[useron.level],str)); bprintf(text[UserMinutes],ultoac(useron.min,tmp)); if(useron.cdt/102400L<1L) { - bprintf(text[YouOnlyHaveNCredits],ultoac(useron.cdt,tmp)); + bprintf(text[YouOnlyHaveNCredits],u64toac(useron.cdt,tmp)); return; } if(cfg.max_minutes && useron.min>=cfg.max_minutes) { bputs(text[YouHaveTooManyMinutes]); return; } - s=useron.cdt/102400L; + s=(uint32_t)(useron.cdt/102400L); if(cfg.max_minutes) while(s>0 && (s*cfg.cdt_min_value)+useron.min>cfg.max_minutes) s--; bprintf(text[CreditsToMin],s); s=getnum(s); if(s>0) { logline(" ","Credit to Minute Conversion"); - useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,-(s*102400L)); - useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,s*(int)cfg.cdt_min_value); + useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,-(s*102400L)); + useron.min=(uint32_t)adjustuserrec(&cfg,useron.number,U_MIN,s*(int)cfg.cdt_min_value); sprintf(str,"Credit Adjustment: %ld",-(s*102400L)); logline("$-",str); sprintf(str,"Minute Adjustment: %u",s*cfg.cdt_min_value); @@ -1284,3 +1284,13 @@ char* sbbs_t::server_host_name(void) { return startup->host_name[0] ? startup->host_name : cfg.sys_inetaddr; } + +char* sbbs_t::ultoac(uint32_t val, char* str, char sep) +{ + return ::u32toac(val, str, sep); +} + +char* sbbs_t::u64toac(uint64_t val, char* str, char sep) +{ + return ::u64toac(val, str, sep); +} diff --git a/src/sbbs3/str_util.c b/src/sbbs3/str_util.c index 64b85ef4f7..9991892fbd 100644 --- a/src/sbbs3/str_util.c +++ b/src/sbbs3/str_util.c @@ -476,9 +476,9 @@ str_list_t trashcan_list(scfg_t* cfg, const char* name) /****************************************************************************/ /* Returns in 'string' a character representation of the number in l with */ -/* commas. */ +/* thousands separators (e.g. commas). */ /****************************************************************************/ -char* ultoac(ulong l, char *string) +char* u32toac(uint32_t l, char *string, char sep) { char str[256]; int i,j,k; @@ -490,24 +490,24 @@ char* ultoac(ulong l, char *string) for(k=1;i>-1;k++) { string[j--]=str[i--]; if(j>0 && !(k%3)) - string[j--]=','; + string[j--]=sep; } return(string); } -char* i64toac(int64_t l, char *string) +char* u64toac(uint64_t l, char *string, char sep) { char str[256]; int i,j,k; - _i64toa(l,str,10); + _ui64toa(l,str,10); i=strlen(str)-1; j=i/3+1+i; string[j--]=0; for(k=1;i>-1;k++) { string[j--]=str[i--]; if(j>0 && !(k%3)) - string[j--]=','; + string[j--]=sep; } return string; } diff --git a/src/sbbs3/str_util.h b/src/sbbs3/str_util.h index 269b13e911..5b9e4b44a4 100644 --- a/src/sbbs3/str_util.h +++ b/src/sbbs3/str_util.h @@ -63,8 +63,8 @@ DLLEXPORT char * net_addr(net_t* net); DLLEXPORT BOOL valid_ctrl_a_attr(char a); DLLEXPORT BOOL valid_ctrl_a_code(char a); DLLEXPORT size_t strip_invalid_attr(char *str); -DLLEXPORT char * ultoac(ulong l,char *str); -DLLEXPORT char * i64toac(int64_t, char *str); +DLLEXPORT char * u32toac(uint32_t, char*, char sep); +DLLEXPORT char * u64toac(uint64_t, char*, char sep); DLLEXPORT char * rot13(char* str); DLLEXPORT uint32_t str_to_bits(uint32_t currval, const char *str); DLLEXPORT BOOL str_has_ctrl(const char*); diff --git a/src/sbbs3/text_defaults.c b/src/sbbs3/text_defaults.c index b2d2500a67..a1863252a1 100644 --- a/src/sbbs3/text_defaults.c +++ b/src/sbbs3/text_defaults.c @@ -719,15 +719,14 @@ const char * const text_defaults[TOTAL_TEXT]={ "\x67\x20\x20\x20\x3a\x20\x01\x68\x25\x2d\x35\x75\x20\x20\x20\x20\x20\x01\x6e\x01\x63\x54\x6f\x64\x61\x79\x20\x3a\x20\x01\x68\x25" "\x75\x0d\x0a" // 431 UserEmails ,"\x01\x6e\x01\x63\x4e\x65\x74\x4d\x61\x69\x6c\x20\x20\x20\x3a\x20\x01\x68\x25\x73\x0d\x0a" // 432 UserNetMail - ,"\x01\x6e\x01\x63\x55\x70\x6c\x6f\x61\x64\x73\x20\x20\x20\x3a\x20\x01\x68\x25\x31\x33\x2e\x31\x33\x73\x20\x01\x6e\x01\x63\x62\x79" - "\x74\x65\x73\x20\x69\x6e\x20\x01\x68\x25\x75\x20\x01\x6e\x01\x63\x66\x69\x6c\x65\x73\x0d\x0a" // 433 UserUploads - ,"\x01\x6e\x01\x63\x44\x6f\x77\x6e\x6c\x6f\x61\x64\x73\x20\x3a\x20\x01\x68\x25\x31\x33\x2e\x31\x33\x73\x20\x01\x6e\x01\x63\x62\x79" - "\x74\x65\x73\x20\x69\x6e\x20\x01\x68\x25\x75\x20\x01\x6e\x01\x63\x66\x69\x6c\x65\x73\x20\x25\x73\x0d\x0a" // 434 UserDownloads + ,"\x01\x6e\x01\x63\x55\x70\x6c\x6f\x61\x64\x73\x20\x20\x20\x3a\x20\x01\x68\x25\x39\x2e\x39\x73\x20\x01\x6e\x01\x63\x62\x79\x74\x65" + "\x73\x20\x69\x6e\x20\x01\x68\x25\x75\x20\x01\x6e\x01\x63\x66\x69\x6c\x65\x73\x0d\x0a" // 433 UserUploads + ,"\x01\x6e\x01\x63\x44\x6f\x77\x6e\x6c\x6f\x61\x64\x73\x20\x3a\x20\x01\x68\x25\x39\x2e\x39\x73\x20\x01\x6e\x01\x63\x62\x79\x74\x65" + "\x73\x20\x69\x6e\x20\x01\x68\x25\x75\x20\x01\x6e\x01\x63\x66\x69\x6c\x65\x73\x20\x25\x73\x0d\x0a" // 434 UserDownloads ,"\x2d\x20\x4c\x65\x65\x63\x68\x3a\x20\x01\x72\x01\x68\x01\x69\x25\x75\x01\x6e" // 435 UserLeech - ,"\x01\x6e\x01\x63\x43\x72\x65\x64\x69\x74\x73\x20\x20\x20\x3a\x20\x01\x68\x25\x31\x33\x2e\x31\x33\x73\x20\x01\x6e\x01\x63\x66\x72" - "\x65\x65\x3a\x20\x01\x68\x25\x73\x20\x01\x6e\x01\x63\x28\x01\x68\x25\x73\x20\x01\x6e\x01\x63\x70\x65\x72\x20\x64\x61\x79\x29\x0d" - "\x0a" // 436 UserCredits - ,"\x01\x6e\x01\x63\x4d\x69\x6e\x75\x74\x65\x73\x20\x20\x20\x3a\x20\x01\x68\x25\x31\x33\x2e\x31\x33\x73\x0d\x0a" // 437 UserMinutes + ,"\x01\x6e\x01\x63\x43\x72\x65\x64\x69\x74\x73\x20\x20\x20\x3a\x20\x01\x68\x25\x39\x2e\x39\x73\x20\x01\x6e\x01\x63\x66\x72\x65\x65" + "\x3a\x20\x01\x68\x25\x73\x20\x01\x6e\x01\x63\x28\x01\x68\x25\x73\x20\x01\x6e\x01\x63\x70\x65\x72\x20\x64\x61\x79\x29\x0d\x0a" // 436 UserCredits + ,"\x01\x6e\x01\x63\x4d\x69\x6e\x75\x74\x65\x73\x20\x20\x20\x3a\x20\x01\x68\x25\x39\x2e\x39\x73\x0d\x0a" // 437 UserMinutes ,"\x0d\x0a\x01\x6e\x01\x63\x53\x65\x63\x20\x4c\x65\x76\x65\x6c\x20\x3a\x20\x01\x68\x25\x64\x0d\x0a" // 438 UeditSecLevel ,"\x01\x6e\x01\x63\x46\x6c\x61\x67\x73\x20\x23\x31\x20\x20\x3a\x20\x01\x68\x25\x2d\x32\x36\x73\x20\x20\x20\x01\x6e\x01\x63\x46\x6c" "\x61\x67\x73\x20\x23\x33\x20\x20\x3a\x20\x01\x68\x25\x73\x0d\x0a\x01\x6e\x01\x63\x46\x6c\x61\x67\x73\x20\x23\x32\x20\x20\x3a\x20" diff --git a/src/sbbs3/uedit/uedit.c b/src/sbbs3/uedit/uedit.c index 3a362e7bc2..837108ebde 100644 --- a/src/sbbs3/uedit/uedit.c +++ b/src/sbbs3/uedit/uedit.c @@ -1002,9 +1002,9 @@ int edit_stats(scfg_t *cfg, user_t *user) sprintf(opt[i++],"Time On Last Call %hu",user->tlast); sprintf(opt[i++],"Extra Time Today %hu",user->textra); sprintf(opt[i++],"Total Downloads %hu",user->dls); - sprintf(opt[i++],"Downloaded Bytes %lu",user->dlb); + sprintf(opt[i++],"Downloaded Bytes %" PRIu64,user->dlb); sprintf(opt[i++],"Total Uploads %hu",user->uls); - sprintf(opt[i++],"Uploaded Bytes %lu",user->ulb); + sprintf(opt[i++],"Uploaded Bytes %" PRIu64,user->ulb); sprintf(opt[i++],"Leech Downloads %u",user->leech); sprintf(opt[i++],"Password Modified %s",user->pwmod?timestr(cfg, user->pwmod, str):"Never"); opt[i][0]=0; @@ -1183,11 +1183,11 @@ int edit_stats(scfg_t *cfg, user_t *user) case 15: /* Downloaded Bytes */ GETUSERDAT(cfg,user); - sprintf(str,"%lu",user->dlb); - uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Downloaded Bytes",str,10,K_EDIT|K_NUMBER); + sprintf(str,"%" PRIu64,user->dlb); + uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Downloaded Bytes",str,20,K_EDIT|K_NUMBER); if(uifc.changes) { - user->dlb=strtoul(str,NULL,10); - putuserrec(cfg,user->number,U_DLB,10,ultoa(user->dlb,str,10)); + user->dlb=strtoull(str,NULL,10); + putuserrec(cfg,user->number,U_DLB,10,userbytestr(user->dlb,str)); } break; case 16: @@ -1203,11 +1203,11 @@ int edit_stats(scfg_t *cfg, user_t *user) case 17: /* Uploaded Bytes */ GETUSERDAT(cfg,user); - sprintf(str,"%lu",user->ulb); - uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Uploaded Bytes",str,10,K_EDIT|K_NUMBER); + sprintf(str,"%" PRIu64,user->ulb); + uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Uploaded Bytes",str,20,K_EDIT|K_NUMBER); if(uifc.changes) { user->ulb=strtoul(str,NULL,10); - putuserrec(cfg,user->number,U_ULB,10,ultoa(user->ulb,str,10)); + putuserrec(cfg,user->number,U_ULB,10,userbytestr(user->ulb,str)); } break; case 18: @@ -1278,8 +1278,8 @@ int edit_security(scfg_t *cfg, user_t *user) sprintf(opt[i++],"Flag Set 4 %s",ltoaf(user->flags4,str)); sprintf(opt[i++],"Exemptions %s",ltoaf(user->exempt,str)); sprintf(opt[i++],"Restrictions %s",ltoaf(user->rest,str)); - sprintf(opt[i++],"Credits %lu",user->cdt); - sprintf(opt[i++],"Free Credits %lu",user->freecdt); + sprintf(opt[i++],"Credits %" PRIu64,user->cdt); + sprintf(opt[i++],"Free Credits %" PRIu64,user->freecdt); sprintf(opt[i++],"Minutes %lu",user->min); opt[i][0]=0; switch(uifc.list(WIN_MID|WIN_ACT,0,0,0,&j,0,"Security Settings",opt)) { @@ -1369,21 +1369,21 @@ int edit_security(scfg_t *cfg, user_t *user) case 8: /* Credits */ GETUSERDAT(cfg,user); - sprintf(str,"%lu",user->cdt); - uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Credits",str,10,K_EDIT|K_NUMBER); + sprintf(str,"%" PRIu64,user->cdt); + uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Credits",str,LEN_CDT,K_EDIT|K_NUMBER); if(uifc.changes) { - user->cdt=strtoul(str,NULL,10); - putuserrec(cfg,user->number,U_CDT,10,ultoa(user->cdt,str,10)); + user->cdt=strtoull(str,NULL,10); + putuserrec(cfg,user->number,U_CDT,0,_ui64toa(user->cdt,str,10)); } break; case 9: /* Free Credits */ GETUSERDAT(cfg,user); - sprintf(str,"%lu",user->freecdt); - uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Free Credits",str,10,K_EDIT|K_NUMBER); + sprintf(str,"%" PRIu64,user->freecdt); + uifc.input(WIN_MID|WIN_ACT|WIN_SAV,0,0,"Free Credits",str,LEN_CDT,K_EDIT|K_NUMBER); if(uifc.changes) { - user->freecdt=strtoul(str,NULL,10); - putuserrec(cfg,user->number,U_FREECDT,10,ultoa(user->freecdt,str,10)); + user->freecdt=strtoull(str,NULL,10); + putuserrec(cfg,user->number,U_FREECDT,0,_ui64toa(user->freecdt,str,10)); } break; case 10: diff --git a/src/sbbs3/upload.cpp b/src/sbbs3/upload.cpp index 92217d759d..f55d00ba36 100644 --- a/src/sbbs3/upload.cpp +++ b/src/sbbs3/upload.cpp @@ -172,7 +172,7 @@ bool sbbs_t::uploadfile(file_t* f) f->hdr.attr |= MSG_ANONYMOUS; smb_hfield_bin(f, SMB_COST, length); smb_hfield_str(f, SENDER, useron.alias); - bprintf(text[FileNBytesReceived],f->name, i64toac(length,tmp)); + bprintf(text[FileNBytesReceived],f->name, u64toac(length,tmp)); if(!addfile(&cfg, f->dir, f, ext, /* metadata: */NULL, &client)) return false; @@ -188,11 +188,11 @@ bool sbbs_t::uploadfile(file_t* f) user_uploaded(&cfg, &useron, 1, length); if(cfg.dir[f->dir]->up_pct && cfg.dir[f->dir]->misc&DIR_CDTUL) { /* credit for upload */ if(cfg.dir[f->dir]->misc&DIR_CDTMIN && cur_cps) /* Give min instead of cdt */ - useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10 + useron.min=(uint32_t)adjustuserrec(&cfg,useron.number,U_MIN ,((ulong)(length*(cfg.dir[f->dir]->up_pct/100.0))/cur_cps)/60); else - useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10 - ,(ulong)(f->cost * (cfg.dir[f->dir]->up_pct/100.0))); + useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT + ,(int64_t)(f->cost * (cfg.dir[f->dir]->up_pct/100.0))); } user_event(EVENT_UPLOAD); diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c index 12110077c0..0cf64c521d 100644 --- a/src/sbbs3/userdat.c +++ b/src/sbbs3/userdat.c @@ -321,11 +321,14 @@ int parseuserdat(scfg_t* cfg, char *userdat, user_t *user) getrec(userdat,U_FBACKS,5,str); user->fbacks=atoi(str); getrec(userdat,U_ETODAY,5,str); user->etoday=atoi(str); getrec(userdat,U_PTODAY,5,str); user->ptoday=atoi(str); - getrec(userdat,U_ULB,10,str); user->ulb=strtoul(str, NULL, 10); + getrec(userdat,U_ULB,10,str); user->ulb=parse_byte_count(str, 1); getrec(userdat,U_ULS,5,str); user->uls=atoi(str); - getrec(userdat,U_DLB,10,str); user->dlb=strtoul(str, NULL, 10); + getrec(userdat,U_DLB,10,str); user->dlb=parse_byte_count(str, 1); getrec(userdat,U_DLS,5,str); user->dls=atoi(str); - getrec(userdat,U_CDT,10,str); user->cdt=strtoul(str, NULL, 10); + getrec(userdat,U_CDT,LEN_CDT,str); + if(str[0] < '0' || str[0] > '9') + getrec(userdat,U_OLDCDT,10,str); + user->cdt=strtoull(str, NULL, 10); getrec(userdat,U_MIN,10,str); user->min=strtoul(str, NULL, 10); getrec(userdat,U_LEVEL,2,str); user->level=atoi(str); getrec(userdat,U_FLAGS1,8,str); user->flags1=ahtoul(str); @@ -359,8 +362,10 @@ int parseuserdat(scfg_t* cfg, char *userdat, user_t *user) getrec(userdat,U_CURDIR,sizeof(user->curdir)-1,user->curdir); getrec(userdat,U_CURXTRN,8,user->curxtrn); - getrec(userdat,U_FREECDT,10,str); - user->freecdt=strtoul(str, NULL, 10); + getrec(userdat,U_FREECDT,LEN_CDT,str); + if(str[0] < '0' || str[0] > '9') + getrec(userdat,U_OLDFREECDT,10,str); + user->freecdt=strtoull(str, NULL, 10); getrec(userdat,U_XEDIT,8,str); for(i=0;i<cfg->total_xedits;i++) @@ -499,6 +504,14 @@ int is_user_online(scfg_t* cfg, uint usernumber) return 0; } +char* userbytestr(uint64_t bytes, char* str) +{ + _ui64toa(bytes, str, 10); + if(strlen(str) > 10) + byte_estimate_to_str(bytes, str, 10 + 1, 1, 4); // +1 for NUL terminator + return str; +} + /****************************************************************************/ /* Writes into user.number's slot in user.dat data in structure 'user' */ /* Called from functions newuser, useredit and main */ @@ -560,11 +573,11 @@ int putuserdat(scfg_t* cfg, user_t* user) putrec(userdat,U_PTODAY,5,ultoa(user->ptoday,str,10)); putrec(userdat,U_PTODAY+5,2,crlf); - putrec(userdat,U_ULB,10,ultoa(user->ulb,str,10)); + putrec(userdat,U_ULB,10,userbytestr(user->ulb, str)); putrec(userdat,U_ULS,5,ultoa(user->uls,str,10)); - putrec(userdat,U_DLB,10,ultoa(user->dlb,str,10)); + putrec(userdat,U_DLB,10,userbytestr(user->dlb, str)); putrec(userdat,U_DLS,5,ultoa(user->dls,str,10)); - putrec(userdat,U_CDT,10,ultoa(user->cdt,str,10)); + putrec(userdat,U_CDT,LEN_CDT,_ui64toa(user->cdt,str,10)); putrec(userdat,U_MIN,10,ultoa(user->min,str,10)); putrec(userdat,U_MIN+10,2,crlf); @@ -592,7 +605,7 @@ int putuserdat(scfg_t* cfg, user_t* user) putrec(userdat,U_IPADDR+LEN_IPADDR,2,crlf); - putrec(userdat,U_FREECDT,10,ultoa(user->freecdt,str,10)); + putrec(userdat,U_FREECDT,LEN_CDT,_ui64toa(user->freecdt,str,10)); putrec(userdat,U_FLAGS3,8,ultoa(user->flags3,str,16)); putrec(userdat,U_FLAGS4,8,ultoa(user->flags4,str,16)); @@ -1609,7 +1622,7 @@ static BOOL ar_exp(scfg_t* cfg, uchar **ptrptr, user_t* user, client_t* client) { BOOL result,not,or,equal; uint i,n,artype=AR_LEVEL,age; - ulong l; + uint64_t l; time_t now; struct tm tm; const char* p; @@ -1830,7 +1843,7 @@ static BOOL ar_exp(scfg_t* cfg, uchar **ptrptr, user_t* user, client_t* client) result=!not; break; case AR_CREDIT: - l=(ulong)i*1024UL; + l = i * 1024UL; if(user==NULL || (equal && user->cdt+user->freecdt!=l) || (!equal && user->cdt+user->freecdt<l)) @@ -2319,12 +2332,12 @@ int putuserrec(scfg_t* cfg, int usernumber, int start, int length, const char *s /* Updates user 'usernumber's record (numeric string) by adding 'adj' to it */ /* returns the new value. */ /****************************************************************************/ -ulong adjustuserrec(scfg_t* cfg, int usernumber, int start, int length, long adj) +uint64_t adjustuserrec(scfg_t* cfg, int usernumber, int start, int64_t adj) { char str[256],path[256]; char tmp[32]; int i,c,file; - ulong val; + uint64_t val; if(!VALID_CFG(cfg) || usernumber<1) return(0); @@ -2340,12 +2353,10 @@ ulong adjustuserrec(scfg_t* cfg, int usernumber, int start, int length, long adj (void)lseek(file,(long)((long)(usernumber-1)*U_LEN)+start,SEEK_SET); - if(length < 1) { /* auto-length */ - length=user_rec_len(start); - if(length < 1) { - close(file); - return 0; - } + int length=user_rec_len(start); + if(length < 1) { + close(file); + return 0; } i=0; @@ -2369,14 +2380,26 @@ ulong adjustuserrec(scfg_t* cfg, int usernumber, int start, int length, long adj for(c=0;c<length;c++) if(str[c]==ETX || str[c]==CR) break; str[c]=0; - if(length > 5) { + if(start == U_ULB || start == U_DLB || length > 10) { + if(start == U_ULB || start == U_DLB) + val = parse_byte_count(str, 1); + else + val = strtoull(str, NULL, 10); + if(adj<0L && val<(uint64_t)-adj) /* don't go negative */ + val=0; + else if(adj > 0 && val + adj < val) + val = UINT64_MAX; + else + val += (uint64_t)adj; + } + else if(length > 5) { val = strtoul(str, NULL, 10); - if(adj<0L && val<(ulong)-adj) /* don't go negative */ + if(adj<0L && val<(uint32_t)-adj) /* don't go negative */ val=0; else if(adj > 0 && val + adj < val) - val = ULONG_MAX; + val = UINT32_MAX; else - val += (ulong)adj; + val += (uint32_t)adj; } else { ushort sval = (ushort)strtoul(str, NULL, 10); if(adj < 0L && sval < (ushort)-adj) /* don't go negative */ @@ -2388,7 +2411,11 @@ ulong adjustuserrec(scfg_t* cfg, int usernumber, int start, int length, long adj val = sval; } (void)lseek(file,(long)((long)(usernumber-1)*U_LEN)+start,SEEK_SET); - putrec(str,0,length,ultoa(val,tmp,10)); + if(start == U_ULB || start == U_DLB) + userbytestr(val, tmp); + else + _ui64toa(val,tmp,10); + putrec(str,0,length,tmp); if(write(file,str,length)!=length) { unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length); close(file); @@ -2404,27 +2431,30 @@ ulong adjustuserrec(scfg_t* cfg, int usernumber, int start, int length, long adj /* Subtract credits from the current user online, accounting for the new */ /* "free credits" field. */ /****************************************************************************/ -void subtract_cdt(scfg_t* cfg, user_t* user, long amt) +void subtract_cdt(scfg_t* cfg, user_t* user, uint64_t amt) { char tmp[64]; - long mod; + int64_t mod; if(!amt || user==NULL) return; if(user->freecdt) { - if((ulong)amt>user->freecdt) { /* subtract both credits and */ + if(amt > user->freecdt) { /* subtract both credits and */ mod=amt-user->freecdt; /* free credits */ - putuserrec(cfg, user->number,U_FREECDT,10,"0"); + putuserrec(cfg, user->number,U_FREECDT,0,"0"); user->freecdt=0; - user->cdt=adjustuserrec(cfg, user->number,U_CDT,10,-mod); + user->cdt=adjustuserrec(cfg, user->number,U_CDT,-mod); } else { /* subtract just free credits */ user->freecdt-=amt; - putuserrec(cfg, user->number,U_FREECDT,10 - ,ultoa(user->freecdt,tmp,10)); + putuserrec(cfg, user->number,U_FREECDT,0 + ,_ui64toa(user->freecdt,tmp,10)); } } - else /* no free credits */ - user->cdt=adjustuserrec(cfg, user->number,U_CDT,10,-amt); + else { /* no free credits */ + if(amt > INT64_MAX) + amt = INT64_MAX; + user->cdt=adjustuserrec(cfg, user->number,U_CDT,-(int64_t)amt); + } } BOOL user_posted_msg(scfg_t* cfg, user_t* user, int count) @@ -2432,8 +2462,8 @@ BOOL user_posted_msg(scfg_t* cfg, user_t* user, int count) if(user==NULL) return(FALSE); - user->posts =(ushort)adjustuserrec(cfg, user->number, U_POSTS, 5, count); - user->ptoday=(ushort)adjustuserrec(cfg, user->number, U_PTODAY, 5, count); + user->posts =(ushort)adjustuserrec(cfg, user->number, U_POSTS, count); + user->ptoday=(ushort)adjustuserrec(cfg, user->number, U_PTODAY, count); return(TRUE); } @@ -2444,10 +2474,10 @@ BOOL user_sent_email(scfg_t* cfg, user_t* user, int count, BOOL feedback) return(FALSE); if(feedback) - user->fbacks=(ushort)adjustuserrec(cfg, user->number, U_FBACKS, 5, count); + user->fbacks=(ushort)adjustuserrec(cfg, user->number, U_FBACKS, count); else - user->emails=(ushort)adjustuserrec(cfg, user->number, U_EMAILS, 5, count); - user->etoday=(ushort)adjustuserrec(cfg, user->number, U_ETODAY, 5, count); + user->emails=(ushort)adjustuserrec(cfg, user->number, U_EMAILS, count); + user->etoday=(ushort)adjustuserrec(cfg, user->number, U_ETODAY, count); return(TRUE); } @@ -2457,8 +2487,8 @@ BOOL user_downloaded(scfg_t* cfg, user_t* user, int files, off_t bytes) if(user==NULL) return(FALSE); - user->dls=(ushort)adjustuserrec(cfg, user->number, U_DLS, 5, files); - user->dlb=adjustuserrec(cfg, user->number, U_DLB, 10, (long)bytes); + user->dls=(ushort)adjustuserrec(cfg, user->number, U_DLS, files); + user->dlb=adjustuserrec(cfg, user->number, U_DLB, bytes); return(TRUE); } @@ -2511,16 +2541,16 @@ BOOL user_downloaded_file(scfg_t* cfg, user_t* user, client_t* client, && uploader.number != user->number && getuserdat(cfg, &uploader) == 0 && (uint32_t)uploader.firston < f.hdr.when_imported.time) { - ulong l = (ulong)f.cost; + uint64_t l = f.cost; if(!(cfg->dir[dirnum]->misc&DIR_CDTDL)) /* Don't give credits on d/l */ l=0; - ulong mod=(ulong)(l*(cfg->dir[dirnum]->dn_pct/100.0)); - adjustuserrec(cfg, uploader.number, U_CDT, 10, mod); + uint64_t mod=(uint64_t)(l*(cfg->dir[dirnum]->dn_pct/100.0)); + adjustuserrec(cfg, uploader.number, U_CDT, mod); if(cfg->text != NULL && !(cfg->dir[dirnum]->misc&DIR_QUIET)) { char str[256]; char tmp[128]; char prefix[128]=""; - ultoac(mod,tmp); + u64toac(mod,tmp,','); const char* alias = user->alias[0] ? user->alias : cfg->text[UNKNOWN_USER]; char username[64]; if(client != NULL && uploader.level >= SYSOP_LEVEL) { @@ -2530,7 +2560,7 @@ BOOL user_downloaded_file(scfg_t* cfg, user_t* user, client_t* client, SAFEPRINTF2(username,"%s [%s]", alias, client->addr); } else SAFECOPY(username, alias); - if(strcmp(cfg->dir[dirnum]->code, "TEMP") == 0 || bytes < (ulong)f.size) + if(strcmp(cfg->dir[dirnum]->code, "TEMP") == 0 || bytes < f.size) SAFECOPY(prefix, cfg->text[Partially]); if(client != NULL) { SAFECAT(prefix, client->protocol); @@ -2555,10 +2585,10 @@ BOOL user_downloaded_file(scfg_t* cfg, user_t* user, client_t* client, /****************************/ user_downloaded(cfg, user, /* files: */1, bytes); if(!is_download_free(cfg, dirnum, user, client)) - subtract_cdt(cfg, user, (long)f.cost); + subtract_cdt(cfg, user, f.cost); if(!(cfg->dir[dirnum]->misc&DIR_NOSTAT)) - inc_sys_download_stats(cfg, /* files: */1, (ulong)bytes); + inc_sys_download_stats(cfg, /* files: */1, (ulong)bytes); // TODO: remove ulong typecast smb_freefilemem(&f); return TRUE; @@ -2570,13 +2600,13 @@ BOOL user_uploaded(scfg_t* cfg, user_t* user, int files, off_t bytes) if(user==NULL) return(FALSE); - user->uls=(ushort)adjustuserrec(cfg, user->number, U_ULS, 5, files); - user->ulb=adjustuserrec(cfg, user->number, U_ULB, 10, (long)bytes); + user->uls=(ushort)adjustuserrec(cfg, user->number, U_ULS, files); + user->ulb=adjustuserrec(cfg, user->number, U_ULB, bytes); return(TRUE); } -BOOL user_adjust_credits(scfg_t* cfg, user_t* user, long amount) +BOOL user_adjust_credits(scfg_t* cfg, user_t* user, int64_t amount) { if(user==NULL) return(FALSE); @@ -2584,7 +2614,7 @@ BOOL user_adjust_credits(scfg_t* cfg, user_t* user, long amount) if(amount<0) /* subtract */ subtract_cdt(cfg, user, -amount); else /* add */ - user->cdt=adjustuserrec(cfg, user->number, U_CDT, 10, amount); + user->cdt=adjustuserrec(cfg, user->number, U_CDT, amount); return(TRUE); } @@ -2594,7 +2624,7 @@ BOOL user_adjust_minutes(scfg_t* cfg, user_t* user, long amount) if(user==NULL) return(FALSE); - user->min=adjustuserrec(cfg, user->number, U_MIN, 10, amount); + user->min=(uint32_t)adjustuserrec(cfg, user->number, U_MIN, amount); return(TRUE); } @@ -2618,8 +2648,8 @@ BOOL logoutuserdat(scfg_t* cfg, user_t* user, time_t now, time_t logontime) putuserrec(cfg,user->number,U_LASTON,8,ultoa((ulong)now,str,16)); putuserrec(cfg,user->number,U_TLAST,5,ultoa(user->tlast,str,10)); - adjustuserrec(cfg,user->number,U_TIMEON,5,user->tlast); - adjustuserrec(cfg,user->number,U_TTODAY,5,user->tlast); + adjustuserrec(cfg,user->number,U_TIMEON,user->tlast); + adjustuserrec(cfg,user->number,U_TTODAY,user->tlast); /* Convert time_t to struct tm */ if(localtime_r(&now,&tm_now)==NULL) @@ -2655,8 +2685,8 @@ void resetdailyuserdat(scfg_t* cfg, user_t* user, BOOL write) if(write) putuserrec(cfg,user->number,U_PTODAY,5,"0"); /* free credits per day */ user->freecdt=cfg->level_freecdtperday[user->level]; - if(write) putuserrec(cfg,user->number,U_FREECDT,10 - ,ultoa(user->freecdt,str,10)); + if(write) putuserrec(cfg,user->number,U_FREECDT,0 + ,_ui64toa(user->freecdt,str,10)); /* time used today */ user->ttoday=0; if(write) putuserrec(cfg,user->number,U_TTODAY,5,"0"); @@ -2933,11 +2963,14 @@ int user_rec_len(int offset) /* 32-bit integers (10 decimal digits) */ case U_ULB: case U_DLB: - case U_CDT: case U_MIN: - case U_FREECDT: return(10); + /* 64-bit integers (20 decimal digits) */ + case U_CDT: + case U_FREECDT: + return 20; + /* 3 char strings */ case U_TMPEXT: return(3); diff --git a/src/sbbs3/userdat.h b/src/sbbs3/userdat.h index b8e4509e81..0ca7ac0239 100644 --- a/src/sbbs3/userdat.h +++ b/src/sbbs3/userdat.h @@ -81,12 +81,13 @@ DLLEXPORT uint userdatdupe(scfg_t*, uint usernumber, uint offset, uint datlen, c DLLEXPORT BOOL chk_ar(scfg_t*, uchar* str, user_t*, client_t*); /* checks access requirements */ +DLLEXPORT char* userbytestr(uint64_t bytes, char* str); DLLEXPORT int getuserrec(scfg_t*, int usernumber, int start, int length, char *str); DLLEXPORT int putuserrec(scfg_t*, int usernumber, int start, int length, const char *str); -DLLEXPORT ulong adjustuserrec(scfg_t*, int usernumber, int start, int length, long adj); +DLLEXPORT uint64_t adjustuserrec(scfg_t*, int usernumber, int start, int64_t adj); DLLEXPORT BOOL logoutuserdat(scfg_t*, user_t*, time_t now, time_t logontime); DLLEXPORT void resetdailyuserdat(scfg_t*, user_t*, BOOL write); -DLLEXPORT void subtract_cdt(scfg_t*, user_t*, long amt); +DLLEXPORT void subtract_cdt(scfg_t*, user_t*, uint64_t amt); DLLEXPORT int user_rec_len(int offset); DLLEXPORT BOOL can_user_access_all_libs(scfg_t*, user_t*, client_t*); DLLEXPORT BOOL can_user_access_all_dirs(scfg_t*, uint libnum, user_t*, client_t*); @@ -133,7 +134,7 @@ DLLEXPORT BOOL user_downloaded(scfg_t*, user_t*, int files, off_t bytes); DLLEXPORT BOOL user_downloaded_file(scfg_t*, user_t*, client_t*, uint dirnum, const char* filename, off_t bytes); DLLEXPORT BOOL user_uploaded(scfg_t*, user_t*, int files, off_t bytes); -DLLEXPORT BOOL user_adjust_credits(scfg_t*, user_t*, long amount); +DLLEXPORT BOOL user_adjust_credits(scfg_t*, user_t*, int64_t amount); DLLEXPORT BOOL user_adjust_minutes(scfg_t*, user_t*, long amount); DLLEXPORT time_t gettimeleft(scfg_t*, user_t*, time_t starttime); diff --git a/src/sbbs3/useredit.cpp b/src/sbbs3/useredit.cpp index c3521a081a..e83c649181 100644 --- a/src/sbbs3/useredit.cpp +++ b/src/sbbs3/useredit.cpp @@ -45,6 +45,7 @@ void sbbs_t::useredit(int usernumber) float f; long l; long kmode = K_LINE|K_EDIT|K_AUTODEL|K_TRIM; + int64_t adj; user_t user; struct tm tm; @@ -125,14 +126,15 @@ void sbbs_t::useredit(int usernumber) bprintf(text[UserEmails] ,user.emails,user.fbacks,getmail(&cfg,user.number,/* Sent: */FALSE, /* SPAM: */FALSE),user.etoday); - bprintf(text[UserUploads],ultoac(user.ulb,tmp),user.uls); + bprintf(text[UserUploads], byte_estimate_to_str(user.ulb, tmp, sizeof(tmp), 1, 1), user.uls); if(user.leech) SAFEPRINTF(str,text[UserLeech],user.leech); else str[0]=0; - bprintf(text[UserDownloads],ultoac(user.dlb,tmp),user.dls,str); - bprintf(text[UserCredits],ultoac(user.cdt,tmp) - ,ultoac(user.freecdt,tmp2),ultoac(cfg.level_freecdtperday[user.level],str)); + bprintf(text[UserDownloads],byte_estimate_to_str(user.dlb, tmp, sizeof(tmp), 1, 1) ,user.dls,str); + bprintf(text[UserCredits],byte_estimate_to_str(user.cdt, tmp, sizeof(tmp), 1, 1) + ,byte_estimate_to_str(user.freecdt, tmp2, sizeof(tmp2), 1, 1) + ,byte_estimate_to_str(cfg.level_freecdtperday[user.level], str, sizeof(str), 1, 1)); bprintf(text[UserMinutes],ultoac(user.min,tmp)); bprintf(text[UeditSecLevel],user.level); bprintf(text[UeditFlags],ltoaf(user.flags1,tmp),ltoaf(user.flags3,tmp2) @@ -433,9 +435,11 @@ void sbbs_t::useredit(int usernumber) break; case 'U': bputs(text[UeditUlBytes]); - ultoa(user.ulb,str,10); - if(getstr(str,10,K_NUMBER|K_LINE|K_EDIT|K_AUTODEL)) - putuserrec(&cfg,user.number,U_ULB,10,str); + _ui64toa(user.ulb,str,10); + if(getstr(str,19,K_UPPER|K_LINE|K_EDIT|K_AUTODEL)) { + user.ulb = parse_byte_count(str, 1); + putuserrec(&cfg,user.number,U_ULB,10,userbytestr(user.ulb, str)); + } if(sys_status&SS_ABORT) break; bputs(text[UeditUploads]); @@ -445,9 +449,11 @@ void sbbs_t::useredit(int usernumber) if(sys_status&SS_ABORT) break; bputs(text[UeditDlBytes]); - ultoa(user.dlb,str,10); - if(getstr(str,10,K_NUMBER|K_LINE|K_EDIT|K_AUTODEL)) - putuserrec(&cfg,user.number,U_DLB,10,str); + _ui64toa(user.dlb,str,10); + if(getstr(str,19,K_UPPER|K_LINE|K_EDIT|K_AUTODEL)) { + user.dlb = parse_byte_count(str, 1); + putuserrec(&cfg,user.number,U_DLB,10,userbytestr(user.dlb, str)); + } if(sys_status&SS_ABORT) break; bputs(text[UeditDownloads]); @@ -540,15 +546,13 @@ void sbbs_t::useredit(int usernumber) break; case '+': bputs(text[ModifyCredits]); - getstr(str,10,K_UPPER|K_LINE); - l=atol(str); - if(strstr(str,"M")) - l*=0x100000L; - else if(strstr(str,"K")) - l*=1024; - else if(strstr(str,"$")) - l*=cfg.cdt_per_dollar; - adjustuserrec(&cfg, user.number, U_CDT, 10, l); + if(getstr(str,10,K_UPPER|K_LINE)) { + if(strstr(str,"$")) + adj = strtoll(str, NULL, 10) * cfg.cdt_per_dollar; + else + adj = parse_byte_count(str, 1); + adjustuserrec(&cfg, user.number, U_CDT, adj); + } break; case '*': bputs(text[ModifyMinutes]); @@ -572,9 +576,11 @@ void sbbs_t::useredit(int usernumber) break; case '$': bputs(text[UeditCredits]); - ultoa(user.cdt,str,10); - if(getstr(str,10,K_NUMBER|K_LINE)) - putuserrec(&cfg,user.number,U_CDT,10,str); + _ui64toa(user.cdt,str,10); + if(getstr(str,19,K_UPPER|K_LINE|K_EDIT|K_AUTODEL)) { + user.cdt = parse_byte_count(str, 1); + putuserrec(&cfg,user.number,U_CDT,0,userbytestr(user.cdt, str)); + } break; case '/': bputs(text[SearchStringPrompt]); diff --git a/src/sbbs3/xtrn.cpp b/src/sbbs3/xtrn.cpp index 2dcca277da..3e457ee53b 100644 --- a/src/sbbs3/xtrn.cpp +++ b/src/sbbs3/xtrn.cpp @@ -2082,7 +2082,7 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch strncat(cmd,str, avail); break; case '$': /* Credits */ - strncat(cmd,ultoa(useron.cdt+useron.freecdt,str,10), avail); + strncat(cmd,_ui64toa(useron.cdt+useron.freecdt,str,10), avail); break; case '%': /* %% for percent sign */ strncat(cmd,"%", avail); diff --git a/src/sbbs3/xtrn_sec.cpp b/src/sbbs3/xtrn_sec.cpp index 518ccc8ab0..7f1313ec9f 100644 --- a/src/sbbs3/xtrn_sec.cpp +++ b/src/sbbs3/xtrn_sec.cpp @@ -567,7 +567,7 @@ void sbbs_t::xtrndat(const char *name, const char *dropdir, uchar type, ulong tl unixtodstr(&cfg,(time32_t)logontime,tmp); exitinfo.LoginDate = tmp; exitinfo.TimeLimit = cfg.level_timepercall[useron.level]; - exitinfo.Credit = useron.cdt; + exitinfo.Credit = (uint32_t)MIN(useron.cdt, UINT32_MAX); exitinfo.UserRecNum = useron.number; exitinfo.WantChat = (sys_status & SS_SYSPAGE); exitinfo.ScreenClear = (useron.misc & CLRSCRN); @@ -771,8 +771,8 @@ void sbbs_t::xtrndat(const char *name, const char *dropdir, uchar type, ulong tl user.fixed.RegExpDate = unixtojulian(useron.expire); user.fixed.ExpSecurityLevel = cfg.expired_level; user.fixed.LastConference = cursubnum; - user.fixed.ulTotDnldBytes = useron.dlb; - user.fixed.ulTotUpldBytes = useron.ulb; + user.fixed.ulTotDnldBytes = (uint32_t)MIN(useron.dlb, UINT32_MAX); + user.fixed.ulTotUpldBytes = (uint32_t)MIN(useron.ulb, UINT32_MAX); user.fixed.DeleteFlag = INT_TO_BOOL(useron.misc & DELETED); user.fixed.RecNum = useron.number; user.fixed.MsgsLeft = useron.posts + useron.emails + useron.fbacks; @@ -1066,7 +1066,7 @@ void sbbs_t::moduserdat(uint xtrnnum) truncsp(str); mod=atol(str)*1024L; if(mod) { - useron.dlb=adjustuserrec(&cfg,useron.number,U_DLB,10,mod); + useron.dlb=adjustuserrec(&cfg,useron.number,U_DLB,mod); subtract_cdt(&cfg,&useron,mod); } } @@ -1125,7 +1125,7 @@ void sbbs_t::moduserdat(uint xtrnnum) } logline(tmp,str); if(mod>0L) /* always add to real cdt */ - useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,mod); + useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,mod); else subtract_cdt(&cfg,&useron,-mod); /* subtract from free cdt first */ } @@ -1176,7 +1176,7 @@ void sbbs_t::moduserdat(uint xtrnnum) if(mod) { SAFEPRINTF(str,"Minute Adjustment: %s",ultoac(mod,tmp)); logline("*+",str); - useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,mod); + useron.min=(uint32_t)adjustuserrec(&cfg,useron.number,U_MIN,mod); } } if(fgets(str,81,stream)) { /* flags #3 */ -- GitLab