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 workDir;
string exeName; string exeName;
string exePath; string exePath;
string argv0;
FILE *_logFile = 0; FILE *_logFile = 0;
void openLog() { void openLog() {
@ -356,17 +357,44 @@ string CurrentExecutablePath(int argc, char *argv[]) {
} }
int main(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) { for (int i = 1; i < argc; ++i) {
if (equal(argv[i], "-debug")) { if (equal(argv[i], "-noupdate")) {
_debug = true; 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")) { } else if (equal(argv[i], "-writeprotected")) {
writeprotected = true; 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) { } else if (equal(argv[i], "-workpath") && ++i < argc) {
workDir = argv[i]; workDir = workdir = argv[i];
} else if (equal(argv[i], "-exename") && ++i < argc) { } else if (equal(argv[i], "-exename") && ++i < argc) {
exeName = argv[i]; exeName = argv[i];
} else if (equal(argv[i], "-exepath") && ++i < argc) { } else if (equal(argv[i], "-exepath") && ++i < argc) {
exePath = argv[i]; exePath = argv[i];
} else if (equal(argv[i], "-argv0") && ++i < argc) {
argv0 = argv[i];
} }
} }
if (exeName.empty() || exeName.find('/') != string::npos) { if (exeName.empty() || exeName.find('/') != string::npos) {
@ -378,6 +406,8 @@ int main(int argc, char *argv[]) {
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
writeLog("Argument: '%s'", argv[i]); writeLog("Argument: '%s'", argv[i]);
} }
if (needupdate) writeLog("Need to update!");
if (autostart) writeLog("From autostart!");
if (writeprotected) writeLog("Write Protected folder!"); if (writeprotected) writeLog("Write Protected folder!");
updaterName = CurrentExecutablePath(argc, argv); updaterName = CurrentExecutablePath(argc, argv);
@ -395,38 +425,42 @@ int main(int argc, char *argv[]) {
exePath = updaterDir; exePath = updaterDir;
writeLog("Using updater binary dir.", exePath.c_str()); writeLog("Using updater binary dir.", exePath.c_str());
} }
if (workDir.empty()) { // old app launched, update prepared in tupdates/ready (not in tupdates/temp) if (needupdate) {
writeLog("No workdir, trying to figure it out"); if (workDir.empty()) { // old app launched, update prepared in tupdates/ready (not in tupdates/temp)
struct passwd *pw = getpwuid(getuid()); customWorkingDir = false;
if (pw && pw->pw_dir && strlen(pw->pw_dir)) {
string tryDir = pw->pw_dir + string("/.TelegramDesktop/");
struct stat statbuf;
writeLog("Trying to use '%s' as workDir, getting stat() for tupdates/ready", tryDir.c_str());
if (!stat((tryDir + "tupdates/ready").c_str(), &statbuf)) {
writeLog("Stat got");
if (S_ISDIR(statbuf.st_mode)) {
writeLog("It is directory, using home work dir");
workDir = tryDir;
}
}
}
if (workDir.empty()) {
workDir = exePath;
struct stat statbuf; writeLog("No workdir, trying to figure it out");
writeLog("Trying to use current as workDir, getting stat() for tupdates/ready"); struct passwd *pw = getpwuid(getuid());
if (!stat("tupdates/ready", &statbuf)) { if (pw && pw->pw_dir && strlen(pw->pw_dir)) {
writeLog("Stat got"); string tryDir = pw->pw_dir + string("/.TelegramDesktop/");
if (S_ISDIR(statbuf.st_mode)) { struct stat statbuf;
writeLog("It is directory, using current dir"); writeLog("Trying to use '%s' as workDir, getting stat() for tupdates/ready", tryDir.c_str());
workDir = string(); if (!stat((tryDir + "tupdates/ready").c_str(), &statbuf)) {
writeLog("Stat got");
if (S_ISDIR(statbuf.st_mode)) {
writeLog("It is directory, using home work dir");
workDir = tryDir;
}
} }
} }
if (workDir.empty()) {
workDir = exePath;
struct stat statbuf;
writeLog("Trying to use current as workDir, getting stat() for tupdates/ready");
if (!stat("tupdates/ready", &statbuf)) {
writeLog("Stat got");
if (S_ISDIR(statbuf.st_mode)) {
writeLog("It is directory, using current dir");
workDir = string();
}
}
}
} else {
writeLog("Passed workpath is '%s'", workDir.c_str());
} }
} else { update();
writeLog("Passed workpath is '%s'", workDir.c_str());
} }
update();
} else { } else {
writeLog("Error: bad exe name!"); writeLog("Error: bad exe name!");
} }
@ -434,7 +468,51 @@ int main(int argc, char *argv[]) {
writeLog("Error: short exe name!"); writeLog("Error: short exe name!");
} }
writeLog("Closing log and quitting.."); // 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(); closeLog();
return 0; return 0;

View file

@ -44,21 +44,27 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
const auto justRelaunch = action == UpdaterLaunch::JustRelaunch; 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; std::vector<std::string> argumentsList;
if (justRelaunch) {
argumentsList.push_back(binaryPath); // What we are launching.
} else if (cWriteProtected()) { const auto launching = justRelaunch
argumentsList.push_back("pkexec"); ? (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()) { if (Logs::DebugEnabled()) {
argumentsList.push_back("-debug"); argumentsList.push_back("-debug");
@ -82,6 +88,9 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
argumentsList.push_back(cWorkingDir().toStdString()); argumentsList.push_back(cWorkingDir().toStdString());
} }
} else { } else {
// Don't relaunch Telegram.
argumentsList.push_back("-justupdate");
argumentsList.push_back("-workpath"); argumentsList.push_back("-workpath");
argumentsList.push_back(cWorkingDir().toStdString()); argumentsList.push_back(cWorkingDir().toStdString());
argumentsList.push_back("-exename"); argumentsList.push_back("-exename");
@ -105,24 +114,22 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
nullptr, nullptr,
nullptr, nullptr,
nullptr); nullptr);
} else { } else if (!GLib::spawn_sync(
if (!GLib::spawn_sync( argumentsList,
argumentsList, std::nullopt,
std::nullopt, // if the spawn is sync, working directory is not set
// if the spawn is sync, working directory is not set // and GLib::SpawnFlags::LEAVE_DESCRIPTORS_OPEN_ is set,
// and GLib::SpawnFlags::LEAVE_DESCRIPTORS_OPEN_ is set, // it goes through an optimized code path
// it goes through an optimized code path GLib::SpawnFlags::SEARCH_PATH_
GLib::SpawnFlags::SEARCH_PATH_ | GLib::SpawnFlags::LEAVE_DESCRIPTORS_OPEN_,
| GLib::SpawnFlags::LEAVE_DESCRIPTORS_OPEN_, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr)) {
nullptr)) { return false;
return false;
}
return launchUpdater(UpdaterLaunch::JustRelaunch);
} }
return launchUpdater(UpdaterLaunch::JustRelaunch);
} }
} // namespace } // namespace