Bug Summary

File:rootdir/src/amuleAppCommon.cpp
Warning:line 71, column 14
This statement is never executed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name amuleAppCommon.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/src -fcoverage-compilation-dir=/rootdir/src -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I .. -D USE_WX_EXTENSIONS -I /usr/lib/x86_64-linux-gnu/wx/include/gtk3-unicode-3.2 -I /usr/include/wx-3.2 -D _FILE_OFFSET_BITS=64 -D WXUSINGDLL -D __WXGTK__ -D wxUSE_GUI=0 -I /usr/include/upnp -D ENABLE_UPNP=1 -I ./libs -I libs -I ./include -D AMULE_DAEMON -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-register -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2025-01-05-184004-17430-1 -x c++ amuleAppCommon.cpp
1//
2// This file is part of the aMule Project.
3//
4// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5//
6// Any parts of this program derived from the xMule, lMule or eMule project,
7// or contributed by third-party developers are copyrighted by their
8// respective authors.
9//
10// This program is free software; you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation; either version 2 of the License, or
13// (at your option) any later version.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with this program; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23//
24
25//
26// This file is for functions common to all three apps (amule, amuled, amulegui),
27// but preprocessor-dependent (using theApp, thePrefs), so it is compiled separately for each app.
28//
29
30
31#include <wx/wx.h>
32#include <wx/cmdline.h> // Needed for wxCmdLineParser
33#include <wx/snglinst.h> // Needed for wxSingleInstanceChecker
34#include <wx/textfile.h> // Needed for wxTextFile
35#include <wx/config.h> // Do_not_auto_remove (win32)
36#include <wx/fileconf.h>
37
38#include "amule.h" // Interface declarations.
39#include <common/Format.h> // Needed for CFormat
40#include "CFile.h" // Needed for CFile
41#include "ED2KLink.h" // Needed for command line passing of links
42#include "FileLock.h" // Needed for CFileLock
43#include "GuiEvents.h" // Needed for Notify_*
44#include "KnownFile.h"
45#include "Logger.h"
46#include "MagnetURI.h" // Needed for CMagnetURI
47#include "Preferences.h"
48#include "ScopedPtr.h"
49#include "MuleVersion.h" // Needed for GetMuleVersion()
50
51#ifndef CLIENT_GUI
52#include "DownloadQueue.h"
53#endif
54
55CamuleAppCommon::CamuleAppCommon()
56{
57 m_singleInstance = NULL__null;
58 ec_config = false;
59 m_geometryEnabled = false;
60 if (IsRemoteGui()) {
61 m_appName = wxT("aMuleGUI")L"aMuleGUI";
62 m_configFile = wxT("remote.conf")L"remote.conf";
63 m_logFile = wxT("remotelogfile")L"remotelogfile";
64 } else {
65 m_configFile = wxT("amule.conf")L"amule.conf";
66 m_logFile = wxT("logfile")L"logfile";
67
68 if (IsDaemon()) {
69 m_appName = wxT("aMuleD")L"aMuleD";
70 } else {
71 m_appName = wxT("aMule")L"aMule";
This statement is never executed
72 }
73 }
74}
75
76CamuleAppCommon::~CamuleAppCommon()
77{
78#if defined(__WXMAC__) && defined(AMULE_DAEMON1)
79 //#warning TODO: fix wxSingleInstanceChecker for amuled on Mac (wx link problems)
80#else
81 delete m_singleInstance;
82#endif
83}
84
85void CamuleAppCommon::RefreshSingleInstanceChecker()
86{
87#if defined(__WXMAC__) && defined(AMULE_DAEMON1)
88 //#warning TODO: fix wxSingleInstanceChecker for amuled on Mac (wx link problems)
89#else
90 delete m_singleInstance;
91 m_singleInstance = new wxSingleInstanceChecker(wxT("muleLock")L"muleLock", thePrefs::GetConfigDir());
92#endif
93}
94
95void CamuleAppCommon::AddLinksFromFile()
96{
97 const wxString fullPath = thePrefs::GetConfigDir() + wxT("ED2KLinks")L"ED2KLinks";
98 if (!wxFile::Exists(fullPath)) {
99 return;
100 }
101
102 // Attempt to lock the ED2KLinks file.
103 CFileLock lock((const char*)unicode2char(fullPath));
104
105 wxTextFile file(fullPath);
106 if ( file.Open() ) {
107 for ( unsigned int i = 0; i < file.GetLineCount(); i++ ) {
108 wxString line = file.GetLine( i ).Strip( wxString::both );
109
110 if ( !line.IsEmpty() ) {
111 // Special case! used by a secondary running mule to raise this one.
112 if (line == wxT("RAISE_DIALOG")L"RAISE_DIALOG") {
113 Notify_ShowGUI()MuleNotify::DoNotify(&MuleNotify::ShowGUI);
114 continue;
115 }
116 unsigned long category = 0;
117 if (line.AfterLast(wxT(':')L':').ToULong(&category) == true) {
118 line = line.BeforeLast(wxT(':')L':');
119 } else { // If ToULong returns false the category still can have been changed!
120 // This is fixed in wx 2.9
121 category = 0;
122 }
123 theApp->downloadqueue->AddLink(line, category);
124 }
125 }
126
127 file.Close();
128 } else {
129 AddLogLineNS(_("Failed to open ED2KLinks file."))theLogger.AddLogLine(L"amuleAppCommon.cpp", 129, false, logStandard
, wxGetTranslation(("Failed to open ED2KLinks file.")), true)
;
130 }
131
132 // Delete the file.
133 wxRemoveFile(thePrefs::GetConfigDir() + wxT("ED2KLinks")L"ED2KLinks");
134}
135
136
137// Returns a magnet ed2k URI
138wxString CamuleAppCommon::CreateMagnetLink(const CAbstractFile *f)
139{
140 CMagnetURI uri;
141
142 uri.AddField(wxT("dn")L"dn", f->GetFileName().Cleanup(false).GetPrintable());
143 uri.AddField(wxT("xt")L"xt", wxString(wxT("urn:ed2k:")L"urn:ed2k:") + f->GetFileHash().Encode().Lower());
144 uri.AddField(wxT("xt")L"xt", wxString(wxT("urn:ed2khash:")L"urn:ed2khash:") + f->GetFileHash().Encode().Lower());
145 uri.AddField(wxT("xl")L"xl", CFormat(wxT("%d")L"%d") % f->GetFileSize());
146
147 return uri.GetLink();
148}
149
150
151// Returns a ed2k file URL
152wxString CamuleAppCommon::CreateED2kLink(const CAbstractFile *f, bool add_source, bool use_hostname, bool add_cryptoptions, bool add_AICH)
153{
154 wxASSERT(!(!add_source && (use_hostname || add_cryptoptions)))do { if ( !(!add_source && (use_hostname || add_cryptoptions
)) ) { } else if ( wxTheAssertHandler && (wxOnAssert(
"amuleAppCommon.cpp", 154, __FUNCTION__, "!(!add_source && (use_hostname || add_cryptoptions))"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
155 // Construct URL like this: ed2k://|file|<filename>|<size>|<hash>|/
156 wxString strURL = CFormat(wxT("ed2k://|file|%s|%i|%s|")L"ed2k://|file|%s|%i|%s|")
157 % f->GetFileName().Cleanup(false)
158 % f->GetFileSize() % f->GetFileHash().Encode();
159
160 // Append the AICH info
161 if (add_AICH) {
162 const CKnownFile* kf = dynamic_cast<const CKnownFile*>(f);
163 if (kf && kf->HasProperAICHHashSet()) {
164 strURL << wxT("h=")L"h=" << kf->GetAICHMasterHash() << wxT("|")L"|";
165 }
166 }
167
168 strURL << wxT("/")L"/";
169
170 if (add_source && theApp->IsConnected() && !theApp->IsFirewalled()) {
171 // Create the first part of the URL
172 strURL << wxT("|sources,")L"|sources,";
173 if (use_hostname) {
174 strURL << thePrefs::GetYourHostname();
175 } else {
176 uint32 clientID = theApp->GetID();
177 strURL = CFormat(wxT("%s%u.%u.%u.%u")L"%s%u.%u.%u.%u")
178 % strURL
179 % (clientID & 0xff)
180 % ((clientID >> 8) & 0xff)
181 % ((clientID >> 16) & 0xff)
182 % ((clientID >> 24) & 0xff);
183 }
184
185 strURL << wxT(":")L":" <<
186 thePrefs::GetPort();
187
188 if (add_cryptoptions) {
189 uint8 uSupportsCryptLayer = thePrefs::IsClientCryptLayerSupported() ? 1 : 0;
190 uint8 uRequestsCryptLayer = thePrefs::IsClientCryptLayerRequested() ? 1 : 0;
191 uint8 uRequiresCryptLayer = thePrefs::IsClientCryptLayerRequired() ? 1 : 0;
192 uint16 byCryptOptions = (uRequiresCryptLayer << 2) | (uRequestsCryptLayer << 1) | (uSupportsCryptLayer << 0) | (uSupportsCryptLayer ? 0x80 : 0x00);
193
194 strURL << wxT(":")L":" << byCryptOptions;
195
196 if (byCryptOptions & 0x80) {
197 strURL << wxT(":")L":" << thePrefs::GetUserHash().Encode();
198 }
199 }
200 strURL << wxT("|/")L"|/";
201 } else if (add_source) {
202 AddLogLineC(_("WARNING: You can't add yourself as a source for an eD2k link while having a lowid."))theLogger.AddLogLine(L"amuleAppCommon.cpp", 202, true, logStandard
, wxGetTranslation(("WARNING: You can't add yourself as a source for an eD2k link while having a lowid."
)))
;
203 }
204
205 // Result is "ed2k://|file|<filename>|<size>|<hash>|[h=<AICH master hash>|]/|sources,[(<ip>|<hostname>):<port>[:cryptoptions[:hash]]]|/"
206 return strURL;
207}
208
209
210bool CamuleAppCommon::InitCommon(int argc, wxChar ** argv)
211{
212 theApp->SetAppName(wxT("aMule")L"aMule");
213 FullMuleVersion = GetFullMuleVersion();
214 OSDescription = wxGetOsDescription();
215 OSType = OSDescription.BeforeFirst( wxT(' ')L' ' );
216 if ( OSType.IsEmpty() ) {
217 OSType = wxT("Unknown")L"Unknown";
218 }
219
220 // Parse cmdline arguments.
221 wxCmdLineParser cmdline(argc, argv);
222
223 // Handle these arguments.
224 cmdline.AddSwitch(wxT("v")L"v", wxT("version")L"version", wxT("Displays the current version number.")L"Displays the current version number.");
225 cmdline.AddSwitch(wxT("h")L"h", wxT("help")L"help", wxT("Displays this information.")L"Displays this information.");
226 cmdline.AddOption(wxT("c")L"c", wxT("config-dir")L"config-dir", wxT("read config from <dir> instead of home")L"read config from <dir> instead of home");
227#ifdef AMULE_DAEMON1
228 cmdline.AddSwitch(wxT("f")L"f", wxT("full-daemon")L"full-daemon", wxT("Fork to background.")L"Fork to background.");
229 cmdline.AddOption(wxT("p")L"p", wxT("pid-file")L"pid-file", wxT("After fork, create a pid-file in the given fullname file.")L"After fork, create a pid-file in the given fullname file.");
230 cmdline.AddSwitch(wxT("e")L"e", wxT("ec-config")L"ec-config", wxT("Configure EC (External Connections).")L"Configure EC (External Connections).");
231#else
232
233#ifdef __WINDOWS__
234 // MSW shows help options in a dialog box, and the formatting doesn't fit there
235#define HELPTAB wxT("\t")L"\t"
236#else
237#define HELPTAB wxT("\t\t\t")L"\t\t\t"
238#endif
239
240 cmdline.AddOption(wxT("geometry")L"geometry", wxEmptyString,
241 wxT("Sets the geometry of the app.\n")L"Sets the geometry of the app.\n"
242 HELPTAB wxT("<str> uses the same format as standard X11 apps:\n")L"<str> uses the same format as standard X11 apps:\n"
243 HELPTAB wxT("[=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]")L"[=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]");
244#endif // !AMULE_DAEMON
245
246 cmdline.AddSwitch(wxT("o")L"o", wxT("log-stdout")L"log-stdout", wxT("Print log messages to stdout.")L"Print log messages to stdout.");
247 cmdline.AddSwitch(wxT("r")L"r", wxT("reset-config")L"reset-config", wxT("Resets config to default values.")L"Resets config to default values.");
248
249#ifdef CLIENT_GUI
250 cmdline.AddSwitch(wxT("s")L"s", wxT("skip")L"skip", wxT("Skip connection dialog.")L"Skip connection dialog.");
251#else
252 // Change webserver path. This is also a config option, so this switch will go at some time.
253 cmdline.AddOption(wxT("w")L"w", wxT("use-amuleweb")L"use-amuleweb", wxT("Specify location of amuleweb binary.")L"Specify location of amuleweb binary.");
254#endif
255#ifndef __WINDOWS__
256 cmdline.AddSwitch(wxT("d")L"d", wxT("disable-fatal")L"disable-fatal", wxT("Do not handle fatal exception.")L"Do not handle fatal exception.");
257// Keep stdin open to run valgrind --gen_suppressions
258 cmdline.AddSwitch(wxT("i")L"i", wxT("enable-stdin")L"enable-stdin", wxT("Do not disable stdin.")L"Do not disable stdin.");
259#endif
260
261 // Allow passing of links to the app
262 cmdline.AddOption(wxT("t")L"t", wxT("category")L"category", wxT("Set category for passed ED2K links.")L"Set category for passed ED2K links.", wxCMD_LINE_VAL_NUMBER);
263 cmdline.AddParam(wxT("ED2K link")L"ED2K link", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
264
265 // wx asserts in debug mode if there is a check for an option that wasn't added.
266 // So we have to wrap around the same #ifdefs as above. >:(
267
268 // Show help on --help or invalid commands
269 if ( cmdline.Parse() ) {
270 return false;
271 } else if (cmdline.Found(wxT("help")L"help")) {
272 cmdline.Usage();
273 return false;
274 }
275
276 if ( cmdline.Found(wxT("version")L"version")) {
277 // This looks silly with logging macros that add a timestamp.
278 printf("%s\n", (const char*)unicode2char(wxString(CFormat(wxT("%s (OS: %s)")L"%s (OS: %s)") % FullMuleVersion % OSType)));
279 return false;
280 }
281
282 wxString configdir;
283 if (cmdline.Found(wxT("config-dir")L"config-dir", &configdir)) {
284 // Make an absolute path from the config dir
285 wxFileName fn(configdir);
286 fn.MakeAbsolute();
287 configdir = fn.GetFullPath();
288 if (configdir.Last() != wxFileName::GetPathSeparator()) {
289 configdir += wxFileName::GetPathSeparator();
290 }
291 thePrefs::SetConfigDir(configdir);
292 } else {
293 thePrefs::SetConfigDir(/*OtherFunctions::*/GetConfigDir(m_configFile));
294 }
295
296 // Backtracing works in MSW.
297 // Problem is just that the backtraces are useless, because apparently the context gets lost
298 // in the try/catch somewhere.
299 // So leave it out.
300#ifndef __WINDOWS__
301 #if wxUSE_ON_FATAL_EXCEPTION1
302 if ( !cmdline.Found(wxT("disable-fatal")L"disable-fatal") ) {
303 // catch fatal exceptions
304 wxHandleFatalExceptions(true);
305 }
306 #endif
307#endif
308
309 theLogger.SetEnabledStdoutLog(cmdline.Found(wxT("log-stdout")L"log-stdout"));
310#ifdef AMULE_DAEMON1
311 enable_daemon_fork = cmdline.Found(wxT("full-daemon")L"full-daemon");
312 if ( cmdline.Found(wxT("pid-file")L"pid-file", &m_PidFile) ) {
313 // Remove any existing PidFile
314 if ( wxFileExists (m_PidFile) ) wxRemoveFile (m_PidFile);
315 }
316 ec_config = cmdline.Found(wxT("ec-config")L"ec-config");
317#else
318 enable_daemon_fork = false;
319
320 // Default geometry of the GUI. Can be changed with a cmdline argument...
321 if ( cmdline.Found(wxT("geometry")L"geometry", &m_geometryString) ) {
322 m_geometryEnabled = true;
323 }
324#endif
325
326 if (theLogger.IsEnabledStdoutLog()) {
327 if ( enable_daemon_fork ) {
328 AddLogLineNS(wxT("Daemon will fork to background - log to stdout disabled"))theLogger.AddLogLine(L"amuleAppCommon.cpp", 328, false, logStandard
, L"Daemon will fork to background - log to stdout disabled",
true)
; // localization not active yet
329 theLogger.SetEnabledStdoutLog(false);
330 } else {
331 AddLogLineNS(wxT("Logging to stdout enabled"))theLogger.AddLogLine(L"amuleAppCommon.cpp", 331, false, logStandard
, L"Logging to stdout enabled", true)
;
332 }
333 }
334
335 AddLogLineNS(wxT("Initialising ") + FullMuleVersion)theLogger.AddLogLine(L"amuleAppCommon.cpp", 335, false, logStandard
, L"Initialising " + FullMuleVersion, true)
;
336
337 // Ensure that "~/.aMule/" is accessible.
338 CPath outDir;
339 if (!CheckMuleDirectory(wxT("configuration")L"configuration", CPath(thePrefs::GetConfigDir()), wxEmptyString, outDir)) {
340 return false;
341 }
342
343 if (cmdline.Found(wxT("reset-config")L"reset-config")) {
344 // Make a backup first.
345 wxRemoveFile(thePrefs::GetConfigDir() + m_configFile + wxT(".backup")L".backup");
346 wxRenameFile(thePrefs::GetConfigDir() + m_configFile, thePrefs::GetConfigDir() + m_configFile + wxT(".backup")L".backup");
347 AddLogLineNS(CFormat(wxT("Your settings have been reset to default values.\nThe old config file has been saved as %s.backup\n")) % m_configFile)theLogger.AddLogLine(L"amuleAppCommon.cpp", 347, false, logStandard
, CFormat(L"Your settings have been reset to default values.\nThe old config file has been saved as %s.backup\n"
) % m_configFile, true)
;
348 }
349
350 size_t linksPassed = cmdline.GetParamCount(); // number of links from the command line
351 // cppcheck-suppress variableScope
352 int linksActuallyPassed = 0; // number of links that pass the syntax check
353 if (linksPassed) {
354 long cat = 0;
355 if (!cmdline.Found(wxT("t")L"t", &cat)) {
356 cat = 0;
357 }
358
359 wxTextFile ed2kFile(thePrefs::GetConfigDir() + wxT("ED2KLinks")L"ED2KLinks");
360 if (!ed2kFile.Exists()) {
361 ed2kFile.Create();
362 }
363 if (ed2kFile.Open()) {
364 for (size_t i = 0; i < linksPassed; i++) {
365 wxString link;
366 if (CheckPassedLink(cmdline.GetParam(i), link, cat)) {
367 ed2kFile.AddLine(link);
368 linksActuallyPassed++;
369 }
370 }
371 ed2kFile.Write();
372 } else {
373 AddLogLineCS(wxT("Failed to open 'ED2KLinks', cannot add links."))theLogger.AddLogLine(L"amuleAppCommon.cpp", 373, true, logStandard
, L"Failed to open 'ED2KLinks', cannot add links.", true)
;
374 }
375 }
376
377#if defined(__WXMAC__) && defined(AMULE_DAEMON1)
378 //#warning TODO: fix wxSingleInstanceChecker for amuled on Mac (wx link problems)
379 AddLogLineCS(wxT("WARNING: The check for other instances is currently disabled in amuled.\n"theLogger.AddLogLine(L"amuleAppCommon.cpp", 380, true, logStandard
, L"WARNING: The check for other instances is currently disabled in amuled.\n"
"Please make sure that no other instance of aMule is running or your files might be corrupted.\n"
, true)
380 "Please make sure that no other instance of aMule is running or your files might be corrupted.\n"))theLogger.AddLogLine(L"amuleAppCommon.cpp", 380, true, logStandard
, L"WARNING: The check for other instances is currently disabled in amuled.\n"
"Please make sure that no other instance of aMule is running or your files might be corrupted.\n"
, true)
;
381#else
382 AddLogLineNS(wxT("Checking if there is an instance already running..."))theLogger.AddLogLine(L"amuleAppCommon.cpp", 382, false, logStandard
, L"Checking if there is an instance already running...", true
)
;
383
384 m_singleInstance = new wxSingleInstanceChecker();
385 wxString lockfile = IsRemoteGui() ? wxT("muleLockRGUI")L"muleLockRGUI" : wxT("muleLock")L"muleLock";
386 if (m_singleInstance->Create(lockfile, thePrefs::GetConfigDir())
387 && m_singleInstance->IsAnotherRunning()) {
388 AddLogLineCS(CFormat(wxT("There is an instance of %s already running")) % m_appName)theLogger.AddLogLine(L"amuleAppCommon.cpp", 388, true, logStandard
, CFormat(L"There is an instance of %s already running") % m_appName
, true)
;
389 AddLogLineNS(CFormat(wxT("(lock file: %s%s)")) % thePrefs::GetConfigDir() % lockfile)theLogger.AddLogLine(L"amuleAppCommon.cpp", 389, false, logStandard
, CFormat(L"(lock file: %s%s)") % thePrefs::GetConfigDir() % lockfile
, true)
;
390 if (linksPassed) {
391 AddLogLineNS(CFormat(wxT("passed %d %s to it, finished")) % linksActuallyPassedtheLogger.AddLogLine(L"amuleAppCommon.cpp", 392, false, logStandard
, CFormat(L"passed %d %s to it, finished") % linksActuallyPassed
% (linksPassed == 1 ? L"link" : L"links"), true)
392 % (linksPassed == 1 ? wxT("link") : wxT("links")))theLogger.AddLogLine(L"amuleAppCommon.cpp", 392, false, logStandard
, CFormat(L"passed %d %s to it, finished") % linksActuallyPassed
% (linksPassed == 1 ? L"link" : L"links"), true)
;
393 return false;
394 }
395
396 // This is very tricky. The most secure way to communicate is via ED2K links file
397 wxTextFile ed2kFile(thePrefs::GetConfigDir() + wxT("ED2KLinks")L"ED2KLinks");
398 if (!ed2kFile.Exists()) {
399 ed2kFile.Create();
400 }
401
402 if (ed2kFile.Open()) {
403 ed2kFile.AddLine(wxT("RAISE_DIALOG")L"RAISE_DIALOG");
404 ed2kFile.Write();
405
406 AddLogLineNS(wxT("Raising current running instance."))theLogger.AddLogLine(L"amuleAppCommon.cpp", 406, false, logStandard
, L"Raising current running instance.", true)
;
407 } else {
408 AddLogLineCS(wxT("Failed to open 'ED2KFile', cannot signal running instance."))theLogger.AddLogLine(L"amuleAppCommon.cpp", 408, true, logStandard
, L"Failed to open 'ED2KFile', cannot signal running instance."
, true)
;
409 }
410
411 return false;
412 } else {
413 AddLogLineNS(wxT("No other instances are running."))theLogger.AddLogLine(L"amuleAppCommon.cpp", 413, false, logStandard
, L"No other instances are running.", true)
;
414 }
415#endif
416
417#ifndef __WINDOWS__
418 // Close standard-input
419 if ( !cmdline.Found(wxT("enable-stdin")L"enable-stdin") ) {
420 // The full daemon will close all std file-descriptors by itself,
421 // so closing it here would lead to the closing on the first open
422 // file, which is the logfile opened below
423 if (!enable_daemon_fork) {
424 close(0);
425 }
426 }
427#endif
428
429 // Create the CFG file we shall use and set the config object as the global cfg file
430 wxConfigwxFileConfig::Set(new wxFileConfig( wxEmptyString, wxEmptyString, thePrefs::GetConfigDir() + m_configFile));
431
432 // Make a backup of the log file
433 CPath logfileName = CPath(thePrefs::GetConfigDir() + m_logFile);
434 if (logfileName.FileExists()) {
435 CPath::BackupFile(logfileName, wxT(".bak")L".bak");
436 }
437
438 // Open the log file
439 if (!theLogger.OpenLogfile(logfileName.GetRaw())) {
440 // use std err as last resolt to indicate problem
441 fputs("ERROR: unable to open log file\n", stderrstderr);
442 // failure to open log is serious problem
443 return false;
444 }
445
446 // Load Preferences
447 CPreferences::BuildItemList(thePrefs::GetConfigDir());
448 CPreferences::LoadAllItems( wxConfigBase::Get() );
449
450#ifdef CLIENT_GUI
451 m_skipConnectionDialog = cmdline.Found(wxT("skip")L"skip");
452#else
453 wxString amulewebPath;
454 if (cmdline.Found(wxT("use-amuleweb")L"use-amuleweb", &amulewebPath)) {
455 thePrefs::SetWSPath(amulewebPath);
456 AddLogLineNS(CFormat(wxT("Using amuleweb in '%s'.")) % amulewebPath)theLogger.AddLogLine(L"amuleAppCommon.cpp", 456, false, logStandard
, CFormat(L"Using amuleweb in '%s'.") % amulewebPath, true)
;
457 }
458#endif
459
460 return true;
461}
462
463/**
464 * Returns a description of the version of aMule being used.
465 *
466 * @return A detailed description of the aMule version, including application
467 * name and wx information.
468 */
469const wxString CamuleAppCommon::GetFullMuleVersion() const
470{
471 return GetMuleAppName() + wxT(" ")L" " + GetMuleVersion();
472}
473
474bool CamuleAppCommon::CheckPassedLink(const wxString &in, wxString &out, int cat)
475{
476 wxString link(in);
477
478 // restore ASCII-encoded pipes
479 link.Replace(wxT("%7C")L"%7C", wxT("|")L"|");
480 link.Replace(wxT("%7c")L"%7c", wxT("|")L"|");
481
482 if (link.compare(0, 7, wxT("magnet:")L"magnet:") == 0) {
483 link = CMagnetED2KConverter(link);
484 if (link.empty()) {
485 AddLogLineCS(CFormat(wxT("Cannot convert magnet link to eD2k: %s")) % in)theLogger.AddLogLine(L"amuleAppCommon.cpp", 485, true, logStandard
, CFormat(L"Cannot convert magnet link to eD2k: %s") % in, true
)
;
486 return false;
487 }
488 }
489
490 try {
491 CScopedPtr<CED2KLink> uri(CED2KLink::CreateLinkFromUrl(link));
492 out = uri.get()->GetLink();
493 if (cat && uri.get()->GetKind() == CED2KLink::kFile) {
494 out += CFormat(wxT(":%d")L":%d") % cat;
495 }
496 return true;
497 } catch ( const wxString& err ) {
498 AddLogLineCS(CFormat(wxT("Invalid eD2k link \"%s\" - ERROR: %s")) % link % err)theLogger.AddLogLine(L"amuleAppCommon.cpp", 498, true, logStandard
, CFormat(L"Invalid eD2k link \"%s\" - ERROR: %s") % link % err
, true)
;
499 }
500 return false;
501}
502
503
504/**
505 * Checks permissions on a aMule directory, creating if needed.
506 *
507 * @param desc A description of the directory in question, used for error messages.
508 * @param directory The directory in question.
509 * @param alternative If the dir specified with 'directory' could not be created, try this instead.
510 * @param outDir Returns the used path.
511 * @return False on error.
512 */
513bool CamuleAppCommon::CheckMuleDirectory(const wxString& desc, const CPath& directory, const wxString& alternative, CPath& outDir)
514{
515 wxString msg;
516
517 if (directory.IsDir(CPath::readwritable)) {
518 outDir = directory;
519 return true;
520 } else if (directory.DirExists()) {
521 // Strings are not translated here because translation isn't up yet.
522 msg = CFormat(wxT("Permissions on the %s directory too strict!\n")L"Permissions on the %s directory too strict!\n"
523 wxT("aMule cannot proceed. To fix this, you must set read/write/exec\n")L"aMule cannot proceed. To fix this, you must set read/write/exec\n"
524 wxT("permissions for the folder '%s'")L"permissions for the folder '%s'")
525 % desc % directory;
526 } else if (CPath::MakeDir(directory)) {
527 outDir = directory;
528 return true;
529 } else {
530 msg << CFormat(wxT("Could not create the %s directory at '%s'.")L"Could not create the %s directory at '%s'.")
531 % desc % directory;
532 }
533
534 // Attempt to use fallback directory.
535 const CPath fallback(alternative);
536 if (fallback.IsOk() && (directory != fallback)) {
537 msg << wxT("\nAttempting to use default directory at location \n'")L"\nAttempting to use default directory at location \n'"
538 << alternative << wxT("'.")L"'.";
539 if (theApp->ShowAlert(msg, wxT("Error accessing directory.")L"Error accessing directory.", wxICON_ERROR0x00000200 | wxOK0x00000004 | wxCANCEL0x00000010) == wxCANCEL0x00000010) {
540 outDir = CPath(wxEmptyString);
541 return false;
542 }
543
544 return CheckMuleDirectory(desc, fallback, wxEmptyString, outDir);
545 }
546
547 theApp->ShowAlert(msg, wxT("Fatal error.")L"Fatal error.", wxICON_ERROR0x00000200 | wxOK0x00000004);
548 outDir = CPath(wxEmptyString);
549 return false;
550}