Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  file_volume.cxx   Sprache: 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 "file_error_transl.hxx"
#include "file_url.hxx"
#include "system.hxx"

#include <errno.h>
#include <limits.h>
#include <string.h>
#include <unistd.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 <sys/statfs.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: */

Messung V0.5
C=92 H=94 G=92

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge