Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 19 additions & 43 deletions mythplugins/mythzoneminder/mythzmserver/zmserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include <algorithm>
#include <array>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <cstdlib>
Expand All @@ -29,18 +30,6 @@
#include <sys/shm.h>
#include <sys/mman.h>

#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
# include <sys/statvfs.h>
#else
# include <sys/param.h>
# include <sys/mount.h>
# ifdef __CYGWIN__
# include <sys/statfs.h>
# else // if !__CYGWIN__
# include <sys/sysctl.h>
# endif // !__CYGWIN__
#endif

#ifndef MSG_NOSIGNAL
static constexpr int MSG_NOSIGNAL { 0 }; // Apple also has SO_NOSIGPIPE?
#endif
Expand Down Expand Up @@ -740,33 +729,23 @@ void ZMServer::handleHello()
send(outStr);
}

long long ZMServer::getDiskSpace(const std::string &filename, long long &total, long long &used)
static uintmax_t disk_usage_percent(const std::filesystem::space_info& space_info)
{
struct statvfs statbuf {};
long long freespace = -1;

total = used = -1;

// there are cases where statfs will return 0 (good), but f_blocks and
// others are invalid and set to 0 (such as when an automounted directory
// is not mounted but still visible because --ghost was used),
// so check to make sure we can have a total size > 0
if ((statvfs(filename.c_str(), &statbuf) == 0) &&
(statbuf.f_blocks > 0) &&
(statbuf.f_bsize > 0))
{
total = statbuf.f_blocks;
total *= statbuf.f_bsize;
total = total >> 10;

freespace = statbuf.f_bavail;
freespace *= statbuf.f_bsize;
freespace = freespace >> 10;

used = total - freespace;
}

return freespace;
constexpr uintmax_t k_unknown_size {static_cast<std::uintmax_t>(-1)};
if (
(space_info.capacity == 0
|| space_info.free == 0
|| space_info.available == 0
) ||
(space_info.capacity == k_unknown_size
|| space_info.free == k_unknown_size
|| space_info.available == k_unknown_size
)
)
{
return 100;
}
return (100 * (space_info.capacity - space_info.available)) / space_info.capacity;
}

void ZMServer::handleGetServerStatus(void)
Expand All @@ -792,12 +771,9 @@ void ZMServer::handleGetServerStatus(void)
ADD_STR(outStr, buf);
}

// get free space on the disk where the events are stored
long long total = 0;
long long used = 0;
std::string eventsDir = g_webPath + "/events/";
getDiskSpace(eventsDir, total, used);
std::string buf = std::to_string(static_cast<int>((used * 100) / total)) + "%";
std::string buf =
std::to_string(disk_usage_percent(std::filesystem::space(eventsDir))) + "%";
ADD_STR(outStr, buf);

send(outStr);
Expand Down
1 change: 0 additions & 1 deletion mythplugins/mythzoneminder/mythzmserver/zmserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,6 @@ class ZMServer
void sendError(const std::string &error);
void getMonitorList(void);
static int getFrame(FrameData &buffer, MONITOR *monitor);
static long long getDiskSpace(const std::string &filename, long long &total, long long &used);
static void tokenize(const std::string &command, std::vector<std::string> &tokens);
void handleHello(void);
static std::string runCommand(const std::string& command);
Expand Down
30 changes: 0 additions & 30 deletions mythtv/libs/libmythbase/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,36 +76,6 @@
# define setenv(x, y, z) ::SetEnvironmentVariableA(x, y)
# define unsetenv(x) 0


struct statfs {
// long f_type; /* type of filesystem */
long f_bsize; /* optimal transfer block size */
long f_blocks; /* total data blocks in file system */
// long f_bfree; /* free blocks in fs */
long f_bavail; /* free blocks avail to non-superuser */
// long f_files; /* total file nodes in file system */
// long f_ffree; /* free file nodes in fs */
// long f_fsid; /* file system id */
// long f_namelen; /* maximum length of filenames */
// long f_spare[6]; /* spare for later */
};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
inline int statfs(const char* path, struct statfs* buffer)
{
DWORD spc = 0, bps = 0, fc = 0, c = 0;

if (buffer && GetDiskFreeSpaceA(path, &spc, &bps, &fc, &c))
{
buffer->f_bsize = bps;
buffer->f_blocks = spc * c;
buffer->f_bavail = spc * fc;
return 0;
}

return -1;
}
#pragma GCC diagnostic pop
# endif

#define lstat stat
Expand Down
61 changes: 40 additions & 21 deletions mythtv/libs/libmythbase/mythdirs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#include <QCoreApplication>

#ifdef Q_OS_ANDROID
#include <filesystem>
#include <QStandardPaths>
#include <sys/statfs.h>
#elif defined(Q_OS_WIN)
#include <QStandardPaths>
#endif
Expand Down Expand Up @@ -139,40 +139,59 @@ void InitializeMythDirs(void)
#if 0
// TODO allow choice of base fs or the SD card for data
QStringList appLocs = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
uint64_t maxFreeSpace = 0;
for(auto s : appLocs)
uintmax_t maxFreeSpace = 0;
constexpr uintmax_t k_unknown_size {static_cast<std::uintmax_t>(-1)};
for(const auto & s : appLocs)
{
struct statfs statFs;
memset(&statFs, 0, sizeof(statFs));
int ret = statfs(s.toLocal8Bit().data(), &statFs);
if (ret == 0 && statFs.f_bavail >= maxFreeSpace)
std::filesystem::space_info space_info = std::filesystem::space(s.toStdString());
if (!(
(space_info.capacity == 0
|| space_info.free == 0
|| space_info.available == 0
) ||
(space_info.capacity == k_unknown_size
|| space_info.free == k_unknown_size
|| space_info.available == k_unknown_size
)
) && space_info.available >= maxFreeSpace
)
{
maxFreeSpace = statFs.f_bavail;
maxFreeSpace = space_info.available;
confdir = s;
}
LOG(VB_GENERAL, LOG_NOTICE, QString(" appdatadir = %1 (%2, %3, %4)")
.arg(s)
.arg(statFs.f_bavail)
.arg(statFs.f_bfree)
.arg(statFs.f_bsize));
.arg(space_info.available)
.arg(space_info.free)
.arg(space_info.capacity)
);
}
QStringList cacheLocs = QStandardPaths::standardLocations(QStandardPaths::CacheLocation);
maxFreeSpace = 0;
for(auto s : cacheLocs)
for(const auto & s : cacheLocs)
{
struct statfs statFs;
memset(&statFs, 0, sizeof(statFs));
int ret = statfs(s.toLocal8Bit().data(), &statFs);
if (ret == 0 && statFs.f_bavail >= maxFreeSpace)
std::filesystem::space_info space_info = std::filesystem::space(s.toStdString());
if (!(
(space_info.capacity == 0
|| space_info.free == 0
|| space_info.available == 0
) ||
(space_info.capacity == k_unknown_size
|| space_info.free == k_unknown_size
|| space_info.available == k_unknown_size
)
) && space_info.available >= maxFreeSpace
)
{
maxFreeSpace = statFs.f_bavail;
maxFreeSpace = space_info.available;
//confdir = s;
}
LOG(VB_GENERAL, LOG_NOTICE, QString(" cachedir = %1 (%2, %3, %4)")
.arg(s)
.arg(statFs.f_bavail)
.arg(statFs.f_bfree)
.arg(statFs.f_bsize));
.arg(s)
.arg(space_info.available)
.arg(space_info.free)
.arg(space_info.capacity)
);
}
#endif

Expand Down