1/*
2 * Copyright 2013-2021, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Ingo Weinhold <ingo_weinhold@gmx.de>
7 * 		Stephan A��mus <superstippi@gmx.de>
8 * 		Rene Gollent <rene@gollent.com>
9 *		Julian Harnath <julian.harnath@rwth-aachen.de>
10 *		Andrew Lindesay <apl@lindesay.co.nz>
11 *
12 * Note that this file has been re-factored from `PackageManager.cpp` and
13 * authors have been carried across in 2021.
14 */
15
16
17#include "UninstallPackageProcess.h"
18
19#include <package/manager/Exceptions.h>
20#include <package/solver/SolverPackage.h>
21
22#include <Catalog.h>
23
24#include "Alert.h"
25#include "AppUtils.h"
26#include "Logger.h"
27#include "PackageManager.h"
28
29
30#undef B_TRANSLATION_CONTEXT
31#define B_TRANSLATION_CONTEXT "UninstallPackageAction"
32
33
34using namespace BPackageKit;
35using namespace BPackageKit::BManager::BPrivate;
36
37using BPackageKit::BSolverPackage;
38
39
40UninstallPackageProcess::UninstallPackageProcess(PackageInfoRef package,
41		Model* model)
42	:
43	AbstractPackageProcess(package, model)
44{
45	fDescription = B_TRANSLATE("Uninstalling \"%PackageName%\"");
46	fDescription.ReplaceAll("%PackageName%", fPackage->Name());
47}
48
49
50UninstallPackageProcess::~UninstallPackageProcess()
51{
52}
53
54
55const char*
56UninstallPackageProcess::Name() const
57{
58	return "UninstallPackageAction";
59}
60
61
62const char*
63UninstallPackageProcess::Description() const
64{
65	return fDescription;
66}
67
68
69status_t
70UninstallPackageProcess::RunInternal()
71{
72	fPackageManager->Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES);
73	PackageInfoRef ref(fPackage);
74	PackageState state = ref->State();
75	fPackageManager->SetCurrentActionPackage(ref, false);
76	fPackageManager->AddProgressListener(this);
77	const char* packageName = ref->Name().String();
78	try {
79		fPackageManager->Uninstall(&packageName, 1);
80	} catch (BFatalErrorException& ex) {
81		BString errorString;
82		errorString.SetToFormat(
83			"Fatal error occurred while uninstalling package %s: "
84			"%s (%s)\n", packageName, ex.Message().String(),
85			ex.Details().String());
86		AppUtils::NotifySimpleError(B_TRANSLATE("Fatal error"), errorString,
87			B_STOP_ALERT);
88		ref->SetState(state);
89		return ex.Error();
90	} catch (BAbortedByUserException& ex) {
91		return B_OK;
92	} catch (BNothingToDoException& ex) {
93		return B_OK;
94	} catch (BException& ex) {
95		HDERROR("Exception occurred while uninstalling package %s: %s",
96			packageName, ex.Message().String());
97		ref->SetState(state);
98		return B_ERROR;
99	}
100
101	fPackageManager->RemoveProgressListener(this);
102
103	ref->ClearInstallationLocations();
104	ref->SetState(NONE);
105
106	return B_OK;
107}
108
109
110void
111UninstallPackageProcess::StartApplyingChanges(
112		BPackageManager::InstalledRepository& repository)
113{
114	BPackageManager::InstalledRepository::PackageList& packages
115		= repository.PackagesToDeactivate();
116	for (int32 i = 0; i < packages.CountItems(); i++) {
117		PackageInfoRef ref(FindPackageByName(packages.ItemAt(i)
118				->Name()));
119		if (ref.IsSet())
120			fRemovedPackages.push_back(ref);
121	}
122}
123
124
125void
126UninstallPackageProcess::ApplyingChangesDone(
127		BPackageManager::InstalledRepository& repository)
128{
129	std::vector<PackageInfoRef>::iterator it;
130	for (it = fRemovedPackages.begin(); it != fRemovedPackages.end(); it++) {
131		PackageInfoRef packageInfoRef = *it;
132		packageInfoRef->SetState(NONE);
133	}
134}
135