Update ooo320-m1
[ooovba.git] / sal / osl / os2 / file.cxx
blobb967cf197fccd85f220c1d93671868c49df00c16
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: file.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 /************************************************************************
33 * ToDo
35 * Fix osl_getCanonicalName
37 * - Fix: check for corresponding struct sizes in exported functions
38 * - check size/use of oslDirectory
39 * - check size/use of oslDirectoryItem
40 * - check size/use of oslFileStatus
41 * - check size/use of oslVolumeDeviceHandle
42 * - check size/use of oslVolumeInfo
43 * - check size/use of oslFileHandle
44 ***********************************************************************/
46 #define INCL_DOSDEVIOCTL // OS2 device definitions
48 #include "system.h"
49 #include <rtl/alloc.h>
51 #include "osl/file.hxx"
54 #include <sal/types.h>
55 #include <osl/thread.h>
56 #include <osl/diagnose.h>
57 #include "file_error_transl.h"
58 #include <osl/time.h>
60 #ifndef _FILE_URL_H_
61 #include "file_url.h"
62 #endif
64 #include "file_path_helper.hxx"
65 #include "uunxapi.hxx"
67 #ifndef _STRING_H_
68 #include <string.h>
69 #endif
71 #ifndef _CTYPE_H_
72 #include <ctype.h>
73 #endif
75 #ifndef _WCHAR_H_
76 #include <wchar.h>
77 #endif
79 #if OSL_DEBUG_LEVEL > 1
80 extern void debug_ustring(rtl_uString*);
81 #endif
84 #ifdef DEBUG_OSL_FILE
85 # define PERROR( a, b ) perror( a ); fprintf( stderr, b )
86 #else
87 # define PERROR( a, b )
88 #endif
90 extern "C" oslFileHandle osl_createFileHandleFromFD( int fd );
92 struct errentry errtable[] = {
93 { NO_ERROR, osl_File_E_None }, /* 0 */
94 { ERROR_INVALID_FUNCTION, osl_File_E_INVAL }, /* 1 */
95 { ERROR_FILE_NOT_FOUND, osl_File_E_NOENT }, /* 2 */
96 { ERROR_PATH_NOT_FOUND, osl_File_E_NOENT }, /* 3 */
97 { ERROR_TOO_MANY_OPEN_FILES, osl_File_E_MFILE }, /* 4 */
98 { ERROR_ACCESS_DENIED, osl_File_E_ACCES }, /* 5 */
99 { ERROR_INVALID_HANDLE, osl_File_E_BADF }, /* 6 */
100 { ERROR_ARENA_TRASHED, osl_File_E_NOMEM }, /* 7 */
101 { ERROR_NOT_ENOUGH_MEMORY, osl_File_E_NOMEM }, /* 8 */
102 { ERROR_INVALID_BLOCK, osl_File_E_NOMEM }, /* 9 */
103 { ERROR_BAD_ENVIRONMENT, osl_File_E_2BIG }, /* 10 */
104 { ERROR_BAD_FORMAT, osl_File_E_NOEXEC }, /* 11 */
105 { ERROR_INVALID_ACCESS, osl_File_E_INVAL }, /* 12 */
106 { ERROR_INVALID_DATA, osl_File_E_INVAL }, /* 13 */
107 { ERROR_INVALID_DRIVE, osl_File_E_NOENT }, /* 15 */
108 { ERROR_CURRENT_DIRECTORY, osl_File_E_ACCES }, /* 16 */
109 { ERROR_NOT_SAME_DEVICE, osl_File_E_XDEV }, /* 17 */
110 { ERROR_NO_MORE_FILES, osl_File_E_NOENT }, /* 18 */
111 { ERROR_NOT_READY, osl_File_E_NOTREADY }, /* 21 */
112 { ERROR_LOCK_VIOLATION, osl_File_E_ACCES }, /* 33 */
113 { ERROR_BAD_NETPATH, osl_File_E_NOENT }, /* 53 */
114 { ERROR_NETWORK_ACCESS_DENIED, osl_File_E_ACCES }, /* 65 */
115 { ERROR_BAD_NET_NAME, osl_File_E_NOENT }, /* 67 */
116 { ERROR_FILE_EXISTS, osl_File_E_EXIST }, /* 80 */
117 { ERROR_CANNOT_MAKE, osl_File_E_ACCES }, /* 82 */
118 { ERROR_FAIL_I24, osl_File_E_ACCES }, /* 83 */
119 { ERROR_INVALID_PARAMETER, osl_File_E_INVAL }, /* 87 */
120 { ERROR_NO_PROC_SLOTS, osl_File_E_AGAIN }, /* 89 */
121 { ERROR_DRIVE_LOCKED, osl_File_E_ACCES }, /* 108 */
122 { ERROR_BROKEN_PIPE, osl_File_E_PIPE }, /* 109 */
123 { ERROR_DISK_FULL, osl_File_E_NOSPC }, /* 112 */
124 { ERROR_INVALID_TARGET_HANDLE, osl_File_E_BADF }, /* 114 */
125 { ERROR_INVALID_HANDLE, osl_File_E_INVAL }, /* 124 */
126 { ERROR_WAIT_NO_CHILDREN, osl_File_E_CHILD }, /* 128 */
127 { ERROR_CHILD_NOT_COMPLETE, osl_File_E_CHILD }, /* 129 */
128 { ERROR_DIRECT_ACCESS_HANDLE, osl_File_E_BADF }, /* 130 */
129 { ERROR_NEGATIVE_SEEK, osl_File_E_INVAL }, /* 131 */
130 { ERROR_SEEK_ON_DEVICE, osl_File_E_ACCES }, /* 132 */
131 { ERROR_DIR_NOT_EMPTY, osl_File_E_NOTEMPTY }, /* 145 */
132 { ERROR_NOT_LOCKED, osl_File_E_ACCES }, /* 158 */
133 { ERROR_BAD_PATHNAME, osl_File_E_NOENT }, /* 161 */
134 { ERROR_MAX_THRDS_REACHED, osl_File_E_AGAIN }, /* 164 */
135 { ERROR_LOCK_FAILED, osl_File_E_ACCES }, /* 167 */
136 { ERROR_ALREADY_EXISTS, osl_File_E_EXIST }, /* 183 */
137 { ERROR_FILENAME_EXCED_RANGE, osl_File_E_NOENT }, /* 206 */
138 { ERROR_NESTING_NOT_ALLOWED, osl_File_E_AGAIN }, /* 215 */
139 { ERROR_DIRECTORY, osl_File_E_NOENT }, /* 267 */
140 //{ ERROR_NOT_ENOUGH_QUOTA, osl_File_E_NOMEM } /* 1816 */
143 #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
145 //#####################################################
146 oslFileError MapError(APIRET dwError)
148 for (int i = 0; i < ELEMENTS_OF_ARRAY(errtable); ++i )
150 if (dwError == errtable[i].oscode)
151 return static_cast<oslFileError>(errtable[i].errnocode);
153 return osl_File_E_INVAL;
156 /******************************************************************************
158 * static members
160 *****************************************************************************/
162 static const char * pFileLockEnvVar = (char *) -1;
165 /******************************************************************************
167 * C-String Function Declarations
169 *****************************************************************************/
171 static oslFileError osl_psz_getVolumeInformation(const sal_Char* , oslVolumeInfo* pInfo, sal_uInt32 uFieldMask);
172 static oslFileError osl_psz_removeFile(const sal_Char* pszPath);
173 static oslFileError osl_psz_createDirectory(const sal_Char* pszPath);
174 static oslFileError osl_psz_removeDirectory(const sal_Char* pszPath);
175 static oslFileError osl_psz_copyFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
176 static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
177 static oslFileError osl_psz_setFileTime(const sal_Char* strFilePath, const TimeValue* pCreationTime, const TimeValue* pLastAccessTime, const TimeValue* pLastWriteTime);
180 /******************************************************************************
182 * Static Module Utility Function Declarations
184 *****************************************************************************/
186 static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists);
187 static oslFileError oslChangeFileModes(const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID);
188 static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName);
189 static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode);
190 static oslFileError oslDoMoveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
191 rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr,rtl_uString** uStr);
193 /******************************************************************************
195 * Non-Static Utility Function Declarations
197 *****************************************************************************/
199 extern "C" int UnicodeToText( char *, size_t, const sal_Unicode *, sal_Int32 );
200 extern "C" int TextToUnicode(
201 const char* text, size_t text_buffer_size, sal_Unicode* unic_text, sal_Int32 unic_text_buffer_size);
203 /******************************************************************************
205 * 'removeable device' aka floppy functions
207 *****************************************************************************/
209 static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath);
210 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy);
211 static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy);
213 #ifdef DEBUG_OSL_FILE
214 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* hFloppy);
215 #endif
217 /**********************************************
218 * _osl_openLocalRoot
219 * enumerate available drives
220 *********************************************/
221 static oslFileError _osl_openLocalRoot( rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
223 rtl_uString *ustrSystemPath = NULL;
224 oslFileError error;
226 if ( !pDirectory )
227 return osl_File_E_INVAL;
229 *pDirectory = NULL;
231 error = osl_getSystemPathFromFileURL_Ex( strDirectoryPath, &ustrSystemPath, sal_False );
233 if ( osl_File_E_None == error )
235 /* create and initialize impl structure */
236 DirectoryImpl* pDirImpl = (DirectoryImpl*) rtl_allocateMemory( sizeof(DirectoryImpl) );
237 if( pDirImpl )
239 ULONG ulDriveNum;
240 APIRET rc;
241 pDirImpl->uType = DIRECTORYTYPE_LOCALROOT;
242 pDirImpl->ustrPath = ustrSystemPath;
243 rc = DosQueryCurrentDisk (&ulDriveNum, &pDirImpl->ulDriveMap);
244 pDirImpl->pDirStruct = 0;
245 pDirImpl->ulNextDrive = 1;
246 pDirImpl->ulNextDriveMask = 1;
248 // determine number of floppy-drives
249 BYTE nFloppies;
250 rc = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY );
251 if (nFloppies == 0) {
252 // if no floppies, start with 3rd drive (C:)
253 pDirImpl->ulNextDrive = 3;
254 pDirImpl->ulNextDriveMask <<= 2;
255 } else if (nFloppies == 1) {
256 // mask drive B (second bit) in this case
257 pDirImpl->ulDriveMap &= ~0x02;
259 *pDirectory = (oslDirectory) pDirImpl;
260 return osl_File_E_None;
262 else
264 errno = osl_File_E_NOMEM;
269 rtl_uString_release( ustrSystemPath );
270 return error;
273 /**********************************************
274 * _osl_getNextDrive
275 *********************************************/
276 static oslFileError SAL_CALL _osl_getNextDrive(
277 oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint )
279 DirectoryImpl *pDirImpl = (DirectoryImpl *)Directory;
280 DirectoryItem_Impl *pItemImpl = NULL;
281 rtl_uString * ustrDrive = NULL;
282 BOOL fSuccess;
283 char buffer[3];
285 uHint = uHint; /* avoid warnings */
287 if ( !pItem )
288 return osl_File_E_INVAL;
290 *pItem = NULL;
292 if ( !pDirImpl )
293 return osl_File_E_INVAL;
295 while( pDirImpl->ulNextDrive <= 26)
297 // exit if bit==1 -> drive found
298 if (pDirImpl->ulDriveMap & pDirImpl->ulNextDriveMask) {
300 /* convert file name to unicode */
301 buffer[0] = '@' + pDirImpl->ulNextDrive;
302 buffer[1] = ':';
303 buffer[2] = 0;
305 pItemImpl = (DirectoryItem_Impl*) rtl_allocateMemory(sizeof(DirectoryItem_Impl));
306 if ( !pItemImpl )
307 return osl_File_E_NOMEM;
309 memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
310 pItemImpl->uType = DIRECTORYITEM_DRIVE;
311 pItemImpl->nRefCount = 1;
313 rtl_string2UString( &pItemImpl->ustrDrive, buffer, 3,
314 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
315 OSL_ASSERT(pItemImpl->ustrDrive != 0);
317 /* use drive as directory item */
318 *pItem = (oslDirectoryItem) pItemImpl;
320 // scan next bit position
321 pDirImpl->ulNextDrive++;
322 pDirImpl->ulNextDriveMask <<= 1;
324 if (*pItem) // item assigned, return now.
325 return osl_File_E_None;
328 // no more items
329 return osl_File_E_NOENT;
332 /**********************************************
333 * _osl_readdir_impl_
335 * readdir wrapper, filters out "." and ".."
336 * on request
337 *********************************************/
339 static struct dirent* _osl_readdir_impl_(DIR* pdir, sal_Bool bFilterLocalAndParentDir)
341 struct dirent* pdirent;
343 while ((pdirent = readdir(pdir)) != NULL)
345 if (bFilterLocalAndParentDir &&
346 ((0 == strcmp(pdirent->d_name, ".")) || (0 == strcmp(pdirent->d_name, ".."))))
347 continue;
348 else
349 break;
352 return pdirent;
355 /*******************************************************************
356 * osl_openDirectory
357 ******************************************************************/
359 oslFileError SAL_CALL osl_openDirectory(rtl_uString* ustrDirectoryURL, oslDirectory* pDirectory)
361 rtl_uString* ustrSystemPath = NULL;
362 oslFileError eRet;
364 char path[PATH_MAX];
366 OSL_ASSERT(ustrDirectoryURL && (ustrDirectoryURL->length > 0));
367 OSL_ASSERT(pDirectory);
369 if (0 == ustrDirectoryURL->length )
370 return osl_File_E_INVAL;
372 if ( 0 == rtl_ustr_compareIgnoreAsciiCase( ustrDirectoryURL->buffer, (const sal_Unicode*)L"file:///" ) )
373 return _osl_openLocalRoot( ustrDirectoryURL, pDirectory );
375 /* convert file URL to system path */
376 eRet = osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL, &ustrSystemPath, sal_False);
378 if( osl_File_E_None != eRet )
379 return eRet;
381 osl_systemPathRemoveSeparator(ustrSystemPath);
383 /* convert unicode path to text */
384 if ( UnicodeToText( path, PATH_MAX, ustrSystemPath->buffer, ustrSystemPath->length ) )
386 // if only the drive is specified (x:), add a \ (x:\) otherwise current
387 // directory is browsed instead of root.
388 if (strlen( path) == 2 && path[1] == ':')
389 strcat( path, "\\");
390 /* open directory */
391 DIR *pdir = opendir( path );
393 if( pdir )
395 /* create and initialize impl structure */
396 DirectoryImpl* pDirImpl = (DirectoryImpl*) rtl_allocateMemory( sizeof(DirectoryImpl) );
398 if( pDirImpl )
400 pDirImpl->uType = DIRECTORYTYPE_FILESYSTEM;
401 pDirImpl->pDirStruct = pdir;
402 pDirImpl->ustrPath = ustrSystemPath;
404 *pDirectory = (oslDirectory) pDirImpl;
405 return osl_File_E_None;
407 else
409 errno = ENOMEM;
410 closedir( pdir );
413 else
414 /* should be removed by optimizer in product version */
415 PERROR( "osl_openDirectory", path );
418 rtl_uString_release( ustrSystemPath );
420 return oslTranslateFileError(OSL_FET_ERROR, errno);
424 /****************************************************************************
425 * osl_getNextDirectoryItem
426 ***************************************************************************/
428 oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory Directory, oslDirectoryItem* pItem, sal_uInt32 uHint)
430 DirectoryImpl* pDirImpl = (DirectoryImpl*)Directory;
431 DirectoryItem_Impl *pItemImpl = NULL;
432 rtl_uString* ustrFileName = NULL;
433 rtl_uString* ustrFilePath = NULL;
434 struct dirent* pEntry;
436 OSL_ASSERT(Directory);
437 OSL_ASSERT(pItem);
439 if ((NULL == Directory) || (NULL == pItem))
440 return osl_File_E_INVAL;
442 if ( pDirImpl->uType == DIRECTORYTYPE_LOCALROOT)
443 return _osl_getNextDrive( Directory, pItem, uHint );
445 pEntry = _osl_readdir_impl_(pDirImpl->pDirStruct, sal_True);
447 if (NULL == pEntry)
448 return osl_File_E_NOENT;
450 pItemImpl = (DirectoryItem_Impl*) rtl_allocateMemory(sizeof(DirectoryItem_Impl));
451 if ( !pItemImpl )
452 return osl_File_E_NOMEM;
454 memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
455 pItemImpl->uType = DIRECTORYITEM_FILE;
456 pItemImpl->nRefCount = 1;
457 pItemImpl->d_attr = pEntry->d_attr;
459 /* convert file name to unicode */
460 rtl_string2UString( &ustrFileName, pEntry->d_name, strlen( pEntry->d_name ),
461 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
462 OSL_ASSERT(ustrFileName != 0);
464 osl_systemPathMakeAbsolutePath(pDirImpl->ustrPath, ustrFileName, &pItemImpl->ustrFilePath);
465 rtl_uString_release( ustrFileName );
467 *pItem = (oslDirectoryItem)pItemImpl;
468 return osl_File_E_None;
471 /****************************************************************************/
472 /* osl_closeDirectory */
473 /****************************************************************************/
475 oslFileError SAL_CALL osl_closeDirectory( oslDirectory Directory )
477 DirectoryImpl* pDirImpl = (DirectoryImpl*) Directory;
478 oslFileError err = osl_File_E_None;
480 OSL_ASSERT( Directory );
482 if( NULL == pDirImpl )
483 return osl_File_E_INVAL;
485 switch ( pDirImpl->uType )
487 case DIRECTORYTYPE_FILESYSTEM:
488 if( closedir( pDirImpl->pDirStruct ) )
489 err = oslTranslateFileError(OSL_FET_ERROR, errno);
490 break;
491 case DIRECTORYTYPE_LOCALROOT:
492 err = osl_File_E_None;
493 break;
494 #if 0
495 case DIRECTORYTYPE_NETROOT:
497 DWORD err = WNetCloseEnum(pDirImpl->hDirectory);
498 eError = (err == NO_ERROR) ? osl_File_E_None : MapError(err);
500 break;
501 #endif
502 default:
503 OSL_ENSURE( 0, "Invalid directory type" );
504 break;
507 /* cleanup members */
508 rtl_uString_release( pDirImpl->ustrPath );
510 rtl_freeMemory( pDirImpl );
512 return err;
515 /****************************************************************************/
516 /* osl_getDirectoryItem */
517 /****************************************************************************/
519 oslFileError SAL_CALL osl_getDirectoryItem( rtl_uString* ustrFileURL, oslDirectoryItem* pItem )
521 rtl_uString* strSysFilePath = NULL;
522 oslFileError error = osl_File_E_INVAL;
523 ULONG dwPathType;
524 PATHTYPE type = PATHTYPE_FILE;
526 OSL_ASSERT(ustrFileURL);
527 OSL_ASSERT(pItem);
529 /* Assume failure */
530 if ( !pItem )
531 return osl_File_E_INVAL;
532 *pItem = NULL;
534 if (0 == ustrFileURL->length || NULL == pItem)
535 return osl_File_E_INVAL;
537 error = osl_getSystemPathFromFileURL_Ex(ustrFileURL, &strSysFilePath, sal_False);
539 if (osl_File_E_None != error)
540 return error;
542 dwPathType = IsValidFilePath( strSysFilePath->buffer, NULL, VALIDATEPATH_NORMAL );
544 if ( dwPathType & PATHTYPE_IS_VOLUME )
545 type = PATHTYPE_VOLUME;
546 else if ( dwPathType & PATHTYPE_IS_SERVER )
547 type = PATHTYPE_NETSERVER;
548 else
549 type = PATHTYPE_FILE;
551 switch ( type )
553 case PATHTYPE_NETSERVER:
555 DirectoryItem_Impl* pItemImpl =
556 reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
558 if ( !pItemImpl )
559 error = osl_File_E_NOMEM;
561 if ( osl_File_E_None == error )
563 memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
564 pItemImpl->uType = DIRECTORYITEM_SERVER;
565 pItemImpl->nRefCount = 1;
566 rtl_uString_assign( &pItemImpl->ustrFilePath, strSysFilePath );
568 *pItem = pItemImpl;
571 break;
572 case PATHTYPE_VOLUME:
574 DirectoryItem_Impl* pItemImpl =
575 reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
577 if ( !pItemImpl )
578 error = osl_File_E_NOMEM;
580 if ( osl_File_E_None == error )
582 memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
583 pItemImpl->uType = DIRECTORYITEM_DRIVE;
584 pItemImpl->nRefCount = 1;
585 rtl_uString_assign( &pItemImpl->ustrDrive, strSysFilePath );
587 if ( pItemImpl->ustrDrive->buffer[pItemImpl->ustrDrive->length-1] != sal_Unicode('\\') )
588 rtl_uString_newConcat( &pItemImpl->ustrDrive,
589 pItemImpl->ustrDrive, rtl::OUString::createFromAscii( "\\" ).pData);
591 *pItem = pItemImpl;
594 break;
595 default:
596 case PATHTYPE_FILE:
598 if ( strSysFilePath->length > 0 && strSysFilePath->buffer[strSysFilePath->length - 1] == '\\' )
599 rtl_uString_newFromStr_WithLength( &strSysFilePath, strSysFilePath->buffer, strSysFilePath->length - 1 );
601 if (0 == access_u(strSysFilePath, F_OK))
603 DirectoryItem_Impl *pItemImpl =
604 reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
606 memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
607 pItemImpl->uType = DIRECTORYITEM_FILE;
608 pItemImpl->nRefCount = 1;
609 rtl_uString_assign( &pItemImpl->ustrFilePath, strSysFilePath );
611 *pItem = pItemImpl;
613 else
614 error = oslTranslateFileError(OSL_FET_ERROR, errno);
616 break;
619 if ( strSysFilePath )
620 rtl_uString_release( strSysFilePath );
622 return error;
625 /****************************************************************************/
626 /* osl_acquireDirectoryItem */
627 /****************************************************************************/
629 oslFileError osl_acquireDirectoryItem( oslDirectoryItem Item )
631 OSL_ASSERT( Item );
632 DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
634 if ( !pItemImpl )
635 return osl_File_E_INVAL;
637 pItemImpl->nRefCount++;
638 return osl_File_E_None;
641 /****************************************************************************/
642 /* osl_releaseDirectoryItem */
643 /****************************************************************************/
645 oslFileError osl_releaseDirectoryItem( oslDirectoryItem Item )
647 OSL_ASSERT( Item );
648 DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
650 if ( !pItemImpl )
651 return osl_File_E_INVAL;
653 if ( ! --pItemImpl->nRefCount )
655 if (pItemImpl->ustrFilePath)
656 rtl_uString_release( pItemImpl->ustrFilePath );
657 if (pItemImpl->ustrDrive)
658 rtl_uString_release( pItemImpl->ustrDrive );
659 rtl_freeMemory( pItemImpl );
661 return osl_File_E_None;
664 /****************************************************************************
665 * osl_createFileHandleFromFD
666 ***************************************************************************/
668 oslFileHandle osl_createFileHandleFromFD( int fd )
670 oslFileHandleImpl* pHandleImpl = NULL;
672 if ( fd >= 0 )
674 pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
676 if( pHandleImpl )
678 pHandleImpl->ustrFilePath = NULL;
679 rtl_uString_new( &pHandleImpl->ustrFilePath );
680 pHandleImpl->fd = fd;
682 /* FIXME: should detect whether the file has been locked */
683 pHandleImpl->bLocked = sal_True;
687 return (oslFileHandle)pHandleImpl;
690 /****************************************************************************
691 * osl_openFile
692 ***************************************************************************/
694 oslFileError osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags )
696 oslFileHandleImpl* pHandleImpl = NULL;
697 oslFileError eRet;
698 rtl_uString* ustrFilePath = NULL;
700 char buffer[PATH_MAX];
701 int fd;
702 int mode = S_IRUSR | S_IRGRP | S_IROTH;
703 int flags = O_RDONLY;
705 struct flock aflock;
707 /* locking the complete file */
708 aflock.l_type = 0;
709 aflock.l_whence = SEEK_SET;
710 aflock.l_start = 0;
711 aflock.l_len = 0;
713 OSL_ASSERT( ustrFileURL );
714 OSL_ASSERT( pHandle );
716 if( ( 0 == ustrFileURL->length ) )
717 return osl_File_E_INVAL;
719 /* convert file URL to system path */
720 eRet = osl_getSystemPathFromFileURL( ustrFileURL, &ustrFilePath );
722 if( osl_File_E_None != eRet )
723 return eRet;
725 osl_systemPathRemoveSeparator(ustrFilePath);
727 /* convert unicode path to text */
728 if( UnicodeToText( buffer, PATH_MAX, ustrFilePath->buffer, ustrFilePath->length ) )
730 /* we do not open devices or such here */
731 if( !( uFlags & osl_File_OpenFlag_Create ) )
733 struct stat aFileStat;
735 if( 0 > stat( buffer, &aFileStat ) )
737 PERROR( "osl_openFile", buffer );
738 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
741 else if( !S_ISREG( aFileStat.st_mode ) )
743 eRet = osl_File_E_INVAL;
747 if( osl_File_E_None == eRet )
750 * set flags and mode
753 if ( uFlags & osl_File_OpenFlag_Write )
755 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
756 flags = O_RDWR;
757 aflock.l_type = F_WRLCK;
760 if ( uFlags & osl_File_OpenFlag_Create )
762 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
763 flags = O_CREAT | O_EXCL | O_RDWR;
766 /* open the file */
767 fd = open( buffer, flags | O_BINARY, mode);
768 if ( fd >= 0 )
770 sal_Bool bNeedsLock = ( ( uFlags & osl_File_OpenFlag_NoLock ) == 0 );
771 sal_Bool bLocked = sal_False;
772 if( bNeedsLock )
774 /* check if file lock is enabled and clear l_type member of flock otherwise */
775 if( (char *) -1 == pFileLockEnvVar )
777 /* FIXME: this is not MT safe */
778 pFileLockEnvVar = getenv("SAL_ENABLE_FILE_LOCKING");
780 if( NULL == pFileLockEnvVar)
781 pFileLockEnvVar = getenv("STAR_ENABLE_FILE_LOCKING");
784 if( NULL == pFileLockEnvVar )
785 aflock.l_type = 0;
787 /* lock the file if flock.l_type is set */
788 bLocked = ( F_WRLCK != aflock.l_type || -1 != fcntl( fd, F_SETLK, &aflock ) );
791 if ( !bNeedsLock || bLocked )
793 /* allocate memory for impl structure */
794 pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
795 if( pHandleImpl )
797 pHandleImpl->ustrFilePath = ustrFilePath;
798 pHandleImpl->fd = fd;
799 pHandleImpl->bLocked = bLocked;
801 *pHandle = (oslFileHandle) pHandleImpl;
803 return osl_File_E_None;
805 else
807 errno = ENOMEM;
811 close( fd );
814 PERROR( "osl_openFile", buffer );
815 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
818 else
819 eRet = osl_File_E_INVAL;
821 rtl_uString_release( ustrFilePath );
822 return eRet;
825 /****************************************************************************/
826 /* osl_closeFile */
827 /****************************************************************************/
829 oslFileError osl_closeFile( oslFileHandle Handle )
831 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl *) Handle;
832 oslFileError eRet = osl_File_E_INVAL;
834 OSL_ASSERT( Handle );
836 if( pHandleImpl )
838 rtl_uString_release( pHandleImpl->ustrFilePath );
840 /* release file lock if locking is enabled */
841 if( pFileLockEnvVar )
843 struct flock aflock;
845 aflock.l_type = F_UNLCK;
846 aflock.l_whence = SEEK_SET;
847 aflock.l_start = 0;
848 aflock.l_len = 0;
850 if ( pHandleImpl->bLocked )
852 /* FIXME: check if file is really locked ? */
854 /* release the file share lock on this file */
855 if( -1 == fcntl( pHandleImpl->fd, F_SETLK, &aflock ) )
856 PERROR( "osl_closeFile", "unlock failed" );
860 if( 0 > close( pHandleImpl->fd ) )
862 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
864 else
865 eRet = osl_File_E_None;
867 rtl_freeMemory( pHandleImpl );
870 return eRet;
873 /****************************************************************************/
874 /* osl_isEndOfFile */
875 /****************************************************************************/
877 oslFileError SAL_CALL osl_isEndOfFile( oslFileHandle Handle, sal_Bool *pIsEOF )
879 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl *) Handle;
880 oslFileError eRet = osl_File_E_INVAL;
882 if ( pHandleImpl)
884 long curPos = lseek( pHandleImpl->fd, 0, SEEK_CUR );
886 if ( curPos >= 0 )
888 long endPos = lseek( pHandleImpl->fd, 0, SEEK_END );
890 if ( endPos >= 0 )
892 *pIsEOF = ( curPos == endPos );
893 curPos = lseek( pHandleImpl->fd, curPos, SEEK_SET );
895 if ( curPos >= 0 )
896 eRet = osl_File_E_None;
897 else
898 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
900 else
901 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
903 else
904 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
907 return eRet;
911 /****************************************************************************/
912 /* osl_moveFile */
913 /****************************************************************************/
915 oslFileError osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
917 char srcPath[PATH_MAX];
918 char destPath[PATH_MAX];
919 oslFileError eRet;
920 APIRET rc;
922 OSL_ASSERT( ustrFileURL );
923 OSL_ASSERT( ustrDestURL );
925 /* convert source url to system path */
926 eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
927 if( eRet != osl_File_E_None )
928 return eRet;
930 /* convert destination url to system path */
931 eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
932 if( eRet != osl_File_E_None )
933 return eRet;
935 //YD 01/05/06 rename() can overwrite existing files.
936 rc = DosDelete( (PCSZ)destPath);
937 rc = DosMove( (PCSZ)srcPath, (PCSZ)destPath);
938 if (!rc)
939 eRet = osl_File_E_None;
940 else
941 eRet = MapError( rc);
943 return eRet;
946 /****************************************************************************/
947 /* osl_copyFile */
948 /****************************************************************************/
950 #define TMP_DEST_FILE_EXTENSION ".osl-tmp"
952 static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists)
954 int nRet=0;
955 sal_Char pszTmpDestFile[PATH_MAX];
956 size_t size_tmp_dest_buff = sizeof(pszTmpDestFile);
958 /* Quick fix for #106048, the whole copy file function seems
959 to be erroneous anyway and needs to be rewritten.
960 Besides osl_copyFile is currently not used from OO/SO code.
962 memset(pszTmpDestFile, 0, size_tmp_dest_buff);
964 if ( DestFileExists )
966 strncpy(pszTmpDestFile, pszDestFileName, size_tmp_dest_buff - 1);
968 if ((strlen(pszTmpDestFile) + strlen(TMP_DEST_FILE_EXTENSION)) >= size_tmp_dest_buff)
969 return osl_File_E_NAMETOOLONG;
971 strncat(pszTmpDestFile, TMP_DEST_FILE_EXTENSION, strlen(TMP_DEST_FILE_EXTENSION));
973 /* FIXME: what if pszTmpDestFile already exists? */
974 /* with getcanonical??? */
975 nRet=rename(pszDestFileName,pszTmpDestFile);
978 /* mfe: should be S_ISREG */
979 if ( !S_ISLNK(nMode) )
981 /* copy SourceFile to DestFile */
982 nRet = oslDoCopyFile(pszSourceFileName,pszDestFileName,nSourceSize, nMode);
984 /* mfe: OK redundant at the moment */
985 else if ( S_ISLNK(nMode) )
987 nRet = oslDoCopyLink(pszSourceFileName,pszDestFileName);
989 else
991 /* mfe: what to do here? */
992 nRet=ENOSYS;
995 if ( nRet > 0 && DestFileExists == 1 )
997 unlink(pszDestFileName);
998 rename(pszTmpDestFile,pszDestFileName);
1001 if ( nRet > 0 )
1003 return oslTranslateFileError(OSL_FET_ERROR, nRet);
1006 if ( DestFileExists == 1 )
1008 unlink(pszTmpDestFile);
1011 return osl_File_E_None;
1014 /*****************************************
1015 * oslChangeFileModes
1016 ****************************************/
1018 static oslFileError oslChangeFileModes( const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID)
1020 int nRet=0;
1021 struct utimbuf aTimeBuffer;
1023 nRet = chmod(pszFileName,nMode);
1024 if ( nRet < 0 )
1026 nRet=errno;
1027 return oslTranslateFileError(OSL_FET_ERROR, nRet);
1030 aTimeBuffer.actime=nAcTime;
1031 aTimeBuffer.modtime=nModTime;
1032 nRet=utime(pszFileName,&aTimeBuffer);
1033 if ( nRet < 0 )
1035 nRet=errno;
1036 return oslTranslateFileError(OSL_FET_ERROR, nRet);
1039 if ( nUID != getuid() )
1041 nUID=getuid();
1044 nRet=chown(pszFileName,nUID,nGID);
1045 if ( nRet < 0 )
1047 nRet=errno;
1049 /* mfe: do not return an error here! */
1050 /* return oslTranslateFileError(nRet);*/
1053 return osl_File_E_None;
1056 /*****************************************
1057 * oslDoCopyLink
1058 ****************************************/
1060 static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName)
1062 int nRet=0;
1064 /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
1065 /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
1066 sal_Char pszLinkContent[PATH_MAX];
1068 pszLinkContent[0] = '\0';
1070 nRet = readlink(pszSourceFileName,pszLinkContent,PATH_MAX);
1072 if ( nRet < 0 )
1074 nRet=errno;
1075 return nRet;
1077 else
1078 pszLinkContent[ nRet ] = 0;
1080 nRet = symlink(pszLinkContent,pszDestFileName);
1082 if ( nRet < 0 )
1084 nRet=errno;
1085 return nRet;
1088 return 0;
1091 /*****************************************
1092 * oslDoCopyFile
1093 ****************************************/
1095 static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode)
1097 int SourceFileFD=0;
1098 int DestFileFD=0;
1099 int nRet=0;
1100 void* pSourceFile=0;
1101 char buffer[ 4096];
1103 SourceFileFD=open(pszSourceFileName,O_RDONLY | O_BINARY);
1104 if ( SourceFileFD < 0 )
1106 nRet=errno;
1107 return nRet;
1110 DestFileFD=open(pszDestFileName, O_WRONLY | O_CREAT | O_BINARY, mode);
1111 if ( DestFileFD < 0 )
1113 nRet=errno;
1114 close(SourceFileFD);
1115 return nRet;
1118 /* HACK: because memory mapping fails on various
1119 platforms if the size of the source file is 0 byte */
1120 if (0 == nSourceSize)
1122 close(SourceFileFD);
1123 close(DestFileFD);
1124 return 0;
1127 while( (nRet = read(SourceFileFD, buffer, sizeof(buffer))) !=0 )
1129 nRet = write( DestFileFD, buffer, nRet);
1132 close(SourceFileFD);
1133 close(DestFileFD);
1135 return nRet;
1138 static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
1140 time_t nAcTime=0;
1141 time_t nModTime=0;
1142 uid_t nUID=0;
1143 gid_t nGID=0;
1144 int nRet=0;
1145 mode_t nMode=0;
1146 struct stat aFileStat;
1147 oslFileError tErr=osl_File_E_invalidError;
1148 size_t nSourceSize=0;
1149 int DestFileExists=1;
1151 /* mfe: does the source file really exists? */
1152 nRet = lstat(pszPath,&aFileStat);
1154 if ( nRet < 0 )
1156 nRet=errno;
1157 return oslTranslateFileError(OSL_FET_ERROR, nRet);
1160 /* mfe: we do only copy files here! */
1161 if ( S_ISDIR(aFileStat.st_mode) )
1163 return osl_File_E_ISDIR;
1166 nSourceSize=(size_t)aFileStat.st_size;
1167 nMode=aFileStat.st_mode;
1168 nAcTime=aFileStat.st_atime;
1169 nModTime=aFileStat.st_mtime;
1170 nUID=aFileStat.st_uid;
1171 nGID=aFileStat.st_gid;
1173 nRet = stat(pszDestPath,&aFileStat);
1174 if ( nRet < 0 )
1176 nRet=errno;
1178 if ( nRet == ENOENT )
1180 DestFileExists=0;
1182 /* return oslTranslateFileError(nRet);*/
1185 /* mfe: the destination file must not be a directory! */
1186 if ( nRet == 0 && S_ISDIR(aFileStat.st_mode) )
1188 return osl_File_E_ISDIR;
1190 else
1192 /* mfe: file does not exists or is no dir */
1195 tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
1197 if ( tErr != osl_File_E_None )
1199 return tErr;
1203 * mfe: ignore return code
1204 * since only the success of the copy is
1205 * important
1207 oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
1209 return tErr;
1212 oslFileError osl_copyFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
1214 char srcPath[PATH_MAX];
1215 char destPath[PATH_MAX];
1216 oslFileError eRet;
1217 APIRET rc;
1219 OSL_ASSERT( ustrFileURL );
1220 OSL_ASSERT( ustrDestURL );
1222 /* convert source url to system path */
1223 eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
1224 if( eRet != osl_File_E_None )
1225 return eRet;
1227 /* convert destination url to system path */
1228 eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
1229 if( eRet != osl_File_E_None )
1230 return eRet;
1232 return osl_psz_copyFile( srcPath, destPath );
1235 /****************************************************************************/
1236 /* osl_removeFile */
1237 /****************************************************************************/
1239 oslFileError osl_removeFile( rtl_uString* ustrFileURL )
1241 char path[PATH_MAX];
1242 oslFileError eRet;
1243 APIRET rc;
1245 OSL_ASSERT( ustrFileURL );
1247 /* convert file url to system path */
1248 eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
1249 if( eRet != osl_File_E_None )
1250 return eRet;
1252 rc = DosDelete( (PCSZ)path);
1253 if (!rc)
1254 eRet = osl_File_E_None;
1255 else
1256 eRet = MapError( rc);
1258 return eRet;
1261 /****************************************************************************/
1262 /* osl_getVolumeInformation */
1263 /****************************************************************************/
1265 #define TXFSDC_BLOCKR 0x00 // block device removable
1266 #define TXFSDC_GETBPB 0x00 // get device bpb info
1267 #define TXFSBPB_REMOVABLE 0x08 // BPB attribute for removable
1269 typedef struct drivecmd
1271 BYTE cmd; // 0=unlock 1=lock 2=eject
1272 BYTE drv; // 0=A, 1=B 2=C ...
1273 } DRIVECMD; // end of struct "drivecmd"
1275 #pragma pack(push, 1) // byte packing
1276 typedef struct txfs_ebpb // ext. boot parameter block
1277 { // at offset 0x0b in bootsector
1278 USHORT SectSize; // 0B bytes per sector
1279 BYTE ClustSize; // 0D sectors per cluster
1280 USHORT FatOffset; // 0E sectors to 1st FAT
1281 BYTE NrOfFats; // 10 nr of FATS (FAT only)
1282 USHORT RootEntries; // 11 Max entries \ (FAT only)
1283 USHORT Sectors; // 13 nr of sectors if < 64K
1284 BYTE MediaType; // 15 mediatype (F8 for HD)
1285 USHORT FatSectors; // 16 sectors/FAT (FAT only)
1286 USHORT LogGeoSect; // 18 sectors/Track
1287 USHORT LogGeoHead; // 1a nr of heads
1288 ULONG HiddenSectors; // 1c sector-offset from MBR/EBR
1289 ULONG BigSectors; // 20 nr of sectors if >= 64K
1290 } TXFS_EBPB; // last byte is at offset 0x23
1292 typedef struct drivebpb
1294 TXFS_EBPB ebpb; // extended BPB
1295 BYTE reserved[6];
1296 USHORT cyls;
1297 BYTE type;
1298 USHORT attributes; // device attributes
1299 BYTE fill[6]; // documented for IOCtl
1300 } DRIVEBPB; // end of struct "drivebpb"
1302 struct CDInfo {
1303 USHORT usCount;
1304 USHORT usFirst;
1307 #pragma pack(pop)
1309 /*****************************************************************************/
1310 // Get number of cdrom readers
1311 /*****************************************************************************/
1312 BOOL GetCDInfo( CDInfo * pCDInfo )
1314 HFILE hFileCD;
1315 ULONG ulAction;
1317 if( NO_ERROR == DosOpen( (PCSZ)"\\DEV\\CD-ROM2$",
1318 &hFileCD, &ulAction, 0, FILE_NORMAL,
1319 OPEN_ACTION_OPEN_IF_EXISTS,
1320 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL )) {
1321 ULONG ulDataSize = sizeof(CDInfo);
1322 APIRET rc = DosDevIOCtl( hFileCD, 0x82, 0x60, NULL, 0,
1323 NULL, (PVOID)pCDInfo, ulDataSize, &ulDataSize);
1324 DosClose( hFileCD);
1325 if(rc == NO_ERROR)
1326 return TRUE;
1328 // failed
1329 pCDInfo->usFirst = 0;
1330 pCDInfo->usCount = 0;
1331 return FALSE;
1334 /*****************************************************************************/
1335 // Determine if unit is a cdrom or not
1336 /*****************************************************************************/
1337 BOOL DriveIsCDROM(UINT uiDrive, CDInfo *pCDInfo)
1339 return (uiDrive >= pCDInfo->usFirst)
1340 && (uiDrive < (pCDInfo->usFirst + pCDInfo->usCount));
1343 /*****************************************************************************/
1344 // Determine attached fstype, e.g. HPFS for specified drive
1345 /*****************************************************************************/
1346 BOOL TxFsType // RET FS type resolved
1348 char *drive, // IN Drive specification
1349 char *fstype, // OUT Attached FS type
1350 char *details // OUT details (UNC) or NULL
1353 BOOL rc = FALSE;
1354 FSQBUFFER2 *fsinfo; // Attached FS info
1355 ULONG fsdlen = 2048; // Fs info data length
1357 strcpy(fstype, "none");
1358 if (details)
1360 strcpy(details, "");
1362 if ((fsinfo = (FSQBUFFER2*)calloc(1, fsdlen)) != NULL)
1364 if (DosQFSAttach((PCSZ)drive, 0, 1, fsinfo, &fsdlen) == NO_ERROR)
1366 strcpy(fstype, (char*) fsinfo->szName + fsinfo->cbName +1);
1367 if (details && (fsinfo->cbFSAData != 0))
1369 strcpy( details, (char*) fsinfo->szName + fsinfo->cbName +
1370 fsinfo->cbFSDName +2);
1372 rc = TRUE;
1374 free(fsinfo);
1376 return (rc);
1377 } // end 'TxFsType'
1378 /*---------------------------------------------------------------------------*/
1381 /*****************************************************************************/
1382 // Determine if a driveletter represents a removable medium/device
1383 /*****************************************************************************/
1384 BOOL TxFsIsRemovable // RET drive is removable
1386 char *drive // IN Driveletter to test
1389 BOOL rc = FALSE;
1390 DRIVECMD IOCtl;
1391 DRIVEBPB RemAt;
1392 ULONG DataLen;
1393 ULONG ParmLen;
1394 BYTE NoRem;
1396 DosError( FERR_DISABLEHARDERR); // avoid 'not ready' popups
1398 ParmLen = sizeof(IOCtl);
1399 IOCtl.cmd = TXFSDC_BLOCKR;
1400 IOCtl.drv = toupper(drive[0]) - 'A';
1401 DataLen = sizeof(NoRem);
1403 if (DosDevIOCtl((HFILE) -1, IOCTL_DISK,
1404 DSK_BLOCKREMOVABLE,
1405 &IOCtl, ParmLen, &ParmLen,
1406 &NoRem, DataLen, &DataLen) == NO_ERROR)
1408 if (NoRem) // non-removable sofar, check
1409 { // BPB as well (USB devices)
1410 ParmLen = sizeof(IOCtl);
1411 IOCtl.cmd = TXFSDC_GETBPB;
1412 IOCtl.drv = toupper(drive[0]) - 'A';
1413 DataLen = sizeof(RemAt);
1415 if (DosDevIOCtl((HFILE) -1, IOCTL_DISK,
1416 DSK_GETDEVICEPARAMS,
1417 &IOCtl, ParmLen, &ParmLen,
1418 &RemAt, DataLen, &DataLen) == NO_ERROR)
1421 if (RemAt.attributes & TXFSBPB_REMOVABLE)
1423 rc = TRUE; // removable, probably USB
1427 else
1429 rc = TRUE; // removable block device
1432 DosError( FERR_ENABLEHARDERR); // enable criterror handler
1433 return (rc);
1434 } // end 'TxFsIsRemovable'
1435 /*---------------------------------------------------------------------------*/
1437 static oslFileError get_drive_type(const char* path, oslVolumeInfo* pInfo)
1439 char Drive_Letter = toupper( *path);
1440 char fstype[ 64];
1442 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
1444 // check for floppy A/B
1445 BYTE nFloppies;
1446 APIRET rc;
1447 rc = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY );
1448 if ((Drive_Letter - 'A') < nFloppies) {
1449 pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
1450 pInfo->uAttributes |= osl_Volume_Attribute_FloppyDisk;
1451 return osl_File_E_None;
1454 // query system for CD drives
1455 CDInfo cdInfo;
1456 GetCDInfo(&cdInfo);
1458 // query if drive is a CDROM
1459 if (DriveIsCDROM( Drive_Letter - 'A', &cdInfo))
1460 pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
1462 if (TxFsIsRemovable( (char*)path))
1463 pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
1465 if (TxFsType( (char*)path, fstype, NULL) == FALSE) {
1466 // query failed, assume fixed disk
1467 pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
1468 return osl_File_E_None;
1471 //- Note, connected Win-NT drives use the REAL FS-name like NTFS!
1472 if ((strncasecmp( fstype, "LAN", 3) == 0) //- OS/2 LAN drives
1473 || (strncasecmp( fstype, "NDFS", 4) == 0) //- NetDrive
1474 || (strncasecmp( fstype, "REMOTE", 5) == 0) ) //- NT disconnected
1475 pInfo->uAttributes |= osl_Volume_Attribute_Remote;
1476 else if (strncasecmp( fstype, "RAMFS", 5) == 0)
1477 pInfo->uAttributes |= osl_Volume_Attribute_RAMDisk;
1478 else if ((strncasecmp( fstype, "CD", 2) == 0) // OS2:CDFS, DOS/WIN:CDROM
1479 || (strncasecmp( fstype, "UDF", 3) == 0) ) // OS2:UDF DVD's
1480 pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
1481 else
1482 pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
1484 return osl_File_E_None;
1487 //#############################################
1488 inline bool is_volume_space_info_request(sal_uInt32 field_mask)
1490 return (field_mask &
1491 (osl_VolumeInfo_Mask_TotalSpace |
1492 osl_VolumeInfo_Mask_UsedSpace |
1493 osl_VolumeInfo_Mask_FreeSpace));
1496 //#############################################
1497 static void get_volume_space_information(const char* path, oslVolumeInfo *pInfo)
1499 FSALLOCATE aFSInfoBuf;
1500 ULONG nDriveNumber = toupper( *path) - 'A' + 1;
1502 // disable error popups
1503 DosError(FERR_DISABLEHARDERR);
1504 APIRET rc = DosQueryFSInfo( nDriveNumber, FSIL_ALLOC,
1505 &aFSInfoBuf, sizeof(aFSInfoBuf) );
1506 // enable error popups
1507 DosError(FERR_ENABLEHARDERR);
1508 if (!rc)
1510 uint64_t aBytesPerCluster( uint64_t(aFSInfoBuf.cbSector) *
1511 uint64_t(aFSInfoBuf.cSectorUnit) );
1512 pInfo->uFreeSpace = aBytesPerCluster * uint64_t(aFSInfoBuf.cUnitAvail);
1513 pInfo->uTotalSpace = aBytesPerCluster * uint64_t(aFSInfoBuf.cUnit);
1514 pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
1515 pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace |
1516 osl_VolumeInfo_Mask_UsedSpace |
1517 osl_VolumeInfo_Mask_FreeSpace;
1521 //#############################################
1522 inline bool is_filesystem_attributes_request(sal_uInt32 field_mask)
1524 return (field_mask &
1525 (osl_VolumeInfo_Mask_MaxNameLength |
1526 osl_VolumeInfo_Mask_MaxPathLength |
1527 osl_VolumeInfo_Mask_FileSystemName |
1528 osl_VolumeInfo_Mask_FileSystemCaseHandling));
1531 //#############################################
1532 inline bool is_drivetype_request(sal_uInt32 field_mask)
1534 return (field_mask & osl_VolumeInfo_Mask_Attributes);
1537 typedef struct _FSQBUFFER_
1539 FSQBUFFER2 aBuf;
1540 UCHAR sBuf[64];
1541 } FSQBUFFER_;
1543 //#############################################
1544 static oslFileError get_filesystem_attributes(const char* path, sal_uInt32 field_mask, oslVolumeInfo* pInfo)
1546 pInfo->uAttributes = 0;
1548 oslFileError osl_error = osl_File_E_None;
1550 // osl_get_drive_type must be called first because
1551 // this function resets osl_VolumeInfo_Mask_Attributes
1552 // on failure
1553 if (is_drivetype_request(field_mask))
1554 osl_error = get_drive_type(path, pInfo);
1556 if ((osl_File_E_None == osl_error) && is_filesystem_attributes_request(field_mask))
1558 FSQBUFFER_ aBuf;
1559 ULONG nBufLen;
1560 APIRET nRet;
1562 nBufLen = sizeof( aBuf );
1563 // disable error popups
1564 DosError(FERR_DISABLEHARDERR);
1565 nRet = DosQueryFSAttach( (PCSZ)path, 0, FSAIL_QUERYNAME, (_FSQBUFFER2*) &aBuf, &nBufLen );
1566 if ( !nRet )
1568 char *pType = (char*)(aBuf.aBuf.szName + aBuf.aBuf.cbName + 1);
1569 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
1570 pInfo->uMaxNameLength = _MAX_FNAME;
1572 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
1573 pInfo->uMaxPathLength = _MAX_PATH;
1575 pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
1576 rtl_uString_newFromAscii(&pInfo->ustrFileSystemName, pType);
1578 // case is preserved always except for FAT
1579 if (strcmp( pType, "FAT" ))
1580 pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
1582 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
1584 // enable error popups
1585 DosError(FERR_ENABLEHARDERR);
1587 return osl_error;
1590 oslFileError SAL_CALL osl_getVolumeInformation( rtl_uString* ustrDirectoryURL, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask )
1592 char volume_root[PATH_MAX];
1593 oslFileError error;
1595 OSL_ASSERT( ustrDirectoryURL );
1596 OSL_ASSERT( pInfo );
1598 /* convert directory url to system path */
1599 error = FileURLToPath( volume_root, PATH_MAX, ustrDirectoryURL );
1600 if( error != osl_File_E_None )
1601 return error;
1603 if (!pInfo)
1604 return osl_File_E_INVAL;
1606 pInfo->uValidFields = 0;
1608 if ((error = get_filesystem_attributes(volume_root, uFieldMask, pInfo)) != osl_File_E_None)
1609 return error;
1611 if (is_volume_space_info_request(uFieldMask))
1612 get_volume_space_information(volume_root, pInfo);
1614 if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
1616 pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
1617 rtl_uString* uVolumeRoot;
1618 rtl_uString_newFromAscii( &uVolumeRoot, volume_root);
1619 osl_getFileURLFromSystemPath( uVolumeRoot, (rtl_uString**)&pInfo->pDeviceHandle);
1620 rtl_uString_release( uVolumeRoot);
1623 return osl_File_E_None;
1626 /****************************************************************************/
1627 /* osl_getFileStatus */
1628 /****************************************************************************/
1629 static oslFileError _osl_getDriveInfo(
1630 oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask)
1632 DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
1633 sal_Unicode cDrive[3];
1634 sal_Unicode cRoot[4];
1636 if ( !pItemImpl )
1637 return osl_File_E_INVAL;
1639 pStatus->uValidFields = 0;
1641 cDrive[0] = pItemImpl->ustrDrive->buffer[0];
1642 cDrive[1] = (sal_Unicode)':';
1643 cDrive[2] = 0;
1644 cRoot[0] = pItemImpl->ustrDrive->buffer[0];
1645 cRoot[1] = (sal_Unicode)':';
1646 cRoot[2] = 0;
1648 if ( uFieldMask & osl_FileStatus_Mask_FileName )
1650 if ( pItemImpl->ustrDrive->buffer[0] == '\\' &&
1651 pItemImpl->ustrDrive->buffer[1] == '\\' )
1653 LPCWSTR lpFirstBkSlash = wcschr( (const wchar_t*)&pItemImpl->ustrDrive->buffer[2], '\\' );
1655 if ( lpFirstBkSlash && lpFirstBkSlash[1] )
1657 LPCWSTR lpLastBkSlash = wcschr( (const wchar_t*)&lpFirstBkSlash[1], '\\' );
1659 if ( lpLastBkSlash )
1660 rtl_uString_newFromStr_WithLength( &pStatus->ustrFileName, (sal_Unicode*)&lpFirstBkSlash[1], lpLastBkSlash - lpFirstBkSlash - 1 );
1661 else
1662 rtl_uString_newFromStr( &pStatus->ustrFileName, (sal_Unicode*)&lpFirstBkSlash[1] );
1663 pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1666 else
1668 FSINFO aFSInfoBuf;
1669 ULONG ulFSInfoLevel = FSIL_VOLSER;
1670 ULONG nDriveNumber;
1671 char szFileName[ _MAX_PATH];
1673 nDriveNumber = toupper(*cDrive) - 'A' + 1;
1674 memset( &aFSInfoBuf, 0, sizeof(FSINFO) );
1675 // disable error popups
1676 DosError(FERR_DISABLEHARDERR);
1677 APIRET rc = DosQueryFSInfo( nDriveNumber, ulFSInfoLevel, &aFSInfoBuf, sizeof(FSINFO) );
1678 // enable error popups
1679 DosError(FERR_ENABLEHARDERR);
1680 memset( szFileName, 0, sizeof( szFileName));
1681 *szFileName = toupper(*cDrive);
1682 strcat( szFileName, ": [");
1683 if ( !rc || aFSInfoBuf.vol.cch)
1684 strncat( szFileName, aFSInfoBuf.vol.szVolLabel, aFSInfoBuf.vol.cch);
1685 strcat( szFileName, "]");
1686 rtl_uString_newFromAscii( &pStatus->ustrFileName, szFileName );
1688 pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1692 pStatus->eType = osl_File_Type_Volume;
1693 pStatus->uValidFields |= osl_FileStatus_Mask_Type;
1695 if ( uFieldMask & osl_FileStatus_Mask_FileURL )
1697 rtl_uString *ustrSystemPath = NULL;
1699 rtl_uString_newFromStr( &ustrSystemPath, pItemImpl->ustrDrive->buffer );
1700 osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL );
1701 rtl_uString_release( ustrSystemPath );
1702 pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
1705 return osl_File_E_None;
1708 oslFileError SAL_CALL osl_getFileStatus(
1709 oslDirectoryItem Item,
1710 oslFileStatus *pStatus,
1711 sal_uInt32 uFieldMask )
1713 DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
1714 struct stat file_stat;
1716 if ( !pItemImpl )
1717 return osl_File_E_INVAL;
1719 if ( pItemImpl->uType == DIRECTORYITEM_DRIVE)
1720 return _osl_getDriveInfo( Item, pStatus, uFieldMask );
1722 osl::lstat(pItemImpl->ustrFilePath, file_stat);
1723 if ( uFieldMask & osl_FileStatus_Mask_Validate )
1725 uFieldMask &= ~ osl_FileStatus_Mask_Validate;
1728 /* If no fields to retrieve left ignore pStatus */
1729 if ( !uFieldMask )
1730 return osl_File_E_None;
1732 /* Otherwise, this must be a valid pointer */
1733 if ( !pStatus )
1734 return osl_File_E_INVAL;
1736 if ( pStatus->uStructSize != sizeof(oslFileStatus) )
1737 return osl_File_E_INVAL;
1739 pStatus->uValidFields = 0;
1741 /* File time stamps */
1743 if ( (uFieldMask & osl_FileStatus_Mask_ModifyTime))
1745 pStatus->aModifyTime.Seconds = file_stat.st_mtime;
1746 pStatus->aModifyTime.Nanosec = 0;
1747 pStatus->uValidFields |= osl_FileStatus_Mask_ModifyTime;
1750 if ( (uFieldMask & osl_FileStatus_Mask_AccessTime))
1752 pStatus->aAccessTime.Seconds = file_stat.st_atime;
1753 pStatus->aAccessTime.Nanosec = 0;
1754 pStatus->uValidFields |= osl_FileStatus_Mask_AccessTime;
1757 if ( (uFieldMask & osl_FileStatus_Mask_CreationTime))
1759 pStatus->aAccessTime.Seconds = file_stat.st_birthtime;
1760 pStatus->aAccessTime.Nanosec = 0;
1761 pStatus->uValidFields |= osl_FileStatus_Mask_CreationTime;
1764 /* Most of the fields are already set, regardless of requiered fields */
1766 osl_systemPathGetFileNameOrLastDirectoryPart(pItemImpl->ustrFilePath, &pStatus->ustrFileName);
1767 pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1769 if (S_ISLNK(file_stat.st_mode))
1770 pStatus->eType = osl_File_Type_Link;
1771 else if (S_ISDIR(file_stat.st_mode))
1772 pStatus->eType = osl_File_Type_Directory;
1773 else if (S_ISREG(file_stat.st_mode))
1774 pStatus->eType = osl_File_Type_Regular;
1775 else if (S_ISFIFO(file_stat.st_mode))
1776 pStatus->eType = osl_File_Type_Fifo;
1777 else if (S_ISSOCK(file_stat.st_mode))
1778 pStatus->eType = osl_File_Type_Socket;
1779 else if (S_ISCHR(file_stat.st_mode) || S_ISBLK(file_stat.st_mode))
1780 pStatus->eType = osl_File_Type_Special;
1781 else
1782 pStatus->eType = osl_File_Type_Unknown;
1784 pStatus->uValidFields |= osl_FileStatus_Mask_Type;
1786 pStatus->uAttributes = pItemImpl->d_attr;
1787 pStatus->uValidFields |= osl_FileStatus_Mask_Attributes;
1789 pStatus->uFileSize = file_stat.st_size;
1790 pStatus->uValidFields |= osl_FileStatus_Mask_FileSize;
1792 if ( uFieldMask & osl_FileStatus_Mask_LinkTargetURL )
1794 rtl_uString *ustrFullPath = NULL;
1796 rtl_uString_newFromStr( &ustrFullPath, rtl_uString_getStr(pItemImpl->ustrFilePath) );
1797 osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrLinkTargetURL );
1798 rtl_uString_release( ustrFullPath );
1800 pStatus->uValidFields |= osl_FileStatus_Mask_LinkTargetURL;
1803 if ( uFieldMask & osl_FileStatus_Mask_FileURL )
1805 rtl_uString *ustrFullPath = NULL;
1807 rtl_uString_newFromStr( &ustrFullPath, rtl_uString_getStr(pItemImpl->ustrFilePath) );
1808 osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrFileURL );
1809 rtl_uString_release( ustrFullPath );
1810 pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
1813 return osl_File_E_None;
1816 /****************************************************************************/
1817 /* osl_createDirectory */
1818 /****************************************************************************/
1820 oslFileError osl_createDirectory( rtl_uString* ustrDirectoryURL )
1822 char path[PATH_MAX];
1823 oslFileError eRet;
1824 APIRET rc;
1826 OSL_ASSERT( ustrDirectoryURL );
1828 /* convert directory url to system path */
1829 eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
1830 if( eRet != osl_File_E_None )
1831 return eRet;
1833 rc = DosCreateDir( (PCSZ)path, NULL);
1834 if (rc == ERROR_ACCESS_DENIED)
1835 rc=ERROR_FILE_EXISTS;
1837 if (!rc)
1838 eRet = osl_File_E_None;
1839 else
1840 eRet = MapError( rc);
1842 return eRet;
1845 /****************************************************************************/
1846 /* osl_removeDirectory */
1847 /****************************************************************************/
1849 oslFileError osl_removeDirectory( rtl_uString* ustrDirectoryURL )
1851 char path[PATH_MAX];
1852 oslFileError eRet;
1853 APIRET rc;
1855 OSL_ASSERT( ustrDirectoryURL );
1857 /* convert directory url to system path */
1858 eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
1859 if( eRet != osl_File_E_None )
1860 return eRet;
1862 rc = DosDeleteDir( (PCSZ)path);
1863 if (!rc)
1864 eRet = osl_File_E_None;
1865 else
1866 eRet = MapError( rc);
1868 return eRet;
1871 //#############################################
1872 int path_make_parent(sal_Unicode* path)
1874 int i = rtl_ustr_lastIndexOfChar(path, '/');
1876 if (i > 0)
1878 *(path + i) = 0;
1879 return i;
1881 else
1882 return 0;
1885 //#############################################
1886 int create_dir_with_callback(
1887 sal_Unicode* directory_path,
1888 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
1889 void* pData)
1891 int mode = S_IRWXU | S_IRWXG | S_IRWXO;
1893 if (osl::mkdir(directory_path, mode) == 0)
1895 if (aDirectoryCreationCallbackFunc)
1897 rtl::OUString url;
1898 osl::FileBase::getFileURLFromSystemPath(directory_path, url);
1899 aDirectoryCreationCallbackFunc(pData, url.pData);
1901 return 0;
1903 return errno;
1906 //#############################################
1907 oslFileError create_dir_recursively_(
1908 sal_Unicode* dir_path,
1909 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
1910 void* pData)
1912 OSL_PRECOND((rtl_ustr_getLength(dir_path) > 0) && ((dir_path + (rtl_ustr_getLength(dir_path) - 1)) != (dir_path + rtl_ustr_lastIndexOfChar(dir_path, '/'))), \
1913 "Path must not end with a slash");
1915 int native_err = create_dir_with_callback(
1916 dir_path, aDirectoryCreationCallbackFunc, pData);
1918 if (native_err == 0)
1919 return osl_File_E_None;
1921 if (native_err != ENOENT)
1922 return oslTranslateFileError(OSL_FET_ERROR, native_err);
1924 // we step back until '/a_dir' at maximum because
1925 // we should get an error unequal ENOENT when
1926 // we try to create 'a_dir' at '/' and would so
1927 // return before
1928 int pos = path_make_parent(dir_path);
1930 oslFileError osl_error = create_dir_recursively_(
1931 dir_path, aDirectoryCreationCallbackFunc, pData);
1933 if (osl_File_E_None != osl_error)
1934 return osl_error;
1936 dir_path[pos] = '/';
1938 return create_dir_recursively_(dir_path, aDirectoryCreationCallbackFunc, pData);
1941 //#######################################
1942 oslFileError SAL_CALL osl_createDirectoryPath(
1943 rtl_uString* aDirectoryUrl,
1944 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
1945 void* pData)
1947 if (aDirectoryUrl == NULL)
1948 return osl_File_E_INVAL;
1950 rtl::OUString sys_path;
1951 oslFileError osl_error = osl_getSystemPathFromFileURL_Ex(
1952 aDirectoryUrl, &sys_path.pData, sal_False);
1954 if (osl_error != osl_File_E_None)
1955 return osl_error;
1957 osl::systemPathRemoveSeparator(sys_path);
1959 // const_cast because sys_path is a local copy which we want to modify inplace instead of
1960 // coyp it into another buffer on the heap again
1961 return create_dir_recursively_(sys_path.pData->buffer, aDirectoryCreationCallbackFunc, pData);
1964 /****************************************************************************/
1965 /* osl_getCanonicalName */
1966 /****************************************************************************/
1968 oslFileError osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uString** pustrValidURL )
1970 OSL_ENSURE(sal_False, "osl_getCanonicalName not implemented");
1972 rtl_uString_newFromString(pustrValidURL, ustrFileURL);
1973 return osl_File_E_None;
1977 /****************************************************************************/
1978 /* osl_setFileAttributes */
1979 /****************************************************************************/
1981 oslFileError osl_setFileAttributes( rtl_uString* ustrFileURL, sal_uInt64 uAttributes )
1983 char path[PATH_MAX];
1984 oslFileError eRet;
1985 FILESTATUS3 fsts3ConfigInfo;
1986 ULONG ulBufSize = sizeof(FILESTATUS3);
1987 APIRET rc = NO_ERROR;
1989 OSL_ASSERT( ustrFileURL );
1991 /* convert file url to system path */
1992 eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
1993 if( eRet != osl_File_E_None )
1994 return eRet;
1996 /* query current attributes */
1997 rc = DosQueryPathInfo( (PCSZ)path, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize);
1998 if (rc != NO_ERROR)
1999 return MapError( rc);
2001 /* set/reset readonly/hidden (see w32\file.cxx) */
2002 fsts3ConfigInfo.attrFile &= ~(FILE_READONLY | FILE_HIDDEN);
2003 if ( uAttributes & osl_File_Attribute_ReadOnly )
2004 fsts3ConfigInfo.attrFile |= FILE_READONLY;
2005 if ( uAttributes & osl_File_Attribute_Hidden )
2006 fsts3ConfigInfo.attrFile |= FILE_HIDDEN;
2008 /* write new attributes */
2009 rc = DosSetPathInfo( (PCSZ)path, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize, 0);
2010 if (rc != NO_ERROR)
2011 return MapError( rc);
2013 /* everything ok */
2014 return osl_File_E_None;
2017 /****************************************************************************/
2018 /* osl_setFileTime */
2019 /****************************************************************************/
2021 oslFileError osl_setFileTime( rtl_uString* ustrFileURL, const TimeValue* pCreationTime,
2022 const TimeValue* pLastAccessTime, const TimeValue* pLastWriteTime )
2024 char path[PATH_MAX];
2025 oslFileError eRet;
2027 OSL_ASSERT( ustrFileURL );
2029 /* convert file url to system path */
2030 eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
2031 if( eRet != osl_File_E_None )
2032 return eRet;
2034 return osl_psz_setFileTime( path, pCreationTime, pLastAccessTime, pLastWriteTime );
2037 /******************************************************************************
2039 * Exported Module Functions
2040 * (independent of C or Unicode Strings)
2042 *****************************************************************************/
2045 /*******************************************
2046 osl_readFile
2047 ********************************************/
2049 oslFileError osl_readFile(oslFileHandle Handle, void* pBuffer, sal_uInt64 uBytesRequested, sal_uInt64* pBytesRead)
2051 ssize_t nBytes = 0;
2052 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
2054 if ((0 == pHandleImpl) || (pHandleImpl->fd < 0) || (0 == pBuffer) || (0 == pBytesRead))
2055 return osl_File_E_INVAL;
2057 nBytes = read(pHandleImpl->fd, pBuffer, uBytesRequested);
2059 if (-1 == nBytes)
2060 return oslTranslateFileError(OSL_FET_ERROR, errno);
2062 *pBytesRead = nBytes;
2063 return osl_File_E_None;
2066 /*******************************************
2067 osl_writeFile
2068 ********************************************/
2070 oslFileError osl_writeFile(oslFileHandle Handle, const void* pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64* pBytesWritten)
2072 ssize_t nBytes = 0;
2073 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
2075 OSL_ASSERT(pHandleImpl);
2076 OSL_ASSERT(pBuffer);
2077 OSL_ASSERT(pBytesWritten);
2079 if ((0 == pHandleImpl) || (0 == pBuffer) || (0 == pBytesWritten))
2080 return osl_File_E_INVAL;
2082 OSL_ASSERT(pHandleImpl->fd >= 0);
2084 if (pHandleImpl->fd < 0)
2085 return osl_File_E_INVAL;
2087 nBytes = write(pHandleImpl->fd, pBuffer, uBytesToWrite);
2089 if (-1 == nBytes)
2090 return oslTranslateFileError(OSL_FET_ERROR, errno);
2092 *pBytesWritten = nBytes;
2093 return osl_File_E_None;
2096 /*******************************************
2097 osl_writeFile
2098 ********************************************/
2100 oslFileError osl_setFilePos( oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uPos )
2102 oslFileHandleImpl* pHandleImpl=0;
2103 int nRet=0;
2104 off_t nOffset=0;
2106 pHandleImpl = (oslFileHandleImpl*) Handle;
2107 if ( pHandleImpl == 0 )
2109 return osl_File_E_INVAL;
2112 if ( pHandleImpl->fd < 0 )
2114 return osl_File_E_INVAL;
2117 /* FIXME mfe: setFilePos: Do we have any runtime function to determine LONG_MAX? */
2118 if ( uPos > LONG_MAX )
2120 return osl_File_E_OVERFLOW;
2123 nOffset=(off_t)uPos;
2125 switch(uHow)
2127 case osl_Pos_Absolut:
2128 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_SET);
2129 break;
2131 case osl_Pos_Current:
2132 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_CUR);
2133 break;
2135 case osl_Pos_End:
2136 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_END);
2137 break;
2139 default:
2140 return osl_File_E_INVAL;
2143 if ( nOffset < 0 )
2145 nRet=errno;
2146 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2149 return osl_File_E_None;
2152 /************************************************
2153 * osl_getFilePos
2154 ***********************************************/
2156 oslFileError osl_getFilePos( oslFileHandle Handle, sal_uInt64* pPos )
2158 oslFileHandleImpl* pHandleImpl=0;
2159 off_t nOffset=0;
2160 int nRet=0;
2162 pHandleImpl = (oslFileHandleImpl*) Handle;
2163 if ( pHandleImpl == 0 || pPos == 0)
2165 return osl_File_E_INVAL;
2168 if ( pHandleImpl->fd < 0 )
2170 return osl_File_E_INVAL;
2173 nOffset = lseek(pHandleImpl->fd,0,SEEK_CUR);
2175 if (nOffset < 0)
2177 nRet =errno;
2179 /* *pPos =0; */
2181 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2184 *pPos=nOffset;
2186 return osl_File_E_None;
2189 /****************************************************************************
2190 * osl_getFileSize
2191 ****************************************************************************/
2193 oslFileError osl_getFileSize( oslFileHandle Handle, sal_uInt64* pSize )
2195 oslFileHandleImpl* pHandleImpl=(oslFileHandleImpl*) Handle;
2196 if (pHandleImpl == 0)
2197 return osl_File_E_INVAL;
2199 struct stat file_stat;
2200 if (fstat(pHandleImpl->fd, &file_stat) == -1)
2201 return oslTranslateFileError(OSL_FET_ERROR, errno);
2203 *pSize = file_stat.st_size;
2204 return osl_File_E_None;
2207 /************************************************
2208 * osl_setFileSize
2209 ***********************************************/
2211 oslFileError osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize )
2213 oslFileHandleImpl* pHandleImpl=0;
2214 off_t nOffset=0;
2216 pHandleImpl = (oslFileHandleImpl*) Handle;
2217 if ( pHandleImpl == 0 )
2219 return osl_File_E_INVAL;
2222 if ( pHandleImpl->fd < 0 )
2224 return osl_File_E_INVAL;
2227 /* FIXME: mfe: setFileSize: Do we have any runtime function to determine LONG_MAX? */
2228 if ( uSize > LONG_MAX )
2230 return osl_File_E_OVERFLOW;
2233 nOffset = (off_t)uSize;
2234 if (ftruncate (pHandleImpl->fd, nOffset) < 0)
2236 /* Failure. Try fallback algorithm */
2237 oslFileError result;
2238 struct stat aStat;
2239 off_t nCurPos;
2241 /* Save original result */
2242 result = oslTranslateFileError (OSL_FET_ERROR, errno);
2243 PERROR("ftruncate", "Try osl_setFileSize [fallback]\n");
2245 /* Check against current size. Fail upon 'shrink' */
2246 if (fstat (pHandleImpl->fd, &aStat) < 0)
2248 PERROR("ftruncate: fstat", "Out osl_setFileSize [error]\n");
2249 return (result);
2251 if ((0 <= nOffset) && (nOffset <= aStat.st_size))
2253 /* Failure upon 'shrink'. Return original result */
2254 return (result);
2257 /* Save current position */
2258 nCurPos = (off_t)lseek (pHandleImpl->fd, (off_t)0, SEEK_CUR);
2259 if (nCurPos == (off_t)(-1))
2261 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
2262 return (result);
2265 /* Try 'expand' via 'lseek()' and 'write()' */
2266 if (lseek (pHandleImpl->fd, (off_t)(nOffset - 1), SEEK_SET) < 0)
2268 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
2269 return (result);
2271 if (write (pHandleImpl->fd, (char*)"", (size_t)1) < 0)
2273 /* Failure. Restore saved position */
2274 PERROR("ftruncate: write", "Out osl_setFileSize [error]\n");
2275 if (lseek (pHandleImpl->fd, (off_t)nCurPos, SEEK_SET) < 0)
2277 #ifdef DEBUG_OSL_FILE
2278 perror("ftruncate: lseek");
2279 #endif /* DEBUG_OSL_FILE */
2281 return (result);
2284 /* Success. Restore saved position */
2285 if (lseek (pHandleImpl->fd, (off_t)nCurPos, SEEK_SET) < 0)
2287 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]");
2288 return (result);
2292 return (osl_File_E_None);
2295 /*###############################################*/
2296 oslFileError SAL_CALL osl_syncFile(oslFileHandle Handle)
2298 oslFileHandleImpl* handle_impl = (oslFileHandleImpl*)Handle;
2300 if (handle_impl == 0)
2301 return osl_File_E_INVAL;
2303 if (fsync(handle_impl->fd) == -1)
2304 return oslTranslateFileError(OSL_FET_ERROR, errno);
2306 return osl_File_E_None;
2309 /******************************************************************************
2311 * C-String Versions of Exported Module Functions
2313 *****************************************************************************/
2315 #ifdef HAVE_STATFS_H
2317 #if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
2318 # define __OSL_STATFS_STRUCT struct statfs
2319 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
2320 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
2321 # define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
2322 # define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
2324 /* always return true if queried for the properties of
2325 the file system. If you think this is wrong under any
2326 of the target platforms fix it!!!! */
2327 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2328 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2329 #endif /* FREEBSD || NETBSD */
2331 #if defined(LINUX)
2332 # define __OSL_NFS_SUPER_MAGIC 0x6969
2333 # define __OSL_SMB_SUPER_MAGIC 0x517B
2334 # define __OSL_MSDOS_SUPER_MAGIC 0x4d44
2335 # define __OSL_NTFS_SUPER_MAGIC 0x5346544e
2336 # define __OSL_STATFS_STRUCT struct statfs
2337 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
2338 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
2339 # define __OSL_STATFS_IS_NFS(a) (__OSL_NFS_SUPER_MAGIC == (a).f_type)
2340 # define __OSL_STATFS_IS_SMB(a) (__OSL_SMB_SUPER_MAGIC == (a).f_type)
2341 # define __OSL_STATFS_ISREMOTE(a) (__OSL_STATFS_IS_NFS((a)) || __OSL_STATFS_IS_SMB((a)))
2342 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type) && (__OSL_NTFS_SUPER_MAGIC != (a).f_type))
2343 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type))
2344 #endif /* LINUX */
2346 #if defined(SOLARIS) || defined(IRIX)
2347 # define __OSL_STATFS_STRUCT struct statvfs
2348 # define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
2349 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
2350 # define __OSL_STATFS_TYPENAME(a) ((a).f_basetype)
2351 # define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
2353 /* always return true if queried for the properties of
2354 the file system. If you think this is wrong under any
2355 of the target platforms fix it!!!! */
2356 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2357 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2358 #endif /* SOLARIS || IRIX*/
2360 # define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
2362 #else /* no statfs available */
2364 # define __OSL_STATFS_STRUCT struct dummy {int i;}
2365 # define __OSL_STATFS_INIT(a) ((void)0)
2366 # define __OSL_STATFS(dir, sfs) (1)
2367 # define __OSL_STATFS_ISREMOTE(sfs) (0)
2368 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2369 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2370 #endif /* HAVE_STATFS_H */
2373 static oslFileError osl_psz_getVolumeInformation (
2374 const sal_Char* pszDirectory, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask)
2376 __OSL_STATFS_STRUCT sfs;
2378 if (!pInfo)
2379 return osl_File_E_INVAL;
2381 __OSL_STATFS_INIT(sfs);
2383 pInfo->uValidFields = 0;
2384 pInfo->uAttributes = 0;
2386 if ((__OSL_STATFS(pszDirectory, &sfs)) < 0)
2388 oslFileError result = oslTranslateFileError(OSL_FET_ERROR, errno);
2389 return (result);
2392 /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
2393 if (uFieldMask & osl_VolumeInfo_Mask_Attributes)
2395 if (__OSL_STATFS_ISREMOTE(sfs))
2396 pInfo->uAttributes |= osl_Volume_Attribute_Remote;
2398 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
2401 if (uFieldMask & osl_VolumeInfo_Mask_FileSystemCaseHandling)
2403 if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs))
2404 pInfo->uAttributes |= osl_Volume_Attribute_Case_Sensitive;
2406 if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs))
2407 pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
2409 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
2412 pInfo->uTotalSpace = 0;
2413 pInfo->uFreeSpace = 0;
2414 pInfo->uUsedSpace = 0;
2416 #if defined(__OSL_STATFS_BLKSIZ)
2418 if ((uFieldMask & osl_VolumeInfo_Mask_TotalSpace) ||
2419 (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
2421 pInfo->uTotalSpace = __OSL_STATFS_BLKSIZ(sfs);
2422 pInfo->uTotalSpace *= (sal_uInt64)(sfs.f_blocks);
2423 pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace;
2426 if ((uFieldMask & osl_VolumeInfo_Mask_FreeSpace) ||
2427 (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
2429 pInfo->uFreeSpace = __OSL_STATFS_BLKSIZ(sfs);
2431 if (getuid() == 0)
2432 pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bfree);
2433 else
2434 pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bavail);
2436 pInfo->uValidFields |= osl_VolumeInfo_Mask_FreeSpace;
2439 #endif /* __OSL_STATFS_BLKSIZ */
2441 if ((pInfo->uValidFields & osl_VolumeInfo_Mask_TotalSpace) &&
2442 (pInfo->uValidFields & osl_VolumeInfo_Mask_FreeSpace ))
2444 pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
2445 pInfo->uValidFields |= osl_VolumeInfo_Mask_UsedSpace;
2448 pInfo->uMaxNameLength = 0;
2449 if (uFieldMask & osl_VolumeInfo_Mask_MaxNameLength)
2451 long nLen = pathconf(pszDirectory, _PC_NAME_MAX);
2452 if (nLen > 0)
2454 pInfo->uMaxNameLength = (sal_uInt32)nLen;
2455 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
2459 pInfo->uMaxPathLength = 0;
2460 if (uFieldMask & osl_VolumeInfo_Mask_MaxPathLength)
2462 long nLen = pathconf (pszDirectory, _PC_PATH_MAX);
2463 if (nLen > 0)
2465 pInfo->uMaxPathLength = (sal_uInt32)nLen;
2466 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
2470 #if defined(__OSL_STATFS_TYPENAME)
2472 if (uFieldMask & osl_VolumeInfo_Mask_FileSystemName)
2474 rtl_string2UString(
2475 &(pInfo->ustrFileSystemName),
2476 __OSL_STATFS_TYPENAME(sfs),
2477 rtl_str_getLength(__OSL_STATFS_TYPENAME(sfs)),
2478 osl_getThreadTextEncoding(),
2479 OUSTRING_TO_OSTRING_CVTFLAGS);
2480 OSL_ASSERT(pInfo->ustrFileSystemName != 0);
2482 pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
2485 #endif /* __OSL_STATFS_TYPENAME */
2487 if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
2489 /* FIXME: check also entries in mntent for the device
2490 and fill it with correct values */
2492 *pInfo->pDeviceHandle = osl_isFloppyDrive(pszDirectory);
2494 if (*pInfo->pDeviceHandle)
2496 pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
2497 pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
2498 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
2501 return osl_File_E_None;
2504 /******************************************
2505 * osl_psz_setFileTime
2506 *****************************************/
2508 static oslFileError osl_psz_setFileTime( const sal_Char* pszFilePath,
2509 const TimeValue* /*pCreationTime*/,
2510 const TimeValue* pLastAccessTime,
2511 const TimeValue* pLastWriteTime )
2513 int nRet=0;
2514 struct utimbuf aTimeBuffer;
2515 struct stat aFileStat;
2516 #ifdef DEBUG_OSL_FILE
2517 struct tm* pTM=0;
2518 #endif
2520 nRet = lstat(pszFilePath,&aFileStat);
2522 if ( nRet < 0 )
2524 nRet=errno;
2525 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2528 #ifdef DEBUG_OSL_FILE
2529 fprintf(stderr,"File Times are (in localtime):\n");
2530 pTM=localtime(&aFileStat.st_ctime);
2531 fprintf(stderr,"CreationTime is '%s'\n",asctime(pTM));
2532 pTM=localtime(&aFileStat.st_atime);
2533 fprintf(stderr,"AccessTime is '%s'\n",asctime(pTM));
2534 pTM=localtime(&aFileStat.st_mtime);
2535 fprintf(stderr,"Modification is '%s'\n",asctime(pTM));
2537 fprintf(stderr,"File Times are (in UTC):\n");
2538 fprintf(stderr,"CreationTime is '%s'\n",ctime(&aFileStat.st_ctime));
2539 fprintf(stderr,"AccessTime is '%s'\n",ctime(&aTimeBuffer.actime));
2540 fprintf(stderr,"Modification is '%s'\n",ctime(&aTimeBuffer.modtime));
2541 #endif
2543 if ( pLastAccessTime != 0 )
2545 aTimeBuffer.actime=pLastAccessTime->Seconds;
2547 else
2549 aTimeBuffer.actime=aFileStat.st_atime;
2552 if ( pLastWriteTime != 0 )
2554 aTimeBuffer.modtime=pLastWriteTime->Seconds;
2556 else
2558 aTimeBuffer.modtime=aFileStat.st_mtime;
2561 /* mfe: Creation time not used here! */
2563 #ifdef DEBUG_OSL_FILE
2564 fprintf(stderr,"File Times are (in localtime):\n");
2565 pTM=localtime(&aFileStat.st_ctime);
2566 fprintf(stderr,"CreationTime now '%s'\n",asctime(pTM));
2567 pTM=localtime(&aTimeBuffer.actime);
2568 fprintf(stderr,"AccessTime now '%s'\n",asctime(pTM));
2569 pTM=localtime(&aTimeBuffer.modtime);
2570 fprintf(stderr,"Modification now '%s'\n",asctime(pTM));
2572 fprintf(stderr,"File Times are (in UTC):\n");
2573 fprintf(stderr,"CreationTime now '%s'\n",ctime(&aFileStat.st_ctime));
2574 fprintf(stderr,"AccessTime now '%s'\n",ctime(&aTimeBuffer.actime));
2575 fprintf(stderr,"Modification now '%s'\n",ctime(&aTimeBuffer.modtime));
2576 #endif
2578 nRet=utime(pszFilePath,&aTimeBuffer);
2579 if ( nRet < 0 )
2581 nRet=errno;
2582 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2585 return osl_File_E_None;
2589 /*****************************************
2590 * osl_psz_removeFile
2591 ****************************************/
2592 #if 0
2593 static oslFileError osl_psz_removeFile( const sal_Char* pszPath )
2595 int nRet=0;
2596 struct stat aStat;
2598 nRet = stat(pszPath,&aStat);
2599 if ( nRet < 0 )
2601 nRet=errno;
2602 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2605 if ( S_ISDIR(aStat.st_mode) )
2607 return osl_File_E_ISDIR;
2610 nRet = unlink(pszPath);
2611 if ( nRet < 0 )
2613 nRet=errno;
2614 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2617 return osl_File_E_None;
2619 #endif
2621 /*****************************************
2622 * osl_psz_createDirectory
2623 ****************************************/
2624 #if 0
2625 static oslFileError osl_psz_createDirectory( const sal_Char* pszPath )
2627 int nRet=0;
2628 int mode = S_IRWXU | S_IRWXG | S_IRWXO;
2630 nRet = mkdir(pszPath,mode);
2632 if ( nRet < 0 )
2634 nRet=errno;
2635 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2638 return osl_File_E_None;
2640 #endif
2641 /*****************************************
2642 * osl_psz_removeDirectory
2643 ****************************************/
2644 #if 0
2645 static oslFileError osl_psz_removeDirectory( const sal_Char* pszPath )
2647 int nRet=0;
2649 nRet = rmdir(pszPath);
2651 if ( nRet < 0 )
2653 nRet=errno;
2654 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2657 return osl_File_E_None;
2659 #endif
2660 /*****************************************
2661 * oslDoMoveFile
2662 ****************************************/
2663 #if 0
2664 static oslFileError oslDoMoveFile( const sal_Char* pszPath, const sal_Char* pszDestPath)
2666 oslFileError tErr=osl_File_E_invalidError;
2668 tErr = osl_psz_moveFile(pszPath,pszDestPath);
2669 if ( tErr == osl_File_E_None )
2671 return tErr;
2674 if ( tErr != osl_File_E_XDEV )
2676 return tErr;
2679 tErr=osl_psz_copyFile(pszPath,pszDestPath);
2681 if ( tErr != osl_File_E_None )
2683 oslFileError tErrRemove;
2684 tErrRemove=osl_psz_removeFile(pszDestPath);
2685 return tErr;
2688 tErr=osl_psz_removeFile(pszPath);
2690 return tErr;
2692 #endif
2693 /*****************************************
2694 * osl_psz_moveFile
2695 ****************************************/
2696 #if 0
2697 static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath)
2700 int nRet = 0;
2702 nRet = rename(pszPath,pszDestPath);
2704 if ( nRet < 0 )
2706 nRet=errno;
2707 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2710 return osl_File_E_None;
2712 #endif
2713 /*****************************************
2714 * osl_psz_copyFile
2715 ****************************************/
2716 #if 0
2717 static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
2719 time_t nAcTime=0;
2720 time_t nModTime=0;
2721 uid_t nUID=0;
2722 gid_t nGID=0;
2723 int nRet=0;
2724 mode_t nMode=0;
2725 struct stat aFileStat;
2726 oslFileError tErr=osl_File_E_invalidError;
2727 size_t nSourceSize=0;
2728 int DestFileExists=1;
2730 /* mfe: does the source file really exists? */
2731 nRet = lstat(pszPath,&aFileStat);
2733 if ( nRet < 0 )
2735 nRet=errno;
2736 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2739 /* mfe: we do only copy files here! */
2740 if ( S_ISDIR(aFileStat.st_mode) )
2742 return osl_File_E_ISDIR;
2745 nSourceSize=(size_t)aFileStat.st_size;
2746 nMode=aFileStat.st_mode;
2747 nAcTime=aFileStat.st_atime;
2748 nModTime=aFileStat.st_mtime;
2749 nUID=aFileStat.st_uid;
2750 nGID=aFileStat.st_gid;
2752 nRet = stat(pszDestPath,&aFileStat);
2753 if ( nRet < 0 )
2755 nRet=errno;
2757 if ( nRet == ENOENT )
2759 DestFileExists=0;
2761 /* return oslTranslateFileError(nRet);*/
2764 /* mfe: the destination file must not be a directory! */
2765 if ( nRet == 0 && S_ISDIR(aFileStat.st_mode) )
2767 return osl_File_E_ISDIR;
2769 else
2771 /* mfe: file does not exists or is no dir */
2774 tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
2776 if ( tErr != osl_File_E_None )
2778 return tErr;
2782 * mfe: ignore return code
2783 * since only the success of the copy is
2784 * important
2786 oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
2788 return tErr;
2790 #endif
2792 /******************************************************************************
2794 * Utility Functions
2796 *****************************************************************************/
2799 /*****************************************
2800 * oslMakeUStrFromPsz
2801 ****************************************/
2803 rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr, rtl_uString** ustrValid)
2805 rtl_string2UString(
2806 ustrValid,
2807 pszStr,
2808 rtl_str_getLength( pszStr ),
2809 osl_getThreadTextEncoding(),
2810 OUSTRING_TO_OSTRING_CVTFLAGS );
2811 OSL_ASSERT(*ustrValid != 0);
2813 return *ustrValid;
2816 /*****************************************************************************
2817 * UnicodeToText
2818 * converting unicode to text manually saves us the penalty of a temporary
2819 * rtl_String object.
2820 ****************************************************************************/
2822 int UnicodeToText( char * buffer, size_t bufLen, const sal_Unicode * uniText, sal_Int32 uniTextLen )
2824 rtl_UnicodeToTextConverter hConverter;
2825 sal_uInt32 nInfo;
2826 sal_Size nSrcChars, nDestBytes;
2828 /* stolen from rtl/string.c */
2829 hConverter = rtl_createUnicodeToTextConverter( osl_getThreadTextEncoding() );
2831 nDestBytes = rtl_convertUnicodeToText( hConverter, 0, uniText, uniTextLen,
2832 buffer, bufLen,
2833 OUSTRING_TO_OSTRING_CVTFLAGS | RTL_UNICODETOTEXT_FLAGS_FLUSH,
2834 &nInfo, &nSrcChars );
2836 rtl_destroyUnicodeToTextConverter( hConverter );
2838 if( nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
2840 errno = EOVERFLOW;
2841 return 0;
2844 /* ensure trailing '\0' */
2845 buffer[nDestBytes] = '\0';
2847 return nDestBytes;
2850 /*****************************************************************************
2851 TextToUnicode
2853 @param text
2854 The text to convert.
2856 @param text_buffer_size
2857 The number of characters.
2859 @param unic_text
2860 The unicode buffer.
2862 @param unic_text_buffer_size
2863 The size in characters of the unicode buffer.
2865 ****************************************************************************/
2867 int TextToUnicode(
2868 const char* text,
2869 size_t text_buffer_size,
2870 sal_Unicode* unic_text,
2871 sal_Int32 unic_text_buffer_size)
2873 rtl_TextToUnicodeConverter hConverter;
2874 sal_uInt32 nInfo;
2875 sal_Size nSrcChars;
2876 sal_Size nDestBytes;
2878 /* stolen from rtl/string.c */
2879 hConverter = rtl_createTextToUnicodeConverter(osl_getThreadTextEncoding());
2881 nDestBytes = rtl_convertTextToUnicode(hConverter,
2883 text, text_buffer_size,
2884 unic_text, unic_text_buffer_size,
2885 OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_FLUSH,
2886 &nInfo, &nSrcChars);
2888 rtl_destroyTextToUnicodeConverter(hConverter);
2890 if (nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL)
2892 errno = EOVERFLOW;
2893 return 0;
2896 /* ensure trailing '\0' */
2897 unic_text[nDestBytes] = '\0';
2899 return nDestBytes;
2902 /******************************************************************************
2904 * GENERIC FLOPPY FUNCTIONS
2906 *****************************************************************************/
2909 /*****************************************
2910 * osl_unmountVolumeDevice
2911 ****************************************/
2913 oslFileError osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
2915 oslFileError tErr = osl_File_E_NOSYS;
2917 tErr = osl_unmountFloppy(Handle);
2919 /* Perhaps current working directory is set to mount point */
2921 if ( tErr )
2923 sal_Char *pszHomeDir = getenv("HOME");
2925 if ( pszHomeDir && strlen( pszHomeDir ) && 0 == chdir( pszHomeDir ) )
2927 /* try again */
2929 tErr = osl_unmountFloppy(Handle);
2931 OSL_ENSURE( tErr, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
2935 return tErr;
2938 /*****************************************
2939 * osl_automountVolumeDevice
2940 ****************************************/
2942 oslFileError osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
2944 oslFileError tErr = osl_File_E_NOSYS;
2946 tErr = osl_mountFloppy(Handle);
2948 return tErr;
2951 /*****************************************
2952 * osl_getVolumeDeviceMountPath
2953 ****************************************/
2955 oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
2957 oslVolumeDeviceHandleImpl* pItem = (oslVolumeDeviceHandleImpl*) Handle;
2958 sal_Char Buffer[PATH_MAX];
2960 Buffer[0] = '\0';
2962 if ( pItem == 0 || pstrPath == 0 )
2964 return osl_File_E_INVAL;
2967 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
2969 return osl_File_E_INVAL;
2972 #ifdef DEBUG_OSL_FILE
2973 fprintf(stderr,"Handle is:\n");
2974 osl_printFloppyHandle(pItem);
2975 #endif
2977 snprintf(Buffer, sizeof(Buffer), "file://%s", pItem->pszMountPoint);
2979 #ifdef DEBUG_OSL_FILE
2980 fprintf(stderr,"Mount Point is: '%s'\n",Buffer);
2981 #endif
2983 oslMakeUStrFromPsz(Buffer, pstrPath);
2985 return osl_File_E_None;
2988 /*****************************************
2989 * osl_acquireVolumeDeviceHandle
2990 ****************************************/
2992 oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
2994 oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
2996 if ( pItem == 0 )
2998 return osl_File_E_INVAL;
3001 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
3003 return osl_File_E_INVAL;
3006 ++pItem->RefCount;
3008 return osl_File_E_None;
3011 /*****************************************
3012 * osl_releaseVolumeDeviceHandle
3013 ****************************************/
3015 oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
3017 oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
3019 if ( pItem == 0 )
3021 return osl_File_E_INVAL;
3024 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
3026 return osl_File_E_INVAL;
3029 --pItem->RefCount;
3031 if ( pItem->RefCount == 0 )
3033 rtl_freeMemory(pItem);
3036 return osl_File_E_None;
3039 /*****************************************
3040 * osl_newVolumeDeviceHandleImpl
3041 ****************************************/
3043 static oslVolumeDeviceHandleImpl* osl_newVolumeDeviceHandleImpl()
3045 oslVolumeDeviceHandleImpl* pHandle;
3046 const size_t nSizeOfHandle = sizeof(oslVolumeDeviceHandleImpl);
3048 pHandle = (oslVolumeDeviceHandleImpl*) rtl_allocateMemory (nSizeOfHandle);
3049 if (pHandle != NULL)
3051 pHandle->ident[0] = 'O';
3052 pHandle->ident[1] = 'V';
3053 pHandle->ident[2] = 'D';
3054 pHandle->ident[3] = 'H';
3055 pHandle->pszMountPoint[0] = '\0';
3056 pHandle->pszFilePath[0] = '\0';
3057 pHandle->pszDevice[0] = '\0';
3058 pHandle->RefCount = 1;
3060 return pHandle;
3063 /*****************************************
3064 * osl_freeVolumeDeviceHandleImpl
3065 ****************************************/
3067 static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl* pHandle)
3069 if (pHandle != NULL)
3070 rtl_freeMemory (pHandle);
3074 /******************************************************************************
3076 * OS/2 FLOPPY FUNCTIONS
3078 *****************************************************************************/
3080 #if defined(OS2)
3081 static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath)
3083 return NULL;
3086 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
3088 return osl_File_E_BUSY;
3091 static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
3093 return osl_File_E_BUSY;
3096 static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
3098 return sal_False;
3101 static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice)
3103 return sal_False;
3107 #ifdef DEBUG_OSL_FILE
3108 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* pItem)
3110 if (pItem == 0 )
3112 fprintf(stderr,"NULL Handle\n");
3113 return;
3115 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
3117 #ifdef TRACE_OSL_FILE
3118 fprintf(stderr,"Invalid Handle]\n");
3119 #endif
3120 return;
3124 fprintf(stderr,"MountPoint : '%s'\n",pItem->pszMountPoint);
3125 fprintf(stderr,"FilePath : '%s'\n",pItem->pszFilePath);
3126 fprintf(stderr,"Device : '%s'\n",pItem->pszDevice);
3128 return;
3130 #endif
3132 #endif /* OS2 */