summaryrefslogtreecommitdiffstats
path: root/Telegram/SourceFiles/platform/linux/launcher_linux.cpp
blob: 0a5b8168dce48f059a1f8249f6bb28f68f4366b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.

For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "platform/linux/launcher_linux.h"

#include "core/crash_reports.h"
#include "core/update_checker.h"
#include "webview/platform/linux/webview_linux_webkitgtk.h"

#include <QtWidgets/QApplication>
#include <glib/glib.hpp>

using namespace gi::repository;

namespace Platform {

Launcher::Launcher(int argc, char *argv[])
: Core::Launcher(argc, argv) {
}

int Launcher::exec() {
	for (auto i = arguments().begin(), e = arguments().end(); i != e; ++i) {
		if (*i == u"-webviewhelper"_q && std::distance(i, e) > 1) {
			Webview::WebKitGTK::SetSocketPath((i + 1)->toStdString());
			return Webview::WebKitGTK::Exec();
		}
	}

	return Core::Launcher::exec();
}

void Launcher::initHook() {
	QApplication::setAttribute(Qt::AA_DisableSessionManager, true);
}

bool Launcher::launchUpdater(UpdaterLaunch action) {
	if (cExeName().isEmpty()) {
		return false;
	}

	const auto justRelaunch = action == UpdaterLaunch::JustRelaunch;

	std::vector<std::string> argumentsList;

	// What we are launching.
	const auto launching = justRelaunch
		? (cExeDir() + cExeName())
		: cWriteProtected()
		? u"pkexec"_q
		: (cExeDir() + u"Updater"_q);
	argumentsList.push_back(launching.toStdString());

	// argv[0] that is passed to what we are launching.
	const auto argv0 = (justRelaunch && !arguments().isEmpty())
		? arguments().first()
		: launching;
	argumentsList.push_back(argv0.toStdString());

	if (!justRelaunch && cWriteProtected()) {
		// Elevated process that pkexec should launch.
		const auto elevated = cWorkingDir() + u"tupdates/temp/Updater"_q;
		argumentsList.push_back(elevated.toStdString());
	}

	if (Logs::DebugEnabled()) {
		argumentsList.push_back("-debug");
	}

	if (justRelaunch) {
		if (cLaunchMode() == LaunchModeAutoStart) {
			argumentsList.push_back("-autostart");
		}
		if (cStartInTray()) {
			argumentsList.push_back("-startintray");
		}
		if (cDataFile() != u"data"_q) {
			argumentsList.push_back("-key");
			argumentsList.push_back(cDataFile().toStdString());
		}
		argumentsList.push_back("-noupdate");
		argumentsList.push_back("-tosettings");
		if (customWorkingDir()) {
			argumentsList.push_back("-workdir");
			argumentsList.push_back(cWorkingDir().toStdString());
		}
	} else {
		// Don't relaunch Telegram.
		argumentsList.push_back("-justupdate");

		argumentsList.push_back("-workpath");
		argumentsList.push_back(cWorkingDir().toStdString());
		argumentsList.push_back("-exename");
		argumentsList.push_back(cExeName().toStdString());
		argumentsList.push_back("-exepath");
		argumentsList.push_back(cExeDir().toStdString());
		if (cWriteProtected()) {
			argumentsList.push_back("-writeprotected");
		}
	}

	Logs::closeMain();
	CrashReports::Finish();

	if (justRelaunch) {
		return GLib::spawn_async(
			initialWorkingDir().toStdString(),
			argumentsList,
			std::nullopt,
			GLib::SpawnFlags::FILE_AND_ARGV_ZERO_,
			nullptr,
			nullptr,
			nullptr);
	} else if (!GLib::spawn_sync(
			argumentsList,
			std::nullopt,
			// if the spawn is sync, working directory is not set
			// and GLib::SpawnFlags::LEAVE_DESCRIPTORS_OPEN_ is set,
			// it goes through an optimized code path
			GLib::SpawnFlags::SEARCH_PATH_
				| GLib::SpawnFlags::LEAVE_DESCRIPTORS_OPEN_,
			nullptr,
			nullptr,
			nullptr,
			nullptr,
			nullptr)) {
		return false;
	}
	return launchUpdater(UpdaterLaunch::JustRelaunch);
}

} // namespace