2 * Copyright 2013-2014, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Ingo Weinhold <ingo_weinhold@gmx.de>
10 #include <package/DaemonClient.h>
14 #include <Directory.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
{
28 BDaemonClient::BDaemonClient()
35 BDaemonClient::~BDaemonClient()
41 BDaemonClient::GetInstallationLocationInfo(
42 BPackageInstallationLocation location
, BInstallationLocationInfo
& _info
)
44 status_t error
= _InitMessenger();
49 BMessage
request(B_MESSAGE_GET_INSTALLATION_LOCATION_INFO
);
50 error
= request
.AddInt32("location", location
);
55 fDaemonMessenger
.SendMessage(&request
, &reply
);
56 if (reply
.what
!= B_MESSAGE_GET_INSTALLATION_LOCATION_INFO_REPLY
)
59 // extract the location info
60 int32 baseDirectoryDevice
;
61 int64 baseDirectoryNode
;
62 int32 packagesDirectoryDevice
;
63 int64 packagesDirectoryNode
;
65 BPackageInfoSet latestActivePackages
;
66 BPackageInfoSet latestInactivePackages
;
67 if ((error
= reply
.FindInt32("base directory device", &baseDirectoryDevice
))
69 || (error
= reply
.FindInt64("base directory node", &baseDirectoryNode
))
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
) {
83 BPackageInfoSet currentlyActivePackages
;
84 error
= _ExtractPackageInfoSet(reply
, "currently active packages",
85 currentlyActivePackages
);
86 if (error
!= B_OK
&& error
!= B_NAME_NOT_FOUND
)
90 error
= reply
.FindString("old state", &oldStateName
);
91 if (error
!= B_OK
&& error
!= B_NAME_NOT_FOUND
)
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
);
110 BDaemonClient::CommitTransaction(const BActivationTransaction
& transaction
,
111 BCommitTransactionResult
& _result
)
113 if (transaction
.InitCheck() != B_OK
)
116 status_t error
= _InitMessenger();
121 BMessage
request(B_MESSAGE_COMMIT_TRANSACTION
);
122 error
= transaction
.Archive(&request
);
127 fDaemonMessenger
.SendMessage(&request
, &reply
);
128 if (reply
.what
!= B_MESSAGE_COMMIT_TRANSACTION_REPLY
)
131 // extract the result
132 return _result
.ExtractFromMessage(reply
);
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
);
146 // open admin directory
148 entryRef
.device
= info
.PackagesDirectoryRef().device
;
149 entryRef
.directory
= info
.PackagesDirectoryRef().node
;
150 error
= entryRef
.set_name(PACKAGES_DIRECTORY_ADMIN_DIRECTORY
);
154 BDirectory adminDirectory
;
155 error
= adminDirectory
.SetTo(&entryRef
);
159 // create a transaction directory
161 BString directoryName
;
162 for (;; uniqueId
++) {
163 directoryName
.SetToFormat("transaction-%d", uniqueId
);
164 if (directoryName
.IsEmpty())
167 error
= adminDirectory
.CreateDirectory(directoryName
,
168 &_transactionDirectory
);
171 if (error
!= B_FILE_EXISTS
)
175 // init the transaction
176 error
= _transaction
.SetTo(location
, info
.ChangeCount(), directoryName
);
179 _transactionDirectory
.GetEntry(&entry
);
180 _transactionDirectory
.Unset();
181 if (entry
.InitCheck() == B_OK
)
191 BDaemonClient::_InitMessenger()
193 if (fDaemonMessenger
.IsValid())
196 // get the package daemon's address
198 fDaemonMessenger
= BMessenger(B_PACKAGE_DAEMON_APP_SIGNATURE
, -1, &error
);
204 BDaemonClient::_ExtractPackageInfoSet(const BMessage
& message
,
205 const char* field
, BPackageInfoSet
& _infos
)
207 // get the number of items
210 if (message
.GetInfo(field
, &type
, &count
) != B_OK
) {
211 // the field is missing
214 if (type
!= B_MESSAGE_TYPE
)
217 for (int32 i
= 0; i
< count
; i
++) {
219 status_t error
= message
.FindMessage(field
, i
, &archive
);
223 BPackageInfo
info(&archive
, &error
);
227 error
= _infos
.AddInfo(info
);
236 } // namespace BPrivate
237 } // namespace BPackageKit