| File: | rootdir/src/amuleAppCommon.cpp |
| Warning: | line 71, column 14 This statement is never executed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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 | |
| 55 | CamuleAppCommon::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 | |
| 76 | CamuleAppCommon::~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 | |
| 85 | void 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 | |
| 95 | void 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 |
| 138 | wxString 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 |
| 152 | wxString 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 | |
| 210 | bool 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 | */ |
| 469 | const wxString CamuleAppCommon::GetFullMuleVersion() const |
| 470 | { |
| 471 | return GetMuleAppName() + wxT(" ")L" " + GetMuleVersion(); |
| 472 | } |
| 473 | |
| 474 | bool 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 | */ |
| 513 | bool 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 | } |