Beta version 4.9.10: Fix after-update relaunch.

This commit is contained in:
John Preston 2023-09-22 14:43:59 +04:00
parent 9604a3bd80
commit 89fac88677
2 changed files with 146 additions and 61 deletions

View file

@ -47,6 +47,7 @@ string updaterName;
string workDir;
string exeName;
string exePath;
string argv0;
FILE *_logFile = 0;
void openLog() {
@ -356,17 +357,44 @@ string CurrentExecutablePath(int argc, char *argv[]) {
}
int main(int argc, char *argv[]) {
bool needupdate = true;
bool autostart = false;
bool debug = false;
bool tosettings = false;
bool startintray = false;
bool customWorkingDir = false;
bool justUpdate = false;
char *key = 0;
char *workdir = 0;
for (int i = 1; i < argc; ++i) {
if (equal(argv[i], "-debug")) {
_debug = true;
if (equal(argv[i], "-noupdate")) {
needupdate = false;
} else if (equal(argv[i], "-autostart")) {
autostart = true;
} else if (equal(argv[i], "-debug")) {
debug = _debug = true;
} else if (equal(argv[i], "-startintray")) {
startintray = true;
} else if (equal(argv[i], "-tosettings")) {
tosettings = true;
} else if (equal(argv[i], "-workdir_custom")) {
customWorkingDir = true;
} else if (equal(argv[i], "-writeprotected")) {
writeprotected = true;
justUpdate = true;
} else if (equal(argv[i], "-justupdate")) {
justUpdate = true;
} else if (equal(argv[i], "-key") && ++i < argc) {
key = argv[i];
} else if (equal(argv[i], "-workpath") && ++i < argc) {
workDir = argv[i];
workDir = workdir = argv[i];
} else if (equal(argv[i], "-exename") && ++i < argc) {
exeName = argv[i];
} else if (equal(argv[i], "-exepath") && ++i < argc) {
exePath = argv[i];
} else if (equal(argv[i], "-argv0") && ++i < argc) {
argv0 = argv[i];
}
}
if (exeName.empty() || exeName.find('/') != string::npos) {
@ -378,6 +406,8 @@ int main(int argc, char *argv[]) {
for (int i = 0; i < argc; ++i) {
writeLog("Argument: '%s'", argv[i]);
}
if (needupdate) writeLog("Need to update!");
if (autostart) writeLog("From autostart!");
if (writeprotected) writeLog("Write Protected folder!");
updaterName = CurrentExecutablePath(argc, argv);
@ -395,7 +425,10 @@ int main(int argc, char *argv[]) {
exePath = updaterDir;
writeLog("Using updater binary dir.", exePath.c_str());
}
if (needupdate) {
if (workDir.empty()) { // old app launched, update prepared in tupdates/ready (not in tupdates/temp)
customWorkingDir = false;
writeLog("No workdir, trying to figure it out");
struct passwd *pw = getpwuid(getuid());
if (pw && pw->pw_dir && strlen(pw->pw_dir)) {
@ -427,6 +460,7 @@ int main(int argc, char *argv[]) {
writeLog("Passed workpath is '%s'", workDir.c_str());
}
update();
}
} else {
writeLog("Error: bad exe name!");
}
@ -434,7 +468,51 @@ int main(int argc, char *argv[]) {
writeLog("Error: short exe name!");
}
// let the parent launch instead
if (justUpdate) {
writeLog("Closing log and quitting..");
} else {
const auto fullBinaryPath = exePath + exeName;
auto values = vector<string>();
const auto push = [&](string arg) {
// Force null-terminated .data() call result.
values.push_back(arg + char(0));
};
push(!argv0.empty() ? argv0 : fullBinaryPath);
push("-noupdate");
if (autostart) push("-autostart");
if (debug) push("-debug");
if (startintray) push("-startintray");
if (tosettings) push("-tosettings");
if (key) {
push("-key");
push(key);
}
if (customWorkingDir && workdir) {
push("-workdir");
push(workdir);
}
auto args = vector<char*>();
for (auto &arg : values) {
args.push_back(arg.data());
}
args.push_back(nullptr);
pid_t pid = fork();
switch (pid) {
case -1:
writeLog("fork() failed!");
return 1;
case 0:
execv(fullBinaryPath.c_str(), args.data());
return 1;
}
writeLog("Executed Telegram, closing log and quitting..");
}
closeLog();
return 0;

View file

@ -44,21 +44,27 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
const auto justRelaunch = action == UpdaterLaunch::JustRelaunch;
const auto binaryPath = justRelaunch
? (cExeDir() + cExeName()).toStdString()
: (cWriteProtected()
? (cWorkingDir() + u"tupdates/temp/Updater"_q)
: (cExeDir() + u"Updater"_q)).toStdString();
std::vector<std::string> argumentsList;
if (justRelaunch) {
argumentsList.push_back(binaryPath);
} else if (cWriteProtected()) {
argumentsList.push_back("pkexec");
// 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());
}
argumentsList.push_back((justRelaunch && !arguments().isEmpty())
? arguments().first().toStdString()
: binaryPath);
if (Logs::DebugEnabled()) {
argumentsList.push_back("-debug");
@ -82,6 +88,9 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
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");
@ -105,8 +114,7 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
nullptr,
nullptr,
nullptr);
} else {
if (!GLib::spawn_sync(
} else if (!GLib::spawn_sync(
argumentsList,
std::nullopt,
// if the spawn is sync, working directory is not set
@ -123,6 +131,5 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
}
return launchUpdater(UpdaterLaunch::JustRelaunch);
}
}
} // namespace