vidalia/main.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "config.h"
00018 #include "Vidalia.h"
00019 #include "MainWindow.h"
00020 #include "VMessageBox.h"
00021 #if defined(USE_BREAKPAD)
00022 #include "CrashReporter.h"
00023 #endif
00024
00025 #include "procutil.h"
00026 #include "stringutil.h"
00027
00028 #include <QObject>
00029 #if defined(Q_OS_WIN32)
00030 #include <QSysInfo>
00031 #endif
00032 #if defined(HAVE_SIGNAL_H)
00033 #include <signal.h>
00034 #endif
00035
00036 #if defined(USE_BREAKPAD)
00037 void
00038 setup_crash_reporter()
00039 {
00040
00041
00042
00043 #if defined(Q_OS_WIN32)
00044 QString crashReporter = Vidalia::applicationDirPath() + "\\crashreporter.exe";
00045 #elif defined(Q_OS_MAC)
00046 QString crashReporter = Vidalia::applicationDirPath() + "/CrashReporter.app";
00047 #endif
00048 if (! QFileInfo(crashReporter).isExecutable()) {
00049 vWarn("Unable to find crash reporting application. Crash reporting will "
00050 "be unavailable.");
00051 return;
00052 }
00053 if (! CrashReporter::set_crash_reporter(crashReporter)) {
00054 vWarn("Vidalia found the crash reporting application, but the path is "
00055 "longer than your platform supports. Skipping crash reporting.");
00056 return;
00057 }
00058
00059
00060
00061
00062 CrashReporter::set_restart_options(Vidalia::applicationFilePath(),
00063 Vidalia::arguments().mid(1));
00064
00065
00066 CrashReporter::set_build_version(VIDALIA_VERSION);
00067
00068
00069
00070 QString dumpPath = Vidalia::dataDirectory() + "/crashreports";
00071 if (! CrashReporter::install_exception_handler(dumpPath)) {
00072 vWarn("Unable to setup Breakpad exception handler. Crash reporting "
00073 "will be unavailable.");
00074 } else {
00075 vInfo("Installed Breakpad exception handler.");
00076 }
00077 }
00078 #endif
00079
00080 extern "C" void
00081 signal_handler(int signal)
00082 {
00083 #ifdef HAVE_SIGNAL_H
00084 if (signal == SIGINT || signal == SIGTERM)
00085 vApp->quit();
00086 #endif
00087 }
00088
00089 void
00090 install_signal_handler()
00091 {
00092 #if defined(HAVE_SIGACTION)
00093 struct sigaction action;
00094
00095 sigemptyset(&action.sa_mask);
00096 action.sa_handler = signal_handler;
00097 action.sa_flags = 0;
00098
00099 if (sigaction(SIGINT, &action, NULL) < 0)
00100 vWarn("Failed to install SIGINT handler.");
00101 if (sigaction(SIGTERM, &action, NULL) < 0)
00102 vWarn("Failed to install SIGTERM handler.");
00103 #elif defined(HAVE_SIGNAL)
00104 if (signal(SIGINT, signal_handler) == SIG_ERR)
00105 vWarn("Failed to install SIGINT handler.");
00106 if (signal(SIGTERM, signal_handler) == SIG_ERR)
00107 vWarn("Failed to install SIGTERM handler.");
00108 #endif
00109 }
00110
00111
00112 bool
00113 is_vidalia_running(const QString &pidfile)
00114 {
00115
00116 qint64 pid = read_pidfile(pidfile);
00117 if (pid > 0) {
00118 #if defined(Q_OS_WIN32)
00119 if (QSysInfo::WindowsVersion == QSysInfo::WV_NT) {
00120
00121
00122
00123 return true;
00124 } else
00125 return (is_process_running(pid));
00126 #else
00127 return (is_process_running(pid));
00128 #endif
00129 }
00130 return false;
00131 }
00132
00133
00134 int
00135 main(int argc, char *argv[])
00136 {
00137 Q_INIT_RESOURCE(vidalia);
00138 QStringList args = char_array_to_stringlist(argv+1, argc-1);
00139
00140
00141
00142
00143 Vidalia vidalia(args, argc, argv);
00144 vNotice("Vidalia %1 using Qt %2").arg(Vidalia::version())
00145 .arg(QT_VERSION_STR);
00146
00147 #if defined(USE_BREAKPAD)
00148
00149 setup_crash_reporter();
00150 #endif
00151 #if defined(USE_MARBLE) && defined(Q_OS_WIN32)
00152 vApp->addLibraryPath(vApp->applicationDirPath() + "/plugins/qt");
00153 #endif
00154
00155
00156
00157 install_signal_handler();
00158
00159
00160
00161 QString errmsg;
00162 if (vidalia.showUsage()) {
00163 Vidalia::showUsageMessageBox();
00164 return 0;
00165 } else if (!vidalia.validateArguments(errmsg)) {
00166 vError("Unable to apply command-line arguments: %1").arg(errmsg);
00167 VMessageBox::critical(0,
00168 vApp->translate("Vidalia",
00169 QT_TRANSLATE_NOOP("Vidalia", "Invalid Argument")), errmsg,
00170 VMessageBox::Ok);
00171 return 1;
00172 }
00173
00174
00175 QString pidfile = vidalia.pidFile();
00176 if (is_vidalia_running(pidfile)) {
00177 vWarn("Detected another process with pid %1. Is Vidalia already running?")
00178 .arg(get_pid());
00179
00180
00181 int ret = VMessageBox::critical(0,
00182 vApp->translate("Vidalia",
00183 QT_TRANSLATE_NOOP("Vidalia", "Vidalia is already running")),
00184 vApp->translate("Vidalia",
00185 QT_TRANSLATE_NOOP("Vidalia",
00186 "Another Vidalia process is possibly already running. "
00187 "If there really is not another Vidalia process running, "
00188 "you can choose to continue anyway.\n\n"
00189 "Would you like to continue starting Vidalia?")),
00190 VMessageBox::Continue, VMessageBox::Quit|VMessageBox::Default);
00191 if (ret != VMessageBox::Continue) {
00192
00193 vError("Exiting duplicate Vidalia process.");
00194 return 1;
00195 }
00196 }
00197 write_pidfile(pidfile);
00198
00199
00200
00201
00202
00203 Vidalia::setQuitOnLastWindowClosed(false);
00204
00205
00206 MainWindow mainWin;
00207
00208
00209 int ret = vidalia.run();
00210
00211
00212 QFile::remove(pidfile);
00213 vNotice("Vidalia is exiting cleanly (return code %1).").arg(ret);
00214
00215 #if defined(USE_BREAKPAD)
00216 vInfo("Removing Breakpad exception handler.");
00217 CrashReporter::remove_exception_handler();
00218 #endif
00219
00220 return ret;
00221 }
00222