1 /* 2 * Copyright 2018-2024, 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 "PackageKitUtils.h" 17 #include "PackageUtils.h" 18 19 20 #undef B_TRANSLATION_CONTEXT 21 #define B_TRANSLATION_CONTEXT "PopulatePkgSizesProcess" 22 23 24 PopulatePkgSizesProcess::PopulatePkgSizesProcess(Model* model) 25 : 26 fModel(model) 27 { 28 } 29 30 31 PopulatePkgSizesProcess::~PopulatePkgSizesProcess() 32 { 33 } 34 35 36 const char* 37 PopulatePkgSizesProcess::Name() const 38 { 39 return "PopulatePkgSizesProcess"; 40 } 41 42 43 const char* 44 PopulatePkgSizesProcess::Description() const 45 { 46 return B_TRANSLATE("Populating package sizes"); 47 } 48 49 50 status_t 51 PopulatePkgSizesProcess::RunInternal() 52 { 53 int32 countPkgs = 0; 54 int32 countPkgSized = 0; 55 int32 countPkgUnsized = 0; 56 57 HDINFO("[%s] will populate size for pkgs without a size", Name()); 58 59 for (int32 d = 0; d < fModel->CountDepots() && !WasStopped(); d++) { 60 DepotInfoRef depotInfo = fModel->DepotAtIndex(d); 61 countPkgs += depotInfo->CountPackages(); 62 63 for (int32 p = 0; p < depotInfo->CountPackages(); p++) { 64 PackageInfoRef packageInfo = depotInfo->PackageAtIndex(p); 65 66 if (!packageInfo.IsSet()) 67 HDFATAL("package is not set"); 68 69 PackageLocalInfoRef localInfo = PackageUtils::NewLocalInfo(packageInfo); 70 PackageState state = localInfo->State(); 71 72 if (localInfo->Size() <= 0 && (state == ACTIVATED || state == INSTALLED)) { 73 off_t derivedSize = _DeriveSize(packageInfo); 74 75 if (derivedSize > 0) { 76 localInfo->SetSize(derivedSize); 77 countPkgSized++; 78 HDDEBUG("[%s] did derive a size for package [%s]", Name(), 79 packageInfo->Name().String()); 80 } else { 81 countPkgUnsized++; 82 HDDEBUG("[%s] unable to derive a size for package [%s]", Name(), 83 packageInfo->Name().String()); 84 } 85 } 86 87 packageInfo->SetLocalInfo(localInfo); 88 } 89 } 90 91 HDINFO("[%s] did populate size for %" B_PRId32 " packages with %" B_PRId32 92 " already having a size and %" B_PRId32 " unable to derive a size", 93 Name(), countPkgSized, countPkgs - countPkgSized, countPkgUnsized); 94 95 return B_OK; 96 } 97 98 99 off_t 100 PopulatePkgSizesProcess::_DeriveSize(const PackageInfoRef package) const 101 { 102 BPath path; 103 if (PackageKitUtils::DeriveLocalFilePath(package, path) == B_OK) { 104 BEntry entry(path.Path()); 105 struct stat s = {}; 106 if (entry.GetStat(&s) == B_OK) 107 return s.st_size; 108 else 109 HDDEBUG("unable to get the size of local file [%s]", path.Path()); 110 } else { 111 HDDEBUG("unable to get the local file of package [%s]", package->Name().String()); 112 } 113 return 0; 114 }