home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************************
-
- Gnucleus - A node application for the Gnutella network
- Copyright (C) 2000 John Marshall
-
- 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.
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- For support, questions, comments, etc...
- E-Mail:
- swabby@c0re.net
-
- Address:
- 21 Cadogan Way
- Nashua, NH, USA 03062
-
- ********************************************************************************/
-
- // GnucleusDoc.cpp : implementation of the CGnucleusDoc class
- //
-
- #include "stdafx.h"
- #include "GnucleusDoc.h"
-
- #include "Gnucleus.h"
- #include "ViewSearch.h"
- #include "ViewSearchSpy.h"
- #include "MainFrm.h"
-
- #include "GnuTransfer.h"
- #include "GnuHash.h"
- #include "GnuControl.h"
-
- #include "IPFilter.h"
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- void CGnucleusDoc::QueueCache::PurgeEarliestHostPort(void)
- {
- using namespace std;
- list<set<CString>::iterator>::iterator iter =
- mHostPortsQueue.begin();
- mHostPorts.erase(*iter);
- mHostPortsQueue.pop_front();
- }
-
- void CGnucleusDoc::QueueCache::AppendLatestHostPort
- (
- const CString& inHostPort
- )
- {
- using namespace std;
- set<CString>::iterator setIter =
- mHostPorts.insert(inHostPort).first;
- mHostPortsQueue.push_back(setIter);
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CGnucleusDoc
-
- IMPLEMENT_DYNCREATE(CGnucleusDoc, CDocument)
-
- BEGIN_MESSAGE_MAP(CGnucleusDoc, CDocument)
- //{{AFX_MSG_MAP(CGnucleusDoc)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- // DO NOT EDIT what you see in these blocks of generated code!
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CGnucleusDoc construction/destruction
-
- CGnucleusDoc::CGnucleusDoc()
- {
- GnuComm = new CGnuControl(this);
-
- TotalHosts = 0;
- m_EstSpeed = 0;
-
- ActiveUploads = 0;
-
- m_readCount = 0;
- m_writeCount = 0;
-
- m_hLangDLL = NULL;
-
- // Load INI, Host file, and shared directories
- ReadINI();
- ReadHostsFile ();
- LoadShare();
- }
-
- CGnucleusDoc::~CGnucleusDoc()
- {
- delete GnuComm;
-
- WriteINI();
- WriteHostsFile();
-
- CIPFilter::Shutdown ();
- }
-
- BOOL CGnucleusDoc::OnNewDocument()
- {
- if (!CDocument::OnNewDocument())
- return FALSE;
-
- TotalHosts = 0;
- // TODO: add reinitialization code here
- // (SDI documents will reuse this document)
-
- return TRUE;
- }
-
- void CGnucleusDoc::UpdateSearchViews(packet_QueryReply *QueryReply)
- {
- bool Found = 0;
- CString Title;
- POSITION pos = GetFirstViewPosition();
-
-
- while (pos != NULL)
- {
- CView* pView = GetNextView(pos);
-
- pView->GetParentFrame()->GetWindowText(Title);
-
- if(Title.Find("Searching for \"") != -1)
- if(((CViewSearch *) pView)->myGuid == QueryReply->Header.Guid)
- {
- ((CViewSearch *) pView)->UpdateResults((byte *) QueryReply);
-
- return;
- }
- }
- }
-
- void CGnucleusDoc::ReadHostsFile()
- {
- CStdioFile infile;
- CString hostFile = "Gnucleus.net";
-
- if (infile.Open(hostFile, CFile::modeCreate | CFile::modeNoTruncate
- | CFile::modeRead))
- {
- CString HostPort;
- while (infile.ReadString(HostPort))
- {
- int a=-1, b=-1, c=-1, d=-1;
- ::sscanf (HostPort, "%d.%d.%d.%d", &a, &b, &c, &d);
-
- if (a > 0 && b > -1 && c > -1 && d > -1)
- {
- if (CIPFilter::IsPrivateIP(a, b, c, d, a, b, c, d) == 0 &&
- CIPFilter::AllowIP (a, b, c, d))
- {
- HostPort.Remove('\r');
- HostPort.Remove('\n');
- SavedHosts.AddTail(HostPort);
- }
- }
- }
- infile.Close();
- }
- }
-
-
- void CGnucleusDoc::WriteHostsFile()
- {
- CString HostPort, OldHost;
- CString hostFile = "Gnucleus.net";
-
- using namespace std;
-
- while (mQueueCache.mHostPortsQueue.size())
- {
- list<set<CString>::iterator>::iterator iter =
- mQueueCache.mHostPortsQueue.begin();
- while (SavedHosts.GetCount() >= 500)
- {
- OldHost = SavedHosts.RemoveTail();
- // TRACE("Removed old host %s from SavedHost\n",OldHost);
- }
- SavedHosts.AddHead(**iter);
- // TRACE("Adding %s to head of SavedHost\n", (LPCTSTR)(**iter));
- mQueueCache.PurgeEarliestHostPort();
- }
-
- CStdioFile outfile;
- if (outfile.Open( hostFile, CFile::modeCreate | CFile::modeWrite))
- {
-
- while( !SavedHosts.IsEmpty() )
- {
- HostPort = SavedHosts.RemoveHead();
- HostPort += "\r\n";
- outfile.WriteString(HostPort);
- }
-
- outfile.Close();
- }
- }
-
- void CGnucleusDoc::ReadINI()
- {
- char buffer[256];
- CString temp, convert, dir;
- CString iniFile = ".\\Gnucleus.ini";
-
- // Connect Settings
- GetPrivateProfileString("Connect", "Port", "0", buffer, 256, iniFile);
- m_ConstPort = atol(buffer);
-
- if(m_ConstPort)
- GnuComm->localPort = m_ConstPort;
-
- GetPrivateProfileString("Connect", "Speed", "0", buffer, 256, iniFile);
- m_ConnectSpeed = atol(buffer);
-
- GetPrivateProfileString("Connect", "Force IP", "0.0.0.0", buffer, 256, iniFile);
- CString strIP(buffer);
- m_ForceIP = StrtoIP(strIP);
-
- GetPrivateProfileString("Connect", "Monitor Type", "2", buffer, 256, iniFile);
- m_MonitorType = atoi(buffer);
-
- GetPrivateProfileString("Connect", "ConnectNum", "3", buffer, 256, iniFile);
- m_ConnectNum = atoi(buffer);
-
- GetPrivateProfileString("Connect", "Timeout", "4", buffer, 256, iniFile);
- m_TimeoutConnect = atoi(buffer);
-
- GetPrivateProfileString("Connect", "Drop for Incoming", "0", buffer, 256, iniFile);
- m_DropForIncoming = (0 != atoi(buffer));
-
- // Search Filter Settings
- int loop;
-
- for(loop = 0; ; ++loop)
- {
- temp.Format ("Item%ld", loop);
-
- if (GetPrivateProfileString ("Search Filter", temp, "", buffer, 256, iniFile) > 0)
- {
- convert = buffer;
-
- int pos = convert.Find(':');
-
- BlockedSearch Search;
- Search.Name = convert.Mid(pos + 1);
- Search.Permis = convert.GetAt(0);
-
- SearchFilter.push_back(Search);
- }
- else
- {
- break;
- }
- }
-
- if( SearchFilter.empty() )
- {
- BlockedSearch Search;
- Search.Name = "*.*";
- Search.Permis = 'A';
- SearchFilter.push_back(Search);
- }
-
- // Filter Settings
- for (loop = 0; ; ++loop)
- {
- temp.Format ("Item%ld", loop);
-
- if (GetPrivateProfileString ("IP Filter", temp, "", buffer, 256, iniFile) > 0)
- {
- convert = buffer;
- convert.Replace("*", "-1");
- convert.Replace('.', ':');
-
- CIPFilter::AddFilter (convert);
- }
- else
- {
- break;
- }
- }
-
- std::vector<CString> FilterList;
-
- CIPFilter::GetConfigStrings( FilterList );
-
- if( FilterList.empty() )
- CIPFilter::AddFilter("A:-1:-1:-1:-1");
-
- // Search Settings
- GetPrivateProfileString("Search", "Max Replies", "64", buffer, 256, iniFile);
- m_MaxReplies = atoi(buffer);
-
-
- // Download Settings
-
- char * default_dir = new char[MAX_PATH]; // for non default desktop directories
- LPITEMIDLIST lp_itemid_list;
- LPMALLOC lp_sh_malloc;
- SHGetMalloc(&lp_sh_malloc);
- SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &lp_itemid_list);
- SHGetPathFromIDList(lp_itemid_list, default_dir);
- lp_sh_malloc->Free(lp_itemid_list); // free ITEMID list
- // lp_sh_malloc->Release(); //?
- GetPrivateProfileString("Download", "DownloadDir", _T(default_dir), buffer, 256, iniFile);
- m_DownloadDir = buffer;
- delete [] default_dir;
-
- GetPrivateProfileString("Download", "Max Downloads", "2", buffer, 256, iniFile);
- m_MaxDownloads = atoi(buffer);
-
- GetPrivateProfileString("Download", "Auto Clear", "1", buffer, 256, iniFile);
- m_AutoClearDL = atoi(buffer) ? true : false;
-
- GetPrivateProfileString("Download", "Timeout", "15", buffer, 256, iniFile);
- m_TimeoutDownload = atoi(buffer);
-
- GetPrivateProfileString("Download", "Resume", "1", buffer, 256, iniFile);
- m_ResumeDL = atoi(buffer) ? true : false;
-
- // Upload Settings
- GetPrivateProfileString("Upload", "Max Uploads", "4", buffer, 256, iniFile);
- m_MaxUploads = atoi(buffer);
-
- GetPrivateProfileString("Upload", "Auto Clear", "1", buffer, 256, iniFile);
- m_AutoClearUL = atoi(buffer) ? true : false;
-
- for (loop = 0; ; ++loop)
- {
- temp.Format ("Dir%ld", loop);
-
-
- if (GetPrivateProfileString ("Share", temp, "", buffer, 256,
- iniFile) > 0)
- {
- dir = buffer;
-
- LockUploadData (true);
- SharedDirList.push_back(dir);
- SharedDirCount.push_back(0);
- SharedDirSize.push_back(0);
- UnlockUploadData (true);
- }
- else
- break;
- }
-
- // Bandwidth Settings
- GetPrivateProfileString("Bandwidth", "Drop for Downloads", "0", buffer, 256, iniFile);
- m_AutoDropDL = atoi(buffer) ? true : false;
-
- GetPrivateProfileString("Bandwidth", "Drop for Uploads", "0", buffer, 256, iniFile);
- m_AutoDropUL = atoi(buffer) ? true : false;
-
- GetPrivateProfileString("Bandwidth", "Total Limit", "0", buffer, 256, iniFile);
- m_LimitTotal = atoi(buffer);
-
- GetPrivateProfileString("Bandwidth", "Upload Limit", "0", buffer, 256, iniFile);
- m_LimitUp = atoi(buffer);
-
- GetPrivateProfileString("Bandwidth", "Visual", "1", buffer, 256, iniFile);
- m_BwVisual = atoi(buffer);
-
- // Language Settings
- GetPrivateProfileString("Language", "DLL_Selected", "Default", buffer, 256, iniFile);
- m_strLangDLLex = buffer;
-
- }
-
- void CGnucleusDoc::WriteINI()
- {
- CString temp,convert;
- CString iniFile = ".\\Gnucleus.ini";
-
- // Connect Settings
- WritePrivateProfileString("Connect", "Port", DWrdtoStr(m_ConstPort), iniFile);
-
- WritePrivateProfileString("Connect", "Speed", DWrdtoStr(m_ConnectSpeed), iniFile);
-
- WritePrivateProfileString("Connect", "Force IP", IPtoStr(m_ForceIP), iniFile);
-
- WritePrivateProfileString("Connect", "Monitor Type", DWrdtoStr(m_MonitorType), iniFile);
-
- WritePrivateProfileString("Connect", "ConnectNum", DWrdtoStr(m_ConnectNum), iniFile);
-
- WritePrivateProfileString("Connect", "Timeout", DWrdtoStr(m_TimeoutConnect), iniFile);
-
- WritePrivateProfileString("Connect", "Drop for Incoming", DWrdtoStr(m_DropForIncoming), iniFile);
-
- int loop;
- // Search Filter
- WritePrivateProfileString("Search Filter", NULL, NULL, iniFile); // First clear out the IPFilters ini file section
-
- std::vector<BlockedSearch>::iterator itSearch;
-
- for (loop = 0, itSearch = SearchFilter.begin (); itSearch != SearchFilter.end (); loop++, itSearch++)
- {
- temp.Format ("Item%ld", loop);
-
- convert = (*itSearch).
- Name;
-
- convert.Insert(0, ":");
- convert.Insert(0, (*itSearch).Permis);
-
- WritePrivateProfileString ("Search Filter", temp, convert,
- iniFile);
- }
-
- // Filter Settings
- WritePrivateProfileString("Filter", NULL, NULL, iniFile); //First clear out the IPFilters ini file section
-
- std::vector<CString>::iterator it;
- std::vector<CString> strings;
- CIPFilter::GetConfigStrings (strings); // Then get the new config strings to write out to the ini file
-
- for (loop = 0, it = strings.begin (); it != strings.end (); loop++, it++)
- {
- temp.Format ("Item%ld", loop);
- convert = *it;
- convert.Replace("-1", "*");
- convert.Replace(':', '.');
- convert.SetAt(1, ':');
-
- WritePrivateProfileString ("IP Filter", temp, convert, iniFile);
- }
-
- // Search Settings
- WritePrivateProfileString("Search", "Max Replies", DWrdtoStr(m_MaxReplies), iniFile);
-
- // Download Settings
- WritePrivateProfileString("Download", "DownloadDir", m_DownloadDir, iniFile);
-
- WritePrivateProfileString("Download", "Max Downloads", DWrdtoStr(m_MaxDownloads), iniFile);
-
- WritePrivateProfileString("Download", "Auto Clear", WrdtoStr( (int)m_AutoClearDL), iniFile);
-
- WritePrivateProfileString("Download", "Timeout", DWrdtoStr(m_TimeoutDownload), iniFile);
-
- WritePrivateProfileString("Download", "Resume", WrdtoStr( (int)m_ResumeDL), iniFile);
-
- // Upload Settings
- WritePrivateProfileString("Upload", "Max Uploads", DWrdtoStr(m_MaxUploads), iniFile);
-
- WritePrivateProfileString("Upload", "Auto Clear", WrdtoStr( (int)m_AutoClearUL), iniFile);
-
- // First clear out the IPFilters ini file section
- WritePrivateProfileString("Share", NULL, NULL, iniFile);
-
- LockUploadData (false);
- for (loop = 0, it = SharedDirList.begin (); it != SharedDirList.end ();
- loop++, it++)
- {
- temp.Format ("Dir%ld", loop);
-
- WritePrivateProfileString ("Share", temp, (*it), iniFile);
- }
- UnlockUploadData (false);
-
- // Bandwidth Settings
- WritePrivateProfileString("Bandwidth", "Drop for Downloads", WrdtoStr( (int)m_AutoDropDL), iniFile);
-
- WritePrivateProfileString("Bandwidth", "Drop for Uploads", WrdtoStr( (int)m_AutoDropUL), iniFile);
-
- WritePrivateProfileString("Bandwidth", "Total Limit", DWrdtoStr(m_LimitTotal), iniFile);
-
- WritePrivateProfileString("Bandwidth", "Upload Limit", DWrdtoStr(m_LimitUp), iniFile);
-
- WritePrivateProfileString("Bandwidth", "Visual", DWrdtoStr(m_BwVisual), iniFile);
-
- // Language Settings
- WritePrivateProfileString("Language", "DLL_Selected", m_strLangDLLex, iniFile);
-
-
- }
-
- void CGnucleusDoc::LoadShare()
- {
- CString Path;
-
- std::vector<CString>::iterator itDir;
- std::vector<DWORD>::iterator itCount;
- std::vector<DWORD>::iterator itSize;
-
- LockUploadData (true);
- for (itDir = SharedDirList.begin(), itCount = SharedDirCount.begin(), itSize = SharedDirSize.begin();
- itDir != SharedDirList.end(), itCount != SharedDirCount.end(), itSize != SharedDirSize.end();
- itDir++, itCount++, itSize++)
- {
- Path = (*itDir);
-
- if(Path.Find("Recursive") != -1)
- RecurseShare(Path.Mid(0, Path.Find(',')), 1, (*itCount), (*itSize));
- else
- RecurseShare(Path, 0, (*itCount), (*itSize));
- }
-
- UnlockUploadData (true);
- }
-
- void CGnucleusDoc::RecurseShare(CString File, bool doRecurse, DWORD &DirCount, DWORD &DirSize)
- {
- CFileFind finder;
-
- // build a string with wildcards
- CString strWildcard(File);
- CString file_name;
-
- if(strWildcard.GetAt( strWildcard.GetLength() - 1) != '\\')
- strWildcard += _T("\\*.*");
- else
- strWildcard += _T("*.*");
-
- // start working for files
- BOOL bWorking = finder.FindFile(strWildcard);
-
- while (bWorking)
- {
- bWorking = finder.FindNextFile();
-
- // skip . and .. files
- if (finder.IsDots())
- continue;
-
- // if it's a directory, recursively search it
- if (finder.IsDirectory())
- {
- CString str = finder.GetFilePath();
-
- if(doRecurse)
- RecurseShare(str, 1, DirCount, DirSize);
- }
- else
- {
- SharedFile addFile;
- addFile.FileDir = finder.GetFilePath();
- addFile.FileName = addFile.FileDir.Mid( addFile.FileDir.ReverseFind('\\') + 1);
- addFile.FileDir.MakeLower();
-
- SharedFiles.push_back(addFile);
- SharedSizes.push_back(finder.GetLength());
-
- DirCount++;
- DirSize += finder.GetLength();
- }
- }
-
- finder.Close();
- }
-
- void CGnucleusDoc::AddToQueueCache(const CString& inHostPort)
- {
- using namespace std;
-
- if (mQueueCache.mHostPorts.end() ==
- mQueueCache.mHostPorts.find(inHostPort))
- {
- if (500 == mQueueCache.mHostPortsQueue.size())
- mQueueCache.PurgeEarliestHostPort();
- mQueueCache.AppendLatestHostPort(inHostPort);
- }
- }
-
- void CGnucleusDoc::RemoveEarliestHostPort(CString* outHostPort)
- {
- ASSERT(outHostPort);
- outHostPort->Empty();
-
- using namespace std;
- if (!mQueueCache.mHostPortsQueue.empty())
- {
- list<set<CString>::iterator>::iterator iter =
- mQueueCache.mHostPortsQueue.begin();
- *outHostPort = **iter;
- mQueueCache.PurgeEarliestHostPort();
- }
- }
-
- void CGnucleusDoc::LockUploadData (bool writeAccess)
- {
- while (m_writeCount) // Writing blocks everyone
- {
- ::Sleep (20);
- }
-
- if (writeAccess)
- {
- m_writeCount++;
-
- ASSERT (m_writeCount == 1);
-
- while (m_readCount)
- {
- ::Sleep (20);
- }
- }
- else
- {
- m_readCount++;
- }
- }
-
- void CGnucleusDoc::UnlockUploadData (bool writeAccess)
- {
- if (writeAccess)
- {
- m_writeCount--;
-
- ASSERT (m_writeCount == 0);
- }
- else
- {
- m_readCount--;
-
- ASSERT (m_readCount >= 0);
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CGnucleusDoc serialization
-
- void CGnucleusDoc::Serialize(CArchive& ar)
- {
- if (ar.IsStoring())
- {
- // TODO: add storing code here
- }
- else
- {
- // TODO: add loading code here
- }
- }
-
- void CGnucleusDoc::UpdateSpy( CString searchText )
- {
- CString Title;
- POSITION pos = GetFirstViewPosition();
-
- while (pos != NULL)
- {
- CView* pView = GetNextView(pos);
-
- pView->GetParentFrame()->GetWindowText(Title);
-
- if(Title.Find("Search Spy") != -1)
- ((CViewSearchSpy *) pView)->AddSearchTerm( searchText );
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CGnucleusDoc diagnostics
-
- #ifdef _DEBUG
- void CGnucleusDoc::AssertValid() const
- {
- CDocument::AssertValid();
- }
-
- void CGnucleusDoc::Dump(CDumpContext& dc) const
- {
- CDocument::Dump(dc);
- }
- #endif //_DEBUG
-
- /////////////////////////////////////////////////////////////////////////////
- // CGnucleusDoc commands
-