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 23 PopulatePkgSizesProcess::PopulatePkgSizesProcess(Model* model) 24 : 25 fModel(model) 26 { 27 } 28 29 30 PopulatePkgSizesProcess::~PopulatePkgSizesProcess() 31 { 32 } 33 34 35 const char* 36 PopulatePkgSizesProcess::Name() const 37 { 38 return "PopulatePkgSizesProcess"; 39 } 40 41 42 const char* 43 PopulatePkgSizesProcess::Description() const 44 { 45 return B_TRANSLATE("Populating package sizes"); 46 } 47 48 49 status_t 50 PopulatePkgSizesProcess::RunInternal() 51 { 52 int countPkgs = 0; 53 int countPkgSized = 0; 54 int 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 92 off_t 93 PopulatePkgSizesProcess::_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 }