xref: /haiku/src/kits/package/PackageRoster.cpp (revision 7749d0bb0c358a3279b1b9cc76d8376e900130a5)
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 <ObjectList.h>
18 #include <Path.h>
19 #include <String.h>
20 
21 #include <package/RepositoryCache.h>
22 #include <package/RepositoryConfig.h>
23 
24 
25 namespace BPackageKit {
26 
27 
28 BPackageRoster::BPackageRoster()
29 {
30 }
31 
32 
33 BPackageRoster::~BPackageRoster()
34 {
35 }
36 
37 
38 status_t
39 BPackageRoster::GetCommonRepositoryConfigPath(BPath* path, bool create) const
40 {
41 	return _GetRepositoryPath(path, create, B_COMMON_SETTINGS_DIRECTORY);
42 }
43 
44 
45 status_t
46 BPackageRoster::GetUserRepositoryConfigPath(BPath* path, bool create) const
47 {
48 	return _GetRepositoryPath(path, create, B_USER_SETTINGS_DIRECTORY);
49 }
50 
51 
52 status_t
53 BPackageRoster::GetCommonRepositoryCachePath(BPath* path, bool create) const
54 {
55 	return _GetRepositoryPath(path, create, B_COMMON_CACHE_DIRECTORY);
56 }
57 
58 
59 status_t
60 BPackageRoster::GetUserRepositoryCachePath(BPath* path, bool create) const
61 {
62 	return _GetRepositoryPath(path, create, B_USER_CACHE_DIRECTORY);
63 }
64 
65 
66 status_t
67 BPackageRoster::VisitCommonRepositoryConfigs(BRepositoryConfigVisitor& visitor)
68 {
69 	BPath commonRepositoryConfigPath;
70 	status_t result
71 		= GetCommonRepositoryConfigPath(&commonRepositoryConfigPath);
72 	if (result != B_OK)
73 		return result;
74 
75 	return _VisitRepositoryConfigs(commonRepositoryConfigPath, visitor);
76 }
77 
78 
79 status_t
80 BPackageRoster::VisitUserRepositoryConfigs(BRepositoryConfigVisitor& visitor)
81 {
82 	BPath userRepositoryConfigPath;
83 	status_t result = GetUserRepositoryConfigPath(&userRepositoryConfigPath);
84 	if (result != B_OK)
85 		return result;
86 
87 	return _VisitRepositoryConfigs(userRepositoryConfigPath, visitor);
88 }
89 
90 
91 status_t
92 BPackageRoster::GetRepositoryNames(BObjectList<BString>& names)
93 {
94 	struct RepositoryNameCollector : public BRepositoryConfigVisitor {
95 		RepositoryNameCollector(BObjectList<BString>& _names)
96 			: names(_names)
97 		{
98 		}
99 		status_t operator()(const BEntry& entry)
100 		{
101 			char name[B_FILE_NAME_LENGTH];
102 			status_t result = entry.GetName(name);
103 			if (result != B_OK)
104 				return result;
105 			int32 count = names.CountItems();
106 			for (int i = 0; i < count; ++i) {
107 				if (names.ItemAt(i)->Compare(name) == 0)
108 					return B_OK;
109 			}
110 			names.AddItem(new (std::nothrow) BString(name));
111 			return B_OK;
112 		}
113 		BObjectList<BString>& names;
114 	};
115 	RepositoryNameCollector repositoryNameCollector(names);
116 	status_t result = VisitUserRepositoryConfigs(repositoryNameCollector);
117 	if (result != B_OK)
118 		return result;
119 
120 	return VisitCommonRepositoryConfigs(repositoryNameCollector);
121 }
122 
123 
124 status_t
125 BPackageRoster::GetRepositoryCache(const BString& name,
126 	BRepositoryCache* repositoryCache)
127 {
128 	if (repositoryCache == NULL)
129 		return B_BAD_VALUE;
130 
131 	// user path has higher precedence than common path
132 	BPath path;
133 	status_t result = GetUserRepositoryCachePath(&path);
134 	if (result != B_OK)
135 		return result;
136 	path.Append(name.String());
137 
138 	BEntry repoCacheEntry(path.Path());
139 	if (repoCacheEntry.Exists())
140 		return repositoryCache->SetTo(repoCacheEntry);
141 
142 	if ((result = GetCommonRepositoryCachePath(&path)) != B_OK)
143 		return result;
144 	path.Append(name.String());
145 
146 	repoCacheEntry.SetTo(path.Path());
147 	return repositoryCache->SetTo(repoCacheEntry);
148 }
149 
150 
151 status_t
152 BPackageRoster::GetRepositoryConfig(const BString& name,
153 	BRepositoryConfig* repositoryConfig)
154 {
155 	if (repositoryConfig == NULL)
156 		return B_BAD_VALUE;
157 
158 	// user path has higher precedence than common path
159 	BPath path;
160 	status_t result = GetUserRepositoryConfigPath(&path);
161 	if (result != B_OK)
162 		return result;
163 	path.Append(name.String());
164 
165 	BEntry repoConfigEntry(path.Path());
166 	if (repoConfigEntry.Exists())
167 		return repositoryConfig->SetTo(repoConfigEntry);
168 
169 	if ((result = GetCommonRepositoryConfigPath(&path)) != B_OK)
170 		return result;
171 	path.Append(name.String());
172 
173 	repoConfigEntry.SetTo(path.Path());
174 	return repositoryConfig->SetTo(repoConfigEntry);
175 }
176 
177 
178 status_t
179 BPackageRoster::_GetRepositoryPath(BPath* path, bool create,
180 	directory_which whichDir) const
181 {
182 	if (path == NULL)
183 		return B_BAD_VALUE;
184 
185 	status_t result = find_directory(whichDir, path);
186 	if (result != B_OK)
187 		return result;
188 	if ((result = path->Append("package-repositories")) != B_OK)
189 		return result;
190 
191 	if (create) {
192 		BEntry entry(path->Path(), true);
193 		if (!entry.Exists()) {
194 			if (mkdir(path->Path(), 0755) != 0)
195 				return errno;
196 		}
197 	}
198 
199 	return B_OK;
200 }
201 
202 
203 status_t
204 BPackageRoster::_VisitRepositoryConfigs(const BPath& path,
205 	BRepositoryConfigVisitor& visitor)
206 {
207 	BDirectory directory(path.Path());
208 	status_t result = directory.InitCheck();
209 	if (result == B_ENTRY_NOT_FOUND)
210 		return B_OK;
211 	if (result != B_OK)
212 		return result;
213 
214 	BEntry entry;
215 	while (directory.GetNextEntry(&entry, true) == B_OK) {
216 		if ((result = visitor(entry)) != B_OK)
217 			return result;
218 	}
219 
220 	return B_OK;
221 }
222 
223 
224 }	// namespace BPackageKit
225