xref: /haiku/src/kits/package/PackageRoster.cpp (revision 204dee708a999d5a71d0cb9497650ee7cef85d0a)
1 /*
2  * Copyright 2011, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Oliver Tappe <zooey@hirschkaefer.de>
7  */
8 
9 
10 #include <package/PackageRoster.h>
11 
12 #include <errno.h>
13 #include <sys/stat.h>
14 
15 #include <Directory.h>
16 #include <Entry.h>
17 #include <Messenger.h>
18 #include <Path.h>
19 #include <String.h>
20 #include <StringList.h>
21 
22 #include <package/InstallationLocationInfo.h>
23 #include <package/PackageInfo.h>
24 #include <package/PackageInfoContentHandler.h>
25 #include <package/PackageInfoSet.h>
26 #include <package/RepositoryCache.h>
27 #include <package/RepositoryConfig.h>
28 
29 #include <package/hpkg/PackageReader.h>
30 
31 
32 #if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU)
33 #	include <package/DaemonClient.h>
34 #endif
35 
36 
37 namespace BPackageKit {
38 
39 
40 using namespace BHPKG;
41 
42 
43 BPackageRoster::BPackageRoster()
44 {
45 }
46 
47 
48 BPackageRoster::~BPackageRoster()
49 {
50 }
51 
52 
53 status_t
54 BPackageRoster::GetCommonRepositoryConfigPath(BPath* path, bool create) const
55 {
56 	return _GetRepositoryPath(path, create, B_COMMON_SETTINGS_DIRECTORY);
57 }
58 
59 
60 status_t
61 BPackageRoster::GetUserRepositoryConfigPath(BPath* path, bool create) const
62 {
63 	return _GetRepositoryPath(path, create, B_USER_SETTINGS_DIRECTORY);
64 }
65 
66 
67 status_t
68 BPackageRoster::GetCommonRepositoryCachePath(BPath* path, bool create) const
69 {
70 	return _GetRepositoryPath(path, create, B_COMMON_CACHE_DIRECTORY);
71 }
72 
73 
74 status_t
75 BPackageRoster::GetUserRepositoryCachePath(BPath* path, bool create) const
76 {
77 	return _GetRepositoryPath(path, create, B_USER_CACHE_DIRECTORY);
78 }
79 
80 
81 status_t
82 BPackageRoster::VisitCommonRepositoryConfigs(BRepositoryConfigVisitor& visitor)
83 {
84 	BPath commonRepositoryConfigPath;
85 	status_t result
86 		= GetCommonRepositoryConfigPath(&commonRepositoryConfigPath);
87 	if (result != B_OK)
88 		return result;
89 
90 	return _VisitRepositoryConfigs(commonRepositoryConfigPath, visitor);
91 }
92 
93 
94 status_t
95 BPackageRoster::VisitUserRepositoryConfigs(BRepositoryConfigVisitor& visitor)
96 {
97 	BPath userRepositoryConfigPath;
98 	status_t result = GetUserRepositoryConfigPath(&userRepositoryConfigPath);
99 	if (result != B_OK)
100 		return result;
101 
102 	return _VisitRepositoryConfigs(userRepositoryConfigPath, visitor);
103 }
104 
105 
106 status_t
107 BPackageRoster::GetRepositoryNames(BStringList& names)
108 {
109 	struct RepositoryNameCollector : public BRepositoryConfigVisitor {
110 		RepositoryNameCollector(BStringList& _names)
111 			: names(_names)
112 		{
113 		}
114 		status_t operator()(const BEntry& entry)
115 		{
116 			char name[B_FILE_NAME_LENGTH];
117 			status_t result = entry.GetName(name);
118 			if (result != B_OK)
119 				return result;
120 			int32 count = names.CountStrings();
121 			for (int i = 0; i < count; ++i) {
122 				if (names.StringAt(i).Compare(name) == 0)
123 					return B_OK;
124 			}
125 			names.Add(name);
126 			return B_OK;
127 		}
128 		BStringList& names;
129 	};
130 	RepositoryNameCollector repositoryNameCollector(names);
131 	status_t result = VisitUserRepositoryConfigs(repositoryNameCollector);
132 	if (result != B_OK)
133 		return result;
134 
135 	return VisitCommonRepositoryConfigs(repositoryNameCollector);
136 }
137 
138 
139 status_t
140 BPackageRoster::GetRepositoryCache(const BString& name,
141 	BRepositoryCache* repositoryCache)
142 {
143 	if (repositoryCache == NULL)
144 		return B_BAD_VALUE;
145 
146 	// user path has higher precedence than common path
147 	BPath path;
148 	status_t result = GetUserRepositoryCachePath(&path);
149 	if (result != B_OK)
150 		return result;
151 	path.Append(name.String());
152 
153 	BEntry repoCacheEntry(path.Path());
154 	if (repoCacheEntry.Exists())
155 		return repositoryCache->SetTo(repoCacheEntry);
156 
157 	if ((result = GetCommonRepositoryCachePath(&path, true)) != B_OK)
158 		return result;
159 	path.Append(name.String());
160 
161 	repoCacheEntry.SetTo(path.Path());
162 	return repositoryCache->SetTo(repoCacheEntry);
163 }
164 
165 
166 status_t
167 BPackageRoster::GetRepositoryConfig(const BString& name,
168 	BRepositoryConfig* repositoryConfig)
169 {
170 	if (repositoryConfig == NULL)
171 		return B_BAD_VALUE;
172 
173 	// user path has higher precedence than common path
174 	BPath path;
175 	status_t result = GetUserRepositoryConfigPath(&path);
176 	if (result != B_OK)
177 		return result;
178 	path.Append(name.String());
179 
180 	BEntry repoConfigEntry(path.Path());
181 	if (repoConfigEntry.Exists())
182 		return repositoryConfig->SetTo(repoConfigEntry);
183 
184 	if ((result = GetCommonRepositoryConfigPath(&path, true)) != B_OK)
185 		return result;
186 	path.Append(name.String());
187 
188 	repoConfigEntry.SetTo(path.Path());
189 	return repositoryConfig->SetTo(repoConfigEntry);
190 }
191 
192 
193 status_t
194 BPackageRoster::GetInstallationLocationInfo(
195 	BPackageInstallationLocation location, BInstallationLocationInfo& _info)
196 {
197 // This method makes sense only on an installed Haiku, but not for the build
198 // tools.
199 #if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU)
200 	return BPackageKit::BPrivate::BDaemonClient().GetInstallationLocationInfo(
201 		location, _info);
202 #else
203 	return B_NOT_SUPPORTED;
204 #endif
205 }
206 
207 
208 status_t
209 BPackageRoster::GetActivePackages(BPackageInstallationLocation location,
210 	BPackageInfoSet& packageInfos)
211 {
212 // This method makes sense only on an installed Haiku, but not for the build
213 // tools.
214 #if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU)
215 	BInstallationLocationInfo info;
216 	status_t error = GetInstallationLocationInfo(location, info);
217 	if (error != B_OK)
218 		return error;
219 
220 	packageInfos = info.ActivePackageInfos();
221 	return B_OK;
222 #else
223 	return B_NOT_SUPPORTED;
224 #endif
225 }
226 
227 
228 status_t
229 BPackageRoster::_GetRepositoryPath(BPath* path, bool create,
230 	directory_which whichDir) const
231 {
232 	if (path == NULL)
233 		return B_BAD_VALUE;
234 
235 	status_t result = find_directory(whichDir, path);
236 	if (result != B_OK)
237 		return result;
238 	if ((result = path->Append("package-repositories")) != B_OK)
239 		return result;
240 
241 	if (create) {
242 		BEntry entry(path->Path(), true);
243 		if (!entry.Exists()) {
244 			if (mkdir(path->Path(), 0755) != 0)
245 				return errno;
246 		}
247 	}
248 
249 	return B_OK;
250 }
251 
252 
253 status_t
254 BPackageRoster::_VisitRepositoryConfigs(const BPath& path,
255 	BRepositoryConfigVisitor& visitor)
256 {
257 	BDirectory directory(path.Path());
258 	status_t result = directory.InitCheck();
259 	if (result == B_ENTRY_NOT_FOUND)
260 		return B_OK;
261 	if (result != B_OK)
262 		return result;
263 
264 	BEntry entry;
265 	while (directory.GetNextEntry(&entry, true) == B_OK) {
266 		if ((result = visitor(entry)) != B_OK)
267 			return result;
268 	}
269 
270 	return B_OK;
271 }
272 
273 
274 }	// namespace BPackageKit
275