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 "ExternalConn.h" // Needed for ExternalConn & MuleConnection
61 #include <common/FileFunctions.h> // Needed for CDirIterator
62 #include "FriendList.h" // Needed for CFriendList
63 #include "HTTPDownload.h" // Needed for CHTTPDownloadThread
64 #include "InternalEvents.h" // Needed for CMuleInternalEvent
65 #include "IPFilter.h" // Needed for CIPFilter
66 #include "KnownFileList.h" // Needed for CKnownFileList
67 #include "ListenSocket.h" // Needed for CListenSocket
68 #include "Logger.h" // Needed for CLogger // Do_not_auto_remove
69 #include "MagnetURI.h" // Needed for CMagnetURI
70 #include "OtherFunctions.h"
71 #include "PartFile.h" // Needed for CPartFile
72 #include "Preferences.h" // Needed for CPreferences
73 #include "SearchList.h" // Needed for CSearchList
74 #include "Server.h" // Needed for GetListName
75 #include "ServerList.h" // Needed for CServerList
76 #include "ServerConnect.h" // Needed for CServerConnect
77 #include "ServerUDPSocket.h" // Needed for CServerUDPSocket
78 #include "Statistics.h" // Needed for CStatistics
79 #include "TerminationProcessAmuleweb.h" // Needed for CTerminationProcessAmuleweb
80 #include "ThreadTasks.h"
81 #include "updownclient.h" // Needed for CUpDownClient
82 #include "UploadQueue.h" // Needed for CUploadQueue
83 #include "UploadBandwidthThrottler.h"
84 #include "UserEvents.h"
85 #include "ScopedPtr.h"
88 #include "UPnPBase.h" // Needed for UPnP
92 #include <wx/sysopt.h> // Do_not_auto_remove
97 #include <CoreFoundation/CFBundle.h> // Do_not_auto_remove
98 #include <wx/mac/corefoundation/cfstring.h> // Do_not_auto_remove
100 #include <wx/msgdlg.h>
102 #include "amuleDlg.h"
106 #ifdef HAVE_SYS_RESOURCE_H
107 #include <sys/resource.h>
110 #ifdef HAVE_SYS_STATVFS_H
111 #include <sys/statvfs.h> // Do_not_auto_remove
116 # define RLIMIT_RESOURCE __rlimit_resource
118 # define RLIMIT_RESOURCE int
121 static void UnlimitResource(RLIMIT_RESOURCE resType
)
123 #if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
125 getrlimit(resType
, &rl
);
126 rl
.rlim_cur
= rl
.rlim_max
;
127 setrlimit(resType
, &rl
);
132 static void SetResourceLimits()
134 #ifdef HAVE_SYS_RESOURCE_H
135 UnlimitResource(RLIMIT_DATA
);
137 UnlimitResource(RLIMIT_FSIZE
);
139 UnlimitResource(RLIMIT_NOFILE
);
141 UnlimitResource(RLIMIT_RSS
);
146 // We store the received signal in order to avoid race-conditions
147 // in the signal handler.
148 bool g_shutdownSignal
= false;
150 void OnShutdownSignal( int /* sig */ )
152 signal(SIGINT
, SIG_DFL
);
153 signal(SIGTERM
, SIG_DFL
);
155 g_shutdownSignal
= true;
158 theApp
->ExitMainLoop();
163 CamuleApp::CamuleApp()
165 // Madcat - Initialize timer as the VERY FIRST thing to avoid any issues later.
166 // Kry - I love to init the vars on init, even before timer.
170 m_app_state
= APP_STATE_STARTING
;
172 theApp
= &wxGetApp();
178 serverconnect
= NULL
;
182 clientcredits
= NULL
;
184 downloadqueue
= NULL
;
187 ECServerHandler
= NULL
;
188 m_singleInstance
= NULL
;
191 uploadBandwidthThrottler
= NULL
;
194 m_upnpMappings
.resize(4);
202 enable_daemon_fork
= false;
204 strFullMuleVersion
= NULL
;
205 strOSDescription
= NULL
;
207 // Apprently needed for *BSD
211 CamuleApp::~CamuleApp()
213 // Closing the log-file as the very last thing, since
214 // wxWidgets log-events are saved in it as well.
215 theLogger
.CloseLogfile();
217 free(strFullMuleVersion
);
218 free(strOSDescription
);
221 int CamuleApp::OnExit()
223 if (m_app_state
!=APP_STATE_STARTING
) {
224 AddLogLineMS(false, _("Now, exiting main app..."));
227 // From wxWidgets docs, wxConfigBase:
229 // Note that you must delete this object (usually in wxApp::OnExit)
230 // in order to avoid memory leaks, wxWidgets won't do it automatically.
232 // As it happens, you may even further simplify the procedure described
233 // above: you may forget about calling Set(). When Get() is called and
234 // there is no current object, it will create one using Create() function.
235 // To disable this behaviour DontCreateOnDemand() is provided.
236 delete wxConfigBase::Set((wxConfigBase
*)NULL
);
239 clientcredits
->SaveList();
241 // Kill amuleweb if running
243 AddLogLineMS(false, CFormat(_("Killing amuleweb instance with pid `%ld' ... ")) % webserver_pid
);
245 wxKill(webserver_pid
, wxSIGTERM
, &rc
);
246 AddLogLineMS(false, _("Killed!"));
249 if (m_app_state
!=APP_STATE_STARTING
) {
250 AddLogLineMS(false, _("aMule OnExit: Terminating core."));
259 delete clientcredits
;
260 clientcredits
= NULL
;
265 // Destroying CDownloadQueue calls destructor for CPartFile
266 // calling CSharedFileList::SafeAddKFile occasionally.
270 delete serverconnect
;
271 serverconnect
= NULL
;
288 delete downloadqueue
;
289 downloadqueue
= NULL
;
299 delete ECServerHandler
;
300 ECServerHandler
= NULL
;
307 CPreferences::EraseItemList();
309 #if defined(__WXMAC__) && defined(AMULE_DAEMON)
310 //#warning TODO: fix wxSingleInstanceChecker for amuled on Mac (wx link problems)
312 delete m_singleInstance
;
314 m_singleInstance
= NULL
;
316 delete uploadBandwidthThrottler
;
317 uploadBandwidthThrottler
= NULL
;
319 if (m_app_state
!=APP_STATE_STARTING
) {
320 AddLogLineNS(_("aMule shutdown completed."));
323 #if wxUSE_MEMORY_TRACING
324 AddLogLineNS(_("Memory debug results for aMule exit:"));
325 // Log mem debug mesages to wxLogStderr
326 wxLog
* oldLog
= wxLog::SetActiveTarget(new wxLogStderr
);
327 //AddLogLineNS(wxT("**************Classes**************");
328 //wxDebugContext::PrintClasses();
329 //AddLogLineNS(wxT("***************Dump***************");
330 //wxDebugContext::Dump();
331 AddLogLineNS(wxT("***************Stats**************"));
332 wxDebugContext::PrintStatistics(true);
334 // Set back to wxLogGui
335 delete wxLog::SetActiveTarget(oldLog
);
340 // Return 0 for succesful program termination
341 return AMULE_APP_BASE::OnExit();
345 int CamuleApp::InitGui(bool, wxString
&)
352 * Checks permissions on a aMule directory, creating if needed.
354 * @param desc A description of the directory in question, used for error messages.
355 * @param directory The directory in question.
356 * @param fallback If the dir specified with 'directory' could not be created, try this instead.
357 * @return The bool is false on error. The wxString contains the used path.
359 std::pair
<bool, CPath
> CheckMuleDirectory(const wxString
& desc
, const CPath
& directory
, const wxString
& alternative
)
363 if (directory
.IsDir(CPath::readwritable
)) {
364 return std::pair
<bool, CPath
>(true, directory
);
365 } else if (directory
.DirExists()) {
366 msg
= CFormat(wxT("Permissions on the %s directory too strict!\n")
367 wxT("aMule cannot proceed. To fix this, you must set read/write/exec\n")
368 wxT("permissions for the folder '%s'"))
370 } else if (CPath::MakeDir(directory
)) {
371 return std::pair
<bool, CPath
>(true, directory
);
373 msg
<< CFormat(wxT("Could not create the %s directory at '%s'."))
377 // Attempt to use fallback directory.
378 const CPath fallback
= CPath(alternative
);
379 if (fallback
.IsOk() && (directory
!= fallback
)) {
380 msg
<< wxT("\nAttempting to use default directory at location \n'")
381 << alternative
<< wxT("'.");
382 theApp
->ShowAlert(msg
, wxT("Error accessing directory."), wxICON_ERROR
| wxOK
);
384 return CheckMuleDirectory(desc
, fallback
, wxEmptyString
);
387 theApp
->ShowAlert(msg
, wxT("Fatal error."), wxICON_ERROR
| wxOK
);
388 return std::pair
<bool, CPath
>(false, CPath(wxEmptyString
));
393 // Application initialization
395 bool CamuleApp::OnInit()
397 #if wxUSE_MEMORY_TRACING
398 // any text before call of Localize_mule needs not to be translated.
399 AddLogLineMS(false, wxT("Checkpoint set on app init for memory debug"));
400 wxDebugContext::SetCheckpoint();
403 // Forward wxLog events to CLogger
404 wxLog::SetActiveTarget(new CLoggerTarget
);
406 m_localip
= StringHosttoUint32(::wxGetFullHostName());
409 // get rid of sigpipe
410 signal(SIGPIPE
, SIG_IGN
);
413 signal(SIGBREAK
, OnShutdownSignal
);
415 // Handle sigint and sigterm
416 signal(SIGINT
, OnShutdownSignal
);
417 signal(SIGTERM
, OnShutdownSignal
);
420 // For listctrl's to behave on Mac
421 wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), 1);
424 // This can't be on constructor or wx2.4.2 doesn't set it.
425 #if !wxCHECK_VERSION(2, 9, 0)
426 SetVendorName(wxT("TikuWarez"));
428 SetAppName(wxT("aMule"));
430 wxString FullMuleVersion
= GetFullMuleVersion();
431 wxString OSDescription
= wxGetOsDescription();
432 strFullMuleVersion
= strdup((const char *)unicode2char(FullMuleVersion
));
433 strOSDescription
= strdup((const char *)unicode2char(OSDescription
));
434 OSType
= OSDescription
.BeforeFirst( wxT(' ') );
435 if ( OSType
.IsEmpty() ) {
436 OSType
= wxT("Unknown");
439 // Handle uncaught exceptions
440 InstallMuleExceptionHandler();
442 // Parse cmdline arguments.
443 wxCmdLineParser
cmdline(AMULE_APP_BASE::argc
, AMULE_APP_BASE::argv
);
445 // Handle these arguments.
446 cmdline
.AddSwitch(wxT("v"), wxT("version"), wxT("Displays the current version number."));
447 cmdline
.AddSwitch(wxT("h"), wxT("help"), wxT("Displays this information."));
448 cmdline
.AddSwitch(wxT("i"), wxT("enable-stdin"), wxT("Does not disable stdin."));
450 cmdline
.AddSwitch(wxT("f"), wxT("full-daemon"), wxT("Fork to background."));
451 cmdline
.AddOption(wxT("p"), wxT("pid-file"), wxT("After fork, create a pid-file in the given fullname file."));
452 cmdline
.AddOption(wxT("c"), wxT("config-dir"), wxT("read config from <dir> instead of home"));
453 cmdline
.AddSwitch(wxT("e"), wxT("ec-config"), wxT("Configure EC (External Connections)."));
455 cmdline
.AddOption(wxT("geometry"), wxEmptyString
,
456 wxT("Sets the geometry of the app.\n")
457 wxT("\t\t\t<str> uses the same format as standard X11 apps:\n")
458 wxT("\t\t\t[=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]"));
460 cmdline
.AddSwitch(wxT("d"), wxT("disable-fatal"), wxT("Does not handle fatal exception."));
461 cmdline
.AddSwitch(wxT("o"), wxT("log-stdout"), wxT("Print log messages to stdout."));
462 cmdline
.AddSwitch(wxT("r"), wxT("reset-config"), wxT("Resets config to default values."));
464 // Change webserver path, not available on Windows
465 cmdline
.AddOption(wxT("w"), wxT("use-amuleweb"), wxT("Specify location of amuleweb binary."));
468 // Show help on --help or invalid commands
469 if ( cmdline
.Parse() ) {
471 } else if ( cmdline
.Found(wxT("help")) ) {
476 bool ec_config
= false;
479 ec_config
= cmdline
.Found(wxT("ec-config"));
480 if ( cmdline
.Found(wxT("config-dir"), &ConfigDir
) ) {
481 if (ConfigDir
.Last() != wxFileName::GetPathSeparator()) {
482 ConfigDir
+= wxFileName::GetPathSeparator();
485 ConfigDir
= GetConfigDir();
488 ConfigDir
= GetConfigDir();
491 if ( !cmdline
.Found(wxT("disable-fatal")) ) {
493 // catch fatal exceptions
494 wxHandleFatalExceptions(true);
498 bool reset_config
= cmdline
.Found(wxT("reset-config"));
500 theLogger
.SetEnabledStdoutLog(cmdline
.Found(wxT("log-stdout")));
502 enable_daemon_fork
= cmdline
.Found(wxT("full-daemon"));
503 if ( cmdline
.Found(wxT("pid-file"), &PidFile
) ) {
504 // Remove any existing PidFile
505 if ( wxFileExists (PidFile
) ) wxRemoveFile (PidFile
);
508 enable_daemon_fork
= false;
512 if (theLogger
.IsEnabledStdoutLog()) {
513 if ( enable_daemon_fork
) {
514 AddLogLineMS(false, wxT("Daemon will fork to background - log to stdout disabled"));
515 theLogger
.SetEnabledStdoutLog(false);
517 AddLogLineMS(false, wxT("Logging to stdout enabled"));
521 if ( cmdline
.Found(wxT("version")) ) {
522 AddLogLineMS(false, CFormat(wxT("%s (OS: %s)")) % FullMuleVersion
% OSType
);
527 // Default geometry of the GUI. Can be changed with a cmdline argument...
528 bool geometry_enabled
= false;
529 wxString geom_string
;
531 if ( cmdline
.Found(wxT("geometry"), &geom_string
) ) {
532 geometry_enabled
= true;
536 AddLogLineMS(false, wxT("Initialising ") + FullMuleVersion
);
538 // Ensure that "~/.aMule/" is accessible.
539 if (!CheckMuleDirectory(wxT("configuration"), CPath(ConfigDir
), wxEmptyString
).first
) {
544 // Make a backup first.
545 wxRemoveFile(ConfigDir
+ wxT("amule.conf.backup"));
546 wxRenameFile(ConfigDir
+ wxT("amule.conf"), ConfigDir
+ wxT("amule.conf.backup"));
547 AddLogLineMS(false, wxT("Your settings have been reset to default values.\nThe old config file has been saved as amule.conf.backup\n"));
550 #if defined(__WXMAC__) && defined(AMULE_DAEMON)
551 //#warning TODO: fix wxSingleInstanceChecker for amuled on Mac (wx link problems)
552 AddLogLineMS(true, wxT("WARNING: The check for other instances is currently disabled in amuled.\n"
553 "Please make sure that no other instance of aMule is running or your files might be corrupted.\n"));
555 AddLogLineMS(false, wxT("Checking if there is an instance already running..."));
557 m_singleInstance
= new wxSingleInstanceChecker();
558 if (m_singleInstance
->Create(wxT("muleLock"), ConfigDir
)
559 && m_singleInstance
->IsAnotherRunning()) {
560 AddLogLineMS(true, wxT("There is an instance of aMule already running"));
561 AddLogLineNS(CFormat(wxT("(lock file: %s%s)")) % ConfigDir
% wxT("muleLock"));
563 // This is very tricky. The most secure way to communicate is via ED2K links file
564 wxTextFile
ed2kFile(ConfigDir
+ wxT("ED2KLinks"));
565 if (!ed2kFile
.Exists()) {
569 if (ed2kFile
.Open()) {
570 ed2kFile
.AddLine(wxT("RAISE_DIALOG"));
573 AddLogLineMS(false, wxT("Raising current running instance."));
575 AddLogLineMS(true, wxT("Failed to open 'ED2KFile', cannot signal running instance."));
580 AddLogLineMS(false, wxT("No other instances are running."));
584 // Close standard-input
585 if ( !cmdline
.Found(wxT("enable-stdin")) ) {
586 // The full daemon will close all std file-descriptors by itself,
587 // so closing it here would lead to the closing on the first open
588 // file, which is the logfile opened below
589 if (!enable_daemon_fork
) {
594 // This creates the CFG file we shall use
595 wxConfigBase
* cfg
= new wxFileConfig( wxEmptyString
, wxEmptyString
, ConfigDir
+ wxT("amule.conf") );
597 // Set the config object as the global cfg file
598 wxConfig::Set( cfg
);
600 // Make a backup of the log file
601 CPath logfileName
= CPath(ConfigDir
+ wxT("logfile"));
602 if (logfileName
.FileExists()) {
603 CPath::BackupFile(logfileName
, wxT(".bak"));
607 if (!theLogger
.OpenLogfile(logfileName
.GetRaw())) {
608 // use std err as last resolt to indicate problem
609 fputs("ERROR: unable to open log file\n", stderr
);
610 // failure to open log is serious problem
615 CPreferences::BuildItemList(ConfigDir
);
616 CPreferences::LoadAllItems( wxConfigBase::Get() );
618 glob_prefs
= new CPreferences();
620 std::pair
<bool, CPath
> checkResult
;
621 checkResult
= CheckMuleDirectory(wxT("temp"), thePrefs::GetTempDir(), ConfigDir
+ wxT("Temp"));
622 if (checkResult
.first
) {
623 thePrefs::SetTempDir(checkResult
.second
);
628 checkResult
= CheckMuleDirectory(wxT("incoming"), thePrefs::GetIncomingDir(), ConfigDir
+ wxT("Incoming"));
629 if (checkResult
.first
) {
630 thePrefs::SetIncomingDir(checkResult
.second
);
636 if (!thePrefs::UseTrayIcon()) {
637 thePrefs::SetMinToTray(false);
640 // Build the filenames for the two OS files
641 SetOSFiles(thePrefs::GetOSDir().GetRaw());
644 // Load localization settings
648 // Configure EC for amuled when invoked with ec-config
650 AddLogLineMS(false, _("\nEC configuration"));
651 thePrefs::SetECPass(GetPassword());
652 thePrefs::EnableExternalConnections(true);
653 AddLogLineMS(false, _("Password set and external connections enabled."));
659 wxT("Warning! You are running aMule as root.\n")
660 wxT("Doing so is not recommended for security reasons,\n")
661 wxT("and you are advised to run aMule as an normal\n")
662 wxT("user instead.");
664 ShowAlert(msg
, _("WARNING"), wxCENTRE
| wxOK
| wxICON_ERROR
);
666 fprintf(stderr
, "\n--------------------------------------------------\n");
667 fprintf(stderr
, "%s", (const char*)unicode2UTF8(msg
));
668 fprintf(stderr
, "\n--------------------------------------------------\n\n");
672 // Display notification on new version or first run
673 wxTextFile
vfile( ConfigDir
+ wxT("lastversion") );
674 wxString
newMule(wxT( VERSION
));
676 if ( !wxFileExists( vfile
.GetName() ) ) {
680 if ( vfile
.Open() ) {
681 // Check if this version has been run before
683 for ( size_t i
= 0; i
< vfile
.GetLineCount(); i
++ ) {
684 // Check if this version has been run before
685 if ( vfile
.GetLine(i
) == newMule
) {
691 // We havent run this version before?
693 // Insert new at top to provide faster searches
694 vfile
.InsertLine( newMule
, 0 );
696 Trigger_New_version( newMule
);
699 // Keep at most 10 entires
700 while ( vfile
.GetLineCount() > 10 )
701 vfile
.RemoveLine( vfile
.GetLineCount() - 1 );
707 // Check if we have the old style locale config
708 wxString langId
= thePrefs::GetLanguageID();
709 if (!langId
.IsEmpty() && (langId
.GetChar(0) >= '0' && langId
.GetChar(0) <= '9')) {
710 wxString
info(_("Your locale has been changed to System Default due to a configuration change. Sorry."));
711 thePrefs::SetLanguageID(wxLang2Str(wxLANGUAGE_DEFAULT
));
712 ShowAlert(info
, _("Info"), wxCENTRE
| wxOK
| wxICON_ERROR
);
715 m_statistics
= new CStatistics();
717 clientlist
= new CClientList();
718 friendlist
= new CFriendList();
719 searchlist
= new CSearchList();
720 knownfiles
= new CKnownFileList();
721 serverlist
= new CServerList();
723 sharedfiles
= new CSharedFileList(knownfiles
);
724 clientcredits
= new CClientCreditsList();
726 // bugfix - do this before creating the uploadqueue
727 downloadqueue
= new CDownloadQueue();
728 uploadqueue
= new CUploadQueue();
729 ipfilter
= new CIPFilter();
731 // Creates all needed listening sockets
733 if (!ReinitializeNetwork(&msg
)) {
734 AddLogLineMS(false, wxT("\n"));
735 AddLogLineMS(false, msg
);
738 // Test if there's any new version
739 if (thePrefs::CheckNewVersion()) {
740 // We use the thread base because I don't want a dialog to pop up.
741 CHTTPDownloadThread
* version_check
=
742 new CHTTPDownloadThread(wxT("http://amule.sourceforge.net/lastversion"),
743 theApp
->ConfigDir
+ wxT("last_version_check"), HTTP_VersionCheck
, false);
744 version_check
->Create();
745 version_check
->Run();
748 // Create main dialog, or fork to background (daemon).
749 InitGui(geometry_enabled
, geom_string
);
751 #if !defined(__WXMAC__) && defined(AMULE_DAEMON)
752 // Need to refresh wxSingleInstanceChecker after the daemon fork() !
753 if (enable_daemon_fork
) {
754 //#warning TODO: fix wxSingleInstanceChecker for amuled on Mac (wx link problems)
755 delete m_singleInstance
;
756 m_singleInstance
= new wxSingleInstanceChecker(wxT("muleLock"), ConfigDir
);
757 // No need to check IsAnotherRunning() - we've done it before.
761 // Has to be created after the call to InitGui, as fork
762 // (when using posix threads) only replicates the mainthread,
763 // and the UBT constructor creates a thread.
764 uploadBandwidthThrottler
= new UploadBandwidthThrottler();
766 // These must be initialized after the gui is loaded.
768 downloadqueue
->LoadMetFiles(thePrefs::GetTempDir());
769 sharedfiles
->Reload();
771 if (thePrefs::IPFilterAutoLoad()) {
772 ipfilter
->Update(thePrefs::IPFilterURL());
776 // Ensure that the up/down ratio is used
777 CPreferences::CheckUlDlRatio();
779 // The user can start pressing buttons like mad if he feels like it.
780 m_app_state
= APP_STATE_RUNNING
;
782 // Kry - Load the sources seeds on app init
783 if (thePrefs::GetSrcSeedsOn()) {
784 downloadqueue
->LoadSourceSeeds();
787 if (!serverlist
->GetServerCount() && thePrefs::GetNetworkED2K()) {
788 // There are no servers and ED2K active -> ask for download.
789 // As we cannot ask in amuled, we just update there
790 // Kry TODO: Store server.met URL on preferences and use it here and in GUI.
792 if (wxYES
== wxMessageBox(
794 _("You don't have any server in the server list.\nDo you want aMule to download a new list now?")),
795 wxString(_("Server list download")),
797 static_cast<wxWindow
*>(theApp
->amuledlg
)))
800 // workaround amuled crash
802 serverlist
->UpdateServerMetFromURL(
803 wxT("http://gruk.org/server.met.gz"));
809 // Autoconnect if that option is enabled
810 if (thePrefs::DoAutoConnect() && (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia())) {
811 AddLogLineM(true, _("Connecting"));
812 if (thePrefs::GetNetworkED2K()) {
813 theApp
->serverconnect
->ConnectToAnyServer();
821 #ifdef ENABLE_IP2COUNTRY
822 theApp
->amuledlg
->EnableIP2Country();
825 // No webserver on Win at all (yet)
828 if (thePrefs::GetWSIsEnabled()) {
829 wxString aMuleConfigFile
= ConfigDir
+ wxT("amule.conf");
830 wxString amulewebPath
= wxT("amuleweb");
831 if(true == cmdline
.Found(wxT("use-amuleweb"), &amulewebPath
)) {
832 AddLogLineNS(CFormat(_("Using amuleweb in '%s'.")) % amulewebPath
);
835 #if defined(__WXMAC__) && !defined(AMULE_DAEMON)
836 // For the Mac GUI application, look for amuleweb in the bundle
837 CFURLRef amulewebUrl
= CFBundleCopyAuxiliaryExecutableURL(
838 CFBundleGetMainBundle(), CFSTR("amuleweb"));
841 CFURLRef absoluteUrl
= CFURLCopyAbsoluteURL(amulewebUrl
);
842 CFRelease(amulewebUrl
);
845 CFStringRef amulewebCfstr
= CFURLCopyFileSystemPath(absoluteUrl
, kCFURLPOSIXPathStyle
);
846 CFRelease(absoluteUrl
);
847 amulewebPath
= wxMacCFStringHolder(amulewebCfstr
).AsString(wxLocale::GetSystemEncoding());
855 wxT("' '--amule-config-file=") +
858 CTerminationProcessAmuleweb
*p
= new CTerminationProcessAmuleweb(cmd
, &webserver_pid
);
859 webserver_pid
= wxExecute(cmd
, wxEXEC_ASYNC
, p
);
860 bool webserver_ok
= webserver_pid
> 0;
862 AddLogLineM(true, CFormat(_("web server running on pid %d")) % webserver_pid
);
866 "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"),
867 _("ERROR"), wxOK
| wxICON_ERROR
);
870 #endif /* ! __WXMSW__ */
872 // Start performing background tasks
873 CThreadScheduler::Start();
878 bool CamuleApp::ReinitializeNetwork(wxString
* msg
)
881 static bool firstTime
= true;
884 // TODO: Destroy previously created sockets
888 // Some sanity checks first
889 if (thePrefs::ECPort() == thePrefs::GetPort()) {
890 // Select a random usable port in the range 1025 ... 2^16 - 1
891 uint16 port
= thePrefs::ECPort();
892 while ( port
< 1024 || port
== thePrefs::GetPort() ) {
893 port
= (uint16
)rand();
895 thePrefs::SetECPort( port
);
898 wxT("Network configuration failed! You cannot use the same port\n")
899 wxT("for the main TCP port and the External Connections port.\n")
900 wxT("The EC port has been changed to avoid conflict, see the\n")
901 wxT("preferences for the new value.\n");
904 AddLogLineM( false, wxEmptyString
);
905 AddLogLineM( true, err
);
906 AddLogLineM( false, wxEmptyString
);
911 if (thePrefs::GetUDPPort() == thePrefs::GetPort() + 3) {
912 // Select a random usable value in the range 1025 ... 2^16 - 1
913 uint16 port
= thePrefs::GetUDPPort();
914 while ( port
< 1024 || port
== thePrefs::GetPort() + 3 ) {
915 port
= (uint16
)rand();
917 thePrefs::SetUDPPort( port
);
920 wxT("Network configuration failed! You set your UDP port to\n")
921 wxT("the value of the main TCP port plus 3.\n")
922 wxT("This port has been reserved for the Server-UDP port. The\n")
923 wxT("port value has been changed to avoid conflict, see the\n")
924 wxT("preferences for the new value\n");
927 AddLogLineM( false, wxEmptyString
);
928 AddLogLineM( true, err
);
929 AddLogLineM( false, wxEmptyString
);
934 // Create the address where we are going to listen
935 // TODO: read this from configuration file
936 amuleIPV4Address myaddr
[4];
938 // Create the External Connections Socket.
940 // Get ready to handle connections from apps like amulecmd
941 if (thePrefs::GetECAddress().IsEmpty() || !myaddr
[0].Hostname(thePrefs::GetECAddress())) {
942 myaddr
[0].AnyAddress();
944 myaddr
[0].Service(thePrefs::ECPort());
945 ECServerHandler
= new ExternalConn(myaddr
[0], msg
);
947 // Create the UDP socket TCP+3.
948 // Used for source asking on servers.
949 if (thePrefs::GetAddress().IsEmpty()) {
950 myaddr
[1].AnyAddress();
951 } else if (!myaddr
[1].Hostname(thePrefs::GetAddress())) {
952 myaddr
[1].AnyAddress();
953 AddLogLineM(true, CFormat(_("Could not bind ports to the specified address: %s"))
954 % thePrefs::GetAddress());
957 wxString ip
= myaddr
[1].IPAddress();
958 myaddr
[1].Service(thePrefs::GetPort()+3);
959 serverconnect
= new CServerConnect(serverlist
, myaddr
[1]);
960 *msg
<< CFormat( wxT("*** Server UDP socket (TCP+3) at %s:%u\n") )
961 % ip
% ((unsigned int)thePrefs::GetPort() + 3u);
963 // Create the ListenSocket (aMule TCP socket).
964 // Used for Client Port / Connections from other clients,
965 // Client to Client Source Exchange.
967 myaddr
[2] = myaddr
[1];
968 myaddr
[2].Service(thePrefs::GetPort());
969 listensocket
= new CListenSocket(myaddr
[2]);
970 *msg
<< CFormat( wxT("*** TCP socket (TCP) listening on %s:%u\n") )
971 % ip
% (unsigned int)(thePrefs::GetPort());
972 // This command just sets a flag to control maximum number of connections.
973 // Notify(true) has already been called to the ListenSocket, so events may
974 // be already comming in.
975 if (listensocket
->Ok()) {
976 listensocket
->StartListening();
978 // If we wern't able to start listening, we need to warn the user
980 err
= CFormat(_("Port %u is not available. You will be LOWID\n")) %
981 (unsigned int)(thePrefs::GetPort());
983 AddLogLineM(true, err
);
986 _("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.")) %
987 (unsigned int)(thePrefs::GetPort());
988 ShowAlert(err
, _("ERROR"), wxOK
| wxICON_ERROR
);
991 // Create the UDP socket.
992 // Used for extended eMule protocol, Queue Rating, File Reask Ping.
993 // Also used for Kademlia.
994 // Default is port 4672.
995 myaddr
[3] = myaddr
[1];
996 myaddr
[3].Service(thePrefs::GetUDPPort());
997 clientudp
= new CClientUDPSocket(myaddr
[3], thePrefs::GetProxyData());
998 if (!thePrefs::IsUDPDisabled()) {
999 *msg
<< CFormat( wxT("*** Client UDP socket (extended eMule) at %s:%u") )
1000 % ip
% thePrefs::GetUDPPort();
1002 *msg
<< wxT("*** Client UDP socket (extended eMule) disabled on preferences");
1006 if (thePrefs::GetUPnPEnabled()) {
1008 m_upnpMappings
[0] = CUPnPPortMapping(
1009 myaddr
[0].Service(),
1011 thePrefs::GetUPnPECEnabled(),
1012 "aMule TCP External Connections Socket");
1013 m_upnpMappings
[1] = CUPnPPortMapping(
1014 myaddr
[1].Service(),
1016 thePrefs::GetUPnPEnabled(),
1017 "aMule UDP socket (TCP+3)");
1018 m_upnpMappings
[2] = CUPnPPortMapping(
1019 myaddr
[2].Service(),
1021 thePrefs::GetUPnPEnabled(),
1022 "aMule TCP Listen Socket");
1023 m_upnpMappings
[3] = CUPnPPortMapping(
1024 myaddr
[3].Service(),
1026 thePrefs::GetUPnPEnabled(),
1027 "aMule UDP Extended eMule Socket");
1028 m_upnp
= new CUPnPControlPoint(thePrefs::GetUPnPTCPPort());
1029 m_upnp
->AddPortMappings(m_upnpMappings
);
1030 } catch(CUPnPException
&e
) {
1032 error_msg
<< e
.what();
1033 AddLogLineM(true, error_msg
);
1034 fprintf(stderr
, "%s\n", (const char *)unicode2char(error_msg
));
1042 // Returns a magnet ed2k URI
1043 wxString
CamuleApp::CreateMagnetLink(const CAbstractFile
*f
)
1047 uri
.AddField(wxT("dn"), f
->GetFileName().Cleanup(false).GetPrintable());
1048 uri
.AddField(wxT("xt"), wxString(wxT("urn:ed2k:")) + f
->GetFileHash().Encode().Lower());
1049 uri
.AddField(wxT("xt"), wxString(wxT("urn:ed2khash:")) + f
->GetFileHash().Encode().Lower());
1050 uri
.AddField(wxT("xl"), CFormat(wxT("%d")) % f
->GetFileSize());
1052 return uri
.GetLink();
1055 // Returns a ed2k file URL
1056 wxString
CamuleApp::CreateED2kLink(const CAbstractFile
*f
, bool add_source
, bool use_hostname
, bool addcryptoptions
)
1058 wxASSERT(!(!add_source
&& (use_hostname
|| addcryptoptions
)));
1059 // Construct URL like this: ed2k://|file|<filename>|<size>|<hash>|/
1060 wxString strURL
= CFormat(wxT("ed2k://|file|%s|%i|%s|/"))
1061 % f
->GetFileName().Cleanup(false)
1062 % f
->GetFileSize() % f
->GetFileHash().Encode();
1064 if (add_source
&& IsConnected() && !IsFirewalled()) {
1065 // Create the first part of the URL
1066 strURL
<< wxT("|sources,");
1068 strURL
<< thePrefs::GetYourHostname();
1070 uint32 clientID
= GetID();
1071 strURL
<< (uint8
) clientID
<< wxT(".") <<
1072 (uint8
)(clientID
>> 8) << wxT(".") <<
1073 (uint8
)(clientID
>> 16) << wxT(".") <<
1074 (uint8
)(clientID
>> 24);
1077 strURL
<< wxT(":") <<
1078 thePrefs::GetPort();
1080 if (addcryptoptions
) {
1081 const uint8 uSupportsCryptLayer
= thePrefs::IsClientCryptLayerSupported() ? 1 : 0;
1082 const uint8 uRequestsCryptLayer
= thePrefs::IsClientCryptLayerRequested() ? 1 : 0;
1083 const uint8 uRequiresCryptLayer
= thePrefs::IsClientCryptLayerRequired() ? 1 : 0;
1084 const uint8 byCryptOptions
= (uRequiresCryptLayer
<< 2) | (uRequestsCryptLayer
<< 1) | (uSupportsCryptLayer
<< 0) | (uSupportsCryptLayer
? 0x80 : 0x00);
1086 strURL
<< wxT(":") << byCryptOptions
;
1088 if (byCryptOptions
& 0x80) {
1089 strURL
<< wxT(":") << thePrefs::GetUserHash().Encode();
1092 strURL
<< wxT("|/");
1093 } else if (add_source
) {
1094 AddLogLineM(true, _("WARNING: You can't add yourself as a source for an eD2k link while having a lowid."));
1097 // Result is "ed2k://|file|<filename>|<size>|<hash>|/|sources,[(<ip>|<hostname>):<port>[:cryptoptions[:hash]]]|/"
1101 // Returns a ed2k link with AICH info if available
1102 wxString
CamuleApp::CreateED2kAICHLink(const CKnownFile
* f
)
1104 // Create the first part of the URL
1105 wxString strURL
= CreateED2kLink(f
);
1106 // Append the AICH info
1107 if (f
->HasProperAICHHashSet()) {
1108 strURL
.RemoveLast(); // remove trailing '/'
1109 strURL
<< wxT("h=") << f
->GetAICHMasterHash() << wxT("|/");
1112 // Result is "ed2k://|file|<filename>|<size>|<hash>|h=<AICH master hash>|/"
1116 /* Original implementation by Bouc7 of the eMule Project.
1117 aMule Signature idea was designed by BigBob and implemented
1118 by Un-Thesis, with design inputs and suggestions from bothie.
1120 void CamuleApp::OnlineSig(bool zero
/* reset stats (used on shutdown) */)
1122 // Do not do anything if online signature is disabled in Preferences
1123 if (!thePrefs::IsOnlineSignatureEnabled() || m_emulesig_path
.IsEmpty()) {
1124 // We do not need to check m_amulesig_path because if m_emulesig_path is empty,
1125 // that means m_amulesig_path is empty too.
1129 // Remove old signature files
1130 if ( wxFileExists( m_emulesig_path
) ) { wxRemoveFile( m_emulesig_path
); }
1131 if ( wxFileExists( m_amulesig_path
) ) { wxRemoveFile( m_amulesig_path
); }
1134 wxTextFile amulesig_out
;
1135 wxTextFile emulesig_out
;
1137 // Open both files if needed
1138 if ( !emulesig_out
.Create( m_emulesig_path
) ) {
1139 AddLogLineM(true, _("Failed to create OnlineSig File"));
1140 // Will never try again.
1141 m_amulesig_path
.Clear();
1142 m_emulesig_path
.Clear();
1146 if ( !amulesig_out
.Create(m_amulesig_path
) ) {
1147 AddLogLineM(true, _("Failed to create aMule OnlineSig File"));
1148 // Will never try again.
1149 m_amulesig_path
.Clear();
1150 m_emulesig_path
.Clear();
1154 wxString emulesig_string
;
1158 emulesig_string
= wxT("0\xA0.0|0.0|0");
1159 amulesig_out
.AddLine(wxT("0\n0\n0\n0\n0\n0\n0.0\n0.0\n0\n0"));
1161 if (IsConnectedED2K()) {
1163 temp
= wxString::Format(wxT("%d"),serverconnect
->GetCurrentServer()->GetPort());
1170 + serverconnect
->GetCurrentServer()->GetListName()
1172 // IP and port of the server
1173 + serverconnect
->GetCurrentServer()->GetFullIP()
1178 // Now for amule sig
1180 // Connected. State 1, full info
1181 amulesig_out
.AddLine(wxT("1"));
1183 amulesig_out
.AddLine(serverconnect
->GetCurrentServer()->GetListName());
1185 amulesig_out
.AddLine(serverconnect
->GetCurrentServer()->GetFullIP());
1187 amulesig_out
.AddLine(temp
);
1189 if (serverconnect
->IsLowID()) {
1190 amulesig_out
.AddLine(wxT("L"));
1192 amulesig_out
.AddLine(wxT("H"));
1195 } else if (serverconnect
->IsConnecting()) {
1196 emulesig_string
= wxT("0");
1198 // Connecting. State 2, No info.
1199 amulesig_out
.AddLine(wxT("2\n0\n0\n0\n0"));
1201 // Not connected to a server
1202 emulesig_string
= wxT("0");
1204 // Not connected, state 0, no info
1205 amulesig_out
.AddLine(wxT("0\n0\n0\n0\n0"));
1207 if (IsConnectedKad()) {
1208 if(Kademlia::CKademlia::IsFirewalled()) {
1209 // Connected. Firewalled. State 1.
1210 amulesig_out
.AddLine(wxT("1"));
1212 // Connected. State 2.
1213 amulesig_out
.AddLine(wxT("2"));
1216 // Not connected.State 0.
1217 amulesig_out
.AddLine(wxT("0"));
1219 emulesig_string
+= wxT("\xA");
1221 // Datarate for downloads
1222 temp
= wxString::Format(wxT("%.1f"), theStats::GetDownloadRate() / 1024.0);
1224 emulesig_string
+= temp
+ wxT("|");
1225 amulesig_out
.AddLine(temp
);
1227 // Datarate for uploads
1228 temp
= wxString::Format(wxT("%.1f"), theStats::GetUploadRate() / 1024.0);
1230 emulesig_string
+= temp
+ wxT("|");
1231 amulesig_out
.AddLine(temp
);
1233 // Number of users waiting for upload
1234 temp
= wxString::Format(wxT("%d"), theStats::GetWaitingUserCount());
1236 emulesig_string
+= temp
;
1237 amulesig_out
.AddLine(temp
);
1239 // Number of shared files (not on eMule)
1240 amulesig_out
.AddLine(wxString::Format(wxT("%d"), theStats::GetSharedFileCount()));
1243 // eMule signature finished here. Write the line to the wxTextFile.
1244 emulesig_out
.AddLine(emulesig_string
);
1246 // Now for aMule signature extras
1248 // Nick on the network
1249 amulesig_out
.AddLine(thePrefs::GetUserNick());
1251 // Total received in bytes
1252 amulesig_out
.AddLine( CFormat( wxT("%llu") ) % (theStats::GetSessionReceivedBytes() + thePrefs::GetTotalDownloaded()) );
1254 // Total sent in bytes
1255 amulesig_out
.AddLine( CFormat( wxT("%llu") ) % (theStats::GetSessionSentBytes() + thePrefs::GetTotalUploaded()) );
1259 amulesig_out
.AddLine(wxT(VERSION
) wxT(" ") wxT(SVNDATE
));
1261 amulesig_out
.AddLine(wxT(VERSION
));
1265 amulesig_out
.AddLine(wxT("0"));
1266 amulesig_out
.AddLine(wxT("0"));
1267 amulesig_out
.AddLine(wxT("0"));
1269 // Total received bytes in session
1270 amulesig_out
.AddLine( CFormat( wxT("%llu") ) %
1271 theStats::GetSessionReceivedBytes() );
1273 // Total sent bytes in session
1274 amulesig_out
.AddLine( CFormat( wxT("%llu") ) %
1275 theStats::GetSessionSentBytes() );
1278 amulesig_out
.AddLine(CFormat(wxT("%llu")) % theStats::GetUptimeSeconds());
1282 emulesig_out
.Write();
1283 amulesig_out
.Write();
1284 } //End Added By Bouc7
1287 // Gracefully handle fatal exceptions and print backtrace if possible
1288 void CamuleApp::OnFatalException()
1290 /* Print the backtrace */
1291 fprintf(stderr
, "\n--------------------------------------------------------------------------------\n");
1292 fprintf(stderr
, "A fatal error has occurred and aMule has crashed.\n");
1293 fprintf(stderr
, "Please assist us in fixing this problem by posting the backtrace below in our\n");
1294 fprintf(stderr
, "'aMule Crashes' forum and include as much information as possible regarding the\n");
1295 fprintf(stderr
, "circumstances of this crash. The forum is located here:\n");
1296 fprintf(stderr
, " http://forum.amule.org/index.php?board=67.0\n");
1297 fprintf(stderr
, "If possible, please try to generate a real backtrace of this crash:\n");
1298 fprintf(stderr
, " http://www.amule.org/wiki/index.php/Backtraces\n\n");
1299 fprintf(stderr
, "----------------------------=| BACKTRACE FOLLOWS: |=----------------------------\n");
1300 fprintf(stderr
, "Current version is: %s\n", strFullMuleVersion
);
1301 fprintf(stderr
, "Running on: %s\n\n", strOSDescription
);
1303 print_backtrace(1); // 1 == skip this function.
1305 fprintf(stderr
, "\n--------------------------------------------------------------------------------\n");
1309 // Sets the localization of aMule
1310 void CamuleApp::Localize_mule()
1312 InitCustomLanguages();
1313 InitLocale(m_locale
, StrLang2wx(thePrefs::GetLanguageID()));
1314 if (!m_locale
.IsOk()) {
1315 AddLogLineM(false,_("The selected locale seems not to be installed on your box. (Note: I'll try to set it anyway)"));
1320 // Displays information related to important changes in aMule.
1321 // Is called when the user runs a new version of aMule
1322 void CamuleApp::Trigger_New_version(wxString new_version
)
1324 wxString info
= wxT(" --- ") + CFormat(_("This is the first time you run aMule %s")) % new_version
+ wxT(" ---\n\n");
1325 if (new_version
== wxT("SVN")) {
1326 info
+= _("This version is a testing version, updated daily, and\n");
1327 info
+= _("we give no warranty it won't break anything, burn your house,\n");
1328 info
+= _("or kill your dog. But it *should* be safe to use anyway.\n");
1329 } else if (new_version
== wxT("2.2.1")) {
1330 thePrefs::SetAddServersFromServer(false);
1331 thePrefs::SetAddServersFromClient(false);
1332 info
+= _("The following options have been changed in this release for security reasons:\n");
1333 info
+= _("\n* Enabled Protocol Obfuscation support for incoming and outgoing connections.\n");
1334 info
+= _("\n* Disabled updating the server list from other server and clients.\n");
1335 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.");
1336 info
+= _("\n\nAdditionally, the browser settings have been reset to the system default. Please configure your browser options again if needed.\n");
1341 info
+= _("More information, support and new releases can found at our homepage,\n");
1342 info
+= _("at www.aMule.org, or in our IRC channel #aMule at irc.freenode.net.\n");
1344 info
+= _("Feel free to report any bugs to http://forum.amule.org");
1346 ShowAlert(info
, _("Info"), wxCENTRE
| wxOK
| wxICON_ERROR
);
1350 void CamuleApp::SetOSFiles(const wxString new_path
)
1352 if ( thePrefs::IsOnlineSignatureEnabled() ) {
1353 if ( ::wxDirExists(new_path
) ) {
1354 m_emulesig_path
= JoinPaths(new_path
, wxT("onlinesig.dat"));
1355 m_amulesig_path
= JoinPaths(new_path
, wxT("amulesig.dat"));
1357 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
);
1358 m_emulesig_path
.Clear();
1359 m_amulesig_path
.Clear();
1362 m_emulesig_path
.Clear();
1363 m_amulesig_path
.Clear();
1369 #ifndef wxUSE_STACKWALKER
1370 #define wxUSE_STACKWALKER 0
1372 void CamuleApp::OnAssertFailure(const wxChar
* file
, int line
,
1373 const wxChar
* func
, const wxChar
* cond
, const wxChar
* msg
)
1375 if (!wxUSE_STACKWALKER
|| !wxThread::IsMain() || !IsRunning()) {
1376 wxString errmsg
= CFormat( wxT("%s:%s:%d: Assertion '%s' failed. %s") )
1377 % file
% func
% line
% cond
% ( msg
? msg
: wxT("") );
1379 fprintf(stderr
, "Assertion failed: %s\n", (const char*)unicode2char(errmsg
));
1381 // Skip the function-calls directly related to the assert call.
1382 fprintf(stderr
, "\nBacktrace follows:\n");
1384 fprintf(stderr
, "\n");
1387 if (wxThread::IsMain() && IsRunning()) {
1388 AMULE_APP_BASE::OnAssertFailure(file
, line
, func
, cond
, msg
);
1390 // Abort, allows gdb to catch the assertion
1397 void CamuleApp::OnUDPDnsDone(CMuleInternalEvent
& evt
)
1399 CServerUDPSocket
* socket
=(CServerUDPSocket
*)evt
.GetClientData();
1400 socket
->OnHostnameResolved(evt
.GetExtraLong());
1404 void CamuleApp::OnSourceDnsDone(CMuleInternalEvent
& evt
)
1406 downloadqueue
->OnHostnameResolved(evt
.GetExtraLong());
1410 void CamuleApp::OnServerDnsDone(CMuleInternalEvent
& evt
)
1412 AddLogLineMS(false, _("Server hostname notified"));
1413 serverconnect
->OnServerHostnameResolved(evt
.GetClientData(), evt
.GetExtraLong());
1417 void CamuleApp::OnTCPTimer(CTimerEvent
& WXUNUSED(evt
))
1422 serverconnect
->StopConnectionTry();
1423 if (IsConnectedED2K() ) {
1426 serverconnect
->ConnectToAnyServer();
1430 void CamuleApp::OnCoreTimer(CTimerEvent
& WXUNUSED(evt
))
1432 // Former TimerProc section
1433 static uint64 msPrev1
, msPrev5
, msPrevSave
, msPrevHist
, msPrevOS
, msPrevKnownMet
;
1434 uint64 msCur
= theStats::GetUptimeMillis();
1435 TheTime
= msCur
/ 1000;
1441 #ifndef AMULE_DAEMON
1442 // Check if we should terminate the app
1443 if ( g_shutdownSignal
) {
1444 wxWindow
* top
= GetTopWindow();
1449 // No top-window, have to force termination.
1455 uploadqueue
->Process();
1456 downloadqueue
->Process();
1457 //theApp->clientcredits->Process();
1458 theStats::CalculateRates();
1460 if (msCur
-msPrevHist
> 1000) {
1461 // unlike the other loop counters in this function this one will sometimes
1462 // produce two calls in quick succession (if there was a gap of more than one
1463 // second between calls to TimerProc) - this is intentional! This way the
1464 // history list keeps an average of one node per second and gets thinned out
1465 // correctly as time progresses.
1468 m_statistics
->RecordHistory();
1473 if (msCur
-msPrev1
> 1000) { // approximately every second
1475 clientcredits
->Process();
1476 clientlist
->Process();
1478 // Publish files to server if needed.
1479 sharedfiles
->Process();
1481 if( Kademlia::CKademlia::IsRunning() ) {
1482 Kademlia::CKademlia::Process();
1483 if(Kademlia::CKademlia::GetPrefs()->HasLostConnection()) {
1487 if (thePrefs::Reconnect()) {
1493 if( serverconnect
->IsConnecting() && !serverconnect
->IsSingleConnect() ) {
1494 serverconnect
->TryAnotherConnectionrequest();
1496 if (serverconnect
->IsConnecting()) {
1497 serverconnect
->CheckForTimeout();
1499 listensocket
->UpdateConnectionsStatus();
1504 if (msCur
-msPrev5
> 5000) { // every 5 seconds
1506 listensocket
->Process();
1509 if (msCur
-msPrevSave
>= 60000) {
1513 // Save total upload/download to preferences
1514 wxConfigBase
* cfg
= wxConfigBase::Get();
1515 buffer
= CFormat(wxT("%llu")) % (theStats::GetSessionReceivedBytes() + thePrefs::GetTotalDownloaded());
1516 cfg
->Write(wxT("/Statistics/TotalDownloadedBytes"), buffer
);
1518 buffer
= CFormat(wxT("%llu")) % (theStats::GetSessionSentBytes() + thePrefs::GetTotalUploaded());
1519 cfg
->Write(wxT("/Statistics/TotalUploadedBytes"), buffer
);
1521 // Write changes to file
1527 if (msCur
- msPrevOS
>= thePrefs::GetOSUpdate() * 1000ull) {
1528 OnlineSig(); // Added By Bouc7
1532 if (msCur
- msPrevKnownMet
>= 30*60*1000/*There must be a prefs option for this*/) {
1533 // Save Shared Files data
1535 msPrevKnownMet
= msCur
;
1539 // Recomended by lugdunummaster himself - from emule 0.30c
1540 serverconnect
->KeepConnectionAlive();
1545 void CamuleApp::OnFinishedHashing(CHashingEvent
& evt
)
1547 wxCHECK_RET(evt
.GetResult(), wxT("No result of hashing"));
1549 CKnownFile
* owner
= const_cast<CKnownFile
*>(evt
.GetOwner());
1550 CKnownFile
* result
= evt
.GetResult();
1553 // Check if the partfile still exists, as it might have
1554 // been deleted in the mean time.
1555 if (downloadqueue
->IsPartFile(owner
)) {
1556 // This cast must not be done before the IsPartFile
1557 // call, as dynamic_cast will barf on dangling pointers.
1558 dynamic_cast<CPartFile
*>(owner
)->PartFileHashFinished(result
);
1561 static int filecount
;
1562 static uint64 bytecount
;
1564 if (knownfiles
->SafeAddKFile(result
)) {
1565 AddDebugLogLineM(false, logKnownFiles
,
1566 CFormat(wxT("Safe adding file to sharedlist: %s")) % result
->GetFileName());
1567 sharedfiles
->SafeAddKFile(result
);
1570 bytecount
+= result
->GetFileSize();
1571 // If we have added 30 files or files with a total size of ~300mb
1572 if ( ( filecount
== 30 ) || ( bytecount
>= 314572800 ) ) {
1573 AddDebugLogLineM(false, logKnownFiles
, wxT("Failsafe for crash on file hashing creation"));
1574 if ( m_app_state
!= APP_STATE_SHUTTINGDOWN
) {
1581 AddDebugLogLineM(false, logKnownFiles
,
1582 CFormat(wxT("File not added to sharedlist: %s")) % result
->GetFileName());
1589 void CamuleApp::OnFinishedAICHHashing(CHashingEvent
& evt
)
1591 wxCHECK_RET(evt
.GetResult(), wxT("No result of AICH-hashing"));
1593 CKnownFile
* owner
= const_cast<CKnownFile
*>(evt
.GetOwner());
1594 CScopedPtr
<CKnownFile
> result(evt
.GetResult());
1596 // Check that the owner is still valid
1597 if (knownfiles
->IsKnownFile(owner
)) {
1598 if (result
->GetAICHHashset()->GetStatus() == AICH_HASHSETCOMPLETE
) {
1599 CAICHHashSet
* oldSet
= owner
->GetAICHHashset();
1600 CAICHHashSet
* newSet
= result
->GetAICHHashset();
1602 owner
->SetAICHHashset(newSet
);
1603 newSet
->SetOwner(owner
);
1605 result
->SetAICHHashset(oldSet
);
1606 oldSet
->SetOwner(result
.get());
1612 void CamuleApp::OnFinishedCompletion(CCompletionEvent
& evt
)
1614 CPartFile
* completed
= const_cast<CPartFile
*>(evt
.GetOwner());
1615 wxCHECK_RET(completed
, wxT("Completion event sent for unspecified file"));
1616 wxASSERT_MSG(downloadqueue
->IsPartFile(completed
), wxT("CCompletionEvent for unknown partfile."));
1618 completed
->CompleteFileEnded(evt
.ErrorOccured(), evt
.GetFullPath());
1619 if (evt
.ErrorOccured()) {
1620 CUserEvents::ProcessEvent(CUserEvents::ErrorOnCompletion
, completed
);
1623 // Check if we should execute an script/app/whatever.
1624 CUserEvents::ProcessEvent(CUserEvents::DownloadCompleted
, completed
);
1627 void CamuleApp::OnFinishedAllocation(CAllocFinishedEvent
& evt
)
1629 CPartFile
*file
= evt
.GetFile();
1630 wxCHECK_RET(file
, wxT("Allocation finished event sent for unspecified file"));
1631 wxASSERT_MSG(downloadqueue
->IsPartFile(file
), wxT("CAllocFinishedEvent for unknown partfile"));
1633 file
->SetPartFileStatus(PS_EMPTY
);
1635 if (evt
.Succeeded()) {
1636 if (evt
.IsPaused()) {
1642 AddLogLineM(false, CFormat(_("Disk space preallocation for file '%s' failed: %s")) % file
->GetFileName() % wxString(UTF82unicode(std::strerror(evt
.GetResult()))));
1646 file
->AllocationFinished();
1649 void CamuleApp::OnNotifyEvent(CMuleGUIEvent
& evt
)
1651 #if defined(AMULE_DAEMON)
1654 if (theApp
->amuledlg
) {
1661 void CamuleApp::ShutDown()
1664 AddDebugLogLineM(false, logGeneral
, wxT("CamuleApp::ShutDown() has started."));
1666 // Signal the hashing thread to terminate
1667 m_app_state
= APP_STATE_SHUTTINGDOWN
;
1671 // Kry - Save the sources seeds on app exit
1672 if (thePrefs::GetSrcSeedsOn()) {
1673 downloadqueue
->SaveSourceSeeds();
1676 OnlineSig(true); // Added By Bouc7
1678 // Close sockets to avoid new clients coming in
1680 listensocket
->Close();
1681 listensocket
->KillAllSockets();
1684 if (serverconnect
) {
1685 serverconnect
->Disconnect();
1688 ECServerHandler
->KillAllSockets();
1691 if (thePrefs::GetUPnPEnabled()) {
1693 m_upnp
->DeletePortMappings(m_upnpMappings
);
1698 // saving data & stuff
1703 thePrefs::Add2TotalDownloaded(theStats::GetSessionReceivedBytes());
1704 thePrefs::Add2TotalUploaded(theStats::GetSessionSentBytes());
1711 clientlist
->DeleteAll();
1714 CThreadScheduler::Terminate();
1716 theApp
->uploadBandwidthThrottler
->EndThread();
1719 AddDebugLogLineM(false, logGeneral
, wxT("CamuleApp::ShutDown() has ended."));
1723 bool CamuleApp::AddServer(CServer
*srv
, bool fromUser
)
1725 if ( serverlist
->AddServer(srv
, fromUser
) ) {
1726 Notify_ServerAdd(srv
);
1733 uint32
CamuleApp::GetPublicIP(bool ignorelocal
) const
1735 if (m_dwPublicIP
== 0) {
1736 if (Kademlia::CKademlia::IsConnected() && Kademlia::CKademlia::GetIPAddress() ) {
1737 return wxUINT32_SWAP_ALWAYS(Kademlia::CKademlia::GetIPAddress());
1739 return ignorelocal
? 0 : m_localip
;
1743 return m_dwPublicIP
;
1747 void CamuleApp::SetPublicIP(const uint32 dwIP
)
1749 wxASSERT((dwIP
== 0) || !IsLowID(dwIP
));
1751 if (dwIP
!= 0 && dwIP
!= m_dwPublicIP
&& serverlist
!= NULL
) {
1752 m_dwPublicIP
= dwIP
;
1753 serverlist
->CheckForExpiredUDPKeys();
1755 m_dwPublicIP
= dwIP
;
1760 wxString
CamuleApp::GetLog(bool reset
)
1762 ConfigDir
= GetConfigDir();
1764 logfile
.Open(ConfigDir
+ wxT("logfile"));
1765 if ( !logfile
.IsOpened() ) {
1766 return _("ERROR: can't open logfile");
1768 int len
= logfile
.Length();
1770 return _("WARNING: logfile is empty. Something is wrong.");
1772 char *tmp_buffer
= new char[len
+ sizeof(wxChar
)];
1773 logfile
.Read(tmp_buffer
, len
);
1774 memset(tmp_buffer
+ len
, 0, sizeof(wxChar
));
1776 // try to guess file format
1778 if (tmp_buffer
[0] && tmp_buffer
[1]) {
1779 str
= wxString(UTF82unicode(tmp_buffer
));
1781 str
= wxString((wxWCharBuffer
&)tmp_buffer
);
1784 delete [] tmp_buffer
;
1786 theLogger
.CloseLogfile();
1787 if (theLogger
.OpenLogfile(ConfigDir
+ wxT("logfile"))) {
1788 AddLogLineM(false, _("Log has been reset"));
1795 wxString
CamuleApp::GetServerLog(bool reset
)
1797 wxString ret
= server_msg
;
1804 wxString
CamuleApp::GetDebugLog(bool reset
)
1806 return GetLog(reset
);
1810 void CamuleApp::AddServerMessageLine(wxString
&msg
)
1812 server_msg
+= msg
+ wxT("\n");
1813 AddLogLineM(false, CFormat(_("ServerMessage: %s")) % msg
);
1818 void CamuleApp::OnFinishedHTTPDownload(CMuleInternalEvent
& event
)
1820 switch (event
.GetInt()) {
1822 ipfilter
->DownloadFinished(event
.GetExtraLong());
1824 case HTTP_ServerMet
:
1825 serverlist
->DownloadFinished(event
.GetExtraLong());
1827 case HTTP_ServerMetAuto
:
1828 serverlist
->AutoDownloadFinished(event
.GetExtraLong());
1830 case HTTP_VersionCheck
:
1831 CheckNewVersion(event
.GetExtraLong());
1834 if (event
.GetExtraLong() != -1) {
1836 wxString file
= ConfigDir
+ wxT("nodes.dat");
1837 if (wxFileExists(file
)) {
1841 if ( Kademlia::CKademlia::IsRunning() ) {
1842 Kademlia::CKademlia::Stop();
1845 wxRenameFile(file
+ wxT(".download"),file
);
1847 Kademlia::CKademlia::Start();
1848 theApp
->ShowConnectionState();
1851 AddLogLineM(true, _("Failed to download the nodes list."));
1854 #ifdef ENABLE_IP2COUNTRY
1856 theApp
->amuledlg
->IP2CountryDownloadFinished(event
.GetExtraLong());
1857 // If we updated, the dialog is already up. Redraw it to show the flags.
1858 theApp
->amuledlg
->Refresh();
1864 void CamuleApp::CheckNewVersion(uint32 result
)
1867 wxString filename
= ConfigDir
+ wxT("last_version_check");
1870 if (!file
.Open(filename
)) {
1871 AddLogLineM(true, _("Failed to open the downloaded version check file") );
1873 } else if (!file
.GetLineCount()) {
1874 AddLogLineM(true, _("Corrupted version check file"));
1876 wxString versionLine
= file
.GetFirstLine();
1877 wxStringTokenizer
tkz(versionLine
, wxT("."));
1879 AddDebugLogLineM(false, logGeneral
, wxString(wxT("Running: ")) + wxT(VERSION
) + wxT(", Version check: ") + versionLine
);
1881 long fields
[] = {0, 0, 0};
1882 for (int i
= 0; i
< 3; ++i
) {
1883 if (!tkz
.HasMoreTokens()) {
1884 AddLogLineM(true, _("Corrupted version check file"));
1887 wxString token
= tkz
.GetNextToken();
1889 if (!token
.ToLong(&fields
[i
])) {
1890 AddLogLineM(true, _("Corrupted version check file"));
1896 long curVer
= make_full_ed2k_version(VERSION_MJR
, VERSION_MIN
, VERSION_UPDATE
);
1897 long newVer
= make_full_ed2k_version(fields
[0], fields
[1], fields
[2]);
1899 if (curVer
< newVer
) {
1900 AddLogLineM(true, _("You are using an outdated version of aMule!"));
1901 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]));
1902 AddLogLineM(false, _("The latest version can always be found at http://www.amule.org"));
1904 AddLogLineMS(true, CFormat(_("WARNING: Your aMuled version is outdated: %i.%i.%i < %li.%li.%li"))
1905 % VERSION_MJR
% VERSION_MIN
% VERSION_UPDATE
% fields
[0] % fields
[1] % fields
[2]);
1908 AddLogLineM(false, _("Your copy of aMule is up to date."));
1913 wxRemoveFile(filename
);
1915 AddLogLineM(true, _("Failed to download the version check file") );
1921 bool CamuleApp::IsConnected() const
1923 return (IsConnectedED2K() || IsConnectedKad());
1927 bool CamuleApp::IsConnectedED2K() const
1929 return serverconnect
&& serverconnect
->IsConnected();
1933 bool CamuleApp::IsConnectedKad() const
1935 return Kademlia::CKademlia::IsConnected();
1939 bool CamuleApp::IsFirewalled() const
1941 if (theApp
->IsConnectedED2K() && !theApp
->serverconnect
->IsLowID()) {
1942 return false; // we have an eD2K HighID -> not firewalled
1945 return IsFirewalledKad(); // If kad says ok, it's ok.
1948 bool CamuleApp::IsFirewalledKad() const
1950 return !Kademlia::CKademlia::IsConnected() // not connected counts as firewalled
1951 || Kademlia::CKademlia::IsFirewalled();
1954 bool CamuleApp::IsFirewalledKadUDP() const
1956 return !Kademlia::CKademlia::IsConnected() // not connected counts as firewalled
1957 || Kademlia::CUDPFirewallTester::IsFirewalledUDP(true);
1960 bool CamuleApp::IsKadRunning() const
1962 return Kademlia::CKademlia::IsRunning();
1966 uint32
CamuleApp::GetKadUsers() const
1968 return Kademlia::CKademlia::GetKademliaUsers();
1971 uint32
CamuleApp::GetKadFiles() const
1973 return Kademlia::CKademlia::GetKademliaFiles();
1976 uint32
CamuleApp::GetKadIndexedSources() const
1978 return Kademlia::CKademlia::GetIndexed()->m_totalIndexSource
;
1981 uint32
CamuleApp::GetKadIndexedKeywords() const
1983 return Kademlia::CKademlia::GetIndexed()->m_totalIndexKeyword
;
1986 uint32
CamuleApp::GetKadIndexedNotes() const
1988 return Kademlia::CKademlia::GetIndexed()->m_totalIndexNotes
;
1991 uint32
CamuleApp::GetKadIndexedLoad() const
1993 return Kademlia::CKademlia::GetIndexed()->m_totalIndexLoad
;
1997 // True IP of machine
1998 uint32
CamuleApp::GetKadIPAdress() const
2000 return wxUINT32_SWAP_ALWAYS(Kademlia::CKademlia::GetPrefs()->GetIPAddress());
2004 uint8
CamuleApp::GetBuddyStatus() const
2006 return clientlist
->GetBuddyStatus();
2009 uint32
CamuleApp::GetBuddyIP() const
2011 return clientlist
->GetBuddy()->GetIP();
2014 uint32
CamuleApp::GetBuddyPort() const
2016 return clientlist
->GetBuddy()->GetUDPPort();
2019 bool CamuleApp::DoCallback( CUpDownClient
*client
)
2021 if(Kademlia::CKademlia::IsConnected()) {
2022 if(IsConnectedED2K()) {
2023 if(serverconnect
->IsLowID()) {
2024 if(Kademlia::CKademlia::IsFirewalled()) {
2025 //Both Connected - Both Firewalled
2028 if(client
->GetServerIP() == theApp
->serverconnect
->GetCurrentServer()->GetIP() &&
2029 client
->GetServerPort() == theApp
->serverconnect
->GetCurrentServer()->GetPort()) {
2030 // Both Connected - Server lowID, Kad Open - Client on same server
2031 // We prevent a callback to the server as this breaks the protocol
2032 // and will get you banned.
2035 // Both Connected - Server lowID, Kad Open - Client on remote server
2040 //Both Connected - Server HighID, Kad don't care
2044 if(Kademlia::CKademlia::IsFirewalled()) {
2045 //Only Kad Connected - Kad Firewalled
2048 //Only Kad Conected - Kad Open
2053 if( IsConnectedED2K() ) {
2054 if( serverconnect
->IsLowID() ) {
2055 //Only Server Connected - Server LowID
2058 //Only Server Connected - Server HighID
2062 //We are not connected at all!
2068 void CamuleApp::ShowUserCount() {
2069 uint32 totaluser
= 0, totalfile
= 0;
2071 theApp
->serverlist
->GetUserFileStatus( totaluser
, totalfile
);
2075 static const wxString s_singlenetstatusformat
= _("Users: %s | Files: %s");
2076 static const wxString s_bothnetstatusformat
= _("Users: E: %s K: %s | Files: E: %s K: %s");
2078 if (thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()) {
2079 buffer
= CFormat(s_bothnetstatusformat
) % CastItoIShort(totaluser
) % CastItoIShort(Kademlia::CKademlia::GetKademliaUsers()) % CastItoIShort(totalfile
) % CastItoIShort(Kademlia::CKademlia::GetKademliaFiles());
2080 } else if (thePrefs::GetNetworkED2K()) {
2081 buffer
= CFormat(s_singlenetstatusformat
) % CastItoIShort(totaluser
) % CastItoIShort(totalfile
);
2082 } else if (thePrefs::GetNetworkKademlia()) {
2083 buffer
= CFormat(s_singlenetstatusformat
) % CastItoIShort(Kademlia::CKademlia::GetKademliaUsers()) % CastItoIShort(Kademlia::CKademlia::GetKademliaFiles());
2085 buffer
= _("No networks selected");
2088 Notify_ShowUserCount(buffer
);
2092 void CamuleApp::ListenSocketHandler(wxSocketEvent
& event
)
2094 wxCHECK_RET(listensocket
, wxT("Connection-event for NULL'd listen-socket"));
2095 wxCHECK_RET(event
.GetSocketEvent() == wxSOCKET_CONNECTION
,
2096 wxT("Invalid event received for listen-socket"));
2098 if (m_app_state
== APP_STATE_RUNNING
) {
2099 listensocket
->OnAccept(0);
2100 } else if (m_app_state
== APP_STATE_STARTING
) {
2101 // When starting up, connection may be made before we are able
2102 // to handle them. However, if these are ignored, no futher
2103 // connection-events will be triggered, so we have to accept it.
2104 wxSocketBase
* socket
= listensocket
->Accept(false);
2106 wxCHECK_RET(socket
, wxT("NULL returned by Accept() during startup"));
2113 void CamuleApp::ShowConnectionState()
2115 static uint8 old_state
= (1<<7); // This flag doesn't exist
2119 if (theApp
->serverconnect
->IsConnected()) {
2120 state
|= CONNECTED_ED2K
;
2123 if (Kademlia::CKademlia::IsRunning()) {
2124 if (Kademlia::CKademlia::IsConnected()) {
2125 if (!Kademlia::CKademlia::IsFirewalled()) {
2126 state
|= CONNECTED_KAD_OK
;
2128 state
|= CONNECTED_KAD_FIREWALLED
;
2131 state
|= CONNECTED_KAD_NOT
;
2135 Notify_ShowConnState(state
);
2137 if (old_state
!= state
) {
2138 // Get the changed value
2139 int changed_flags
= old_state
^ state
;
2141 if (changed_flags
& CONNECTED_ED2K
) {
2142 // ED2K status changed
2143 wxString connected_server
;
2144 CServer
* ed2k_server
= theApp
->serverconnect
->GetCurrentServer();
2146 connected_server
= ed2k_server
->GetListName();
2148 if (state
& CONNECTED_ED2K
) {
2149 // We connected to some server
2150 const wxString id
= theApp
->serverconnect
->IsLowID() ? _("with LowID") : _("with HighID");
2152 AddLogLineM(true, CFormat(_("Connected to %s %s")) % connected_server
% id
);
2154 if ( theApp
->serverconnect
->IsConnecting() ) {
2155 AddLogLineM(true, CFormat(_("Connecting to %s")) % connected_server
);
2157 AddLogLineM(true, _("Disconnected from eD2k"));
2162 if (changed_flags
& CONNECTED_KAD_NOT
) {
2163 if (state
& CONNECTED_KAD_NOT
) {
2164 AddLogLineM(true, _("Kad started."));
2166 AddLogLineM(true, _("Kad stopped."));
2170 if (changed_flags
& (CONNECTED_KAD_OK
| CONNECTED_KAD_FIREWALLED
)) {
2171 if (state
& (CONNECTED_KAD_OK
| CONNECTED_KAD_FIREWALLED
)) {
2172 if (state
& CONNECTED_KAD_OK
) {
2173 AddLogLineM(true, _("Connected to Kad (ok)"));
2175 AddLogLineM(true, _("Connected to Kad (firewalled)"));
2178 AddLogLineM(true, _("Disconnected from Kad"));
2184 theApp
->downloadqueue
->OnConnectionState(IsConnected());
2188 Notify_ShowConnState(state
);
2192 void CamuleApp::UDPSocketHandler(wxSocketEvent
& event
)
2194 CMuleUDPSocket
* socket
= (CMuleUDPSocket
*)(event
.GetClientData());
2195 wxCHECK_RET(socket
, wxT("No socket owner specified."));
2197 if (IsOnShutDown() || thePrefs::IsUDPDisabled()) return;
2200 if (event
.GetSocketEvent() == wxSOCKET_INPUT
) {
2201 // Back to the queue!
2202 theApp
->AddPendingEvent(event
);
2207 switch (event
.GetSocketEvent()) {
2208 case wxSOCKET_INPUT
:
2209 socket
->OnReceive(0);
2212 case wxSOCKET_OUTPUT
:
2217 socket
->OnDisconnected(0);
2227 void CamuleApp::OnUnhandledException()
2229 // Call the generic exception-handler.
2230 fprintf(stderr
, "\taMule Version: %s\n", (const char*)unicode2char(GetFullMuleVersion()));
2231 ::OnUnhandledException();
2234 void CamuleApp::StartKad()
2236 if (!Kademlia::CKademlia::IsRunning() && thePrefs::GetNetworkKademlia()) {
2237 // Kad makes no sense without the Client-UDP socket.
2238 if (!thePrefs::IsUDPDisabled()) {
2239 Kademlia::CKademlia::Start();
2241 AddLogLineM(true,_("Kad network cannot be used if UDP port is disabled on preferences, not starting."));
2243 } else if (!thePrefs::GetNetworkKademlia()) {
2244 AddLogLineM(true,_("Kad network disabled on preferences, not connecting."));
2248 void CamuleApp::StopKad()
2250 // Stop Kad if it's running
2251 if (Kademlia::CKademlia::IsRunning()) {
2252 Kademlia::CKademlia::Stop();
2257 void CamuleApp::BootstrapKad(uint32 ip
, uint16 port
)
2259 if (!Kademlia::CKademlia::IsRunning()) {
2260 Kademlia::CKademlia::Start();
2261 theApp
->ShowConnectionState();
2264 Kademlia::CKademlia::Bootstrap(ip
, port
, true);
2268 void CamuleApp::UpdateNotesDat(const wxString
& url
)
2270 wxString
strTempFilename(theApp
->ConfigDir
+ wxT("nodes.dat.download"));
2272 CHTTPDownloadThread
*downloader
= new CHTTPDownloadThread(url
, strTempFilename
, HTTP_NodesDat
);
2273 downloader
->Create();
2278 void CamuleApp::DisconnectED2K()
2280 // Stop ED2K if it's running
2281 if (IsConnectedED2K()) {
2282 serverconnect
->Disconnect();
2286 bool CamuleApp::CryptoAvailable() const
2288 return clientcredits
&& clientcredits
->CryptoAvailable();
2291 uint32
CamuleApp::GetED2KID() const {
2292 return serverconnect
? serverconnect
->GetClientID() : 0;
2295 uint32
CamuleApp::GetID() const {
2298 if( Kademlia::CKademlia::IsConnected() && !Kademlia::CKademlia::IsFirewalled() ) {
2299 // We trust Kad above ED2K
2300 ID
= ENDIAN_NTOHL(Kademlia::CKademlia::GetIPAddress());
2301 } else if( theApp
->serverconnect
->IsConnected() ) {
2302 ID
= theApp
->serverconnect
->GetClientID();
2303 } else if ( Kademlia::CKademlia::IsConnected() && Kademlia::CKademlia::IsFirewalled() ) {
2304 // A firewalled Kad client get's a "1"
2313 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
)
2314 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SOURCE_DNS_DONE
)
2315 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE
)
2316 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE
)
2317 // File_checked_for_headers