merged tag ooo/DEV300_m102
[LibreOffice.git] / sal / osl / unx / file_volume.cxx
blobcc7f61ec6a8b18ae398536d671a30835d6ebc1f6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #include "osl/file.h"
30 #include "osl/diagnose.h"
31 #include "osl/thread.h"
32 #include "rtl/alloc.h"
34 #include "file_error_transl.h"
35 #include "file_url.h"
36 #include "system.h"
38 #include <errno.h>
39 #include <limits.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <sys/wait.h>
45 #ifdef HAVE_STATFS_H
46 #undef HAVE_STATFS_H
47 #endif
49 #if defined(LINUX) && defined(__FreeBSD_kernel__)
50 #undef LINUX
51 #define FREEBSD 1
52 #endif
55 #if defined(SOLARIS)
57 #include <sys/mnttab.h>
58 #include <sys/statvfs.h>
59 #define HAVE_STATFS_H
60 #include <sys/fs/ufs_quota.h>
61 static const sal_Char* MOUNTTAB="/etc/mnttab";
63 #elif defined(LINUX)
65 #include <mntent.h>
66 #include <sys/vfs.h>
67 #define HAVE_STATFS_H
68 #include <sys/quota.h>
69 //#include <ctype.h>
70 static const sal_Char* MOUNTTAB="/etc/mtab";
72 #elif defined(NETBSD) || defined(FREEBSD)
74 #include <sys/param.h>
75 #include <sys/ucred.h>
76 #include <sys/mount.h>
77 #include <ufs/ufs/quota.h>
78 //#include <ctype.h>
79 #define HAVE_STATFS_H
81 /* No mounting table on *BSD
82 * This information is stored only in the kernel. */
83 /* static const sal_Char* MOUNTTAB="/etc/mtab"; */
85 #elif defined(MACOSX)
87 #include <ufs/ufs/quota.h>
88 //#include <ctype.h>
89 #include <sys/param.h>
90 #include <sys/mount.h>
91 #define HAVE_STATFS_H
92 // static const sal_Char* MOUNTTAB="/etc/mtab";
94 #endif /* HAVE_STATFS_H */
96 /************************************************************************
97 * ToDo
99 * - Fix: check for corresponding struct sizes in exported functions
100 * - check size/use of oslVolumeDeviceHandle
101 * - check size/use of oslVolumeInfo
102 ***********************************************************************/
103 /******************************************************************************
105 * Data Type Definition
107 ******************************************************************************/
109 typedef struct _oslVolumeDeviceHandleImpl
111 sal_Char pszMountPoint[PATH_MAX];
112 sal_Char pszFilePath[PATH_MAX];
113 sal_Char pszDevice[PATH_MAX];
114 sal_Char ident[4];
115 sal_uInt32 RefCount;
116 } oslVolumeDeviceHandleImpl;
118 /******************************************************************************
120 * 'removeable device' aka floppy functions
122 *****************************************************************************/
124 static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath);
125 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy);
126 static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy);
128 #if defined(SOLARIS)
129 static sal_Bool osl_isFloppyMounted(sal_Char* pszPath, sal_Char* pszMountPath);
130 static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, sal_Char* pBuffer);
131 static sal_Bool osl_checkFloppyPath(sal_Char* pszPath, sal_Char* pszFilePath, sal_Char* pszDevicePath);
132 #endif /* SOLARIS */
134 #if defined(LINUX)
135 static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice);
136 static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem);
137 #endif /* LINUX */
139 #ifdef DEBUG_OSL_FILE
140 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* hFloppy);
141 #endif /* DEBUG_OSL_FILE */
143 /******************************************************************************
145 * C-String Function Declarations
147 *****************************************************************************/
149 static oslFileError osl_psz_getVolumeInformation(const sal_Char* , oslVolumeInfo* pInfo, sal_uInt32 uFieldMask);
151 /****************************************************************************/
152 /* osl_getVolumeInformation */
153 /****************************************************************************/
155 oslFileError osl_getVolumeInformation( rtl_uString* ustrDirectoryURL, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask )
157 char path[PATH_MAX];
158 oslFileError eRet;
160 OSL_ASSERT( ustrDirectoryURL );
161 OSL_ASSERT( pInfo );
163 /* convert directory url to system path */
164 eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
165 if( eRet != osl_File_E_None )
166 return eRet;
168 #ifdef MACOSX
169 if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
170 return oslTranslateFileError( OSL_FET_ERROR, errno );
171 #endif/* MACOSX */
173 return osl_psz_getVolumeInformation( path, pInfo, uFieldMask);
176 /******************************************************************************
178 * C-String Versions of Exported Module Functions
180 *****************************************************************************/
182 #ifdef HAVE_STATFS_H
184 #if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
185 # define __OSL_STATFS_STRUCT struct statfs
186 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
187 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
188 # define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
189 # define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
191 /* always return true if queried for the properties of
192 the file system. If you think this is wrong under any
193 of the target platforms fix it!!!! */
194 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
195 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
196 #endif /* FREEBSD || NETBSD || MACOSX */
198 #if defined(LINUX)
199 # define __OSL_NFS_SUPER_MAGIC 0x6969
200 # define __OSL_SMB_SUPER_MAGIC 0x517B
201 # define __OSL_MSDOS_SUPER_MAGIC 0x4d44
202 # define __OSL_NTFS_SUPER_MAGIC 0x5346544e
203 # define __OSL_STATFS_STRUCT struct statfs
204 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
205 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
206 # define __OSL_STATFS_IS_NFS(a) (__OSL_NFS_SUPER_MAGIC == (a).f_type)
207 # define __OSL_STATFS_IS_SMB(a) (__OSL_SMB_SUPER_MAGIC == (a).f_type)
208 # define __OSL_STATFS_ISREMOTE(a) (__OSL_STATFS_IS_NFS((a)) || __OSL_STATFS_IS_SMB((a)))
209 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type) && (__OSL_NTFS_SUPER_MAGIC != (a).f_type))
210 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type))
211 #endif /* LINUX */
213 #if defined(SOLARIS)
214 # define __OSL_STATFS_STRUCT struct statvfs
215 # define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
216 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
217 # define __OSL_STATFS_TYPENAME(a) ((a).f_basetype)
218 # define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
220 /* always return true if queried for the properties of
221 the file system. If you think this is wrong under any
222 of the target platforms fix it!!!! */
223 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
224 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
225 #endif /* SOLARIS */
227 # define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
229 #else /* no statfs available */
231 # define __OSL_STATFS_STRUCT struct dummy {int i;}
232 # define __OSL_STATFS_INIT(a) ((void)0)
233 # define __OSL_STATFS(dir, sfs) (1)
234 # define __OSL_STATFS_ISREMOTE(sfs) (0)
235 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
236 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
237 #endif /* HAVE_STATFS_H */
240 static oslFileError osl_psz_getVolumeInformation (
241 const sal_Char* pszDirectory, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask)
243 __OSL_STATFS_STRUCT sfs;
245 if (!pInfo)
246 return osl_File_E_INVAL;
248 __OSL_STATFS_INIT(sfs);
250 pInfo->uValidFields = 0;
251 pInfo->uAttributes = 0;
253 if ((__OSL_STATFS(pszDirectory, &sfs)) < 0)
255 oslFileError result = oslTranslateFileError(OSL_FET_ERROR, errno);
256 return (result);
259 /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
260 if (uFieldMask & osl_VolumeInfo_Mask_Attributes)
262 if (__OSL_STATFS_ISREMOTE(sfs))
263 pInfo->uAttributes |= osl_Volume_Attribute_Remote;
265 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
268 if (uFieldMask & osl_VolumeInfo_Mask_FileSystemCaseHandling)
270 if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs))
271 pInfo->uAttributes |= osl_Volume_Attribute_Case_Sensitive;
273 if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs))
274 pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
276 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
279 pInfo->uTotalSpace = 0;
280 pInfo->uFreeSpace = 0;
281 pInfo->uUsedSpace = 0;
283 #if defined(__OSL_STATFS_BLKSIZ)
285 if ((uFieldMask & osl_VolumeInfo_Mask_TotalSpace) ||
286 (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
288 pInfo->uTotalSpace = __OSL_STATFS_BLKSIZ(sfs);
289 pInfo->uTotalSpace *= (sal_uInt64)(sfs.f_blocks);
290 pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace;
293 if ((uFieldMask & osl_VolumeInfo_Mask_FreeSpace) ||
294 (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
296 pInfo->uFreeSpace = __OSL_STATFS_BLKSIZ(sfs);
298 if (getuid() == 0)
299 pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bfree);
300 else
301 pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bavail);
303 pInfo->uValidFields |= osl_VolumeInfo_Mask_FreeSpace;
306 #endif /* __OSL_STATFS_BLKSIZ */
308 if ((pInfo->uValidFields & osl_VolumeInfo_Mask_TotalSpace) &&
309 (pInfo->uValidFields & osl_VolumeInfo_Mask_FreeSpace ))
311 pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
312 pInfo->uValidFields |= osl_VolumeInfo_Mask_UsedSpace;
315 pInfo->uMaxNameLength = 0;
316 if (uFieldMask & osl_VolumeInfo_Mask_MaxNameLength)
318 long nLen = pathconf(pszDirectory, _PC_NAME_MAX);
319 if (nLen > 0)
321 pInfo->uMaxNameLength = (sal_uInt32)nLen;
322 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
326 pInfo->uMaxPathLength = 0;
327 if (uFieldMask & osl_VolumeInfo_Mask_MaxPathLength)
329 long nLen = pathconf (pszDirectory, _PC_PATH_MAX);
330 if (nLen > 0)
332 pInfo->uMaxPathLength = (sal_uInt32)nLen;
333 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
337 #if defined(__OSL_STATFS_TYPENAME)
339 if (uFieldMask & osl_VolumeInfo_Mask_FileSystemName)
341 rtl_string2UString(
342 &(pInfo->ustrFileSystemName),
343 __OSL_STATFS_TYPENAME(sfs),
344 rtl_str_getLength(__OSL_STATFS_TYPENAME(sfs)),
345 osl_getThreadTextEncoding(),
346 OUSTRING_TO_OSTRING_CVTFLAGS);
347 OSL_ASSERT(pInfo->ustrFileSystemName != 0);
349 pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
352 #endif /* __OSL_STATFS_TYPENAME */
354 if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
356 /* FIXME: check also entries in mntent for the device
357 and fill it with correct values */
359 *pInfo->pDeviceHandle = osl_isFloppyDrive(pszDirectory);
361 if (*pInfo->pDeviceHandle)
363 pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
364 pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
365 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
368 return osl_File_E_None;
371 /******************************************************************************
373 * GENERIC FLOPPY FUNCTIONS
375 *****************************************************************************/
378 /*****************************************
379 * osl_unmountVolumeDevice
380 ****************************************/
382 oslFileError osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
384 oslFileError tErr = osl_File_E_NOSYS;
386 tErr = osl_unmountFloppy(Handle);
388 /* Perhaps current working directory is set to mount point */
390 if ( tErr )
392 sal_Char *pszHomeDir = getenv("HOME");
394 if ( pszHomeDir && strlen( pszHomeDir ) && 0 == chdir( pszHomeDir ) )
396 /* try again */
398 tErr = osl_unmountFloppy(Handle);
400 OSL_ENSURE( tErr, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
404 return tErr;
407 /*****************************************
408 * osl_automountVolumeDevice
409 ****************************************/
411 oslFileError osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
413 oslFileError tErr = osl_File_E_NOSYS;
415 tErr = osl_mountFloppy(Handle);
417 return tErr;
420 /*****************************************
421 * osl_getVolumeDeviceMountPath
422 ****************************************/
423 static rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr, rtl_uString** ustrValid)
425 rtl_string2UString(
426 ustrValid,
427 pszStr,
428 rtl_str_getLength( pszStr ),
429 osl_getThreadTextEncoding(),
430 OUSTRING_TO_OSTRING_CVTFLAGS );
431 OSL_ASSERT(*ustrValid != 0);
433 return *ustrValid;
436 oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
438 oslVolumeDeviceHandleImpl* pItem = (oslVolumeDeviceHandleImpl*) Handle;
439 sal_Char Buffer[PATH_MAX];
441 Buffer[0] = '\0';
443 if ( pItem == 0 || pstrPath == 0 )
445 return osl_File_E_INVAL;
448 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
450 return osl_File_E_INVAL;
453 #ifdef DEBUG_OSL_FILE
454 fprintf(stderr,"Handle is:\n");
455 osl_printFloppyHandle(pItem);
456 #endif
458 snprintf(Buffer, sizeof(Buffer), "file://%s", pItem->pszMountPoint);
460 #ifdef DEBUG_OSL_FILE
461 fprintf(stderr,"Mount Point is: '%s'\n",Buffer);
462 #endif
464 oslMakeUStrFromPsz(Buffer, pstrPath);
466 return osl_File_E_None;
469 /*****************************************
470 * osl_acquireVolumeDeviceHandle
471 ****************************************/
473 oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
475 oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
477 if ( pItem == 0 )
479 return osl_File_E_INVAL;
482 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
484 return osl_File_E_INVAL;
487 ++pItem->RefCount;
489 return osl_File_E_None;
492 /*****************************************
493 * osl_releaseVolumeDeviceHandle
494 ****************************************/
496 oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
498 oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
500 if ( pItem == 0 )
502 return osl_File_E_INVAL;
505 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
507 return osl_File_E_INVAL;
510 --pItem->RefCount;
512 if ( pItem->RefCount == 0 )
514 rtl_freeMemory(pItem);
517 return osl_File_E_None;
520 #ifndef MACOSX
522 /*****************************************
523 * osl_newVolumeDeviceHandleImpl
524 ****************************************/
526 static oslVolumeDeviceHandleImpl* osl_newVolumeDeviceHandleImpl()
528 oslVolumeDeviceHandleImpl* pHandle;
529 const size_t nSizeOfHandle = sizeof(oslVolumeDeviceHandleImpl);
531 pHandle = (oslVolumeDeviceHandleImpl*) rtl_allocateMemory (nSizeOfHandle);
532 if (pHandle != NULL)
534 pHandle->ident[0] = 'O';
535 pHandle->ident[1] = 'V';
536 pHandle->ident[2] = 'D';
537 pHandle->ident[3] = 'H';
538 pHandle->pszMountPoint[0] = '\0';
539 pHandle->pszFilePath[0] = '\0';
540 pHandle->pszDevice[0] = '\0';
541 pHandle->RefCount = 1;
543 return pHandle;
546 /*****************************************
547 * osl_freeVolumeDeviceHandleImpl
548 ****************************************/
550 static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl* pHandle)
552 if (pHandle != NULL)
553 rtl_freeMemory (pHandle);
555 #endif
557 /******************************************************************************
559 * SOLARIS FLOPPY FUNCTIONS
561 *****************************************************************************/
563 #if defined(SOLARIS)
564 /* compare a given devicename with the typical device names on a Solaris box */
565 static sal_Bool
566 osl_isAFloppyDevice (const char* pDeviceName)
568 const char* pFloppyDevice [] = {
569 "/dev/fd", "/dev/rfd",
570 "/dev/diskette", "/dev/rdiskette",
571 "/vol/dev/diskette", "/vol/dev/rdiskette"
574 int i;
575 for (i = 0; i < (sizeof(pFloppyDevice)/sizeof(pFloppyDevice[0])); i++)
577 if (strncmp(pDeviceName, pFloppyDevice[i], strlen(pFloppyDevice[i])) == 0)
578 return sal_True;
580 return sal_False;
583 /* compare two directories whether the first may be a parent of the second. this
584 * does not realpath() resolving */
585 static sal_Bool
586 osl_isAParentDirectory (const char* pParentDir, const char* pSubDir)
588 return strncmp(pParentDir, pSubDir, strlen(pParentDir)) == 0;
591 /* the name of the routine is obviously silly. But anyway create a
592 * oslVolumeDeviceHandle with correct mount point, device name and a resolved filepath
593 * only if pszPath points to file or directory on a floppy */
594 static oslVolumeDeviceHandle
595 osl_isFloppyDrive(const sal_Char* pszPath)
597 FILE* pMountTab;
598 struct mnttab aMountEnt;
599 oslVolumeDeviceHandleImpl* pHandle;
601 if ((pHandle = osl_newVolumeDeviceHandleImpl()) == NULL)
603 return NULL;
605 if (realpath(pszPath, pHandle->pszFilePath) == NULL)
607 osl_freeVolumeDeviceHandleImpl (pHandle);
608 return NULL;
610 if ((pMountTab = fopen (MOUNTTAB, "r")) == NULL)
612 osl_freeVolumeDeviceHandleImpl (pHandle);
613 return NULL;
616 while (getmntent(pMountTab, &aMountEnt) == 0)
618 const char *pMountPoint = aMountEnt.mnt_mountp;
619 const char *pDevice = aMountEnt.mnt_special;
620 if ( osl_isAParentDirectory (aMountEnt.mnt_mountp, pHandle->pszFilePath)
621 && osl_isAFloppyDevice (aMountEnt.mnt_special))
623 /* skip the last item for it is the name of the disk */
624 char * pc = strrchr( aMountEnt.mnt_special, '/' );
626 if ( NULL != pc )
628 int len = pc - aMountEnt.mnt_special;
630 strncpy( pHandle->pszDevice, aMountEnt.mnt_special, len );
631 pHandle->pszDevice[len] = '\0';
633 else
635 /* #106048 use save str functions to avoid buffer overflows */
636 memset(pHandle->pszDevice, 0, sizeof(pHandle->pszDevice));
637 strncpy(pHandle->pszDevice, aMountEnt.mnt_special, sizeof(pHandle->pszDevice) - 1);
640 /* remember the mount point */
641 memset(pHandle->pszMountPoint, 0, sizeof(pHandle->pszMountPoint));
642 strncpy(pHandle->pszMountPoint, aMountEnt.mnt_mountp, sizeof(pHandle->pszMountPoint) - 1);
644 fclose (pMountTab);
645 return pHandle;
649 fclose (pMountTab);
650 osl_freeVolumeDeviceHandleImpl (pHandle);
651 return NULL;
654 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
656 FILE* pMountTab;
657 struct mnttab aMountEnt;
658 oslVolumeDeviceHandleImpl* pHandle = (oslVolumeDeviceHandleImpl*) hFloppy;
660 int nRet=0;
661 sal_Char pszCmd[512] = "";
663 if ( pHandle == 0 )
664 return osl_File_E_INVAL;
666 /* FIXME: don't know what this is good for */
667 if ( pHandle->ident[0] != 'O' || pHandle->ident[1] != 'V' || pHandle->ident[2] != 'D' || pHandle->ident[3] != 'H' )
668 return osl_File_E_INVAL;
670 snprintf(pszCmd, sizeof(pszCmd), "eject -q %s > /dev/null 2>&1", pHandle->pszDevice);
672 nRet = system( pszCmd );
674 switch ( WEXITSTATUS(nRet) )
676 case 0:
678 /* lookup the device in mount tab again */
679 if ((pMountTab = fopen (MOUNTTAB, "r")) == NULL)
680 return osl_File_E_BUSY;
682 while (getmntent(pMountTab, &aMountEnt) == 0)
684 const char *pMountPoint = aMountEnt.mnt_mountp;
685 const char *pDevice = aMountEnt.mnt_special;
686 if ( 0 == strncmp( pHandle->pszDevice, aMountEnt.mnt_special, strlen(pHandle->pszDevice) ) )
688 memset(pHandle->pszMountPoint, 0, sizeof(pHandle->pszMountPoint));
689 strncpy (pHandle->pszMountPoint, aMountEnt.mnt_mountp, sizeof(pHandle->pszMountPoint) - 1);
691 fclose (pMountTab);
692 return osl_File_E_None;
696 fclose (pMountTab);
697 return osl_File_E_BUSY;
699 //break; // break not necessary here, see return statements before
701 case 1:
702 return osl_File_E_BUSY;
704 default:
705 break;
708 return osl_File_E_BUSY;
711 static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
713 // FILE* pMountTab;
714 // struct mnttab aMountEnt;
715 oslVolumeDeviceHandleImpl* pHandle = (oslVolumeDeviceHandleImpl*) hFloppy;
717 int nRet=0;
718 sal_Char pszCmd[512] = "";
720 if ( pHandle == 0 )
721 return osl_File_E_INVAL;
723 /* FIXME: don't know what this is good for */
724 if ( pHandle->ident[0] != 'O' || pHandle->ident[1] != 'V' || pHandle->ident[2] != 'D' || pHandle->ident[3] != 'H' )
725 return osl_File_E_INVAL;
727 snprintf(pszCmd, sizeof(pszCmd), "eject %s > /dev/null 2>&1", pHandle->pszDevice);
729 nRet = system( pszCmd );
731 switch ( WEXITSTATUS(nRet) )
733 case 0:
735 FILE* pMountTab;
736 struct mnttab aMountEnt;
738 /* lookup if device is still in mount tab */
739 if ((pMountTab = fopen (MOUNTTAB, "r")) == NULL)
740 return osl_File_E_BUSY;
742 while (getmntent(pMountTab, &aMountEnt) == 0)
744 const char *pMountPoint = aMountEnt.mnt_mountp;
745 const char *pDevice = aMountEnt.mnt_special;
746 if ( 0 == strncmp( pHandle->pszDevice, aMountEnt.mnt_special, strlen(pHandle->pszDevice) ) )
748 fclose (pMountTab);
749 return osl_File_E_BUSY;
753 fclose (pMountTab);
754 pHandle->pszMountPoint[0] = 0;
755 return osl_File_E_None;
758 //break; //break not necessary, see return statements before
760 case 1:
761 return osl_File_E_NODEV;
763 case 4:
764 pHandle->pszMountPoint[0] = 0;
765 return osl_File_E_None;
767 default:
768 break;
771 return osl_File_E_BUSY;
774 #endif /* SOLARIS */
776 /******************************************************************************
778 * LINUX FLOPPY FUNCTIONS
780 *****************************************************************************/
782 #if defined(LINUX)
783 static oslVolumeDeviceHandle
784 osl_isFloppyDrive (const sal_Char* pszPath)
786 oslVolumeDeviceHandleImpl* pItem = osl_newVolumeDeviceHandleImpl();
787 if (osl_getFloppyMountEntry(pszPath, pItem))
788 return (oslVolumeDeviceHandle) pItem;
790 osl_freeVolumeDeviceHandleImpl (pItem);
791 return 0;
793 #endif /* LINUX */
795 #if defined(LINUX)
796 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
798 sal_Bool bRet = sal_False;
799 oslVolumeDeviceHandleImpl* pItem=0;
800 int nRet;
801 sal_Char pszCmd[PATH_MAX];
802 const sal_Char* pszMountProg = "mount";
803 sal_Char* pszSuDo = 0;
804 sal_Char* pszTmp = 0;
806 pszCmd[0] = '\0';
808 #ifdef TRACE_OSL_FILE
809 fprintf(stderr,"In osl_mountFloppy\n");
810 #endif
812 pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
814 if ( pItem == 0 )
816 #ifdef TRACE_OSL_FILE
817 fprintf(stderr,"Out osl_mountFloppy [pItem == 0]\n");
818 #endif
820 return osl_File_E_INVAL;
823 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
825 #ifdef TRACE_OSL_FILE
826 fprintf(stderr,"Out osl_mountFloppy [invalid handle]\n");
827 #endif
828 return osl_File_E_INVAL;
831 bRet = osl_isFloppyMounted(pItem);
832 if ( bRet == sal_True )
834 #ifdef DEBUG_OSL_FILE
835 fprintf(stderr,"detected mounted floppy at '%s'\n",pItem->pszMountPoint);
836 #endif
837 return osl_File_E_BUSY;
840 /* mfe: we can't use the mount(2) system call!!! */
841 /* even if we are root */
842 /* since mtab is not updated!!! */
843 /* but we need it to be updated */
844 /* some "magic" must be done */
846 /* nRet = mount(pItem->pszDevice,pItem->pszMountPoint,0,0,0); */
847 /* if ( nRet != 0 ) */
848 /* { */
849 /* nRet=errno; */
850 /* #ifdef DEBUG_OSL_FILE */
851 /* perror("mount"); */
852 /* #endif */
853 /* } */
855 pszTmp = getenv("SAL_MOUNT_MOUNTPROG");
856 if ( pszTmp != 0 )
858 pszMountProg=pszTmp;
861 pszTmp=getenv("SAL_MOUNT_SU_DO");
862 if ( pszTmp != 0 )
864 pszSuDo=pszTmp;
867 if ( pszSuDo != 0 )
869 snprintf(pszCmd, sizeof(pszCmd), "%s %s %s %s",pszSuDo,pszMountProg,pItem->pszDevice,pItem->pszMountPoint);
871 else
873 snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszMountProg,pItem->pszMountPoint);
877 #ifdef DEBUG_OSL_FILE
878 fprintf(stderr,"executing '%s'\n",pszCmd);
879 #endif
881 nRet = system(pszCmd);
883 #ifdef DEBUG_OSL_FILE
884 fprintf(stderr,"call returned '%i'\n",nRet);
885 fprintf(stderr,"exit status is '%i'\n", WEXITSTATUS(nRet));
886 #endif
889 switch ( WEXITSTATUS(nRet) )
891 case 0:
892 nRet=0;
893 break;
895 case 2:
896 nRet=EPERM;
897 break;
899 case 4:
900 nRet=ENOENT;
901 break;
903 case 8:
904 nRet=EINTR;
905 break;
907 case 16:
908 nRet=EPERM;
909 break;
911 case 32:
912 nRet=EBUSY;
913 break;
915 case 64:
916 nRet=EAGAIN;
917 break;
919 default:
920 nRet=EBUSY;
921 break;
924 return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
926 #endif /* LINUX */
929 #if defined(LINUX)
930 static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
932 oslVolumeDeviceHandleImpl* pItem=0;
933 int nRet=0;
934 sal_Char pszCmd[PATH_MAX];
935 sal_Char* pszTmp = 0;
936 sal_Char* pszSuDo = 0;
937 const sal_Char* pszUmountProg = "umount";
939 pszCmd[0] = '\0';
941 #ifdef TRACE_OSL_FILE
942 fprintf(stderr,"In osl_unmountFloppy\n");
943 #endif
945 pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
947 if ( pItem == 0 )
949 #ifdef TRACE_OSL_FILE
950 fprintf(stderr,"Out osl_unmountFloppy [pItem==0]\n");
951 #endif
952 return osl_File_E_INVAL;
955 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
957 #ifdef TRACE_OSL_FILE
958 fprintf(stderr,"Out osl_unmountFloppy [invalid handle]\n");
959 #endif
960 return osl_File_E_INVAL;
963 /* mfe: we can't use the umount(2) system call!!! */
964 /* even if we are root */
965 /* since mtab is not updated!!! */
966 /* but we need it to be updated */
967 /* some "magic" must be done */
969 /* nRet=umount(pItem->pszDevice); */
970 /* if ( nRet != 0 ) */
971 /* { */
972 /* nRet = errno; */
974 /* #ifdef DEBUG_OSL_FILE */
975 /* perror("mount"); */
976 /* #endif */
977 /* } */
980 pszTmp = getenv("SAL_MOUNT_UMOUNTPROG");
981 if ( pszTmp != 0 )
983 pszUmountProg=pszTmp;
986 pszTmp = getenv("SAL_MOUNT_SU_DO");
987 if ( pszTmp != 0 )
989 pszSuDo=pszTmp;
992 if ( pszSuDo != 0 )
994 snprintf(pszCmd, sizeof(pszCmd), "%s %s %s",pszSuDo,pszUmountProg,pItem->pszMountPoint);
996 else
998 snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszUmountProg,pItem->pszMountPoint);
1002 #ifdef DEBUG_OSL_FILE
1003 fprintf(stderr,"executing '%s'\n",pszCmd);
1004 #endif
1006 nRet = system(pszCmd);
1008 #ifdef DEBUG_OSL_FILE
1009 fprintf(stderr,"call returned '%i'\n",nRet);
1010 fprintf(stderr,"exit status is '%i'\n", WEXITSTATUS(nRet));
1011 #endif
1013 switch ( WEXITSTATUS(nRet) )
1015 case 0:
1016 nRet=0;
1017 break;
1019 default:
1020 nRet=EBUSY;
1021 break;
1024 #ifdef TRACE_OSL_FILE
1025 fprintf(stderr,"Out osl_unmountFloppy [ok]\n");
1026 #endif
1028 return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
1030 /* return osl_File_E_None;*/
1033 #endif /* LINUX */
1035 #if defined(LINUX)
1036 static sal_Bool
1037 osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
1039 struct mntent* pMountEnt;
1040 FILE* pMountTab;
1042 pMountTab = setmntent (MOUNTTAB, "r");
1043 if (pMountTab == 0)
1044 return sal_False;
1046 while ((pMountEnt = getmntent(pMountTab)) != 0)
1048 if ( strncmp(pMountEnt->mnt_dir, pszPath, strlen(pMountEnt->mnt_dir)) == 0
1049 && strncmp(pMountEnt->mnt_fsname, "/dev/fd", strlen("/dev/fd")) == 0)
1051 memset(pItem->pszMountPoint, 0, sizeof(pItem->pszMountPoint));
1052 strncpy(pItem->pszMountPoint, pMountEnt->mnt_dir, sizeof(pItem->pszMountPoint) - 1);
1054 memset(pItem->pszFilePath, 0, sizeof(pItem->pszFilePath));
1055 strncpy(pItem->pszFilePath, pMountEnt->mnt_dir, sizeof(pItem->pszFilePath) - 1);
1057 memset(pItem->pszDevice, 0, sizeof(pItem->pszDevice));
1058 strncpy(pItem->pszDevice, pMountEnt->mnt_fsname, sizeof(pItem->pszDevice) - 1);
1060 endmntent (pMountTab);
1061 return sal_True;
1065 endmntent (pMountTab);
1066 return sal_False;
1068 #endif /* LINUX */
1070 #if defined(LINUX)
1071 static sal_Bool
1072 osl_isFloppyMounted (oslVolumeDeviceHandleImpl* pDevice)
1074 oslVolumeDeviceHandleImpl aItem;
1076 if ( osl_getFloppyMountEntry (pDevice->pszMountPoint, &aItem)
1077 && strcmp (aItem.pszMountPoint, pDevice->pszMountPoint) == 0
1078 && strcmp (aItem.pszDevice, pDevice->pszDevice) == 0)
1080 return sal_True;
1082 return sal_False;
1084 #endif /* LINUX */
1086 /* NetBSD floppy functions have to be added here. Until we have done that,
1087 * we use the MACOSX definitions for nonexistent floppy.
1088 * */
1090 /******************************************************************************
1092 * MAC OS X FLOPPY FUNCTIONS
1094 *****************************************************************************/
1096 #if (defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
1097 static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath)
1099 return NULL;
1101 #endif /* MACOSX */
1103 #if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
1104 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
1106 return osl_File_E_BUSY;
1108 #endif /* MACOSX */
1110 #if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
1111 static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
1113 return osl_File_E_BUSY;
1115 #endif /* MACOSX */
1117 #if ( defined(NETBSD) || defined(FREEBSD) )
1118 static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
1120 return sal_False;
1122 #endif /* NETBSD || FREEBSD */
1124 #if ( defined(NETBSD) || defined(FREEBSD) )
1125 static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice)
1127 return sal_False;
1129 #endif /* NETBSD || FREEBSD */
1132 #ifdef DEBUG_OSL_FILE
1133 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* pItem)
1135 if (pItem == 0 )
1137 fprintf(stderr,"NULL Handle\n");
1138 return;
1140 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
1142 #ifdef TRACE_OSL_FILE
1143 fprintf(stderr,"Invalid Handle]\n");
1144 #endif
1145 return;
1149 fprintf(stderr,"MountPoint : '%s'\n",pItem->pszMountPoint);
1150 fprintf(stderr,"FilePath : '%s'\n",pItem->pszFilePath);
1151 fprintf(stderr,"Device : '%s'\n",pItem->pszDevice);
1153 return;
1155 #endif