Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "osl/file.h"
30 : :
31 : : #include "osl/diagnose.h"
32 : : #include "osl/thread.h"
33 : : #include "rtl/alloc.h"
34 : :
35 : : #include "file_error_transl.h"
36 : : #include "file_url.h"
37 : : #include "system.h"
38 : :
39 : : #include <errno.h>
40 : : #include <limits.h>
41 : : #include <stdio.h>
42 : : #include <string.h>
43 : : #include <unistd.h>
44 : : #include <sys/wait.h>
45 : : #include <sal/macros.h>
46 : :
47 : : #ifdef HAVE_STATFS_H
48 : : #undef HAVE_STATFS_H
49 : : #endif
50 : :
51 : : #if defined(LINUX) && defined(__FreeBSD_kernel__)
52 : : #undef LINUX
53 : : #define FREEBSD 1
54 : : #endif
55 : :
56 : :
57 : : #if defined(SOLARIS)
58 : :
59 : : #include <sys/mnttab.h>
60 : : #include <sys/statvfs.h>
61 : : #define HAVE_STATFS_H
62 : :
63 : : #elif defined(LINUX)
64 : :
65 : : #include <mntent.h>
66 : : #include <sys/vfs.h>
67 : : #define HAVE_STATFS_H
68 : :
69 : : #elif defined(NETBSD) || defined(FREEBSD) || defined(OPENBSD) || defined(DRAGONFLY)
70 : :
71 : : #include <sys/param.h>
72 : : #include <sys/ucred.h>
73 : : #include <sys/mount.h>
74 : : #define HAVE_STATFS_H
75 : :
76 : : #elif defined(MACOSX)
77 : :
78 : : #include <sys/param.h>
79 : : #include <sys/mount.h>
80 : : #define HAVE_STATFS_H
81 : :
82 : : #endif /* HAVE_STATFS_H */
83 : :
84 : : /************************************************************************
85 : : * ToDo
86 : : *
87 : : * - Fix: check for corresponding struct sizes in exported functions
88 : : * - check size/use of oslVolumeDeviceHandle
89 : : * - check size/use of oslVolumeInfo
90 : : ***********************************************************************/
91 : : /******************************************************************************
92 : : *
93 : : * Data Type Definition
94 : : *
95 : : ******************************************************************************/
96 : :
97 : : typedef struct _oslVolumeDeviceHandleImpl
98 : : {
99 : : sal_Char pszMountPoint[PATH_MAX];
100 : : sal_Char pszFilePath[PATH_MAX];
101 : : sal_Char pszDevice[PATH_MAX];
102 : : sal_Char ident[4];
103 : : sal_uInt32 RefCount;
104 : : } oslVolumeDeviceHandleImpl;
105 : :
106 : : /******************************************************************************
107 : : *
108 : : * C-String Function Declarations
109 : : *
110 : : *****************************************************************************/
111 : :
112 : : static oslFileError osl_psz_getVolumeInformation(const sal_Char* , oslVolumeInfo* pInfo, sal_uInt32 uFieldMask);
113 : :
114 : : /****************************************************************************/
115 : : /* osl_getVolumeInformation */
116 : : /****************************************************************************/
117 : :
118 : 50 : oslFileError osl_getVolumeInformation( rtl_uString* ustrDirectoryURL, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask )
119 : : {
120 : : char path[PATH_MAX];
121 : : oslFileError eRet;
122 : :
123 : : OSL_ASSERT( ustrDirectoryURL );
124 : : OSL_ASSERT( pInfo );
125 : :
126 : : /* convert directory url to system path */
127 [ + - ]: 50 : eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
128 [ + + ]: 50 : if( eRet != osl_File_E_None )
129 : 5 : return eRet;
130 : :
131 : : #ifdef MACOSX
132 : : if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
133 : : return oslTranslateFileError( OSL_FET_ERROR, errno );
134 : : #endif/* MACOSX */
135 : :
136 [ + - ]: 50 : return osl_psz_getVolumeInformation( path, pInfo, uFieldMask);
137 : : }
138 : :
139 : : /******************************************************************************
140 : : *
141 : : * C-String Versions of Exported Module Functions
142 : : *
143 : : *****************************************************************************/
144 : :
145 : : #ifdef HAVE_STATFS_H
146 : :
147 : : #if defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD) || defined(DRAGONFLY)
148 : : # define __OSL_STATFS_STRUCT struct statfs
149 : : # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
150 : : # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
151 : : # define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
152 : : #if defined(OPENBSD)
153 : : # define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_fstypename, "nfs") == 0)
154 : : #else
155 : : # define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
156 : : #endif
157 : :
158 : : /* always return true if queried for the properties of
159 : : the file system. If you think this is wrong under any
160 : : of the target platforms fix it!!!! */
161 : : # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
162 : : # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
163 : : #endif /* FREEBSD || MACOSX || OPENBSD */
164 : :
165 : : #if defined(NETBSD)
166 : :
167 : : #include <sys/param.h>
168 : :
169 : : /* statvfs() replaced statfs() in 2.99.9 */
170 : : # if __NetBSD_Version__ >= 299000900
171 : : /* 2.0D or later */
172 : : # define __OSL_STATFS_STRUCT struct statvfs
173 : : # define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
174 : : # define __OSL_STATFS_ISREMOTE(a) (((a).f_flag & ST_LOCAL) == 0)
175 : :
176 : : # else
177 : : /* version before 2.0D */
178 : : # define __OSL_STATFS_STRUCT struct statfs
179 : : # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
180 : : # define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
181 : :
182 : : # endif /* >2.0D */
183 : :
184 : : # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
185 : : # define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
186 : :
187 : : # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (strcmp((a).f_fstypename, "msdos") != 0 && strcmp((a).f_fstypename, "ntfs") != 0 && strcmp((a).f_fstypename, "smbfs") != 0)
188 : : # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (strcmp((a).f_fstypename, "msdos") != 0)
189 : : #endif /* NETBSD */
190 : :
191 : : #if defined(LINUX)
192 : : # define __OSL_NFS_SUPER_MAGIC 0x6969
193 : : # define __OSL_SMB_SUPER_MAGIC 0x517B
194 : : # define __OSL_MSDOS_SUPER_MAGIC 0x4d44
195 : : # define __OSL_NTFS_SUPER_MAGIC 0x5346544e
196 : : # define __OSL_STATFS_STRUCT struct statfs
197 : : # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
198 : : # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
199 : : # define __OSL_STATFS_IS_NFS(a) (__OSL_NFS_SUPER_MAGIC == (a).f_type)
200 : : # define __OSL_STATFS_IS_SMB(a) (__OSL_SMB_SUPER_MAGIC == (a).f_type)
201 : : # define __OSL_STATFS_ISREMOTE(a) (__OSL_STATFS_IS_NFS((a)) || __OSL_STATFS_IS_SMB((a)))
202 : : # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type) && (__OSL_NTFS_SUPER_MAGIC != (a).f_type))
203 : : # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type))
204 : : #endif /* LINUX */
205 : :
206 : : #if defined(SOLARIS)
207 : : # define __OSL_STATFS_STRUCT struct statvfs
208 : : # define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
209 : : # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
210 : : # define __OSL_STATFS_TYPENAME(a) ((a).f_basetype)
211 : : # define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
212 : :
213 : : /* always return true if queried for the properties of
214 : : the file system. If you think this is wrong under any
215 : : of the target platforms fix it!!!! */
216 : : # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
217 : : # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
218 : : #endif /* SOLARIS */
219 : :
220 : : # define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
221 : :
222 : : #else /* no statfs available */
223 : :
224 : : # define __OSL_STATFS_STRUCT struct dummy {int i;}
225 : : # define __OSL_STATFS_INIT(a) ((void)a)
226 : : # define __OSL_STATFS(dir, sfs) (1)
227 : : # define __OSL_STATFS_ISREMOTE(sfs) (0)
228 : : # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
229 : : # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
230 : : #endif /* HAVE_STATFS_H */
231 : :
232 : :
233 : 45 : static oslFileError osl_psz_getVolumeInformation (
234 : : const sal_Char* pszDirectory, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask)
235 : : {
236 : : __OSL_STATFS_STRUCT sfs;
237 : :
238 [ - + ]: 45 : if (!pInfo)
239 : 0 : return osl_File_E_INVAL;
240 : :
241 : 45 : __OSL_STATFS_INIT(sfs);
242 : :
243 : 45 : pInfo->uValidFields = 0;
244 : 45 : pInfo->uAttributes = 0;
245 : :
246 [ + + ]: 45 : if ((__OSL_STATFS(pszDirectory, &sfs)) < 0)
247 : : {
248 [ + - ]: 5 : oslFileError result = oslTranslateFileError(OSL_FET_ERROR, errno);
249 : 5 : return (result);
250 : : }
251 : :
252 : : /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
253 [ + + ]: 40 : if (uFieldMask & osl_VolumeInfo_Mask_Attributes)
254 : : {
255 [ + - ][ - + ]: 5 : if (__OSL_STATFS_ISREMOTE(sfs))
256 : 0 : pInfo->uAttributes |= osl_Volume_Attribute_Remote;
257 : :
258 : 5 : pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
259 : : }
260 : :
261 [ + + ]: 40 : if (uFieldMask & osl_VolumeInfo_Mask_FileSystemCaseHandling)
262 : : {
263 [ + - ][ + - ]: 5 : if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs))
264 : 5 : pInfo->uAttributes |= osl_Volume_Attribute_Case_Sensitive;
265 : :
266 [ + - ]: 5 : if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs))
267 : 5 : pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
268 : :
269 : 5 : pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
270 : : }
271 : :
272 : 40 : pInfo->uTotalSpace = 0;
273 : 40 : pInfo->uFreeSpace = 0;
274 : 40 : pInfo->uUsedSpace = 0;
275 : :
276 : : #if defined(__OSL_STATFS_BLKSIZ)
277 : :
278 [ + + ][ + + ]: 40 : if ((uFieldMask & osl_VolumeInfo_Mask_TotalSpace) ||
279 : : (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
280 : : {
281 : 10 : pInfo->uTotalSpace = __OSL_STATFS_BLKSIZ(sfs);
282 : 10 : pInfo->uTotalSpace *= (sal_uInt64)(sfs.f_blocks);
283 : 10 : pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace;
284 : : }
285 : :
286 [ + + ][ + + ]: 40 : if ((uFieldMask & osl_VolumeInfo_Mask_FreeSpace) ||
287 : : (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
288 : : {
289 : 10 : pInfo->uFreeSpace = __OSL_STATFS_BLKSIZ(sfs);
290 : :
291 [ + - ]: 10 : if (getuid() == 0)
292 : 10 : pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bfree);
293 : : else
294 : 0 : pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bavail);
295 : :
296 : 10 : pInfo->uValidFields |= osl_VolumeInfo_Mask_FreeSpace;
297 : : }
298 : :
299 : : #endif /* __OSL_STATFS_BLKSIZ */
300 : :
301 [ + + ][ + + ]: 40 : if ((pInfo->uValidFields & osl_VolumeInfo_Mask_TotalSpace) &&
302 : : (pInfo->uValidFields & osl_VolumeInfo_Mask_FreeSpace ))
303 : : {
304 : 5 : pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
305 : 5 : pInfo->uValidFields |= osl_VolumeInfo_Mask_UsedSpace;
306 : : }
307 : :
308 : 40 : pInfo->uMaxNameLength = 0;
309 [ + + ]: 40 : if (uFieldMask & osl_VolumeInfo_Mask_MaxNameLength)
310 : : {
311 : 5 : long nLen = pathconf(pszDirectory, _PC_NAME_MAX);
312 [ + - ]: 5 : if (nLen > 0)
313 : : {
314 : 5 : pInfo->uMaxNameLength = (sal_uInt32)nLen;
315 : 5 : pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
316 : : }
317 : : }
318 : :
319 : 40 : pInfo->uMaxPathLength = 0;
320 [ + + ]: 40 : if (uFieldMask & osl_VolumeInfo_Mask_MaxPathLength)
321 : : {
322 : 5 : long nLen = pathconf (pszDirectory, _PC_PATH_MAX);
323 [ + - ]: 5 : if (nLen > 0)
324 : : {
325 : 5 : pInfo->uMaxPathLength = (sal_uInt32)nLen;
326 : 5 : pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
327 : : }
328 : : }
329 : :
330 : : #if defined(__OSL_STATFS_TYPENAME)
331 : :
332 : : if (uFieldMask & osl_VolumeInfo_Mask_FileSystemName)
333 : : {
334 : : rtl_string2UString(
335 : : &(pInfo->ustrFileSystemName),
336 : : __OSL_STATFS_TYPENAME(sfs),
337 : : rtl_str_getLength(__OSL_STATFS_TYPENAME(sfs)),
338 : : osl_getThreadTextEncoding(),
339 : : OUSTRING_TO_OSTRING_CVTFLAGS);
340 : : OSL_ASSERT(pInfo->ustrFileSystemName != 0);
341 : :
342 : : pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
343 : : }
344 : :
345 : : #endif /* __OSL_STATFS_TYPENAME */
346 : :
347 : 45 : return osl_File_E_None;
348 : : }
349 : :
350 : : /******************************************************************************
351 : : *
352 : : * GENERIC FLOPPY FUNCTIONS
353 : : *
354 : : *****************************************************************************/
355 : :
356 : : /*****************************************
357 : : * osl_getVolumeDeviceMountPath
358 : : ****************************************/
359 : 0 : static rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr, rtl_uString** ustrValid)
360 : : {
361 : : rtl_string2UString(
362 : : ustrValid,
363 : : pszStr,
364 : : rtl_str_getLength( pszStr ),
365 : 0 : osl_getThreadTextEncoding(),
366 : 0 : OUSTRING_TO_OSTRING_CVTFLAGS );
367 : : OSL_ASSERT(*ustrValid != 0);
368 : :
369 : 0 : return *ustrValid;
370 : : }
371 : :
372 : 0 : oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
373 : : {
374 : 0 : oslVolumeDeviceHandleImpl* pItem = (oslVolumeDeviceHandleImpl*) Handle;
375 : : sal_Char Buffer[PATH_MAX];
376 : :
377 : 0 : Buffer[0] = '\0';
378 : :
379 [ # # ][ # # ]: 0 : if ( pItem == 0 || pstrPath == 0 )
380 : : {
381 : 0 : return osl_File_E_INVAL;
382 : : }
383 : :
384 [ # # ][ # # ]: 0 : if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
[ # # ][ # # ]
385 : : {
386 : 0 : return osl_File_E_INVAL;
387 : : }
388 : :
389 : 0 : snprintf(Buffer, sizeof(Buffer), "file://%s", pItem->pszMountPoint);
390 : :
391 : : #ifdef DEBUG_OSL_FILE
392 : : fprintf(stderr,"Mount Point is: '%s'\n",Buffer);
393 : : #endif
394 : :
395 [ # # ]: 0 : oslMakeUStrFromPsz(Buffer, pstrPath);
396 : :
397 : 0 : return osl_File_E_None;
398 : : }
399 : :
400 : : /*****************************************
401 : : * osl_acquireVolumeDeviceHandle
402 : : ****************************************/
403 : :
404 : 0 : oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
405 : : {
406 : 0 : oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
407 : :
408 [ # # ]: 0 : if ( pItem == 0 )
409 : : {
410 : 0 : return osl_File_E_INVAL;
411 : : }
412 : :
413 [ # # ][ # # ]: 0 : if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
[ # # ][ # # ]
414 : : {
415 : 0 : return osl_File_E_INVAL;
416 : : }
417 : :
418 : 0 : ++pItem->RefCount;
419 : :
420 : 0 : return osl_File_E_None;
421 : : }
422 : :
423 : : /*****************************************
424 : : * osl_releaseVolumeDeviceHandle
425 : : ****************************************/
426 : :
427 : 0 : oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
428 : : {
429 : 0 : oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
430 : :
431 [ # # ]: 0 : if ( pItem == 0 )
432 : : {
433 : 0 : return osl_File_E_INVAL;
434 : : }
435 : :
436 [ # # ][ # # ]: 0 : if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
[ # # ][ # # ]
437 : : {
438 : 0 : return osl_File_E_INVAL;
439 : : }
440 : :
441 : 0 : --pItem->RefCount;
442 : :
443 [ # # ]: 0 : if ( pItem->RefCount == 0 )
444 : : {
445 : 0 : rtl_freeMemory(pItem);
446 : : }
447 : :
448 : 0 : return osl_File_E_None;
449 : : }
450 : :
451 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|