<commit_before>/**
 * @file filesystem.cpp
 * @brief Generic host filesystem access interfaces
 *
 * (c) 2013-2014 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */
#include "mega/filesystem.h"
#include "mega/node.h"
#include "mega/megaclient.h"
#include "mega/logging.h"
#include "mega/mega_utf8proc.h"

namespace mega {
FileSystemAccess::FileSystemAccess()
    : waiter(NULL)
    , skip_errorreport(false)
    , transient_error(false)
    , notifyerr(false)
    , notifyfailed(false)
    , target_exists(false)
    , client(NULL)
{
}

void FileSystemAccess::captimestamp(m_time_t* t)
{
    // FIXME: remove upper bound before the year 2100 and upgrade server-side timestamps to BIGINT
    if (*t > (uint32_t)-1) *t = (uint32_t)-1;
    else if (*t < 0) *t = 0;
}

bool FileSystemAccess::islchex(char c) const
{
    return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
}

const char *FileSystemAccess::fstypetostring(FileSystemType type) const
{
    switch (type)
    {
        case FS_NTFS:
            return "NTFS";
        case FS_EXFAT:
            return "EXFAT";
        case FS_FAT32:
            return "FAT32";
        case FS_EXT:
            return "EXT";
        case FS_HFS:
            return "HFS";
        case FS_APFS:
            return "APFS";
        case FS_FUSE:
            return "FUSE";
        case FS_SDCARDFS:
            return "SDCARDFS";
        case FS_F2FS:
            return "F2FS";
        case FS_UNKNOWN:    // fall through
            return "UNKNOWN FS";
    }

    return "UNKNOWN FS";
}

FileSystemType FileSystemAccess::getlocalfstype(const string *dstPath) const
{
    if (!dstPath || dstPath->empty())
    {
        return FS_UNKNOWN;
    }

#if defined (__linux__) && !defined (__ANDROID__)
    // Filesystem detection for Linux
    struct statfs fileStat;
    if (!statfs(dstPath->c_str(), &fileStat))
    {
        switch (fileStat.f_type)
        {
            case EXT2_SUPER_MAGIC:
                return FS_EXT;
            case MSDOS_SUPER_MAGIC:
                return FS_FAT32;
            case HFS_SUPER_MAGIC:
                return FS_HFS;
            case NTFS_SB_MAGIC:
                return FS_NTFS;
            default:
                return FS_UNKNOWN;
        }
    }
#elif defined (__ANDROID__)
    // Filesystem detection for Android
    struct statfs fileStat;
    if (!statfs(dstPath->c_str(), &fileStat))
    {
        switch (fileStat.f_type)
        {
            case EXT2_SUPER_MAGIC:
                return FS_EXT;
            case MSDOS_SUPER_MAGIC:
                return FS_FAT32;
            case HFS_SUPER_MAGIC:
                return FS_HFS;
            case NTFS_SB_MAGIC:
                return FS_NTFS;
            case SDCARDFS_SUPER_MAGIC:
                return FS_SDCARDFS;
            case FUSEBLK_SUPER_MAGIC:
            case FUSECTL_SUPER_MAGIC:
                return FS_FUSE;
            case F2FS_SUPER_MAGIC:
                return FS_F2FS;
            default:
                return FS_UNKNOWN;
        }
    }
#elif defined  (__APPLE__) || defined (USE_IOS)
    // Filesystem detection for Apple and iOS
    struct statfs fileStat;
    if (!statfs(dstPath->c_str(), &fileStat))
    {
        if (!strcmp(fileStat.f_fstypename, "apfs"))
        {
            return FS_APFS;
        }
        if (!strcmp(fileStat.f_fstypename, "hfs"))
        {
            return FS_HFS;
        }
        if (!strcmp(fileStat.f_fstypename, "ntfs"))
        {
            return FS_NTFS;
        }
        if (!strcmp(fileStat.f_fstypename, "msdos"))
        {
            return FS_FAT32;
        }
    }
#elif defined(_WIN32) || defined(WINDOWS_PHONE)
    // Filesystem detection for Windows
    std::wstring wPath(dstPath->begin(), dstPath->end());
    std::wstring volMountPoint;
    volMountPoint.resize(MAX_PATH);
    DWORD mountLen = static_cast<DWORD>(volMountPoint.size());
    if (!(GetVolumePathNameW(wPath.c_str(), &volMountPoint[0], mountLen)))
    {
        return FS_UNKNOWN;
    }

    LPCWSTR auxMountPoint = volMountPoint.c_str();
    WCHAR volumeName[MAX_PATH + 1] = { 0 };
    WCHAR fileSystemName[MAX_PATH + 1] = { 0 };
    DWORD serialNumber = 0;
    DWORD maxComponentLen = 0;
    DWORD fileSystemFlags = 0;

    if (GetVolumeInformationW(auxMountPoint, volumeName, sizeof(volumeName),
                             &serialNumber, &maxComponentLen, &fileSystemFlags,
                             fileSystemName, sizeof(fileSystemName)))
    {
        if (!wcscmp(fileSystemName, L"NTFS"))<commit_msg>do encoding conversion (path2local), before calling W methos in getFileSystemType, to fix case when the important part of the path has non ASCII characters (e.g: samba share with non ascii characters in folder name)<commit_after>/**
 * @file filesystem.cpp
 * @brief Generic host filesystem access interfaces
 *
 * (c) 2013-2014 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */
#include "mega/filesystem.h"
#include "mega/node.h"
#include "mega/megaclient.h"
#include "mega/logging.h"
#include "mega/mega_utf8proc.h"

namespace mega {
FileSystemAccess::FileSystemAccess()
    : waiter(NULL)
    , skip_errorreport(false)
    , transient_error(false)
    , notifyerr(false)
    , notifyfailed(false)
    , target_exists(false)
    , client(NULL)
{
}

void FileSystemAccess::captimestamp(m_time_t* t)
{
    // FIXME: remove upper bound before the year 2100 and upgrade server-side timestamps to BIGINT
    if (*t > (uint32_t)-1) *t = (uint32_t)-1;
    else if (*t < 0) *t = 0;
}

bool FileSystemAccess::islchex(char c) const
{
    return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
}

const char *FileSystemAccess::fstypetostring(FileSystemType type) const
{
    switch (type)
    {
        case FS_NTFS:
            return "NTFS";
        case FS_EXFAT:
            return "EXFAT";
        case FS_FAT32:
            return "FAT32";
        case FS_EXT:
            return "EXT";
        case FS_HFS:
            return "HFS";
        case FS_APFS:
            return "APFS";
        case FS_FUSE:
            return "FUSE";
        case FS_SDCARDFS:
            return "SDCARDFS";
        case FS_F2FS:
            return "F2FS";
        case FS_UNKNOWN:    // fall through
            return "UNKNOWN FS";
    }

    return "UNKNOWN FS";
}

FileSystemType FileSystemAccess::getlocalfstype(const string *dstPath) const
{
    if (!dstPath || dstPath->empty())
    {
        return FS_UNKNOWN;
    }

#if defined (__linux__) && !defined (__ANDROID__)
    // Filesystem detection for Linux
    struct statfs fileStat;
    if (!statfs(dstPath->c_str(), &fileStat))
    {
        switch (fileStat.f_type)
        {
            case EXT2_SUPER_MAGIC:
                return FS_EXT;
            case MSDOS_SUPER_MAGIC:
                return FS_FAT32;
            case HFS_SUPER_MAGIC:
                return FS_HFS;
            case NTFS_SB_MAGIC:
                return FS_NTFS;
            default:
                return FS_UNKNOWN;
        }
    }
#elif defined (__ANDROID__)
    // Filesystem detection for Android
    struct statfs fileStat;
    if (!statfs(dstPath->c_str(), &fileStat))
    {
        switch (fileStat.f_type)
        {
            case EXT2_SUPER_MAGIC:
                return FS_EXT;
            case MSDOS_SUPER_MAGIC:
                return FS_FAT32;
            case HFS_SUPER_MAGIC:
                return FS_HFS;
            case NTFS_SB_MAGIC:
                return FS_NTFS;
            case SDCARDFS_SUPER_MAGIC:
                return FS_SDCARDFS;
            case FUSEBLK_SUPER_MAGIC:
            case FUSECTL_SUPER_MAGIC:
                return FS_FUSE;
            case F2FS_SUPER_MAGIC:
                return FS_F2FS;
            default:
                return FS_UNKNOWN;
        }
    }
#elif defined  (__APPLE__) || defined (USE_IOS)
    // Filesystem detection for Apple and iOS
    struct statfs fileStat;
    if (!statfs(dstPath->c_str(), &fileStat))
    {
        if (!strcmp(fileStat.f_fstypename, "apfs"))
        {
            return FS_APFS;
        }
        if (!strcmp(fileStat.f_fstypename, "hfs"))
        {
            return FS_HFS;
        }
        if (!strcmp(fileStat.f_fstypename, "ntfs"))
        {
            return FS_NTFS;
        }
        if (!strcmp(fileStat.f_fstypename, "msdos"))
        {
            return FS_FAT32;
        }
    }
#elif defined(_WIN32) || defined(WINDOWS_PHONE)
    // Filesystem detection for Windows

    string utf8path = *dstPath;
    string localpath;
    path2local(&utf8path, &localpath);
    std::wstring volMountPoint;
    volMountPoint.resize(MAX_PATH);
    DWORD mountLen = static_cast<DWORD>(volMountPoint.size());
    if (!(GetVolumePathNameW((LPCWSTR)localpath.data(), &volMountPoint[0], mountLen)))
    {
        return FS_UNKNOWN;
    }

    LPCWSTR auxMountPoint = volMountPoint.c_str();
    WCHAR volumeName[MAX_PATH + 1] = { 0 };
    WCHAR fileSystemName[MAX_PATH + 1] = { 0 };
    DWORD serialNumber = 0;
    DWORD maxComponentLen = 0;
    DWORD fileSystemFlags = 0;

    if (GetVolumeInformationW(auxMountPoint, volumeName, sizeof(volumeName),
                             &serialNumber, &maxComponentLen, &fileSystemFlags,
                             fileSystemName, sizeof(fileSystemName)))
    {
        if (!wcscmp(fileSystemName, L"NTFS"))
{'fraction_non_alphanumeric': 0.09686168151879117, 'fraction_numerical': 0.010073614877954282, 'mean_word_length': 2.133535660091047, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4779919', 'n_tokens_mistral': 3419, 'n_tokens_neox': 3233, 'n_words': 834}