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 ************************************************************************/
30 #include "osl/diagnose.h"
31 #include "osl/thread.h"
32 #include "rtl/alloc.h"
34 #include "file_error_transl.h"
49 #if defined(LINUX) && defined(__FreeBSD_kernel__)
57 #include <sys/mnttab.h>
58 #include <sys/statvfs.h>
60 #include <sys/fs/ufs_quota.h>
61 static const sal_Char
* MOUNTTAB
="/etc/mnttab";
68 #include <sys/quota.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>
81 /* No mounting table on *BSD
82 * This information is stored only in the kernel. */
83 /* static const sal_Char* MOUNTTAB="/etc/mtab"; */
87 #include <ufs/ufs/quota.h>
89 #include <sys/param.h>
90 #include <sys/mount.h>
92 // static const sal_Char* MOUNTTAB="/etc/mtab";
94 #endif /* HAVE_STATFS_H */
96 /************************************************************************
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
];
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
);
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
);
135 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
);
136 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
);
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
)
160 OSL_ASSERT( ustrDirectoryURL
);
163 /* convert directory url to system path */
164 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
165 if( eRet
!= osl_File_E_None
)
169 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
170 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
173 return osl_psz_getVolumeInformation( path
, pInfo
, uFieldMask
);
176 /******************************************************************************
178 * C-String Versions of Exported Module Functions
180 *****************************************************************************/
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 */
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))
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)
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
;
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
);
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
);
299 pInfo
->uFreeSpace
*= (sal_uInt64
)(sfs
.f_bfree
);
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
);
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
);
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
)
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 */
392 sal_Char
*pszHomeDir
= getenv("HOME");
394 if ( pszHomeDir
&& strlen( pszHomeDir
) && 0 == chdir( pszHomeDir
) )
398 tErr
= osl_unmountFloppy(Handle
);
400 OSL_ENSURE( tErr
, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
407 /*****************************************
408 * osl_automountVolumeDevice
409 ****************************************/
411 oslFileError
osl_automountVolumeDevice( oslVolumeDeviceHandle Handle
)
413 oslFileError tErr
= osl_File_E_NOSYS
;
415 tErr
= osl_mountFloppy(Handle
);
420 /*****************************************
421 * osl_getVolumeDeviceMountPath
422 ****************************************/
423 static rtl_uString
* oslMakeUStrFromPsz(const sal_Char
* pszStr
, rtl_uString
** ustrValid
)
428 rtl_str_getLength( pszStr
),
429 osl_getThreadTextEncoding(),
430 OUSTRING_TO_OSTRING_CVTFLAGS
);
431 OSL_ASSERT(*ustrValid
!= 0);
436 oslFileError
osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle
, rtl_uString
**pstrPath
)
438 oslVolumeDeviceHandleImpl
* pItem
= (oslVolumeDeviceHandleImpl
*) Handle
;
439 sal_Char Buffer
[PATH_MAX
];
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
);
458 snprintf(Buffer
, sizeof(Buffer
), "file://%s", pItem
->pszMountPoint
);
460 #ifdef DEBUG_OSL_FILE
461 fprintf(stderr
,"Mount Point is: '%s'\n",Buffer
);
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
;
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
;
489 return osl_File_E_None
;
492 /*****************************************
493 * osl_releaseVolumeDeviceHandle
494 ****************************************/
496 oslFileError
osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
498 oslVolumeDeviceHandleImpl
* pItem
=(oslVolumeDeviceHandleImpl
*) Handle
;
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
;
512 if ( pItem
->RefCount
== 0 )
514 rtl_freeMemory(pItem
);
517 return osl_File_E_None
;
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
);
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;
546 /*****************************************
547 * osl_freeVolumeDeviceHandleImpl
548 ****************************************/
550 static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl
* pHandle
)
553 rtl_freeMemory (pHandle
);
557 /******************************************************************************
559 * SOLARIS FLOPPY FUNCTIONS
561 *****************************************************************************/
564 /* compare a given devicename with the typical device names on a Solaris box */
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"
575 for (i
= 0; i
< (sizeof(pFloppyDevice
)/sizeof(pFloppyDevice
[0])); i
++)
577 if (strncmp(pDeviceName
, pFloppyDevice
[i
], strlen(pFloppyDevice
[i
])) == 0)
583 /* compare two directories whether the first may be a parent of the second. this
584 * does not realpath() resolving */
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
)
598 struct mnttab aMountEnt
;
599 oslVolumeDeviceHandleImpl
* pHandle
;
601 if ((pHandle
= osl_newVolumeDeviceHandleImpl()) == NULL
)
605 if (realpath(pszPath
, pHandle
->pszFilePath
) == NULL
)
607 osl_freeVolumeDeviceHandleImpl (pHandle
);
610 if ((pMountTab
= fopen (MOUNTTAB
, "r")) == NULL
)
612 osl_freeVolumeDeviceHandleImpl (pHandle
);
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
, '/' );
628 int len
= pc
- aMountEnt
.mnt_special
;
630 strncpy( pHandle
->pszDevice
, aMountEnt
.mnt_special
, len
);
631 pHandle
->pszDevice
[len
] = '\0';
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);
650 osl_freeVolumeDeviceHandleImpl (pHandle
);
654 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
657 struct mnttab aMountEnt
;
658 oslVolumeDeviceHandleImpl
* pHandle
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
661 sal_Char pszCmd
[512] = "";
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
) )
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);
692 return osl_File_E_None
;
697 return osl_File_E_BUSY
;
699 //break; // break not necessary here, see return statements before
702 return osl_File_E_BUSY
;
708 return osl_File_E_BUSY
;
711 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
714 // struct mnttab aMountEnt;
715 oslVolumeDeviceHandleImpl
* pHandle
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
718 sal_Char pszCmd
[512] = "";
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
) )
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
) ) )
749 return osl_File_E_BUSY
;
754 pHandle
->pszMountPoint
[0] = 0;
755 return osl_File_E_None
;
758 //break; //break not necessary, see return statements before
761 return osl_File_E_NODEV
;
764 pHandle
->pszMountPoint
[0] = 0;
765 return osl_File_E_None
;
771 return osl_File_E_BUSY
;
776 /******************************************************************************
778 * LINUX FLOPPY FUNCTIONS
780 *****************************************************************************/
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
);
796 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
798 sal_Bool bRet
= sal_False
;
799 oslVolumeDeviceHandleImpl
* pItem
=0;
801 sal_Char pszCmd
[PATH_MAX
];
802 const sal_Char
* pszMountProg
= "mount";
803 sal_Char
* pszSuDo
= 0;
804 sal_Char
* pszTmp
= 0;
808 #ifdef TRACE_OSL_FILE
809 fprintf(stderr
,"In osl_mountFloppy\n");
812 pItem
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
816 #ifdef TRACE_OSL_FILE
817 fprintf(stderr
,"Out osl_mountFloppy [pItem == 0]\n");
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");
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
);
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 ) */
850 /* #ifdef DEBUG_OSL_FILE */
851 /* perror("mount"); */
855 pszTmp
= getenv("SAL_MOUNT_MOUNTPROG");
861 pszTmp
=getenv("SAL_MOUNT_SU_DO");
869 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s %s %s",pszSuDo
,pszMountProg
,pItem
->pszDevice
,pItem
->pszMountPoint
);
873 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s",pszMountProg
,pItem
->pszMountPoint
);
877 #ifdef DEBUG_OSL_FILE
878 fprintf(stderr
,"executing '%s'\n",pszCmd
);
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
));
889 switch ( WEXITSTATUS(nRet
) )
924 return ((0 == nRet
) ? oslTranslateFileError(OSL_FET_SUCCESS
, nRet
) : oslTranslateFileError(OSL_FET_ERROR
, nRet
));
930 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
932 oslVolumeDeviceHandleImpl
* pItem
=0;
934 sal_Char pszCmd
[PATH_MAX
];
935 sal_Char
* pszTmp
= 0;
936 sal_Char
* pszSuDo
= 0;
937 const sal_Char
* pszUmountProg
= "umount";
941 #ifdef TRACE_OSL_FILE
942 fprintf(stderr
,"In osl_unmountFloppy\n");
945 pItem
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
949 #ifdef TRACE_OSL_FILE
950 fprintf(stderr
,"Out osl_unmountFloppy [pItem==0]\n");
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");
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 ) */
974 /* #ifdef DEBUG_OSL_FILE */
975 /* perror("mount"); */
980 pszTmp
= getenv("SAL_MOUNT_UMOUNTPROG");
983 pszUmountProg
=pszTmp
;
986 pszTmp
= getenv("SAL_MOUNT_SU_DO");
994 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s %s",pszSuDo
,pszUmountProg
,pItem
->pszMountPoint
);
998 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s",pszUmountProg
,pItem
->pszMountPoint
);
1002 #ifdef DEBUG_OSL_FILE
1003 fprintf(stderr
,"executing '%s'\n",pszCmd
);
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
));
1013 switch ( WEXITSTATUS(nRet
) )
1024 #ifdef TRACE_OSL_FILE
1025 fprintf(stderr
,"Out osl_unmountFloppy [ok]\n");
1028 return ((0 == nRet
) ? oslTranslateFileError(OSL_FET_SUCCESS
, nRet
) : oslTranslateFileError(OSL_FET_ERROR
, nRet
));
1030 /* return osl_File_E_None;*/
1037 osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
)
1039 struct mntent
* pMountEnt
;
1042 pMountTab
= setmntent (MOUNTTAB
, "r");
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
);
1065 endmntent (pMountTab
);
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)
1086 /* NetBSD floppy functions have to be added here. Until we have done that,
1087 * we use the MACOSX definitions for nonexistent floppy.
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
)
1103 #if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
1104 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
1106 return osl_File_E_BUSY
;
1110 #if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
1111 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
1113 return osl_File_E_BUSY
;
1117 #if ( defined(NETBSD) || defined(FREEBSD) )
1118 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
)
1122 #endif /* NETBSD || FREEBSD */
1124 #if ( defined(NETBSD) || defined(FREEBSD) )
1125 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
)
1129 #endif /* NETBSD || FREEBSD */
1132 #ifdef DEBUG_OSL_FILE
1133 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl
* pItem
)
1137 fprintf(stderr
,"NULL Handle\n");
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");
1149 fprintf(stderr
,"MountPoint : '%s'\n",pItem
->pszMountPoint
);
1150 fprintf(stderr
,"FilePath : '%s'\n",pItem
->pszFilePath
);
1151 fprintf(stderr
,"Device : '%s'\n",pItem
->pszDevice
);