1 /* 2 * Copyright 2011-2015, 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/RefreshRepositoryRequest.h> 11 12 #include <Directory.h> 13 #include <Path.h> 14 15 #include <JobQueue.h> 16 17 #include <package/ActivateRepositoryCacheJob.h> 18 #include <package/ChecksumAccessors.h> 19 #include <package/ValidateChecksumJob.h> 20 #include <package/FetchFileJob.h> 21 #include <package/RepositoryCache.h> 22 #include <package/RepositoryConfig.h> 23 #include <package/PackageRoster.h> 24 25 26 namespace BPackageKit { 27 28 29 using namespace BPrivate; 30 31 32 BRefreshRepositoryRequest::BRefreshRepositoryRequest(const BContext& context, 33 const BRepositoryConfig& repoConfig) 34 : 35 inherited(context), 36 fRepoConfig(repoConfig) 37 { 38 } 39 40 41 BRefreshRepositoryRequest::~BRefreshRepositoryRequest() 42 { 43 } 44 45 46 status_t 47 BRefreshRepositoryRequest::CreateInitialJobs() 48 { 49 status_t result = InitCheck(); 50 if (result != B_OK) 51 return B_NO_INIT; 52 53 if ((result = fRepoConfig.InitCheck()) != B_OK) 54 return result; 55 56 // fetch the current checksum and compare with our cache's checksum, 57 // if they differ, fetch the updated cache 58 result = fContext.GetNewTempfile("repochecksum-", &fFetchedChecksumFile); 59 if (result != B_OK) 60 return result; 61 BString repoChecksumURL 62 = BString(fRepoConfig.BaseURL()) << "/" << "repo.sha256"; 63 FetchFileJob* fetchChecksumJob = new (std::nothrow) FetchFileJob( 64 fContext, 65 BString("Fetching repository checksum from ") << fRepoConfig.BaseURL(), 66 repoChecksumURL, fFetchedChecksumFile); 67 if (fetchChecksumJob == NULL) 68 return B_NO_MEMORY; 69 if ((result = QueueJob(fetchChecksumJob)) != B_OK) { 70 delete fetchChecksumJob; 71 return result; 72 } 73 74 BRepositoryCache repoCache; 75 BPackageRoster roster; 76 roster.GetRepositoryCache(fRepoConfig.Name(), &repoCache); 77 78 ValidateChecksumJob* validateChecksumJob 79 = new (std::nothrow) ValidateChecksumJob(fContext, 80 BString("Validating checksum for ") << fRepoConfig.Name(), 81 new (std::nothrow) ChecksumFileChecksumAccessor( 82 fFetchedChecksumFile), 83 new (std::nothrow) GeneralFileChecksumAccessor(repoCache.Entry(), 84 true), 85 false); 86 if (validateChecksumJob == NULL) 87 return B_NO_MEMORY; 88 validateChecksumJob->AddDependency(fetchChecksumJob); 89 if ((result = QueueJob(validateChecksumJob)) != B_OK) { 90 delete validateChecksumJob; 91 return result; 92 } 93 fValidateChecksumJob = validateChecksumJob; 94 95 return B_OK; 96 } 97 98 99 void 100 BRefreshRepositoryRequest::JobSucceeded(BSupportKit::BJob* job) 101 { 102 if (job == fValidateChecksumJob 103 && !fValidateChecksumJob->ChecksumsMatch()) { 104 // the remote repo cache has a different checksum, we fetch it 105 fValidateChecksumJob = NULL; 106 // don't re-trigger fetching if anything goes wrong, fail instead 107 _FetchRepositoryCache(); 108 } 109 } 110 111 112 status_t 113 BRefreshRepositoryRequest::_FetchRepositoryCache() 114 { 115 // download repository cache and put it in either the common/user cache 116 // path, depending on where the corresponding repo-config lives 117 118 // job fetching the cache 119 BEntry tempRepoCache; 120 status_t result = fContext.GetNewTempfile("repocache-", &tempRepoCache); 121 if (result != B_OK) 122 return result; 123 BString repoCacheURL = BString(fRepoConfig.BaseURL()) << "/" << "repo"; 124 FetchFileJob* fetchCacheJob = new (std::nothrow) FetchFileJob(fContext, 125 BString("Fetching repository-cache from ") << fRepoConfig.BaseURL(), 126 repoCacheURL, tempRepoCache); 127 if (fetchCacheJob == NULL) 128 return B_NO_MEMORY; 129 if ((result = QueueJob(fetchCacheJob)) != B_OK) { 130 delete fetchCacheJob; 131 return result; 132 } 133 134 // job validating the cache's checksum 135 ValidateChecksumJob* validateChecksumJob 136 = new (std::nothrow) ValidateChecksumJob(fContext, 137 BString("Validating checksum for ") << fRepoConfig.Name(), 138 new (std::nothrow) ChecksumFileChecksumAccessor( 139 fFetchedChecksumFile), 140 new (std::nothrow) GeneralFileChecksumAccessor(tempRepoCache)); 141 if (validateChecksumJob == NULL) 142 return B_NO_MEMORY; 143 validateChecksumJob->AddDependency(fetchCacheJob); 144 if ((result = QueueJob(validateChecksumJob)) != B_OK) { 145 delete validateChecksumJob; 146 return result; 147 } 148 149 // job activating the cache 150 BPath targetRepoCachePath; 151 BPackageRoster roster; 152 result = fRepoConfig.IsUserSpecific() 153 ? roster.GetUserRepositoryCachePath(&targetRepoCachePath, true) 154 : roster.GetCommonRepositoryCachePath(&targetRepoCachePath, true); 155 if (result != B_OK) 156 return result; 157 BDirectory targetDirectory(targetRepoCachePath.Path()); 158 ActivateRepositoryCacheJob* activateJob 159 = new (std::nothrow) ActivateRepositoryCacheJob(fContext, 160 BString("Activating repository cache for ") << fRepoConfig.Name(), 161 tempRepoCache, fRepoConfig.Name(), targetDirectory); 162 if (activateJob == NULL) 163 return B_NO_MEMORY; 164 activateJob->AddDependency(validateChecksumJob); 165 if ((result = QueueJob(activateJob)) != B_OK) { 166 delete activateJob; 167 return result; 168 } 169 170 return B_OK; 171 } 172 173 174 } // namespace BPackageKit 175