/*
 *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
#include "fileutils.h"
#include <opendht/crypto.h>

#ifdef RING_UWP
#include <io.h> // for access and close
#endif

#ifdef __APPLE__
#include <TargetConditionals.h>
#endif

#ifdef _WIN32
#include <windows.h>
#include "string_utils.h"
#endif

#include <sys/types.h>
#include <sys/stat.h>

#ifndef _MSC_VER
#include <libgen.h>
#endif

#ifdef _MSC_VER
#include "windirent.h"
#else
#include <dirent.h>
#endif

#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#ifndef _WIN32
#include <pwd.h>
#else
#include <shlobj.h>
#define NAME_MAX 255
#endif
#if !defined __ANDROID__ && !defined _WIN32
#include <wordexp.h>
#endif

#include <nettle/sha3.h>

#include <sstream>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <limits>
#include <array>

#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <cstddef>
#include <ciso646>

extern "C" {
#include <pj/ctype.h>
#include <pjlib-util/md5.h>
}

#include <filesystem>

#define PIDFILE     ".ring.pid"
#define ERASE_BLOCK 4096

namespace dhtnet {
namespace fileutils {

// returns true if directory exists
bool
check_dir(const char* path, [[maybe_unused]] mode_t dirmode, mode_t parentmode)
{
    DIR* dir = opendir(path);

    if (!dir) { // doesn't exist
        if (not recursive_mkdir(path, parentmode)) {
            perror(path);
            return false;
        }
#ifndef _WIN32
        if (chmod(path, dirmode) < 0) {
            //JAMI_ERR("fileutils::check_dir(): chmod() failed on '%s', %s", path, strerror(errno));
            return false;
        }
#endif
    } else
        closedir(dir);
    return true;
}

std::string
expand_path(const std::string& path)
{
#if defined __ANDROID__ || defined _MSC_VER || defined WIN32 || defined __APPLE__
    //JAMI_ERR("Path expansion not implemented, returning original");
    return path;
#else

    std::string result;

    wordexp_t p;
    int ret = wordexp(path.c_str(), &p, 0);

    switch (ret) {
    case WRDE_BADCHAR:
        /*JAMI_ERR("Illegal occurrence of newline or one of |, &, ;, <, >, "
                 "(, ), {, }.");*/
        return result;
    case WRDE_BADVAL:
        //JAMI_ERR("An undefined shell variable was referenced");
        return result;
    case WRDE_CMDSUB:
        //JAMI_ERR("Command substitution occurred");
        return result;
    case WRDE_SYNTAX:
        //JAMI_ERR("Shell syntax error");
        return result;
    case WRDE_NOSPACE:
        //JAMI_ERR("Out of memory.");
        // This is the only error where we must call wordfree
        break;
    default:
        if (p.we_wordc > 0)
            result = std::string(p.we_wordv[0]);
        break;
    }

    wordfree(&p);

    return result;
#endif
}

std::mutex&
getFileLock(const std::string& path)
{
    static std::mutex fileLockLock {};
    static std::map<std::string, std::mutex> fileLocks {};

    std::lock_guard<std::mutex> l(fileLockLock);
    return fileLocks[path];
}

bool
isFile(const std::string& path, bool resolveSymlink)
{
    if (path.empty())
        return false;
#ifdef _WIN32
    if (resolveSymlink) {
        struct _stat64i32 s;
        if (_wstat(dhtnet::to_wstring(path).c_str(), &s) == 0)
            return S_ISREG(s.st_mode);
    } else {
        DWORD attr = GetFileAttributes(dhtnet::to_wstring(path).c_str());
        if ((attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_DIRECTORY)
            && !(attr & FILE_ATTRIBUTE_REPARSE_POINT))
            return true;
    }
#else
    if (resolveSymlink) {
        struct stat s;
        if (stat(path.c_str(), &s) == 0)
            return S_ISREG(s.st_mode);
    } else {
        struct stat s;
        if (lstat(path.c_str(), &s) == 0)
            return S_ISREG(s.st_mode);
    }
#endif

    return false;
}

bool
isDirectory(const std::string& path)
{
    struct stat s;
    if (stat(path.c_str(), &s) == 0)
        return s.st_mode & S_IFDIR;
    return false;
}

bool
isDirectoryWritable(const std::string& directory)
{
    return accessFile(directory, W_OK) == 0;
}

bool
hasHardLink(const std::string& path)
{
#ifndef _WIN32
    struct stat s;
    if (lstat(path.c_str(), &s) == 0)
        return s.st_nlink > 1;
#endif
    return false;
}

bool
isSymLink(const std::string& path)
{
#ifndef _WIN32
    struct stat s;
    if (lstat(path.c_str(), &s) == 0)
        return S_ISLNK(s.st_mode);
#elif !defined(_MSC_VER)
    DWORD attr = GetFileAttributes(dhtnet::to_wstring(path).c_str());
    if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
        return true;
#endif
    return false;
}

std::chrono::system_clock::time_point
writeTime(const std::string& path)
{
#ifndef _WIN32
    struct stat s;
    auto ret = stat(path.c_str(), &s);
    if (ret)
        throw std::runtime_error("Can't check write time for: " + path);
    return std::chrono::system_clock::from_time_t(s.st_mtime);
#else
#if RING_UWP
    _CREATEFILE2_EXTENDED_PARAMETERS ext_params = {0};
    ext_params.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
    ext_params.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
    ext_params.dwFileFlags = FILE_FLAG_NO_BUFFERING;
    ext_params.dwSecurityQosFlags = SECURITY_ANONYMOUS;
    ext_params.lpSecurityAttributes = nullptr;
    ext_params.hTemplateFile = nullptr;
    HANDLE h = CreateFile2(dhtnet::to_wstring(path).c_str(),
                           GENERIC_READ,
                           FILE_SHARE_READ,
                           OPEN_EXISTING,
                           &ext_params);
#elif _WIN32
    HANDLE h = CreateFileW(dhtnet::to_wstring(path).c_str(),
                           GENERIC_READ,
                           FILE_SHARE_READ,
                           nullptr,
                           OPEN_EXISTING,
                           FILE_ATTRIBUTE_NORMAL,
                           nullptr);
#endif
    if (h == INVALID_HANDLE_VALUE)
        throw std::runtime_error("Can't open: " + path);
    FILETIME lastWriteTime;
    if (!GetFileTime(h, nullptr, nullptr, &lastWriteTime))
        throw std::runtime_error("Can't check write time for: " + path);
    CloseHandle(h);
    SYSTEMTIME sTime;
    if (!FileTimeToSystemTime(&lastWriteTime, &sTime))
        throw std::runtime_error("Can't check write time for: " + path);
    struct tm tm
    {};
    tm.tm_year = sTime.wYear - 1900;
    tm.tm_mon = sTime.wMonth - 1;
    tm.tm_mday = sTime.wDay;
    tm.tm_hour = sTime.wHour;
    tm.tm_min = sTime.wMinute;
    tm.tm_sec = sTime.wSecond;
    tm.tm_isdst = -1;
    return std::chrono::system_clock::from_time_t(mktime(&tm));
#endif
}

bool
createSymlink(const std::string& linkFile, const std::string& target)
{
    try {
        std::filesystem::create_symlink(target, linkFile);
    } catch (const std::exception& e) {
        //JAMI_ERR("Couldn't create soft link: %s", e.what());
        return false;
    }
    return true;
}

bool
createHardlink(const std::string& linkFile, const std::string& target)
{
    try {
        std::filesystem::create_hard_link(target, linkFile);
    } catch (const std::exception& e) {
        //JAMI_ERR("Couldn't create hard link: %s", e.what());
        return false;
    }
    return true;
}

void
createFileLink(const std::string& linkFile, const std::string& target, bool hard)
{
    if (not hard or not createHardlink(linkFile, target))
        createSymlink(linkFile, target);
}

std::string_view
getFileExtension(std::string_view filename)
{
    std::string_view result;
    auto sep = filename.find_last_of('.');
    if (sep != std::string_view::npos && sep != filename.size() - 1)
        result = filename.substr(sep + 1);
    if (result.size() >= 8)
        return {};
    return result;
}

bool
isPathRelative(const std::string& path)
{
#ifndef _WIN32
    return not path.empty() and not(path[0] == '/');
#else
    return not path.empty() and path.find(":") == std::string::npos;
#endif
}

std::string
getCleanPath(const std::string& base, const std::string& path)
{
    if (base.empty() or path.size() < base.size())
        return path;
    auto base_sep = base + DIR_SEPARATOR_STR;
    if (path.compare(0, base_sep.size(), base_sep) == 0)
        return path.substr(base_sep.size());
    else
        return path;
}

std::string
getFullPath(const std::string& base, const std::string& path)
{
    bool isRelative {not base.empty() and isPathRelative(path)};
    return isRelative ? base + DIR_SEPARATOR_STR + path : path;
}

std::vector<uint8_t>
loadFile(const std::string& path, const std::string& default_dir)
{
    std::vector<uint8_t> buffer;
    std::ifstream file = ifstream(getFullPath(default_dir, path), std::ios::binary);
    if (!file)
        throw std::runtime_error("Can't read file: " + path);
    file.seekg(0, std::ios::end);
    auto size = file.tellg();
    if (size > std::numeric_limits<unsigned>::max())
        throw std::runtime_error("File is too big: " + path);
    buffer.resize(size);
    file.seekg(0, std::ios::beg);
    if (!file.read((char*) buffer.data(), size))
        throw std::runtime_error("Can't load file: " + path);
    return buffer;
}

std::string
loadTextFile(const std::string& path, const std::string& default_dir)
{
    std::string buffer;
    std::ifstream file = ifstream(getFullPath(default_dir, path));
    if (!file)
        throw std::runtime_error("Can't read file: " + path);
    file.seekg(0, std::ios::end);
    auto size = file.tellg();
    if (size > std::numeric_limits<unsigned>::max())
        throw std::runtime_error("File is too big: " + path);
    buffer.resize(size);
    file.seekg(0, std::ios::beg);
    if (!file.read((char*) buffer.data(), size))
        throw std::runtime_error("Can't load file: " + path);
    return buffer;
}

void
saveFile(const std::string& path, const uint8_t* data, size_t data_size, [[maybe_unused]] mode_t mode)
{
    std::ofstream file = fileutils::ofstream(path, std::ios::trunc | std::ios::binary);
    if (!file.is_open()) {
        //JAMI_ERR("Could not write data to %s", path.c_str());
        return;
    }
    file.write((char*) data, data_size);
#ifndef _WIN32
    if (chmod(path.c_str(), mode) < 0)
        /*JAMI_WARN("fileutils::saveFile(): chmod() failed on '%s', %s",
                  path.c_str(),
                  strerror(errno))*/;
#endif
}

std::vector<uint8_t>
loadCacheFile(const std::string& path, std::chrono::system_clock::duration maxAge)
{
    // writeTime throws exception if file doesn't exist
    auto duration = std::chrono::system_clock::now() - writeTime(path);
    if (duration > maxAge)
        throw std::runtime_error("file too old");

    //JAMI_DBG("Loading cache file '%.*s'", (int) path.size(), path.c_str());
    return loadFile(path);
}

std::string
loadCacheTextFile(const std::string& path, std::chrono::system_clock::duration maxAge)
{
    // writeTime throws exception if file doesn't exist
    auto duration = std::chrono::system_clock::now() - writeTime(path);
    if (duration > maxAge)
        throw std::runtime_error("file too old");

    //JAMI_DBG("Loading cache file '%.*s'", (int) path.size(), path.c_str());
    return loadTextFile(path);
}

static size_t
dirent_buf_size([[maybe_unused]] DIR* dirp)
{
    long name_max;
#if defined(HAVE_FPATHCONF) && defined(HAVE_DIRFD) && defined(_PC_NAME_MAX)
    name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
    if (name_max == -1)
#if defined(NAME_MAX)
        name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
#else
        return (size_t) (-1);
#endif
#else
#if defined(NAME_MAX)
    name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
#else
#error "buffer size for readdir_r cannot be determined"
#endif
#endif
    size_t name_end = (size_t) offsetof(struct dirent, d_name) + name_max + 1;
    return name_end > sizeof(struct dirent) ? name_end : sizeof(struct dirent);
}

std::vector<std::string>
readDirectory(const std::string& dir)
{
    DIR* dp = opendir(dir.c_str());
    if (!dp)
        return {};

    size_t size = dirent_buf_size(dp);
    if (size == (size_t) (-1))
        return {};
    std::vector<uint8_t> buf(size);
    dirent* entry;

    std::vector<std::string> files;
#ifndef _WIN32
    while (!readdir_r(dp, reinterpret_cast<dirent*>(buf.data()), &entry) && entry) {
#else
    while ((entry = readdir(dp)) != nullptr) {
#endif
        std::string fname {entry->d_name};
        if (fname == "." || fname == "..")
            continue;
        files.emplace_back(std::move(fname));
    }
    closedir(dp);
    return files;
} // namespace fileutils

/*
std::vector<uint8_t>
readArchive(const std::string& path, const std::string& pwd)
{
    JAMI_DBG("Reading archive from %s", path.c_str());

    auto isUnencryptedGzip = [](const std::vector<uint8_t>& data) {
        // NOTE: some webserver modify gzip files and this can end with a gunzip in a gunzip
        // file. So, to make the readArchive more robust, we can support this case by detecting
        // gzip header via 1f8b 08
        // We don't need to support more than 2 level, else somebody may be able to send
        // gunzip in loops and abuse.
        return data.size() > 3 && data[0] == 0x1f && data[1] == 0x8b && data[2] == 0x08;
    };

    auto decompress = [](std::vector<uint8_t>& data) {
        try {
            data = archiver::decompress(data);
        } catch (const std::exception& e) {
            JAMI_ERR("Error decrypting archive: %s", e.what());
            throw e;
        }
    };

    std::vector<uint8_t> data;
    // Read file
    try {
        data = loadFile(path);
    } catch (const std::exception& e) {
        JAMI_ERR("Error loading archive: %s", e.what());
        throw e;
    }

    if (isUnencryptedGzip(data)) {
        if (!pwd.empty())
            JAMI_WARN() << "A gunzip in a gunzip is detected. A webserver may have a bad config";

        decompress(data);
    }

    if (!pwd.empty()) {
        // Decrypt
        try {
            data = dht::crypto::aesDecrypt(data, pwd);
        } catch (const std::exception& e) {
            JAMI_ERR("Error decrypting archive: %s", e.what());
            throw e;
        }
        decompress(data);
    } else if (isUnencryptedGzip(data)) {
        JAMI_WARN() << "A gunzip in a gunzip is detected. A webserver may have a bad config";
        decompress(data);
    }
    return data;
}

void
writeArchive(const std::string& archive_str, const std::string& path, const std::string& password)
{
    JAMI_DBG("Writing archive to %s", path.c_str());

    if (not password.empty()) {
        // Encrypt using provided password
        std::vector<uint8_t> data = dht::crypto::aesEncrypt(archiver::compress(archive_str),
                                                            password);
        // Write
        try {
            saveFile(path, data);
        } catch (const std::runtime_error& ex) {
            JAMI_ERR("Export failed: %s", ex.what());
            return;
        }
    } else {
        JAMI_WARN("Unsecured archiving (no password)");
        archiver::compressGzip(archive_str, path);
    }
}*/

bool
recursive_mkdir(const std::string& path, mode_t mode)
{
#ifndef _WIN32
    if (mkdir(path.data(), mode) != 0) {
#else
    if (_wmkdir(dhtnet::to_wstring(path.data()).c_str()) != 0) {
#endif
        if (errno == ENOENT) {
            recursive_mkdir(path.substr(0, path.find_last_of(DIR_SEPARATOR_CH)), mode);
#ifndef _WIN32
            if (mkdir(path.data(), mode) != 0) {
#else
            if (_wmkdir(dhtnet::to_wstring(path.data()).c_str()) != 0) {
#endif
                //JAMI_ERR("Could not create directory.");
                return false;
            }
        }
    } // namespace dhtnet
    return true;
}

#ifdef _WIN32
bool
eraseFile_win32(const std::string& path, bool dosync)
{
    HANDLE h
        = CreateFileA(path.c_str(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if (h == INVALID_HANDLE_VALUE) {
        // JAMI_WARN("Can not open file %s for erasing.", path.c_str());
        return false;
    }

    LARGE_INTEGER size;
    if (!GetFileSizeEx(h, &size)) {
        // JAMI_WARN("Can not erase file %s: GetFileSizeEx() failed.", path.c_str());
        CloseHandle(h);
        return false;
    }
    if (size.QuadPart == 0) {
        CloseHandle(h);
        return false;
    }

    uint64_t size_blocks = size.QuadPart / ERASE_BLOCK;
    if (size.QuadPart % ERASE_BLOCK)
        size_blocks++;

    char* buffer;
    try {
        buffer = new char[ERASE_BLOCK];
    } catch (std::bad_alloc& ba) {
        // JAMI_WARN("Can not allocate buffer for erasing %s.", path.c_str());
        CloseHandle(h);
        return false;
    }
    memset(buffer, 0x00, ERASE_BLOCK);

    OVERLAPPED ovlp;
    if (size.QuadPart < (1024 - 42)) { // a small file can be stored in the MFT record
        ovlp.Offset = 0;
        ovlp.OffsetHigh = 0;
        WriteFile(h, buffer, (DWORD) size.QuadPart, 0, &ovlp);
        FlushFileBuffers(h);
    }
    for (uint64_t i = 0; i < size_blocks; i++) {
        uint64_t offset = i * ERASE_BLOCK;
        ovlp.Offset = offset & 0x00000000FFFFFFFF;
        ovlp.OffsetHigh = offset >> 32;
        WriteFile(h, buffer, ERASE_BLOCK, 0, &ovlp);
    }

    delete[] buffer;

    if (dosync)
        FlushFileBuffers(h);

    CloseHandle(h);
    return true;
}

#else

bool
eraseFile_posix(const std::string& path, bool dosync)
{
    struct stat st;
    if (stat(path.c_str(), &st) == -1) {
        //JAMI_WARN("Can not erase file %s: fstat() failed.", path.c_str());
        return false;
    }
    // Remove read-only flag if possible
    chmod(path.c_str(), st.st_mode | (S_IWGRP+S_IWUSR) );

    int fd = open(path.c_str(), O_WRONLY);
    if (fd == -1) {
        //JAMI_WARN("Can not open file %s for erasing.", path.c_str());
        return false;
    }

    if (st.st_size == 0) {
        close(fd);
        return false;
    }

    lseek(fd, 0, SEEK_SET);

    std::array<char, ERASE_BLOCK> buffer;
    buffer.fill(0);
    decltype(st.st_size) written(0);
    while (written < st.st_size) {
        auto ret = write(fd, buffer.data(), buffer.size());
        if (ret < 0) {
            //JAMI_WARNING("Error while overriding file with zeros.");
            break;
        } else
            written += ret;
    }

    if (dosync)
        fsync(fd);

    close(fd);
    return written >= st.st_size;
}
#endif

bool
eraseFile(const std::string& path, bool dosync)
{
#ifdef _WIN32
    return eraseFile_win32(path, dosync);
#else
    return eraseFile_posix(path, dosync);
#endif
}

int
remove(const std::string& path, bool erase)
{
    if (erase and isFile(path, false) and !hasHardLink(path))
        eraseFile(path, true);

#ifdef _WIN32
    // use Win32 api since std::remove will not unlink directory in use
    if (isDirectory(path))
        return !RemoveDirectory(dhtnet::to_wstring(path).c_str());
#endif

    return std::remove(path.c_str());
}

int
removeAll(const std::string& path, bool erase)
{
    if (path.empty())
        return -1;
    if (isDirectory(path) and !isSymLink(path)) {
        auto dir = path;
        if (dir.back() != DIR_SEPARATOR_CH)
            dir += DIR_SEPARATOR_CH;
        for (auto& entry : fileutils::readDirectory(dir))
            removeAll(dir + entry, erase);
    }
    return remove(path, erase);
}

void
openStream(std::ifstream& file, const std::string& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
    file.open(dhtnet::to_wstring(path), mode);
#else
    file.open(path, mode);
#endif
}

void
openStream(std::ofstream& file, const std::string& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
    file.open(dhtnet::to_wstring(path), mode);
#else
    file.open(path, mode);
#endif
}

std::ifstream
ifstream(const std::string& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
    return std::ifstream(dhtnet::to_wstring(path), mode);
#else
    return std::ifstream(path, mode);
#endif
}

std::ofstream
ofstream(const std::string& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
    return std::ofstream(dhtnet::to_wstring(path), mode);
#else
    return std::ofstream(path, mode);
#endif
}

int64_t
size(const std::string& path)
{
    int64_t size = 0;
    try {
        std::ifstream file;
        openStream(file, path, std::ios::binary | std::ios::in);
        file.seekg(0, std::ios_base::end);
        size = file.tellg();
        file.close();
    } catch (...) {
    }
    return size;
}

std::string
sha3File(const std::string& path)
{
    sha3_512_ctx ctx;
    sha3_512_init(&ctx);

    std::ifstream file;
    try {
        if (!fileutils::isFile(path))
            return {};
        openStream(file, path, std::ios::binary | std::ios::in);
        if (!file)
            return {};
        std::vector<char> buffer(8192, 0);
        while (!file.eof()) {
            file.read(buffer.data(), buffer.size());
            std::streamsize readSize = file.gcount();
            sha3_512_update(&ctx, readSize, (const uint8_t*) buffer.data());
        }
        file.close();
    } catch (...) {
        return {};
    }

    unsigned char digest[SHA3_512_DIGEST_SIZE];
    sha3_512_digest(&ctx, SHA3_512_DIGEST_SIZE, digest);

    char hash[SHA3_512_DIGEST_SIZE * 2];

    for (int i = 0; i < SHA3_512_DIGEST_SIZE; ++i)
        pj_val_to_hex_digit(digest[i], &hash[2 * i]);

    return {hash, SHA3_512_DIGEST_SIZE * 2};
}

std::string
sha3sum(const std::vector<uint8_t>& buffer)
{
    sha3_512_ctx ctx;
    sha3_512_init(&ctx);
    sha3_512_update(&ctx, buffer.size(), (const uint8_t*) buffer.data());

    unsigned char digest[SHA3_512_DIGEST_SIZE];
    sha3_512_digest(&ctx, SHA3_512_DIGEST_SIZE, digest);

    char hash[SHA3_512_DIGEST_SIZE * 2];

    for (int i = 0; i < SHA3_512_DIGEST_SIZE; ++i)
        pj_val_to_hex_digit(digest[i], &hash[2 * i]);

    return {hash, SHA3_512_DIGEST_SIZE * 2};
}

int
accessFile(const std::string& file, int mode)
{
#ifdef _WIN32
    return _waccess(dhtnet::to_wstring(file).c_str(), mode);
#else
    return access(file.c_str(), mode);
#endif
}

uint64_t
lastWriteTime(const std::string& p)
{
#if USE_STD_FILESYSTEM
    return std::chrono::duration_cast<std::chrono::milliseconds>(
               std::filesystem::last_write_time(std::filesystem::path(p)).time_since_epoch())
        .count();
#else
    struct stat result;
    if (stat(p.c_str(), &result) == 0)
        return result.st_mtime;
    return 0;
#endif
}

} // namespace fileutils
} // namespace dhtnet
