From 20cfdb185e469b22ec9152ff2f28e18b645f32b8 Mon Sep 17 00:00:00 2001 From: "Rob Swindell (on Windows 11)" <rob@synchro.net> Date: Thu, 12 Sep 2024 13:40:22 -0700 Subject: [PATCH] Split-up the opening and writing of msg pointer files, to help debug issue Reported by Keyop (upon being auto-disconnected overnight): !ERROR 9 (Bad file descriptor) in data_ovl.cpp line 47 (putmsgptrs) writing "message pointers" access=0 Unfortunately, the way putmsgptrs() was written, we couldn't tell if this was an open (data/user/*.subs file) issue or a writing issue. So create putmsgptrs_fp() and use that from sbbs_t::putmsgptrs(), so we can log a different error (with more accurate details) if it's a file-open failure versues a file-write failure. --- src/sbbs3/data_ovl.cpp | 15 +++++++++++++-- src/sbbs3/userdat.c | 35 +++++++++++++++++++++++++++-------- src/sbbs3/userdat.h | 4 ++++ 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/sbbs3/data_ovl.cpp b/src/sbbs3/data_ovl.cpp index 039c632dcc..6fd173ac2a 100644 --- a/src/sbbs3/data_ovl.cpp +++ b/src/sbbs3/data_ovl.cpp @@ -43,8 +43,19 @@ void sbbs_t::getmsgptrs() void sbbs_t::putmsgptrs() { - if(!::putmsgptrs(&cfg,&useron,subscan)) - errormsg(WHERE, ERR_WRITE, "message pointers", 0); + if(useron.number == 0 || useron.rest&FLAG('G')) + return; + char path[MAX_PATH + 1]; + msgptrs_filename(&cfg, useron.number, path, sizeof path); + const uint access = O_RDWR | O_CREAT | O_TEXT; + FILE* fp = fnopen(NULL, path, access); + if (fp == NULL) { + errormsg(WHERE, ERR_OPEN, path, access); + } else { + if(!putmsgptrs_fp(&cfg,&useron,subscan, fp)) + errormsg(WHERE, ERR_WRITE, "message pointers", 0); + fclose(fp); + } } void sbbs_t::reinit_msg_ptrs() diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c index f62cc873bc..9c7c2188c5 100644 --- a/src/sbbs3/userdat.c +++ b/src/sbbs3/userdat.c @@ -56,6 +56,12 @@ char* userdat_filename(scfg_t* cfg, char* path, size_t size) return path; } +char* msgptrs_filename(scfg_t* cfg, unsigned user_number, char* path, size_t size) +{ + safe_snprintf(path, size, "%suser/%4.4u.subs", cfg->data_dir, user_number); + return path; +} + /****************************************************************************/ /****************************************************************************/ void split_userdat(char *userdat, char* field[]) @@ -3973,7 +3979,7 @@ bool getmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan, void (*progress)( return initmsgptrs(cfg, subscan, cfg->guest_msgscan_init, progress, cbdata); /* New way: */ - SAFEPRINTF2(path,"%suser/%4.4u.subs", cfg->data_dir, user->number); + msgptrs_filename(cfg, user->number, path, sizeof path); FILE* fp = fnopen(NULL, path, O_RDONLY|O_TEXT); if (fp != NULL) { str_list_t ini = iniReadFile(fp); @@ -4032,12 +4038,30 @@ bool getmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan, void (*progress)( } /****************************************************************************/ -/* Writes to data/user/####.subs the msgptr array for the current user */ -/* Pass usernumber value of 0 to indicate "Guest" login */ +/* Writes to data/user/####.subs the msgptr array for the specified user */ /****************************************************************************/ bool putmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan) { char path[MAX_PATH+1]; + + if (user->number==0 || (user->rest&FLAG('G'))) /* Guest */ + return true; + + msgptrs_filename(cfg, user->number, path, sizeof path); + FILE* fp = fnopen(NULL, path, O_RDWR|O_CREAT|O_TEXT); + if (fp == NULL) + return false; + bool result = putmsgptrs_fp(cfg, user, subscan, fp); + fclose(fp); + + return result; +} + +/****************************************************************************/ +/* Writes to FILE* the msgptr array for the specified user */ +/****************************************************************************/ +bool putmsgptrs_fp(scfg_t* cfg, user_t* user, subscan_t* subscan, FILE* fp) +{ int i; time_t now = time(NULL); bool result = true; @@ -4046,10 +4070,6 @@ bool putmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan) return(true); fixmsgptrs(cfg, subscan); - SAFEPRINTF2(path,"%suser/%4.4u.subs", cfg->data_dir, user->number); - FILE* fp = fnopen(NULL, path, O_RDWR|O_CREAT|O_TEXT); - if (fp == NULL) - return false; str_list_t new = strListInit(); str_list_t ini = iniReadFile(fp); ini_style_t ini_style = { .key_prefix = "\t", .section_separator = "" }; @@ -4077,7 +4097,6 @@ bool putmsgptrs(scfg_t* cfg, user_t* user, subscan_t* subscan) result = iniWriteFile(fp, new); strListFree(&new); iniFreeStringList(ini); - fclose(fp); return result; } diff --git a/src/sbbs3/userdat.h b/src/sbbs3/userdat.h index bad512ecfd..137b3bf14c 100644 --- a/src/sbbs3/userdat.h +++ b/src/sbbs3/userdat.h @@ -22,6 +22,8 @@ #ifndef _USERDAT_H #define _USERDAT_H +#include <stdio.h> // FILE + #include "scfgdefs.h" /* scfg_t */ #include "client.h" /* client_t */ #include "link_list.h" @@ -38,6 +40,7 @@ extern "C" { #endif DLLEXPORT char* userdat_filename(scfg_t*, char*, size_t); +DLLEXPORT char* msgptrs_filename(scfg_t*, unsigned user_number, char*, size_t); DLLEXPORT int openuserdat(scfg_t*, bool for_modify); DLLEXPORT bool seekuserdat(int file, unsigned user_number); DLLEXPORT int closeuserdat(int file); @@ -164,6 +167,7 @@ DLLEXPORT bool user_set_time_property(scfg_t*, unsigned user_number, const char* DLLEXPORT bool newmsgs(smb_t*, time_t); DLLEXPORT bool getmsgptrs(scfg_t*, user_t*, subscan_t*, void (*progress)(void*, int, int), void* cbdata); DLLEXPORT bool putmsgptrs(scfg_t*, user_t*, subscan_t*); +DLLEXPORT bool putmsgptrs_fp(scfg_t*, user_t*, subscan_t*, FILE*); DLLEXPORT bool fixmsgptrs(scfg_t*, subscan_t*); DLLEXPORT bool initmsgptrs(scfg_t*, subscan_t*, unsigned days, void (*progress)(void*, int, int), void* cbdata); -- GitLab