1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
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"
51 #include <sys/mnttab.h>
52 #include <sys/statvfs.h>
54 #include <sys/fs/ufs_quota.h>
55 static const sal_Char
* MOUNTTAB
="/etc/mnttab";
62 #include <sys/quota.h>
64 static const sal_Char
* MOUNTTAB
="/etc/mtab";
66 #elif defined(NETBSD) || defined(FREEBSD)
68 #include <sys/param.h>
69 #include <sys/ucred.h>
70 #include <sys/mount.h>
71 #include <ufs/ufs/quota.h>
75 /* No mounting table on *BSD
76 * This information is stored only in the kernel. */
77 /* static const sal_Char* MOUNTTAB="/etc/mtab"; */
82 #include <sys/mount.h>
83 #include <sys/statvfs.h>
85 #include <sys/quota.h>
87 static const sal_Char
* MOUNTTAB
="/etc/mtab";
91 #include <ufs/ufs/quota.h>
93 #include <sys/param.h>
94 #include <sys/mount.h>
96 // static const sal_Char* MOUNTTAB="/etc/mtab";
98 #endif /* HAVE_STATFS_H */
100 /************************************************************************
103 * - Fix: check for corresponding struct sizes in exported functions
104 * - check size/use of oslVolumeDeviceHandle
105 * - check size/use of oslVolumeInfo
106 ***********************************************************************/
107 /******************************************************************************
109 * Data Type Definition
111 ******************************************************************************/
113 typedef struct _oslVolumeDeviceHandleImpl
115 sal_Char pszMountPoint
[PATH_MAX
];
116 sal_Char pszFilePath
[PATH_MAX
];
117 sal_Char pszDevice
[PATH_MAX
];
120 } oslVolumeDeviceHandleImpl
;
122 /******************************************************************************
124 * 'removeable device' aka floppy functions
126 *****************************************************************************/
128 static oslVolumeDeviceHandle
osl_isFloppyDrive(const sal_Char
* pszPath
);
129 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
);
130 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
);
133 static sal_Bool
osl_isFloppyMounted(sal_Char
* pszPath
, sal_Char
* pszMountPath
);
134 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, sal_Char
* pBuffer
);
135 static sal_Bool
osl_checkFloppyPath(sal_Char
* pszPath
, sal_Char
* pszFilePath
, sal_Char
* pszDevicePath
);
139 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
);
140 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
);
145 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
);
146 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
);
149 #ifdef DEBUG_OSL_FILE
150 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl
* hFloppy
);
151 #endif /* DEBUG_OSL_FILE */
153 /******************************************************************************
155 * C-String Function Declarations
157 *****************************************************************************/
159 static oslFileError
osl_psz_getVolumeInformation(const sal_Char
* , oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
);
161 /****************************************************************************/
162 /* osl_getVolumeInformation */
163 /****************************************************************************/
165 oslFileError
osl_getVolumeInformation( rtl_uString
* ustrDirectoryURL
, oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
)
170 OSL_ASSERT( ustrDirectoryURL
);
173 /* convert directory url to system path */
174 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
175 if( eRet
!= osl_File_E_None
)
179 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
180 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
183 return osl_psz_getVolumeInformation( path
, pInfo
, uFieldMask
);
186 /******************************************************************************
188 * C-String Versions of Exported Module Functions
190 *****************************************************************************/
194 #if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
195 # define __OSL_STATFS_STRUCT struct statfs
196 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
197 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
198 # define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
199 # define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
201 /* always return true if queried for the properties of
202 the file system. If you think this is wrong under any
203 of the target platforms fix it!!!! */
204 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
205 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
206 #endif /* FREEBSD || NETBSD || MACOSX */
209 # define __OSL_NFS_SUPER_MAGIC 0x6969
210 # define __OSL_SMB_SUPER_MAGIC 0x517B
211 # define __OSL_MSDOS_SUPER_MAGIC 0x4d44
212 # define __OSL_NTFS_SUPER_MAGIC 0x5346544e
213 # define __OSL_STATFS_STRUCT struct statfs
214 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
215 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
216 # define __OSL_STATFS_IS_NFS(a) (__OSL_NFS_SUPER_MAGIC == (a).f_type)
217 # define __OSL_STATFS_IS_SMB(a) (__OSL_SMB_SUPER_MAGIC == (a).f_type)
218 # define __OSL_STATFS_ISREMOTE(a) (__OSL_STATFS_IS_NFS((a)) || __OSL_STATFS_IS_SMB((a)))
219 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type) && (__OSL_NTFS_SUPER_MAGIC != (a).f_type))
220 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type))
223 #if defined(SOLARIS) || defined(IRIX)
224 # define __OSL_STATFS_STRUCT struct statvfs
225 # define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
226 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
227 # define __OSL_STATFS_TYPENAME(a) ((a).f_basetype)
228 # define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
230 /* always return true if queried for the properties of
231 the file system. If you think this is wrong under any
232 of the target platforms fix it!!!! */
233 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
234 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
235 #endif /* SOLARIS || IRIX*/
237 # define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
239 #else /* no statfs available */
241 # define __OSL_STATFS_STRUCT struct dummy {int i;}
242 # define __OSL_STATFS_INIT(a) ((void)0)
243 # define __OSL_STATFS(dir, sfs) (1)
244 # define __OSL_STATFS_ISREMOTE(sfs) (0)
245 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
246 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
247 #endif /* HAVE_STATFS_H */
250 static oslFileError
osl_psz_getVolumeInformation (
251 const sal_Char
* pszDirectory
, oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
)
253 __OSL_STATFS_STRUCT sfs
;
256 return osl_File_E_INVAL
;
258 __OSL_STATFS_INIT(sfs
);
260 pInfo
->uValidFields
= 0;
261 pInfo
->uAttributes
= 0;
263 if ((__OSL_STATFS(pszDirectory
, &sfs
)) < 0)
265 oslFileError result
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
269 /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
270 if (uFieldMask
& osl_VolumeInfo_Mask_Attributes
)
272 if (__OSL_STATFS_ISREMOTE(sfs
))
273 pInfo
->uAttributes
|= osl_Volume_Attribute_Remote
;
275 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
278 if (uFieldMask
& osl_VolumeInfo_Mask_FileSystemCaseHandling
)
280 if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs
))
281 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Sensitive
;
283 if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs
))
284 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Is_Preserved
;
286 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
289 pInfo
->uTotalSpace
= 0;
290 pInfo
->uFreeSpace
= 0;
291 pInfo
->uUsedSpace
= 0;
293 #if defined(__OSL_STATFS_BLKSIZ)
295 if ((uFieldMask
& osl_VolumeInfo_Mask_TotalSpace
) ||
296 (uFieldMask
& osl_VolumeInfo_Mask_UsedSpace
))
298 pInfo
->uTotalSpace
= __OSL_STATFS_BLKSIZ(sfs
);
299 pInfo
->uTotalSpace
*= (sal_uInt64
)(sfs
.f_blocks
);
300 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_TotalSpace
;
303 if ((uFieldMask
& osl_VolumeInfo_Mask_FreeSpace
) ||
304 (uFieldMask
& osl_VolumeInfo_Mask_UsedSpace
))
306 pInfo
->uFreeSpace
= __OSL_STATFS_BLKSIZ(sfs
);
309 pInfo
->uFreeSpace
*= (sal_uInt64
)(sfs
.f_bfree
);
311 pInfo
->uFreeSpace
*= (sal_uInt64
)(sfs
.f_bavail
);
313 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FreeSpace
;
316 #endif /* __OSL_STATFS_BLKSIZ */
318 if ((pInfo
->uValidFields
& osl_VolumeInfo_Mask_TotalSpace
) &&
319 (pInfo
->uValidFields
& osl_VolumeInfo_Mask_FreeSpace
))
321 pInfo
->uUsedSpace
= pInfo
->uTotalSpace
- pInfo
->uFreeSpace
;
322 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_UsedSpace
;
325 pInfo
->uMaxNameLength
= 0;
326 if (uFieldMask
& osl_VolumeInfo_Mask_MaxNameLength
)
328 long nLen
= pathconf(pszDirectory
, _PC_NAME_MAX
);
331 pInfo
->uMaxNameLength
= (sal_uInt32
)nLen
;
332 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxNameLength
;
336 pInfo
->uMaxPathLength
= 0;
337 if (uFieldMask
& osl_VolumeInfo_Mask_MaxPathLength
)
339 long nLen
= pathconf (pszDirectory
, _PC_PATH_MAX
);
342 pInfo
->uMaxPathLength
= (sal_uInt32
)nLen
;
343 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxPathLength
;
347 #if defined(__OSL_STATFS_TYPENAME)
349 if (uFieldMask
& osl_VolumeInfo_Mask_FileSystemName
)
352 &(pInfo
->ustrFileSystemName
),
353 __OSL_STATFS_TYPENAME(sfs
),
354 rtl_str_getLength(__OSL_STATFS_TYPENAME(sfs
)),
355 osl_getThreadTextEncoding(),
356 OUSTRING_TO_OSTRING_CVTFLAGS
);
357 OSL_ASSERT(pInfo
->ustrFileSystemName
!= 0);
359 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FileSystemName
;
362 #endif /* __OSL_STATFS_TYPENAME */
364 if (uFieldMask
& osl_VolumeInfo_Mask_DeviceHandle
)
366 /* FIXME: check also entries in mntent for the device
367 and fill it with correct values */
369 *pInfo
->pDeviceHandle
= osl_isFloppyDrive(pszDirectory
);
371 if (*pInfo
->pDeviceHandle
)
373 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_DeviceHandle
;
374 pInfo
->uAttributes
|= osl_Volume_Attribute_Removeable
;
375 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
378 return osl_File_E_None
;
381 /******************************************************************************
383 * GENERIC FLOPPY FUNCTIONS
385 *****************************************************************************/
388 /*****************************************
389 * osl_unmountVolumeDevice
390 ****************************************/
392 oslFileError
osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle
)
394 oslFileError tErr
= osl_File_E_NOSYS
;
396 tErr
= osl_unmountFloppy(Handle
);
398 /* Perhaps current working directory is set to mount point */
402 sal_Char
*pszHomeDir
= getenv("HOME");
404 if ( pszHomeDir
&& strlen( pszHomeDir
) && 0 == chdir( pszHomeDir
) )
408 tErr
= osl_unmountFloppy(Handle
);
410 OSL_ENSURE( tErr
, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
417 /*****************************************
418 * osl_automountVolumeDevice
419 ****************************************/
421 oslFileError
osl_automountVolumeDevice( oslVolumeDeviceHandle Handle
)
423 oslFileError tErr
= osl_File_E_NOSYS
;
425 tErr
= osl_mountFloppy(Handle
);
430 /*****************************************
431 * osl_getVolumeDeviceMountPath
432 ****************************************/
433 static rtl_uString
* oslMakeUStrFromPsz(const sal_Char
* pszStr
, rtl_uString
** ustrValid
)
438 rtl_str_getLength( pszStr
),
439 osl_getThreadTextEncoding(),
440 OUSTRING_TO_OSTRING_CVTFLAGS
);
441 OSL_ASSERT(*ustrValid
!= 0);
446 oslFileError
osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle
, rtl_uString
**pstrPath
)
448 oslVolumeDeviceHandleImpl
* pItem
= (oslVolumeDeviceHandleImpl
*) Handle
;
449 sal_Char Buffer
[PATH_MAX
];
453 if ( pItem
== 0 || pstrPath
== 0 )
455 return osl_File_E_INVAL
;
458 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
460 return osl_File_E_INVAL
;
463 #ifdef DEBUG_OSL_FILE
464 fprintf(stderr
,"Handle is:\n");
465 osl_printFloppyHandle(pItem
);
468 snprintf(Buffer
, sizeof(Buffer
), "file://%s", pItem
->pszMountPoint
);
470 #ifdef DEBUG_OSL_FILE
471 fprintf(stderr
,"Mount Point is: '%s'\n",Buffer
);
474 oslMakeUStrFromPsz(Buffer
, pstrPath
);
476 return osl_File_E_None
;
479 /*****************************************
480 * osl_acquireVolumeDeviceHandle
481 ****************************************/
483 oslFileError SAL_CALL
osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
485 oslVolumeDeviceHandleImpl
* pItem
=(oslVolumeDeviceHandleImpl
*) Handle
;
489 return osl_File_E_INVAL
;
492 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
494 return osl_File_E_INVAL
;
499 return osl_File_E_None
;
502 /*****************************************
503 * osl_releaseVolumeDeviceHandle
504 ****************************************/
506 oslFileError
osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
508 oslVolumeDeviceHandleImpl
* pItem
=(oslVolumeDeviceHandleImpl
*) Handle
;
512 return osl_File_E_INVAL
;
515 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
517 return osl_File_E_INVAL
;
522 if ( pItem
->RefCount
== 0 )
524 rtl_freeMemory(pItem
);
527 return osl_File_E_None
;
532 /*****************************************
533 * osl_newVolumeDeviceHandleImpl
534 ****************************************/
536 static oslVolumeDeviceHandleImpl
* osl_newVolumeDeviceHandleImpl()
538 oslVolumeDeviceHandleImpl
* pHandle
;
539 const size_t nSizeOfHandle
= sizeof(oslVolumeDeviceHandleImpl
);
541 pHandle
= (oslVolumeDeviceHandleImpl
*) rtl_allocateMemory (nSizeOfHandle
);
544 pHandle
->ident
[0] = 'O';
545 pHandle
->ident
[1] = 'V';
546 pHandle
->ident
[2] = 'D';
547 pHandle
->ident
[3] = 'H';
548 pHandle
->pszMountPoint
[0] = '\0';
549 pHandle
->pszFilePath
[0] = '\0';
550 pHandle
->pszDevice
[0] = '\0';
551 pHandle
->RefCount
= 1;
556 /*****************************************
557 * osl_freeVolumeDeviceHandleImpl
558 ****************************************/
560 static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl
* pHandle
)
563 rtl_freeMemory (pHandle
);
567 /******************************************************************************
569 * SOLARIS FLOPPY FUNCTIONS
571 *****************************************************************************/
574 /* compare a given devicename with the typical device names on a Solaris box */
576 osl_isAFloppyDevice (const char* pDeviceName
)
578 const char* pFloppyDevice
[] = {
579 "/dev/fd", "/dev/rfd",
580 "/dev/diskette", "/dev/rdiskette",
581 "/vol/dev/diskette", "/vol/dev/rdiskette"
585 for (i
= 0; i
< (sizeof(pFloppyDevice
)/sizeof(pFloppyDevice
[0])); i
++)
587 if (strncmp(pDeviceName
, pFloppyDevice
[i
], strlen(pFloppyDevice
[i
])) == 0)
593 /* compare two directories whether the first may be a parent of the second. this
594 * does not realpath() resolving */
596 osl_isAParentDirectory (const char* pParentDir
, const char* pSubDir
)
598 return strncmp(pParentDir
, pSubDir
, strlen(pParentDir
)) == 0;
601 /* the name of the routine is obviously silly. But anyway create a
602 * oslVolumeDeviceHandle with correct mount point, device name and a resolved filepath
603 * only if pszPath points to file or directory on a floppy */
604 static oslVolumeDeviceHandle
605 osl_isFloppyDrive(const sal_Char
* pszPath
)
608 struct mnttab aMountEnt
;
609 oslVolumeDeviceHandleImpl
* pHandle
;
611 if ((pHandle
= osl_newVolumeDeviceHandleImpl()) == NULL
)
615 if (realpath(pszPath
, pHandle
->pszFilePath
) == NULL
)
617 osl_freeVolumeDeviceHandleImpl (pHandle
);
620 if ((pMountTab
= fopen (MOUNTTAB
, "r")) == NULL
)
622 osl_freeVolumeDeviceHandleImpl (pHandle
);
626 while (getmntent(pMountTab
, &aMountEnt
) == 0)
628 const char *pMountPoint
= aMountEnt
.mnt_mountp
;
629 const char *pDevice
= aMountEnt
.mnt_special
;
630 if ( osl_isAParentDirectory (aMountEnt
.mnt_mountp
, pHandle
->pszFilePath
)
631 && osl_isAFloppyDevice (aMountEnt
.mnt_special
))
633 /* skip the last item for it is the name of the disk */
634 char * pc
= strrchr( aMountEnt
.mnt_special
, '/' );
638 int len
= pc
- aMountEnt
.mnt_special
;
640 strncpy( pHandle
->pszDevice
, aMountEnt
.mnt_special
, len
);
641 pHandle
->pszDevice
[len
] = '\0';
645 /* #106048 use save str functions to avoid buffer overflows */
646 memset(pHandle
->pszDevice
, 0, sizeof(pHandle
->pszDevice
));
647 strncpy(pHandle
->pszDevice
, aMountEnt
.mnt_special
, sizeof(pHandle
->pszDevice
) - 1);
650 /* remember the mount point */
651 memset(pHandle
->pszMountPoint
, 0, sizeof(pHandle
->pszMountPoint
));
652 strncpy(pHandle
->pszMountPoint
, aMountEnt
.mnt_mountp
, sizeof(pHandle
->pszMountPoint
) - 1);
660 osl_freeVolumeDeviceHandleImpl (pHandle
);
664 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
667 struct mnttab aMountEnt
;
668 oslVolumeDeviceHandleImpl
* pHandle
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
671 sal_Char pszCmd
[512] = "";
674 return osl_File_E_INVAL
;
676 /* FIXME: don't know what this is good for */
677 if ( pHandle
->ident
[0] != 'O' || pHandle
->ident
[1] != 'V' || pHandle
->ident
[2] != 'D' || pHandle
->ident
[3] != 'H' )
678 return osl_File_E_INVAL
;
680 snprintf(pszCmd
, sizeof(pszCmd
), "eject -q %s > /dev/null 2>&1", pHandle
->pszDevice
);
682 nRet
= system( pszCmd
);
684 switch ( WEXITSTATUS(nRet
) )
688 /* lookup the device in mount tab again */
689 if ((pMountTab
= fopen (MOUNTTAB
, "r")) == NULL
)
690 return osl_File_E_BUSY
;
692 while (getmntent(pMountTab
, &aMountEnt
) == 0)
694 const char *pMountPoint
= aMountEnt
.mnt_mountp
;
695 const char *pDevice
= aMountEnt
.mnt_special
;
696 if ( 0 == strncmp( pHandle
->pszDevice
, aMountEnt
.mnt_special
, strlen(pHandle
->pszDevice
) ) )
698 memset(pHandle
->pszMountPoint
, 0, sizeof(pHandle
->pszMountPoint
));
699 strncpy (pHandle
->pszMountPoint
, aMountEnt
.mnt_mountp
, sizeof(pHandle
->pszMountPoint
) - 1);
702 return osl_File_E_None
;
707 return osl_File_E_BUSY
;
709 //break; // break not necessary here, see return statements before
712 return osl_File_E_BUSY
;
718 return osl_File_E_BUSY
;
721 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
724 // struct mnttab aMountEnt;
725 oslVolumeDeviceHandleImpl
* pHandle
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
728 sal_Char pszCmd
[512] = "";
731 return osl_File_E_INVAL
;
733 /* FIXME: don't know what this is good for */
734 if ( pHandle
->ident
[0] != 'O' || pHandle
->ident
[1] != 'V' || pHandle
->ident
[2] != 'D' || pHandle
->ident
[3] != 'H' )
735 return osl_File_E_INVAL
;
737 snprintf(pszCmd
, sizeof(pszCmd
), "eject %s > /dev/null 2>&1", pHandle
->pszDevice
);
739 nRet
= system( pszCmd
);
741 switch ( WEXITSTATUS(nRet
) )
746 struct mnttab aMountEnt
;
748 /* lookup if device is still in mount tab */
749 if ((pMountTab
= fopen (MOUNTTAB
, "r")) == NULL
)
750 return osl_File_E_BUSY
;
752 while (getmntent(pMountTab
, &aMountEnt
) == 0)
754 const char *pMountPoint
= aMountEnt
.mnt_mountp
;
755 const char *pDevice
= aMountEnt
.mnt_special
;
756 if ( 0 == strncmp( pHandle
->pszDevice
, aMountEnt
.mnt_special
, strlen(pHandle
->pszDevice
) ) )
759 return osl_File_E_BUSY
;
764 pHandle
->pszMountPoint
[0] = 0;
765 return osl_File_E_None
;
768 //break; //break not necessary, see return statements before
771 return osl_File_E_NODEV
;
774 pHandle
->pszMountPoint
[0] = 0;
775 return osl_File_E_None
;
781 return osl_File_E_BUSY
;
786 /******************************************************************************
788 * LINUX FLOPPY FUNCTIONS
790 *****************************************************************************/
793 static oslVolumeDeviceHandle
794 osl_isFloppyDrive (const sal_Char
* pszPath
)
796 oslVolumeDeviceHandleImpl
* pItem
= osl_newVolumeDeviceHandleImpl();
797 if (osl_getFloppyMountEntry(pszPath
, pItem
))
798 return (oslVolumeDeviceHandle
) pItem
;
800 osl_freeVolumeDeviceHandleImpl (pItem
);
806 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
808 sal_Bool bRet
= sal_False
;
809 oslVolumeDeviceHandleImpl
* pItem
=0;
811 sal_Char pszCmd
[PATH_MAX
];
812 const sal_Char
* pszMountProg
= "mount";
813 sal_Char
* pszSuDo
= 0;
814 sal_Char
* pszTmp
= 0;
818 #ifdef TRACE_OSL_FILE
819 fprintf(stderr
,"In osl_mountFloppy\n");
822 pItem
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
826 #ifdef TRACE_OSL_FILE
827 fprintf(stderr
,"Out osl_mountFloppy [pItem == 0]\n");
830 return osl_File_E_INVAL
;
833 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
835 #ifdef TRACE_OSL_FILE
836 fprintf(stderr
,"Out osl_mountFloppy [invalid handle]\n");
838 return osl_File_E_INVAL
;
841 bRet
= osl_isFloppyMounted(pItem
);
842 if ( bRet
== sal_True
)
844 #ifdef DEBUG_OSL_FILE
845 fprintf(stderr
,"detected mounted floppy at '%s'\n",pItem
->pszMountPoint
);
847 return osl_File_E_BUSY
;
850 /* mfe: we can't use the mount(2) system call!!! */
851 /* even if we are root */
852 /* since mtab is not updated!!! */
853 /* but we need it to be updated */
854 /* some "magic" must be done */
856 /* nRet = mount(pItem->pszDevice,pItem->pszMountPoint,0,0,0); */
857 /* if ( nRet != 0 ) */
860 /* #ifdef DEBUG_OSL_FILE */
861 /* perror("mount"); */
865 pszTmp
= getenv("SAL_MOUNT_MOUNTPROG");
871 pszTmp
=getenv("SAL_MOUNT_SU_DO");
879 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s %s %s",pszSuDo
,pszMountProg
,pItem
->pszDevice
,pItem
->pszMountPoint
);
883 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s",pszMountProg
,pItem
->pszMountPoint
);
887 #ifdef DEBUG_OSL_FILE
888 fprintf(stderr
,"executing '%s'\n",pszCmd
);
891 nRet
= system(pszCmd
);
893 #ifdef DEBUG_OSL_FILE
894 fprintf(stderr
,"call returned '%i'\n",nRet
);
895 fprintf(stderr
,"exit status is '%i'\n", WEXITSTATUS(nRet
));
899 switch ( WEXITSTATUS(nRet
) )
934 return ((0 == nRet
) ? oslTranslateFileError(OSL_FET_SUCCESS
, nRet
) : oslTranslateFileError(OSL_FET_ERROR
, nRet
));
940 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
942 oslVolumeDeviceHandleImpl
* pItem
=0;
944 sal_Char pszCmd
[PATH_MAX
];
945 sal_Char
* pszTmp
= 0;
946 sal_Char
* pszSuDo
= 0;
947 const sal_Char
* pszUmountProg
= "umount";
951 #ifdef TRACE_OSL_FILE
952 fprintf(stderr
,"In osl_unmountFloppy\n");
955 pItem
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
959 #ifdef TRACE_OSL_FILE
960 fprintf(stderr
,"Out osl_unmountFloppy [pItem==0]\n");
962 return osl_File_E_INVAL
;
965 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
967 #ifdef TRACE_OSL_FILE
968 fprintf(stderr
,"Out osl_unmountFloppy [invalid handle]\n");
970 return osl_File_E_INVAL
;
973 /* mfe: we can't use the umount(2) system call!!! */
974 /* even if we are root */
975 /* since mtab is not updated!!! */
976 /* but we need it to be updated */
977 /* some "magic" must be done */
979 /* nRet=umount(pItem->pszDevice); */
980 /* if ( nRet != 0 ) */
984 /* #ifdef DEBUG_OSL_FILE */
985 /* perror("mount"); */
990 pszTmp
= getenv("SAL_MOUNT_UMOUNTPROG");
993 pszUmountProg
=pszTmp
;
996 pszTmp
= getenv("SAL_MOUNT_SU_DO");
1004 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s %s",pszSuDo
,pszUmountProg
,pItem
->pszMountPoint
);
1008 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s",pszUmountProg
,pItem
->pszMountPoint
);
1012 #ifdef DEBUG_OSL_FILE
1013 fprintf(stderr
,"executing '%s'\n",pszCmd
);
1016 nRet
= system(pszCmd
);
1018 #ifdef DEBUG_OSL_FILE
1019 fprintf(stderr
,"call returned '%i'\n",nRet
);
1020 fprintf(stderr
,"exit status is '%i'\n", WEXITSTATUS(nRet
));
1023 switch ( WEXITSTATUS(nRet
) )
1034 #ifdef TRACE_OSL_FILE
1035 fprintf(stderr
,"Out osl_unmountFloppy [ok]\n");
1038 return ((0 == nRet
) ? oslTranslateFileError(OSL_FET_SUCCESS
, nRet
) : oslTranslateFileError(OSL_FET_ERROR
, nRet
));
1040 /* return osl_File_E_None;*/
1047 osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
)
1049 struct mntent
* pMountEnt
;
1052 pMountTab
= setmntent (MOUNTTAB
, "r");
1056 while ((pMountEnt
= getmntent(pMountTab
)) != 0)
1058 if ( strncmp(pMountEnt
->mnt_dir
, pszPath
, strlen(pMountEnt
->mnt_dir
)) == 0
1059 && strncmp(pMountEnt
->mnt_fsname
, "/dev/fd", strlen("/dev/fd")) == 0)
1061 memset(pItem
->pszMountPoint
, 0, sizeof(pItem
->pszMountPoint
));
1062 strncpy(pItem
->pszMountPoint
, pMountEnt
->mnt_dir
, sizeof(pItem
->pszMountPoint
) - 1);
1064 memset(pItem
->pszFilePath
, 0, sizeof(pItem
->pszFilePath
));
1065 strncpy(pItem
->pszFilePath
, pMountEnt
->mnt_dir
, sizeof(pItem
->pszFilePath
) - 1);
1067 memset(pItem
->pszDevice
, 0, sizeof(pItem
->pszDevice
));
1068 strncpy(pItem
->pszDevice
, pMountEnt
->mnt_fsname
, sizeof(pItem
->pszDevice
) - 1);
1070 endmntent (pMountTab
);
1075 endmntent (pMountTab
);
1082 osl_isFloppyMounted (oslVolumeDeviceHandleImpl
* pDevice
)
1084 oslVolumeDeviceHandleImpl aItem
;
1086 if ( osl_getFloppyMountEntry (pDevice
->pszMountPoint
, &aItem
)
1087 && strcmp (aItem
.pszMountPoint
, pDevice
->pszMountPoint
) == 0
1088 && strcmp (aItem
.pszDevice
, pDevice
->pszDevice
) == 0)
1096 /******************************************************************************
1098 * IRIX FLOPPY FUNCTIONS
1100 *****************************************************************************/
1103 static oslVolumeDeviceHandle
osl_isFloppyDrive(const sal_Char
* pszPath
)
1105 oslVolumeDeviceHandleImpl
* pItem
= osl_newVolumeDeviceHandleImpl ();
1106 sal_Bool bRet
= sal_False
;
1108 #ifdef TRACE_OSL_FILE
1109 fprintf(stderr
,"In osl_isFloppyDrive\n");
1112 bRet
=osl_getFloppyMountEntry(pszPath
,pItem
);
1114 if ( bRet
== sal_False
)
1116 #ifdef TRACE_OSL_FILE
1117 fprintf(stderr
,"Out osl_isFloppyDrive [not a floppy]\n");
1119 rtl_freeMemory(pItem
);
1124 #ifdef DEBUG_OSL_FILE
1125 osl_printFloppyHandle(pItem
);
1127 #ifdef TRACE_OSL_FILE
1128 fprintf(stderr
,"Out osl_isFloppyDrive [ok]\n");
1131 return (oslVolumeDeviceHandle
) pItem
;
1135 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
1137 sal_Bool bRet
= sal_False
;
1138 oslVolumeDeviceHandleImpl
* pItem
=0;
1140 sal_Char pszCmd
[PATH_MAX
];
1141 sal_Char
* pszMountProg
= "mount";
1142 sal_Char
* pszSuDo
= 0;
1143 sal_Char
* pszTmp
= 0;
1147 #ifdef TRACE_OSL_FILE
1148 fprintf(stderr
,"In osl_mountFloppy\n");
1151 pItem
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
1155 #ifdef TRACE_OSL_FILE
1156 fprintf(stderr
,"Out osl_mountFloppy [pItem == 0]\n");
1159 return osl_File_E_INVAL
;
1162 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
1164 #ifdef TRACE_OSL_FILE
1165 fprintf(stderr
,"Out osl_mountFloppy [invalid handle]\n");
1167 return osl_File_E_INVAL
;
1170 bRet
= osl_isFloppyMounted(pItem
);
1171 if ( bRet
== sal_True
)
1173 #ifdef DEBUG_OSL_FILE
1174 fprintf(stderr
,"detected mounted floppy at '%s'\n",pItem
->pszMountPoint
);
1176 return osl_File_E_BUSY
;
1179 /* mfe: we can't use the mount(2) system call!!! */
1180 /* even if we are root */
1181 /* since mtab is not updated!!! */
1182 /* but we need it to be updated */
1183 /* some "magic" must be done */
1185 /* nRet = mount(pItem->pszDevice,pItem->pszMountPoint,0,0,0); */
1186 /* if ( nRet != 0 ) */
1189 /* #ifdef DEBUG_OSL_FILE */
1190 /* perror("mount"); */
1194 pszTmp
= getenv("SAL_MOUNT_MOUNTPROG");
1197 pszMountProg
=pszTmp
;
1200 pszTmp
=getenv("SAL_MOUNT_SU_DO");
1208 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s %s %s",pszSuDo
,pszMountProg
,pItem
->pszDevice
,pItem
->pszMountPoint
);
1212 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s",pszMountProg
,pItem
->pszMountPoint
);
1216 #ifdef DEBUG_OSL_FILE
1217 fprintf(stderr
,"executing '%s'\n",pszCmd
);
1220 nRet
= system(pszCmd
);
1222 #ifdef DEBUG_OSL_FILE
1223 fprintf(stderr
,"call returned '%i'\n",nRet
);
1224 fprintf(stderr
,"exit status is '%i'\n", WEXITSTATUS(nRet
));
1228 switch ( WEXITSTATUS(nRet
) )
1263 return ((0 == nRet
) ? oslTranslateFileError(OSL_FET_SUCCESS
, nRet
) : oslTranslateFileError(OSL_FET_ERROR
, nRet
));
1266 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
1268 oslVolumeDeviceHandleImpl
* pItem
=0;
1270 sal_Char pszCmd
[PATH_MAX
];
1271 sal_Char
* pszTmp
= 0;
1272 sal_Char
* pszSuDo
= 0;
1273 sal_Char
* pszUmountProg
= "umount";
1277 #ifdef TRACE_OSL_FILE
1278 fprintf(stderr
,"In osl_unmountFloppy\n");
1281 pItem
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
1285 #ifdef TRACE_OSL_FILE
1286 fprintf(stderr
,"Out osl_unmountFloppy [pItem==0]\n");
1288 return osl_File_E_INVAL
;
1291 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
1293 #ifdef TRACE_OSL_FILE
1294 fprintf(stderr
,"Out osl_unmountFloppy [invalid handle]\n");
1296 return osl_File_E_INVAL
;
1299 /* mfe: we can't use the umount(2) system call!!! */
1300 /* even if we are root */
1301 /* since mtab is not updated!!! */
1302 /* but we need it to be updated */
1303 /* some "magic" must be done */
1305 /* nRet=umount(pItem->pszDevice); */
1306 /* if ( nRet != 0 ) */
1310 /* #ifdef DEBUG_OSL_FILE */
1311 /* perror("mount"); */
1316 pszTmp
= getenv("SAL_MOUNT_UMOUNTPROG");
1319 pszUmountProg
=pszTmp
;
1322 pszTmp
= getenv("SAL_MOUNT_SU_DO");
1330 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s %s",pszSuDo
,pszUmountProg
,pItem
->pszMountPoint
);
1334 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s",pszUmountProg
,pItem
->pszMountPoint
);
1338 #ifdef DEBUG_OSL_FILE
1339 fprintf(stderr
,"executing '%s'\n",pszCmd
);
1342 nRet
= system(pszCmd
);
1344 #ifdef DEBUG_OSL_FILE
1345 fprintf(stderr
,"call returned '%i'\n",nRet
);
1346 fprintf(stderr
,"exit status is '%i'\n", WEXITSTATUS(nRet
));
1349 switch ( WEXITSTATUS(nRet
) )
1360 #ifdef TRACE_OSL_FILE
1361 fprintf(stderr
,"Out osl_unmountFloppy [ok]\n");
1364 return ((0 == nRet
) ? oslTranslateFileError(OSL_FET_SUCCESS
, nRet
) : oslTranslateFileError(OSL_FET_ERROR
, nRet
));
1366 /* return osl_File_E_None;*/
1369 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
)
1371 struct mntent
* pMountEnt
=0;
1372 sal_Char buffer
[PATH_MAX
];
1378 mntfile
= setmntent(MOUNTTAB
,"r");
1380 #ifdef TRACE_OSL_FILE
1381 fprintf(stderr
,"In osl_getFloppyMountEntry\n");
1384 memset(buffer
, 0, sizeof(buffer
));
1385 strncpy(buffer
, pszPath
, sizeof(buffer
) - 1);
1387 #ifdef DEBUG_OSL_FILE
1388 fprintf(stderr
,"Checking mount of %s\n",buffer
);
1395 #ifdef DEBUG_OSL_FILE
1398 #ifdef TRACE_OSL_FILE
1399 fprintf(stderr
,"Out osl_getFloppyMountEntry [mntfile]\n");
1404 pMountEnt
=getmntent(mntfile
);
1405 while ( pMountEnt
!= 0 )
1407 #ifdef DEBUG_OSL_FILE
1408 /* fprintf(stderr,"mnt_fsname : %s\n",pMountEnt->mnt_fsname); */
1409 /* fprintf(stderr,"mnt_dir : %s\n",pMountEnt->mnt_dir); */
1410 /* fprintf(stderr,"mnt_type : %s\n",pMountEnt->mnt_type);*/
1412 if ( strcmp(pMountEnt
->mnt_dir
,buffer
) == 0 &&
1413 strncmp(pMountEnt
->mnt_fsname
,"/dev/fd",strlen("/dev/fd")) == 0 )
1416 memset(pItem
->pszMountPoint
, 0, sizeof(pItem
->pszMountPoint
));
1417 strncpy(pItem
->pszMountPoint
, pMountEnt
->mnt_dir
, sizeof(pItem
->pszMountPoint
) - 1);
1419 memset(pItem
->pszFilePath
, 0, sizeof(pItem
->pszFilePath
));
1420 strncpy(pItem
->pszFilePath
, pMountEnt
->mnt_dir
, sizeof(pItem
->pszFilePath
) - 1);
1422 memset(pItem
->pszDevice
, 0, sizeof(pItem
->pszDevice
));
1423 strncpy(pItem
->pszDevice
, pMountEnt
->mnt_fsname
, sizeof(pItem
->pszDevice
) - 1);
1426 #ifdef DEBUG_OSL_FILE
1427 fprintf(stderr
,"Mount Point found '%s'\n",pItem
->pszMountPoint
);
1429 #ifdef TRACE_OSL_FILE
1430 fprintf(stderr
,"Out osl_getFloppyMountEntry [found]\n");
1434 #ifdef DEBUG_OSL_FILE
1435 /* fprintf(stderr,"=================\n");*/
1437 pMountEnt
=getmntent(mntfile
);
1440 #ifdef TRACE_OSL_FILE
1441 fprintf(stderr
,"Out osl_getFloppyMountEntry [not found]\n");
1448 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
)
1450 sal_Char buffer
[PATH_MAX
];
1451 oslVolumeDeviceHandleImpl
* pItem
=0;
1456 #ifdef TRACE_OSL_FILE
1457 fprintf(stderr
,"In osl_isFloppyMounted\n");
1460 pItem
= osl_newVolumeDeviceHandleImpl ();
1462 return osl_File_E_NOMEM
;
1464 memset(buffer
, 0, sizeof(buffer
));
1465 strncpy(buffer
, pDevice
->pszMountPoint
, sizeof(buffer
) - 1);
1467 #ifdef DEBUG_OSL_FILE
1468 fprintf(stderr
,"Checking mount of %s\n",buffer
);
1471 bRet
= osl_getFloppyMountEntry(buffer
,pItem
);
1473 if ( bRet
== sal_False
)
1475 #ifdef TRACE_OSL_FILE
1476 fprintf(stderr
,"Out osl_isFloppyMounted [not mounted]\n");
1481 if (strcmp(pItem
->pszMountPoint
, pDevice
->pszMountPoint
) == 0 &&
1482 strcmp(pItem
->pszDevice
,pDevice
->pszDevice
) == 0)
1484 #ifdef TRACE_OSL_FILE
1485 fprintf(stderr
,"Out osl_isFloppyMounted [is mounted]\n");
1487 rtl_freeMemory(pItem
);
1491 #ifdef TRACE_OSL_FILE
1492 fprintf(stderr
,"Out osl_isFloppyMounted [may be EBUSY]\n");
1495 rtl_freeMemory(pItem
);
1501 /* NetBSD floppy functions have to be added here. Until we have done that,
1502 * we use the MACOSX definitions for nonexistent floppy.
1505 /******************************************************************************
1507 * MAC OS X FLOPPY FUNCTIONS
1509 *****************************************************************************/
1511 #if (defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
1512 static oslVolumeDeviceHandle
osl_isFloppyDrive(const sal_Char
* pszPath
)
1518 #if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
1519 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
1521 return osl_File_E_BUSY
;
1525 #if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
1526 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
1528 return osl_File_E_BUSY
;
1532 #if ( defined(NETBSD) || defined(FREEBSD) )
1533 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
)
1537 #endif /* NETBSD || FREEBSD */
1539 #if ( defined(NETBSD) || defined(FREEBSD) )
1540 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
)
1544 #endif /* NETBSD || FREEBSD */
1547 #ifdef DEBUG_OSL_FILE
1548 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl
* pItem
)
1552 fprintf(stderr
,"NULL Handle\n");
1555 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
1557 #ifdef TRACE_OSL_FILE
1558 fprintf(stderr
,"Invalid Handle]\n");
1564 fprintf(stderr
,"MountPoint : '%s'\n",pItem
->pszMountPoint
);
1565 fprintf(stderr
,"FilePath : '%s'\n",pItem
->pszFilePath
);
1566 fprintf(stderr
,"Device : '%s'\n",pItem
->pszDevice
);