merged tag ooo/DEV300_m102
[LibreOffice.git] / sal / osl / os2 / file.cxx
blob2e668d23d638d14ecc9f69114c3a5868f0868f90
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
29 /************************************************************************
30 * ToDo
32 * Fix osl_getCanonicalName
34 * - Fix: check for corresponding struct sizes in exported functions
35 * - check size/use of oslDirectory
36 * - check size/use of oslDirectoryItem
37 * - check size/use of oslFileStatus
38 * - check size/use of oslVolumeDeviceHandle
39 * - check size/use of oslVolumeInfo
40 * - check size/use of oslFileHandle
41 ***********************************************************************/
43 #define INCL_DOSDEVIOCTL // OS2 device definitions
45 #include "system.h"
46 #include <rtl/alloc.h>
48 #include "osl/file.hxx"
51 #include <sal/types.h>
52 #include <osl/thread.h>
53 #include <osl/diagnose.h>
54 #include "file_error_transl.h"
55 #include <osl/time.h>
57 #ifndef _FILE_URL_H_
58 #include "file_url.h"
59 #endif
61 #include "file_path_helper.hxx"
62 #include "uunxapi.hxx"
64 #ifndef _STRING_H_
65 #include <string.h>
66 #endif
68 #ifndef _CTYPE_H_
69 #include <ctype.h>
70 #endif
72 #ifndef _WCHAR_H_
73 #include <wchar.h>
74 #endif
76 #if OSL_DEBUG_LEVEL > 1
77 extern void debug_ustring(rtl_uString*);
78 #endif
81 #ifdef DEBUG_OSL_FILE
82 # define PERROR( a, b ) perror( a ); fprintf( stderr, b )
83 #else
84 # define PERROR( a, b )
85 #endif
87 extern "C" oslFileHandle osl_createFileHandleFromFD( int fd );
89 struct errentry errtable[] = {
90 { NO_ERROR, osl_File_E_None }, /* 0 */
91 { ERROR_INVALID_FUNCTION, osl_File_E_INVAL }, /* 1 */
92 { ERROR_FILE_NOT_FOUND, osl_File_E_NOENT }, /* 2 */
93 { ERROR_PATH_NOT_FOUND, osl_File_E_NOENT }, /* 3 */
94 { ERROR_TOO_MANY_OPEN_FILES, osl_File_E_MFILE }, /* 4 */
95 { ERROR_ACCESS_DENIED, osl_File_E_ACCES }, /* 5 */
96 { ERROR_INVALID_HANDLE, osl_File_E_BADF }, /* 6 */
97 { ERROR_ARENA_TRASHED, osl_File_E_NOMEM }, /* 7 */
98 { ERROR_NOT_ENOUGH_MEMORY, osl_File_E_NOMEM }, /* 8 */
99 { ERROR_INVALID_BLOCK, osl_File_E_NOMEM }, /* 9 */
100 { ERROR_BAD_ENVIRONMENT, osl_File_E_2BIG }, /* 10 */
101 { ERROR_BAD_FORMAT, osl_File_E_NOEXEC }, /* 11 */
102 { ERROR_INVALID_ACCESS, osl_File_E_INVAL }, /* 12 */
103 { ERROR_INVALID_DATA, osl_File_E_INVAL }, /* 13 */
104 { ERROR_INVALID_DRIVE, osl_File_E_NOENT }, /* 15 */
105 { ERROR_CURRENT_DIRECTORY, osl_File_E_ACCES }, /* 16 */
106 { ERROR_NOT_SAME_DEVICE, osl_File_E_XDEV }, /* 17 */
107 { ERROR_NO_MORE_FILES, osl_File_E_NOENT }, /* 18 */
108 { ERROR_NOT_READY, osl_File_E_NOTREADY }, /* 21 */
109 { ERROR_LOCK_VIOLATION, osl_File_E_ACCES }, /* 33 */
110 { ERROR_BAD_NETPATH, osl_File_E_NOENT }, /* 53 */
111 { ERROR_NETWORK_ACCESS_DENIED, osl_File_E_ACCES }, /* 65 */
112 { ERROR_BAD_NET_NAME, osl_File_E_NOENT }, /* 67 */
113 { ERROR_FILE_EXISTS, osl_File_E_EXIST }, /* 80 */
114 { ERROR_CANNOT_MAKE, osl_File_E_ACCES }, /* 82 */
115 { ERROR_FAIL_I24, osl_File_E_ACCES }, /* 83 */
116 { ERROR_INVALID_PARAMETER, osl_File_E_INVAL }, /* 87 */
117 { ERROR_NO_PROC_SLOTS, osl_File_E_AGAIN }, /* 89 */
118 { ERROR_DRIVE_LOCKED, osl_File_E_ACCES }, /* 108 */
119 { ERROR_BROKEN_PIPE, osl_File_E_PIPE }, /* 109 */
120 { ERROR_DISK_FULL, osl_File_E_NOSPC }, /* 112 */
121 { ERROR_INVALID_TARGET_HANDLE, osl_File_E_BADF }, /* 114 */
122 { ERROR_INVALID_HANDLE, osl_File_E_INVAL }, /* 124 */
123 { ERROR_WAIT_NO_CHILDREN, osl_File_E_CHILD }, /* 128 */
124 { ERROR_CHILD_NOT_COMPLETE, osl_File_E_CHILD }, /* 129 */
125 { ERROR_DIRECT_ACCESS_HANDLE, osl_File_E_BADF }, /* 130 */
126 { ERROR_NEGATIVE_SEEK, osl_File_E_INVAL }, /* 131 */
127 { ERROR_SEEK_ON_DEVICE, osl_File_E_ACCES }, /* 132 */
128 { ERROR_DIR_NOT_EMPTY, osl_File_E_NOTEMPTY }, /* 145 */
129 { ERROR_NOT_LOCKED, osl_File_E_ACCES }, /* 158 */
130 { ERROR_BAD_PATHNAME, osl_File_E_NOENT }, /* 161 */
131 { ERROR_MAX_THRDS_REACHED, osl_File_E_AGAIN }, /* 164 */
132 { ERROR_LOCK_FAILED, osl_File_E_ACCES }, /* 167 */
133 { ERROR_ALREADY_EXISTS, osl_File_E_EXIST }, /* 183 */
134 { ERROR_FILENAME_EXCED_RANGE, osl_File_E_NOENT }, /* 206 */
135 { ERROR_NESTING_NOT_ALLOWED, osl_File_E_AGAIN }, /* 215 */
136 { ERROR_DIRECTORY, osl_File_E_NOENT }, /* 267 */
137 //{ ERROR_NOT_ENOUGH_QUOTA, osl_File_E_NOMEM } /* 1816 */
140 #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
142 //#####################################################
143 oslFileError MapError(APIRET dwError)
145 for (int i = 0; i < ELEMENTS_OF_ARRAY(errtable); ++i )
147 if (dwError == errtable[i].oscode)
148 return static_cast<oslFileError>(errtable[i].errnocode);
150 return osl_File_E_INVAL;
153 /******************************************************************************
155 * static members
157 *****************************************************************************/
159 static const char * pFileLockEnvVar = (char *) -1;
162 /******************************************************************************
164 * C-String Function Declarations
166 *****************************************************************************/
168 static oslFileError osl_psz_getVolumeInformation(const sal_Char* , oslVolumeInfo* pInfo, sal_uInt32 uFieldMask);
169 static oslFileError osl_psz_removeFile(const sal_Char* pszPath);
170 static oslFileError osl_psz_createDirectory(const sal_Char* pszPath);
171 static oslFileError osl_psz_removeDirectory(const sal_Char* pszPath);
172 static oslFileError osl_psz_copyFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
173 static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
174 static oslFileError osl_psz_setFileTime(const sal_Char* strFilePath, const TimeValue* pCreationTime, const TimeValue* pLastAccessTime, const TimeValue* pLastWriteTime);
177 /******************************************************************************
179 * Static Module Utility Function Declarations
181 *****************************************************************************/
183 static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists);
184 static oslFileError oslChangeFileModes(const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID);
185 static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName);
186 static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode);
187 static oslFileError oslDoMoveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
188 rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr,rtl_uString** uStr);
190 /******************************************************************************
192 * Non-Static Utility Function Declarations
194 *****************************************************************************/
196 extern "C" int UnicodeToText( char *, size_t, const sal_Unicode *, sal_Int32 );
197 extern "C" int TextToUnicode(
198 const char* text, size_t text_buffer_size, sal_Unicode* unic_text, sal_Int32 unic_text_buffer_size);
200 /******************************************************************************
202 * 'removeable device' aka floppy functions
204 *****************************************************************************/
206 static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath);
207 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy);
208 static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy);
210 #ifdef DEBUG_OSL_FILE
211 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* hFloppy);
212 #endif
214 /**********************************************
215 * _osl_openLocalRoot
216 * enumerate available drives
217 *********************************************/
218 static oslFileError _osl_openLocalRoot( rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
220 rtl_uString *ustrSystemPath = NULL;
221 oslFileError error;
223 if ( !pDirectory )
224 return osl_File_E_INVAL;
226 *pDirectory = NULL;
228 error = osl_getSystemPathFromFileURL_Ex( strDirectoryPath, &ustrSystemPath, sal_False );
230 if ( osl_File_E_None == error )
232 /* create and initialize impl structure */
233 DirectoryImpl* pDirImpl = (DirectoryImpl*) rtl_allocateMemory( sizeof(DirectoryImpl) );
234 if( pDirImpl )
236 ULONG ulDriveNum;
237 APIRET rc;
238 pDirImpl->uType = DIRECTORYTYPE_LOCALROOT;
239 pDirImpl->ustrPath = ustrSystemPath;
240 rc = DosQueryCurrentDisk (&ulDriveNum, &pDirImpl->ulDriveMap);
241 pDirImpl->pDirStruct = 0;
242 pDirImpl->ulNextDrive = 1;
243 pDirImpl->ulNextDriveMask = 1;
245 // determine number of floppy-drives
246 BYTE nFloppies;
247 rc = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY );
248 if (nFloppies == 0) {
249 // if no floppies, start with 3rd drive (C:)
250 pDirImpl->ulNextDrive = 3;
251 pDirImpl->ulNextDriveMask <<= 2;
252 } else if (nFloppies == 1) {
253 // mask drive B (second bit) in this case
254 pDirImpl->ulDriveMap &= ~0x02;
256 *pDirectory = (oslDirectory) pDirImpl;
257 return osl_File_E_None;
259 else
261 errno = osl_File_E_NOMEM;
266 rtl_uString_release( ustrSystemPath );
267 return error;
270 /**********************************************
271 * _osl_getNextDrive
272 *********************************************/
273 static oslFileError SAL_CALL _osl_getNextDrive(
274 oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint )
276 DirectoryImpl *pDirImpl = (DirectoryImpl *)Directory;
277 DirectoryItem_Impl *pItemImpl = NULL;
278 rtl_uString * ustrDrive = NULL;
279 BOOL fSuccess;
280 char buffer[3];
282 uHint = uHint; /* avoid warnings */
284 if ( !pItem )
285 return osl_File_E_INVAL;
287 *pItem = NULL;
289 if ( !pDirImpl )
290 return osl_File_E_INVAL;
292 while( pDirImpl->ulNextDrive <= 26)
294 // exit if bit==1 -> drive found
295 if (pDirImpl->ulDriveMap & pDirImpl->ulNextDriveMask) {
297 /* convert file name to unicode */
298 buffer[0] = '@' + pDirImpl->ulNextDrive;
299 buffer[1] = ':';
300 buffer[2] = 0;
302 pItemImpl = (DirectoryItem_Impl*) rtl_allocateMemory(sizeof(DirectoryItem_Impl));
303 if ( !pItemImpl )
304 return osl_File_E_NOMEM;
306 memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
307 pItemImpl->uType = DIRECTORYITEM_DRIVE;
308 pItemImpl->nRefCount = 1;
310 rtl_string2UString( &pItemImpl->ustrDrive, buffer, 3,
311 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
312 OSL_ASSERT(pItemImpl->ustrDrive != 0);
314 /* use drive as directory item */
315 *pItem = (oslDirectoryItem) pItemImpl;
317 // scan next bit position
318 pDirImpl->ulNextDrive++;
319 pDirImpl->ulNextDriveMask <<= 1;
321 if (*pItem) // item assigned, return now.
322 return osl_File_E_None;
325 // no more items
326 return osl_File_E_NOENT;
329 /**********************************************
330 * _osl_readdir_impl_
332 * readdir wrapper, filters out "." and ".."
333 * on request
334 *********************************************/
336 static struct dirent* _osl_readdir_impl_(DIR* pdir, sal_Bool bFilterLocalAndParentDir)
338 struct dirent* pdirent;
340 while ((pdirent = readdir(pdir)) != NULL)
342 if (bFilterLocalAndParentDir &&
343 ((0 == strcmp(pdirent->d_name, ".")) || (0 == strcmp(pdirent->d_name, ".."))))
344 continue;
345 else
346 break;
349 return pdirent;
352 /*******************************************************************
353 * osl_openDirectory
354 ******************************************************************/
356 oslFileError SAL_CALL osl_openDirectory(rtl_uString* ustrDirectoryURL, oslDirectory* pDirectory)
358 rtl_uString* ustrSystemPath = NULL;
359 oslFileError eRet;
361 char path[PATH_MAX];
363 OSL_ASSERT(ustrDirectoryURL && (ustrDirectoryURL->length > 0));
364 OSL_ASSERT(pDirectory);
366 if (0 == ustrDirectoryURL->length )
367 return osl_File_E_INVAL;
369 if ( 0 == rtl_ustr_compareIgnoreAsciiCase( ustrDirectoryURL->buffer, (const sal_Unicode*)L"file:///" ) )
370 return _osl_openLocalRoot( ustrDirectoryURL, pDirectory );
372 /* convert file URL to system path */
373 eRet = osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL, &ustrSystemPath, sal_False);
375 if( osl_File_E_None != eRet )
376 return eRet;
378 osl_systemPathRemoveSeparator(ustrSystemPath);
380 /* convert unicode path to text */
381 if ( UnicodeToText( path, PATH_MAX, ustrSystemPath->buffer, ustrSystemPath->length ) )
383 // if only the drive is specified (x:), add a \ (x:\) otherwise current
384 // directory is browsed instead of root.
385 if (strlen( path) == 2 && path[1] == ':')
386 strcat( path, "\\");
387 /* open directory */
388 DIR *pdir = opendir( path );
390 if( pdir )
392 /* create and initialize impl structure */
393 DirectoryImpl* pDirImpl = (DirectoryImpl*) rtl_allocateMemory( sizeof(DirectoryImpl) );
395 if( pDirImpl )
397 pDirImpl->uType = DIRECTORYTYPE_FILESYSTEM;
398 pDirImpl->pDirStruct = pdir;
399 pDirImpl->ustrPath = ustrSystemPath;
401 *pDirectory = (oslDirectory) pDirImpl;
402 return osl_File_E_None;
404 else
406 errno = ENOMEM;
407 closedir( pdir );
410 else
411 /* should be removed by optimizer in product version */
412 PERROR( "osl_openDirectory", path );
415 rtl_uString_release( ustrSystemPath );
417 return oslTranslateFileError(OSL_FET_ERROR, errno);
421 /****************************************************************************
422 * osl_getNextDirectoryItem
423 ***************************************************************************/
425 oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory Directory, oslDirectoryItem* pItem, sal_uInt32 uHint)
427 DirectoryImpl* pDirImpl = (DirectoryImpl*)Directory;
428 DirectoryItem_Impl *pItemImpl = NULL;
429 rtl_uString* ustrFileName = NULL;
430 rtl_uString* ustrFilePath = NULL;
431 struct dirent* pEntry;
433 OSL_ASSERT(Directory);
434 OSL_ASSERT(pItem);
436 if ((NULL == Directory) || (NULL == pItem))
437 return osl_File_E_INVAL;
439 if ( pDirImpl->uType == DIRECTORYTYPE_LOCALROOT)
440 return _osl_getNextDrive( Directory, pItem, uHint );
442 pEntry = _osl_readdir_impl_(pDirImpl->pDirStruct, sal_True);
444 if (NULL == pEntry)
445 return osl_File_E_NOENT;
447 pItemImpl = (DirectoryItem_Impl*) rtl_allocateMemory(sizeof(DirectoryItem_Impl));
448 if ( !pItemImpl )
449 return osl_File_E_NOMEM;
451 memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
452 pItemImpl->uType = DIRECTORYITEM_FILE;
453 pItemImpl->nRefCount = 1;
454 pItemImpl->d_attr = pEntry->d_attr;
456 /* convert file name to unicode */
457 rtl_string2UString( &ustrFileName, pEntry->d_name, strlen( pEntry->d_name ),
458 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
459 OSL_ASSERT(ustrFileName != 0);
461 osl_systemPathMakeAbsolutePath(pDirImpl->ustrPath, ustrFileName, &pItemImpl->ustrFilePath);
462 rtl_uString_release( ustrFileName );
464 *pItem = (oslDirectoryItem)pItemImpl;
465 return osl_File_E_None;
468 /****************************************************************************/
469 /* osl_closeDirectory */
470 /****************************************************************************/
472 oslFileError SAL_CALL osl_closeDirectory( oslDirectory Directory )
474 DirectoryImpl* pDirImpl = (DirectoryImpl*) Directory;
475 oslFileError err = osl_File_E_None;
477 OSL_ASSERT( Directory );
479 if( NULL == pDirImpl )
480 return osl_File_E_INVAL;
482 switch ( pDirImpl->uType )
484 case DIRECTORYTYPE_FILESYSTEM:
485 if( closedir( pDirImpl->pDirStruct ) )
486 err = oslTranslateFileError(OSL_FET_ERROR, errno);
487 break;
488 case DIRECTORYTYPE_LOCALROOT:
489 err = osl_File_E_None;
490 break;
491 #if 0
492 case DIRECTORYTYPE_NETROOT:
494 DWORD err = WNetCloseEnum(pDirImpl->hDirectory);
495 eError = (err == NO_ERROR) ? osl_File_E_None : MapError(err);
497 break;
498 #endif
499 default:
500 OSL_ENSURE( 0, "Invalid directory type" );
501 break;
504 /* cleanup members */
505 rtl_uString_release( pDirImpl->ustrPath );
507 rtl_freeMemory( pDirImpl );
509 return err;
512 /****************************************************************************/
513 /* osl_getDirectoryItem */
514 /****************************************************************************/
516 oslFileError SAL_CALL osl_getDirectoryItem( rtl_uString* ustrFileURL, oslDirectoryItem* pItem )
518 rtl_uString* strSysFilePath = NULL;
519 oslFileError error = osl_File_E_INVAL;
520 ULONG dwPathType;
521 PATHTYPE type = PATHTYPE_FILE;
523 OSL_ASSERT(ustrFileURL);
524 OSL_ASSERT(pItem);
526 /* Assume failure */
527 if ( !pItem )
528 return osl_File_E_INVAL;
529 *pItem = NULL;
531 if (0 == ustrFileURL->length || NULL == pItem)
532 return osl_File_E_INVAL;
534 error = osl_getSystemPathFromFileURL_Ex(ustrFileURL, &strSysFilePath, sal_False);
536 if (osl_File_E_None != error)
537 return error;
539 dwPathType = IsValidFilePath( strSysFilePath->buffer, NULL, VALIDATEPATH_NORMAL );
541 if ( dwPathType & PATHTYPE_IS_VOLUME )
542 type = PATHTYPE_VOLUME;
543 else if ( dwPathType & PATHTYPE_IS_SERVER )
544 type = PATHTYPE_NETSERVER;
545 else
546 type = PATHTYPE_FILE;
548 switch ( type )
550 case PATHTYPE_NETSERVER:
552 DirectoryItem_Impl* pItemImpl =
553 reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
555 if ( !pItemImpl )
556 error = osl_File_E_NOMEM;
558 if ( osl_File_E_None == error )
560 memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
561 pItemImpl->uType = DIRECTORYITEM_SERVER;
562 pItemImpl->nRefCount = 1;
563 rtl_uString_assign( &pItemImpl->ustrFilePath, strSysFilePath );
565 *pItem = pItemImpl;
568 break;
569 case PATHTYPE_VOLUME:
571 DirectoryItem_Impl* pItemImpl =
572 reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
574 if ( !pItemImpl )
575 error = osl_File_E_NOMEM;
577 if ( osl_File_E_None == error )
579 memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
580 pItemImpl->uType = DIRECTORYITEM_DRIVE;
581 pItemImpl->nRefCount = 1;
582 rtl_uString_assign( &pItemImpl->ustrDrive, strSysFilePath );
584 if ( pItemImpl->ustrDrive->buffer[pItemImpl->ustrDrive->length-1] != sal_Unicode('\\') )
585 rtl_uString_newConcat( &pItemImpl->ustrDrive,
586 pItemImpl->ustrDrive, rtl::OUString::createFromAscii( "\\" ).pData);
588 *pItem = pItemImpl;
591 break;
592 default:
593 case PATHTYPE_FILE:
595 if ( strSysFilePath->length > 0 && strSysFilePath->buffer[strSysFilePath->length - 1] == '\\' )
596 rtl_uString_newFromStr_WithLength( &strSysFilePath, strSysFilePath->buffer, strSysFilePath->length - 1 );
598 if (0 == access_u(strSysFilePath, F_OK))
600 DirectoryItem_Impl *pItemImpl =
601 reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
603 memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
604 pItemImpl->uType = DIRECTORYITEM_FILE;
605 pItemImpl->nRefCount = 1;
606 rtl_uString_assign( &pItemImpl->ustrFilePath, strSysFilePath );
608 *pItem = pItemImpl;
610 else
611 error = oslTranslateFileError(OSL_FET_ERROR, errno);
613 break;
616 if ( strSysFilePath )
617 rtl_uString_release( strSysFilePath );
619 return error;
622 /****************************************************************************/
623 /* osl_acquireDirectoryItem */
624 /****************************************************************************/
626 oslFileError osl_acquireDirectoryItem( oslDirectoryItem Item )
628 OSL_ASSERT( Item );
629 DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
631 if ( !pItemImpl )
632 return osl_File_E_INVAL;
634 pItemImpl->nRefCount++;
635 return osl_File_E_None;
638 /****************************************************************************/
639 /* osl_releaseDirectoryItem */
640 /****************************************************************************/
642 oslFileError osl_releaseDirectoryItem( oslDirectoryItem Item )
644 OSL_ASSERT( Item );
645 DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
647 if ( !pItemImpl )
648 return osl_File_E_INVAL;
650 if ( ! --pItemImpl->nRefCount )
652 if (pItemImpl->ustrFilePath)
653 rtl_uString_release( pItemImpl->ustrFilePath );
654 if (pItemImpl->ustrDrive)
655 rtl_uString_release( pItemImpl->ustrDrive );
656 rtl_freeMemory( pItemImpl );
658 return osl_File_E_None;
661 /****************************************************************************
662 * osl_createFileHandleFromFD
663 ***************************************************************************/
665 oslFileHandle osl_createFileHandleFromFD( int fd )
667 oslFileHandleImpl* pHandleImpl = NULL;
669 if ( fd >= 0 )
671 pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
673 if( pHandleImpl )
675 pHandleImpl->ustrFilePath = NULL;
676 rtl_uString_new( &pHandleImpl->ustrFilePath );
677 pHandleImpl->fd = fd;
679 /* FIXME: should detect whether the file has been locked */
680 pHandleImpl->bLocked = sal_True;
684 return (oslFileHandle)pHandleImpl;
687 /****************************************************************************
688 * osl_openFile
689 ***************************************************************************/
691 oslFileError osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags )
693 oslFileHandleImpl* pHandleImpl = NULL;
694 oslFileError eRet;
695 rtl_uString* ustrFilePath = NULL;
697 char buffer[PATH_MAX];
698 int fd;
699 int mode = S_IRUSR | S_IRGRP | S_IROTH;
700 int flags = O_RDONLY;
702 struct flock aflock;
704 /* locking the complete file */
705 aflock.l_type = 0;
706 aflock.l_whence = SEEK_SET;
707 aflock.l_start = 0;
708 aflock.l_len = 0;
710 OSL_ASSERT( ustrFileURL );
711 OSL_ASSERT( pHandle );
713 if( ( 0 == ustrFileURL->length ) )
714 return osl_File_E_INVAL;
716 /* convert file URL to system path */
717 eRet = osl_getSystemPathFromFileURL( ustrFileURL, &ustrFilePath );
719 if( osl_File_E_None != eRet )
720 return eRet;
722 osl_systemPathRemoveSeparator(ustrFilePath);
724 /* convert unicode path to text */
725 if( UnicodeToText( buffer, PATH_MAX, ustrFilePath->buffer, ustrFilePath->length ) )
727 /* we do not open devices or such here */
728 if( !( uFlags & osl_File_OpenFlag_Create ) )
730 struct stat aFileStat;
732 if( 0 > stat( buffer, &aFileStat ) )
734 PERROR( "osl_openFile", buffer );
735 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
738 else if( !S_ISREG( aFileStat.st_mode ) )
740 eRet = osl_File_E_INVAL;
744 if( osl_File_E_None == eRet )
747 * set flags and mode
750 if ( uFlags & osl_File_OpenFlag_Write )
752 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
753 flags = O_RDWR;
754 aflock.l_type = F_WRLCK;
757 if ( uFlags & osl_File_OpenFlag_Create )
759 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
760 flags = O_CREAT | O_EXCL | O_RDWR;
763 /* open the file */
764 fd = open( buffer, flags | O_BINARY, mode);
765 if ( fd >= 0 )
767 sal_Bool bNeedsLock = ( ( uFlags & osl_File_OpenFlag_NoLock ) == 0 );
768 sal_Bool bLocked = sal_False;
769 if( bNeedsLock )
771 /* check if file lock is enabled and clear l_type member of flock otherwise */
772 if( (char *) -1 == pFileLockEnvVar )
774 /* FIXME: this is not MT safe */
775 pFileLockEnvVar = getenv("SAL_ENABLE_FILE_LOCKING");
777 if( NULL == pFileLockEnvVar)
778 pFileLockEnvVar = getenv("STAR_ENABLE_FILE_LOCKING");
781 if( NULL == pFileLockEnvVar )
782 aflock.l_type = 0;
784 /* lock the file if flock.l_type is set */
785 bLocked = ( F_WRLCK != aflock.l_type || -1 != fcntl( fd, F_SETLK, &aflock ) );
788 if ( !bNeedsLock || bLocked )
790 /* allocate memory for impl structure */
791 pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
792 if( pHandleImpl )
794 pHandleImpl->ustrFilePath = ustrFilePath;
795 pHandleImpl->fd = fd;
796 pHandleImpl->bLocked = bLocked;
798 *pHandle = (oslFileHandle) pHandleImpl;
800 return osl_File_E_None;
802 else
804 errno = ENOMEM;
808 close( fd );
811 PERROR( "osl_openFile", buffer );
812 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
815 else
816 eRet = osl_File_E_INVAL;
818 rtl_uString_release( ustrFilePath );
819 return eRet;
822 /****************************************************************************/
823 /* osl_closeFile */
824 /****************************************************************************/
826 oslFileError osl_closeFile( oslFileHandle Handle )
828 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl *) Handle;
829 oslFileError eRet = osl_File_E_INVAL;
831 OSL_ASSERT( Handle );
833 if( pHandleImpl )
835 rtl_uString_release( pHandleImpl->ustrFilePath );
837 /* release file lock if locking is enabled */
838 if( pFileLockEnvVar )
840 struct flock aflock;
842 aflock.l_type = F_UNLCK;
843 aflock.l_whence = SEEK_SET;
844 aflock.l_start = 0;
845 aflock.l_len = 0;
847 if ( pHandleImpl->bLocked )
849 /* FIXME: check if file is really locked ? */
851 /* release the file share lock on this file */
852 if( -1 == fcntl( pHandleImpl->fd, F_SETLK, &aflock ) )
853 PERROR( "osl_closeFile", "unlock failed" );
857 if( 0 > close( pHandleImpl->fd ) )
859 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
861 else
862 eRet = osl_File_E_None;
864 rtl_freeMemory( pHandleImpl );
867 return eRet;
870 /****************************************************************************/
871 /* osl_isEndOfFile */
872 /****************************************************************************/
874 oslFileError SAL_CALL osl_isEndOfFile( oslFileHandle Handle, sal_Bool *pIsEOF )
876 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl *) Handle;
877 oslFileError eRet = osl_File_E_INVAL;
879 if ( pHandleImpl)
881 long curPos = lseek( pHandleImpl->fd, 0, SEEK_CUR );
883 if ( curPos >= 0 )
885 long endPos = lseek( pHandleImpl->fd, 0, SEEK_END );
887 if ( endPos >= 0 )
889 *pIsEOF = ( curPos == endPos );
890 curPos = lseek( pHandleImpl->fd, curPos, SEEK_SET );
892 if ( curPos >= 0 )
893 eRet = osl_File_E_None;
894 else
895 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
897 else
898 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
900 else
901 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
904 return eRet;
908 /****************************************************************************/
909 /* osl_moveFile */
910 /****************************************************************************/
912 oslFileError osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
914 char srcPath[PATH_MAX];
915 char destPath[PATH_MAX];
916 oslFileError eRet;
917 APIRET rc;
919 OSL_ASSERT( ustrFileURL );
920 OSL_ASSERT( ustrDestURL );
922 /* convert source url to system path */
923 eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
924 if( eRet != osl_File_E_None )
925 return eRet;
927 /* convert destination url to system path */
928 eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
929 if( eRet != osl_File_E_None )
930 return eRet;
932 //YD 01/05/06 rename() can overwrite existing files.
933 rc = DosDelete( (PCSZ)destPath);
934 rc = DosMove( (PCSZ)srcPath, (PCSZ)destPath);
935 if (!rc)
936 eRet = osl_File_E_None;
937 else
938 eRet = MapError( rc);
940 return eRet;
943 /****************************************************************************/
944 /* osl_copyFile */
945 /****************************************************************************/
947 #define TMP_DEST_FILE_EXTENSION ".osl-tmp"
949 static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists)
951 int nRet=0;
952 sal_Char pszTmpDestFile[PATH_MAX];
953 size_t size_tmp_dest_buff = sizeof(pszTmpDestFile);
955 /* Quick fix for #106048, the whole copy file function seems
956 to be erroneous anyway and needs to be rewritten.
957 Besides osl_copyFile is currently not used from OO/SO code.
959 memset(pszTmpDestFile, 0, size_tmp_dest_buff);
961 if ( DestFileExists )
963 strncpy(pszTmpDestFile, pszDestFileName, size_tmp_dest_buff - 1);
965 if ((strlen(pszTmpDestFile) + strlen(TMP_DEST_FILE_EXTENSION)) >= size_tmp_dest_buff)
966 return osl_File_E_NAMETOOLONG;
968 strncat(pszTmpDestFile, TMP_DEST_FILE_EXTENSION, strlen(TMP_DEST_FILE_EXTENSION));
970 /* FIXME: what if pszTmpDestFile already exists? */
971 /* with getcanonical??? */
972 nRet=rename(pszDestFileName,pszTmpDestFile);
975 /* mfe: should be S_ISREG */
976 if ( !S_ISLNK(nMode) )
978 /* copy SourceFile to DestFile */
979 nRet = oslDoCopyFile(pszSourceFileName,pszDestFileName,nSourceSize, nMode);
981 /* mfe: OK redundant at the moment */
982 else if ( S_ISLNK(nMode) )
984 nRet = oslDoCopyLink(pszSourceFileName,pszDestFileName);
986 else
988 /* mfe: what to do here? */
989 nRet=ENOSYS;
992 if ( nRet > 0 && DestFileExists == 1 )
994 unlink(pszDestFileName);
995 rename(pszTmpDestFile,pszDestFileName);
998 if ( nRet > 0 )
1000 return oslTranslateFileError(OSL_FET_ERROR, nRet);
1003 if ( DestFileExists == 1 )
1005 unlink(pszTmpDestFile);
1008 return osl_File_E_None;
1011 /*****************************************
1012 * oslChangeFileModes
1013 ****************************************/
1015 static oslFileError oslChangeFileModes( const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID)
1017 int nRet=0;
1018 struct utimbuf aTimeBuffer;
1020 nRet = chmod(pszFileName,nMode);
1021 if ( nRet < 0 )
1023 nRet=errno;
1024 return oslTranslateFileError(OSL_FET_ERROR, nRet);
1027 aTimeBuffer.actime=nAcTime;
1028 aTimeBuffer.modtime=nModTime;
1029 nRet=utime(pszFileName,&aTimeBuffer);
1030 if ( nRet < 0 )
1032 nRet=errno;
1033 return oslTranslateFileError(OSL_FET_ERROR, nRet);
1036 if ( nUID != getuid() )
1038 nUID=getuid();
1041 nRet=chown(pszFileName,nUID,nGID);
1042 if ( nRet < 0 )
1044 nRet=errno;
1046 /* mfe: do not return an error here! */
1047 /* return oslTranslateFileError(nRet);*/
1050 return osl_File_E_None;
1053 /*****************************************
1054 * oslDoCopyLink
1055 ****************************************/
1057 static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName)
1059 int nRet=0;
1061 /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
1062 /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
1063 sal_Char pszLinkContent[PATH_MAX];
1065 pszLinkContent[0] = '\0';
1067 nRet = readlink(pszSourceFileName,pszLinkContent,PATH_MAX);
1069 if ( nRet < 0 )
1071 nRet=errno;
1072 return nRet;
1074 else
1075 pszLinkContent[ nRet ] = 0;
1077 nRet = symlink(pszLinkContent,pszDestFileName);
1079 if ( nRet < 0 )
1081 nRet=errno;
1082 return nRet;
1085 return 0;
1088 /*****************************************
1089 * oslDoCopyFile
1090 ****************************************/
1092 static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode)
1094 int SourceFileFD=0;
1095 int DestFileFD=0;
1096 int nRet=0;
1097 void* pSourceFile=0;
1098 char buffer[ 4096];
1100 SourceFileFD=open(pszSourceFileName,O_RDONLY | O_BINARY);
1101 if ( SourceFileFD < 0 )
1103 nRet=errno;
1104 return nRet;
1107 DestFileFD=open(pszDestFileName, O_WRONLY | O_CREAT | O_BINARY, mode);
1108 if ( DestFileFD < 0 )
1110 nRet=errno;
1111 close(SourceFileFD);
1112 return nRet;
1115 /* HACK: because memory mapping fails on various
1116 platforms if the size of the source file is 0 byte */
1117 if (0 == nSourceSize)
1119 close(SourceFileFD);
1120 close(DestFileFD);
1121 return 0;
1124 while( (nRet = read(SourceFileFD, buffer, sizeof(buffer))) !=0 )
1126 nRet = write( DestFileFD, buffer, nRet);
1129 close(SourceFileFD);
1130 close(DestFileFD);
1132 return nRet;
1135 static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
1137 time_t nAcTime=0;
1138 time_t nModTime=0;
1139 uid_t nUID=0;
1140 gid_t nGID=0;
1141 int nRet=0;
1142 mode_t nMode=0;
1143 struct stat aFileStat;
1144 oslFileError tErr=osl_File_E_invalidError;
1145 size_t nSourceSize=0;
1146 int DestFileExists=1;
1148 /* mfe: does the source file really exists? */
1149 nRet = lstat(pszPath,&aFileStat);
1151 if ( nRet < 0 )
1153 nRet=errno;
1154 return oslTranslateFileError(OSL_FET_ERROR, nRet);
1157 /* mfe: we do only copy files here! */
1158 if ( S_ISDIR(aFileStat.st_mode) )
1160 return osl_File_E_ISDIR;
1163 nSourceSize=(size_t)aFileStat.st_size;
1164 nMode=aFileStat.st_mode;
1165 nAcTime=aFileStat.st_atime;
1166 nModTime=aFileStat.st_mtime;
1167 nUID=aFileStat.st_uid;
1168 nGID=aFileStat.st_gid;
1170 nRet = stat(pszDestPath,&aFileStat);
1171 if ( nRet < 0 )
1173 nRet=errno;
1175 if ( nRet == ENOENT )
1177 DestFileExists=0;
1179 /* return oslTranslateFileError(nRet);*/
1182 /* mfe: the destination file must not be a directory! */
1183 if ( nRet == 0 && S_ISDIR(aFileStat.st_mode) )
1185 return osl_File_E_ISDIR;
1187 else
1189 /* mfe: file does not exists or is no dir */
1192 tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
1194 if ( tErr != osl_File_E_None )
1196 return tErr;
1200 * mfe: ignore return code
1201 * since only the success of the copy is
1202 * important
1204 oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
1206 return tErr;
1209 oslFileError osl_copyFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
1211 char srcPath[PATH_MAX];
1212 char destPath[PATH_MAX];
1213 oslFileError eRet;
1214 APIRET rc;
1216 OSL_ASSERT( ustrFileURL );
1217 OSL_ASSERT( ustrDestURL );
1219 /* convert source url to system path */
1220 eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
1221 if( eRet != osl_File_E_None )
1222 return eRet;
1224 /* convert destination url to system path */
1225 eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
1226 if( eRet != osl_File_E_None )
1227 return eRet;
1229 return osl_psz_copyFile( srcPath, destPath );
1232 /****************************************************************************/
1233 /* osl_removeFile */
1234 /****************************************************************************/
1236 oslFileError osl_removeFile( rtl_uString* ustrFileURL )
1238 char path[PATH_MAX];
1239 oslFileError eRet;
1240 APIRET rc;
1242 OSL_ASSERT( ustrFileURL );
1244 /* convert file url to system path */
1245 eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
1246 if( eRet != osl_File_E_None )
1247 return eRet;
1249 rc = DosDelete( (PCSZ)path);
1250 if (!rc)
1251 eRet = osl_File_E_None;
1252 else
1253 eRet = MapError( rc);
1255 return eRet;
1258 /****************************************************************************/
1259 /* osl_getVolumeInformation */
1260 /****************************************************************************/
1262 #define TXFSDC_BLOCKR 0x00 // block device removable
1263 #define TXFSDC_GETBPB 0x00 // get device bpb info
1264 #define TXFSBPB_REMOVABLE 0x08 // BPB attribute for removable
1266 typedef struct drivecmd
1268 BYTE cmd; // 0=unlock 1=lock 2=eject
1269 BYTE drv; // 0=A, 1=B 2=C ...
1270 } DRIVECMD; // end of struct "drivecmd"
1272 #pragma pack(push, 1) // byte packing
1273 typedef struct txfs_ebpb // ext. boot parameter block
1274 { // at offset 0x0b in bootsector
1275 USHORT SectSize; // 0B bytes per sector
1276 BYTE ClustSize; // 0D sectors per cluster
1277 USHORT FatOffset; // 0E sectors to 1st FAT
1278 BYTE NrOfFats; // 10 nr of FATS (FAT only)
1279 USHORT RootEntries; // 11 Max entries \ (FAT only)
1280 USHORT Sectors; // 13 nr of sectors if < 64K
1281 BYTE MediaType; // 15 mediatype (F8 for HD)
1282 USHORT FatSectors; // 16 sectors/FAT (FAT only)
1283 USHORT LogGeoSect; // 18 sectors/Track
1284 USHORT LogGeoHead; // 1a nr of heads
1285 ULONG HiddenSectors; // 1c sector-offset from MBR/EBR
1286 ULONG BigSectors; // 20 nr of sectors if >= 64K
1287 } TXFS_EBPB; // last byte is at offset 0x23
1289 typedef struct drivebpb
1291 TXFS_EBPB ebpb; // extended BPB
1292 BYTE reserved[6];
1293 USHORT cyls;
1294 BYTE type;
1295 USHORT attributes; // device attributes
1296 BYTE fill[6]; // documented for IOCtl
1297 } DRIVEBPB; // end of struct "drivebpb"
1299 struct CDInfo {
1300 USHORT usCount;
1301 USHORT usFirst;
1304 #pragma pack(pop)
1306 /*****************************************************************************/
1307 // Get number of cdrom readers
1308 /*****************************************************************************/
1309 BOOL GetCDInfo( CDInfo * pCDInfo )
1311 HFILE hFileCD;
1312 ULONG ulAction;
1314 if( NO_ERROR == DosOpen( (PCSZ)"\\DEV\\CD-ROM2$",
1315 &hFileCD, &ulAction, 0, FILE_NORMAL,
1316 OPEN_ACTION_OPEN_IF_EXISTS,
1317 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL )) {
1318 ULONG ulDataSize = sizeof(CDInfo);
1319 APIRET rc = DosDevIOCtl( hFileCD, 0x82, 0x60, NULL, 0,
1320 NULL, (PVOID)pCDInfo, ulDataSize, &ulDataSize);
1321 DosClose( hFileCD);
1322 if(rc == NO_ERROR)
1323 return TRUE;
1325 // failed
1326 pCDInfo->usFirst = 0;
1327 pCDInfo->usCount = 0;
1328 return FALSE;
1331 /*****************************************************************************/
1332 // Determine if unit is a cdrom or not
1333 /*****************************************************************************/
1334 BOOL DriveIsCDROM(UINT uiDrive, CDInfo *pCDInfo)
1336 return (uiDrive >= pCDInfo->usFirst)
1337 && (uiDrive < (pCDInfo->usFirst + pCDInfo->usCount));
1340 /*****************************************************************************/
1341 // Determine attached fstype, e.g. HPFS for specified drive
1342 /*****************************************************************************/
1343 BOOL TxFsType // RET FS type resolved
1345 char *drive, // IN Drive specification
1346 char *fstype, // OUT Attached FS type
1347 char *details // OUT details (UNC) or NULL
1350 BOOL rc = FALSE;
1351 FSQBUFFER2 *fsinfo; // Attached FS info
1352 ULONG fsdlen = 2048; // Fs info data length
1354 strcpy(fstype, "none");
1355 if (details)
1357 strcpy(details, "");
1359 if ((fsinfo = (FSQBUFFER2*)calloc(1, fsdlen)) != NULL)
1361 if (DosQFSAttach((PCSZ)drive, 0, 1, fsinfo, &fsdlen) == NO_ERROR)
1363 strcpy(fstype, (char*) fsinfo->szName + fsinfo->cbName +1);
1364 if (details && (fsinfo->cbFSAData != 0))
1366 strcpy( details, (char*) fsinfo->szName + fsinfo->cbName +
1367 fsinfo->cbFSDName +2);
1369 rc = TRUE;
1371 free(fsinfo);
1373 return (rc);
1374 } // end 'TxFsType'
1375 /*---------------------------------------------------------------------------*/
1378 /*****************************************************************************/
1379 // Determine if a driveletter represents a removable medium/device
1380 /*****************************************************************************/
1381 BOOL TxFsIsRemovable // RET drive is removable
1383 char *drive // IN Driveletter to test
1386 BOOL rc = FALSE;
1387 DRIVECMD IOCtl;
1388 DRIVEBPB RemAt;
1389 ULONG DataLen;
1390 ULONG ParmLen;
1391 BYTE NoRem;
1393 DosError( FERR_DISABLEHARDERR); // avoid 'not ready' popups
1395 ParmLen = sizeof(IOCtl);
1396 IOCtl.cmd = TXFSDC_BLOCKR;
1397 IOCtl.drv = toupper(drive[0]) - 'A';
1398 DataLen = sizeof(NoRem);
1400 if (DosDevIOCtl((HFILE) -1, IOCTL_DISK,
1401 DSK_BLOCKREMOVABLE,
1402 &IOCtl, ParmLen, &ParmLen,
1403 &NoRem, DataLen, &DataLen) == NO_ERROR)
1405 if (NoRem) // non-removable sofar, check
1406 { // BPB as well (USB devices)
1407 ParmLen = sizeof(IOCtl);
1408 IOCtl.cmd = TXFSDC_GETBPB;
1409 IOCtl.drv = toupper(drive[0]) - 'A';
1410 DataLen = sizeof(RemAt);
1412 if (DosDevIOCtl((HFILE) -1, IOCTL_DISK,
1413 DSK_GETDEVICEPARAMS,
1414 &IOCtl, ParmLen, &ParmLen,
1415 &RemAt, DataLen, &DataLen) == NO_ERROR)
1418 if (RemAt.attributes & TXFSBPB_REMOVABLE)
1420 rc = TRUE; // removable, probably USB
1424 else
1426 rc = TRUE; // removable block device
1429 DosError( FERR_ENABLEHARDERR); // enable criterror handler
1430 return (rc);
1431 } // end 'TxFsIsRemovable'
1432 /*---------------------------------------------------------------------------*/
1434 static oslFileError get_drive_type(const char* path, oslVolumeInfo* pInfo)
1436 char Drive_Letter = toupper( *path);
1437 char fstype[ 64];
1439 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
1441 // check for floppy A/B
1442 BYTE nFloppies;
1443 APIRET rc;
1444 rc = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY );
1445 if ((Drive_Letter - 'A') < nFloppies) {
1446 pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
1447 pInfo->uAttributes |= osl_Volume_Attribute_FloppyDisk;
1448 return osl_File_E_None;
1451 // query system for CD drives
1452 CDInfo cdInfo;
1453 GetCDInfo(&cdInfo);
1455 // query if drive is a CDROM
1456 if (DriveIsCDROM( Drive_Letter - 'A', &cdInfo))
1457 pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
1459 if (TxFsIsRemovable( (char*)path))
1460 pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
1462 if (TxFsType( (char*)path, fstype, NULL) == FALSE) {
1463 // query failed, assume fixed disk
1464 pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
1465 return osl_File_E_None;
1468 //- Note, connected Win-NT drives use the REAL FS-name like NTFS!
1469 if ((strncasecmp( fstype, "LAN", 3) == 0) //- OS/2 LAN drives
1470 || (strncasecmp( fstype, "NDFS", 4) == 0) //- NetDrive
1471 || (strncasecmp( fstype, "REMOTE", 5) == 0) ) //- NT disconnected
1472 pInfo->uAttributes |= osl_Volume_Attribute_Remote;
1473 else if (strncasecmp( fstype, "RAMFS", 5) == 0)
1474 pInfo->uAttributes |= osl_Volume_Attribute_RAMDisk;
1475 else if ((strncasecmp( fstype, "CD", 2) == 0) // OS2:CDFS, DOS/WIN:CDROM
1476 || (strncasecmp( fstype, "UDF", 3) == 0) ) // OS2:UDF DVD's
1477 pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
1478 else
1479 pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
1481 return osl_File_E_None;
1484 //#############################################
1485 inline bool is_volume_space_info_request(sal_uInt32 field_mask)
1487 return (field_mask &
1488 (osl_VolumeInfo_Mask_TotalSpace |
1489 osl_VolumeInfo_Mask_UsedSpace |
1490 osl_VolumeInfo_Mask_FreeSpace));
1493 //#############################################
1494 static void get_volume_space_information(const char* path, oslVolumeInfo *pInfo)
1496 FSALLOCATE aFSInfoBuf;
1497 ULONG nDriveNumber = toupper( *path) - 'A' + 1;
1499 // disable error popups
1500 DosError(FERR_DISABLEHARDERR);
1501 APIRET rc = DosQueryFSInfo( nDriveNumber, FSIL_ALLOC,
1502 &aFSInfoBuf, sizeof(aFSInfoBuf) );
1503 // enable error popups
1504 DosError(FERR_ENABLEHARDERR);
1505 if (!rc)
1507 uint64_t aBytesPerCluster( uint64_t(aFSInfoBuf.cbSector) *
1508 uint64_t(aFSInfoBuf.cSectorUnit) );
1509 pInfo->uFreeSpace = aBytesPerCluster * uint64_t(aFSInfoBuf.cUnitAvail);
1510 pInfo->uTotalSpace = aBytesPerCluster * uint64_t(aFSInfoBuf.cUnit);
1511 pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
1512 pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace |
1513 osl_VolumeInfo_Mask_UsedSpace |
1514 osl_VolumeInfo_Mask_FreeSpace;
1518 //#############################################
1519 inline bool is_filesystem_attributes_request(sal_uInt32 field_mask)
1521 return (field_mask &
1522 (osl_VolumeInfo_Mask_MaxNameLength |
1523 osl_VolumeInfo_Mask_MaxPathLength |
1524 osl_VolumeInfo_Mask_FileSystemName |
1525 osl_VolumeInfo_Mask_FileSystemCaseHandling));
1528 //#############################################
1529 inline bool is_drivetype_request(sal_uInt32 field_mask)
1531 return (field_mask & osl_VolumeInfo_Mask_Attributes);
1534 typedef struct _FSQBUFFER_
1536 FSQBUFFER2 aBuf;
1537 UCHAR sBuf[64];
1538 } FSQBUFFER_;
1540 //#############################################
1541 static oslFileError get_filesystem_attributes(const char* path, sal_uInt32 field_mask, oslVolumeInfo* pInfo)
1543 pInfo->uAttributes = 0;
1545 oslFileError osl_error = osl_File_E_None;
1547 // osl_get_drive_type must be called first because
1548 // this function resets osl_VolumeInfo_Mask_Attributes
1549 // on failure
1550 if (is_drivetype_request(field_mask))
1551 osl_error = get_drive_type(path, pInfo);
1553 if ((osl_File_E_None == osl_error) && is_filesystem_attributes_request(field_mask))
1555 FSQBUFFER_ aBuf;
1556 ULONG nBufLen;
1557 APIRET nRet;
1559 nBufLen = sizeof( aBuf );
1560 // disable error popups
1561 DosError(FERR_DISABLEHARDERR);
1562 nRet = DosQueryFSAttach( (PCSZ)path, 0, FSAIL_QUERYNAME, (_FSQBUFFER2*) &aBuf, &nBufLen );
1563 if ( !nRet )
1565 char *pType = (char*)(aBuf.aBuf.szName + aBuf.aBuf.cbName + 1);
1566 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
1567 pInfo->uMaxNameLength = _MAX_FNAME;
1569 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
1570 pInfo->uMaxPathLength = _MAX_PATH;
1572 pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
1573 rtl_uString_newFromAscii(&pInfo->ustrFileSystemName, pType);
1575 // case is preserved always except for FAT
1576 if (strcmp( pType, "FAT" ))
1577 pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
1579 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
1581 // enable error popups
1582 DosError(FERR_ENABLEHARDERR);
1584 return osl_error;
1587 oslFileError SAL_CALL osl_getVolumeInformation( rtl_uString* ustrDirectoryURL, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask )
1589 char volume_root[PATH_MAX];
1590 oslFileError error;
1592 OSL_ASSERT( ustrDirectoryURL );
1593 OSL_ASSERT( pInfo );
1595 /* convert directory url to system path */
1596 error = FileURLToPath( volume_root, PATH_MAX, ustrDirectoryURL );
1597 if( error != osl_File_E_None )
1598 return error;
1600 if (!pInfo)
1601 return osl_File_E_INVAL;
1603 pInfo->uValidFields = 0;
1605 if ((error = get_filesystem_attributes(volume_root, uFieldMask, pInfo)) != osl_File_E_None)
1606 return error;
1608 if (is_volume_space_info_request(uFieldMask))
1609 get_volume_space_information(volume_root, pInfo);
1611 if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
1613 pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
1614 rtl_uString* uVolumeRoot;
1615 rtl_uString_newFromAscii( &uVolumeRoot, volume_root);
1616 osl_getFileURLFromSystemPath( uVolumeRoot, (rtl_uString**)&pInfo->pDeviceHandle);
1617 rtl_uString_release( uVolumeRoot);
1620 return osl_File_E_None;
1623 /****************************************************************************/
1624 /* osl_getFileStatus */
1625 /****************************************************************************/
1626 static oslFileError _osl_getDriveInfo(
1627 oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask)
1629 DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
1630 sal_Unicode cDrive[3];
1631 sal_Unicode cRoot[4];
1633 if ( !pItemImpl )
1634 return osl_File_E_INVAL;
1636 pStatus->uValidFields = 0;
1638 cDrive[0] = pItemImpl->ustrDrive->buffer[0];
1639 cDrive[1] = (sal_Unicode)':';
1640 cDrive[2] = 0;
1641 cRoot[0] = pItemImpl->ustrDrive->buffer[0];
1642 cRoot[1] = (sal_Unicode)':';
1643 cRoot[2] = 0;
1645 if ( uFieldMask & osl_FileStatus_Mask_FileName )
1647 if ( pItemImpl->ustrDrive->buffer[0] == '\\' &&
1648 pItemImpl->ustrDrive->buffer[1] == '\\' )
1650 LPCWSTR lpFirstBkSlash = wcschr( (const wchar_t*)&pItemImpl->ustrDrive->buffer[2], '\\' );
1652 if ( lpFirstBkSlash && lpFirstBkSlash[1] )
1654 LPCWSTR lpLastBkSlash = wcschr( (const wchar_t*)&lpFirstBkSlash[1], '\\' );
1656 if ( lpLastBkSlash )
1657 rtl_uString_newFromStr_WithLength( &pStatus->ustrFileName, (sal_Unicode*)&lpFirstBkSlash[1], lpLastBkSlash - lpFirstBkSlash - 1 );
1658 else
1659 rtl_uString_newFromStr( &pStatus->ustrFileName, (sal_Unicode*)&lpFirstBkSlash[1] );
1660 pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1663 else
1665 FSINFO aFSInfoBuf;
1666 ULONG ulFSInfoLevel = FSIL_VOLSER;
1667 ULONG nDriveNumber;
1668 char szFileName[ _MAX_PATH];
1670 nDriveNumber = toupper(*cDrive) - 'A' + 1;
1671 memset( &aFSInfoBuf, 0, sizeof(FSINFO) );
1672 // disable error popups
1673 DosError(FERR_DISABLEHARDERR);
1674 APIRET rc = DosQueryFSInfo( nDriveNumber, ulFSInfoLevel, &aFSInfoBuf, sizeof(FSINFO) );
1675 // enable error popups
1676 DosError(FERR_ENABLEHARDERR);
1677 memset( szFileName, 0, sizeof( szFileName));
1678 *szFileName = toupper(*cDrive);
1679 strcat( szFileName, ": [");
1680 if ( !rc || aFSInfoBuf.vol.cch)
1681 strncat( szFileName, aFSInfoBuf.vol.szVolLabel, aFSInfoBuf.vol.cch);
1682 strcat( szFileName, "]");
1683 rtl_uString_newFromAscii( &pStatus->ustrFileName, szFileName );
1685 pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1689 pStatus->eType = osl_File_Type_Volume;
1690 pStatus->uValidFields |= osl_FileStatus_Mask_Type;
1692 if ( uFieldMask & osl_FileStatus_Mask_FileURL )
1694 rtl_uString *ustrSystemPath = NULL;
1696 rtl_uString_newFromStr( &ustrSystemPath, pItemImpl->ustrDrive->buffer );
1697 osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL );
1698 rtl_uString_release( ustrSystemPath );
1699 pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
1702 return osl_File_E_None;
1705 oslFileError SAL_CALL osl_getFileStatus(
1706 oslDirectoryItem Item,
1707 oslFileStatus *pStatus,
1708 sal_uInt32 uFieldMask )
1710 DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
1711 struct stat file_stat;
1713 if ( !pItemImpl )
1714 return osl_File_E_INVAL;
1716 if ( pItemImpl->uType == DIRECTORYITEM_DRIVE)
1717 return _osl_getDriveInfo( Item, pStatus, uFieldMask );
1719 osl::lstat(pItemImpl->ustrFilePath, file_stat);
1720 if ( uFieldMask & osl_FileStatus_Mask_Validate )
1722 uFieldMask &= ~ osl_FileStatus_Mask_Validate;
1725 /* If no fields to retrieve left ignore pStatus */
1726 if ( !uFieldMask )
1727 return osl_File_E_None;
1729 /* Otherwise, this must be a valid pointer */
1730 if ( !pStatus )
1731 return osl_File_E_INVAL;
1733 if ( pStatus->uStructSize != sizeof(oslFileStatus) )
1734 return osl_File_E_INVAL;
1736 pStatus->uValidFields = 0;
1738 /* File time stamps */
1740 if ( (uFieldMask & osl_FileStatus_Mask_ModifyTime))
1742 pStatus->aModifyTime.Seconds = file_stat.st_mtime;
1743 pStatus->aModifyTime.Nanosec = 0;
1744 pStatus->uValidFields |= osl_FileStatus_Mask_ModifyTime;
1747 if ( (uFieldMask & osl_FileStatus_Mask_AccessTime))
1749 pStatus->aAccessTime.Seconds = file_stat.st_atime;
1750 pStatus->aAccessTime.Nanosec = 0;
1751 pStatus->uValidFields |= osl_FileStatus_Mask_AccessTime;
1754 if ( (uFieldMask & osl_FileStatus_Mask_CreationTime))
1756 pStatus->aAccessTime.Seconds = file_stat.st_birthtime;
1757 pStatus->aAccessTime.Nanosec = 0;
1758 pStatus->uValidFields |= osl_FileStatus_Mask_CreationTime;
1761 /* Most of the fields are already set, regardless of requiered fields */
1763 osl_systemPathGetFileNameOrLastDirectoryPart(pItemImpl->ustrFilePath, &pStatus->ustrFileName);
1764 pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1766 if (S_ISLNK(file_stat.st_mode))
1767 pStatus->eType = osl_File_Type_Link;
1768 else if (S_ISDIR(file_stat.st_mode))
1769 pStatus->eType = osl_File_Type_Directory;
1770 else if (S_ISREG(file_stat.st_mode))
1771 pStatus->eType = osl_File_Type_Regular;
1772 else if (S_ISFIFO(file_stat.st_mode))
1773 pStatus->eType = osl_File_Type_Fifo;
1774 else if (S_ISSOCK(file_stat.st_mode))
1775 pStatus->eType = osl_File_Type_Socket;
1776 else if (S_ISCHR(file_stat.st_mode) || S_ISBLK(file_stat.st_mode))
1777 pStatus->eType = osl_File_Type_Special;
1778 else
1779 pStatus->eType = osl_File_Type_Unknown;
1781 pStatus->uValidFields |= osl_FileStatus_Mask_Type;
1783 pStatus->uAttributes = pItemImpl->d_attr;
1784 pStatus->uValidFields |= osl_FileStatus_Mask_Attributes;
1786 pStatus->uFileSize = file_stat.st_size;
1787 pStatus->uValidFields |= osl_FileStatus_Mask_FileSize;
1789 if ( uFieldMask & osl_FileStatus_Mask_LinkTargetURL )
1791 rtl_uString *ustrFullPath = NULL;
1793 rtl_uString_newFromStr( &ustrFullPath, rtl_uString_getStr(pItemImpl->ustrFilePath) );
1794 osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrLinkTargetURL );
1795 rtl_uString_release( ustrFullPath );
1797 pStatus->uValidFields |= osl_FileStatus_Mask_LinkTargetURL;
1800 if ( uFieldMask & osl_FileStatus_Mask_FileURL )
1802 rtl_uString *ustrFullPath = NULL;
1804 rtl_uString_newFromStr( &ustrFullPath, rtl_uString_getStr(pItemImpl->ustrFilePath) );
1805 osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrFileURL );
1806 rtl_uString_release( ustrFullPath );
1807 pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
1810 return osl_File_E_None;
1813 /****************************************************************************/
1814 /* osl_createDirectory */
1815 /****************************************************************************/
1817 oslFileError osl_createDirectory( rtl_uString* ustrDirectoryURL )
1819 char path[PATH_MAX];
1820 oslFileError eRet;
1821 APIRET rc;
1823 OSL_ASSERT( ustrDirectoryURL );
1825 /* convert directory url to system path */
1826 eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
1827 if( eRet != osl_File_E_None )
1828 return eRet;
1830 rc = DosCreateDir( (PCSZ)path, NULL);
1831 if (rc == ERROR_ACCESS_DENIED)
1832 rc=ERROR_FILE_EXISTS;
1834 if (!rc)
1835 eRet = osl_File_E_None;
1836 else
1837 eRet = MapError( rc);
1839 return eRet;
1842 /****************************************************************************/
1843 /* osl_removeDirectory */
1844 /****************************************************************************/
1846 oslFileError osl_removeDirectory( rtl_uString* ustrDirectoryURL )
1848 char path[PATH_MAX];
1849 oslFileError eRet;
1850 APIRET rc;
1852 OSL_ASSERT( ustrDirectoryURL );
1854 /* convert directory url to system path */
1855 eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
1856 if( eRet != osl_File_E_None )
1857 return eRet;
1859 rc = DosDeleteDir( (PCSZ)path);
1860 if (!rc)
1861 eRet = osl_File_E_None;
1862 else
1863 eRet = MapError( rc);
1865 return eRet;
1868 //#############################################
1869 int path_make_parent(sal_Unicode* path)
1871 int i = rtl_ustr_lastIndexOfChar(path, '/');
1873 if (i > 0)
1875 *(path + i) = 0;
1876 return i;
1878 else
1879 return 0;
1882 //#############################################
1883 int create_dir_with_callback(
1884 sal_Unicode* directory_path,
1885 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
1886 void* pData)
1888 int mode = S_IRWXU | S_IRWXG | S_IRWXO;
1890 if (osl::mkdir(directory_path, mode) == 0)
1892 if (aDirectoryCreationCallbackFunc)
1894 rtl::OUString url;
1895 osl::FileBase::getFileURLFromSystemPath(directory_path, url);
1896 aDirectoryCreationCallbackFunc(pData, url.pData);
1898 return 0;
1900 return errno;
1903 //#############################################
1904 oslFileError create_dir_recursively_(
1905 sal_Unicode* dir_path,
1906 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
1907 void* pData)
1909 OSL_PRECOND((rtl_ustr_getLength(dir_path) > 0) && ((dir_path + (rtl_ustr_getLength(dir_path) - 1)) != (dir_path + rtl_ustr_lastIndexOfChar(dir_path, '/'))), \
1910 "Path must not end with a slash");
1912 int native_err = create_dir_with_callback(
1913 dir_path, aDirectoryCreationCallbackFunc, pData);
1915 if (native_err == 0)
1916 return osl_File_E_None;
1918 if (native_err != ENOENT)
1919 return oslTranslateFileError(OSL_FET_ERROR, native_err);
1921 // we step back until '/a_dir' at maximum because
1922 // we should get an error unequal ENOENT when
1923 // we try to create 'a_dir' at '/' and would so
1924 // return before
1925 int pos = path_make_parent(dir_path);
1927 oslFileError osl_error = create_dir_recursively_(
1928 dir_path, aDirectoryCreationCallbackFunc, pData);
1930 if (osl_File_E_None != osl_error)
1931 return osl_error;
1933 dir_path[pos] = '/';
1935 return create_dir_recursively_(dir_path, aDirectoryCreationCallbackFunc, pData);
1938 //#######################################
1939 oslFileError SAL_CALL osl_createDirectoryPath(
1940 rtl_uString* aDirectoryUrl,
1941 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
1942 void* pData)
1944 if (aDirectoryUrl == NULL)
1945 return osl_File_E_INVAL;
1947 rtl::OUString sys_path;
1948 oslFileError osl_error = osl_getSystemPathFromFileURL_Ex(
1949 aDirectoryUrl, &sys_path.pData, sal_False);
1951 if (osl_error != osl_File_E_None)
1952 return osl_error;
1954 osl::systemPathRemoveSeparator(sys_path);
1956 // const_cast because sys_path is a local copy which we want to modify inplace instead of
1957 // coyp it into another buffer on the heap again
1958 return create_dir_recursively_(sys_path.pData->buffer, aDirectoryCreationCallbackFunc, pData);
1961 /****************************************************************************/
1962 /* osl_getCanonicalName */
1963 /****************************************************************************/
1965 oslFileError osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uString** pustrValidURL )
1967 OSL_ENSURE(sal_False, "osl_getCanonicalName not implemented");
1969 rtl_uString_newFromString(pustrValidURL, ustrFileURL);
1970 return osl_File_E_None;
1974 /****************************************************************************/
1975 /* osl_setFileAttributes */
1976 /****************************************************************************/
1978 oslFileError osl_setFileAttributes( rtl_uString* ustrFileURL, sal_uInt64 uAttributes )
1980 char path[PATH_MAX];
1981 oslFileError eRet;
1982 FILESTATUS3 fsts3ConfigInfo;
1983 ULONG ulBufSize = sizeof(FILESTATUS3);
1984 APIRET rc = NO_ERROR;
1986 OSL_ASSERT( ustrFileURL );
1988 /* convert file url to system path */
1989 eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
1990 if( eRet != osl_File_E_None )
1991 return eRet;
1993 /* query current attributes */
1994 rc = DosQueryPathInfo( (PCSZ)path, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize);
1995 if (rc != NO_ERROR)
1996 return MapError( rc);
1998 /* set/reset readonly/hidden (see w32\file.cxx) */
1999 fsts3ConfigInfo.attrFile &= ~(FILE_READONLY | FILE_HIDDEN);
2000 if ( uAttributes & osl_File_Attribute_ReadOnly )
2001 fsts3ConfigInfo.attrFile |= FILE_READONLY;
2002 if ( uAttributes & osl_File_Attribute_Hidden )
2003 fsts3ConfigInfo.attrFile |= FILE_HIDDEN;
2005 /* write new attributes */
2006 rc = DosSetPathInfo( (PCSZ)path, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize, 0);
2007 if (rc != NO_ERROR)
2008 return MapError( rc);
2010 /* everything ok */
2011 return osl_File_E_None;
2014 /****************************************************************************/
2015 /* osl_setFileTime */
2016 /****************************************************************************/
2018 oslFileError osl_setFileTime( rtl_uString* ustrFileURL, const TimeValue* pCreationTime,
2019 const TimeValue* pLastAccessTime, const TimeValue* pLastWriteTime )
2021 char path[PATH_MAX];
2022 oslFileError eRet;
2024 OSL_ASSERT( ustrFileURL );
2026 /* convert file url to system path */
2027 eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
2028 if( eRet != osl_File_E_None )
2029 return eRet;
2031 return osl_psz_setFileTime( path, pCreationTime, pLastAccessTime, pLastWriteTime );
2034 /******************************************************************************
2036 * Exported Module Functions
2037 * (independent of C or Unicode Strings)
2039 *****************************************************************************/
2042 /*******************************************
2043 osl_readFile
2044 ********************************************/
2046 oslFileError osl_readFile(oslFileHandle Handle, void* pBuffer, sal_uInt64 uBytesRequested, sal_uInt64* pBytesRead)
2048 ssize_t nBytes = 0;
2049 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
2051 if ((0 == pHandleImpl) || (pHandleImpl->fd < 0) || (0 == pBuffer) || (0 == pBytesRead))
2052 return osl_File_E_INVAL;
2054 nBytes = read(pHandleImpl->fd, pBuffer, uBytesRequested);
2056 if (-1 == nBytes)
2057 return oslTranslateFileError(OSL_FET_ERROR, errno);
2059 *pBytesRead = nBytes;
2060 return osl_File_E_None;
2063 /*******************************************
2064 osl_writeFile
2065 ********************************************/
2067 oslFileError osl_writeFile(oslFileHandle Handle, const void* pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64* pBytesWritten)
2069 ssize_t nBytes = 0;
2070 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
2072 OSL_ASSERT(pHandleImpl);
2073 OSL_ASSERT(pBuffer);
2074 OSL_ASSERT(pBytesWritten);
2076 if ((0 == pHandleImpl) || (0 == pBuffer) || (0 == pBytesWritten))
2077 return osl_File_E_INVAL;
2079 OSL_ASSERT(pHandleImpl->fd >= 0);
2081 if (pHandleImpl->fd < 0)
2082 return osl_File_E_INVAL;
2084 nBytes = write(pHandleImpl->fd, pBuffer, uBytesToWrite);
2086 if (-1 == nBytes)
2087 return oslTranslateFileError(OSL_FET_ERROR, errno);
2089 *pBytesWritten = nBytes;
2090 return osl_File_E_None;
2093 /*******************************************
2094 osl_writeFile
2095 ********************************************/
2097 oslFileError osl_setFilePos( oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uPos )
2099 oslFileHandleImpl* pHandleImpl=0;
2100 int nRet=0;
2101 off_t nOffset=0;
2103 pHandleImpl = (oslFileHandleImpl*) Handle;
2104 if ( pHandleImpl == 0 )
2106 return osl_File_E_INVAL;
2109 if ( pHandleImpl->fd < 0 )
2111 return osl_File_E_INVAL;
2114 /* FIXME mfe: setFilePos: Do we have any runtime function to determine LONG_MAX? */
2115 if ( uPos > LONG_MAX )
2117 return osl_File_E_OVERFLOW;
2120 nOffset=(off_t)uPos;
2122 switch(uHow)
2124 case osl_Pos_Absolut:
2125 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_SET);
2126 break;
2128 case osl_Pos_Current:
2129 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_CUR);
2130 break;
2132 case osl_Pos_End:
2133 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_END);
2134 break;
2136 default:
2137 return osl_File_E_INVAL;
2140 if ( nOffset < 0 )
2142 nRet=errno;
2143 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2146 return osl_File_E_None;
2149 /************************************************
2150 * osl_getFilePos
2151 ***********************************************/
2153 oslFileError osl_getFilePos( oslFileHandle Handle, sal_uInt64* pPos )
2155 oslFileHandleImpl* pHandleImpl=0;
2156 off_t nOffset=0;
2157 int nRet=0;
2159 pHandleImpl = (oslFileHandleImpl*) Handle;
2160 if ( pHandleImpl == 0 || pPos == 0)
2162 return osl_File_E_INVAL;
2165 if ( pHandleImpl->fd < 0 )
2167 return osl_File_E_INVAL;
2170 nOffset = lseek(pHandleImpl->fd,0,SEEK_CUR);
2172 if (nOffset < 0)
2174 nRet =errno;
2176 /* *pPos =0; */
2178 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2181 *pPos=nOffset;
2183 return osl_File_E_None;
2186 /****************************************************************************
2187 * osl_getFileSize
2188 ****************************************************************************/
2190 oslFileError osl_getFileSize( oslFileHandle Handle, sal_uInt64* pSize )
2192 oslFileHandleImpl* pHandleImpl=(oslFileHandleImpl*) Handle;
2193 if (pHandleImpl == 0)
2194 return osl_File_E_INVAL;
2196 struct stat file_stat;
2197 if (fstat(pHandleImpl->fd, &file_stat) == -1)
2198 return oslTranslateFileError(OSL_FET_ERROR, errno);
2200 *pSize = file_stat.st_size;
2201 return osl_File_E_None;
2204 /************************************************
2205 * osl_setFileSize
2206 ***********************************************/
2208 oslFileError osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize )
2210 oslFileHandleImpl* pHandleImpl=0;
2211 off_t nOffset=0;
2213 pHandleImpl = (oslFileHandleImpl*) Handle;
2214 if ( pHandleImpl == 0 )
2216 return osl_File_E_INVAL;
2219 if ( pHandleImpl->fd < 0 )
2221 return osl_File_E_INVAL;
2224 /* FIXME: mfe: setFileSize: Do we have any runtime function to determine LONG_MAX? */
2225 if ( uSize > LONG_MAX )
2227 return osl_File_E_OVERFLOW;
2230 nOffset = (off_t)uSize;
2231 if (ftruncate (pHandleImpl->fd, nOffset) < 0)
2233 /* Failure. Try fallback algorithm */
2234 oslFileError result;
2235 struct stat aStat;
2236 off_t nCurPos;
2238 /* Save original result */
2239 result = oslTranslateFileError (OSL_FET_ERROR, errno);
2240 PERROR("ftruncate", "Try osl_setFileSize [fallback]\n");
2242 /* Check against current size. Fail upon 'shrink' */
2243 if (fstat (pHandleImpl->fd, &aStat) < 0)
2245 PERROR("ftruncate: fstat", "Out osl_setFileSize [error]\n");
2246 return (result);
2248 if ((0 <= nOffset) && (nOffset <= aStat.st_size))
2250 /* Failure upon 'shrink'. Return original result */
2251 return (result);
2254 /* Save current position */
2255 nCurPos = (off_t)lseek (pHandleImpl->fd, (off_t)0, SEEK_CUR);
2256 if (nCurPos == (off_t)(-1))
2258 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
2259 return (result);
2262 /* Try 'expand' via 'lseek()' and 'write()' */
2263 if (lseek (pHandleImpl->fd, (off_t)(nOffset - 1), SEEK_SET) < 0)
2265 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
2266 return (result);
2268 if (write (pHandleImpl->fd, (char*)"", (size_t)1) < 0)
2270 /* Failure. Restore saved position */
2271 PERROR("ftruncate: write", "Out osl_setFileSize [error]\n");
2272 if (lseek (pHandleImpl->fd, (off_t)nCurPos, SEEK_SET) < 0)
2274 #ifdef DEBUG_OSL_FILE
2275 perror("ftruncate: lseek");
2276 #endif /* DEBUG_OSL_FILE */
2278 return (result);
2281 /* Success. Restore saved position */
2282 if (lseek (pHandleImpl->fd, (off_t)nCurPos, SEEK_SET) < 0)
2284 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]");
2285 return (result);
2289 return (osl_File_E_None);
2292 /*###############################################*/
2293 oslFileError SAL_CALL osl_syncFile(oslFileHandle Handle)
2295 oslFileHandleImpl* handle_impl = (oslFileHandleImpl*)Handle;
2297 if (handle_impl == 0)
2298 return osl_File_E_INVAL;
2300 if (fsync(handle_impl->fd) == -1)
2301 return oslTranslateFileError(OSL_FET_ERROR, errno);
2303 return osl_File_E_None;
2306 /******************************************************************************
2308 * C-String Versions of Exported Module Functions
2310 *****************************************************************************/
2312 #ifdef HAVE_STATFS_H
2314 #if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
2315 # define __OSL_STATFS_STRUCT struct statfs
2316 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
2317 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
2318 # define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
2319 # define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
2321 /* always return true if queried for the properties of
2322 the file system. If you think this is wrong under any
2323 of the target platforms fix it!!!! */
2324 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2325 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2326 #endif /* FREEBSD || NETBSD */
2328 #if defined(LINUX)
2329 # define __OSL_NFS_SUPER_MAGIC 0x6969
2330 # define __OSL_SMB_SUPER_MAGIC 0x517B
2331 # define __OSL_MSDOS_SUPER_MAGIC 0x4d44
2332 # define __OSL_NTFS_SUPER_MAGIC 0x5346544e
2333 # define __OSL_STATFS_STRUCT struct statfs
2334 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
2335 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
2336 # define __OSL_STATFS_IS_NFS(a) (__OSL_NFS_SUPER_MAGIC == (a).f_type)
2337 # define __OSL_STATFS_IS_SMB(a) (__OSL_SMB_SUPER_MAGIC == (a).f_type)
2338 # define __OSL_STATFS_ISREMOTE(a) (__OSL_STATFS_IS_NFS((a)) || __OSL_STATFS_IS_SMB((a)))
2339 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type) && (__OSL_NTFS_SUPER_MAGIC != (a).f_type))
2340 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type))
2341 #endif /* LINUX */
2343 #if defined(SOLARIS)
2344 # define __OSL_STATFS_STRUCT struct statvfs
2345 # define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
2346 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
2347 # define __OSL_STATFS_TYPENAME(a) ((a).f_basetype)
2348 # define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
2350 /* always return true if queried for the properties of
2351 the file system. If you think this is wrong under any
2352 of the target platforms fix it!!!! */
2353 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2354 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2355 #endif /* SOLARIS */
2357 # define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
2359 #else /* no statfs available */
2361 # define __OSL_STATFS_STRUCT struct dummy {int i;}
2362 # define __OSL_STATFS_INIT(a) ((void)0)
2363 # define __OSL_STATFS(dir, sfs) (1)
2364 # define __OSL_STATFS_ISREMOTE(sfs) (0)
2365 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2366 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2367 #endif /* HAVE_STATFS_H */
2370 static oslFileError osl_psz_getVolumeInformation (
2371 const sal_Char* pszDirectory, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask)
2373 __OSL_STATFS_STRUCT sfs;
2375 if (!pInfo)
2376 return osl_File_E_INVAL;
2378 __OSL_STATFS_INIT(sfs);
2380 pInfo->uValidFields = 0;
2381 pInfo->uAttributes = 0;
2383 if ((__OSL_STATFS(pszDirectory, &sfs)) < 0)
2385 oslFileError result = oslTranslateFileError(OSL_FET_ERROR, errno);
2386 return (result);
2389 /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
2390 if (uFieldMask & osl_VolumeInfo_Mask_Attributes)
2392 if (__OSL_STATFS_ISREMOTE(sfs))
2393 pInfo->uAttributes |= osl_Volume_Attribute_Remote;
2395 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
2398 if (uFieldMask & osl_VolumeInfo_Mask_FileSystemCaseHandling)
2400 if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs))
2401 pInfo->uAttributes |= osl_Volume_Attribute_Case_Sensitive;
2403 if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs))
2404 pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
2406 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
2409 pInfo->uTotalSpace = 0;
2410 pInfo->uFreeSpace = 0;
2411 pInfo->uUsedSpace = 0;
2413 #if defined(__OSL_STATFS_BLKSIZ)
2415 if ((uFieldMask & osl_VolumeInfo_Mask_TotalSpace) ||
2416 (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
2418 pInfo->uTotalSpace = __OSL_STATFS_BLKSIZ(sfs);
2419 pInfo->uTotalSpace *= (sal_uInt64)(sfs.f_blocks);
2420 pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace;
2423 if ((uFieldMask & osl_VolumeInfo_Mask_FreeSpace) ||
2424 (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
2426 pInfo->uFreeSpace = __OSL_STATFS_BLKSIZ(sfs);
2428 if (getuid() == 0)
2429 pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bfree);
2430 else
2431 pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bavail);
2433 pInfo->uValidFields |= osl_VolumeInfo_Mask_FreeSpace;
2436 #endif /* __OSL_STATFS_BLKSIZ */
2438 if ((pInfo->uValidFields & osl_VolumeInfo_Mask_TotalSpace) &&
2439 (pInfo->uValidFields & osl_VolumeInfo_Mask_FreeSpace ))
2441 pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
2442 pInfo->uValidFields |= osl_VolumeInfo_Mask_UsedSpace;
2445 pInfo->uMaxNameLength = 0;
2446 if (uFieldMask & osl_VolumeInfo_Mask_MaxNameLength)
2448 long nLen = pathconf(pszDirectory, _PC_NAME_MAX);
2449 if (nLen > 0)
2451 pInfo->uMaxNameLength = (sal_uInt32)nLen;
2452 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
2456 pInfo->uMaxPathLength = 0;
2457 if (uFieldMask & osl_VolumeInfo_Mask_MaxPathLength)
2459 long nLen = pathconf (pszDirectory, _PC_PATH_MAX);
2460 if (nLen > 0)
2462 pInfo->uMaxPathLength = (sal_uInt32)nLen;
2463 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
2467 #if defined(__OSL_STATFS_TYPENAME)
2469 if (uFieldMask & osl_VolumeInfo_Mask_FileSystemName)
2471 rtl_string2UString(
2472 &(pInfo->ustrFileSystemName),
2473 __OSL_STATFS_TYPENAME(sfs),
2474 rtl_str_getLength(__OSL_STATFS_TYPENAME(sfs)),
2475 osl_getThreadTextEncoding(),
2476 OUSTRING_TO_OSTRING_CVTFLAGS);
2477 OSL_ASSERT(pInfo->ustrFileSystemName != 0);
2479 pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
2482 #endif /* __OSL_STATFS_TYPENAME */
2484 if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
2486 /* FIXME: check also entries in mntent for the device
2487 and fill it with correct values */
2489 *pInfo->pDeviceHandle = osl_isFloppyDrive(pszDirectory);
2491 if (*pInfo->pDeviceHandle)
2493 pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
2494 pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
2495 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
2498 return osl_File_E_None;
2501 /******************************************
2502 * osl_psz_setFileTime
2503 *****************************************/
2505 static oslFileError osl_psz_setFileTime( const sal_Char* pszFilePath,
2506 const TimeValue* /*pCreationTime*/,
2507 const TimeValue* pLastAccessTime,
2508 const TimeValue* pLastWriteTime )
2510 int nRet=0;
2511 struct utimbuf aTimeBuffer;
2512 struct stat aFileStat;
2513 #ifdef DEBUG_OSL_FILE
2514 struct tm* pTM=0;
2515 #endif
2517 nRet = lstat(pszFilePath,&aFileStat);
2519 if ( nRet < 0 )
2521 nRet=errno;
2522 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2525 #ifdef DEBUG_OSL_FILE
2526 fprintf(stderr,"File Times are (in localtime):\n");
2527 pTM=localtime(&aFileStat.st_ctime);
2528 fprintf(stderr,"CreationTime is '%s'\n",asctime(pTM));
2529 pTM=localtime(&aFileStat.st_atime);
2530 fprintf(stderr,"AccessTime is '%s'\n",asctime(pTM));
2531 pTM=localtime(&aFileStat.st_mtime);
2532 fprintf(stderr,"Modification is '%s'\n",asctime(pTM));
2534 fprintf(stderr,"File Times are (in UTC):\n");
2535 fprintf(stderr,"CreationTime is '%s'\n",ctime(&aFileStat.st_ctime));
2536 fprintf(stderr,"AccessTime is '%s'\n",ctime(&aTimeBuffer.actime));
2537 fprintf(stderr,"Modification is '%s'\n",ctime(&aTimeBuffer.modtime));
2538 #endif
2540 if ( pLastAccessTime != 0 )
2542 aTimeBuffer.actime=pLastAccessTime->Seconds;
2544 else
2546 aTimeBuffer.actime=aFileStat.st_atime;
2549 if ( pLastWriteTime != 0 )
2551 aTimeBuffer.modtime=pLastWriteTime->Seconds;
2553 else
2555 aTimeBuffer.modtime=aFileStat.st_mtime;
2558 /* mfe: Creation time not used here! */
2560 #ifdef DEBUG_OSL_FILE
2561 fprintf(stderr,"File Times are (in localtime):\n");
2562 pTM=localtime(&aFileStat.st_ctime);
2563 fprintf(stderr,"CreationTime now '%s'\n",asctime(pTM));
2564 pTM=localtime(&aTimeBuffer.actime);
2565 fprintf(stderr,"AccessTime now '%s'\n",asctime(pTM));
2566 pTM=localtime(&aTimeBuffer.modtime);
2567 fprintf(stderr,"Modification now '%s'\n",asctime(pTM));
2569 fprintf(stderr,"File Times are (in UTC):\n");
2570 fprintf(stderr,"CreationTime now '%s'\n",ctime(&aFileStat.st_ctime));
2571 fprintf(stderr,"AccessTime now '%s'\n",ctime(&aTimeBuffer.actime));
2572 fprintf(stderr,"Modification now '%s'\n",ctime(&aTimeBuffer.modtime));
2573 #endif
2575 nRet=utime(pszFilePath,&aTimeBuffer);
2576 if ( nRet < 0 )
2578 nRet=errno;
2579 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2582 return osl_File_E_None;
2586 /*****************************************
2587 * osl_psz_removeFile
2588 ****************************************/
2589 #if 0
2590 static oslFileError osl_psz_removeFile( const sal_Char* pszPath )
2592 int nRet=0;
2593 struct stat aStat;
2595 nRet = stat(pszPath,&aStat);
2596 if ( nRet < 0 )
2598 nRet=errno;
2599 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2602 if ( S_ISDIR(aStat.st_mode) )
2604 return osl_File_E_ISDIR;
2607 nRet = unlink(pszPath);
2608 if ( nRet < 0 )
2610 nRet=errno;
2611 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2614 return osl_File_E_None;
2616 #endif
2618 /*****************************************
2619 * osl_psz_createDirectory
2620 ****************************************/
2621 #if 0
2622 static oslFileError osl_psz_createDirectory( const sal_Char* pszPath )
2624 int nRet=0;
2625 int mode = S_IRWXU | S_IRWXG | S_IRWXO;
2627 nRet = mkdir(pszPath,mode);
2629 if ( nRet < 0 )
2631 nRet=errno;
2632 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2635 return osl_File_E_None;
2637 #endif
2638 /*****************************************
2639 * osl_psz_removeDirectory
2640 ****************************************/
2641 #if 0
2642 static oslFileError osl_psz_removeDirectory( const sal_Char* pszPath )
2644 int nRet=0;
2646 nRet = rmdir(pszPath);
2648 if ( nRet < 0 )
2650 nRet=errno;
2651 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2654 return osl_File_E_None;
2656 #endif
2657 /*****************************************
2658 * oslDoMoveFile
2659 ****************************************/
2660 #if 0
2661 static oslFileError oslDoMoveFile( const sal_Char* pszPath, const sal_Char* pszDestPath)
2663 oslFileError tErr=osl_File_E_invalidError;
2665 tErr = osl_psz_moveFile(pszPath,pszDestPath);
2666 if ( tErr == osl_File_E_None )
2668 return tErr;
2671 if ( tErr != osl_File_E_XDEV )
2673 return tErr;
2676 tErr=osl_psz_copyFile(pszPath,pszDestPath);
2678 if ( tErr != osl_File_E_None )
2680 oslFileError tErrRemove;
2681 tErrRemove=osl_psz_removeFile(pszDestPath);
2682 return tErr;
2685 tErr=osl_psz_removeFile(pszPath);
2687 return tErr;
2689 #endif
2690 /*****************************************
2691 * osl_psz_moveFile
2692 ****************************************/
2693 #if 0
2694 static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath)
2697 int nRet = 0;
2699 nRet = rename(pszPath,pszDestPath);
2701 if ( nRet < 0 )
2703 nRet=errno;
2704 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2707 return osl_File_E_None;
2709 #endif
2710 /*****************************************
2711 * osl_psz_copyFile
2712 ****************************************/
2713 #if 0
2714 static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
2716 time_t nAcTime=0;
2717 time_t nModTime=0;
2718 uid_t nUID=0;
2719 gid_t nGID=0;
2720 int nRet=0;
2721 mode_t nMode=0;
2722 struct stat aFileStat;
2723 oslFileError tErr=osl_File_E_invalidError;
2724 size_t nSourceSize=0;
2725 int DestFileExists=1;
2727 /* mfe: does the source file really exists? */
2728 nRet = lstat(pszPath,&aFileStat);
2730 if ( nRet < 0 )
2732 nRet=errno;
2733 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2736 /* mfe: we do only copy files here! */
2737 if ( S_ISDIR(aFileStat.st_mode) )
2739 return osl_File_E_ISDIR;
2742 nSourceSize=(size_t)aFileStat.st_size;
2743 nMode=aFileStat.st_mode;
2744 nAcTime=aFileStat.st_atime;
2745 nModTime=aFileStat.st_mtime;
2746 nUID=aFileStat.st_uid;
2747 nGID=aFileStat.st_gid;
2749 nRet = stat(pszDestPath,&aFileStat);
2750 if ( nRet < 0 )
2752 nRet=errno;
2754 if ( nRet == ENOENT )
2756 DestFileExists=0;
2758 /* return oslTranslateFileError(nRet);*/
2761 /* mfe: the destination file must not be a directory! */
2762 if ( nRet == 0 && S_ISDIR(aFileStat.st_mode) )
2764 return osl_File_E_ISDIR;
2766 else
2768 /* mfe: file does not exists or is no dir */
2771 tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
2773 if ( tErr != osl_File_E_None )
2775 return tErr;
2779 * mfe: ignore return code
2780 * since only the success of the copy is
2781 * important
2783 oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
2785 return tErr;
2787 #endif
2789 /******************************************************************************
2791 * Utility Functions
2793 *****************************************************************************/
2796 /*****************************************
2797 * oslMakeUStrFromPsz
2798 ****************************************/
2800 rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr, rtl_uString** ustrValid)
2802 rtl_string2UString(
2803 ustrValid,
2804 pszStr,
2805 rtl_str_getLength( pszStr ),
2806 osl_getThreadTextEncoding(),
2807 OUSTRING_TO_OSTRING_CVTFLAGS );
2808 OSL_ASSERT(*ustrValid != 0);
2810 return *ustrValid;
2813 /*****************************************************************************
2814 * UnicodeToText
2815 * converting unicode to text manually saves us the penalty of a temporary
2816 * rtl_String object.
2817 ****************************************************************************/
2819 int UnicodeToText( char * buffer, size_t bufLen, const sal_Unicode * uniText, sal_Int32 uniTextLen )
2821 rtl_UnicodeToTextConverter hConverter;
2822 sal_uInt32 nInfo;
2823 sal_Size nSrcChars, nDestBytes;
2825 /* stolen from rtl/string.c */
2826 hConverter = rtl_createUnicodeToTextConverter( osl_getThreadTextEncoding() );
2828 nDestBytes = rtl_convertUnicodeToText( hConverter, 0, uniText, uniTextLen,
2829 buffer, bufLen,
2830 OUSTRING_TO_OSTRING_CVTFLAGS | RTL_UNICODETOTEXT_FLAGS_FLUSH,
2831 &nInfo, &nSrcChars );
2833 rtl_destroyUnicodeToTextConverter( hConverter );
2835 if( nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
2837 errno = EOVERFLOW;
2838 return 0;
2841 /* ensure trailing '\0' */
2842 buffer[nDestBytes] = '\0';
2844 return nDestBytes;
2847 /*****************************************************************************
2848 TextToUnicode
2850 @param text
2851 The text to convert.
2853 @param text_buffer_size
2854 The number of characters.
2856 @param unic_text
2857 The unicode buffer.
2859 @param unic_text_buffer_size
2860 The size in characters of the unicode buffer.
2862 ****************************************************************************/
2864 int TextToUnicode(
2865 const char* text,
2866 size_t text_buffer_size,
2867 sal_Unicode* unic_text,
2868 sal_Int32 unic_text_buffer_size)
2870 rtl_TextToUnicodeConverter hConverter;
2871 sal_uInt32 nInfo;
2872 sal_Size nSrcChars;
2873 sal_Size nDestBytes;
2875 /* stolen from rtl/string.c */
2876 hConverter = rtl_createTextToUnicodeConverter(osl_getThreadTextEncoding());
2878 nDestBytes = rtl_convertTextToUnicode(hConverter,
2880 text, text_buffer_size,
2881 unic_text, unic_text_buffer_size,
2882 OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_FLUSH,
2883 &nInfo, &nSrcChars);
2885 rtl_destroyTextToUnicodeConverter(hConverter);
2887 if (nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL)
2889 errno = EOVERFLOW;
2890 return 0;
2893 /* ensure trailing '\0' */
2894 unic_text[nDestBytes] = '\0';
2896 return nDestBytes;
2899 /******************************************************************************
2901 * GENERIC FLOPPY FUNCTIONS
2903 *****************************************************************************/
2906 /*****************************************
2907 * osl_unmountVolumeDevice
2908 ****************************************/
2910 oslFileError osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
2912 oslFileError tErr = osl_File_E_NOSYS;
2914 tErr = osl_unmountFloppy(Handle);
2916 /* Perhaps current working directory is set to mount point */
2918 if ( tErr )
2920 sal_Char *pszHomeDir = getenv("HOME");
2922 if ( pszHomeDir && strlen( pszHomeDir ) && 0 == chdir( pszHomeDir ) )
2924 /* try again */
2926 tErr = osl_unmountFloppy(Handle);
2928 OSL_ENSURE( tErr, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
2932 return tErr;
2935 /*****************************************
2936 * osl_automountVolumeDevice
2937 ****************************************/
2939 oslFileError osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
2941 oslFileError tErr = osl_File_E_NOSYS;
2943 tErr = osl_mountFloppy(Handle);
2945 return tErr;
2948 /*****************************************
2949 * osl_getVolumeDeviceMountPath
2950 ****************************************/
2952 oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
2954 oslVolumeDeviceHandleImpl* pItem = (oslVolumeDeviceHandleImpl*) Handle;
2955 sal_Char Buffer[PATH_MAX];
2957 Buffer[0] = '\0';
2959 if ( pItem == 0 || pstrPath == 0 )
2961 return osl_File_E_INVAL;
2964 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
2966 return osl_File_E_INVAL;
2969 #ifdef DEBUG_OSL_FILE
2970 fprintf(stderr,"Handle is:\n");
2971 osl_printFloppyHandle(pItem);
2972 #endif
2974 snprintf(Buffer, sizeof(Buffer), "file://%s", pItem->pszMountPoint);
2976 #ifdef DEBUG_OSL_FILE
2977 fprintf(stderr,"Mount Point is: '%s'\n",Buffer);
2978 #endif
2980 oslMakeUStrFromPsz(Buffer, pstrPath);
2982 return osl_File_E_None;
2985 /*****************************************
2986 * osl_acquireVolumeDeviceHandle
2987 ****************************************/
2989 oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
2991 oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
2993 if ( pItem == 0 )
2995 return osl_File_E_INVAL;
2998 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
3000 return osl_File_E_INVAL;
3003 ++pItem->RefCount;
3005 return osl_File_E_None;
3008 /*****************************************
3009 * osl_releaseVolumeDeviceHandle
3010 ****************************************/
3012 oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
3014 oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
3016 if ( pItem == 0 )
3018 return osl_File_E_INVAL;
3021 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
3023 return osl_File_E_INVAL;
3026 --pItem->RefCount;
3028 if ( pItem->RefCount == 0 )
3030 rtl_freeMemory(pItem);
3033 return osl_File_E_None;
3036 /*****************************************
3037 * osl_newVolumeDeviceHandleImpl
3038 ****************************************/
3040 static oslVolumeDeviceHandleImpl* osl_newVolumeDeviceHandleImpl()
3042 oslVolumeDeviceHandleImpl* pHandle;
3043 const size_t nSizeOfHandle = sizeof(oslVolumeDeviceHandleImpl);
3045 pHandle = (oslVolumeDeviceHandleImpl*) rtl_allocateMemory (nSizeOfHandle);
3046 if (pHandle != NULL)
3048 pHandle->ident[0] = 'O';
3049 pHandle->ident[1] = 'V';
3050 pHandle->ident[2] = 'D';
3051 pHandle->ident[3] = 'H';
3052 pHandle->pszMountPoint[0] = '\0';
3053 pHandle->pszFilePath[0] = '\0';
3054 pHandle->pszDevice[0] = '\0';
3055 pHandle->RefCount = 1;
3057 return pHandle;
3060 /*****************************************
3061 * osl_freeVolumeDeviceHandleImpl
3062 ****************************************/
3064 static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl* pHandle)
3066 if (pHandle != NULL)
3067 rtl_freeMemory (pHandle);
3071 /******************************************************************************
3073 * OS/2 FLOPPY FUNCTIONS
3075 *****************************************************************************/
3077 #if defined(OS2)
3078 static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath)
3080 return NULL;
3083 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
3085 return osl_File_E_BUSY;
3088 static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
3090 return osl_File_E_BUSY;
3093 static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
3095 return sal_False;
3098 static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice)
3100 return sal_False;
3104 #ifdef DEBUG_OSL_FILE
3105 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* pItem)
3107 if (pItem == 0 )
3109 fprintf(stderr,"NULL Handle\n");
3110 return;
3112 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
3114 #ifdef TRACE_OSL_FILE
3115 fprintf(stderr,"Invalid Handle]\n");
3116 #endif
3117 return;
3121 fprintf(stderr,"MountPoint : '%s'\n",pItem->pszMountPoint);
3122 fprintf(stderr,"FilePath : '%s'\n",pItem->pszFilePath);
3123 fprintf(stderr,"Device : '%s'\n",pItem->pszDevice);
3125 return;
3127 #endif
3129 #endif /* OS2 */