1/* 2 * Copyright 2018-2023, Andrew Lindesay <apl@lindesay.co.nz>. 3 4 * All rights reserved. Distributed under the terms of the MIT License. 5 * 6 * Note that this file included code earlier from `MainWindow.cpp` and 7 * copyrights have been latterly been carried across in 2021. 8 */ 9 10 11#include "PopulatePkgSizesProcess.h" 12 13#include <Catalog.h> 14 15#include "Logger.h" 16#include "PackageUtils.h" 17 18 19#undef B_TRANSLATION_CONTEXT 20#define B_TRANSLATION_CONTEXT "PopulatePkgSizesProcess" 21 22 23PopulatePkgSizesProcess::PopulatePkgSizesProcess(Model* model) 24 : 25 fModel(model) 26{ 27} 28 29 30PopulatePkgSizesProcess::~PopulatePkgSizesProcess() 31{ 32} 33 34 35const char* 36PopulatePkgSizesProcess::Name() const 37{ 38 return "PopulatePkgSizesProcess"; 39} 40 41 42const char* 43PopulatePkgSizesProcess::Description() const 44{ 45 return B_TRANSLATE("Populating package sizes"); 46} 47 48 49status_t 50PopulatePkgSizesProcess::RunInternal() 51{ 52 int32 countPkgs = 0; 53 int32 countPkgSized = 0; 54 int32 countPkgUnsized = 0; 55 56 HDINFO("[%s] will populate size for pkgs without a size", Name()); 57 58 for (int32 d = 0; d < fModel->CountDepots() && !WasStopped(); d++) { 59 DepotInfoRef depotInfo = fModel->DepotAtIndex(d); 60 countPkgs += depotInfo->CountPackages(); 61 62 for (int32 p = 0; p < depotInfo->CountPackages(); p++) { 63 PackageInfoRef packageInfo = depotInfo->PackageAtIndex(p); 64 PackageState state = packageInfo->State(); 65 66 if (packageInfo->Size() <= 0 67 && (state == ACTIVATED || state == INSTALLED)) { 68 off_t derivedSize = _DeriveSize(packageInfo); 69 70 if (derivedSize > 0) { 71 packageInfo->SetSize(derivedSize); 72 countPkgSized++; 73 HDDEBUG("[%s] did derive a size for package [%s]", 74 Name(), packageInfo->Name().String()); 75 } else { 76 countPkgUnsized++; 77 HDDEBUG("[%s] unable to derive a size for package [%s]", 78 Name(), packageInfo->Name().String()); 79 } 80 } 81 } 82 } 83 84 HDINFO("[%s] did populate size for %" B_PRId32 " packages with %" B_PRId32 85 " already having a size and %" B_PRId32 " unable to derive a size", 86 Name(), countPkgSized, countPkgs - countPkgSized, countPkgUnsized); 87 88 return B_OK; 89} 90 91 92off_t 93PopulatePkgSizesProcess::_DeriveSize(const PackageInfoRef package) const 94{ 95 BPath path; 96 if (PackageUtils::DeriveLocalFilePath(package.Get(), path) == B_OK) { 97 BEntry entry(path.Path()); 98 struct stat s = {}; 99 if (entry.GetStat(&s) == B_OK) 100 return s.st_size; 101 else 102 HDDEBUG("unable to get the size of local file [%s]", path.Path()); 103 } else 104 HDDEBUG("unable to get the local file of package [%s]", package->Name().String()); 105 return 0; 106}