// Displays which channel the user is in, who's in the channel with them, // whether or not the channel is secured, and tells the user how to obtain // help void intro(int loc) { int nodes[20]; bout << "|#7You are in " << channels[loc - INST_LOC_CH1 + 1].name << wwiv::endl; who_online(nodes, loc); if (nodes[0]) { for (int i = 1; i <= nodes[0]; i++) { WUser u; application()->users()->ReadUser(&u, nodes[i]); if (((nodes[0] - i) == 1) && (nodes[0] >= 2)) { bout << "|#1" << u.GetName() << " |#7and "; } else { bout << "|#1" << u.GetName() << (((nodes[0] > 1) && (i != nodes[0])) ? "|#7, " : " "); } } } if (nodes[0] == 1) { bout << "|#7is here with you.\r\n"; } else if (nodes[0] > 1) { bout << "|#7are here with you.\r\n"; } else { bout << "|#7You are the only one here.\r\n"; } char szFileName[ MAX_PATH ]; sprintf(szFileName, "CHANNEL.%d", (loc + 1 - INST_LOC_CH1)); if (loc != INST_LOC_CH1 && File::Exists(szFileName)) { bout << "|#7This channel is |#1secured|#7.\r\n"; } bout << "|#7Type ? for help.\r\n"; }
bool LoadMenuSetup(int user_number) { if (!pSecondUserRec) { MenuSysopLog("Mem Error"); return false; } UnloadMenuSetup(); if (!user_number) { return false; } File userConfig(syscfg.datadir, CONFIG_USR); if (!userConfig.Exists()) { return false; } WUser user; application()->users()->ReadUser(&user, user_number); if (userConfig.Open(File::modeReadOnly | File::modeBinary)) { userConfig.Seek(user_number * sizeof(user_config), File::seekBegin); int len = userConfig.Read(pSecondUserRec, sizeof(user_config)); userConfig.Close(); if (len != sizeof(user_config) || !IsEqualsIgnoreCase(reinterpret_cast<char*>(pSecondUserRec->name), user.GetName())) { memset(pSecondUserRec, 0, sizeof(user_config)); strcpy(reinterpret_cast<char*>(pSecondUserRec->name), user.GetName()); return 0; } nSecondUserRecLoaded = user_number; return true; } return false; }
void ch_direct(const char *pszMessage, int loc, char *pszColorString, int node, int nOffSet) { if (strlen(pszMessage + nOffSet) == 0) { bout << "|#1[|#9Message required after using a / or > command.|#1]\r\n"; return; } instancerec ir; get_inst_info(node, &ir); char szMessage[ 512 ]; if (ir.loc == loc) { if (!strlen(pszMessage + nOffSet)) { bout << "|#1[|#9Message required after using a / or > command.|#1]\r\n"; return; } WUser u; application()->users()->ReadUser(&u, ir.user); char szUserName[ 81 ]; strcpy(szUserName, u.GetName()); sprintf(szMessage, "|#9From %.12s|#6 [to %s]|#1: %s%s", session()->user()->GetName(), szUserName, pszColorString, pszMessage + nOffSet + 1); for (int i = 1; i <= num_instances(); i++) { get_inst_info(i, &ir); if (ir.loc == loc && i != application()->GetInstanceNumber()) { send_inst_str(i, szMessage); } } bout << "|#1[|#9Message directed to " << szUserName << "|#1\r\n"; } else { bout << szMessage; bout.nl(); } }
int wusrinst(char *n) { instancerec ir; for (int i = 0; i <= num_instances(); i++) { get_inst_info(i, &ir); if (ir.flags & INST_FLAGS_ONLINE) { WUser user; application()->users()->ReadUser(&user, ir.user); if (IsEqualsIgnoreCase(user.GetName(), n)) { return i; } } } return 0; }
void WriteMenuSetup(int user_number) { if (!user_number) { return; } WUser user; application()->users()->ReadUser(&user, user_number); strcpy(pSecondUserRec->name, user.GetName()); File userConfig(syscfg.datadir, CONFIG_USR); if (!userConfig.Open(File::modeReadWrite | File::modeBinary | File::modeCreateFile)) { return; } userConfig.Seek(user_number * sizeof(user_config), File::seekBegin); userConfig.Write(pSecondUserRec, sizeof(user_config)); userConfig.Close(); }
void WriteMenuSetup(int nUserNum) { if (!nUserNum) { return; } WUser user; GetApplication()->GetUserManager()->ReadUser(&user, nUserNum); strcpy(pSecondUserRec->name, user.GetName()); WFile userConfig(syscfg.datadir, CONFIG_USR); if (!userConfig.Open(WFile::modeReadWrite | WFile::modeBinary | WFile::modeCreateFile)) { return; } userConfig.Seek(nUserNum * sizeof(user_config), WFile::seekBegin); userConfig.Write(pSecondUserRec, sizeof(user_config)); userConfig.Close(); }
void reset_files() { WUser user; WStatus* pStatus = GetApplication()->GetStatusManager()->BeginTransaction(); pStatus->SetNumUsers(0); GetSession()->bout.NewLine(); int nNumUsers = GetApplication()->GetUserManager()->GetNumberOfUserRecords(); WFile userFile(syscfg.datadir, USER_LST); if (userFile.Open(WFile::modeBinary | WFile::modeReadWrite)) { for (int i = 1; i <= nNumUsers; i++) { long pos = static_cast<long>(syscfg.userreclen) * static_cast<long>(i); userFile.Seek(pos, WFile::seekBegin); userFile.Read(&user.data, syscfg.userreclen); if (!user.IsUserDeleted()) { user.FixUp(); if (isr1(i, nNumUsers, user.GetName())) { pStatus->IncrementNumUsers(); } } else { memset(&user.data, 0, syscfg.userreclen); user.SetInactFlag(0); user.SetInactFlag(inact_deleted); } userFile.Seek(pos, WFile::seekBegin); userFile.Write(&user.data, syscfg.userreclen); if ((i % 10) == 0) { userFile.Close(); GetSession()->bout << i << "\r "; userFile.Open(WFile::modeBinary | WFile::modeReadWrite); } } userFile.Close(); } GetSession()->bout << "\r\n\r\n"; WFile namesFile(syscfg.datadir, NAMES_LST); if (!namesFile.Open(WFile::modeReadWrite | WFile::modeBinary | WFile::modeTruncate)) { std::cout << namesFile.GetFullPathName() << " NOT FOUND" << std::endl; GetApplication()->AbortBBS(true); } namesFile.Write(smallist, sizeof(smalrec) * pStatus->GetNumUsers()); namesFile.Close(); GetApplication()->GetStatusManager()->CommitTransaction(pStatus); }
bool check_dupes(const char *pszPhoneNumber) { int nUserNumber = find_phone_number(pszPhoneNumber); if (nUserNumber && nUserNumber != session()->usernum) { char szBuffer[ 255 ]; sprintf(szBuffer, " %s entered phone # %s", session()->user()->GetName(), pszPhoneNumber); sysoplog(szBuffer, false); ssm(1, 0, szBuffer); WUser user; application()->users()->ReadUser(&user, nUserNumber); sprintf(szBuffer, " also entered by %s", user.GetName()); sysoplog(szBuffer, false); ssm(1, 0, szBuffer); return true; } return false; }
void auto_purge() { char s[80]; unsigned int days = 0; int skipsl = 0; IniFile iniFile(FilePath(GetApplication()->GetHomeDir(), WWIV_INI), INI_TAG); if (iniFile.IsOpen()) { days = iniFile.GetNumericValue("AUTO_USER_PURGE"); skipsl = iniFile.GetNumericValue("NO_PURGE_SL"); } iniFile.Close(); if (days < 60) { if (days > 0) { sysoplog("!!! WARNING: Auto-Purge canceled [AUTO_USER_PURGE < 60]", false); sysoplog("!!! WARNING: Edit WWIV.INI and Fix this", false); } return; } time_t tTime = time(NULL); int nUserNumber = 1; sysoplogfi(false, "Auto-Purged Inactive Users (over %d days, SL less than %d)", days, skipsl); do { WUser user; GetApplication()->GetUserManager()->ReadUser(&user, nUserNumber); if (!user.IsExemptAutoDelete()) { unsigned int d = static_cast<unsigned int>((tTime - user.GetLastOnDateNumber()) / SECONDS_PER_DAY_FLOAT); // if user is not already deleted && SL<NO_PURGE_SL && last_logon // greater than AUTO_USER_PURGE days ago if (!user.IsUserDeleted() && user.GetSl() < skipsl && d > days) { sprintf(s, "*** AUTOPURGE: Deleted User: #%3.3d %s", nUserNumber, user.GetName()); sysoplog(s, false); deluser(nUserNumber); } } ++nUserNumber; } while (nUserNumber <= GetApplication()->GetStatusManager()->GetUserCount()); }
// // Returns user number // or 0 if user not found // or special value // // This function will remove the special characters from arround the searchString that are // used by the network and remote, etc. // // Special values: // // -1 = NEW USER // -2 = WWIVnet // -3 = Remote Command // -4 = Unknown Special Login // int finduser(const std::string searchString) { WUser user; guest_user = false; GetApplication()->GetUserManager()->SetUserWritesAllowed(true); if (searchString == "NEW") { return -1; } if (searchString == "!-@NETWORK@-!") { return -2; } if (searchString == "!-@REMOTE@-!") { return -3; } int nUserNumber = atoi(searchString.c_str()); if (nUserNumber > 0) { GetApplication()->GetUserManager()->ReadUser(&user, nUserNumber); if (user.IsUserDeleted()) { //printf( "DEBUG: User %s is deleted!\r\n", user.GetName() ); return 0; } return nUserNumber; } nUserNumber = GetApplication()->GetUserManager()->FindUser(searchString); if (nUserNumber == 0L) { return 0; } else { GetApplication()->GetUserManager()->ReadUser(&user, nUserNumber); if (user.IsUserDeleted()) { return 0; } else { if (IsEqualsIgnoreCase(user.GetName(), "GUEST")) { guest_user = true; GetApplication()->GetUserManager()->SetUserWritesAllowed(false); } return nUserNumber; } } }
// This function is called when a / sign is encountered at the beginning of // a message, used for whispering void ch_whisper(const char *pszMessage, char *pszColorString, int node, int nOffSet) { if (strlen(pszMessage + nOffSet) == 0) { bout << "|#1[|#9Message required after using a / or > command.|#1]\r\n"; return; } if (!node) { return; } instancerec ir; get_inst_info(node, &ir); char szText[ 512 ]; if (ir.loc >= INST_LOC_CH1 && ir.loc <= INST_LOC_CH10) { sprintf(szText, "|#9From %.12s|#6 [WHISPERED]|#2|#1:%s%s", session()->user()->GetName(), pszColorString, pszMessage + nOffSet); } else { strcpy(szText, pszMessage + nOffSet); } send_inst_str(node, szText); WUser u; application()->users()->ReadUser(&u, ir.user); bout << "|#1[|#9Message sent only to " << u.GetName() << "|#1]\r\n"; }
void show_chains(int *mapp, int *map) { char szBuffer[ 255 ]; GetSession()->bout.Color(0); GetSession()->bout.ClearScreen(); GetSession()->bout.NewLine(); bool abort = false; bool next = false; if (GetApplication()->HasConfigFlag(OP_FLAGS_CHAIN_REG) && chains_reg) { sprintf(szBuffer, "|#5 Num |#1%-42.42s|#2%-22.22s|#1%-5.5s", "Description", "Sponsored by", "Usage"); pla(szBuffer, &abort); if (okansi()) { sprintf(szBuffer, "|#%d %s", FRAME_COLOR, "\xDA\xC4\xC4\xC4\xC2\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC2\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC2\xC4\xC4\xC4\xC4\xC4\xBF"); } else { sprintf(szBuffer, " +---+-----------------------------------------+---------------------+-----+"); } pla(szBuffer, &abort); for (int i = 0; i < *mapp && !abort && !hangup; i++) { WUser user; strcat(szBuffer, ". "); if (okansi()) { GetApplication()->GetUserManager()->ReadUser(&user, chains_reg[map[i]].regby[0]); sprintf(szBuffer, " |#%d\xB3|#5%3d|#%d\xB3|#1%-41s|#%d\xB3|%2.2d%-21s|#%d\xB3|#1%5d|#%d\xB3", FRAME_COLOR, i + 1, FRAME_COLOR, chains[map[i]].description, FRAME_COLOR, (chains_reg[map[i]].regby[0]) ? 14 : 13, (chains_reg[map[i]].regby[0]) ? user.GetName() : "Available", FRAME_COLOR, chains_reg[map[i]].usage, FRAME_COLOR); pla(szBuffer, &abort); if (chains_reg[map[i]].regby[0] != 0) { for (int i1 = 1; i1 < 5 && !abort; i1++) { if (chains_reg[map[i]].regby[i1] != 0) { GetApplication()->GetUserManager()->ReadUser(&user, chains_reg[map[i]].regby[i1]); sprintf(szBuffer, " |#%d\xB3 \xBA%-41s\xB3|#2%-21s|#%d\xB3%5.5s\xB3", FRAME_COLOR, " ", user.GetName(), FRAME_COLOR, " "); pla(szBuffer, &abort); } } } } else { GetApplication()->GetUserManager()->ReadUser(&user, chains_reg[map[i]].regby[0]); sprintf(szBuffer, " |%3d|%-41.41s|%-21.21s|%5d|", i + 1, chains[map[i]].description, (chains_reg[map[i]].regby[0]) ? user.GetName() : "Available", chains_reg[map[i]].usage); pla(szBuffer, &abort); if (chains_reg[map[i]].regby[0] != 0) { for (int i1 = 1; i1 < 5; i1++) { if (chains_reg[map[i]].regby[i1] != 0) { GetApplication()->GetUserManager()->ReadUser(&user, chains_reg[map[i]].regby[i1]); sprintf(szBuffer, " | | |%-21.21s| |", (chains_reg[map[i]].regby[i1]) ? user.GetName() : "Available"); pla(szBuffer, &abort); } } } } } if (okansi()) { sprintf(szBuffer, "|#%d %s", FRAME_COLOR, "\xC0\xC4\xC4\xC4\xC1\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC1\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC1\xC4\xC4\xC4\xC4\xC4\xD9"); } else { sprintf(szBuffer, " +---+-----------------------------------------+---------------------+-----+"); } pla(szBuffer, &abort); } else { GetSession()->bout.DisplayLiteBar(" [ %s Online Programs ] ", syscfg.systemname); GetSession()->bout << "|#7\xDA\xC4\xC4\xC2\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC2\xC4\xC4\xC2\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xBF\r\n"; for (int i = 0; i < *mapp && !abort && !hangup; i++) { sprintf(szBuffer, "|#7\xB3|#2%2d|#7\xB3 |#1%-33.33s|#7\xB3", i + 1, chains[map[i]].description); osan(szBuffer, &abort, &next); i++; if (!abort && !hangup) { char szBuffer[ 255 ]; if (i >= *mapp) { sprintf(szBuffer, " |#7\xB3 |#7\xB3"); } else { sprintf(szBuffer, "|#2%2d|#7\xB3 |#1%-33.33s|#7\xB3", i + 1, chains[map[i]].description); } pla(szBuffer, &abort); } } GetSession()->bout << "|#7\xC0\xC4\xC4\xC1\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC1\xC4\xC4\xC1\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xD9\r\n"; } }
// Displays the list of chains to a user static void show_chains(int *mapp, int *map) { bout.Color(0); bout.cls(); bout.nl(); bool abort = false; bool next = false; if (application()->HasConfigFlag(OP_FLAGS_CHAIN_REG) && chains_reg) { pla(StringPrintf("|#5 Num |#1%-42.42s|#2%-22.22s|#1%-5.5s", "Description", "Sponsored by", "Usage"), &abort); if (okansi()) { pla(StringPrintf("|#%d %s", FRAME_COLOR, "\xDA\xC4\xC4\xC4\xC2\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC2\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC2\xC4\xC4\xC4\xC4\xC4\xBF"), &abort); } else { pla(StringPrintf(" +---+-----------------------------------------+---------------------+-----+"), &abort); } for (int i = 0; i < *mapp && !abort && !hangup; i++) { WUser user; if (okansi()) { application()->users()->ReadUser(&user, chains_reg[map[i]].regby[0]); pla(StringPrintf(" |#%d\xB3|#5%3d|#%d\xB3|#1%-41s|#%d\xB3|%2.2d%-21s|#%d\xB3|#1%5d|#%d\xB3", FRAME_COLOR, i + 1, FRAME_COLOR, chains[map[i]].description, FRAME_COLOR, (chains_reg[map[i]].regby[0]) ? 14 : 13, (chains_reg[map[i]].regby[0]) ? user.GetName() : "Available", FRAME_COLOR, chains_reg[map[i]].usage, FRAME_COLOR), &abort); if (chains_reg[map[i]].regby[0] != 0) { for (int i1 = 1; i1 < 5 && !abort; i1++) { if (chains_reg[map[i]].regby[i1] != 0) { application()->users()->ReadUser(&user, chains_reg[map[i]].regby[i1]); pla(StringPrintf(" |#%d\xB3 \xBA%-41s\xB3|#2%-21s|#%d\xB3%5.5s\xB3", FRAME_COLOR, " ", user.GetName(), FRAME_COLOR, " "), &abort); } } } } else { application()->users()->ReadUser(&user, chains_reg[map[i]].regby[0]); pla(StringPrintf(" |%3d|%-41.41s|%-21.21s|%5d|", i + 1, chains[map[i]].description, (chains_reg[map[i]].regby[0]) ? user.GetName() : "Available", chains_reg[map[i]].usage), &abort); if (chains_reg[map[i]].regby[0] != 0) { for (int i1 = 1; i1 < 5; i1++) { if (chains_reg[map[i]].regby[i1] != 0) { application()->users()->ReadUser(&user, chains_reg[map[i]].regby[i1]); pla(StringPrintf(" | | |%-21.21s| |", (chains_reg[map[i]].regby[i1]) ? user.GetName() : "Available"), &abort); } } } } } if (okansi()) { pla(StringPrintf("|#%d %s", FRAME_COLOR, "\xC0\xC4\xC4\xC4\xC1\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC1\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC1\xC4\xC4\xC4\xC4\xC4\xD9"), &abort); } else { pla(StringPrintf(" +---+-----------------------------------------+---------------------+-----+"), &abort); } } else { bout.litebar(" %s Online Programs ", syscfg.systemname); bout << "|#7\xDA\xC4\xC4\xC2\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC2\xC4\xC4\xC2\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xBF\r\n"; for (int i = 0; i < *mapp && !abort && !hangup; i++) { osan(StringPrintf("|#7\xB3|#2%2d|#7\xB3 |#1%-33.33s|#7\xB3", i + 1, chains[map[i]].description), &abort, &next); i++; if (!abort && !hangup) { if (i >= *mapp) { pla(StringPrintf(" |#7\xB3 |#7\xB3"), &abort); } else { pla(StringPrintf("|#2%2d|#7\xB3 |#1%-33.33s|#7\xB3", i + 1, chains[map[i]].description), &abort); } } } bout << "|#7\xC0\xC4\xC4\xC1\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC1\xC4\xC4\xC1\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xD9\r\n"; } }
int FixUsersCommand::Execute() { std::cout << "Runnning FixUsersCommand::Execute" << std::endl; File userFile(syscfg.datadir, USER_LST); if(!userFile.Exists()) { Print(NOK, true, "%s does not exist.", userFile.full_pathname().c_str()); giveUp(); } WUserManager userMgr; userMgr.InitializeUserManager(syscfg.datadir, sizeof(userrec), syscfg.maxusers); Print(OK, true, "Checking USER.LST... found %d user records.", userMgr.GetNumberOfUserRecords()); Print(OK, true, "TBD: Check for trashed user recs."); if(userMgr.GetNumberOfUserRecords() > syscfg.maxusers) { Print(OK, true, "Might be too many."); maybeGiveUp(); } else { Print(OK, true, "Reasonable number."); } std::vector<smalrec> smallrecords; std::set<std::string> names; const int num_user_records = userMgr.GetNumberOfUserRecords(); for(int i = 1; i <= num_user_records; i++) { WUser user; userMgr.ReadUser(&user, i); user.FixUp(); userMgr.WriteUser(&user, i); if (!user.IsUserDeleted() && !user.IsUserInactive()) { smalrec sr = { 0 }; strcpy((char*) sr.name, user.GetName()); sr.number = static_cast<unsigned short>(i); std::string namestring((char*) sr.name); if (names.find(namestring) == names.end()) { smallrecords.push_back(sr); names.insert(namestring); const std::string msg = StringPrintf("Keeping user: %s #%d", sr.name, sr.number); Print(OK, true, msg.c_str()); } else { std::cout << "[skipping duplicate user: "******" #" << sr.number << "]"; } } }; std::sort(smallrecords.begin(), smallrecords.end(), [](const smalrec& a, const smalrec& b) -> bool { int equal = strcmp((char*)a.name, (char*)b.name); // Sort by user number if names match. if (equal == 0) { return a.number < b.number; } // Otherwise sort by name comparison. return equal < 0; }); printf("size=%lu %lu\n", smallrecords.size(), sizeof(smalrec) * smallrecords.size()); Print(OK, true, "Checking NAMES.LST"); File nameFile(syscfg.datadir, NAMES_LST); if(!nameFile.Exists()) { Print(NOK, true, "%s does not exist, regenerating with %d names", nameFile.full_pathname().c_str(), smallrecords.size()); nameFile.Close(); nameFile.Open(File::modeCreateFile | File::modeBinary | File::modeWriteOnly); nameFile.Write(&smallrecords[0], sizeof(smalrec) * smallrecords.size()); nameFile.Close(); } else { if(nameFile.Open(File::modeReadOnly | File::modeBinary)) { unsigned long size = nameFile.GetLength(); unsigned short recs = static_cast<unsigned short>(size / sizeof(smalrec)); if (recs != status.users) { status.users = recs; Print(NOK, true, "STATUS.DAT contained an incorrect user count."); } else { Print(OK, true, "STATUS.DAT matches expected user count of %d users.", status.users); } } nameFile.Close(); } return 0; }