From fb441e4efd6e89d918c17d42206a95ef66e0bf90 Mon Sep 17 00:00:00 2001 From: rswindell <> Date: Mon, 7 Dec 2015 09:16:05 +0000 Subject: [PATCH] Split getuserdat() into 3 functions: - openuserdat() - readuserdat() - parseuserdat() getuserdat() still exists and just calls those 3 functions. This allows other code (e.g. the control panel) to optimize iterative calls to getuserdat() by opening the file just once or even reading the entire contents at once and then parsing each user record from memory. Updated style of arguments in userdat.h (i.e. remove argument name if obvious from the type). --- src/sbbs3/userdat.c | 100 ++++++++++++++++++++++++++++++++++---------- src/sbbs3/userdat.h | 77 ++++++++++++++++++---------------- 2 files changed, 118 insertions(+), 59 deletions(-) diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c index e1ce249401..5a783de9f9 100644 --- a/src/sbbs3/userdat.c +++ b/src/sbbs3/userdat.c @@ -193,34 +193,45 @@ BOOL DLLCALL del_lastuser(scfg_t* cfg) return(TRUE); } - /****************************************************************************/ -/* Fills the structure 'user' with info for user.number from user.dat */ -/* Called from functions useredit, waitforcall and main_sec */ +/* Opens the user database returning the file descriptor or -1 on error */ /****************************************************************************/ -int DLLCALL getuserdat(scfg_t* cfg, user_t *user) +int DLLCALL openuserdat(scfg_t* cfg) { - char userdat[U_LEN+1],str[U_LEN+1]; - int i,file; - unsigned user_number; + char path[MAX_PATH+1]; - if(user==NULL) - return(-1); + if(!VALID_CFG(cfg)) + return(-1); - user_number=user->number; - memset(user,0,sizeof(user_t)); + SAFEPRINTF(path,"%suser/user.dat",cfg->data_dir); + return nopen(path,O_RDONLY|O_DENYNONE); +} + +/****************************************************************************/ +/* Locks and reads a single user record from an open user.dat file into a */ +/* buffer of U_LEN+1 in size. */ +/* Returns 0 on success. */ +/****************************************************************************/ +int DLLCALL readuserdat(scfg_t* cfg, unsigned user_number, char* userdat, int infile) +{ + int i,file; if(!VALID_CFG(cfg) || user_number<1) return(-1); - SAFEPRINTF(userdat,"%suser/user.dat",cfg->data_dir); - if((file=nopen(userdat,O_RDONLY|O_DENYNONE))==-1) - return(errno); + if(infile > 0) + file = infile; + else { + if((file = openuserdat(cfg)) < 0) + return file; + } if(user_number > (unsigned)(filelength(file)/U_LEN)) { - close(file); + if(file != infile) + close(file); return(-1); /* no such user record */ } + lseek(file,(long)((long)(user_number-1)*U_LEN),SEEK_SET); i=0; while(i<LOOP_NODEDAB @@ -229,21 +240,43 @@ int DLLCALL getuserdat(scfg_t* cfg, user_t *user) mswait(100); i++; } - if(i>=LOOP_NODEDAB) { - close(file); + if(file != infile) + close(file); return(-2); } if(read(file,userdat,U_LEN)!=U_LEN) { unlock(file,(long)((long)(user_number-1)*U_LEN),U_LEN); - close(file); + if(file != infile) + close(file); return(-3); } - unlock(file,(long)((long)(user_number-1)*U_LEN),U_LEN); - close(file); + if(file != infile) + close(file); + return 0; +} + +/****************************************************************************/ +/* Fills the structure 'user' with info for user.number from userdat */ +/* (a buffer representing a single user 'record' from the user.dat file */ +/****************************************************************************/ +int DLLCALL parseuserdat(scfg_t* cfg, char *userdat, user_t *user) +{ + char str[U_LEN+1]; + int i; + unsigned user_number; + + if(user==NULL) + return(-1); + + user_number=user->number; + memset(user,0,sizeof(user_t)); + if(!VALID_CFG(cfg) || user_number < 1) + return(-1); + /* The user number needs to be set here before calling chk_ar() below for user-number comparisons in AR strings to function correctly */ user->number=user_number; /* Signal of success */ @@ -352,7 +385,6 @@ int DLLCALL getuserdat(scfg_t* cfg, user_t *user) getrec(userdat,U_CHAT,8,str); user->chat=ahtoul(str); - /* Reset daily stats if not already logged on today */ if(user->ltoday || user->etoday || user->ptoday || user->ttoday) { time_t now; @@ -368,10 +400,34 @@ int DLLCALL getuserdat(scfg_t* cfg, user_t *user) resetdailyuserdat(cfg,user,/* write: */FALSE); } } - return(0); } +/****************************************************************************/ +/* Fills the structure 'user' with info for user.number from user.dat file */ +/****************************************************************************/ +int DLLCALL getuserdat(scfg_t* cfg, user_t *user) +{ + int retval; + int file; + char userdat[U_LEN+1]; + + if(!VALID_CFG(cfg) || user==NULL || user->number < 1) + return(-1); + + if((file = openuserdat(cfg)) < 0) + return file; + + memset(userdat, 0, sizeof(userdat)); + if((retval = readuserdat(cfg, user->number, userdat, file)) != 0) { + close(file); + return retval; + } + retval = parseuserdat(cfg, userdat, user); + close(file); + return retval; +} + /****************************************************************************/ /****************************************************************************/ static void dirtyuserdat(scfg_t* cfg, uint usernumber) diff --git a/src/sbbs3/userdat.h b/src/sbbs3/userdat.h index 0e02a5e86b..0f8496aad4 100644 --- a/src/sbbs3/userdat.h +++ b/src/sbbs3/userdat.h @@ -77,33 +77,36 @@ extern "C" { extern char* crlf; extern char* nulstr; -DLLEXPORT int DLLCALL getuserdat(scfg_t* cfg, user_t* user); /* Fill userdat struct with user data */ -DLLEXPORT int DLLCALL putuserdat(scfg_t* cfg, user_t* user); /* Put userdat struct into user file */ -DLLEXPORT int DLLCALL newuserdat(scfg_t* cfg, user_t* user); /* Create new userdat in user file */ -DLLEXPORT uint DLLCALL matchuser(scfg_t* cfg, const char *str, BOOL sysop_alias); /* Checks for a username match */ -DLLEXPORT char* DLLCALL alias(scfg_t* cfg, const char* name, char* buf); -DLLEXPORT int DLLCALL putusername(scfg_t* cfg, int number, char * name); -DLLEXPORT uint DLLCALL total_users(scfg_t* cfg); -DLLEXPORT uint DLLCALL lastuser(scfg_t* cfg); -DLLEXPORT BOOL DLLCALL del_lastuser(scfg_t* cfg); -DLLEXPORT uint DLLCALL getage(scfg_t* cfg, char *birthdate); -DLLEXPORT char* DLLCALL username(scfg_t* cfg, int usernumber, char * str); -DLLEXPORT char* DLLCALL usermailaddr(scfg_t* cfg, char* addr, const char* name); -DLLEXPORT int DLLCALL getnodedat(scfg_t* cfg, uint number, node_t *node, int* file); -DLLEXPORT int DLLCALL putnodedat(scfg_t* cfg, uint number, node_t *node, int file); -DLLEXPORT char* DLLCALL nodestatus(scfg_t* cfg, node_t* node, char* buf, size_t buflen); -DLLEXPORT void DLLCALL printnodedat(scfg_t* cfg, uint number, node_t* node); +DLLEXPORT int DLLCALL openuserdat(scfg_t*); +DLLEXPORT int DLLCALL readuserdat(scfg_t*, unsigned user_number, char* userdat, int infile); +DLLEXPORT int DLLCALL parseuserdat(scfg_t*, char* userdat, user_t*); +DLLEXPORT int DLLCALL getuserdat(scfg_t*, user_t*); /* Fill userdat struct with user data */ +DLLEXPORT int DLLCALL putuserdat(scfg_t*, user_t*); /* Put userdat struct into user file */ +DLLEXPORT int DLLCALL newuserdat(scfg_t*, user_t*); /* Create new userdat in user file */ +DLLEXPORT uint DLLCALL matchuser(scfg_t*, const char *str, BOOL sysop_alias); /* Checks for a username match */ +DLLEXPORT char* DLLCALL alias(scfg_t*, const char* name, char* buf); +DLLEXPORT int DLLCALL putusername(scfg_t*, int number, char * name); +DLLEXPORT uint DLLCALL total_users(scfg_t*); +DLLEXPORT uint DLLCALL lastuser(scfg_t*); +DLLEXPORT BOOL DLLCALL del_lastuser(scfg_t*); +DLLEXPORT uint DLLCALL getage(scfg_t*, char *birthdate); +DLLEXPORT char* DLLCALL username(scfg_t*, int usernumber, char * str); +DLLEXPORT char* DLLCALL usermailaddr(scfg_t*, char* addr, const char* name); +DLLEXPORT int DLLCALL getnodedat(scfg_t*, uint number, node_t *node, int* file); +DLLEXPORT int DLLCALL putnodedat(scfg_t*, uint number, node_t *node, int file); +DLLEXPORT char* DLLCALL nodestatus(scfg_t*, node_t* node, char* buf, size_t buflen); +DLLEXPORT void DLLCALL printnodedat(scfg_t*, uint number, node_t* node); DLLEXPORT void DLLCALL packchatpass(char *pass, node_t* node); DLLEXPORT char* DLLCALL unpackchatpass(char *pass, node_t* node); -DLLEXPORT char* DLLCALL getsmsg(scfg_t* cfg, int usernumber); -DLLEXPORT int DLLCALL putsmsg(scfg_t* cfg, int usernumber, char *strin); -DLLEXPORT char* DLLCALL getnmsg(scfg_t* cfg, int node_num); -DLLEXPORT int DLLCALL putnmsg(scfg_t* cfg, int num, char *strin); +DLLEXPORT char* DLLCALL getsmsg(scfg_t*, int usernumber); +DLLEXPORT int DLLCALL putsmsg(scfg_t*, int usernumber, char *strin); +DLLEXPORT char* DLLCALL getnmsg(scfg_t*, int node_num); +DLLEXPORT int DLLCALL putnmsg(scfg_t*, int num, char *strin); -DLLEXPORT uint DLLCALL userdatdupe(scfg_t* cfg, uint usernumber, uint offset, uint datlen, char *dat +DLLEXPORT uint DLLCALL userdatdupe(scfg_t*, uint usernumber, uint offset, uint datlen, char *dat ,BOOL del, BOOL next); -DLLEXPORT BOOL DLLCALL chk_ar(scfg_t* cfg, uchar* str, user_t*, client_t*); /* checks access requirements */ +DLLEXPORT BOOL DLLCALL chk_ar(scfg_t*, uchar* str, user_t*, client_t*); /* checks access requirements */ DLLEXPORT int DLLCALL getuserrec(scfg_t*, int usernumber, int start, int length, char *str); DLLEXPORT int DLLCALL putuserrec(scfg_t*, int usernumber, int start, uint length, const char *str); @@ -112,13 +115,13 @@ DLLEXPORT BOOL DLLCALL logoutuserdat(scfg_t*, user_t*, time_t now, time_t logont DLLEXPORT void DLLCALL resetdailyuserdat(scfg_t*, user_t*, BOOL write); DLLEXPORT void DLLCALL subtract_cdt(scfg_t*, user_t*, long amt); DLLEXPORT int DLLCALL user_rec_len(int offset); -DLLEXPORT BOOL DLLCALL can_user_access_sub(scfg_t* cfg, uint subnum, user_t* user, client_t* client); -DLLEXPORT BOOL DLLCALL can_user_read_sub(scfg_t* cfg, uint subnum, user_t* user, client_t* client); -DLLEXPORT BOOL DLLCALL can_user_post(scfg_t* cfg, uint subnum, user_t* user, client_t* client, uint* reason); -DLLEXPORT BOOL DLLCALL can_user_send_mail(scfg_t* cfg, enum smb_net_type, uint usernumber, user_t* user, uint* reason); -DLLEXPORT BOOL DLLCALL is_user_subop(scfg_t* cfg, uint subnum, user_t* user, client_t* client); -DLLEXPORT BOOL DLLCALL is_download_free(scfg_t* cfg, uint dirnum, user_t* user, client_t* client); -DLLEXPORT BOOL DLLCALL filter_ip(scfg_t* cfg, const char* prot, const char* reason, const char* host +DLLEXPORT BOOL DLLCALL can_user_access_sub(scfg_t*, uint subnum, user_t*, client_t* client); +DLLEXPORT BOOL DLLCALL can_user_read_sub(scfg_t*, uint subnum, user_t*, client_t* client); +DLLEXPORT BOOL DLLCALL can_user_post(scfg_t*, uint subnum, user_t*, client_t* client, uint* reason); +DLLEXPORT BOOL DLLCALL can_user_send_mail(scfg_t*, enum smb_net_type, uint usernumber, user_t*, uint* reason); +DLLEXPORT BOOL DLLCALL is_user_subop(scfg_t*, uint subnum, user_t*, client_t* client); +DLLEXPORT BOOL DLLCALL is_download_free(scfg_t*, uint dirnum, user_t*, client_t* client); +DLLEXPORT BOOL DLLCALL filter_ip(scfg_t*, const char* prot, const char* reason, const char* host ,const char* ip_addr, const char* username, const char* fname); /* New-message-scan pointer functions: */ @@ -129,16 +132,16 @@ DLLEXPORT BOOL DLLCALL initmsgptrs(scfg_t*, subscan_t*, unsigned days); /* New atomic numeric user field adjustment functions: */ -DLLEXPORT BOOL DLLCALL user_posted_msg(scfg_t* cfg, user_t* user, int count); -DLLEXPORT BOOL DLLCALL user_sent_email(scfg_t* cfg, user_t* user, int count, BOOL feedback); -DLLEXPORT BOOL DLLCALL user_downloaded(scfg_t* cfg, user_t* user, int files, long bytes); -DLLEXPORT BOOL DLLCALL user_uploaded(scfg_t* cfg, user_t* user, int files, long bytes); -DLLEXPORT BOOL DLLCALL user_adjust_credits(scfg_t* cfg, user_t* user, long amount); -DLLEXPORT BOOL DLLCALL user_adjust_minutes(scfg_t* cfg, user_t* user, long amount); +DLLEXPORT BOOL DLLCALL user_posted_msg(scfg_t*, user_t*, int count); +DLLEXPORT BOOL DLLCALL user_sent_email(scfg_t*, user_t*, int count, BOOL feedback); +DLLEXPORT BOOL DLLCALL user_downloaded(scfg_t*, user_t*, int files, long bytes); +DLLEXPORT BOOL DLLCALL user_uploaded(scfg_t*, user_t*, int files, long bytes); +DLLEXPORT BOOL DLLCALL user_adjust_credits(scfg_t*, user_t*, long amount); +DLLEXPORT BOOL DLLCALL user_adjust_minutes(scfg_t*, user_t*, long amount); -DLLEXPORT time_t DLLCALL gettimeleft(scfg_t* cfg, user_t* user, time_t starttime); +DLLEXPORT time_t DLLCALL gettimeleft(scfg_t*, user_t*, time_t starttime); -DLLEXPORT BOOL DLLCALL check_name(scfg_t* cfg, const char* name); +DLLEXPORT BOOL DLLCALL check_name(scfg_t*, const char* name); /* Login attempt/hack tracking */ typedef struct { -- GitLab