blob: 9548c618d808b1aeadba03130e2c319a485a0e71 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdio.h>
#include <unistd.h>
#include <optional>
#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/strings/strcat.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/linux/ipc_constants.h"
#include "chrome/updater/linux/systemd_util.h"
#include "chrome/updater/posix/setup.h"
#include "chrome/updater/util/posix_util.h"
#include "chrome/updater/util/util.h"
namespace updater {
int Setup(UpdaterScope scope) {
VLOG(1) << base::CommandLine::ForCurrentProcess()->GetCommandLineString()
<< " : " << __func__;
std::optional<base::FilePath> dest_path = GetVersionedInstallDirectory(scope);
if (!dest_path) {
return kErrorFailedToGetVersionedInstallDirectory;
}
if (base::PathExists(*dest_path)) {
if (!DeleteExcept(dest_path->Append("Crashpad"))) {
LOG(ERROR) << "Could not remove existing copy of this updater.";
return kErrorFailedToDeleteFolder;
}
}
dest_path = dest_path->Append(GetExecutableRelativePath());
base::FilePath exe_path;
if (!base::PathService::Get(base::FILE_EXE, &exe_path)) {
return kErrorPathServiceFailed;
}
if (!base::CopyFile(exe_path, dest_path.value())) {
return kErrorFailedToCopyBinary;
}
// rwx------ for user installs, rwxr-xr-x for system installs.
int permissions_mask = base::FILE_PERMISSION_USER_MASK;
if (IsSystemInstall(scope)) {
permissions_mask |= base::FILE_PERMISSION_READ_BY_GROUP |
base::FILE_PERMISSION_EXECUTE_BY_GROUP |
base::FILE_PERMISSION_READ_BY_OTHERS |
base::FILE_PERMISSION_EXECUTE_BY_OTHERS;
}
if (!base::SetPosixFilePermissions(dest_path.value(), permissions_mask)) {
return kErrorFailedToCopyBinary;
}
return kErrorOk;
}
int UninstallCandidate(UpdaterScope scope) {
VLOG(1) << base::CommandLine::ForCurrentProcess()->GetCommandLineString()
<< " : " << __func__;
int error = kErrorOk;
if (!DeleteCandidateInstallFolder(scope)) {
VLOG(1) << "Failed to delete versioned folder.";
error = kErrorFailedToDeleteFolder;
}
std::optional<base::FilePath> versioned_socket =
GetActiveDutyInternalSocketPath(scope);
if (!versioned_socket || !base::DeleteFile(versioned_socket.value())) {
VLOG(1) << "Failed to delete versioned socket file.";
error = kErrorFailedToDeleteSocket;
}
return error;
}
int PromoteCandidate(UpdaterScope scope) {
// Create a hard link in the base install directory to this updater.
std::optional<base::FilePath> launcher_path =
GetUpdateServiceLauncherPath(scope);
base::FilePath updater_executable;
if (!launcher_path ||
!base::PathService::Get(base::FILE_EXE, &updater_executable)) {
return kErrorFailedToGetVersionedInstallDirectory;
}
base::FilePath tmp_launcher_name =
launcher_path->DirName().Append("launcher_new");
if (link(updater_executable.value().c_str(),
tmp_launcher_name.value().c_str())) {
return kErrorFailedToLinkCurrent;
}
if (rename(tmp_launcher_name.value().c_str(),
launcher_path->value().c_str())) {
return kErrorFailedToRenameCurrent;
}
if (!InstallSystemdUnits(scope)) {
return kErrorFailedToInstallSystemdUnit;
}
return kErrorOk;
}
int Uninstall(UpdaterScope scope) {
VLOG(1) << base::CommandLine::ForCurrentProcess()->GetCommandLineString()
<< " : " << __func__;
int error = kErrorOk;
if (!UninstallSystemdUnits(scope)) {
error = kErrorFailedToRemoveSystemdUnit;
}
if (!DeleteFolder(GetInstallDirectory(scope)) ||
!DeleteFolder(GetInstallDirectory(scope))) {
error = kErrorFailedToDeleteFolder;
}
return error;
}
} // namespace updater