1/* 2 * Copyright 2011-2020, 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/RepositoryConfig.h> 12 13#include <stdlib.h> 14 15#include <new> 16 17#include <Directory.h> 18#include <driver_settings.h> 19#include <File.h> 20#include <FindDirectory.h> 21#include <Path.h> 22 23#include <DriverSettings.h> 24 25 26#define STORAGE_VERSION 2 27 28#define KEY_BASE_URL_V1 "url" 29#define KEY_IDENTIFIER_V1 "url" 30 31#define KEY_BASE_URL_V2 "baseurl" 32#define KEY_IDENTIFIER_V2 "identifier" 33#define KEY_IDENTIFIER_V2_ALT "url" 34 // should not be used any more in favour of 'identifier' 35 36#define KEY_PRIORITY "priority" 37#define KEY_CONFIG_VERSION "cfgversion" 38 39namespace BPackageKit { 40 41 42// these are mappings of known legacy identifier URLs that are possibly 43// still present in some installations. These are in pairs; the first 44// being the legacy URL and the next being the replacement. This can 45// be phased out over time. 46 47static const char* kLegacyUrlMappings[] = { 48 "https://eu.hpkg.haiku-os.org/haikuports/master/x86_gcc2/current", 49 "https://hpkg.haiku-os.org/haikuports/master/x86_gcc2/current", 50 "https://eu.hpkg.haiku-os.org/haikuports/master/x86_64/current", 51 "https://hpkg.haiku-os.org/haikuports/master/x86_64/current", 52 NULL, 53 NULL 54}; 55 56 57BRepositoryConfig::BRepositoryConfig() 58 : 59 fInitStatus(B_NO_INIT), 60 fPriority(kUnsetPriority), 61 fIsUserSpecific(false) 62{ 63} 64 65 66BRepositoryConfig::BRepositoryConfig(const BEntry& entry) 67{ 68 SetTo(entry); 69} 70 71 72BRepositoryConfig::BRepositoryConfig(const BString& name, 73 const BString& baseURL, uint8 priority) 74 : 75 fInitStatus(B_OK), 76 fName(name), 77 fBaseURL(baseURL), 78 fPriority(priority), 79 fIsUserSpecific(false) 80{ 81} 82 83 84BRepositoryConfig::~BRepositoryConfig() 85{ 86} 87 88 89status_t 90BRepositoryConfig::Store(const BEntry& entry) const 91{ 92 BFile file(&entry, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); 93 status_t result = file.InitCheck(); 94 if (result != B_OK) 95 return result; 96 97 BString configString; 98 configString << KEY_CONFIG_VERSION << "=" << STORAGE_VERSION << "\n"; 99 configString << "\n"; 100 configString << "# the url where the repository data can be " 101 "accessed.\n"; 102 configString << KEY_BASE_URL_V2 << "=" << fBaseURL << "\n"; 103 configString << "\n"; 104 105 configString << "# an identifier for the repository that is " 106 "consistent across mirrors\n"; 107 if (fIdentifier.IsEmpty()) 108 configString << "# " << KEY_IDENTIFIER_V2 << "=???\n"; 109 else 110 configString << KEY_IDENTIFIER_V2 << "=" << fIdentifier << "\n"; 111 configString << "\n"; 112 113 configString << "# a deprecated copy of the [" 114 << KEY_IDENTIFIER_V2 << "] key above for older os versions\n"; 115 if (fIdentifier.IsEmpty()) 116 configString << "# " << KEY_IDENTIFIER_V2_ALT << "=???\n"; 117 else 118 configString << KEY_IDENTIFIER_V2_ALT << "=" << fIdentifier << "\n"; 119 configString << "\n"; 120 121 configString << KEY_PRIORITY << "=" << fPriority << "\n"; 122 123 int32 size = configString.Length(); 124 if ((result = file.Write(configString.String(), size)) < size) 125 return (result >= 0) ? B_ERROR : result; 126 127 return B_OK; 128} 129 130 131status_t 132BRepositoryConfig::InitCheck() const 133{ 134 return fInitStatus; 135} 136 137 138static const char* 139repository_config_swap_legacy_identifier_v1(const char* identifier) 140{ 141 for (int32 i = 0; kLegacyUrlMappings[i] != NULL; i += 2) { 142 if (strcmp(identifier, kLegacyUrlMappings[i]) == 0) 143 return kLegacyUrlMappings[i + 1]; 144 } 145 return identifier; 146} 147 148 149status_t 150BRepositoryConfig::SetTo(const BEntry& entry) 151{ 152 fEntry = entry; 153 fInitStatus = B_NO_INIT; 154 155 entry_ref ref; 156 status_t result = entry.GetRef(&ref); 157 if (result != B_OK) 158 return result; 159 160 BDriverSettings driverSettings; 161 result = driverSettings.Load(ref); 162 if (result != B_OK) 163 return result; 164 165 const char* version = driverSettings.GetParameterValue(KEY_CONFIG_VERSION); 166 int versionNumber = version == NULL ? 1 : atoi(version); 167 const char *baseUrlKey; 168 const char *identifierKeys[3] = { NULL, NULL, NULL }; 169 170 switch (versionNumber) { 171 case 1: 172 baseUrlKey = KEY_BASE_URL_V1; 173 identifierKeys[0] = KEY_IDENTIFIER_V1; 174 break; 175 case 2: 176 baseUrlKey = KEY_BASE_URL_V2; 177 identifierKeys[0] = KEY_IDENTIFIER_V2; 178 identifierKeys[1] = KEY_IDENTIFIER_V2_ALT; 179 break; 180 default: 181 return B_BAD_DATA; 182 } 183 184 const char* baseUrl = driverSettings.GetParameterValue(baseUrlKey); 185 const char* priorityString = driverSettings.GetParameterValue(KEY_PRIORITY); 186 const char* identifier = NULL; 187 188 for (int32 i = 0; identifier == NULL && identifierKeys[i] != NULL; i++) 189 identifier = driverSettings.GetParameterValue(identifierKeys[i]); 190 191 if (baseUrl == NULL || *baseUrl == '\0') 192 return B_BAD_DATA; 193 if (identifier == NULL || *identifier == '\0') 194 return B_BAD_DATA; 195 196 if (versionNumber == 1) 197 identifier = repository_config_swap_legacy_identifier_v1(identifier); 198 199 fName = entry.Name(); 200 fBaseURL = baseUrl; 201 fPriority = priorityString == NULL 202 ? kUnsetPriority : atoi(priorityString); 203 fIdentifier = identifier; 204 205 BPath userSettingsPath; 206 if (find_directory(B_USER_SETTINGS_DIRECTORY, &userSettingsPath) == B_OK) { 207 BDirectory userSettingsDir(userSettingsPath.Path()); 208 fIsUserSpecific = userSettingsDir.Contains(&entry); 209 } else 210 fIsUserSpecific = false; 211 212 fInitStatus = B_OK; 213 214 return B_OK; 215} 216 217 218const BString& 219BRepositoryConfig::Name() const 220{ 221 return fName; 222} 223 224 225const BString& 226BRepositoryConfig::BaseURL() const 227{ 228 return fBaseURL; 229} 230 231 232const BString& 233BRepositoryConfig::Identifier() const 234{ 235 return fIdentifier; 236} 237 238 239uint8 240BRepositoryConfig::Priority() const 241{ 242 return fPriority; 243} 244 245 246bool 247BRepositoryConfig::IsUserSpecific() const 248{ 249 return fIsUserSpecific; 250} 251 252 253const BEntry& 254BRepositoryConfig::Entry() const 255{ 256 return fEntry; 257} 258 259 260BString 261BRepositoryConfig::PackagesURL() const 262{ 263 if (fBaseURL.IsEmpty()) 264 return BString(); 265 return BString().SetToFormat("%s/packages", fBaseURL.String()); 266} 267 268 269void 270BRepositoryConfig::SetName(const BString& name) 271{ 272 fName = name; 273} 274 275 276void 277BRepositoryConfig::SetBaseURL(const BString& baseURL) 278{ 279 fBaseURL = baseURL; 280} 281 282 283void 284BRepositoryConfig::SetIdentifier(const BString& identifier) 285{ 286 fIdentifier = identifier; 287} 288 289 290void 291BRepositoryConfig::SetPriority(uint8 priority) 292{ 293 fPriority = priority; 294} 295 296 297void 298BRepositoryConfig::SetIsUserSpecific(bool isUserSpecific) 299{ 300 fIsUserSpecific = isUserSpecific; 301} 302 303 304} // namespace BPackageKit 305