office-gobmx/sal/osl/unx/file_volume.cxx
Noel Grandin e994b3fc3b sal_Char->char in remotebridges..sax
Change-Id: I6d32942960a5e997f16eb1301c45495661cd4cea
Reviewed-on: https://gerrit.libreoffice.org/85514
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2019-12-19 19:17:57 +01:00

336 lines
12 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <sal/config.h>
#include <osl/file.h>
#include <osl/diagnose.h>
#include <osl/thread.h>
#include <rtl/alloc.h>
#include "file_error_transl.hxx"
#include "file_url.hxx"
#include "system.hxx"
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sal/macros.h>
#ifdef HAVE_STATFS_H
#undef HAVE_STATFS_H
#endif
#if defined(LINUX) && defined(__FreeBSD_kernel__)
#undef LINUX
#define FREEBSD 1
#endif
#if defined(__sun)
#include <sys/mnttab.h>
#include <sys/statvfs.h>
#define HAVE_STATFS_H
#elif defined(LINUX)
#include <mntent.h>
#include <sys/vfs.h>
#define HAVE_STATFS_H
#elif defined(NETBSD) || defined(FREEBSD) || defined(OPENBSD) || defined(DRAGONFLY)
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#define HAVE_STATFS_H
#elif defined(MACOSX)
#include <sys/param.h>
#include <sys/mount.h>
#define HAVE_STATFS_H
#endif /* HAVE_STATFS_H */
/************************************************************************
* ToDo
*
* - Fix: check for corresponding struct sizes in exported functions
* - check size/use of oslVolumeInfo
***********************************************************************/
/******************************************************************************
*
* C-String Function Declarations
*
*****************************************************************************/
static oslFileError osl_psz_getVolumeInformation(const char* , oslVolumeInfo* pInfo, sal_uInt32 uFieldMask);
/****************************************************************************/
/* osl_getVolumeInformation */
/****************************************************************************/
oslFileError osl_getVolumeInformation( rtl_uString* ustrDirectoryURL, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask )
{
char path[PATH_MAX];
oslFileError eRet;
OSL_ASSERT( ustrDirectoryURL );
OSL_ASSERT( pInfo );
/* convert directory url to system path */
eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
if( eRet != osl_File_E_None )
return eRet;
#ifdef MACOSX
if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
return oslTranslateFileError( errno );
#endif/* MACOSX */
return osl_psz_getVolumeInformation( path, pInfo, uFieldMask);
}
/******************************************************************************
*
* C-String Versions of Exported Module Functions
*
*****************************************************************************/
#ifdef HAVE_STATFS_H
#if defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD) || defined(DRAGONFLY)
# define OSL_detail_STATFS_STRUCT struct statfs
# define OSL_detail_STATFS(dir, sfs) statfs((dir), (sfs))
# define OSL_detail_STATFS_BLKSIZ(a) (static_cast<sal_uInt64>((a).f_bsize))
# define OSL_detail_STATFS_TYPENAME(a) ((a).f_fstypename)
#if defined(OPENBSD)
# define OSL_detail_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_fstypename, "nfs") == 0)
#else
# define OSL_detail_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
#endif
/* always return true if queried for the properties of
the file system. If you think this is wrong under any
of the target platforms fix it!!!! */
# define OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(a) (true)
# define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (true)
#endif /* FREEBSD || MACOSX || OPENBSD */
#if defined(NETBSD)
# define OSL_detail_STATFS_STRUCT struct statvfs
# define OSL_detail_STATFS(dir, sfs) statvfs((dir), (sfs))
# define OSL_detail_STATFS_ISREMOTE(a) (((a).f_flag & ST_LOCAL) == 0)
# define OSL_detail_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
# define OSL_detail_STATFS_TYPENAME(a) ((a).f_fstypename)
# define OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(a) (strcmp((a).f_fstypename, "msdos") != 0 && strcmp((a).f_fstypename, "ntfs") != 0 && strcmp((a).f_fstypename, "smbfs") != 0)
# define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (strcmp((a).f_fstypename, "msdos") != 0)
#endif /* NETBSD */
#if defined(LINUX)
# define OSL_detail_NFS_SUPER_MAGIC 0x6969
# define OSL_detail_SMB_SUPER_MAGIC 0x517B
# define OSL_detail_MSDOS_SUPER_MAGIC 0x4d44
# define OSL_detail_NTFS_SUPER_MAGIC 0x5346544e
# define OSL_detail_STATFS_STRUCT struct statfs
# define OSL_detail_STATFS(dir, sfs) statfs((dir), (sfs))
# define OSL_detail_STATFS_BLKSIZ(a) (static_cast<sal_uInt64>((a).f_bsize))
# define OSL_detail_STATFS_IS_NFS(a) (OSL_detail_NFS_SUPER_MAGIC == (a).f_type)
# define OSL_detail_STATFS_IS_SMB(a) (OSL_detail_SMB_SUPER_MAGIC == (a).f_type)
# define OSL_detail_STATFS_ISREMOTE(a) (OSL_detail_STATFS_IS_NFS((a)) || OSL_detail_STATFS_IS_SMB((a)))
# define OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(a) ((OSL_detail_MSDOS_SUPER_MAGIC != (a).f_type) && (OSL_detail_NTFS_SUPER_MAGIC != (a).f_type))
# define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) ((OSL_detail_MSDOS_SUPER_MAGIC != (a).f_type))
#endif /* LINUX */
#if defined(__sun)
# define OSL_detail_STATFS_STRUCT struct statvfs
# define OSL_detail_STATFS(dir, sfs) statvfs((dir), (sfs))
# define OSL_detail_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
# define OSL_detail_STATFS_TYPENAME(a) ((a).f_basetype)
# define OSL_detail_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
/* always return true if queried for the properties of
the file system. If you think this is wrong under any
of the target platforms fix it!!!! */
# define OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(a) (true)
# define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (true)
#endif /* __sun */
# define OSL_detail_STATFS_INIT(a) (memset(&(a), 0, sizeof(OSL_detail_STATFS_STRUCT)))
#else /* no statfs available */
# define OSL_detail_STATFS_STRUCT struct dummy {int i;}
# define OSL_detail_STATFS_INIT(a) ((void)a)
# define OSL_detail_STATFS(dir, sfs) (1)
# define OSL_detail_STATFS_ISREMOTE(sfs) (false)
# define OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(a) (true)
# define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (true)
#endif /* HAVE_STATFS_H */
static oslFileError osl_psz_getVolumeInformation (
const char* pszDirectory, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask)
{
if (!pInfo)
return osl_File_E_INVAL;
pInfo->uValidFields = 0;
pInfo->uAttributes = 0;
pInfo->uTotalSpace = 0;
pInfo->uFreeSpace = 0;
pInfo->uUsedSpace = 0;
if ((uFieldMask
& (osl_VolumeInfo_Mask_Attributes | osl_VolumeInfo_Mask_TotalSpace
| osl_VolumeInfo_Mask_UsedSpace | osl_VolumeInfo_Mask_FreeSpace
| osl_VolumeInfo_Mask_FileSystemName
| osl_VolumeInfo_Mask_FileSystemCaseHandling))
!= 0)
{
OSL_detail_STATFS_STRUCT sfs;
OSL_detail_STATFS_INIT(sfs);
// coverity[fs_check_call : FALSE]
if ((OSL_detail_STATFS(pszDirectory, &sfs)) < (0))
{
oslFileError result = oslTranslateFileError(errno);
return result;
}
/* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
if (uFieldMask & osl_VolumeInfo_Mask_Attributes)
{
bool const remote = OSL_detail_STATFS_ISREMOTE(sfs);
// extracted from the 'if' to avoid Clang -Wunreachable-code
if (remote)
pInfo->uAttributes |= osl_Volume_Attribute_Remote;
pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
}
if (uFieldMask & osl_VolumeInfo_Mask_FileSystemCaseHandling)
{
if (OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(sfs))
pInfo->uAttributes |= osl_Volume_Attribute_Case_Sensitive;
if (OSL_detail_STATFS_IS_CASE_PRESERVING_FS(sfs))
pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
}
#if defined(OSL_detail_STATFS_BLKSIZ)
if ((uFieldMask & osl_VolumeInfo_Mask_TotalSpace) ||
(uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
{
pInfo->uTotalSpace = OSL_detail_STATFS_BLKSIZ(sfs);
pInfo->uTotalSpace *= static_cast<sal_uInt64>(sfs.f_blocks);
pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace;
}
if ((uFieldMask & osl_VolumeInfo_Mask_FreeSpace) ||
(uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
{
pInfo->uFreeSpace = OSL_detail_STATFS_BLKSIZ(sfs);
if (getuid() == 0)
pInfo->uFreeSpace *= static_cast<sal_uInt64>(sfs.f_bfree);
else
pInfo->uFreeSpace *= static_cast<sal_uInt64>(sfs.f_bavail);
pInfo->uValidFields |= osl_VolumeInfo_Mask_FreeSpace;
}
if ((pInfo->uValidFields & osl_VolumeInfo_Mask_TotalSpace) &&
(pInfo->uValidFields & osl_VolumeInfo_Mask_FreeSpace ))
{
pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
pInfo->uValidFields |= osl_VolumeInfo_Mask_UsedSpace;
}
#endif /* OSL_detail_STATFS_BLKSIZ */
#if defined(OSL_detail_STATFS_TYPENAME)
if (uFieldMask & osl_VolumeInfo_Mask_FileSystemName)
{
rtl_string2UString(
&(pInfo->ustrFileSystemName),
OSL_detail_STATFS_TYPENAME(sfs),
rtl_str_getLength(OSL_detail_STATFS_TYPENAME(sfs)),
osl_getThreadTextEncoding(),
OUSTRING_TO_OSTRING_CVTFLAGS);
OSL_ASSERT(pInfo->ustrFileSystemName != nullptr);
pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
}
#endif /* OSL_detail_STATFS_TYPENAME */
}
pInfo->uMaxNameLength = 0;
if (uFieldMask & osl_VolumeInfo_Mask_MaxNameLength)
{
long nLen = pathconf(pszDirectory, _PC_NAME_MAX);
if (nLen > 0)
{
pInfo->uMaxNameLength = static_cast<sal_uInt32>(nLen);
pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
}
}
pInfo->uMaxPathLength = 0;
if (uFieldMask & osl_VolumeInfo_Mask_MaxPathLength)
{
long nLen = pathconf (pszDirectory, _PC_PATH_MAX);
if (nLen > 0)
{
pInfo->uMaxPathLength = static_cast<sal_uInt32>(nLen);
pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
}
}
return osl_File_E_None;
}
oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle, rtl_uString ** )
{
return osl_File_E_INVAL;
}
oslFileError osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle )
{
return osl_File_E_INVAL;
}
oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle )
{
return osl_File_E_INVAL;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */