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