vfs: check userland buffers before reading them.
[haiku.git] / src / apps / haikudepot / server / ServerIconExportUpdateProcess.cpp
blob5d434c9a3505b6e0cfae783f1c935c762a78a4b0
1 /*
2 * Copyright 2017, Andrew Lindesay <apl@lindesay.co.nz>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
6 #include "ServerIconExportUpdateProcess.h"
8 #include <stdio.h>
9 #include <sys/stat.h>
10 #include <time.h>
12 #include <Autolock.h>
13 #include <FileIO.h>
14 #include <support/StopWatch.h>
15 #include <support/ZlibCompressionAlgorithm.h>
17 #include "Logger.h"
18 #include "ServerSettings.h"
19 #include "StorageUtils.h"
20 #include "TarArchiveService.h"
23 /*! This constructor will locate the cached data in a standardized location */
25 ServerIconExportUpdateProcess::ServerIconExportUpdateProcess(
26 AbstractServerProcessListener* listener,
27 const BPath& localStorageDirectoryPath,
28 Model* model,
29 uint32 options)
31 AbstractServerProcess(listener, options),
32 fLocalStorageDirectoryPath(localStorageDirectoryPath),
33 fModel(model),
34 fLocalIconStore(LocalIconStore(localStorageDirectoryPath)),
35 fCountIconsSet(0)
40 ServerIconExportUpdateProcess::~ServerIconExportUpdateProcess()
45 const char*
46 ServerIconExportUpdateProcess::Name()
48 return "ServerIconExportUpdateProcess";
52 status_t
53 ServerIconExportUpdateProcess::RunInternal()
55 status_t result = B_OK;
57 if (IsSuccess(result) && HasOption(SERVER_PROCESS_DROP_CACHE)) {
58 result = StorageUtils::RemoveDirectoryContents(
59 fLocalStorageDirectoryPath);
62 if (IsSuccess(result)) {
63 bool hasData;
65 result = HasLocalData(&hasData);
67 if (IsSuccess(result) && ShouldAttemptNetworkDownload(hasData))
68 result = DownloadAndUnpack();
70 if (IsSuccess(result)) {
71 status_t hasDataResult = HasLocalData(&hasData);
73 if (IsSuccess(hasDataResult) && !hasData)
74 result = APP_ERR_NO_DATA;
78 if (IsSuccess(result) && !WasStopped())
79 result = Populate();
81 return result;
85 status_t
86 ServerIconExportUpdateProcess::PopulateForPkg(const PackageInfoRef& package)
88 BPath bestIconPath;
90 if ( fLocalIconStore.TryFindIconPath(
91 package->Name(), bestIconPath) == B_OK) {
93 BFile bestIconFile(bestIconPath.Path(), O_RDONLY);
94 BitmapRef bitmapRef(new(std::nothrow)SharedBitmap(bestIconFile), true);
95 // TODO; somehow handle the locking!
96 //BAutolock locker(&fLock);
97 package->SetIcon(bitmapRef);
99 if (Logger::IsDebugEnabled()) {
100 fprintf(stdout, "have set the package icon for [%s] from [%s]\n",
101 package->Name().String(), bestIconPath.Path());
104 fCountIconsSet++;
106 return B_OK;
109 if (Logger::IsDebugEnabled()) {
110 fprintf(stdout, "did not set the package icon for [%s]; no data\n",
111 package->Name().String());
114 return B_FILE_NOT_FOUND;
118 bool
119 ServerIconExportUpdateProcess::ConsumePackage(
120 const PackageInfoRef& packageInfoRef, void* context)
122 PopulateForPkg(packageInfoRef);
123 return !WasStopped();
127 status_t
128 ServerIconExportUpdateProcess::Populate()
130 BStopWatch watch("ServerIconExportUpdateProcess::Populate", true);
131 fModel->ForAllPackages(this, NULL);
133 if (Logger::IsInfoEnabled()) {
134 double secs = watch.ElapsedTime() / 1000000.0;
135 fprintf(stdout, "did populate %" B_PRId32 " packages' icons"
136 " (%6.3g secs)\n", fCountIconsSet, secs);
139 return B_OK;
143 status_t
144 ServerIconExportUpdateProcess::DownloadAndUnpack()
146 BPath tarGzFilePath(tmpnam(NULL));
147 status_t result = B_OK;
149 printf("will start fetching icons\n");
151 result = Download(tarGzFilePath);
153 if (result != APP_ERR_NOT_MODIFIED) {
154 if (result != B_OK)
155 return result;
157 printf("delete any existing stored data\n");
158 StorageUtils::RemoveDirectoryContents(fLocalStorageDirectoryPath);
160 BFile *tarGzFile = new BFile(tarGzFilePath.Path(), O_RDONLY);
161 BDataIO* tarIn;
163 BZlibDecompressionParameters* zlibDecompressionParameters
164 = new BZlibDecompressionParameters();
166 result = BZlibCompressionAlgorithm()
167 .CreateDecompressingInputStream(tarGzFile,
168 zlibDecompressionParameters, tarIn);
170 if (result == B_OK) {
171 BStopWatch watch("ServerIconExportUpdateProcess::DownloadAndUnpack_Unpack", true);
173 result = TarArchiveService::Unpack(*tarIn,
174 fLocalStorageDirectoryPath, NULL);
176 if (result == B_OK) {
177 double secs = watch.ElapsedTime() / 1000000.0;
178 fprintf(stdout, "did unpack icon tgz in (%6.3g secs)\n", secs);
180 if (0 != remove(tarGzFilePath.Path())) {
181 fprintf(stdout, "unable to delete the temporary tgz path; "
182 "%s\n", tarGzFilePath.Path());
187 delete tarGzFile;
190 printf("did complete fetching icons\n");
192 return result;
196 status_t
197 ServerIconExportUpdateProcess::HasLocalData(bool* result) const
199 BPath path;
200 off_t size;
201 GetStandardMetaDataPath(path);
202 return StorageUtils::ExistsObject(path, result, NULL, &size)
203 && size > 0;
207 void
208 ServerIconExportUpdateProcess::GetStandardMetaDataPath(BPath& path) const
210 path.SetTo(fLocalStorageDirectoryPath.Path());
211 path.Append("hicn/info.json");
215 void
216 ServerIconExportUpdateProcess::GetStandardMetaDataJsonPath(
217 BString& jsonPath) const
219 // the "$" here indicates that the data is at the top level.
220 jsonPath.SetTo("$");
224 status_t
225 ServerIconExportUpdateProcess::Download(BPath& tarGzFilePath)
227 return DownloadToLocalFileAtomically(tarGzFilePath,
228 ServerSettings::CreateFullUrl("/__pkgicon/all.tar.gz"));