1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
24 #include <osl/diagnose.h>
25 #include <osl/thread.h>
27 #include "file_error_transl.hxx"
28 #include "file_url.hxx"
40 #if defined(LINUX) && defined(__FreeBSD_kernel__)
47 #include <sys/mnttab.h>
48 #include <sys/statvfs.h>
52 #include <sys/statfs.h>
55 #elif defined(NETBSD) || defined(FREEBSD) || defined(OPENBSD) || defined(DRAGONFLY)
57 #include <sys/param.h>
58 #include <sys/ucred.h>
59 #include <sys/mount.h>
64 #include <sys/param.h>
65 #include <sys/mount.h>
68 #endif /* HAVE_STATFS_H */
70 /************************************************************************
73 * - Fix: check for corresponding struct sizes in exported functions
74 * - check size/use of oslVolumeInfo
75 ***********************************************************************/
77 /******************************************************************************
79 * C-String Function Declarations
81 *****************************************************************************/
83 static oslFileError
osl_psz_getVolumeInformation(const char* , oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
);
85 /****************************************************************************/
86 /* osl_getVolumeInformation */
87 /****************************************************************************/
89 oslFileError
osl_getVolumeInformation( rtl_uString
* ustrDirectoryURL
, oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
)
94 OSL_ASSERT( ustrDirectoryURL
);
97 /* convert directory url to system path */
98 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
99 if( eRet
!= osl_File_E_None
)
103 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
104 return oslTranslateFileError( errno
);
107 return osl_psz_getVolumeInformation( path
, pInfo
, uFieldMask
);
110 /******************************************************************************
112 * C-String Versions of Exported Module Functions
114 *****************************************************************************/
118 #if defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD) || defined(DRAGONFLY)
119 # define OSL_detail_STATFS_STRUCT struct statfs
120 # define OSL_detail_STATFS(dir, sfs) statfs((dir), (sfs))
121 # define OSL_detail_STATFS_BLKSIZ(a) (static_cast<sal_uInt64>((a).f_bsize))
122 # define OSL_detail_STATFS_TYPENAME(a) ((a).f_fstypename)
124 # define OSL_detail_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_fstypename, "nfs") == 0)
126 # define OSL_detail_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
129 /* always return true if queried for the properties of
130 the file system. If you think this is wrong under any
131 of the target platforms fix it!!!! */
132 # define OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(a) (true)
133 # define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (true)
134 #endif /* FREEBSD || MACOSX || OPENBSD */
138 # define OSL_detail_STATFS_STRUCT struct statvfs
139 # define OSL_detail_STATFS(dir, sfs) statvfs((dir), (sfs))
140 # define OSL_detail_STATFS_ISREMOTE(a) (((a).f_flag & ST_LOCAL) == 0)
142 # define OSL_detail_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
143 # define OSL_detail_STATFS_TYPENAME(a) ((a).f_fstypename)
145 # 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)
146 # define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (strcmp((a).f_fstypename, "msdos") != 0)
150 # define OSL_detail_NFS_SUPER_MAGIC 0x6969
151 # define OSL_detail_SMB_SUPER_MAGIC 0x517B
152 # define OSL_detail_MSDOS_SUPER_MAGIC 0x4d44
153 # define OSL_detail_NTFS_SUPER_MAGIC 0x5346544e
154 # define OSL_detail_STATFS_STRUCT struct statfs
155 # define OSL_detail_STATFS(dir, sfs) statfs((dir), (sfs))
156 # define OSL_detail_STATFS_BLKSIZ(a) (static_cast<sal_uInt64>((a).f_bsize))
157 # define OSL_detail_STATFS_IS_NFS(a) (OSL_detail_NFS_SUPER_MAGIC == (a).f_type)
158 # define OSL_detail_STATFS_IS_SMB(a) (OSL_detail_SMB_SUPER_MAGIC == (a).f_type)
159 # define OSL_detail_STATFS_ISREMOTE(a) (OSL_detail_STATFS_IS_NFS((a)) || OSL_detail_STATFS_IS_SMB((a)))
160 # 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))
161 # define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) ((OSL_detail_MSDOS_SUPER_MAGIC != (a).f_type))
165 # define OSL_detail_STATFS_STRUCT struct statvfs
166 # define OSL_detail_STATFS(dir, sfs) statvfs((dir), (sfs))
167 # define OSL_detail_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
168 # define OSL_detail_STATFS_TYPENAME(a) ((a).f_basetype)
169 # define OSL_detail_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
171 /* always return true if queried for the properties of
172 the file system. If you think this is wrong under any
173 of the target platforms fix it!!!! */
174 # define OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(a) (true)
175 # define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (true)
178 # define OSL_detail_STATFS_INIT(a) (memset(&(a), 0, sizeof(OSL_detail_STATFS_STRUCT)))
180 #else /* no statfs available */
182 # define OSL_detail_STATFS_STRUCT struct dummy {int i;}
183 # define OSL_detail_STATFS_INIT(a) ((void)a)
184 # define OSL_detail_STATFS(dir, sfs) (1)
185 # define OSL_detail_STATFS_ISREMOTE(sfs) (false)
186 # define OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(a) (true)
187 # define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (true)
188 #endif /* HAVE_STATFS_H */
190 static oslFileError
osl_psz_getVolumeInformation (
191 const char* pszDirectory
, oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
)
194 return osl_File_E_INVAL
;
196 pInfo
->uValidFields
= 0;
197 pInfo
->uAttributes
= 0;
198 pInfo
->uTotalSpace
= 0;
199 pInfo
->uFreeSpace
= 0;
200 pInfo
->uUsedSpace
= 0;
203 & (osl_VolumeInfo_Mask_Attributes
| osl_VolumeInfo_Mask_TotalSpace
204 | osl_VolumeInfo_Mask_UsedSpace
| osl_VolumeInfo_Mask_FreeSpace
205 | osl_VolumeInfo_Mask_FileSystemName
206 | osl_VolumeInfo_Mask_FileSystemCaseHandling
))
209 OSL_detail_STATFS_STRUCT sfs
;
210 OSL_detail_STATFS_INIT(sfs
);
211 // coverity[fs_check_call : FALSE]
212 if ((OSL_detail_STATFS(pszDirectory
, &sfs
)) < (0))
214 oslFileError result
= oslTranslateFileError(errno
);
218 /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
219 if (uFieldMask
& osl_VolumeInfo_Mask_Attributes
)
221 bool const remote
= OSL_detail_STATFS_ISREMOTE(sfs
);
222 // extracted from the 'if' to avoid Clang -Wunreachable-code
224 pInfo
->uAttributes
|= osl_Volume_Attribute_Remote
;
226 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
229 if (uFieldMask
& osl_VolumeInfo_Mask_FileSystemCaseHandling
)
231 if (OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(sfs
))
232 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Sensitive
;
234 if (OSL_detail_STATFS_IS_CASE_PRESERVING_FS(sfs
))
235 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Is_Preserved
;
237 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
240 #if defined(OSL_detail_STATFS_BLKSIZ)
242 if ((uFieldMask
& osl_VolumeInfo_Mask_TotalSpace
) ||
243 (uFieldMask
& osl_VolumeInfo_Mask_UsedSpace
))
245 pInfo
->uTotalSpace
= OSL_detail_STATFS_BLKSIZ(sfs
);
246 pInfo
->uTotalSpace
*= static_cast<sal_uInt64
>(sfs
.f_blocks
);
247 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_TotalSpace
;
250 if ((uFieldMask
& osl_VolumeInfo_Mask_FreeSpace
) ||
251 (uFieldMask
& osl_VolumeInfo_Mask_UsedSpace
))
253 pInfo
->uFreeSpace
= OSL_detail_STATFS_BLKSIZ(sfs
);
256 pInfo
->uFreeSpace
*= static_cast<sal_uInt64
>(sfs
.f_bfree
);
258 pInfo
->uFreeSpace
*= static_cast<sal_uInt64
>(sfs
.f_bavail
);
260 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FreeSpace
;
263 if ((pInfo
->uValidFields
& osl_VolumeInfo_Mask_TotalSpace
) &&
264 (pInfo
->uValidFields
& osl_VolumeInfo_Mask_FreeSpace
))
266 pInfo
->uUsedSpace
= pInfo
->uTotalSpace
- pInfo
->uFreeSpace
;
267 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_UsedSpace
;
270 #endif /* OSL_detail_STATFS_BLKSIZ */
272 #if defined(OSL_detail_STATFS_TYPENAME)
274 if (uFieldMask
& osl_VolumeInfo_Mask_FileSystemName
)
277 &(pInfo
->ustrFileSystemName
),
278 OSL_detail_STATFS_TYPENAME(sfs
),
279 rtl_str_getLength(OSL_detail_STATFS_TYPENAME(sfs
)),
280 osl_getThreadTextEncoding(),
281 OUSTRING_TO_OSTRING_CVTFLAGS
);
282 OSL_ASSERT(pInfo
->ustrFileSystemName
!= nullptr);
284 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FileSystemName
;
287 #endif /* OSL_detail_STATFS_TYPENAME */
290 pInfo
->uMaxNameLength
= 0;
291 if (uFieldMask
& osl_VolumeInfo_Mask_MaxNameLength
)
293 long nLen
= pathconf(pszDirectory
, _PC_NAME_MAX
);
296 pInfo
->uMaxNameLength
= static_cast<sal_uInt32
>(nLen
);
297 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxNameLength
;
301 pInfo
->uMaxPathLength
= 0;
302 if (uFieldMask
& osl_VolumeInfo_Mask_MaxPathLength
)
304 long nLen
= pathconf (pszDirectory
, _PC_PATH_MAX
);
307 pInfo
->uMaxPathLength
= static_cast<sal_uInt32
>(nLen
);
308 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxPathLength
;
312 return osl_File_E_None
;
315 oslFileError
osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle
, rtl_uString
** )
317 return osl_File_E_INVAL
;
320 oslFileError
osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle
)
322 return osl_File_E_INVAL
;
325 oslFileError
osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle
)
327 return osl_File_E_INVAL
;
330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */