2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2008 Merkur ( devs@emule-project.net / http://www.emule-project.net )
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "amule.h" // Interface declarations.
34 #include <wx/process.h>
35 #include <wx/sstream.h>
38 #include "config.h" // Needed for HAVE_GETRLIMIT, HAVE_SETRLIMIT,
39 // HAVE_SYS_RESOURCE_H, HAVE_SYS_STATVFS_H, VERSION
43 #include <common/ClientVersion.h>
45 #include <wx/cmdline.h> // Needed for wxCmdLineParser
46 #include <wx/config.h> // Do_not_auto_remove (win32)
47 #include <wx/fileconf.h>
48 #include <wx/snglinst.h>
49 #include <wx/tokenzr.h>
50 #include <wx/wfstream.h>
53 #include <common/Format.h> // Needed for CFormat
54 #include "kademlia/kademlia/Kademlia.h"
55 #include "kademlia/kademlia/Prefs.h"
56 #include "kademlia/kademlia/UDPFirewallTester.h"
57 #include "ClientCreditsList.h" // Needed for CClientCreditsList
58 #include "ClientList.h" // Needed for CClientList
59 #include "ClientUDPSocket.h" // Needed for CClientUDPSocket & CMuleUDPSocket
60 #include "ED2KLink.h" // Needed for command line passing of links
61 #include "ExternalConn.h" // Needed for ExternalConn & MuleConnection
62 #include <common/FileFunctions.h> // Needed for CDirIterator
63 #include "FriendList.h" // Needed for CFriendList
64 #include "HTTPDownload.h" // Needed for CHTTPDownloadThread
65 #include "InternalEvents.h" // Needed for CMuleInternalEvent
66 #include "IPFilter.h" // Needed for CIPFilter
67 #include "KnownFileList.h" // Needed for CKnownFileList
68 #include "ListenSocket.h" // Needed for CListenSocket
69 #include "Logger.h" // Needed for CLogger // Do_not_auto_remove
70 #include "MagnetURI.h" // Needed for CMagnetURI
71 #include "OtherFunctions.h"
72 #include "PartFile.h" // Needed for CPartFile
73 #include "Preferences.h" // Needed for CPreferences
74 #include "SearchList.h" // Needed for CSearchList
75 #include "Server.h" // Needed for GetListName
76 #include "ServerList.h" // Needed for CServerList
77 #include "ServerConnect.h" // Needed for CServerConnect
78 #include "ServerUDPSocket.h" // Needed for CServerUDPSocket
79 #include "Statistics.h" // Needed for CStatistics
80 #include "TerminationProcessAmuleweb.h" // Needed for CTerminationProcessAmuleweb
81 #include "ThreadTasks.h"
82 #include "updownclient.h" // Needed for CUpDownClient
83 #include "UploadQueue.h" // Needed for CUploadQueue
84 #include "UploadBandwidthThrottler.h"
85 #include "UserEvents.h"
86 #include "ScopedPtr.h"
89 #include "UPnPBase.h" // Needed for UPnP
93 #include <wx/sysopt.h> // Do_not_auto_remove
98 #include <CoreFoundation/CFBundle.h> // Do_not_auto_remove
99 #if wxCHECK_VERSION(2, 9, 0)
100 #include <wx/osx/core/cfstring.h> // Do_not_auto_remove
102 #include <wx/mac/corefoundation/cfstring.h> // Do_not_auto_remove
105 #include <wx/msgdlg.h>
107 #include "amuleDlg.h"
111 #ifdef HAVE_SYS_RESOURCE_H
112 #include <sys/resource.h>
115 #ifdef HAVE_SYS_STATVFS_H
116 #include <sys/statvfs.h> // Do_not_auto_remove
121 # define RLIMIT_RESOURCE __rlimit_resource
123 # define RLIMIT_RESOURCE int
126 static void UnlimitResource(RLIMIT_RESOURCE resType
)
128 #if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
130 getrlimit(resType
, &rl
);
131 rl
.rlim_cur
= rl
.rlim_max
;
132 setrlimit(resType
, &rl
);
137 static void SetResourceLimits()
139 #ifdef HAVE_SYS_RESOURCE_H
140 UnlimitResource(RLIMIT_DATA
);
142 UnlimitResource(RLIMIT_FSIZE
);
144 UnlimitResource(RLIMIT_NOFILE
);
146 UnlimitResource(RLIMIT_RSS
);
151 // We store the received signal in order to avoid race-conditions
152 // in the signal handler.
153 bool g_shutdownSignal
= false;
155 void OnShutdownSignal( int /* sig */ )
157 signal(SIGINT
, SIG_DFL
);
158 signal(SIGTERM
, SIG_DFL
);
160 g_shutdownSignal
= true;
163 theApp
->ExitMainLoop();
168 CamuleApp::CamuleApp()
170 // Madcat - Initialize timer as the VERY FIRST thing to avoid any issues later.
171 // Kry - I love to init the vars on init, even before timer.
175 m_app_state
= APP_STATE_STARTING
;
177 theApp
= &wxGetApp();
183 serverconnect
= NULL
;
187 clientcredits
= NULL
;
189 downloadqueue
= NULL
;
192 ECServerHandler
= NULL
;
193 m_singleInstance
= NULL
;
196 uploadBandwidthThrottler
= NULL
;
199 m_upnpMappings
.resize(4);
207 enable_daemon_fork
= false;
209 strFullMuleVersion
= NULL
;
210 strOSDescription
= NULL
;
212 // Apprently needed for *BSD
216 CamuleApp::~CamuleApp()
218 // Closing the log-file as the very last thing, since
219 // wxWidgets log-events are saved in it as well.
220 theLogger
.CloseLogfile();
222 free(strFullMuleVersion
);
223 free(strOSDescription
);
226 int CamuleApp::OnExit()
228 if (m_app_state
!=APP_STATE_STARTING
) {
229 AddLogLineMS(false, _("Now, exiting main app..."));
232 // From wxWidgets docs, wxConfigBase:
234 // Note that you must delete this object (usually in wxApp::OnExit)
235 // in order to avoid memory leaks, wxWidgets won't do it automatically.
237 // As it happens, you may even further simplify the procedure described
238 // above: you may forget about calling Set(). When Get() is called and
239 // there is no current object, it will create one using Create() function.
240 // To disable this behaviour DontCreateOnDemand() is provided.
241 delete wxConfigBase::Set((wxConfigBase
*)NULL
);
244 clientcredits
->SaveList();
246 // Kill amuleweb if running
248 AddLogLineMS(false, CFormat(_("Killing amuleweb instance with pid `%ld' ... ")) % webserver_pid
);
250 wxKill(webserver_pid
, wxSIGTERM
, &rc
);
251 AddLogLineMS(false, _("Killed!"));
254 if (m_app_state
!=APP_STATE_STARTING
) {
255 AddLogLineMS(false, _("aMule OnExit: Terminating core."));
264 delete clientcredits
;
265 clientcredits
= NULL
;
270 // Destroying CDownloadQueue calls destructor for CPartFile
271 // calling CSharedFileList::SafeAddKFile occasionally.
275 delete serverconnect
;
276 serverconnect
= NULL
;
293 delete downloadqueue
;
294 downloadqueue
= NULL
;
304 delete ECServerHandler
;
305 ECServerHandler
= NULL
;
312 CPreferences::EraseItemList();
314 #if defined(__WXMAC__) && defined(AMULE_DAEMON)
315 //#warning TODO: fix wxSingleInstanceChecker for amuled on Mac (wx link problems)
317 delete m_singleInstance
;
319 m_singleInstance
= NULL
;
321 delete uploadBandwidthThrottler
;
322 uploadBandwidthThrottler
= NULL
;
324 if (m_app_state
!=APP_STATE_STARTING
) {
325 AddLogLineNS(_("aMule shutdown completed."));
328 #if wxUSE_MEMORY_TRACING
329 AddLogLineNS(_("Memory debug results for aMule exit:"));
330 // Log mem debug mesages to wxLogStderr
331 wxLog
* oldLog
= wxLog::SetActiveTarget(new wxLogStderr
);
332 //AddLogLineNS(wxT("**************Classes**************");
333 //wxDebugContext::PrintClasses();
334 //AddLogLineNS(wxT("***************Dump***************");
335 //wxDebugContext::Dump();
336 AddLogLineNS(wxT("***************Stats**************"));
337 wxDebugContext::PrintStatistics(true);
339 // Set back to wxLogGui
340 delete wxLog::SetActiveTarget(oldLog
);
345 // Return 0 for succesful program termination
346 return AMULE_APP_BASE::OnExit();
350 int CamuleApp::InitGui(bool, wxString
&)
357 * Checks permissions on a aMule directory, creating if needed.
359 * @param desc A description of the directory in question, used for error messages.
360 * @param directory The directory in question.
361 * @param fallback If the dir specified with 'directory' could not be created, try this instead.
362 * @return The bool is false on error. The wxString contains the used path.
364 std::pair
<bool, CPath
> CheckMuleDirectory(const wxString
& desc
, const CPath
& directory
, const wxString
& alternative
)
368 if (directory
.IsDir(CPath::readwritable
)) {
369 return std::pair
<bool, CPath
>(true, directory
);
370 } else if (directory
.DirExists()) {
371 // Strings are not translated here because translation isn't up yet.
372 msg
= CFormat(wxT("Permissions on the %s directory too strict!\n")
373 wxT("aMule cannot proceed. To fix this, you must set read/write/exec\n")
374 wxT("permissions for the folder '%s'"))
376 } else if (CPath::MakeDir(directory
)) {
377 return std::pair
<bool, CPath
>(true, directory
);
379 msg
<< CFormat(wxT("Could not create the %s directory at '%s'."))
383 // Attempt to use fallback directory.
384 const CPath
fallback(alternative
);
385 if (fallback
.IsOk() && (directory
!= fallback
)) {
386 msg
<< wxT("\nAttempting to use default directory at location \n'")
387 << alternative
<< wxT("'.");
388 if (theApp
->ShowAlert(msg
, wxT("Error accessing directory."), wxICON_ERROR
| wxOK
| wxCANCEL
) == wxCANCEL
) {
389 return std::pair
<bool, CPath
>(false, CPath(wxEmptyString
));
392 return CheckMuleDirectory(desc
, fallback
, wxEmptyString
);
395 theApp
->ShowAlert(msg
, wxT("Fatal error."), wxICON_ERROR
| wxOK
);
396 return std::pair
<bool, CPath
>(false, CPath(wxEmptyString
));
401 // Application initialization
403 bool CamuleApp::OnInit()
405 #if wxUSE_MEMORY_TRACING
406 // any text before call of Localize_mule needs not to be translated.
407 AddLogLineMS(false, wxT("Checkpoint set on app init for memory debug"));
408 wxDebugContext::SetCheckpoint();
411 // Forward wxLog events to CLogger
412 wxLog::SetActiveTarget(new CLoggerTarget
);
414 m_localip
= StringHosttoUint32(::wxGetFullHostName());
417 // get rid of sigpipe
418 signal(SIGPIPE
, SIG_IGN
);
421 signal(SIGBREAK
, OnShutdownSignal
);
423 // Handle sigint and sigterm
424 signal(SIGINT
, OnShutdownSignal
);
425 signal(SIGTERM
, OnShutdownSignal
);
428 // For listctrl's to behave on Mac
429 wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), 1);
432 // This can't be on constructor or wx2.4.2 doesn't set it.
433 #if !wxCHECK_VERSION(2, 9, 0)
434 SetVendorName(wxT("TikuWarez"));
436 SetAppName(wxT("aMule"));
438 wxString FullMuleVersion
= GetFullMuleVersion();
439 wxString OSDescription
= wxGetOsDescription();
440 strFullMuleVersion
= strdup((const char *)unicode2char(FullMuleVersion
));
441 strOSDescription
= strdup((const char *)unicode2char(OSDescription
));
442 OSType
= OSDescription
.BeforeFirst( wxT(' ') );
443 if ( OSType
.IsEmpty() ) {
444 OSType
= wxT("Unknown");
447 // Handle uncaught exceptions
448 InstallMuleExceptionHandler();
450 // Parse cmdline arguments.
451 wxCmdLineParser
cmdline(AMULE_APP_BASE::argc
, AMULE_APP_BASE::argv
);
453 // Handle these arguments.
454 cmdline
.AddSwitch(wxT("v"), wxT("version"), wxT("Displays the current version number."));
455 cmdline
.AddSwitch(wxT("h"), wxT("help"), wxT("Displays this information."));
456 cmdline
.AddSwitch(wxT("i"), wxT("enable-stdin"), wxT("Does not disable stdin."));
458 cmdline
.AddSwitch(wxT("f"), wxT("full-daemon"), wxT("Fork to background."));
459 cmdline
.AddOption(wxT("p"), wxT("pid-file"), wxT("After fork, create a pid-file in the given fullname file."));
460 cmdline
.AddOption(wxT("c"), wxT("config-dir"), wxT("read config from <dir> instead of home"));
461 cmdline
.AddSwitch(wxT("e"), wxT("ec-config"), wxT("Configure EC (External Connections)."));
463 cmdline
.AddOption(wxT("geometry"), wxEmptyString
,
464 wxT("Sets the geometry of the app.\n")
465 wxT("\t\t\t<str> uses the same format as standard X11 apps:\n")
466 wxT("\t\t\t[=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]"));
468 cmdline
.AddSwitch(wxT("d"), wxT("disable-fatal"), wxT("Does not handle fatal exception."));
469 cmdline
.AddSwitch(wxT("o"), wxT("log-stdout"), wxT("Print log messages to stdout."));
470 cmdline
.AddSwitch(wxT("r"), wxT("reset-config"), wxT("Resets config to default values."));
472 // Change webserver path, not available on Windows
473 cmdline
.AddOption(wxT("w"), wxT("use-amuleweb"), wxT("Specify location of amuleweb binary."));
475 // Allow passing of links to the app
476 cmdline
.AddOption(wxT("c"), wxT("category"), wxT("Set category for passed ED2K links."), wxCMD_LINE_VAL_NUMBER
);
477 cmdline
.AddParam(wxT("ED2K link"), wxCMD_LINE_VAL_STRING
, wxCMD_LINE_PARAM_OPTIONAL
| wxCMD_LINE_PARAM_MULTIPLE
);
479 // Show help on --help or invalid commands
480 if ( cmdline
.Parse() ) {
482 } else if ( cmdline
.Found(wxT("help")) ) {
487 bool ec_config
= false;
490 ec_config
= cmdline
.Found(wxT("ec-config"));
491 if ( cmdline
.Found(wxT("config-dir"), &ConfigDir
) ) {
492 if (ConfigDir
.Last() != wxFileName::GetPathSeparator()) {
493 ConfigDir
+= wxFileName::GetPathSeparator();
496 ConfigDir
= GetConfigDir();
499 ConfigDir
= GetConfigDir();
502 if ( !cmdline
.Found(wxT("disable-fatal")) ) {
504 // catch fatal exceptions
505 wxHandleFatalExceptions(true);
509 bool reset_config
= cmdline
.Found(wxT("reset-config"));
511 theLogger
.SetEnabledStdoutLog(cmdline
.Found(wxT("log-stdout")));
513 enable_daemon_fork
= cmdline
.Found(wxT("full-daemon"));
514 if ( cmdline
.Found(wxT("pid-file"), &PidFile
) ) {
515 // Remove any existing PidFile
516 if ( wxFileExists (PidFile
) ) wxRemoveFile (PidFile
);
519 enable_daemon_fork
= false;
523 if (theLogger
.IsEnabledStdoutLog()) {
524 if ( enable_daemon_fork
) {
525 AddLogLineMS(false, wxT("Daemon will fork to background - log to stdout disabled"));
526 theLogger
.SetEnabledStdoutLog(false);
528 AddLogLineMS(false, wxT("Logging to stdout enabled"));
532 if ( cmdline
.Found(wxT("version")) ) {
533 AddLogLineMS(false, CFormat(wxT("%s (OS: %s)")) % FullMuleVersion
% OSType
);
538 // Default geometry of the GUI. Can be changed with a cmdline argument...
539 bool geometry_enabled
= false;
540 wxString geom_string
;
542 if ( cmdline
.Found(wxT("geometry"), &geom_string
) ) {
543 geometry_enabled
= true;
547 AddLogLineMS(false, wxT("Initialising ") + FullMuleVersion
);
549 // Ensure that "~/.aMule/" is accessible.
550 if (!CheckMuleDirectory(wxT("configuration"), CPath(ConfigDir
), wxEmptyString
).first
) {
555 // Make a backup first.
556 wxRemoveFile(ConfigDir
+ wxT("amule.conf.backup"));
557 wxRenameFile(ConfigDir
+ wxT("amule.conf"), ConfigDir
+ wxT("amule.conf.backup"));
558 AddLogLineMS(false, wxT("Your settings have been reset to default values.\nThe old config file has been saved as amule.conf.backup\n"));
561 size_t linksPassed
= cmdline
.GetParamCount(); // number of links from the command line
562 int linksActuallyPassed
= 0; // number of links that pass the syntax check
565 if (!cmdline
.Found(wxT("c"), &cat
)) {
569 wxTextFile
ed2kFile(ConfigDir
+ wxT("ED2KLinks"));
570 if (!ed2kFile
.Exists()) {
573 if (ed2kFile
.Open()) {
574 for (size_t i
= 0; i
< linksPassed
; i
++) {
576 if (CheckPassedLink(cmdline
.GetParam(i
), link
, cat
)) {
577 ed2kFile
.AddLine(link
);
578 linksActuallyPassed
++;
583 AddLogLineCS(wxT("Failed to open 'ED2KFile', cannot add links."));
587 #if defined(__WXMAC__) && defined(AMULE_DAEMON)
588 //#warning TODO: fix wxSingleInstanceChecker for amuled on Mac (wx link problems)
589 AddLogLineMS(true, wxT("WARNING: The check for other instances is currently disabled in amuled.\n"
590 "Please make sure that no other instance of aMule is running or your files might be corrupted.\n"));
592 AddLogLineMS(false, wxT("Checking if there is an instance already running..."));
594 m_singleInstance
= new wxSingleInstanceChecker();
595 if (m_singleInstance
->Create(wxT("muleLock"), ConfigDir
)
596 && m_singleInstance
->IsAnotherRunning()) {
597 AddLogLineMS(true, wxT("There is an instance of aMule already running"));
598 AddLogLineNS(CFormat(wxT("(lock file: %s%s)")) % ConfigDir
% wxT("muleLock"));
600 AddLogLineNS(CFormat(wxT("passed %d %s to it, finished")) % linksActuallyPassed
601 % (linksPassed
== 1 ? wxT("link") : wxT("links")));
605 // This is very tricky. The most secure way to communicate is via ED2K links file
606 wxTextFile
ed2kFile(ConfigDir
+ wxT("ED2KLinks"));
607 if (!ed2kFile
.Exists()) {
611 if (ed2kFile
.Open()) {
612 ed2kFile
.AddLine(wxT("RAISE_DIALOG"));
615 AddLogLineMS(false, wxT("Raising current running instance."));
617 AddLogLineMS(true, wxT("Failed to open 'ED2KFile', cannot signal running instance."));
622 AddLogLineMS(false, wxT("No other instances are running."));
626 // Close standard-input
627 if ( !cmdline
.Found(wxT("enable-stdin")) ) {
628 // The full daemon will close all std file-descriptors by itself,
629 // so closing it here would lead to the closing on the first open
630 // file, which is the logfile opened below
631 if (!enable_daemon_fork
) {
636 // This creates the CFG file we shall use
637 wxConfigBase
* cfg
= new wxFileConfig( wxEmptyString
, wxEmptyString
, ConfigDir
+ wxT("amule.conf") );
639 // Set the config object as the global cfg file
640 wxConfig::Set( cfg
);
642 // Make a backup of the log file
643 CPath logfileName
= CPath(ConfigDir
+ wxT("logfile"));
644 if (logfileName
.FileExists()) {
645 CPath::BackupFile(logfileName
, wxT(".bak"));
649 if (!theLogger
.OpenLogfile(logfileName
.GetRaw())) {
650 // use std err as last resolt to indicate problem
651 fputs("ERROR: unable to open log file\n", stderr
);
652 // failure to open log is serious problem
657 CPreferences::BuildItemList(ConfigDir
);
658 CPreferences::LoadAllItems( wxConfigBase::Get() );
660 glob_prefs
= new CPreferences();
662 std::pair
<bool, CPath
> checkResult
;
663 checkResult
= CheckMuleDirectory(wxT("temp"), thePrefs::GetTempDir(), ConfigDir
+ wxT("Temp"));
664 if (checkResult
.first
) {
665 thePrefs::SetTempDir(checkResult
.second
);
670 checkResult
= CheckMuleDirectory(wxT("incoming"), thePrefs::GetIncomingDir(), ConfigDir
+ wxT("Incoming"));
671 if (checkResult
.first
) {
672 thePrefs::SetIncomingDir(checkResult
.second
);
678 if (!thePrefs::UseTrayIcon()) {
679 thePrefs::SetMinToTray(false);
682 // Build the filenames for the two OS files
683 SetOSFiles(thePrefs::GetOSDir().GetRaw());
686 // Load localization settings
690 // Configure EC for amuled when invoked with ec-config
692 AddLogLineMS(false, _("\nEC configuration"));
693 thePrefs::SetECPass(GetPassword());
694 thePrefs::EnableExternalConnections(true);
695 AddLogLineMS(false, _("Password set and external connections enabled."));
701 wxT("Warning! You are running aMule as root.\n")
702 wxT("Doing so is not recommended for security reasons,\n")
703 wxT("and you are advised to run aMule as an normal\n")
704 wxT("user instead.");
706 ShowAlert(msg
, _("WARNING"), wxCENTRE
| wxOK
| wxICON_ERROR
);
708 fprintf(stderr
, "\n--------------------------------------------------\n");
709 fprintf(stderr
, "%s", (const char*)unicode2UTF8(msg
));
710 fprintf(stderr
, "\n--------------------------------------------------\n\n");
714 // Display notification on new version or first run
715 wxTextFile
vfile( ConfigDir
+ wxT("lastversion") );
716 wxString
newMule(wxT( VERSION
));
718 if ( !wxFileExists( vfile
.GetName() ) ) {
722 if ( vfile
.Open() ) {
723 // Check if this version has been run before
725 for ( size_t i
= 0; i
< vfile
.GetLineCount(); i
++ ) {
726 // Check if this version has been run before
727 if ( vfile
.GetLine(i
) == newMule
) {
733 // We havent run this version before?
735 // Insert new at top to provide faster searches
736 vfile
.InsertLine( newMule
, 0 );
738 Trigger_New_version( newMule
);
741 // Keep at most 10 entires
742 while ( vfile
.GetLineCount() > 10 )
743 vfile
.RemoveLine( vfile
.GetLineCount() - 1 );
749 // Check if we have the old style locale config
750 wxString langId
= thePrefs::GetLanguageID();
751 if (!langId
.IsEmpty() && (langId
.GetChar(0) >= '0' && langId
.GetChar(0) <= '9')) {
752 wxString
info(_("Your locale has been changed to System Default due to a configuration change. Sorry."));
753 thePrefs::SetLanguageID(wxLang2Str(wxLANGUAGE_DEFAULT
));
754 ShowAlert(info
, _("Info"), wxCENTRE
| wxOK
| wxICON_ERROR
);
757 m_statistics
= new CStatistics();
759 clientlist
= new CClientList();
760 friendlist
= new CFriendList();
761 searchlist
= new CSearchList();
762 knownfiles
= new CKnownFileList();
763 serverlist
= new CServerList();
765 sharedfiles
= new CSharedFileList(knownfiles
);
766 clientcredits
= new CClientCreditsList();
768 // bugfix - do this before creating the uploadqueue
769 downloadqueue
= new CDownloadQueue();
770 uploadqueue
= new CUploadQueue();
771 ipfilter
= new CIPFilter();
773 // Creates all needed listening sockets
775 if (!ReinitializeNetwork(&msg
)) {
776 AddLogLineMS(false, wxT("\n"));
777 AddLogLineMS(false, msg
);
780 // Test if there's any new version
781 if (thePrefs::CheckNewVersion()) {
782 // We use the thread base because I don't want a dialog to pop up.
783 CHTTPDownloadThread
* version_check
=
784 new CHTTPDownloadThread(wxT("http://amule.sourceforge.net/lastversion"),
785 theApp
->ConfigDir
+ wxT("last_version_check"), HTTP_VersionCheck
, false);
786 version_check
->Create();
787 version_check
->Run();
790 // Create main dialog, or fork to background (daemon).
791 InitGui(geometry_enabled
, geom_string
);
793 #if !defined(__WXMAC__) && defined(AMULE_DAEMON)
794 // Need to refresh wxSingleInstanceChecker after the daemon fork() !
795 if (enable_daemon_fork
) {
796 //#warning TODO: fix wxSingleInstanceChecker for amuled on Mac (wx link problems)
797 delete m_singleInstance
;
798 m_singleInstance
= new wxSingleInstanceChecker(wxT("muleLock"), ConfigDir
);
799 // No need to check IsAnotherRunning() - we've done it before.
803 // Has to be created after the call to InitGui, as fork
804 // (when using posix threads) only replicates the mainthread,
805 // and the UBT constructor creates a thread.
806 uploadBandwidthThrottler
= new UploadBandwidthThrottler();
808 // These must be initialized after the gui is loaded.
810 downloadqueue
->LoadMetFiles(thePrefs::GetTempDir());
811 sharedfiles
->Reload();
813 if (thePrefs::IPFilterAutoLoad()) {
814 ipfilter
->Update(thePrefs::IPFilterURL());
818 // Ensure that the up/down ratio is used
819 CPreferences::CheckUlDlRatio();
821 // The user can start pressing buttons like mad if he feels like it.
822 m_app_state
= APP_STATE_RUNNING
;
824 // Kry - Load the sources seeds on app init
825 if (thePrefs::GetSrcSeedsOn()) {
826 downloadqueue
->LoadSourceSeeds();
829 if (!serverlist
->GetServerCount() && thePrefs::GetNetworkED2K()) {
830 // There are no servers and ED2K active -> ask for download.
831 // As we cannot ask in amuled, we just update there
832 // Kry TODO: Store server.met URL on preferences and use it here and in GUI.
834 if (wxYES
== wxMessageBox(
836 _("You don't have any server in the server list.\nDo you want aMule to download a new list now?")),
837 wxString(_("Server list download")),
839 static_cast<wxWindow
*>(theApp
->amuledlg
)))
842 // workaround amuled crash
844 serverlist
->UpdateServerMetFromURL(
845 wxT("http://gruk.org/server.met.gz"));
851 // Autoconnect if that option is enabled
852 if (thePrefs::DoAutoConnect() && (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia())) {
853 AddLogLineM(true, _("Connecting"));
854 if (thePrefs::GetNetworkED2K()) {
855 theApp
->serverconnect
->ConnectToAnyServer();
863 #ifdef ENABLE_IP2COUNTRY
864 theApp
->amuledlg
->EnableIP2Country();
867 // No webserver on Win at all (yet)
870 if (thePrefs::GetWSIsEnabled()) {
871 wxString aMuleConfigFile
= ConfigDir
+ wxT("amule.conf");
872 wxString amulewebPath
= wxT("amuleweb");
873 if(true == cmdline
.Found(wxT("use-amuleweb"), &amulewebPath
)) {
874 AddLogLineNS(CFormat(_("Using amuleweb in '%s'.")) % amulewebPath
);
877 #if defined(__WXMAC__) && !defined(AMULE_DAEMON)
878 // For the Mac GUI application, look for amuleweb in the bundle
879 CFURLRef amulewebUrl
= CFBundleCopyAuxiliaryExecutableURL(
880 CFBundleGetMainBundle(), CFSTR("amuleweb"));
883 CFURLRef absoluteUrl
= CFURLCopyAbsoluteURL(amulewebUrl
);
884 CFRelease(amulewebUrl
);
887 CFStringRef amulewebCfstr
= CFURLCopyFileSystemPath(absoluteUrl
, kCFURLPOSIXPathStyle
);
888 CFRelease(absoluteUrl
);
889 #if wxCHECK_VERSION(2, 9, 0)
890 amulewebPath
= wxCFStringRef(amulewebCfstr
).AsString(wxLocale::GetSystemEncoding());
892 amulewebPath
= wxMacCFStringHolder(amulewebCfstr
).AsString(wxLocale::GetSystemEncoding());
901 wxT("' '--amule-config-file=") +
904 CTerminationProcessAmuleweb
*p
= new CTerminationProcessAmuleweb(cmd
, &webserver_pid
);
905 webserver_pid
= wxExecute(cmd
, wxEXEC_ASYNC
, p
);
906 bool webserver_ok
= webserver_pid
> 0;
908 AddLogLineM(true, CFormat(_("web server running on pid %d")) % webserver_pid
);
912 "You requested to run web server on startup, but the amuleweb binary cannot be run. Please install the package containing aMule web server, or compile aMule using --enable-webserver and run make install"),
913 _("ERROR"), wxOK
| wxICON_ERROR
);
916 #endif /* ! __WXMSW__ */
918 // Start performing background tasks
919 CThreadScheduler::Start();
924 bool CamuleApp::CheckPassedLink(const wxString
&in
, wxString
&out
, int cat
)
928 if (link
.compare(0, 7, wxT("magnet:")) == 0) {
929 link
= CMagnetED2KConverter(link
);
931 AddLogLineCS(CFormat(wxT("Cannot convert magnet link to eD2k: %s")) % in
);
937 CScopedPtr
<CED2KLink
> uri(CED2KLink::CreateLinkFromUrl(link
));
938 out
= uri
.get()->GetLink();
939 if (cat
&& uri
.get()->GetKind() == CED2KLink::kFile
) {
940 out
+= CFormat(wxT(":%d")) % cat
;
943 } catch ( const wxString
& err
) {
944 AddLogLineCS(CFormat(wxT("Invalid eD2k link \"%s\" - ERROR: %s")) % link
% err
);
949 bool CamuleApp::ReinitializeNetwork(wxString
* msg
)
952 static bool firstTime
= true;
955 // TODO: Destroy previously created sockets
959 // Some sanity checks first
960 if (thePrefs::ECPort() == thePrefs::GetPort()) {
961 // Select a random usable port in the range 1025 ... 2^16 - 1
962 uint16 port
= thePrefs::ECPort();
963 while ( port
< 1024 || port
== thePrefs::GetPort() ) {
964 port
= (uint16
)rand();
966 thePrefs::SetECPort( port
);
969 wxT("Network configuration failed! You cannot use the same port\n")
970 wxT("for the main TCP port and the External Connections port.\n")
971 wxT("The EC port has been changed to avoid conflict, see the\n")
972 wxT("preferences for the new value.\n");
975 AddLogLineM( false, wxEmptyString
);
976 AddLogLineM( true, err
);
977 AddLogLineM( false, wxEmptyString
);
982 if (thePrefs::GetUDPPort() == thePrefs::GetPort() + 3) {
983 // Select a random usable value in the range 1025 ... 2^16 - 1
984 uint16 port
= thePrefs::GetUDPPort();
985 while ( port
< 1024 || port
== thePrefs::GetPort() + 3 ) {
986 port
= (uint16
)rand();
988 thePrefs::SetUDPPort( port
);
991 wxT("Network configuration failed! You set your UDP port to\n")
992 wxT("the value of the main TCP port plus 3.\n")
993 wxT("This port has been reserved for the Server-UDP port. The\n")
994 wxT("port value has been changed to avoid conflict, see the\n")
995 wxT("preferences for the new value\n");
998 AddLogLineM( false, wxEmptyString
);
999 AddLogLineM( true, err
);
1000 AddLogLineM( false, wxEmptyString
);
1005 // Create the address where we are going to listen
1006 // TODO: read this from configuration file
1007 amuleIPV4Address myaddr
[4];
1009 // Create the External Connections Socket.
1011 // Get ready to handle connections from apps like amulecmd
1012 if (thePrefs::GetECAddress().IsEmpty() || !myaddr
[0].Hostname(thePrefs::GetECAddress())) {
1013 myaddr
[0].AnyAddress();
1015 myaddr
[0].Service(thePrefs::ECPort());
1016 ECServerHandler
= new ExternalConn(myaddr
[0], msg
);
1018 // Create the UDP socket TCP+3.
1019 // Used for source asking on servers.
1020 if (thePrefs::GetAddress().IsEmpty()) {
1021 myaddr
[1].AnyAddress();
1022 } else if (!myaddr
[1].Hostname(thePrefs::GetAddress())) {
1023 myaddr
[1].AnyAddress();
1024 AddLogLineM(true, CFormat(_("Could not bind ports to the specified address: %s"))
1025 % thePrefs::GetAddress());
1028 wxString ip
= myaddr
[1].IPAddress();
1029 myaddr
[1].Service(thePrefs::GetPort()+3);
1030 serverconnect
= new CServerConnect(serverlist
, myaddr
[1]);
1031 *msg
<< CFormat( wxT("*** Server UDP socket (TCP+3) at %s:%u\n") )
1032 % ip
% ((unsigned int)thePrefs::GetPort() + 3u);
1034 // Create the ListenSocket (aMule TCP socket).
1035 // Used for Client Port / Connections from other clients,
1036 // Client to Client Source Exchange.
1038 myaddr
[2] = myaddr
[1];
1039 myaddr
[2].Service(thePrefs::GetPort());
1040 listensocket
= new CListenSocket(myaddr
[2]);
1041 *msg
<< CFormat( wxT("*** TCP socket (TCP) listening on %s:%u\n") )
1042 % ip
% (unsigned int)(thePrefs::GetPort());
1043 // This command just sets a flag to control maximum number of connections.
1044 // Notify(true) has already been called to the ListenSocket, so events may
1045 // be already comming in.
1046 if (listensocket
->Ok()) {
1047 listensocket
->StartListening();
1049 // If we wern't able to start listening, we need to warn the user
1051 err
= CFormat(_("Port %u is not available. You will be LOWID\n")) %
1052 (unsigned int)(thePrefs::GetPort());
1054 AddLogLineM(true, err
);
1057 _("Port %u is not available!\n\nThis means that you will be LOWID.\n\nCheck your network to make sure the port is open for output and input.")) %
1058 (unsigned int)(thePrefs::GetPort());
1059 ShowAlert(err
, _("ERROR"), wxOK
| wxICON_ERROR
);
1062 // Create the UDP socket.
1063 // Used for extended eMule protocol, Queue Rating, File Reask Ping.
1064 // Also used for Kademlia.
1065 // Default is port 4672.
1066 myaddr
[3] = myaddr
[1];
1067 myaddr
[3].Service(thePrefs::GetUDPPort());
1068 clientudp
= new CClientUDPSocket(myaddr
[3], thePrefs::GetProxyData());
1069 if (!thePrefs::IsUDPDisabled()) {
1070 *msg
<< CFormat( wxT("*** Client UDP socket (extended eMule) at %s:%u") )
1071 % ip
% thePrefs::GetUDPPort();
1073 *msg
<< wxT("*** Client UDP socket (extended eMule) disabled on preferences");
1077 if (thePrefs::GetUPnPEnabled()) {
1079 m_upnpMappings
[0] = CUPnPPortMapping(
1080 myaddr
[0].Service(),
1082 thePrefs::GetUPnPECEnabled(),
1083 "aMule TCP External Connections Socket");
1084 m_upnpMappings
[1] = CUPnPPortMapping(
1085 myaddr
[1].Service(),
1087 thePrefs::GetUPnPEnabled(),
1088 "aMule UDP socket (TCP+3)");
1089 m_upnpMappings
[2] = CUPnPPortMapping(
1090 myaddr
[2].Service(),
1092 thePrefs::GetUPnPEnabled(),
1093 "aMule TCP Listen Socket");
1094 m_upnpMappings
[3] = CUPnPPortMapping(
1095 myaddr
[3].Service(),
1097 thePrefs::GetUPnPEnabled(),
1098 "aMule UDP Extended eMule Socket");
1099 m_upnp
= new CUPnPControlPoint(thePrefs::GetUPnPTCPPort());
1100 m_upnp
->AddPortMappings(m_upnpMappings
);
1101 } catch(CUPnPException
&e
) {
1103 error_msg
<< e
.what();
1104 AddLogLineM(true, error_msg
);
1105 fprintf(stderr
, "%s\n", (const char *)unicode2char(error_msg
));
1113 /* Original implementation by Bouc7 of the eMule Project.
1114 aMule Signature idea was designed by BigBob and implemented
1115 by Un-Thesis, with design inputs and suggestions from bothie.
1117 void CamuleApp::OnlineSig(bool zero
/* reset stats (used on shutdown) */)
1119 // Do not do anything if online signature is disabled in Preferences
1120 if (!thePrefs::IsOnlineSignatureEnabled() || m_emulesig_path
.IsEmpty()) {
1121 // We do not need to check m_amulesig_path because if m_emulesig_path is empty,
1122 // that means m_amulesig_path is empty too.
1126 // Remove old signature files
1127 if ( wxFileExists( m_emulesig_path
) ) { wxRemoveFile( m_emulesig_path
); }
1128 if ( wxFileExists( m_amulesig_path
) ) { wxRemoveFile( m_amulesig_path
); }
1131 wxTextFile amulesig_out
;
1132 wxTextFile emulesig_out
;
1134 // Open both files if needed
1135 if ( !emulesig_out
.Create( m_emulesig_path
) ) {
1136 AddLogLineM(true, _("Failed to create OnlineSig File"));
1137 // Will never try again.
1138 m_amulesig_path
.Clear();
1139 m_emulesig_path
.Clear();
1143 if ( !amulesig_out
.Create(m_amulesig_path
) ) {
1144 AddLogLineM(true, _("Failed to create aMule OnlineSig File"));
1145 // Will never try again.
1146 m_amulesig_path
.Clear();
1147 m_emulesig_path
.Clear();
1151 wxString emulesig_string
;
1155 emulesig_string
= wxT("0\xA0.0|0.0|0");
1156 amulesig_out
.AddLine(wxT("0\n0\n0\n0\n0\n0\n0.0\n0.0\n0\n0"));
1158 if (IsConnectedED2K()) {
1160 temp
= wxString::Format(wxT("%d"),serverconnect
->GetCurrentServer()->GetPort());
1167 + serverconnect
->GetCurrentServer()->GetListName()
1169 // IP and port of the server
1170 + serverconnect
->GetCurrentServer()->GetFullIP()
1175 // Now for amule sig
1177 // Connected. State 1, full info
1178 amulesig_out
.AddLine(wxT("1"));
1180 amulesig_out
.AddLine(serverconnect
->GetCurrentServer()->GetListName());
1182 amulesig_out
.AddLine(serverconnect
->GetCurrentServer()->GetFullIP());
1184 amulesig_out
.AddLine(temp
);
1186 if (serverconnect
->IsLowID()) {
1187 amulesig_out
.AddLine(wxT("L"));
1189 amulesig_out
.AddLine(wxT("H"));
1192 } else if (serverconnect
->IsConnecting()) {
1193 emulesig_string
= wxT("0");
1195 // Connecting. State 2, No info.
1196 amulesig_out
.AddLine(wxT("2\n0\n0\n0\n0"));
1198 // Not connected to a server
1199 emulesig_string
= wxT("0");
1201 // Not connected, state 0, no info
1202 amulesig_out
.AddLine(wxT("0\n0\n0\n0\n0"));
1204 if (IsConnectedKad()) {
1205 if(Kademlia::CKademlia::IsFirewalled()) {
1206 // Connected. Firewalled. State 1.
1207 amulesig_out
.AddLine(wxT("1"));
1209 // Connected. State 2.
1210 amulesig_out
.AddLine(wxT("2"));
1213 // Not connected.State 0.
1214 amulesig_out
.AddLine(wxT("0"));
1216 emulesig_string
+= wxT("\xA");
1218 // Datarate for downloads
1219 temp
= wxString::Format(wxT("%.1f"), theStats::GetDownloadRate() / 1024.0);
1221 emulesig_string
+= temp
+ wxT("|");
1222 amulesig_out
.AddLine(temp
);
1224 // Datarate for uploads
1225 temp
= wxString::Format(wxT("%.1f"), theStats::GetUploadRate() / 1024.0);
1227 emulesig_string
+= temp
+ wxT("|");
1228 amulesig_out
.AddLine(temp
);
1230 // Number of users waiting for upload
1231 temp
= wxString::Format(wxT("%d"), theStats::GetWaitingUserCount());
1233 emulesig_string
+= temp
;
1234 amulesig_out
.AddLine(temp
);
1236 // Number of shared files (not on eMule)
1237 amulesig_out
.AddLine(wxString::Format(wxT("%d"), theStats::GetSharedFileCount()));
1240 // eMule signature finished here. Write the line to the wxTextFile.
1241 emulesig_out
.AddLine(emulesig_string
);
1243 // Now for aMule signature extras
1245 // Nick on the network
1246 amulesig_out
.AddLine(thePrefs::GetUserNick());
1248 // Total received in bytes
1249 amulesig_out
.AddLine( CFormat( wxT("%llu") ) % (theStats::GetSessionReceivedBytes() + thePrefs::GetTotalDownloaded()) );
1251 // Total sent in bytes
1252 amulesig_out
.AddLine( CFormat( wxT("%llu") ) % (theStats::GetSessionSentBytes() + thePrefs::GetTotalUploaded()) );
1256 amulesig_out
.AddLine(wxT(VERSION
) wxT(" ") wxT(SVNDATE
));
1258 amulesig_out
.AddLine(wxT(VERSION
));
1262 amulesig_out
.AddLine(wxT("0"));
1263 amulesig_out
.AddLine(wxT("0"));
1264 amulesig_out
.AddLine(wxT("0"));
1266 // Total received bytes in session
1267 amulesig_out
.AddLine( CFormat( wxT("%llu") ) %
1268 theStats::GetSessionReceivedBytes() );
1270 // Total sent bytes in session
1271 amulesig_out
.AddLine( CFormat( wxT("%llu") ) %
1272 theStats::GetSessionSentBytes() );
1275 amulesig_out
.AddLine(CFormat(wxT("%llu")) % theStats::GetUptimeSeconds());
1279 emulesig_out
.Write();
1280 amulesig_out
.Write();
1281 } //End Added By Bouc7
1284 // Gracefully handle fatal exceptions and print backtrace if possible
1285 void CamuleApp::OnFatalException()
1287 /* Print the backtrace */
1288 fprintf(stderr
, "\n--------------------------------------------------------------------------------\n");
1289 fprintf(stderr
, "A fatal error has occurred and aMule has crashed.\n");
1290 fprintf(stderr
, "Please assist us in fixing this problem by posting the backtrace below in our\n");
1291 fprintf(stderr
, "'aMule Crashes' forum and include as much information as possible regarding the\n");
1292 fprintf(stderr
, "circumstances of this crash. The forum is located here:\n");
1293 fprintf(stderr
, " http://forum.amule.org/index.php?board=67.0\n");
1294 fprintf(stderr
, "If possible, please try to generate a real backtrace of this crash:\n");
1295 fprintf(stderr
, " http://wiki.amule.org/index.php/Backtraces\n\n");
1296 fprintf(stderr
, "----------------------------=| BACKTRACE FOLLOWS: |=----------------------------\n");
1297 fprintf(stderr
, "Current version is: %s\n", strFullMuleVersion
);
1298 fprintf(stderr
, "Running on: %s\n\n", strOSDescription
);
1300 print_backtrace(1); // 1 == skip this function.
1302 fprintf(stderr
, "\n--------------------------------------------------------------------------------\n");
1306 // Sets the localization of aMule
1307 void CamuleApp::Localize_mule()
1309 InitCustomLanguages();
1310 InitLocale(m_locale
, StrLang2wx(thePrefs::GetLanguageID()));
1311 if (!m_locale
.IsOk()) {
1312 AddLogLineM(false,_("The selected locale seems not to be installed on your box. (Note: I'll try to set it anyway)"));
1317 // Displays information related to important changes in aMule.
1318 // Is called when the user runs a new version of aMule
1319 void CamuleApp::Trigger_New_version(wxString new_version
)
1321 wxString info
= wxT(" --- ") + CFormat(_("This is the first time you run aMule %s")) % new_version
+ wxT(" ---\n\n");
1322 if (new_version
== wxT("SVN")) {
1323 info
+= _("This version is a testing version, updated daily, and\n");
1324 info
+= _("we give no warranty it won't break anything, burn your house,\n");
1325 info
+= _("or kill your dog. But it *should* be safe to use anyway.\n");
1326 } else if (new_version
== wxT("2.2.1")) {
1327 thePrefs::SetAddServersFromServer(false);
1328 thePrefs::SetAddServersFromClient(false);
1329 info
+= _("The following options have been changed in this release for security reasons:\n");
1330 info
+= _("\n* Enabled Protocol Obfuscation support for incoming and outgoing connections.\n");
1331 info
+= _("\n* Disabled updating the server list from other server and clients.\n");
1332 info
+= _("\nFor more information on the reason for this changes, seach\nthe aMule wiki at http://wiki.amule.org for \"fake servers\" info.\nIt's important that you clear any fake server from your server list for aMule to work properly.");
1333 info
+= _("\n\nAdditionally, the browser settings have been reset to the system default. Please configure your browser options again if needed.\n");
1338 info
+= _("More information, support and new releases can found at our homepage,\n");
1339 info
+= _("at www.aMule.org, or in our IRC channel #aMule at irc.freenode.net.\n");
1341 info
+= _("Feel free to report any bugs to http://forum.amule.org");
1343 ShowAlert(info
, _("Info"), wxCENTRE
| wxOK
| wxICON_ERROR
);
1347 void CamuleApp::SetOSFiles(const wxString new_path
)
1349 if ( thePrefs::IsOnlineSignatureEnabled() ) {
1350 if ( ::wxDirExists(new_path
) ) {
1351 m_emulesig_path
= JoinPaths(new_path
, wxT("onlinesig.dat"));
1352 m_amulesig_path
= JoinPaths(new_path
, wxT("amulesig.dat"));
1354 ShowAlert(_("The folder for Online Signature files you specified is INVALID!\n OnlineSignature will be DISABLED until you fix it on preferences."), _("ERROR"), wxOK
| wxICON_ERROR
);
1355 m_emulesig_path
.Clear();
1356 m_amulesig_path
.Clear();
1359 m_emulesig_path
.Clear();
1360 m_amulesig_path
.Clear();
1366 #ifndef wxUSE_STACKWALKER
1367 #define wxUSE_STACKWALKER 0
1369 void CamuleApp::OnAssertFailure(const wxChar
* file
, int line
,
1370 const wxChar
* func
, const wxChar
* cond
, const wxChar
* msg
)
1372 if (!wxUSE_STACKWALKER
|| !wxThread::IsMain() || !IsRunning()) {
1373 wxString errmsg
= CFormat( wxT("%s:%s:%d: Assertion '%s' failed. %s") )
1374 % file
% func
% line
% cond
% ( msg
? msg
: wxT("") );
1376 fprintf(stderr
, "Assertion failed: %s\n", (const char*)unicode2char(errmsg
));
1378 // Skip the function-calls directly related to the assert call.
1379 fprintf(stderr
, "\nBacktrace follows:\n");
1381 fprintf(stderr
, "\n");
1384 if (wxThread::IsMain() && IsRunning()) {
1385 AMULE_APP_BASE::OnAssertFailure(file
, line
, func
, cond
, msg
);
1387 // Abort, allows gdb to catch the assertion
1394 void CamuleApp::OnUDPDnsDone(CMuleInternalEvent
& evt
)
1396 CServerUDPSocket
* socket
=(CServerUDPSocket
*)evt
.GetClientData();
1397 socket
->OnHostnameResolved(evt
.GetExtraLong());
1401 void CamuleApp::OnSourceDnsDone(CMuleInternalEvent
& evt
)
1403 downloadqueue
->OnHostnameResolved(evt
.GetExtraLong());
1407 void CamuleApp::OnServerDnsDone(CMuleInternalEvent
& evt
)
1409 AddLogLineMS(false, _("Server hostname notified"));
1410 serverconnect
->OnServerHostnameResolved(evt
.GetClientData(), evt
.GetExtraLong());
1414 void CamuleApp::OnTCPTimer(CTimerEvent
& WXUNUSED(evt
))
1419 serverconnect
->StopConnectionTry();
1420 if (IsConnectedED2K() ) {
1423 serverconnect
->ConnectToAnyServer();
1427 void CamuleApp::OnCoreTimer(CTimerEvent
& WXUNUSED(evt
))
1429 // Former TimerProc section
1430 static uint64 msPrev1
, msPrev5
, msPrevSave
, msPrevHist
, msPrevOS
, msPrevKnownMet
;
1431 uint64 msCur
= theStats::GetUptimeMillis();
1432 TheTime
= msCur
/ 1000;
1438 #ifndef AMULE_DAEMON
1439 // Check if we should terminate the app
1440 if ( g_shutdownSignal
) {
1441 wxWindow
* top
= GetTopWindow();
1446 // No top-window, have to force termination.
1452 uploadqueue
->Process();
1453 downloadqueue
->Process();
1454 //theApp->clientcredits->Process();
1455 theStats::CalculateRates();
1457 if (msCur
-msPrevHist
> 1000) {
1458 // unlike the other loop counters in this function this one will sometimes
1459 // produce two calls in quick succession (if there was a gap of more than one
1460 // second between calls to TimerProc) - this is intentional! This way the
1461 // history list keeps an average of one node per second and gets thinned out
1462 // correctly as time progresses.
1465 m_statistics
->RecordHistory();
1470 if (msCur
-msPrev1
> 1000) { // approximately every second
1472 clientcredits
->Process();
1473 clientlist
->Process();
1475 // Publish files to server if needed.
1476 sharedfiles
->Process();
1478 if( Kademlia::CKademlia::IsRunning() ) {
1479 Kademlia::CKademlia::Process();
1480 if(Kademlia::CKademlia::GetPrefs()->HasLostConnection()) {
1484 if (thePrefs::Reconnect()) {
1490 if( serverconnect
->IsConnecting() && !serverconnect
->IsSingleConnect() ) {
1491 serverconnect
->TryAnotherConnectionrequest();
1493 if (serverconnect
->IsConnecting()) {
1494 serverconnect
->CheckForTimeout();
1496 listensocket
->UpdateConnectionsStatus();
1501 if (msCur
-msPrev5
> 5000) { // every 5 seconds
1503 listensocket
->Process();
1506 if (msCur
-msPrevSave
>= 60000) {
1510 // Save total upload/download to preferences
1511 wxConfigBase
* cfg
= wxConfigBase::Get();
1512 buffer
= CFormat(wxT("%llu")) % (theStats::GetSessionReceivedBytes() + thePrefs::GetTotalDownloaded());
1513 cfg
->Write(wxT("/Statistics/TotalDownloadedBytes"), buffer
);
1515 buffer
= CFormat(wxT("%llu")) % (theStats::GetSessionSentBytes() + thePrefs::GetTotalUploaded());
1516 cfg
->Write(wxT("/Statistics/TotalUploadedBytes"), buffer
);
1518 // Write changes to file
1524 if (msCur
- msPrevOS
>= thePrefs::GetOSUpdate() * 1000ull) {
1525 OnlineSig(); // Added By Bouc7
1529 if (msCur
- msPrevKnownMet
>= 30*60*1000/*There must be a prefs option for this*/) {
1530 // Save Shared Files data
1532 msPrevKnownMet
= msCur
;
1536 // Recomended by lugdunummaster himself - from emule 0.30c
1537 serverconnect
->KeepConnectionAlive();
1542 void CamuleApp::OnFinishedHashing(CHashingEvent
& evt
)
1544 wxCHECK_RET(evt
.GetResult(), wxT("No result of hashing"));
1546 CKnownFile
* owner
= const_cast<CKnownFile
*>(evt
.GetOwner());
1547 CKnownFile
* result
= evt
.GetResult();
1550 // Check if the partfile still exists, as it might have
1551 // been deleted in the mean time.
1552 if (downloadqueue
->IsPartFile(owner
)) {
1553 // This cast must not be done before the IsPartFile
1554 // call, as dynamic_cast will barf on dangling pointers.
1555 dynamic_cast<CPartFile
*>(owner
)->PartFileHashFinished(result
);
1558 static int filecount
;
1559 static uint64 bytecount
;
1561 if (knownfiles
->SafeAddKFile(result
)) {
1562 AddDebugLogLineM(false, logKnownFiles
,
1563 CFormat(wxT("Safe adding file to sharedlist: %s")) % result
->GetFileName());
1564 sharedfiles
->SafeAddKFile(result
);
1567 bytecount
+= result
->GetFileSize();
1568 // If we have added 30 files or files with a total size of ~300mb
1569 if ( ( filecount
== 30 ) || ( bytecount
>= 314572800 ) ) {
1570 AddDebugLogLineM(false, logKnownFiles
, wxT("Failsafe for crash on file hashing creation"));
1571 if ( m_app_state
!= APP_STATE_SHUTTINGDOWN
) {
1578 AddDebugLogLineM(false, logKnownFiles
,
1579 CFormat(wxT("File not added to sharedlist: %s")) % result
->GetFileName());
1586 void CamuleApp::OnFinishedAICHHashing(CHashingEvent
& evt
)
1588 wxCHECK_RET(evt
.GetResult(), wxT("No result of AICH-hashing"));
1590 CKnownFile
* owner
= const_cast<CKnownFile
*>(evt
.GetOwner());
1591 CScopedPtr
<CKnownFile
> result(evt
.GetResult());
1593 // Check that the owner is still valid
1594 if (knownfiles
->IsKnownFile(owner
)) {
1595 if (result
->GetAICHHashset()->GetStatus() == AICH_HASHSETCOMPLETE
) {
1596 CAICHHashSet
* oldSet
= owner
->GetAICHHashset();
1597 CAICHHashSet
* newSet
= result
->GetAICHHashset();
1599 owner
->SetAICHHashset(newSet
);
1600 newSet
->SetOwner(owner
);
1602 result
->SetAICHHashset(oldSet
);
1603 oldSet
->SetOwner(result
.get());
1609 void CamuleApp::OnFinishedCompletion(CCompletionEvent
& evt
)
1611 CPartFile
* completed
= const_cast<CPartFile
*>(evt
.GetOwner());
1612 wxCHECK_RET(completed
, wxT("Completion event sent for unspecified file"));
1613 wxASSERT_MSG(downloadqueue
->IsPartFile(completed
), wxT("CCompletionEvent for unknown partfile."));
1615 completed
->CompleteFileEnded(evt
.ErrorOccured(), evt
.GetFullPath());
1616 if (evt
.ErrorOccured()) {
1617 CUserEvents::ProcessEvent(CUserEvents::ErrorOnCompletion
, completed
);
1620 // Check if we should execute an script/app/whatever.
1621 CUserEvents::ProcessEvent(CUserEvents::DownloadCompleted
, completed
);
1624 void CamuleApp::OnFinishedAllocation(CAllocFinishedEvent
& evt
)
1626 CPartFile
*file
= evt
.GetFile();
1627 wxCHECK_RET(file
, wxT("Allocation finished event sent for unspecified file"));
1628 wxASSERT_MSG(downloadqueue
->IsPartFile(file
), wxT("CAllocFinishedEvent for unknown partfile"));
1630 file
->SetPartFileStatus(PS_EMPTY
);
1632 if (evt
.Succeeded()) {
1633 if (evt
.IsPaused()) {
1639 AddLogLineM(false, CFormat(_("Disk space preallocation for file '%s' failed: %s")) % file
->GetFileName() % wxString(UTF82unicode(std::strerror(evt
.GetResult()))));
1643 file
->AllocationFinished();
1646 void CamuleApp::OnNotifyEvent(CMuleGUIEvent
& evt
)
1648 #if defined(AMULE_DAEMON)
1651 if (theApp
->amuledlg
) {
1658 void CamuleApp::ShutDown()
1661 AddDebugLogLineM(false, logGeneral
, wxT("CamuleApp::ShutDown() has started."));
1663 // Signal the hashing thread to terminate
1664 m_app_state
= APP_STATE_SHUTTINGDOWN
;
1668 // Kry - Save the sources seeds on app exit
1669 if (thePrefs::GetSrcSeedsOn()) {
1670 downloadqueue
->SaveSourceSeeds();
1673 OnlineSig(true); // Added By Bouc7
1675 // Close sockets to avoid new clients coming in
1677 listensocket
->Close();
1678 listensocket
->KillAllSockets();
1681 if (serverconnect
) {
1682 serverconnect
->Disconnect();
1685 ECServerHandler
->KillAllSockets();
1688 if (thePrefs::GetUPnPEnabled()) {
1690 m_upnp
->DeletePortMappings(m_upnpMappings
);
1695 // saving data & stuff
1700 thePrefs::Add2TotalDownloaded(theStats::GetSessionReceivedBytes());
1701 thePrefs::Add2TotalUploaded(theStats::GetSessionSentBytes());
1707 CPath configFileName
= CPath(ConfigDir
+ wxT("amule.conf"));
1708 CPath::BackupFile(configFileName
, wxT(".bak"));
1711 clientlist
->DeleteAll();
1714 // Now we have tried to delete all our clients and sockets,
1715 // but wx 2.9 has only scheduled them for deletion.
1716 // Force deletion now, or it will occur when we wait for a locket mutex,
1717 // and the uploadBandwidthThrottler will crash on invalid objects.
1718 AddDebugLogLineN(logGeneral
, wxT("Cleanup pending objects."));
1719 ProcessPendingEvents();
1721 CThreadScheduler::Terminate();
1723 AddDebugLogLineN(logGeneral
, wxT("Terminate upload thread."));
1724 uploadBandwidthThrottler
->EndThread();
1727 AddDebugLogLineM(false, logGeneral
, wxT("CamuleApp::ShutDown() has ended."));
1731 bool CamuleApp::AddServer(CServer
*srv
, bool fromUser
)
1733 if ( serverlist
->AddServer(srv
, fromUser
) ) {
1734 Notify_ServerAdd(srv
);
1741 uint32
CamuleApp::GetPublicIP(bool ignorelocal
) const
1743 if (m_dwPublicIP
== 0) {
1744 if (Kademlia::CKademlia::IsConnected() && Kademlia::CKademlia::GetIPAddress() ) {
1745 return wxUINT32_SWAP_ALWAYS(Kademlia::CKademlia::GetIPAddress());
1747 return ignorelocal
? 0 : m_localip
;
1751 return m_dwPublicIP
;
1755 void CamuleApp::SetPublicIP(const uint32 dwIP
)
1757 wxASSERT((dwIP
== 0) || !IsLowID(dwIP
));
1759 if (dwIP
!= 0 && dwIP
!= m_dwPublicIP
&& serverlist
!= NULL
) {
1760 m_dwPublicIP
= dwIP
;
1761 serverlist
->CheckForExpiredUDPKeys();
1763 m_dwPublicIP
= dwIP
;
1768 wxString
CamuleApp::GetLog(bool reset
)
1770 ConfigDir
= GetConfigDir();
1772 logfile
.Open(ConfigDir
+ wxT("logfile"));
1773 if ( !logfile
.IsOpened() ) {
1774 return _("ERROR: can't open logfile");
1776 int len
= logfile
.Length();
1778 return _("WARNING: logfile is empty. Something is wrong.");
1780 char *tmp_buffer
= new char[len
+ sizeof(wxChar
)];
1781 logfile
.Read(tmp_buffer
, len
);
1782 memset(tmp_buffer
+ len
, 0, sizeof(wxChar
));
1784 // try to guess file format
1786 if (tmp_buffer
[0] && tmp_buffer
[1]) {
1787 str
= wxString(UTF82unicode(tmp_buffer
));
1789 str
= wxWCharBuffer((wchar_t *)tmp_buffer
);
1792 delete [] tmp_buffer
;
1794 theLogger
.CloseLogfile();
1795 if (theLogger
.OpenLogfile(ConfigDir
+ wxT("logfile"))) {
1796 AddLogLineM(false, _("Log has been reset"));
1803 wxString
CamuleApp::GetServerLog(bool reset
)
1805 wxString ret
= server_msg
;
1812 wxString
CamuleApp::GetDebugLog(bool reset
)
1814 return GetLog(reset
);
1818 void CamuleApp::AddServerMessageLine(wxString
&msg
)
1820 server_msg
+= msg
+ wxT("\n");
1821 AddLogLineM(false, CFormat(_("ServerMessage: %s")) % msg
);
1826 void CamuleApp::OnFinishedHTTPDownload(CMuleInternalEvent
& event
)
1828 switch (event
.GetInt()) {
1830 ipfilter
->DownloadFinished(event
.GetExtraLong());
1832 case HTTP_ServerMet
:
1833 serverlist
->DownloadFinished(event
.GetExtraLong());
1835 case HTTP_ServerMetAuto
:
1836 serverlist
->AutoDownloadFinished(event
.GetExtraLong());
1838 case HTTP_VersionCheck
:
1839 CheckNewVersion(event
.GetExtraLong());
1842 if (event
.GetExtraLong() != -1) {
1844 wxString file
= ConfigDir
+ wxT("nodes.dat");
1845 if (wxFileExists(file
)) {
1849 if ( Kademlia::CKademlia::IsRunning() ) {
1850 Kademlia::CKademlia::Stop();
1853 wxRenameFile(file
+ wxT(".download"),file
);
1855 Kademlia::CKademlia::Start();
1856 theApp
->ShowConnectionState();
1859 AddLogLineM(true, _("Failed to download the nodes list."));
1862 #ifdef ENABLE_IP2COUNTRY
1864 theApp
->amuledlg
->IP2CountryDownloadFinished(event
.GetExtraLong());
1865 // If we updated, the dialog is already up. Redraw it to show the flags.
1866 theApp
->amuledlg
->Refresh();
1872 void CamuleApp::CheckNewVersion(uint32 result
)
1875 wxString filename
= ConfigDir
+ wxT("last_version_check");
1878 if (!file
.Open(filename
)) {
1879 AddLogLineM(true, _("Failed to open the downloaded version check file") );
1881 } else if (!file
.GetLineCount()) {
1882 AddLogLineM(true, _("Corrupted version check file"));
1884 wxString versionLine
= file
.GetFirstLine();
1885 wxStringTokenizer
tkz(versionLine
, wxT("."));
1887 AddDebugLogLineM(false, logGeneral
, wxString(wxT("Running: ")) + wxT(VERSION
) + wxT(", Version check: ") + versionLine
);
1889 long fields
[] = {0, 0, 0};
1890 for (int i
= 0; i
< 3; ++i
) {
1891 if (!tkz
.HasMoreTokens()) {
1892 AddLogLineM(true, _("Corrupted version check file"));
1895 wxString token
= tkz
.GetNextToken();
1897 if (!token
.ToLong(&fields
[i
])) {
1898 AddLogLineM(true, _("Corrupted version check file"));
1904 long curVer
= make_full_ed2k_version(VERSION_MJR
, VERSION_MIN
, VERSION_UPDATE
);
1905 long newVer
= make_full_ed2k_version(fields
[0], fields
[1], fields
[2]);
1907 if (curVer
< newVer
) {
1908 AddLogLineM(true, _("You are using an outdated version of aMule!"));
1909 AddLogLineM(false, wxString::Format(_("Your aMule version is %i.%i.%i and the latest version is %li.%li.%li"), VERSION_MJR
, VERSION_MIN
, VERSION_UPDATE
, fields
[0], fields
[1], fields
[2]));
1910 AddLogLineM(false, _("The latest version can always be found at http://www.amule.org"));
1912 AddLogLineMS(true, CFormat(_("WARNING: Your aMuled version is outdated: %i.%i.%i < %li.%li.%li"))
1913 % VERSION_MJR
% VERSION_MIN
% VERSION_UPDATE
% fields
[0] % fields
[1] % fields
[2]);
1916 AddLogLineM(false, _("Your copy of aMule is up to date."));
1921 wxRemoveFile(filename
);
1923 AddLogLineM(true, _("Failed to download the version check file") );
1929 bool CamuleApp::IsConnected() const
1931 return (IsConnectedED2K() || IsConnectedKad());
1935 bool CamuleApp::IsConnectedED2K() const
1937 return serverconnect
&& serverconnect
->IsConnected();
1941 bool CamuleApp::IsConnectedKad() const
1943 return Kademlia::CKademlia::IsConnected();
1947 bool CamuleApp::IsFirewalled() const
1949 if (theApp
->IsConnectedED2K() && !theApp
->serverconnect
->IsLowID()) {
1950 return false; // we have an eD2K HighID -> not firewalled
1953 return IsFirewalledKad(); // If kad says ok, it's ok.
1956 bool CamuleApp::IsFirewalledKad() const
1958 return !Kademlia::CKademlia::IsConnected() // not connected counts as firewalled
1959 || Kademlia::CKademlia::IsFirewalled();
1962 bool CamuleApp::IsFirewalledKadUDP() const
1964 return !Kademlia::CKademlia::IsConnected() // not connected counts as firewalled
1965 || Kademlia::CUDPFirewallTester::IsFirewalledUDP(true);
1968 bool CamuleApp::IsKadRunning() const
1970 return Kademlia::CKademlia::IsRunning();
1974 uint32
CamuleApp::GetKadUsers() const
1976 return Kademlia::CKademlia::GetKademliaUsers();
1979 uint32
CamuleApp::GetKadFiles() const
1981 return Kademlia::CKademlia::GetKademliaFiles();
1984 uint32
CamuleApp::GetKadIndexedSources() const
1986 return Kademlia::CKademlia::GetIndexed()->m_totalIndexSource
;
1989 uint32
CamuleApp::GetKadIndexedKeywords() const
1991 return Kademlia::CKademlia::GetIndexed()->m_totalIndexKeyword
;
1994 uint32
CamuleApp::GetKadIndexedNotes() const
1996 return Kademlia::CKademlia::GetIndexed()->m_totalIndexNotes
;
1999 uint32
CamuleApp::GetKadIndexedLoad() const
2001 return Kademlia::CKademlia::GetIndexed()->m_totalIndexLoad
;
2005 // True IP of machine
2006 uint32
CamuleApp::GetKadIPAdress() const
2008 return wxUINT32_SWAP_ALWAYS(Kademlia::CKademlia::GetPrefs()->GetIPAddress());
2012 uint8
CamuleApp::GetBuddyStatus() const
2014 return clientlist
->GetBuddyStatus();
2017 uint32
CamuleApp::GetBuddyIP() const
2019 return clientlist
->GetBuddy()->GetIP();
2022 uint32
CamuleApp::GetBuddyPort() const
2024 return clientlist
->GetBuddy()->GetUDPPort();
2027 bool CamuleApp::CanDoCallback(CUpDownClient
*client
)
2029 if (Kademlia::CKademlia::IsConnected()) {
2030 if (IsConnectedED2K()) {
2031 if (serverconnect
->IsLowID()) {
2032 if (Kademlia::CKademlia::IsFirewalled()) {
2033 //Both Connected - Both Firewalled
2036 if (client
->GetServerIP() == theApp
->serverconnect
->GetCurrentServer()->GetIP() &&
2037 client
->GetServerPort() == theApp
->serverconnect
->GetCurrentServer()->GetPort()) {
2038 // Both Connected - Server lowID, Kad Open - Client on same server
2039 // We prevent a callback to the server as this breaks the protocol
2040 // and will get you banned.
2043 // Both Connected - Server lowID, Kad Open - Client on remote server
2048 //Both Connected - Server HighID, Kad don't care
2052 if (Kademlia::CKademlia::IsFirewalled()) {
2053 //Only Kad Connected - Kad Firewalled
2056 //Only Kad Conected - Kad Open
2061 if (IsConnectedED2K()) {
2062 if (serverconnect
->IsLowID()) {
2063 //Only Server Connected - Server LowID
2066 //Only Server Connected - Server HighID
2070 //We are not connected at all!
2076 void CamuleApp::ShowUserCount() {
2077 uint32 totaluser
= 0, totalfile
= 0;
2079 theApp
->serverlist
->GetUserFileStatus( totaluser
, totalfile
);
2083 static const wxString s_singlenetstatusformat
= _("Users: %s | Files: %s");
2084 static const wxString s_bothnetstatusformat
= _("Users: E: %s K: %s | Files: E: %s K: %s");
2086 if (thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()) {
2087 buffer
= CFormat(s_bothnetstatusformat
) % CastItoIShort(totaluser
) % CastItoIShort(Kademlia::CKademlia::GetKademliaUsers()) % CastItoIShort(totalfile
) % CastItoIShort(Kademlia::CKademlia::GetKademliaFiles());
2088 } else if (thePrefs::GetNetworkED2K()) {
2089 buffer
= CFormat(s_singlenetstatusformat
) % CastItoIShort(totaluser
) % CastItoIShort(totalfile
);
2090 } else if (thePrefs::GetNetworkKademlia()) {
2091 buffer
= CFormat(s_singlenetstatusformat
) % CastItoIShort(Kademlia::CKademlia::GetKademliaUsers()) % CastItoIShort(Kademlia::CKademlia::GetKademliaFiles());
2093 buffer
= _("No networks selected");
2096 Notify_ShowUserCount(buffer
);
2100 void CamuleApp::ListenSocketHandler(wxSocketEvent
& event
)
2102 wxCHECK_RET(listensocket
, wxT("Connection-event for NULL'd listen-socket"));
2103 wxCHECK_RET(event
.GetSocketEvent() == wxSOCKET_CONNECTION
,
2104 wxT("Invalid event received for listen-socket"));
2106 if (m_app_state
== APP_STATE_RUNNING
) {
2107 listensocket
->OnAccept(0);
2108 } else if (m_app_state
== APP_STATE_STARTING
) {
2109 // When starting up, connection may be made before we are able
2110 // to handle them. However, if these are ignored, no futher
2111 // connection-events will be triggered, so we have to accept it.
2112 wxSocketBase
* socket
= listensocket
->Accept(false);
2114 wxCHECK_RET(socket
, wxT("NULL returned by Accept() during startup"));
2121 void CamuleApp::ShowConnectionState()
2123 static uint8 old_state
= (1<<7); // This flag doesn't exist
2127 if (theApp
->serverconnect
->IsConnected()) {
2128 state
|= CONNECTED_ED2K
;
2131 if (Kademlia::CKademlia::IsRunning()) {
2132 if (Kademlia::CKademlia::IsConnected()) {
2133 if (!Kademlia::CKademlia::IsFirewalled()) {
2134 state
|= CONNECTED_KAD_OK
;
2136 state
|= CONNECTED_KAD_FIREWALLED
;
2139 state
|= CONNECTED_KAD_NOT
;
2143 Notify_ShowConnState(state
);
2145 if (old_state
!= state
) {
2146 // Get the changed value
2147 int changed_flags
= old_state
^ state
;
2149 if (changed_flags
& CONNECTED_ED2K
) {
2150 // ED2K status changed
2151 wxString connected_server
;
2152 CServer
* ed2k_server
= theApp
->serverconnect
->GetCurrentServer();
2154 connected_server
= ed2k_server
->GetListName();
2156 if (state
& CONNECTED_ED2K
) {
2157 // We connected to some server
2158 const wxString id
= theApp
->serverconnect
->IsLowID() ? _("with LowID") : _("with HighID");
2160 AddLogLineM(true, CFormat(_("Connected to %s %s")) % connected_server
% id
);
2162 if ( theApp
->serverconnect
->IsConnecting() ) {
2163 AddLogLineM(true, CFormat(_("Connecting to %s")) % connected_server
);
2165 AddLogLineM(true, _("Disconnected from eD2k"));
2170 if (changed_flags
& CONNECTED_KAD_NOT
) {
2171 if (state
& CONNECTED_KAD_NOT
) {
2172 AddLogLineM(true, _("Kad started."));
2174 AddLogLineM(true, _("Kad stopped."));
2178 if (changed_flags
& (CONNECTED_KAD_OK
| CONNECTED_KAD_FIREWALLED
)) {
2179 if (state
& (CONNECTED_KAD_OK
| CONNECTED_KAD_FIREWALLED
)) {
2180 if (state
& CONNECTED_KAD_OK
) {
2181 AddLogLineM(true, _("Connected to Kad (ok)"));
2183 AddLogLineM(true, _("Connected to Kad (firewalled)"));
2186 AddLogLineM(true, _("Disconnected from Kad"));
2192 theApp
->downloadqueue
->OnConnectionState(IsConnected());
2196 Notify_ShowConnState(state
);
2200 void CamuleApp::UDPSocketHandler(wxSocketEvent
& event
)
2202 CMuleUDPSocket
* socket
= (CMuleUDPSocket
*)(event
.GetClientData());
2203 wxCHECK_RET(socket
, wxT("No socket owner specified."));
2205 if (IsOnShutDown() || thePrefs::IsUDPDisabled()) return;
2208 if (event
.GetSocketEvent() == wxSOCKET_INPUT
) {
2209 // Back to the queue!
2210 theApp
->AddPendingEvent(event
);
2215 switch (event
.GetSocketEvent()) {
2216 case wxSOCKET_INPUT
:
2217 socket
->OnReceive(0);
2220 case wxSOCKET_OUTPUT
:
2225 socket
->OnDisconnected(0);
2235 void CamuleApp::OnUnhandledException()
2237 // Call the generic exception-handler.
2238 fprintf(stderr
, "\taMule Version: %s\n", (const char*)unicode2char(GetFullMuleVersion()));
2239 ::OnUnhandledException();
2242 void CamuleApp::StartKad()
2244 if (!Kademlia::CKademlia::IsRunning() && thePrefs::GetNetworkKademlia()) {
2245 // Kad makes no sense without the Client-UDP socket.
2246 if (!thePrefs::IsUDPDisabled()) {
2247 Kademlia::CKademlia::Start();
2249 AddLogLineM(true,_("Kad network cannot be used if UDP port is disabled on preferences, not starting."));
2251 } else if (!thePrefs::GetNetworkKademlia()) {
2252 AddLogLineM(true,_("Kad network disabled on preferences, not connecting."));
2256 void CamuleApp::StopKad()
2258 // Stop Kad if it's running
2259 if (Kademlia::CKademlia::IsRunning()) {
2260 Kademlia::CKademlia::Stop();
2265 void CamuleApp::BootstrapKad(uint32 ip
, uint16 port
)
2267 if (!Kademlia::CKademlia::IsRunning()) {
2268 Kademlia::CKademlia::Start();
2269 theApp
->ShowConnectionState();
2272 Kademlia::CKademlia::Bootstrap(ip
, port
, true);
2276 void CamuleApp::UpdateNotesDat(const wxString
& url
)
2278 wxString
strTempFilename(theApp
->ConfigDir
+ wxT("nodes.dat.download"));
2280 CHTTPDownloadThread
*downloader
= new CHTTPDownloadThread(url
, strTempFilename
, HTTP_NodesDat
);
2281 downloader
->Create();
2286 void CamuleApp::DisconnectED2K()
2288 // Stop ED2K if it's running
2289 if (IsConnectedED2K()) {
2290 serverconnect
->Disconnect();
2294 bool CamuleApp::CryptoAvailable() const
2296 return clientcredits
&& clientcredits
->CryptoAvailable();
2299 uint32
CamuleApp::GetED2KID() const {
2300 return serverconnect
? serverconnect
->GetClientID() : 0;
2303 uint32
CamuleApp::GetID() const {
2306 if( Kademlia::CKademlia::IsConnected() && !Kademlia::CKademlia::IsFirewalled() ) {
2307 // We trust Kad above ED2K
2308 ID
= ENDIAN_NTOHL(Kademlia::CKademlia::GetIPAddress());
2309 } else if( theApp
->serverconnect
->IsConnected() ) {
2310 ID
= theApp
->serverconnect
->GetClientID();
2311 } else if ( Kademlia::CKademlia::IsConnected() && Kademlia::CKademlia::IsFirewalled() ) {
2312 // A firewalled Kad client get's a "1"
2321 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
)
2322 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SOURCE_DNS_DONE
)
2323 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE
)
2324 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE
)
2325 // File_checked_for_headers