diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c index e1ce249401eb609de76e0cdd87f269af0b9ff85c..5a783de9f972cdb594d352cf6aa551f0224e2280 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 0e02a5e86b6dd7da987badf31f36e5b23ade70a7..0f8496aad49697565bec8e949b176cc07cd792a3 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 {