diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c index ada3b2ded35b407dc6b006870540af20904f6438..be8f0c90f1cf61c25e0a328437ce822580964f98 100644 --- a/src/sbbs3/userdat.c +++ b/src/sbbs3/userdat.c @@ -2217,66 +2217,73 @@ int getuserrec(scfg_t* cfg, int usernumber,int start, int length, char *str) } /****************************************************************************/ -/* Places into user.dat at the offset for usernumber+start for length bytes */ -/* Called from various locations */ +/* Write a string (str) into user.dat at the offset for usernumber + start */ +/* 'length' may be auto-determined (from 'start') by passing 0 for length */ +/* If 'str' is longer than 'length', only 'length' characters are written */ /****************************************************************************/ -int putuserrec(scfg_t* cfg, int usernumber,int start, uint length, const char *str) +int putuserrec(scfg_t* cfg, int usernumber, int start, int length, const char *str) { - char str2[256]; + const char* p; + char buf[256]; + char path[MAX_PATH + 1]; int file; - uint c,i; + uint i; - if(!VALID_CFG(cfg) || usernumber<1 || str==NULL) - return(-1); + if(!VALID_CFG(cfg) || usernumber < 1 || str == NULL) + return -1; - if(length > sizeof(str2) - 1) - return -10; + if(length == 0) { /* auto-length */ + length = user_rec_len(start); + if(length < 1) + return -2; + } + size_t slen = strlen(str); + if(slen >= (size_t)length) + p = str; + else { + if(length > sizeof(buf)) + return -10; + memset(buf, ETX, length); + memcpy(buf, str, slen); + p = buf; + } - SAFEPRINTF(str2,"%suser/user.dat",cfg->data_dir); - if((file=nopen(str2,O_RDWR|O_DENYNONE))==-1) - return(errno); + SAFEPRINTF(path, "%suser/user.dat", cfg->data_dir); + if((file = nopen(path, O_RDWR|O_DENYNONE))==-1) + return errno; - if(filelength(file)<((long)usernumber-1)*U_LEN) { + off_t offset = (usernumber - 1) * U_LEN; + if(filelength(file) < offset) { close(file); - return(-4); - } - - if(length==0) { /* auto-length */ - length=user_rec_len(start); - if((long)length < 0) { - close(file); - return -2; - } + return -4; } - SAFECOPY(str2,str); - if(strlen(str2)<length) { - for(c=strlen(str2);c<length;c++) - str2[c]=ETX; - str2[c]=0; + offset += start; + if(lseek(file, offset, SEEK_SET) != offset) { + close(file); + return -5; } - lseek(file,(long)((long)((long)((long)usernumber-1)*U_LEN)+start),SEEK_SET); i=0; - while(i<LOOP_NODEDAB - && lock(file,(long)((long)(usernumber-1)*U_LEN)+start,length)==-1) { + while(i < LOOP_NODEDAB + && lock(file, offset, length) == -1) { if(i) mswait(100); i++; } - if(i>=LOOP_NODEDAB) { + if(i >= LOOP_NODEDAB) { close(file); - return(-3); + return -3; } - int wr = write(file, str2, length); - unlock(file,(long)((long)(usernumber-1)*U_LEN)+start,length); + int wr = write(file, p, length); + unlock(file, offset, length); close(file); if(wr != length) - return -4; - dirtyuserdat(cfg,usernumber); - return(0); + return -6; + dirtyuserdat(cfg, usernumber); + return 0; } /****************************************************************************/ diff --git a/src/sbbs3/userdat.h b/src/sbbs3/userdat.h index 2f47bfadbd4e32d46aeb31dbeec371e5a21073cc..9dc1d7915f344a0e30370550440c64759a69213e 100644 --- a/src/sbbs3/userdat.h +++ b/src/sbbs3/userdat.h @@ -81,7 +81,7 @@ 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 int getuserrec(scfg_t*, int usernumber, int start, int length, char *str); -DLLEXPORT int putuserrec(scfg_t*, int usernumber, int start, uint length, const 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 BOOL logoutuserdat(scfg_t*, user_t*, time_t now, time_t logontime); DLLEXPORT void resetdailyuserdat(scfg_t*, user_t*, BOOL write);