1/*
2 * Copyright 2011-2018, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Oliver Tappe <zooey@hirschkaefer.de>
7 *		Andrew Lindesay <apl@lindesay.co.nz>
8 */
9
10
11#include <package/RepositoryInfo.h>
12
13#include <stdlib.h>
14
15#include <new>
16
17#include <driver_settings.h>
18#include <File.h>
19#include <Message.h>
20
21#include <AutoDeleter.h>
22#include <package/PackageInfo.h>
23
24
25namespace BPackageKit {
26
27
28const uint8 BRepositoryInfo::kDefaultPriority	= 50;
29
30const char* const BRepositoryInfo::kNameField			= "name";
31const char* const BRepositoryInfo::kURLField			= "url";
32const char* const BRepositoryInfo::kBaseURLField		= "baseUrl";
33const char* const BRepositoryInfo::kVendorField			= "vendor";
34const char* const BRepositoryInfo::kSummaryField		= "summary";
35const char* const BRepositoryInfo::kPriorityField		= "priority";
36const char* const BRepositoryInfo::kArchitectureField	= "architecture";
37const char* const BRepositoryInfo::kLicenseNameField	= "licenseName";
38const char* const BRepositoryInfo::kLicenseTextField	= "licenseText";
39
40
41BRepositoryInfo::BRepositoryInfo()
42	:
43	fInitStatus(B_NO_INIT),
44	fPriority(kDefaultPriority),
45	fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT)
46{
47}
48
49
50BRepositoryInfo::BRepositoryInfo(BMessage* data)
51	:
52	inherited(data),
53	fLicenseTexts(5)
54{
55	fInitStatus = _SetTo(data);
56}
57
58
59BRepositoryInfo::BRepositoryInfo(const BEntry& entry)
60{
61	fInitStatus = _SetTo(entry);
62}
63
64
65BRepositoryInfo::~BRepositoryInfo()
66{
67}
68
69
70/*static*/ BRepositoryInfo*
71BRepositoryInfo::Instantiate(BMessage* data)
72{
73	if (validate_instantiation(data, "BPackageKit::BRepositoryInfo"))
74		return new (std::nothrow) BRepositoryInfo(data);
75
76	return NULL;
77}
78
79
80status_t
81BRepositoryInfo::Archive(BMessage* data, bool deep) const
82{
83	status_t result = inherited::Archive(data, deep);
84	if (result != B_OK)
85		return result;
86
87	if (!fBaseURL.IsEmpty()) {
88		if ((result = data->AddString(kBaseURLField, fBaseURL)) != B_OK)
89			return result;
90	}
91
92	if ((result = data->AddString(kNameField, fName)) != B_OK)
93		return result;
94	if ((result = data->AddString(kURLField, fURL)) != B_OK)
95		return result;
96	if ((result = data->AddString(kVendorField, fVendor)) != B_OK)
97		return result;
98	result = data->AddString(kSummaryField, fSummary);
99	if (result != B_OK)
100		return result;
101	if ((result = data->AddUInt8(kPriorityField, fPriority)) != B_OK)
102		return result;
103	if ((result = data->AddUInt8(kArchitectureField, fArchitecture)) != B_OK)
104		return result;
105	for (int i = 0; i < fLicenseNames.CountStrings(); ++i) {
106		result = data->AddString(kLicenseNameField, fLicenseNames.StringAt(i));
107		if (result != B_OK)
108			return result;
109	}
110	for (int i = 0; i < fLicenseTexts.CountStrings(); ++i) {
111		result = data->AddString(kLicenseTextField, fLicenseTexts.StringAt(i));
112		if (result != B_OK)
113			return result;
114	}
115
116	return B_OK;
117}
118
119
120status_t
121BRepositoryInfo::InitCheck() const
122{
123	return fInitStatus;
124}
125
126
127status_t
128BRepositoryInfo::SetTo(const BMessage* data)
129{
130	return fInitStatus = _SetTo(data);
131}
132
133
134status_t
135BRepositoryInfo::SetTo(const BEntry& entry)
136{
137	return fInitStatus = _SetTo(entry);
138}
139
140
141const BString&
142BRepositoryInfo::Name() const
143{
144	return fName;
145}
146
147
148const BString&
149BRepositoryInfo::BaseURL() const
150{
151	return fBaseURL;
152}
153
154
155const BString&
156BRepositoryInfo::URL() const
157{
158	return fURL;
159}
160
161
162const BString&
163BRepositoryInfo::Vendor() const
164{
165	return fVendor;
166}
167
168
169const BString&
170BRepositoryInfo::Summary() const
171{
172	return fSummary;
173}
174
175
176uint8
177BRepositoryInfo::Priority() const
178{
179	return fPriority;
180}
181
182
183BPackageArchitecture
184BRepositoryInfo::Architecture() const
185{
186	return fArchitecture;
187}
188
189
190const BStringList&
191BRepositoryInfo::LicenseNames() const
192{
193	return fLicenseNames;
194}
195
196
197const BStringList&
198BRepositoryInfo::LicenseTexts() const
199{
200	return fLicenseTexts;
201}
202
203
204void
205BRepositoryInfo::SetName(const BString& name)
206{
207	fName = name;
208}
209
210
211void
212BRepositoryInfo::SetURL(const BString& url)
213{
214	fURL = url;
215}
216
217
218void
219BRepositoryInfo::SetBaseURL(const BString& url)
220{
221	fBaseURL = url;
222}
223
224
225void
226BRepositoryInfo::SetVendor(const BString& vendor)
227{
228	fVendor = vendor;
229}
230
231
232void
233BRepositoryInfo::SetSummary(const BString& summary)
234{
235	fSummary = summary;
236}
237
238
239void
240BRepositoryInfo::SetPriority(uint8 priority)
241{
242	fPriority = priority;
243}
244
245
246void
247BRepositoryInfo::SetArchitecture(BPackageArchitecture architecture)
248{
249	fArchitecture = architecture;
250}
251
252
253status_t
254BRepositoryInfo::AddLicense(const BString& licenseName,
255	const BString& licenseText)
256{
257	if (!fLicenseNames.Add(licenseName) || !fLicenseTexts.Add(licenseText))
258		return B_NO_MEMORY;
259
260	return B_OK;
261}
262
263
264void
265BRepositoryInfo::ClearLicenses()
266{
267	fLicenseNames.MakeEmpty();
268	fLicenseTexts.MakeEmpty();
269}
270
271
272status_t
273BRepositoryInfo::_SetTo(const BMessage* data)
274{
275	if (data == NULL)
276		return B_BAD_VALUE;
277
278	data->FindString(kBaseURLField, &fBaseURL);
279		// optional value for historical reasons
280
281	status_t result;
282	if ((result = data->FindString(kNameField, &fName)) != B_OK)
283		return result;
284	if ((result = data->FindString(kURLField, &fURL)) != B_OK)
285		return result;
286	if ((result = data->FindString(kVendorField, &fVendor)) != B_OK)
287		return result;
288	if ((result = data->FindString(kSummaryField, &fSummary)) != B_OK)
289		return result;
290	if ((result = data->FindUInt8(kPriorityField, &fPriority)) != B_OK)
291		return result;
292	result = data->FindUInt8(kArchitectureField, (uint8*)&fArchitecture);
293	if (result != B_OK)
294		return result;
295	if (fArchitecture == B_PACKAGE_ARCHITECTURE_ANY)
296		return B_BAD_DATA;
297
298	const char* licenseName;
299	const char* licenseText;
300	for (int i = 0;
301		data->FindString(kLicenseNameField, i, &licenseName) == B_OK
302			&& data->FindString(kLicenseTextField, i, &licenseText) == B_OK;
303		++i) {
304		if (!fLicenseNames.Add(licenseName) || !fLicenseTexts.Add(licenseText))
305			return B_NO_MEMORY;
306	}
307
308	return B_OK;
309}
310
311
312status_t
313BRepositoryInfo::_SetTo(const BEntry& entry)
314{
315	BFile file(&entry, B_READ_ONLY);
316	status_t result = file.InitCheck();
317	if (result != B_OK)
318		return result;
319
320	off_t size;
321	if ((result = file.GetSize(&size)) != B_OK)
322		return result;
323
324	BString configString;
325	char* buffer = configString.LockBuffer(size);
326	if (buffer == NULL)
327		return B_NO_MEMORY;
328
329	if ((result = file.Read(buffer, size)) < size) {
330		configString.UnlockBuffer(0);
331		return (result >= 0) ? B_IO_ERROR : result;
332	}
333
334	buffer[size] = '\0';
335	configString.UnlockBuffer(size);
336
337	void* settingsHandle = parse_driver_settings_string(configString.String());
338	if (settingsHandle == NULL)
339		return B_BAD_DATA;
340	CObjectDeleter<void, status_t> settingsHandleDeleter(settingsHandle,
341		&unload_driver_settings);
342
343	const char* name = get_driver_parameter(settingsHandle, "name", NULL, NULL);
344	const char* url = get_driver_parameter(settingsHandle, "url", NULL, NULL);
345	const char* baseUrl = get_driver_parameter(settingsHandle, "baseurl", NULL, NULL);
346	const char* vendor
347		= get_driver_parameter(settingsHandle, "vendor", NULL, NULL);
348	const char* summary
349		= get_driver_parameter(settingsHandle, "summary", NULL, NULL);
350	const char* priorityString
351		= get_driver_parameter(settingsHandle, "priority", NULL, NULL);
352	const char* architectureString
353		= get_driver_parameter(settingsHandle, "architecture", NULL, NULL);
354
355	if (name == NULL || *name == '\0' || url == NULL || *url == '\0'
356		|| vendor == NULL || *vendor == '\0'
357		|| summary == NULL || *summary == '\0'
358		|| priorityString == NULL || *priorityString == '\0'
359		|| architectureString == NULL || *architectureString == '\0') {
360		return B_BAD_DATA;
361	}
362
363	BPackageArchitecture architecture;
364	if (BPackageInfo::GetArchitectureByName(architectureString, architecture)
365			!= B_OK || architecture == B_PACKAGE_ARCHITECTURE_ANY) {
366		return B_BAD_DATA;
367	}
368
369	fName = name;
370	fBaseURL = baseUrl;
371	fURL = url;
372	fVendor = vendor;
373	fSummary = summary;
374	fPriority = atoi(priorityString);
375	fArchitecture = architecture;
376
377	return B_OK;
378}
379
380
381}	// namespace BPackageKit
382