aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose Alonso Cardenas Marquez <acm@FreeBSD.org>2024-06-13 00:08:35 +0000
committerJose Alonso Cardenas Marquez <acm@FreeBSD.org>2024-06-13 00:08:35 +0000
commit539c968785234fe925d0795081280c9689207d0b (patch)
tree2be24f7781c4bdd151f99c90d1e93f074c40e7e1
parent59d2347ed426d4cf1c99475c910fd30fe7670b5e (diff)
downloadports-539c968785234fe925d0795081280c9689207d0b.tar.gz
ports-539c968785234fe925d0795081280c9689207d0b.zip
sysutils/libsysstat-qt6: New port: Library used to query system info and statistics ported to qt6
Qt-based library to query system information like CPU, memory usage and network traffic. PR: 278905 Approved by: jsm
-rw-r--r--sysutils/Makefile2
-rw-r--r--sysutils/libsysstat-qt6/Makefile21
-rw-r--r--sysutils/libsysstat-qt6/distinfo3
-rw-r--r--sysutils/libsysstat-qt6/files/config.h.in3
-rw-r--r--sysutils/libsysstat-qt6/files/patch-CMakeLists.txt32
-rw-r--r--sysutils/libsysstat-qt6/files/patch-cpustat.cpp307
-rw-r--r--sysutils/libsysstat-qt6/files/patch-cpustat.h32
-rw-r--r--sysutils/libsysstat-qt6/files/patch-cpustat__p.h65
-rw-r--r--sysutils/libsysstat-qt6/files/patch-memstat.cpp123
-rw-r--r--sysutils/libsysstat-qt6/files/patch-memstat.h26
-rw-r--r--sysutils/libsysstat-qt6/files/patch-netstat.cpp122
-rw-r--r--sysutils/libsysstat-qt6/pkg-descr2
-rw-r--r--sysutils/libsysstat-qt6/pkg-plist20
13 files changed, 758 insertions, 0 deletions
diff --git a/sysutils/Makefile b/sysutils/Makefile
index 25665d4d2792..2d0debe2cc0e 100644
--- a/sysutils/Makefile
+++ b/sysutils/Makefile
@@ -680,6 +680,7 @@
SUBDIR += libptytty
SUBDIR += libsunacl
SUBDIR += libsysstat
+ SUBDIR += libsysstat-qt6
SUBDIR += libtpms
SUBDIR += libtree
SUBDIR += libudisks
@@ -727,6 +728,7 @@
SUBDIR += lxqt-config
SUBDIR += lxqt-policykit
SUBDIR += lxqt-powermanagement
+ SUBDIR += lxqt-qt6plugin
SUBDIR += lxqt-qtplugin
SUBDIR += lxsplit
SUBDIR += lxtask
diff --git a/sysutils/libsysstat-qt6/Makefile b/sysutils/libsysstat-qt6/Makefile
new file mode 100644
index 000000000000..ccf52c2b58bf
--- /dev/null
+++ b/sysutils/libsysstat-qt6/Makefile
@@ -0,0 +1,21 @@
+PORTNAME= libsysstat
+PORTVERSION= 1.0.0
+CATEGORIES= sysutils
+PKGNAMESUFFIX= -qt6
+
+MAINTAINER= lxqt@FreeBSD.org
+COMMENT= Library used to query system info and statistics ported to qt6
+WWW= https://lxqt-project.org
+
+LICENSE= LGPL21+
+LICENSE_FILE= ${WRKSRC}/COPYING
+
+USES= cmake compiler:c++17-lang lxqt:2 pkgconfig tar:xz qt:6
+USE_QT= base:run tools:build
+USE_LDCONFIG= yes
+USE_LXQT= buildtools2
+
+post-extract:
+ @${CP} ${FILESDIR}/config.h.in ${WRKSRC}
+
+.include <bsd.port.mk>
diff --git a/sysutils/libsysstat-qt6/distinfo b/sysutils/libsysstat-qt6/distinfo
new file mode 100644
index 000000000000..52a3d64cabac
--- /dev/null
+++ b/sysutils/libsysstat-qt6/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1714103030
+SHA256 (lxqt/libsysstat-1.0.0.tar.xz) = f79b5e3e2e79a52b58fab5639f11b7a5f40e4a9995660181712cb4c4cd460435
+SIZE (lxqt/libsysstat-1.0.0.tar.xz) = 17684
diff --git a/sysutils/libsysstat-qt6/files/config.h.in b/sysutils/libsysstat-qt6/files/config.h.in
new file mode 100644
index 000000000000..05211acde503
--- /dev/null
+++ b/sysutils/libsysstat-qt6/files/config.h.in
@@ -0,0 +1,3 @@
+#cmakedefine HAVE_SYSCTL_H
+#cmakedefine HAVE_IF_H
+#cmakedefine HAVE_KVM_H
diff --git a/sysutils/libsysstat-qt6/files/patch-CMakeLists.txt b/sysutils/libsysstat-qt6/files/patch-CMakeLists.txt
new file mode 100644
index 000000000000..985c523ebf7b
--- /dev/null
+++ b/sysutils/libsysstat-qt6/files/patch-CMakeLists.txt
@@ -0,0 +1,32 @@
+--- CMakeLists.txt.orig 2024-04-17 05:57:59.000000000 -0500
++++ CMakeLists.txt 2024-04-25 13:02:12.269260000 -0500
+@@ -28,6 +28,16 @@
+ include(LXQtCreatePortableHeaders)
+ include(LXQtCompilerSettings NO_POLICY_SCOPE)
+
++if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
++include(CheckIncludeFiles)
++include(CheckLibraryExists)
++check_include_files("sys/socket.h;net/if.h;net/if_mib.h;net/if_types.h" HAVE_IF_H)
++check_library_exists(kvm kvm_getswapinfo "kvm.h" HAVE_KVM_H)
++check_library_exists(c sysctlbyname "sys/sysctl.h" HAVE_SYSCTL_H)
++configure_file(config.h.in config.h)
++add_definitions("-DHAVE_CONFIG_H=1")
++endif()
++
+ set(CMAKE_AUTOMOC ON)
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+@@ -80,7 +90,11 @@
+ ${SYSSTAT_QM_FILES}
+ )
+
+-target_link_libraries(${SYSSTAT_LIBRARY_NAME} Qt6::Core)
++if(HAVE_SYSCTL_H AND HAVE_KVM_H)
++ target_link_libraries(${SYSSTAT_LIBRARY_NAME} c kvm Qt6::Core)
++else()
++ target_link_libraries(${SYSSTAT_LIBRARY_NAME} Qt6::Core)
++endif()
+
+ set_target_properties(${SYSSTAT_LIBRARY_NAME} PROPERTIES
+ VERSION ${SYSSTAT_VERSION}
diff --git a/sysutils/libsysstat-qt6/files/patch-cpustat.cpp b/sysutils/libsysstat-qt6/files/patch-cpustat.cpp
new file mode 100644
index 000000000000..8ead007be490
--- /dev/null
+++ b/sysutils/libsysstat-qt6/files/patch-cpustat.cpp
@@ -0,0 +1,307 @@
+--- cpustat.cpp.orig 2021-11-05 10:06:40 UTC
++++ cpustat.cpp
+@@ -22,16 +22,65 @@
+ ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ **
+ ** END_COMMON_COPYRIGHT_HEADER */
+-
+-
+ #include <unistd.h>
+-
+ #include "cpustat.h"
++#ifdef HAVE_SYSCTL_H
++extern "C"
++{
++ #include <stdlib.h>
++ #include <limits.h>
++ #include <string.h>
++ #include <sys/resource.h> /* CPUSTATES */
++
++ #include <sys/types.h>
++ #include <sys/sysctl.h>
++}
++#endif
+ #include "cpustat_p.h"
+
+
+ namespace SysStat {
++#ifdef HAVE_SYSCTL_H
++char *GetFirstFragment(char *string, const char *delim)
++{
++ char *token = NULL;
+
++ token = strsep(&string, delim);
++ if (token != NULL)
++ {
++ /* We need only the first fragment, so no loop! */
++ return token;
++ }
++ else
++ return NULL;
++}
++
++int GetCpu(void)
++{
++ static int mib[] = { CTL_HW, HW_NCPU };
++ int buf;
++ size_t len = sizeof(int);
++
++ if (sysctl(mib, 2, &buf, &len, NULL, 0) < 0)
++ return 0;
++ else
++ return buf;
++}
++
++/* Frequence is in MHz */
++ulong CpuStatPrivate::CurrentFreq(QString mSource)
++{
++ ulong freq=0;
++ size_t len = sizeof(freq);
++ int i = mSource.mid(3).toInt();
++ if (sysctl(mib2[i],4,&freq, &len, NULL, 0) < 0) {
++ perror("sysctl");
++ return 0;
++ }
++ else
++ return freq;
++}
++#endif
+ CpuStatPrivate::CpuStatPrivate(CpuStat *parent)
+ : BaseStatPrivate(parent)
+ , mMonitoring(CpuStat::LoadAndFrequency)
+@@ -39,7 +88,17 @@ CpuStatPrivate::CpuStatPrivate(CpuStat *parent)
+ mSource = defaultSource();
+
+ connect(mTimer, SIGNAL(timeout()), SLOT(timeout()));
+-
++#ifdef HAVE_SYSCTL_H
++ size_t flen=2;
++ size_t alen=4;
++ sysctlnametomib("kern.cp_times",mib0,&flen);
++ sysctlnametomib("kern.cp_time",mib1,&flen);
++ int ncpu = GetCpu();
++ for (int i=0;i<ncpu;i++) {
++ QString cpu_sysctl_name = QString::fromLatin1("dev.cpu.%1.freq").arg(i);
++ sysctlnametomib(cpu_sysctl_name.toStdString().c_str(),mib2[i],&alen);
++ }
++#endif
+ mUserHz = sysconf(_SC_CLK_TCK);
+
+ updateSources();
+@@ -47,6 +106,51 @@ CpuStatPrivate::CpuStatPrivate(CpuStat *parent)
+
+ void CpuStatPrivate::addSource(const QString &source)
+ {
++#ifdef HAVE_SYSCTL_H
++ char buf[1024];
++ char *tokens, *t;
++ ulong min = 0, max = 0;
++ size_t len = sizeof(buf);
++
++ /* The string returned by the dev.cpu.0.freq_levels sysctl
++ * is a space separated list of MHz/milliwatts.
++ */
++ if (source != QStringLiteral("cpu") && source.mid(0,3).toInt() >-1) {
++
++ if (sysctlbyname(QString::fromLatin1("dev.cpu.%1.freq_levels").arg(source.mid(0,3).toInt()).toStdString().c_str(), buf, &len, NULL, 0) < 0)
++ return;
++ }
++ t = strndup(buf, len);
++ if (t == NULL)
++ {
++ free(t);
++ return;
++ }
++ while ((tokens = strsep(&t, " ")) != NULL)
++ {
++ char *freq;
++ ulong res;
++
++ freq = GetFirstFragment(tokens, "/");
++ if (freq != NULL)
++ {
++ res = strtoul(freq, &freq, 10);
++ if (res > max)
++ {
++ max = res;
++ }
++ else
++ {
++ if ((min == 0) || (res < min))
++ min = res;
++ }
++ }
++
++ }
++
++ free(t);
++ mBounds[source] = qMakePair(min, max);
++#else
+ bool ok = false;
+
+ uint min = readAllFile(qPrintable(QString::fromLatin1("/sys/devices/system/cpu/%1/cpufreq/scaling_min_freq").arg(source))).toUInt(&ok);
+@@ -56,11 +160,34 @@ void CpuStatPrivate::addSource(const QString &source)
+ if (ok)
+ mBounds[source] = qMakePair(min, max);
+ }
++#endif
+ }
+
+ void CpuStatPrivate::updateSources()
+ {
+ mSources.clear();
++#ifdef HAVE_SYSCTL_H
++ mBounds.clear();
++ int cpu;
++
++ cpu = GetCpu();
++ mSources.append(QString::fromLatin1("cpu"));
++ for (int i =0;i<cpu;i++)
++ {
++ mSources.append(QString::fromLatin1("cpu%1").arg(i));
++ addSource(QString::fromLatin1("cpu%1").arg(i));
++ }
++ long max=0;
++ long min=0;
++ for (Bounds::ConstIterator I = mBounds.constBegin(); I != mBounds.constEnd(); ++I)
++ {
++ min += mBounds[I.key()].first;
++ max += mBounds[I.key()].second;
++
++ }
++
++ mBounds[QStringLiteral("cpu")] = qMakePair(min,max);
++#else
+ const QStringList rows = readAllFile("/proc/stat").split(QLatin1Char('\n'), Qt::SkipEmptyParts);
+ for (const QString &row : rows)
+ {
+@@ -98,6 +225,7 @@ void CpuStatPrivate::updateSources()
+ addSource(QString::fromLatin1("cpu%1").arg(number));
+ }
+ }
++#endif
+ }
+
+ CpuStatPrivate::~CpuStatPrivate() = default;
+@@ -124,6 +252,113 @@ void CpuStatPrivate::recalculateMinMax()
+
+ void CpuStatPrivate::timeout()
+ {
++#ifdef HAVE_SYSCTL_H
++ if ( (mMonitoring == CpuStat::LoadOnly)
++ || (mMonitoring == CpuStat::LoadAndFrequency) )
++ {
++ int cpuNumber=0;
++ long *cp_times=0;
++
++ if(mSource!=QLatin1String("cpu"))
++ {
++ size_t cp_size = sizeof(long) * CPUSTATES * GetCpu();
++ cp_times = (long *)malloc(cp_size);
++ cpuNumber = mSource.mid(0,3).toInt();
++ if (sysctl(mib0,2, cp_times, &cp_size, NULL, 0) < 0)
++ free(cp_times);
++ } else {
++ size_t cp_size = sizeof(long)*CPUSTATES;
++ cp_times = (long *)malloc(cp_size);
++ if(sysctl(mib1,2,cp_times,&cp_size,NULL,0) < 0)
++ {
++ perror("sysctl");
++ free(cp_times);
++ }
++ }
++ Values current;
++ current.user = static_cast<ulong>(cp_times[CP_USER+cpuNumber*CPUSTATES]);
++ current.nice = static_cast<ulong>(cp_times[CP_NICE+cpuNumber*CPUSTATES]);
++ current.system = static_cast<ulong>(cp_times[CP_SYS+cpuNumber*CPUSTATES]);
++ current.idle = static_cast<ulong>(cp_times[CP_IDLE+cpuNumber*CPUSTATES]);
++ current.other = static_cast<ulong>(cp_times[CP_INTR+cpuNumber*CPUSTATES]);
++ current.total = current.user + current.nice + current.system+current.idle+current.other;
++ float sumDelta = static_cast<float>(current.total - mPrevious.total);
++ if ((mPrevious.total != 0) && ((sumDelta < mIntervalMin) || (sumDelta > mIntervalMax)))
++ {
++ if (mMonitoring == CpuStat::LoadAndFrequency)
++ {
++ float freqRate = 1.0;
++ ulong freq = CurrentFreq(mSource);
++
++ if (mSource == QLatin1String("cpu")) {
++ freq=0;
++ for (Bounds::ConstIterator I = mBounds.constBegin(); I != mBounds.constEnd(); ++I) {
++ if (I.key() != QStringLiteral("cpu"))
++ {
++ freq += CurrentFreq(I.key());
++ }
++ }
++ }
++
++ if (freq > 0)
++ {
++ freqRate = static_cast<float>(freq) / static_cast<float>(mBounds[mSource].second);
++ emit update(0.0, 0.0, 0.0, 0.0, static_cast<float>(freqRate), freq);
++ }
++ } else {
++ emit update(0.0, 0.0, 0.0, 0.0);
++ }
++ mPrevious.clear();
++ } else {
++ if (mMonitoring == CpuStat::LoadAndFrequency)
++ {
++ float freqRate = 1.0;
++ ulong freq = CurrentFreq(mSource);
++
++ if (freq > 0)
++ {
++ if (mSource == QLatin1String("cpu")) {
++ freq=0;
++ for (Bounds::ConstIterator I = mBounds.constBegin(); I != mBounds.constEnd(); ++I) {
++ if (I.key() != QStringLiteral("cpu"))
++ {
++ freq += CurrentFreq(I.key());
++ }
++ }
++ }
++ freqRate = static_cast<float>(freq) / static_cast<float>(mBounds[mSource].second);
++ emit update(
++ static_cast<float>(current.user - mPrevious.user ) / sumDelta,
++ static_cast<float>(current.nice - mPrevious.nice ) / sumDelta,
++ static_cast<float>(current.system - mPrevious.system) / sumDelta,
++ static_cast<float>(current.other - mPrevious.other ) / sumDelta,
++ static_cast<float>(freqRate),
++ freq);
++
++ }
++ }
++ else
++ {
++ emit update(
++ static_cast<float>(current.user - mPrevious.user ) / sumDelta,
++ static_cast<float>(current.nice - mPrevious.nice ) / sumDelta,
++ static_cast<float>(current.system - mPrevious.system) / sumDelta,
++ static_cast<float>(current.other - mPrevious.other ) / sumDelta);
++ }
++
++ mPrevious = current;
++ }
++ free(cp_times);
++ }
++ else
++ {
++ ulong freq = 0;
++
++ freq = CurrentFreq(mSource);
++ if (freq > 0)
++ emit update(freq);
++ }
++#else
+ if ( (mMonitoring == CpuStat::LoadOnly)
+ || (mMonitoring == CpuStat::LoadAndFrequency) )
+ {
+@@ -258,6 +493,7 @@ void CpuStatPrivate::timeout()
+ }
+ emit update(freq);
+ }
++#endif
+ }
+
+ QString CpuStatPrivate::defaultSource()
diff --git a/sysutils/libsysstat-qt6/files/patch-cpustat.h b/sysutils/libsysstat-qt6/files/patch-cpustat.h
new file mode 100644
index 000000000000..01720c1d0e1d
--- /dev/null
+++ b/sysutils/libsysstat-qt6/files/patch-cpustat.h
@@ -0,0 +1,32 @@
+--- cpustat.h.orig 2020-11-03 14:45:02 UTC
++++ cpustat.h
+@@ -27,14 +27,19 @@
+ #ifndef LIBSYSSTAT__CPU_STAT__INCLUDED
+ #define LIBSYSSTAT__CPU_STAT__INCLUDED
+
+-
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
+ #include <QtCore/QObject>
+
+ #include "basestat.h"
+
+
+ namespace SysStat {
+-
++#ifdef HAVE_SYSCTL_H
++ char *GetFirstFragment(char *string, const char *delim);
++ int GetCpu(void);
++#endif
+ class CpuStatPrivate;
+
+ class SYSSTATSHARED_EXPORT CpuStat : public BaseStat
+@@ -54,7 +59,6 @@ class SYSSTATSHARED_EXPORT CpuStat : public BaseStat (
+
+ uint minFreq(const QString &source) const;
+ uint maxFreq(const QString &source) const;
+-
+ signals:
+ void update(float user, float nice, float system, float other, float frequencyRate, uint frequency);
+ void update(float user, float nice, float system, float other);
diff --git a/sysutils/libsysstat-qt6/files/patch-cpustat__p.h b/sysutils/libsysstat-qt6/files/patch-cpustat__p.h
new file mode 100644
index 000000000000..3c56a8038991
--- /dev/null
+++ b/sysutils/libsysstat-qt6/files/patch-cpustat__p.h
@@ -0,0 +1,65 @@
+--- cpustat_p.h.orig 2021-04-07 06:58:34 UTC
++++ cpustat_p.h
+@@ -27,6 +27,9 @@
+ #ifndef LIBSYSSTAT__CPU_STAT__PRIVATE__INCLUDED
+ #define LIBSYSSTAT__CPU_STAT__PRIVATE__INCLUDED
+
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
+
+ #include <QtCore/QObject>
+ #include <QtCore/QtGlobal>
+@@ -52,8 +55,15 @@ class CpuStatPrivate : public BaseStatPrivate (public)
+ CpuStat::Monitoring monitoring() const;
+ void setMonitoring(CpuStat::Monitoring value);
+
++#ifdef HAVE_SYSCTL_H
++ ulong minFreq(const QString &source) const;
++ ulong maxFreq(const QString &source) const;
++ ulong CurrentFreq(const QString);
++
++#else
+ uint minFreq(const QString &source) const;
+ uint maxFreq(const QString &source) const;
++#endif
+
+ signals:
+ void update(float user, float nice, float system, float other);
+@@ -74,12 +84,21 @@ private slots: (private)
+ {
+ Values();
+
++#ifdef HAVE_SYSCTL_H
++ ulong user;
++ ulong nice;
++ ulong system;
++ ulong idle;
++ ulong other;
++ ulong total;
++#else
+ qulonglong user;
+ qulonglong nice;
+ qulonglong system;
+ qulonglong idle;
+ qulonglong other;
+ qulonglong total;
++#endif
+
+ void sum();
+
+@@ -89,7 +108,14 @@ private slots: (private)
+
+ CpuStat::Monitoring mMonitoring;
+
++#ifdef HAVE_SYSCTL_H
++ typedef QMap<QString, QPair<ulong, ulong> > Bounds;
++ int mib0[2];
++ int mib1[2];
++ int mib2[512][4];
++#else
+ typedef QMap<QString, QPair<uint, uint> > Bounds;
++#endif
+ Bounds mBounds;
+
+ int mUserHz;
diff --git a/sysutils/libsysstat-qt6/files/patch-memstat.cpp b/sysutils/libsysstat-qt6/files/patch-memstat.cpp
new file mode 100644
index 000000000000..78e493983d06
--- /dev/null
+++ b/sysutils/libsysstat-qt6/files/patch-memstat.cpp
@@ -0,0 +1,123 @@
+--- memstat.cpp.orig 2021-11-05 10:06:40 UTC
++++ memstat.cpp
+@@ -26,10 +26,58 @@
+
+ #include "memstat.h"
+ #include "memstat_p.h"
++#if defined(HAVE_KVM_H) && defined(HAVE_SYSCTL_H)
++extern "C"
++{
++ #include <paths.h>
++ #include <unistd.h>
++ #include <fcntl.h>
+
++ #include <kvm.h>
++ #include <sys/types.h>
++ #include <sys/sysctl.h>
++}
++#endif
+
+ namespace SysStat {
++#ifdef HAVE_SYSCTL_H
++int SwapDevices()
++{
++ int buf;
++ size_t len = sizeof(int);
+
++ if (sysctlbyname("vm.nswapdev", &buf, &len, NULL, 0) < 0)
++ return 0;
++ else
++ return buf;
++}
++
++qulonglong MemGetByBytes(QString property)
++{
++ qulonglong buf=0;
++ size_t len = sizeof(qulonglong);
++
++ std::string s = property.toStdString();
++ const char *name = s.c_str();
++
++ if (sysctlbyname(name, &buf, &len, NULL, 0) < 0)
++ return 0;
++ else
++ return buf;
++}
++
++qulonglong MemGetByPages(QString name)
++{
++ qulonglong res = 0;
++
++
++ res = MemGetByBytes(name);
++ if (res > 0)
++ res = res * getpagesize();
++
++ return res;
++}
++#endif
+ MemStatPrivate::MemStatPrivate(MemStat *parent)
+ : BaseStatPrivate(parent)
+ {
+@@ -49,8 +97,39 @@ void MemStatPrivate::timeout()
+ qulonglong memBuffers = 0;
+ qulonglong memCached = 0;
+ qulonglong swapTotal = 0;
+- qulonglong swapFree = 0;
++#ifdef HAVE_SYSCTL_H
++ memTotal = MemGetByBytes(QLatin1String("hw.physmem"));
++ memFree = MemGetByPages(QLatin1String("vm.stats.vm.v_free_count"));
++ memBuffers = MemGetByBytes(QLatin1String("vfs.bufspace"));
++ memCached = MemGetByPages(QLatin1String("vm.stats.vm.v_inactive_count"));
+
++#endif
++#ifdef HAVE_KVM_H
++ qulonglong swapUsed = 0;
++ kvm_t *kd;
++ struct kvm_swap kswap[16]; /* size taken from pstat/pstat.c */
++
++ kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open");
++ if (kd == NULL)
++ kvm_close(kd);
++
++ if (kvm_getswapinfo(kd, kswap, (sizeof(kswap) / sizeof(kswap[0])), SWIF_DEV_PREFIX) > 0)
++ {
++ int swapd = SwapDevices();
++ /* TODO: loop over swap devives */
++ if (swapd >= 1)
++ {
++ swapTotal = static_cast<qulonglong>(kswap[0].ksw_total * getpagesize());
++ swapUsed = static_cast<qulonglong>(kswap[0].ksw_used * getpagesize());
++ }
++
++ kvm_close(kd);
++ }
++ else
++ kvm_close(kd);
++#endif
++#ifndef HAVE_SYSCTL_H
++ qulonglong swapFree = 0;
+ const QStringList rows = readAllFile("/proc/meminfo").split(QLatin1Char('\n'), Qt::SkipEmptyParts);
+ for (const QString &row : rows)
+ {
+@@ -72,6 +151,7 @@ void MemStatPrivate::timeout()
+ swapFree = tokens[1].toULong();
+ }
+
++#endif
+ if (mSource == QLatin1String("memory"))
+ {
+ if (memTotal)
+@@ -88,8 +168,11 @@ void MemStatPrivate::timeout()
+ {
+ if (swapTotal)
+ {
++#ifndef HAVE_KVM_H
+ float swapUsed_d = static_cast<float>(swapTotal - swapFree) / static_cast<float>(swapTotal);
+-
++#else
++ float swapUsed_d = static_cast<float>(swapUsed) / static_cast<float>(swapTotal);
++#endif
+ emit swapUpdate(swapUsed_d);
+ }
+ }
diff --git a/sysutils/libsysstat-qt6/files/patch-memstat.h b/sysutils/libsysstat-qt6/files/patch-memstat.h
new file mode 100644
index 000000000000..399764f046fb
--- /dev/null
+++ b/sysutils/libsysstat-qt6/files/patch-memstat.h
@@ -0,0 +1,26 @@
+--- memstat.h.orig 2019-01-30 19:24:29 UTC
++++ memstat.h
+@@ -27,7 +27,9 @@
+ #ifndef LIBSYSSTAT__MEM_STAT__INCLUDED
+ #define LIBSYSSTAT__MEM_STAT__INCLUDED
+
+-
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
+ #include <QtCore/QObject>
+
+ #include "basestat.h"
+@@ -36,7 +38,11 @@
+ namespace SysStat {
+
+ class MemStatPrivate;
+-
++#if defined(HAVE_SYSCTL_H) && defined(HAVE_KVM_H)
++ int SwapDevices();
++ qulonglong MemGetByBytes(const QString property);
++ qulonglong MemGetByPages(const QString property);
++#endif
+ class SYSSTATSHARED_EXPORT MemStat : public BaseStat
+ {
+ Q_OBJECT
diff --git a/sysutils/libsysstat-qt6/files/patch-netstat.cpp b/sysutils/libsysstat-qt6/files/patch-netstat.cpp
new file mode 100644
index 000000000000..d62dc5a4a1ac
--- /dev/null
+++ b/sysutils/libsysstat-qt6/files/patch-netstat.cpp
@@ -0,0 +1,122 @@
+--- netstat.cpp.orig 2021-11-05 10:06:40 UTC
++++ netstat.cpp
+@@ -26,8 +26,23 @@
+
+ #include "netstat.h"
+ #include "netstat_p.h"
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
+
++#if defined(HAVE_SYSCTL_H) && defined(HAVE_IF_H)
++extern "C"
++{
++ #include <net/if.h>
++ #include <net/if_mib.h>
++ #include <net/if_types.h>
++ #include <sys/socket.h> /* PF_LINK */
++ #include <sys/types.h>
++ #include <sys/sysctl.h>
++}
++#endif
+
++
+ namespace SysStat {
+
+ NetStatPrivate::NetStatPrivate(NetStat *parent)
+@@ -37,6 +52,7 @@ NetStatPrivate::NetStatPrivate(NetStat *parent)
+
+ connect(mTimer, SIGNAL(timeout()), SLOT(timeout()));
+
++#ifndef HAVE_SYSCTL_H
+
+ QStringList rows(readAllFile("/proc/net/dev").split(QLatin1Char('\n'), Qt::SkipEmptyParts));
+
+@@ -50,12 +66,79 @@ NetStatPrivate::NetStatPrivate(NetStat *parent)
+
+ mSources.append(tokens[0].trimmed());
+ }
++#else
++ int count;
++ size_t len;
++ int cntifmib[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT };// net.link.generic.system.ifcount;
++ len = sizeof(int);
++ if (sysctl(cntifmib, 5, &count, &len, NULL, 0) < 0)
++ perror("sysctl");
++
++
++ struct ifmibdata ifmd;
++ size_t len1 = sizeof(ifmd);
++ for (int i=1; i<=count;i++) {
++ int name[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, i, IFDATA_GENERAL };
++
++ if (sysctl(name, 6, &ifmd, &len1, NULL, 0) < 0) {
++ perror("sysctl");
++ }
++ if ((ifmd.ifmd_data.ifi_type == IFT_ETHER) || (ifmd.ifmd_data.ifi_type == IFT_IEEE80211)) {
++ const char *iface = ifmd.ifmd_name;
++ mSources.append(QString::fromLatin1(iface));
++ }
++ }
++#endif
+ }
+
+ NetStatPrivate::~NetStatPrivate() = default;
+
+ void NetStatPrivate::timeout()
+ {
++#if defined(HAVE_IF_H) && defined(HAVE_SYSCTL_H)
++ int count;
++ size_t len;
++ int name[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT };
++ struct ifmibdata ifmd;
++
++ len = sizeof(int);
++ if (sysctl(name, 5, &count, &len, NULL, 0) < 0)
++ return;
++
++ for (int i = 1; i <= count; i++)
++ {
++ len = sizeof(ifmd);
++ int name[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, i, IFDATA_GENERAL };
++
++ if (sysctl(name, 6, &ifmd, &len, NULL, 0) < 0)
++ break;
++
++ if ((ifmd.ifmd_data.ifi_type == IFT_ETHER) || (ifmd.ifmd_data.ifi_type == IFT_IEEE80211))
++ {
++ const char *iface = ifmd.ifmd_name;
++ QString interfaceName = QString::fromLatin1(iface);
++ if ((ifmd.ifmd_data.ifi_link_state == LINK_STATE_UP) && (ifmd.ifmd_data.ifi_ipackets > 0))
++ {
++
++
++ Values current;
++ current.received = ifmd.ifmd_data.ifi_ibytes;
++ current.transmitted = ifmd.ifmd_data.ifi_obytes;
++
++ if (!mPrevious.contains(interfaceName))
++ mPrevious.insert(interfaceName, Values());
++ const Values &previous = mPrevious[interfaceName];
++
++ if (interfaceName == mSource)
++ emit update((( current.received - previous.received ) * 1000 ) / mTimer->interval(), (( current.transmitted - previous.transmitted ) * 1000 ) / mTimer->interval());
++
++ mPrevious[interfaceName] = current;
++ } else if(interfaceName == mSource)
++ emit(update(0,0));
++
++ }
++ }
++#else
+ QStringList rows(readAllFile("/proc/net/dev").split(QLatin1Char('\n'), Qt::SkipEmptyParts));
+
+
+@@ -97,6 +180,7 @@ void NetStatPrivate::timeout()
+
+ mPrevious[interfaceName] = current;
+ }
++#endif
+ }
+
+ QString NetStatPrivate::defaultSource()
diff --git a/sysutils/libsysstat-qt6/pkg-descr b/sysutils/libsysstat-qt6/pkg-descr
new file mode 100644
index 000000000000..0c091aa86aec
--- /dev/null
+++ b/sysutils/libsysstat-qt6/pkg-descr
@@ -0,0 +1,2 @@
+Qt-based library to query system information like CPU, memory usage and
+network traffic.
diff --git a/sysutils/libsysstat-qt6/pkg-plist b/sysutils/libsysstat-qt6/pkg-plist
new file mode 100644
index 000000000000..2cfa71a85d82
--- /dev/null
+++ b/sysutils/libsysstat-qt6/pkg-plist
@@ -0,0 +1,20 @@
+include/sysstat-qt6/SysStat/BaseStat
+include/sysstat-qt6/SysStat/CpuStat
+include/sysstat-qt6/SysStat/Global
+include/sysstat-qt6/SysStat/MemStat
+include/sysstat-qt6/SysStat/NetStat
+include/sysstat-qt6/SysStat/Version
+include/sysstat-qt6/basestat.h
+include/sysstat-qt6/cpustat.h
+include/sysstat-qt6/memstat.h
+include/sysstat-qt6/netstat.h
+include/sysstat-qt6/sysstat_global.h
+include/sysstat-qt6/version.h
+lib/libsysstat-qt6.so
+lib/libsysstat-qt6.so.1
+lib/libsysstat-qt6.so.%%VERSION%%
+libdata/pkgconfig/sysstat-qt6.pc
+share/cmake/sysstat-qt6/sysstat-qt6-config-version.cmake
+share/cmake/sysstat-qt6/sysstat-qt6-config.cmake
+share/cmake/sysstat-qt6/sysstat-qt6-targets-%%CMAKE_BUILD_TYPE%%.cmake
+share/cmake/sysstat-qt6/sysstat-qt6-targets.cmake