// This file is a part of the xMule Project. // // Copyright (c) 2004 Theodore R. Smith (donate@xmule.org / http://xmule.hopto.org/) // RSA-1024 Fingerprint: 4145 9DFD 5338 4FCC 1636 86E5 2E5A 42D8 BA13 460B // // Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.xmule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License //as published by the Free Software Foundation; either //version 2 of the License, or (at your option) any later version. // //This program is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. // //You should have received a copy of the GNU General Public License //along with this program; if not, write to the Free Software //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifdef HAVE_CONFIG_H #include #endif // HAVE_CONFIG_H // Test if we have _GNU_SOURCE before the next step will mess up // setting __USE_GNU that we need for string.h to define basename // (only needed for gcc-2.95 compatibility, gcc 3.2 always defines it) #include "wx/setup.h" // Mario Sergio Fujikawa Ferreira // to detect if this is a *BSD system #if defined(HAVE_SYS_PARAM_H) #include #endif #ifdef PRECOMP # include "xmule-headers.h" #else # include "AddFileThread.h" # include "DownloadQueue.h" # include "muuli_wdr.h" # include "SharedFileList.h" # include "UploadQueue.h" # include "xmuleDlg.h" #endif #include #include #include #include #include #include // *BSD compatibility // required for basename(1) definition #if (defined(BSD) && (BSD >= 199103)) #include #endif // so we get basename(1) only if we have _GNU_SOURCE or BSD // what about other constellations ? -- let's try this: #ifndef __USE_GNU #include #endif #define GetDlgItem(X) (wxStaticCast(wxWindow::FindWindowById((X)),wxButton)) CSharedFileList:: CSharedFileList( CPreferences *in_prefs, CServerConnect *in_server, CKnownFileList *in_filelist) { app_prefs = in_prefs; server = in_server; filelist = in_filelist; output = 0; FindSharedFiles(); } CSharedFileList:: ~CSharedFileList() { } void CSharedFileList:: FindSharedFiles() { // Ovde se zajebavamo ;)) /* Abort loading if we are shutting down. */ if (!theApp.xmuledlg -> IsRunning()) { return; } /* All part files are automatically shared. */ if (!m_Files_map.empty()) { list_mut.Lock(); //neka napravi praznu listu m_Files_map.clear(); list_mut.Unlock(); //e dalje mu nedamo return; theApp.downloadqueue -> AddPartFilesToShare(); } /* Global incoming dir and all category incoming directories are automatically shared. */ AddFilesFromDirectory(theApp.glob_prefs -> GetIncomingDir()); for (int i = 1 ; i < theApp.glob_prefs -> GetCatCount() ; i++) { AddFilesFromDirectory(theApp. glob_prefs -> GetCatPath(i)); } for (int ij = 0 ; ij < app_prefs -> shareddir_list.GetCount() ; ij++) { if (!wxFileName:: DirExists(app_prefs -> shareddir_list.Item(ij))) { app_prefs -> shareddir_list.Remove(ij); --ij; } } for (int ii = 0 ; ii < app_prefs -> shareddir_list.GetCount() ; ii++) { AddFilesFromDirectory((char *) app_prefs -> shareddir_list.Item(ii) .GetData()); } uint32 newFiles = CAddFileThread:: GetCount(); if (!newFiles) { theApp.xmuledlg -> AddLogLine(false, GetResString(IDS_SHAREDFOUND), m_Files_map.size()); } else { theApp.xmuledlg -> AddLogLine(false, GetResString(IDS_SHAREDFOUNDHASHING), m_Files_map.size(), newFiles); } } void CSharedFileList:: AddFilesFromDirectory(char *directory) { char *searchpath = new char[strlen(directory) + 3]; if (directory[strlen(directory) - 1] != '/') { sprintf(searchpath, "%s/*", directory); } else { sprintf(searchpath, "%s*", directory); } wxString fname =:: wxFindFirstFile(searchpath, wxFILE); delete[] searchpath; if (fname.IsEmpty()) { return; } while (!fname.IsEmpty()) { wxFileName fName(fname); wxDateTime accTime, modTime, crtTime; fName.GetTimes( &accTime, &modTime, &crtTime); uint32 fdate = modTime.GetTicks(); int koko; struct stat sbf; stat(fname.GetData(), &sbf); koko = sbf.st_size; CKnownFile *toadd = filelist -> FindKnownFile((char *) fName.GetFullName() .GetData(), fdate, koko); if (toadd) { if (m_Files_map.find(CCKey(toadd -> GetFileHash())) == m_Files_map.end()) { toadd -> SetPath(directory); output -> ShowFile(toadd); list_mut.Lock(); m_Files_map[CCKey(toadd -> GetFileHash()) ] = toadd; list_mut.Unlock(); } else { if (wxStrcmp(fName.GetFullName() .GetData(), toadd -> GetFileName())) printf( "Warning: File '%s' already shared as '%s'\n", fName.GetFullName() .GetData(), toadd -> GetFileName()); } } else { CAddFileThread:: AddFile(directory, fName.GetFullName() .GetData()); } fname =:: wxFindNextFile(); } } void CSharedFileList:: SafeAddKFile(CKnownFile *toadd, bool bOnlyAdd) { list_mut.Lock(); if (m_Files_map.find(CCKey( toadd -> GetFileHash())) != m_Files_map.end()) { list_mut.Unlock(); return; } m_Files_map[CCKey(toadd -> GetFileHash()) ] = toadd; list_mut.Unlock(); if (bOnlyAdd) { output -> ShowFile(toadd); return; } if (output) { output -> ShowFile( toadd); } if (!server -> IsConnected()) { return; } CMemFile *files = new CMemFile(100); uint32 filecount = 1; files -> Write( &filecount, 4); CreateOfferedFilePacket(toadd, files); Packet *packet = new Packet(files); packet -> opcode = OP_OFFERFILES; CServer *cur_server=server->GetCurrentServer(); if (cur_server) { if(cur_server->GetTCPFlags()&0x00000001) { packet->PackPacket(); } } delete files; theApp.uploadqueue -> AddUpDataOverheadServer(packet -> size); server -> SendPacket(packet, true); } void CSharedFileList:: RemoveFile(CKnownFile *toremove) { output -> RemoveFile(toremove); m_Files_map.erase(CCKey( toremove -> GetFileHash())); } void CSharedFileList:: Reload(bool sendtoserver, bool firstload) { if (GetDlgItem(IDC_RELOADSHAREDFILES) -> GetLabel() == GetResString(IDS_SF_RELOAD)) { GetDlgItem(IDC_RELOADSHAREDFILES) -> SetLabel(wxT("Loading...")); output -> DeleteAllItems(); this -> FindSharedFiles(); if ((output) && (firstload == false)) output -> ShowFileList(this); if (sendtoserver) SendListToServer(); GetDlgItem(IDC_RELOADSHAREDFILES) -> SetLabel(GetResString(IDS_SF_RELOAD)); } output -> InitSort(); } void CSharedFileList:: SetOutputCtrl(CSharedFilesCtrl *in_ctrl) { output = in_ctrl; output -> ShowFileList(this); } void CSharedFileList:: SendListToServer() { if (m_Files_map.empty() || !server -> IsConnected()) return; CMemFile *files = new CMemFile(); uint32 filecount = m_Files_map.size(); files -> Write( &filecount, 4); for (CKnownFileMap:: iterator pos = m_Files_map.begin() ; pos != m_Files_map.end() ; pos++) { CreateOfferedFilePacket(pos -> second, files); } Packet *packet = new Packet(files); packet -> opcode = OP_OFFERFILES; CServer *cur_server=server->GetCurrentServer(); if (cur_server) { if(cur_server->GetTCPFlags()&0x00000001) { packet->PackPacket(); } } delete files; theApp.uploadqueue -> AddUpDataOverheadServer(packet -> size); server -> SendPacket(packet, true); } CKnownFile *CSharedFileList:: GetFileByIndex(int index) { int count = 0; for (CKnownFileMap:: iterator pos = m_Files_map.begin() ; pos != m_Files_map.end() ; pos++) { if (index == count) return pos -> second; count++; } return 0; } void CSharedFileList:: CreateOfferedFilePacket(CKnownFile *cur_file, CMemFile *files) { files -> Write(cur_file -> GetFileHash(), 16); char *buffer = new char[6]; memset(buffer, 0, 6); files -> Write(buffer, 6); delete[] buffer; files -> Write(cur_file -> GetFileTypePtr(), 4); CTag *nametag = new CTag(FT_FILENAME, cur_file -> GetFileName()); nametag -> WriteTagToFile(files); delete nametag; CTag *sizetag = new CTag(FT_FILESIZE, cur_file -> GetFileSize()); sizetag -> WriteTagToFile(files); delete sizetag; } uint64 CSharedFileList:: GetDatasize() { uint64 fsize; fsize = 0; for (CKnownFileMap:: iterator pos = m_Files_map. begin() ; pos != m_Files_map.end() ; pos++) { fsize += pos -> second -> GetFileSize(); } return fsize; } CKnownFile *CSharedFileList:: GetFileByID(uchar *filehash) { CCKey tkey(filehash); if (m_Files_map.find(tkey) != m_Files_map.end()) return m_Files_map[tkey]; else return 0; } short CSharedFileList:: GetFilePriorityByID(uchar *filehash) { CKnownFile *tocheck = GetFileByID(filehash); if (tocheck) return tocheck -> GetUpPriority(); else return - 10; } void CSharedFileList:: UpdateItem(CKnownFile *toupdate) { output -> UpdateItem(toupdate); } void CSharedFileList:: GetSharedFilesByDirectory(const char *directory, CTypedPtrList < CPtrList, CKnownFile *> &list) { for (CKnownFileMap:: iterator pos = m_Files_map.begin() ; pos != m_Files_map.end() ; pos++) { CKnownFile *cur_file = pos -> second; if (0 != strcmp(cur_file -> GetPath(), directory)) continue; list.AddTail(cur_file); } }