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/RepositoryCache.h> 11 12 #include <stdio.h> 13 14 #include <new> 15 16 #include <Directory.h> 17 #include <File.h> 18 #include <FindDirectory.h> 19 #include <Path.h> 20 21 #include <package/hpkg/ErrorOutput.h> 22 #include <package/hpkg/PackageInfoAttributeValue.h> 23 #include <package/hpkg/RepositoryContentHandler.h> 24 #include <package/hpkg/RepositoryReader.h> 25 #include <package/PackageInfo.h> 26 #include <package/RepositoryInfo.h> 27 28 29 namespace BPackageKit { 30 31 32 using namespace BHPKG; 33 34 35 // #pragma mark - RepositoryContentHandler 36 37 38 struct BRepositoryCache::RepositoryContentHandler : BRepositoryContentHandler { 39 RepositoryContentHandler(BRepositoryInfo* repositoryInfo, 40 BPackageInfoSet& packages) 41 : 42 fRepositoryInfo(repositoryInfo), 43 fPackages(packages) 44 { 45 } 46 47 virtual status_t HandleEntry(BPackageEntry* entry) 48 { 49 return B_OK; 50 } 51 52 virtual status_t HandleEntryAttribute(BPackageEntry* entry, 53 BPackageEntryAttribute* attribute) 54 { 55 return B_OK; 56 } 57 58 virtual status_t HandleEntryDone(BPackageEntry* entry) 59 { 60 return B_OK; 61 } 62 63 virtual status_t HandlePackageAttribute( 64 const BPackageInfoAttributeValue& value) 65 { 66 switch (value.attributeID) { 67 case B_PACKAGE_INFO_NAME: 68 fPackageInfo.SetName(value.string); 69 break; 70 71 case B_PACKAGE_INFO_SUMMARY: 72 fPackageInfo.SetSummary(value.string); 73 break; 74 75 case B_PACKAGE_INFO_DESCRIPTION: 76 fPackageInfo.SetDescription(value.string); 77 break; 78 79 case B_PACKAGE_INFO_VENDOR: 80 fPackageInfo.SetVendor(value.string); 81 break; 82 83 case B_PACKAGE_INFO_PACKAGER: 84 fPackageInfo.SetPackager(value.string); 85 break; 86 87 case B_PACKAGE_INFO_FLAGS: 88 fPackageInfo.SetFlags(value.unsignedInt); 89 break; 90 91 case B_PACKAGE_INFO_ARCHITECTURE: 92 fPackageInfo.SetArchitecture( 93 (BPackageArchitecture)value.unsignedInt); 94 break; 95 96 case B_PACKAGE_INFO_VERSION: 97 fPackageInfo.SetVersion(value.version); 98 break; 99 100 case B_PACKAGE_INFO_COPYRIGHTS: 101 fPackageInfo.AddCopyright(value.string); 102 break; 103 104 case B_PACKAGE_INFO_LICENSES: 105 fPackageInfo.AddLicense(value.string); 106 break; 107 108 case B_PACKAGE_INFO_PROVIDES: 109 fPackageInfo.AddProvides(value.resolvable); 110 break; 111 112 case B_PACKAGE_INFO_REQUIRES: 113 fPackageInfo.AddRequires(value.resolvableExpression); 114 break; 115 116 case B_PACKAGE_INFO_SUPPLEMENTS: 117 fPackageInfo.AddSupplements(value.resolvableExpression); 118 break; 119 120 case B_PACKAGE_INFO_CONFLICTS: 121 fPackageInfo.AddConflicts(value.resolvableExpression); 122 break; 123 124 case B_PACKAGE_INFO_FRESHENS: 125 fPackageInfo.AddFreshens(value.resolvableExpression); 126 break; 127 128 case B_PACKAGE_INFO_REPLACES: 129 fPackageInfo.AddReplaces(value.string); 130 break; 131 132 case B_PACKAGE_INFO_URLS: 133 fPackageInfo.AddURL(value.string); 134 break; 135 136 case B_PACKAGE_INFO_SOURCE_URLS: 137 fPackageInfo.AddSourceURL(value.string); 138 break; 139 140 case B_PACKAGE_INFO_INSTALL_PATH: 141 fPackageInfo.SetInstallPath(value.string); 142 break; 143 144 case B_PACKAGE_INFO_CHECKSUM: 145 { 146 fPackageInfo.SetChecksum(value.string); 147 status_t result = fPackageInfo.InitCheck(); 148 if (result != B_OK) 149 return result; 150 151 result = fPackages.AddInfo(fPackageInfo); 152 if (result != B_OK) 153 return result; 154 155 fPackageInfo.Clear(); 156 break; 157 } 158 159 default: 160 return B_BAD_DATA; 161 } 162 163 return B_OK; 164 } 165 166 virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo) 167 { 168 *fRepositoryInfo = repositoryInfo; 169 170 return B_OK; 171 } 172 173 virtual void HandleErrorOccurred() 174 { 175 } 176 177 private: 178 BRepositoryInfo* fRepositoryInfo; 179 BPackageInfo fPackageInfo; 180 BPackageInfoSet& fPackages; 181 }; 182 183 184 // #pragma mark - StandardErrorOutput 185 186 187 class BRepositoryCache::StandardErrorOutput : public BErrorOutput { 188 virtual void PrintErrorVarArgs(const char* format, va_list args) 189 { 190 vfprintf(stderr, format, args); 191 } 192 }; 193 194 195 // #pragma mark - BRepositoryCache 196 197 198 BRepositoryCache::BRepositoryCache() 199 : 200 fIsUserSpecific(false), 201 fPackages() 202 { 203 } 204 205 206 BRepositoryCache::~BRepositoryCache() 207 { 208 } 209 210 211 const BEntry& 212 BRepositoryCache::Entry() const 213 { 214 return fEntry; 215 } 216 217 218 const BRepositoryInfo& 219 BRepositoryCache::Info() const 220 { 221 return fInfo; 222 } 223 224 225 bool 226 BRepositoryCache::IsUserSpecific() const 227 { 228 return fIsUserSpecific; 229 } 230 231 232 void 233 BRepositoryCache::SetIsUserSpecific(bool isUserSpecific) 234 { 235 fIsUserSpecific = isUserSpecific; 236 } 237 238 239 status_t 240 BRepositoryCache::SetTo(const BEntry& entry) 241 { 242 // unset 243 fPackages.MakeEmpty(); 244 fEntry.Unset(); 245 246 // init package info set 247 status_t result = fPackages.Init(); 248 if (result != B_OK) 249 return result; 250 251 // get cache file path 252 fEntry = entry; 253 254 BPath repositoryCachePath; 255 if ((result = entry.GetPath(&repositoryCachePath)) != B_OK) 256 return result; 257 258 // read repository cache 259 StandardErrorOutput errorOutput; 260 BRepositoryReader repositoryReader(&errorOutput); 261 if ((result = repositoryReader.Init(repositoryCachePath.Path())) != B_OK) 262 return result; 263 264 RepositoryContentHandler handler(&fInfo, fPackages); 265 if ((result = repositoryReader.ParseContent(&handler)) != B_OK) 266 return result; 267 268 BPath userSettingsPath; 269 if (find_directory(B_USER_SETTINGS_DIRECTORY, &userSettingsPath) == B_OK) { 270 BDirectory userSettingsDir(userSettingsPath.Path()); 271 fIsUserSpecific = userSettingsDir.Contains(&entry); 272 } else 273 fIsUserSpecific = false; 274 275 return B_OK; 276 } 277 278 279 uint32 280 BRepositoryCache::CountPackages() const 281 { 282 return fPackages.CountInfos(); 283 } 284 285 286 BRepositoryCache::Iterator 287 BRepositoryCache::GetIterator() const 288 { 289 return fPackages.GetIterator(); 290 } 291 292 293 } // namespace BPackageKit 294