BPicture: Fix archive constructor.
[haiku.git] / src / kits / package / DaemonClient.cpp
blobee0e7c2cd832811a69d4037dbb605bd95db4bdcf
1 /*
2 * Copyright 2013-2014, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Ingo Weinhold <ingo_weinhold@gmx.de>
7 */
10 #include <package/DaemonClient.h>
12 #include <time.h>
14 #include <Directory.h>
15 #include <Entry.h>
16 #include <package/CommitTransactionResult.h>
17 #include <package/InstallationLocationInfo.h>
18 #include <package/PackageInfo.h>
20 #include <package/ActivationTransaction.h>
21 #include <package/PackagesDirectoryDefs.h>
24 namespace BPackageKit {
25 namespace BPrivate {
28 BDaemonClient::BDaemonClient()
30 fDaemonMessenger()
35 BDaemonClient::~BDaemonClient()
40 status_t
41 BDaemonClient::GetInstallationLocationInfo(
42 BPackageInstallationLocation location, BInstallationLocationInfo& _info)
44 status_t error = _InitMessenger();
45 if (error != B_OK)
46 return error;
48 // send the request
49 BMessage request(B_MESSAGE_GET_INSTALLATION_LOCATION_INFO);
50 error = request.AddInt32("location", location);
51 if (error != B_OK)
52 return error;
54 BMessage reply;
55 fDaemonMessenger.SendMessage(&request, &reply);
56 if (reply.what != B_MESSAGE_GET_INSTALLATION_LOCATION_INFO_REPLY)
57 return B_ERROR;
59 // extract the location info
60 int32 baseDirectoryDevice;
61 int64 baseDirectoryNode;
62 int32 packagesDirectoryDevice;
63 int64 packagesDirectoryNode;
64 int64 changeCount;
65 BPackageInfoSet latestActivePackages;
66 BPackageInfoSet latestInactivePackages;
67 if ((error = reply.FindInt32("base directory device", &baseDirectoryDevice))
68 != B_OK
69 || (error = reply.FindInt64("base directory node", &baseDirectoryNode))
70 != B_OK
71 || (error = reply.FindInt32("packages directory device",
72 &packagesDirectoryDevice)) != B_OK
73 || (error = reply.FindInt64("packages directory node",
74 &packagesDirectoryNode)) != B_OK
75 || (error = _ExtractPackageInfoSet(reply, "latest active packages",
76 latestActivePackages)) != B_OK
77 || (error = _ExtractPackageInfoSet(reply, "latest inactive packages",
78 latestInactivePackages)) != B_OK
79 || (error = reply.FindInt64("change count", &changeCount)) != B_OK) {
80 return error;
83 BPackageInfoSet currentlyActivePackages;
84 error = _ExtractPackageInfoSet(reply, "currently active packages",
85 currentlyActivePackages);
86 if (error != B_OK && error != B_NAME_NOT_FOUND)
87 return error;
89 BString oldStateName;
90 error = reply.FindString("old state", &oldStateName);
91 if (error != B_OK && error != B_NAME_NOT_FOUND)
92 return error;
94 _info.Unset();
95 _info.SetLocation(location);
96 _info.SetBaseDirectoryRef(node_ref(baseDirectoryDevice, baseDirectoryNode));
97 _info.SetPackagesDirectoryRef(
98 node_ref(packagesDirectoryDevice, packagesDirectoryNode));
99 _info.SetLatestActivePackageInfos(latestActivePackages);
100 _info.SetLatestInactivePackageInfos(latestInactivePackages);
101 _info.SetCurrentlyActivePackageInfos(currentlyActivePackages);
102 _info.SetOldStateName(oldStateName);
103 _info.SetChangeCount(changeCount);
105 return B_OK;
109 status_t
110 BDaemonClient::CommitTransaction(const BActivationTransaction& transaction,
111 BCommitTransactionResult& _result)
113 if (transaction.InitCheck() != B_OK)
114 return B_BAD_VALUE;
116 status_t error = _InitMessenger();
117 if (error != B_OK)
118 return error;
120 // send the request
121 BMessage request(B_MESSAGE_COMMIT_TRANSACTION);
122 error = transaction.Archive(&request);
123 if (error != B_OK)
124 return error;
126 BMessage reply;
127 fDaemonMessenger.SendMessage(&request, &reply);
128 if (reply.what != B_MESSAGE_COMMIT_TRANSACTION_REPLY)
129 return B_ERROR;
131 // extract the result
132 return _result.ExtractFromMessage(reply);
136 status_t
137 BDaemonClient::CreateTransaction(BPackageInstallationLocation location,
138 BActivationTransaction& _transaction, BDirectory& _transactionDirectory)
140 // get an info for the location
141 BInstallationLocationInfo info;
142 status_t error = GetInstallationLocationInfo(location, info);
143 if (error != B_OK)
144 return error;
146 // open admin directory
147 entry_ref entryRef;
148 entryRef.device = info.PackagesDirectoryRef().device;
149 entryRef.directory = info.PackagesDirectoryRef().node;
150 error = entryRef.set_name(PACKAGES_DIRECTORY_ADMIN_DIRECTORY);
151 if (error != B_OK)
152 return error;
154 BDirectory adminDirectory;
155 error = adminDirectory.SetTo(&entryRef);
156 if (error != B_OK)
157 return error;
159 // create a transaction directory
160 int uniqueId = 1;
161 BString directoryName;
162 for (;; uniqueId++) {
163 directoryName.SetToFormat("transaction-%d", uniqueId);
164 if (directoryName.IsEmpty())
165 return B_NO_MEMORY;
167 error = adminDirectory.CreateDirectory(directoryName,
168 &_transactionDirectory);
169 if (error == B_OK)
170 break;
171 if (error != B_FILE_EXISTS)
172 return error;
175 // init the transaction
176 error = _transaction.SetTo(location, info.ChangeCount(), directoryName);
177 if (error != B_OK) {
178 BEntry entry;
179 _transactionDirectory.GetEntry(&entry);
180 _transactionDirectory.Unset();
181 if (entry.InitCheck() == B_OK)
182 entry.Remove();
183 return error;
186 return B_OK;
190 status_t
191 BDaemonClient::_InitMessenger()
193 if (fDaemonMessenger.IsValid())
194 return B_OK;
196 // get the package daemon's address
197 status_t error;
198 fDaemonMessenger = BMessenger(B_PACKAGE_DAEMON_APP_SIGNATURE, -1, &error);
199 return error;
203 status_t
204 BDaemonClient::_ExtractPackageInfoSet(const BMessage& message,
205 const char* field, BPackageInfoSet& _infos)
207 // get the number of items
208 type_code type;
209 int32 count;
210 if (message.GetInfo(field, &type, &count) != B_OK) {
211 // the field is missing
212 return B_OK;
214 if (type != B_MESSAGE_TYPE)
215 return B_BAD_DATA;
217 for (int32 i = 0; i < count; i++) {
218 BMessage archive;
219 status_t error = message.FindMessage(field, i, &archive);
220 if (error != B_OK)
221 return error;
223 BPackageInfo info(&archive, &error);
224 if (error != B_OK)
225 return error;
227 error = _infos.AddInfo(info);
228 if (error != B_OK)
229 return error;
232 return B_OK;
236 } // namespace BPrivate
237 } // namespace BPackageKit