Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sal / osl / unx / file_volume.cxx
blob5e661bd656c353517996808acc7c668b96470046
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <osl/file.h>
24 #include <osl/diagnose.h>
25 #include <osl/thread.h>
26 #include <rtl/alloc.h>
28 #include "file_error_transl.hxx"
29 #include "file_url.hxx"
30 #include "system.hxx"
32 #include <errno.h>
33 #include <limits.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <sys/wait.h>
38 #include <sal/macros.h>
40 #ifdef HAVE_STATFS_H
41 #undef HAVE_STATFS_H
42 #endif
44 #if defined(LINUX) && defined(__FreeBSD_kernel__)
45 #undef LINUX
46 #define FREEBSD 1
47 #endif
49 #if defined(__sun)
51 #include <sys/mnttab.h>
52 #include <sys/statvfs.h>
53 #define HAVE_STATFS_H
55 #elif defined(LINUX)
57 #include <mntent.h>
58 #include <sys/vfs.h>
59 #define HAVE_STATFS_H
61 #elif defined(NETBSD) || defined(FREEBSD) || defined(OPENBSD) || defined(DRAGONFLY)
63 #include <sys/param.h>
64 #include <sys/ucred.h>
65 #include <sys/mount.h>
66 #define HAVE_STATFS_H
68 #elif defined(MACOSX)
70 #include <sys/param.h>
71 #include <sys/mount.h>
72 #define HAVE_STATFS_H
74 #endif /* HAVE_STATFS_H */
76 /************************************************************************
77 * ToDo
79 * - Fix: check for corresponding struct sizes in exported functions
80 * - check size/use of oslVolumeInfo
81 ***********************************************************************/
83 /******************************************************************************
85 * C-String Function Declarations
87 *****************************************************************************/
89 static oslFileError osl_psz_getVolumeInformation(const char* , oslVolumeInfo* pInfo, sal_uInt32 uFieldMask);
91 /****************************************************************************/
92 /* osl_getVolumeInformation */
93 /****************************************************************************/
95 oslFileError osl_getVolumeInformation( rtl_uString* ustrDirectoryURL, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask )
97 char path[PATH_MAX];
98 oslFileError eRet;
100 OSL_ASSERT( ustrDirectoryURL );
101 OSL_ASSERT( pInfo );
103 /* convert directory url to system path */
104 eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
105 if( eRet != osl_File_E_None )
106 return eRet;
108 #ifdef MACOSX
109 if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
110 return oslTranslateFileError( errno );
111 #endif/* MACOSX */
113 return osl_psz_getVolumeInformation( path, pInfo, uFieldMask);
116 /******************************************************************************
118 * C-String Versions of Exported Module Functions
120 *****************************************************************************/
122 #ifdef HAVE_STATFS_H
124 #if defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD) || defined(DRAGONFLY)
125 # define OSL_detail_STATFS_STRUCT struct statfs
126 # define OSL_detail_STATFS(dir, sfs) statfs((dir), (sfs))
127 # define OSL_detail_STATFS_BLKSIZ(a) (static_cast<sal_uInt64>((a).f_bsize))
128 # define OSL_detail_STATFS_TYPENAME(a) ((a).f_fstypename)
129 #if defined(OPENBSD)
130 # define OSL_detail_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_fstypename, "nfs") == 0)
131 #else
132 # define OSL_detail_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
133 #endif
135 /* always return true if queried for the properties of
136 the file system. If you think this is wrong under any
137 of the target platforms fix it!!!! */
138 # define OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(a) (true)
139 # define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (true)
140 #endif /* FREEBSD || MACOSX || OPENBSD */
142 #if defined(NETBSD)
144 # define OSL_detail_STATFS_STRUCT struct statvfs
145 # define OSL_detail_STATFS(dir, sfs) statvfs((dir), (sfs))
146 # define OSL_detail_STATFS_ISREMOTE(a) (((a).f_flag & ST_LOCAL) == 0)
148 # define OSL_detail_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
149 # define OSL_detail_STATFS_TYPENAME(a) ((a).f_fstypename)
151 # 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)
152 # define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (strcmp((a).f_fstypename, "msdos") != 0)
153 #endif /* NETBSD */
155 #if defined(LINUX)
156 # define OSL_detail_NFS_SUPER_MAGIC 0x6969
157 # define OSL_detail_SMB_SUPER_MAGIC 0x517B
158 # define OSL_detail_MSDOS_SUPER_MAGIC 0x4d44
159 # define OSL_detail_NTFS_SUPER_MAGIC 0x5346544e
160 # define OSL_detail_STATFS_STRUCT struct statfs
161 # define OSL_detail_STATFS(dir, sfs) statfs((dir), (sfs))
162 # define OSL_detail_STATFS_BLKSIZ(a) (static_cast<sal_uInt64>((a).f_bsize))
163 # define OSL_detail_STATFS_IS_NFS(a) (OSL_detail_NFS_SUPER_MAGIC == (a).f_type)
164 # define OSL_detail_STATFS_IS_SMB(a) (OSL_detail_SMB_SUPER_MAGIC == (a).f_type)
165 # define OSL_detail_STATFS_ISREMOTE(a) (OSL_detail_STATFS_IS_NFS((a)) || OSL_detail_STATFS_IS_SMB((a)))
166 # 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))
167 # define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) ((OSL_detail_MSDOS_SUPER_MAGIC != (a).f_type))
168 #endif /* LINUX */
170 #if defined(__sun)
171 # define OSL_detail_STATFS_STRUCT struct statvfs
172 # define OSL_detail_STATFS(dir, sfs) statvfs((dir), (sfs))
173 # define OSL_detail_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
174 # define OSL_detail_STATFS_TYPENAME(a) ((a).f_basetype)
175 # define OSL_detail_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
177 /* always return true if queried for the properties of
178 the file system. If you think this is wrong under any
179 of the target platforms fix it!!!! */
180 # define OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(a) (true)
181 # define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (true)
182 #endif /* __sun */
184 # define OSL_detail_STATFS_INIT(a) (memset(&(a), 0, sizeof(OSL_detail_STATFS_STRUCT)))
186 #else /* no statfs available */
188 # define OSL_detail_STATFS_STRUCT struct dummy {int i;}
189 # define OSL_detail_STATFS_INIT(a) ((void)a)
190 # define OSL_detail_STATFS(dir, sfs) (1)
191 # define OSL_detail_STATFS_ISREMOTE(sfs) (false)
192 # define OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(a) (true)
193 # define OSL_detail_STATFS_IS_CASE_PRESERVING_FS(a) (true)
194 #endif /* HAVE_STATFS_H */
196 static oslFileError osl_psz_getVolumeInformation (
197 const char* pszDirectory, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask)
199 if (!pInfo)
200 return osl_File_E_INVAL;
202 pInfo->uValidFields = 0;
203 pInfo->uAttributes = 0;
204 pInfo->uTotalSpace = 0;
205 pInfo->uFreeSpace = 0;
206 pInfo->uUsedSpace = 0;
208 if ((uFieldMask
209 & (osl_VolumeInfo_Mask_Attributes | osl_VolumeInfo_Mask_TotalSpace
210 | osl_VolumeInfo_Mask_UsedSpace | osl_VolumeInfo_Mask_FreeSpace
211 | osl_VolumeInfo_Mask_FileSystemName
212 | osl_VolumeInfo_Mask_FileSystemCaseHandling))
213 != 0)
215 OSL_detail_STATFS_STRUCT sfs;
216 OSL_detail_STATFS_INIT(sfs);
217 // coverity[fs_check_call : FALSE]
218 if ((OSL_detail_STATFS(pszDirectory, &sfs)) < (0))
220 oslFileError result = oslTranslateFileError(errno);
221 return result;
224 /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
225 if (uFieldMask & osl_VolumeInfo_Mask_Attributes)
227 bool const remote = OSL_detail_STATFS_ISREMOTE(sfs);
228 // extracted from the 'if' to avoid Clang -Wunreachable-code
229 if (remote)
230 pInfo->uAttributes |= osl_Volume_Attribute_Remote;
232 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
235 if (uFieldMask & osl_VolumeInfo_Mask_FileSystemCaseHandling)
237 if (OSL_detail_STATFS_IS_CASE_SENSITIVE_FS(sfs))
238 pInfo->uAttributes |= osl_Volume_Attribute_Case_Sensitive;
240 if (OSL_detail_STATFS_IS_CASE_PRESERVING_FS(sfs))
241 pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
243 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
246 #if defined(OSL_detail_STATFS_BLKSIZ)
248 if ((uFieldMask & osl_VolumeInfo_Mask_TotalSpace) ||
249 (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
251 pInfo->uTotalSpace = OSL_detail_STATFS_BLKSIZ(sfs);
252 pInfo->uTotalSpace *= static_cast<sal_uInt64>(sfs.f_blocks);
253 pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace;
256 if ((uFieldMask & osl_VolumeInfo_Mask_FreeSpace) ||
257 (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
259 pInfo->uFreeSpace = OSL_detail_STATFS_BLKSIZ(sfs);
261 if (getuid() == 0)
262 pInfo->uFreeSpace *= static_cast<sal_uInt64>(sfs.f_bfree);
263 else
264 pInfo->uFreeSpace *= static_cast<sal_uInt64>(sfs.f_bavail);
266 pInfo->uValidFields |= osl_VolumeInfo_Mask_FreeSpace;
269 if ((pInfo->uValidFields & osl_VolumeInfo_Mask_TotalSpace) &&
270 (pInfo->uValidFields & osl_VolumeInfo_Mask_FreeSpace ))
272 pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
273 pInfo->uValidFields |= osl_VolumeInfo_Mask_UsedSpace;
276 #endif /* OSL_detail_STATFS_BLKSIZ */
278 #if defined(OSL_detail_STATFS_TYPENAME)
280 if (uFieldMask & osl_VolumeInfo_Mask_FileSystemName)
282 rtl_string2UString(
283 &(pInfo->ustrFileSystemName),
284 OSL_detail_STATFS_TYPENAME(sfs),
285 rtl_str_getLength(OSL_detail_STATFS_TYPENAME(sfs)),
286 osl_getThreadTextEncoding(),
287 OUSTRING_TO_OSTRING_CVTFLAGS);
288 OSL_ASSERT(pInfo->ustrFileSystemName != nullptr);
290 pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
293 #endif /* OSL_detail_STATFS_TYPENAME */
296 pInfo->uMaxNameLength = 0;
297 if (uFieldMask & osl_VolumeInfo_Mask_MaxNameLength)
299 long nLen = pathconf(pszDirectory, _PC_NAME_MAX);
300 if (nLen > 0)
302 pInfo->uMaxNameLength = static_cast<sal_uInt32>(nLen);
303 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
307 pInfo->uMaxPathLength = 0;
308 if (uFieldMask & osl_VolumeInfo_Mask_MaxPathLength)
310 long nLen = pathconf (pszDirectory, _PC_PATH_MAX);
311 if (nLen > 0)
313 pInfo->uMaxPathLength = static_cast<sal_uInt32>(nLen);
314 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
318 return osl_File_E_None;
321 oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle, rtl_uString ** )
323 return osl_File_E_INVAL;
326 oslFileError osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle )
328 return osl_File_E_INVAL;
331 oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle )
333 return osl_File_E_INVAL;
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */