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 39 namespace 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 47 static 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 57 BRepositoryConfig::BRepositoryConfig() 58 : 59 fInitStatus(B_NO_INIT), 60 fPriority(kUnsetPriority), 61 fIsUserSpecific(false) 62 { 63 } 64 65 66 BRepositoryConfig::BRepositoryConfig(const BEntry& entry) 67 { 68 SetTo(entry); 69 } 70 71 72 BRepositoryConfig::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 84 BRepositoryConfig::~BRepositoryConfig() 85 { 86 } 87 88 89 status_t 90 BRepositoryConfig::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 131 status_t 132 BRepositoryConfig::InitCheck() const 133 { 134 return fInitStatus; 135 } 136 137 138 static const char* 139 repository_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 149 status_t 150 BRepositoryConfig::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 218 const BString& 219 BRepositoryConfig::Name() const 220 { 221 return fName; 222 } 223 224 225 const BString& 226 BRepositoryConfig::BaseURL() const 227 { 228 return fBaseURL; 229 } 230 231 232 const BString& 233 BRepositoryConfig::Identifier() const 234 { 235 return fIdentifier; 236 } 237 238 239 uint8 240 BRepositoryConfig::Priority() const 241 { 242 return fPriority; 243 } 244 245 246 bool 247 BRepositoryConfig::IsUserSpecific() const 248 { 249 return fIsUserSpecific; 250 } 251 252 253 const BEntry& 254 BRepositoryConfig::Entry() const 255 { 256 return fEntry; 257 } 258 259 260 BString 261 BRepositoryConfig::PackagesURL() const 262 { 263 if (fBaseURL.IsEmpty()) 264 return BString(); 265 return BString().SetToFormat("%s/packages", fBaseURL.String()); 266 } 267 268 269 void 270 BRepositoryConfig::SetName(const BString& name) 271 { 272 fName = name; 273 } 274 275 276 void 277 BRepositoryConfig::SetBaseURL(const BString& baseURL) 278 { 279 fBaseURL = baseURL; 280 } 281 282 283 void 284 BRepositoryConfig::SetIdentifier(const BString& identifier) 285 { 286 fIdentifier = identifier; 287 } 288 289 290 void 291 BRepositoryConfig::SetPriority(uint8 priority) 292 { 293 fPriority = priority; 294 } 295 296 297 void 298 BRepositoryConfig::SetIsUserSpecific(bool isUserSpecific) 299 { 300 fIsUserSpecific = isUserSpecific; 301 } 302 303 304 } // namespace BPackageKit 305