void CClientCreditsList::LoadList() { CString strFileName = thePrefs.GetConfigDir() + CLIENTS_MET_FILENAME; const int iOpenFlags = CFile::modeRead|CFile::osSequentialScan|CFile::typeBinary|CFile::shareDenyWrite; CSafeBufferedFile file; CFileException fexp; if (!file.Open(strFileName, iOpenFlags, &fexp)){ if (fexp.m_cause != CFileException::fileNotFound){ CString strError(GetResString(IDS_ERR_LOADCREDITFILE)); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){ strError += _T(" - "); strError += szError; } LogError(LOG_STATUSBAR, _T("%s"), strError); } return; } setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try{ uint8 version = file.ReadUInt8(); if (version != CREDITFILE_VERSION && version != CREDITFILE_VERSION_29){ LogWarning(GetResString(IDS_ERR_CREDITFILEOLD)); file.Close(); return; } // everything is ok, lets see if the backup exist... CString strBakFileName; strBakFileName.Format(_T("%s") CLIENTS_MET_FILENAME _T(".bak"), thePrefs.GetConfigDir()); DWORD dwBakFileSize = 0; BOOL bCreateBackup = TRUE; HANDLE hBakFile = ::CreateFile(strBakFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hBakFile != INVALID_HANDLE_VALUE) { // Ok, the backup exist, get the size dwBakFileSize = ::GetFileSize(hBakFile, NULL); //debug if (dwBakFileSize > (DWORD)file.GetLength()) { // the size of the backup was larger then the org. file, something is wrong here, don't overwrite old backup.. bCreateBackup = FALSE; } //else: backup is smaller or the same size as org. file, proceed with copying of file ::CloseHandle(hBakFile); } //else: the backup doesn't exist, create it if (bCreateBackup) { file.Close(); // close the file before copying if (!::CopyFile(strFileName, strBakFileName, FALSE)) LogError(GetResString(IDS_ERR_MAKEBAKCREDITFILE)); // reopen file CFileException fexp; if (!file.Open(strFileName, iOpenFlags, &fexp)){ CString strError(GetResString(IDS_ERR_LOADCREDITFILE)); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){ strError += _T(" - "); strError += szError; } LogError(LOG_STATUSBAR, _T("%s"), strError); return; } setvbuf(file.m_pStream, NULL, _IOFBF, 16384); file.Seek(1, CFile::begin); //set filepointer behind file version byte } UINT count = file.ReadUInt32(); m_mapClients.InitHashTable(count+5000); // TODO: should be prime number... and 20% larger const uint32 dwExpired = time(NULL) - 12960000; // today - 150 day uint32 cDeleted = 0; for (UINT i = 0; i < count; i++){ CreditStruct* newcstruct = new CreditStruct; MEMSET(newcstruct, 0, sizeof(CreditStruct)); if (version == CREDITFILE_VERSION_29) file.Read(newcstruct, sizeof(CreditStruct_29a)); else file.Read(newcstruct, sizeof(CreditStruct)); if (newcstruct->nLastSeen < dwExpired){ cDeleted++; delete newcstruct; continue; } CClientCredits* newcredits = new CClientCredits(newcstruct); m_mapClients.SetAt(CCKey(newcredits->GetKey()), newcredits); } file.Close(); if (cDeleted>0) AddLogLine(false, GetResString(IDS_CREDITFILELOADED) + GetResString(IDS_CREDITSEXPIRED), count-cDeleted,cDeleted); else AddLogLine(false, GetResString(IDS_CREDITFILELOADED), count); } catch(CFileException* error){ if (error->m_cause == CFileException::endOfFile) LogError(LOG_STATUSBAR, GetResString(IDS_CREDITFILECORRUPT)); else{ TCHAR buffer[MAX_CFEXP_ERRORMSG]; error->GetErrorMessage(buffer, ARRSIZE(buffer)); LogError(LOG_STATUSBAR, GetResString(IDS_ERR_CREDITFILEREAD), buffer); } error->Delete(); } }
bool CServerList::SaveServermetToFile() { if (thePrefs.GetLogFileSaving()) AddDebugLogLine(false, _T("Saving servers list file \"%s\""), SERVER_MET_FILENAME); m_nLastSaved = ::GetTickCount(); CString newservermet(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); newservermet += SERVER_MET_FILENAME _T(".new"); CSafeBufferedFile servermet; CFileException fexp; if (!servermet.Open(newservermet, CFile::modeWrite|CFile::modeCreate|CFile::typeBinary|CFile::shareDenyWrite, &fexp)){ CString strError(GetResString(IDS_ERR_SAVESERVERMET)); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){ strError += _T(" - "); strError += szError; } LogError(LOG_STATUSBAR, _T("%s"), strError); return false; } setvbuf(servermet.m_pStream, NULL, _IOFBF, 16384); try{ servermet.WriteUInt8(0xE0); UINT fservercount = list.GetCount(); servermet.WriteUInt32(fservercount); for (UINT j = 0; j < fservercount; j++) { const CServer* nextserver = GetServerAt(j); // don't write potential out-dated IPs of dynIP-servers servermet.WriteUInt32(nextserver->HasDynIP() ? 0 : nextserver->GetIP()); servermet.WriteUInt16(nextserver->GetPort()); UINT uTagCount = 0; ULONG uTagCountFilePos = (ULONG)servermet.GetPosition(); servermet.WriteUInt32(uTagCount); if (!nextserver->GetListName().IsEmpty()){ CTag servername(ST_SERVERNAME, nextserver->GetListName()); servername.WriteTagToFile(&servermet, utf8strOptBOM); uTagCount++; } if (!nextserver->GetDynIP().IsEmpty()){ CTag serverdynip(ST_DYNIP, nextserver->GetDynIP()); serverdynip.WriteTagToFile(&servermet, utf8strOptBOM); uTagCount++; } if (!nextserver->GetDescription().IsEmpty()){ CTag serverdesc(ST_DESCRIPTION, nextserver->GetDescription()); serverdesc.WriteTagToFile(&servermet, utf8strOptBOM); uTagCount++; } if (nextserver->GetFailedCount()){ CTag serverfail(ST_FAIL, nextserver->GetFailedCount()); serverfail.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetPreference() != SRV_PR_NORMAL){ CTag serverpref(ST_PREFERENCE, nextserver->GetPreference()); serverpref.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetUsers()){ CTag serveruser("users", nextserver->GetUsers()); serveruser.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetFiles()){ CTag serverfiles("files", nextserver->GetFiles()); serverfiles.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetPing()){ CTag serverping(ST_PING, nextserver->GetPing()); serverping.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetLastPingedTime()){ CTag serverlastp(ST_LASTPING, nextserver->GetLastPingedTime()); serverlastp.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetMaxUsers()){ CTag servermaxusers(ST_MAXUSERS, nextserver->GetMaxUsers()); servermaxusers.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetSoftFiles()){ CTag softfiles(ST_SOFTFILES, nextserver->GetSoftFiles()); softfiles.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetHardFiles()){ CTag hardfiles(ST_HARDFILES, nextserver->GetHardFiles()); hardfiles.WriteTagToFile(&servermet); uTagCount++; } if (!nextserver->GetVersion().IsEmpty()){ // as long as we don't receive an integer version tag from the local server (TCP) we store it as string CTag version(ST_VERSION, nextserver->GetVersion()); version.WriteTagToFile(&servermet, utf8strOptBOM); uTagCount++; } if (nextserver->GetUDPFlags()){ CTag tagUDPFlags(ST_UDPFLAGS, nextserver->GetUDPFlags()); tagUDPFlags.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetLowIDUsers()){ CTag tagLowIDUsers(ST_LOWIDUSERS, nextserver->GetLowIDUsers()); tagLowIDUsers.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetServerKeyUDP(true)){ CTag tagServerKeyUDP(ST_UDPKEY, nextserver->GetServerKeyUDP(true)); tagServerKeyUDP.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetServerKeyUDPIP()){ CTag tagServerKeyUDPIP(ST_UDPKEYIP, nextserver->GetServerKeyUDPIP()); tagServerKeyUDPIP.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetObfuscationPortTCP()){ CTag tagObfuscationPortTCP(ST_TCPPORTOBFUSCATION, nextserver->GetObfuscationPortTCP()); tagObfuscationPortTCP.WriteTagToFile(&servermet); uTagCount++; } if (nextserver->GetObfuscationPortUDP()){ CTag tagObfuscationPortUDP(ST_UDPPORTOBFUSCATION, nextserver->GetObfuscationPortUDP()); tagObfuscationPortUDP.WriteTagToFile(&servermet); uTagCount++; } servermet.Seek(uTagCountFilePos, CFile::begin); servermet.WriteUInt32(uTagCount); servermet.SeekToEnd(); } if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && !theApp.emuledlg->IsRunning())){ servermet.Flush(); // flush file stream buffers to disk buffers if (_commit(_fileno(servermet.m_pStream)) != 0) // commit disk buffers to disk AfxThrowFileException(CFileException::hardIO, GetLastError(), servermet.GetFileName()); } servermet.Close(); CString curservermet(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); CString oldservermet(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); curservermet += SERVER_MET_FILENAME; oldservermet += _T("server_met.old"); if (_taccess(oldservermet, 0) == 0) CFile::Remove(oldservermet); if (_taccess(curservermet, 0) == 0) CFile::Rename(curservermet,oldservermet); CFile::Rename(newservermet,curservermet); } catch(CFileException* error) { CString strError(GetResString(IDS_ERR_SAVESERVERMET2)); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (error->GetErrorMessage(szError, ARRSIZE(szError))){ strError += _T(" - "); strError += szError; } LogError(LOG_STATUSBAR, _T("%s"), strError); error->Delete(); return false; } return true; }