summaryrefslogtreecommitdiff
path: root/sal/osl/os2/file.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sal/osl/os2/file.cxx')
-rw-r--r--sal/osl/os2/file.cxx3129
1 files changed, 3129 insertions, 0 deletions
diff --git a/sal/osl/os2/file.cxx b/sal/osl/os2/file.cxx
new file mode 100644
index 000000000000..2e668d23d638
--- /dev/null
+++ b/sal/osl/os2/file.cxx
@@ -0,0 +1,3129 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+/************************************************************************
+ * ToDo
+ *
+ * Fix osl_getCanonicalName
+ *
+ * - Fix: check for corresponding struct sizes in exported functions
+ * - check size/use of oslDirectory
+ * - check size/use of oslDirectoryItem
+ * - check size/use of oslFileStatus
+ * - check size/use of oslVolumeDeviceHandle
+ * - check size/use of oslVolumeInfo
+ * - check size/use of oslFileHandle
+ ***********************************************************************/
+
+#define INCL_DOSDEVIOCTL // OS2 device definitions
+
+#include "system.h"
+#include <rtl/alloc.h>
+
+#include "osl/file.hxx"
+
+
+#include <sal/types.h>
+#include <osl/thread.h>
+#include <osl/diagnose.h>
+#include "file_error_transl.h"
+#include <osl/time.h>
+
+#ifndef _FILE_URL_H_
+#include "file_url.h"
+#endif
+
+#include "file_path_helper.hxx"
+#include "uunxapi.hxx"
+
+#ifndef _STRING_H_
+#include <string.h>
+#endif
+
+#ifndef _CTYPE_H_
+#include <ctype.h>
+#endif
+
+#ifndef _WCHAR_H_
+#include <wchar.h>
+#endif
+
+#if OSL_DEBUG_LEVEL > 1
+ extern void debug_ustring(rtl_uString*);
+#endif
+
+
+#ifdef DEBUG_OSL_FILE
+# define PERROR( a, b ) perror( a ); fprintf( stderr, b )
+#else
+# define PERROR( a, b )
+#endif
+
+extern "C" oslFileHandle osl_createFileHandleFromFD( int fd );
+
+ struct errentry errtable[] = {
+ { NO_ERROR, osl_File_E_None }, /* 0 */
+ { ERROR_INVALID_FUNCTION, osl_File_E_INVAL }, /* 1 */
+ { ERROR_FILE_NOT_FOUND, osl_File_E_NOENT }, /* 2 */
+ { ERROR_PATH_NOT_FOUND, osl_File_E_NOENT }, /* 3 */
+ { ERROR_TOO_MANY_OPEN_FILES, osl_File_E_MFILE }, /* 4 */
+ { ERROR_ACCESS_DENIED, osl_File_E_ACCES }, /* 5 */
+ { ERROR_INVALID_HANDLE, osl_File_E_BADF }, /* 6 */
+ { ERROR_ARENA_TRASHED, osl_File_E_NOMEM }, /* 7 */
+ { ERROR_NOT_ENOUGH_MEMORY, osl_File_E_NOMEM }, /* 8 */
+ { ERROR_INVALID_BLOCK, osl_File_E_NOMEM }, /* 9 */
+ { ERROR_BAD_ENVIRONMENT, osl_File_E_2BIG }, /* 10 */
+ { ERROR_BAD_FORMAT, osl_File_E_NOEXEC }, /* 11 */
+ { ERROR_INVALID_ACCESS, osl_File_E_INVAL }, /* 12 */
+ { ERROR_INVALID_DATA, osl_File_E_INVAL }, /* 13 */
+ { ERROR_INVALID_DRIVE, osl_File_E_NOENT }, /* 15 */
+ { ERROR_CURRENT_DIRECTORY, osl_File_E_ACCES }, /* 16 */
+ { ERROR_NOT_SAME_DEVICE, osl_File_E_XDEV }, /* 17 */
+ { ERROR_NO_MORE_FILES, osl_File_E_NOENT }, /* 18 */
+ { ERROR_NOT_READY, osl_File_E_NOTREADY }, /* 21 */
+ { ERROR_LOCK_VIOLATION, osl_File_E_ACCES }, /* 33 */
+ { ERROR_BAD_NETPATH, osl_File_E_NOENT }, /* 53 */
+ { ERROR_NETWORK_ACCESS_DENIED, osl_File_E_ACCES }, /* 65 */
+ { ERROR_BAD_NET_NAME, osl_File_E_NOENT }, /* 67 */
+ { ERROR_FILE_EXISTS, osl_File_E_EXIST }, /* 80 */
+ { ERROR_CANNOT_MAKE, osl_File_E_ACCES }, /* 82 */
+ { ERROR_FAIL_I24, osl_File_E_ACCES }, /* 83 */
+ { ERROR_INVALID_PARAMETER, osl_File_E_INVAL }, /* 87 */
+ { ERROR_NO_PROC_SLOTS, osl_File_E_AGAIN }, /* 89 */
+ { ERROR_DRIVE_LOCKED, osl_File_E_ACCES }, /* 108 */
+ { ERROR_BROKEN_PIPE, osl_File_E_PIPE }, /* 109 */
+ { ERROR_DISK_FULL, osl_File_E_NOSPC }, /* 112 */
+ { ERROR_INVALID_TARGET_HANDLE, osl_File_E_BADF }, /* 114 */
+ { ERROR_INVALID_HANDLE, osl_File_E_INVAL }, /* 124 */
+ { ERROR_WAIT_NO_CHILDREN, osl_File_E_CHILD }, /* 128 */
+ { ERROR_CHILD_NOT_COMPLETE, osl_File_E_CHILD }, /* 129 */
+ { ERROR_DIRECT_ACCESS_HANDLE, osl_File_E_BADF }, /* 130 */
+ { ERROR_NEGATIVE_SEEK, osl_File_E_INVAL }, /* 131 */
+ { ERROR_SEEK_ON_DEVICE, osl_File_E_ACCES }, /* 132 */
+ { ERROR_DIR_NOT_EMPTY, osl_File_E_NOTEMPTY }, /* 145 */
+ { ERROR_NOT_LOCKED, osl_File_E_ACCES }, /* 158 */
+ { ERROR_BAD_PATHNAME, osl_File_E_NOENT }, /* 161 */
+ { ERROR_MAX_THRDS_REACHED, osl_File_E_AGAIN }, /* 164 */
+ { ERROR_LOCK_FAILED, osl_File_E_ACCES }, /* 167 */
+ { ERROR_ALREADY_EXISTS, osl_File_E_EXIST }, /* 183 */
+ { ERROR_FILENAME_EXCED_RANGE, osl_File_E_NOENT }, /* 206 */
+ { ERROR_NESTING_NOT_ALLOWED, osl_File_E_AGAIN }, /* 215 */
+ { ERROR_DIRECTORY, osl_File_E_NOENT }, /* 267 */
+ //{ ERROR_NOT_ENOUGH_QUOTA, osl_File_E_NOMEM } /* 1816 */
+ };
+
+ #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
+
+ //#####################################################
+ oslFileError MapError(APIRET dwError)
+ {
+ for (int i = 0; i < ELEMENTS_OF_ARRAY(errtable); ++i )
+ {
+ if (dwError == errtable[i].oscode)
+ return static_cast<oslFileError>(errtable[i].errnocode);
+ }
+ return osl_File_E_INVAL;
+ }
+
+/******************************************************************************
+ *
+ * static members
+ *
+ *****************************************************************************/
+
+static const char * pFileLockEnvVar = (char *) -1;
+
+
+/******************************************************************************
+ *
+ * C-String Function Declarations
+ *
+ *****************************************************************************/
+
+static oslFileError osl_psz_getVolumeInformation(const sal_Char* , oslVolumeInfo* pInfo, sal_uInt32 uFieldMask);
+static oslFileError osl_psz_removeFile(const sal_Char* pszPath);
+static oslFileError osl_psz_createDirectory(const sal_Char* pszPath);
+static oslFileError osl_psz_removeDirectory(const sal_Char* pszPath);
+static oslFileError osl_psz_copyFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
+static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
+static oslFileError osl_psz_setFileTime(const sal_Char* strFilePath, const TimeValue* pCreationTime, const TimeValue* pLastAccessTime, const TimeValue* pLastWriteTime);
+
+
+/******************************************************************************
+ *
+ * Static Module Utility Function Declarations
+ *
+ *****************************************************************************/
+
+static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists);
+static oslFileError oslChangeFileModes(const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID);
+static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName);
+static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode);
+static oslFileError oslDoMoveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
+rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr,rtl_uString** uStr);
+
+/******************************************************************************
+ *
+ * Non-Static Utility Function Declarations
+ *
+ *****************************************************************************/
+
+extern "C" int UnicodeToText( char *, size_t, const sal_Unicode *, sal_Int32 );
+extern "C" int TextToUnicode(
+ const char* text, size_t text_buffer_size, sal_Unicode* unic_text, sal_Int32 unic_text_buffer_size);
+
+/******************************************************************************
+ *
+ * 'removeable device' aka floppy functions
+ *
+ *****************************************************************************/
+
+static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath);
+static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy);
+static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy);
+
+#ifdef DEBUG_OSL_FILE
+static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* hFloppy);
+#endif
+
+/**********************************************
+ * _osl_openLocalRoot
+ * enumerate available drives
+ *********************************************/
+static oslFileError _osl_openLocalRoot( rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
+{
+ rtl_uString *ustrSystemPath = NULL;
+ oslFileError error;
+
+ if ( !pDirectory )
+ return osl_File_E_INVAL;
+
+ *pDirectory = NULL;
+
+ error = osl_getSystemPathFromFileURL_Ex( strDirectoryPath, &ustrSystemPath, sal_False );
+
+ if ( osl_File_E_None == error )
+ {
+ /* create and initialize impl structure */
+ DirectoryImpl* pDirImpl = (DirectoryImpl*) rtl_allocateMemory( sizeof(DirectoryImpl) );
+ if( pDirImpl )
+ {
+ ULONG ulDriveNum;
+ APIRET rc;
+ pDirImpl->uType = DIRECTORYTYPE_LOCALROOT;
+ pDirImpl->ustrPath = ustrSystemPath;
+ rc = DosQueryCurrentDisk (&ulDriveNum, &pDirImpl->ulDriveMap);
+ pDirImpl->pDirStruct = 0;
+ pDirImpl->ulNextDrive = 1;
+ pDirImpl->ulNextDriveMask = 1;
+
+ // determine number of floppy-drives
+ BYTE nFloppies;
+ rc = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY );
+ if (nFloppies == 0) {
+ // if no floppies, start with 3rd drive (C:)
+ pDirImpl->ulNextDrive = 3;
+ pDirImpl->ulNextDriveMask <<= 2;
+ } else if (nFloppies == 1) {
+ // mask drive B (second bit) in this case
+ pDirImpl->ulDriveMap &= ~0x02;
+ }
+ *pDirectory = (oslDirectory) pDirImpl;
+ return osl_File_E_None;
+ }
+ else
+ {
+ errno = osl_File_E_NOMEM;
+ }
+
+ }
+
+ rtl_uString_release( ustrSystemPath );
+ return error;
+}
+
+/**********************************************
+ * _osl_getNextDrive
+ *********************************************/
+static oslFileError SAL_CALL _osl_getNextDrive(
+ oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint )
+{
+ DirectoryImpl *pDirImpl = (DirectoryImpl *)Directory;
+ DirectoryItem_Impl *pItemImpl = NULL;
+ rtl_uString * ustrDrive = NULL;
+ BOOL fSuccess;
+ char buffer[3];
+
+ uHint = uHint; /* avoid warnings */
+
+ if ( !pItem )
+ return osl_File_E_INVAL;
+
+ *pItem = NULL;
+
+ if ( !pDirImpl )
+ return osl_File_E_INVAL;
+
+ while( pDirImpl->ulNextDrive <= 26)
+ {
+ // exit if bit==1 -> drive found
+ if (pDirImpl->ulDriveMap & pDirImpl->ulNextDriveMask) {
+
+ /* convert file name to unicode */
+ buffer[0] = '@' + pDirImpl->ulNextDrive;
+ buffer[1] = ':';
+ buffer[2] = 0;
+
+ pItemImpl = (DirectoryItem_Impl*) rtl_allocateMemory(sizeof(DirectoryItem_Impl));
+ if ( !pItemImpl )
+ return osl_File_E_NOMEM;
+
+ memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
+ pItemImpl->uType = DIRECTORYITEM_DRIVE;
+ pItemImpl->nRefCount = 1;
+
+ rtl_string2UString( &pItemImpl->ustrDrive, buffer, 3,
+ osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
+ OSL_ASSERT(pItemImpl->ustrDrive != 0);
+
+ /* use drive as directory item */
+ *pItem = (oslDirectoryItem) pItemImpl;
+ }
+ // scan next bit position
+ pDirImpl->ulNextDrive++;
+ pDirImpl->ulNextDriveMask <<= 1;
+
+ if (*pItem) // item assigned, return now.
+ return osl_File_E_None;
+ }
+
+ // no more items
+ return osl_File_E_NOENT;
+}
+
+/**********************************************
+ * _osl_readdir_impl_
+ *
+ * readdir wrapper, filters out "." and ".."
+ * on request
+ *********************************************/
+
+static struct dirent* _osl_readdir_impl_(DIR* pdir, sal_Bool bFilterLocalAndParentDir)
+{
+ struct dirent* pdirent;
+
+ while ((pdirent = readdir(pdir)) != NULL)
+ {
+ if (bFilterLocalAndParentDir &&
+ ((0 == strcmp(pdirent->d_name, ".")) || (0 == strcmp(pdirent->d_name, ".."))))
+ continue;
+ else
+ break;
+ }
+
+ return pdirent;
+}
+
+/*******************************************************************
+ * osl_openDirectory
+ ******************************************************************/
+
+oslFileError SAL_CALL osl_openDirectory(rtl_uString* ustrDirectoryURL, oslDirectory* pDirectory)
+{
+ rtl_uString* ustrSystemPath = NULL;
+ oslFileError eRet;
+
+ char path[PATH_MAX];
+
+ OSL_ASSERT(ustrDirectoryURL && (ustrDirectoryURL->length > 0));
+ OSL_ASSERT(pDirectory);
+
+ if (0 == ustrDirectoryURL->length )
+ return osl_File_E_INVAL;
+
+ if ( 0 == rtl_ustr_compareIgnoreAsciiCase( ustrDirectoryURL->buffer, (const sal_Unicode*)L"file:///" ) )
+ return _osl_openLocalRoot( ustrDirectoryURL, pDirectory );
+
+ /* convert file URL to system path */
+ eRet = osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL, &ustrSystemPath, sal_False);
+
+ if( osl_File_E_None != eRet )
+ return eRet;
+
+ osl_systemPathRemoveSeparator(ustrSystemPath);
+
+ /* convert unicode path to text */
+ if ( UnicodeToText( path, PATH_MAX, ustrSystemPath->buffer, ustrSystemPath->length ) )
+ {
+ // if only the drive is specified (x:), add a \ (x:\) otherwise current
+ // directory is browsed instead of root.
+ if (strlen( path) == 2 && path[1] == ':')
+ strcat( path, "\\");
+ /* open directory */
+ DIR *pdir = opendir( path );
+
+ if( pdir )
+ {
+ /* create and initialize impl structure */
+ DirectoryImpl* pDirImpl = (DirectoryImpl*) rtl_allocateMemory( sizeof(DirectoryImpl) );
+
+ if( pDirImpl )
+ {
+ pDirImpl->uType = DIRECTORYTYPE_FILESYSTEM;
+ pDirImpl->pDirStruct = pdir;
+ pDirImpl->ustrPath = ustrSystemPath;
+
+ *pDirectory = (oslDirectory) pDirImpl;
+ return osl_File_E_None;
+ }
+ else
+ {
+ errno = ENOMEM;
+ closedir( pdir );
+ }
+ }
+ else
+ /* should be removed by optimizer in product version */
+ PERROR( "osl_openDirectory", path );
+ }
+
+ rtl_uString_release( ustrSystemPath );
+
+ return oslTranslateFileError(OSL_FET_ERROR, errno);
+}
+
+
+/****************************************************************************
+ * osl_getNextDirectoryItem
+ ***************************************************************************/
+
+oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory Directory, oslDirectoryItem* pItem, sal_uInt32 uHint)
+{
+ DirectoryImpl* pDirImpl = (DirectoryImpl*)Directory;
+ DirectoryItem_Impl *pItemImpl = NULL;
+ rtl_uString* ustrFileName = NULL;
+ rtl_uString* ustrFilePath = NULL;
+ struct dirent* pEntry;
+
+ OSL_ASSERT(Directory);
+ OSL_ASSERT(pItem);
+
+ if ((NULL == Directory) || (NULL == pItem))
+ return osl_File_E_INVAL;
+
+ if ( pDirImpl->uType == DIRECTORYTYPE_LOCALROOT)
+ return _osl_getNextDrive( Directory, pItem, uHint );
+
+ pEntry = _osl_readdir_impl_(pDirImpl->pDirStruct, sal_True);
+
+ if (NULL == pEntry)
+ return osl_File_E_NOENT;
+
+ pItemImpl = (DirectoryItem_Impl*) rtl_allocateMemory(sizeof(DirectoryItem_Impl));
+ if ( !pItemImpl )
+ return osl_File_E_NOMEM;
+
+ memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
+ pItemImpl->uType = DIRECTORYITEM_FILE;
+ pItemImpl->nRefCount = 1;
+ pItemImpl->d_attr = pEntry->d_attr;
+
+ /* convert file name to unicode */
+ rtl_string2UString( &ustrFileName, pEntry->d_name, strlen( pEntry->d_name ),
+ osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
+ OSL_ASSERT(ustrFileName != 0);
+
+ osl_systemPathMakeAbsolutePath(pDirImpl->ustrPath, ustrFileName, &pItemImpl->ustrFilePath);
+ rtl_uString_release( ustrFileName );
+
+ *pItem = (oslDirectoryItem)pItemImpl;
+ return osl_File_E_None;
+}
+
+/****************************************************************************/
+/* osl_closeDirectory */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_closeDirectory( oslDirectory Directory )
+{
+ DirectoryImpl* pDirImpl = (DirectoryImpl*) Directory;
+ oslFileError err = osl_File_E_None;
+
+ OSL_ASSERT( Directory );
+
+ if( NULL == pDirImpl )
+ return osl_File_E_INVAL;
+
+ switch ( pDirImpl->uType )
+ {
+ case DIRECTORYTYPE_FILESYSTEM:
+ if( closedir( pDirImpl->pDirStruct ) )
+ err = oslTranslateFileError(OSL_FET_ERROR, errno);
+ break;
+ case DIRECTORYTYPE_LOCALROOT:
+ err = osl_File_E_None;
+ break;
+#if 0
+ case DIRECTORYTYPE_NETROOT:
+ {
+ DWORD err = WNetCloseEnum(pDirImpl->hDirectory);
+ eError = (err == NO_ERROR) ? osl_File_E_None : MapError(err);
+ }
+ break;
+#endif
+ default:
+ OSL_ENSURE( 0, "Invalid directory type" );
+ break;
+ }
+
+ /* cleanup members */
+ rtl_uString_release( pDirImpl->ustrPath );
+
+ rtl_freeMemory( pDirImpl );
+
+ return err;
+}
+
+/****************************************************************************/
+/* osl_getDirectoryItem */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_getDirectoryItem( rtl_uString* ustrFileURL, oslDirectoryItem* pItem )
+{
+ rtl_uString* strSysFilePath = NULL;
+ oslFileError error = osl_File_E_INVAL;
+ ULONG dwPathType;
+ PATHTYPE type = PATHTYPE_FILE;
+
+ OSL_ASSERT(ustrFileURL);
+ OSL_ASSERT(pItem);
+
+ /* Assume failure */
+ if ( !pItem )
+ return osl_File_E_INVAL;
+ *pItem = NULL;
+
+ if (0 == ustrFileURL->length || NULL == pItem)
+ return osl_File_E_INVAL;
+
+ error = osl_getSystemPathFromFileURL_Ex(ustrFileURL, &strSysFilePath, sal_False);
+
+ if (osl_File_E_None != error)
+ return error;
+
+ dwPathType = IsValidFilePath( strSysFilePath->buffer, NULL, VALIDATEPATH_NORMAL );
+
+ if ( dwPathType & PATHTYPE_IS_VOLUME )
+ type = PATHTYPE_VOLUME;
+ else if ( dwPathType & PATHTYPE_IS_SERVER )
+ type = PATHTYPE_NETSERVER;
+ else
+ type = PATHTYPE_FILE;
+
+ switch ( type )
+ {
+ case PATHTYPE_NETSERVER:
+ {
+ DirectoryItem_Impl* pItemImpl =
+ reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
+
+ if ( !pItemImpl )
+ error = osl_File_E_NOMEM;
+
+ if ( osl_File_E_None == error )
+ {
+ memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
+ pItemImpl->uType = DIRECTORYITEM_SERVER;
+ pItemImpl->nRefCount = 1;
+ rtl_uString_assign( &pItemImpl->ustrFilePath, strSysFilePath );
+
+ *pItem = pItemImpl;
+ }
+ }
+ break;
+ case PATHTYPE_VOLUME:
+ {
+ DirectoryItem_Impl* pItemImpl =
+ reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
+
+ if ( !pItemImpl )
+ error = osl_File_E_NOMEM;
+
+ if ( osl_File_E_None == error )
+ {
+ memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
+ pItemImpl->uType = DIRECTORYITEM_DRIVE;
+ pItemImpl->nRefCount = 1;
+ rtl_uString_assign( &pItemImpl->ustrDrive, strSysFilePath );
+
+ if ( pItemImpl->ustrDrive->buffer[pItemImpl->ustrDrive->length-1] != sal_Unicode('\\') )
+ rtl_uString_newConcat( &pItemImpl->ustrDrive,
+ pItemImpl->ustrDrive, rtl::OUString::createFromAscii( "\\" ).pData);
+
+ *pItem = pItemImpl;
+ }
+ }
+ break;
+ default:
+ case PATHTYPE_FILE:
+ {
+ if ( strSysFilePath->length > 0 && strSysFilePath->buffer[strSysFilePath->length - 1] == '\\' )
+ rtl_uString_newFromStr_WithLength( &strSysFilePath, strSysFilePath->buffer, strSysFilePath->length - 1 );
+
+ if (0 == access_u(strSysFilePath, F_OK))
+ {
+ DirectoryItem_Impl *pItemImpl =
+ reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
+
+ memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
+ pItemImpl->uType = DIRECTORYITEM_FILE;
+ pItemImpl->nRefCount = 1;
+ rtl_uString_assign( &pItemImpl->ustrFilePath, strSysFilePath );
+
+ *pItem = pItemImpl;
+ }
+ else
+ error = oslTranslateFileError(OSL_FET_ERROR, errno);
+ }
+ break;
+ }
+
+ if ( strSysFilePath )
+ rtl_uString_release( strSysFilePath );
+
+ return error;
+}
+
+/****************************************************************************/
+/* osl_acquireDirectoryItem */
+/****************************************************************************/
+
+oslFileError osl_acquireDirectoryItem( oslDirectoryItem Item )
+{
+ OSL_ASSERT( Item );
+ DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
+
+ if ( !pItemImpl )
+ return osl_File_E_INVAL;
+
+ pItemImpl->nRefCount++;
+ return osl_File_E_None;
+}
+
+/****************************************************************************/
+/* osl_releaseDirectoryItem */
+/****************************************************************************/
+
+oslFileError osl_releaseDirectoryItem( oslDirectoryItem Item )
+{
+ OSL_ASSERT( Item );
+ DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
+
+ if ( !pItemImpl )
+ return osl_File_E_INVAL;
+
+ if ( ! --pItemImpl->nRefCount )
+ {
+ if (pItemImpl->ustrFilePath)
+ rtl_uString_release( pItemImpl->ustrFilePath );
+ if (pItemImpl->ustrDrive)
+ rtl_uString_release( pItemImpl->ustrDrive );
+ rtl_freeMemory( pItemImpl );
+ }
+ return osl_File_E_None;
+}
+
+/****************************************************************************
+ * osl_createFileHandleFromFD
+ ***************************************************************************/
+
+oslFileHandle osl_createFileHandleFromFD( int fd )
+{
+ oslFileHandleImpl* pHandleImpl = NULL;
+
+ if ( fd >= 0 )
+ {
+ pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
+
+ if( pHandleImpl )
+ {
+ pHandleImpl->ustrFilePath = NULL;
+ rtl_uString_new( &pHandleImpl->ustrFilePath );
+ pHandleImpl->fd = fd;
+
+ /* FIXME: should detect whether the file has been locked */
+ pHandleImpl->bLocked = sal_True;
+ }
+ }
+
+ return (oslFileHandle)pHandleImpl;
+}
+
+/****************************************************************************
+ * osl_openFile
+ ***************************************************************************/
+
+oslFileError osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags )
+{
+ oslFileHandleImpl* pHandleImpl = NULL;
+ oslFileError eRet;
+ rtl_uString* ustrFilePath = NULL;
+
+ char buffer[PATH_MAX];
+ int fd;
+ int mode = S_IRUSR | S_IRGRP | S_IROTH;
+ int flags = O_RDONLY;
+
+ struct flock aflock;
+
+ /* locking the complete file */
+ aflock.l_type = 0;
+ aflock.l_whence = SEEK_SET;
+ aflock.l_start = 0;
+ aflock.l_len = 0;
+
+ OSL_ASSERT( ustrFileURL );
+ OSL_ASSERT( pHandle );
+
+ if( ( 0 == ustrFileURL->length ) )
+ return osl_File_E_INVAL;
+
+ /* convert file URL to system path */
+ eRet = osl_getSystemPathFromFileURL( ustrFileURL, &ustrFilePath );
+
+ if( osl_File_E_None != eRet )
+ return eRet;
+
+ osl_systemPathRemoveSeparator(ustrFilePath);
+
+ /* convert unicode path to text */
+ if( UnicodeToText( buffer, PATH_MAX, ustrFilePath->buffer, ustrFilePath->length ) )
+ {
+ /* we do not open devices or such here */
+ if( !( uFlags & osl_File_OpenFlag_Create ) )
+ {
+ struct stat aFileStat;
+
+ if( 0 > stat( buffer, &aFileStat ) )
+ {
+ PERROR( "osl_openFile", buffer );
+ eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
+ }
+
+ else if( !S_ISREG( aFileStat.st_mode ) )
+ {
+ eRet = osl_File_E_INVAL;
+ }
+ }
+
+ if( osl_File_E_None == eRet )
+ {
+ /*
+ * set flags and mode
+ */
+
+ if ( uFlags & osl_File_OpenFlag_Write )
+ {
+ mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ flags = O_RDWR;
+ aflock.l_type = F_WRLCK;
+ }
+
+ if ( uFlags & osl_File_OpenFlag_Create )
+ {
+ mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ flags = O_CREAT | O_EXCL | O_RDWR;
+ }
+
+ /* open the file */
+ fd = open( buffer, flags | O_BINARY, mode);
+ if ( fd >= 0 )
+ {
+ sal_Bool bNeedsLock = ( ( uFlags & osl_File_OpenFlag_NoLock ) == 0 );
+ sal_Bool bLocked = sal_False;
+ if( bNeedsLock )
+ {
+ /* check if file lock is enabled and clear l_type member of flock otherwise */
+ if( (char *) -1 == pFileLockEnvVar )
+ {
+ /* FIXME: this is not MT safe */
+ pFileLockEnvVar = getenv("SAL_ENABLE_FILE_LOCKING");
+
+ if( NULL == pFileLockEnvVar)
+ pFileLockEnvVar = getenv("STAR_ENABLE_FILE_LOCKING");
+ }
+
+ if( NULL == pFileLockEnvVar )
+ aflock.l_type = 0;
+
+ /* lock the file if flock.l_type is set */
+ bLocked = ( F_WRLCK != aflock.l_type || -1 != fcntl( fd, F_SETLK, &aflock ) );
+ }
+
+ if ( !bNeedsLock || bLocked )
+ {
+ /* allocate memory for impl structure */
+ pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
+ if( pHandleImpl )
+ {
+ pHandleImpl->ustrFilePath = ustrFilePath;
+ pHandleImpl->fd = fd;
+ pHandleImpl->bLocked = bLocked;
+
+ *pHandle = (oslFileHandle) pHandleImpl;
+
+ return osl_File_E_None;
+ }
+ else
+ {
+ errno = ENOMEM;
+ }
+ }
+
+ close( fd );
+ }
+
+ PERROR( "osl_openFile", buffer );
+ eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
+ }
+ }
+ else
+ eRet = osl_File_E_INVAL;
+
+ rtl_uString_release( ustrFilePath );
+ return eRet;
+}
+
+/****************************************************************************/
+/* osl_closeFile */
+/****************************************************************************/
+
+oslFileError osl_closeFile( oslFileHandle Handle )
+{
+ oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl *) Handle;
+ oslFileError eRet = osl_File_E_INVAL;
+
+ OSL_ASSERT( Handle );
+
+ if( pHandleImpl )
+ {
+ rtl_uString_release( pHandleImpl->ustrFilePath );
+
+ /* release file lock if locking is enabled */
+ if( pFileLockEnvVar )
+ {
+ struct flock aflock;
+
+ aflock.l_type = F_UNLCK;
+ aflock.l_whence = SEEK_SET;
+ aflock.l_start = 0;
+ aflock.l_len = 0;
+
+ if ( pHandleImpl->bLocked )
+ {
+ /* FIXME: check if file is really locked ? */
+
+ /* release the file share lock on this file */
+ if( -1 == fcntl( pHandleImpl->fd, F_SETLK, &aflock ) )
+ PERROR( "osl_closeFile", "unlock failed" );
+ }
+ }
+
+ if( 0 > close( pHandleImpl->fd ) )
+ {
+ eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
+ }
+ else
+ eRet = osl_File_E_None;
+
+ rtl_freeMemory( pHandleImpl );
+ }
+
+ return eRet;
+}
+
+/****************************************************************************/
+/* osl_isEndOfFile */
+/****************************************************************************/
+
+oslFileError SAL_CALL osl_isEndOfFile( oslFileHandle Handle, sal_Bool *pIsEOF )
+{
+ oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl *) Handle;
+ oslFileError eRet = osl_File_E_INVAL;
+
+ if ( pHandleImpl)
+ {
+ long curPos = lseek( pHandleImpl->fd, 0, SEEK_CUR );
+
+ if ( curPos >= 0 )
+ {
+ long endPos = lseek( pHandleImpl->fd, 0, SEEK_END );
+
+ if ( endPos >= 0 )
+ {
+ *pIsEOF = ( curPos == endPos );
+ curPos = lseek( pHandleImpl->fd, curPos, SEEK_SET );
+
+ if ( curPos >= 0 )
+ eRet = osl_File_E_None;
+ else
+ eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
+ }
+ else
+ eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
+ }
+ else
+ eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
+ }
+
+ return eRet;
+}
+
+
+/****************************************************************************/
+/* osl_moveFile */
+/****************************************************************************/
+
+oslFileError osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
+{
+ char srcPath[PATH_MAX];
+ char destPath[PATH_MAX];
+ oslFileError eRet;
+ APIRET rc;
+
+ OSL_ASSERT( ustrFileURL );
+ OSL_ASSERT( ustrDestURL );
+
+ /* convert source url to system path */
+ eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+ /* convert destination url to system path */
+ eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+ //YD 01/05/06 rename() can overwrite existing files.
+ rc = DosDelete( (PCSZ)destPath);
+ rc = DosMove( (PCSZ)srcPath, (PCSZ)destPath);
+ if (!rc)
+ eRet = osl_File_E_None;
+ else
+ eRet = MapError( rc);
+
+ return eRet;
+}
+
+/****************************************************************************/
+/* osl_copyFile */
+/****************************************************************************/
+
+#define TMP_DEST_FILE_EXTENSION ".osl-tmp"
+
+static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists)
+{
+ int nRet=0;
+ sal_Char pszTmpDestFile[PATH_MAX];
+ size_t size_tmp_dest_buff = sizeof(pszTmpDestFile);
+
+ /* Quick fix for #106048, the whole copy file function seems
+ to be erroneous anyway and needs to be rewritten.
+ Besides osl_copyFile is currently not used from OO/SO code.
+ */
+ memset(pszTmpDestFile, 0, size_tmp_dest_buff);
+
+ if ( DestFileExists )
+ {
+ strncpy(pszTmpDestFile, pszDestFileName, size_tmp_dest_buff - 1);
+
+ if ((strlen(pszTmpDestFile) + strlen(TMP_DEST_FILE_EXTENSION)) >= size_tmp_dest_buff)
+ return osl_File_E_NAMETOOLONG;
+
+ strncat(pszTmpDestFile, TMP_DEST_FILE_EXTENSION, strlen(TMP_DEST_FILE_EXTENSION));
+
+ /* FIXME: what if pszTmpDestFile already exists? */
+ /* with getcanonical??? */
+ nRet=rename(pszDestFileName,pszTmpDestFile);
+ }
+
+ /* mfe: should be S_ISREG */
+ if ( !S_ISLNK(nMode) )
+ {
+ /* copy SourceFile to DestFile */
+ nRet = oslDoCopyFile(pszSourceFileName,pszDestFileName,nSourceSize, nMode);
+ }
+ /* mfe: OK redundant at the moment */
+ else if ( S_ISLNK(nMode) )
+ {
+ nRet = oslDoCopyLink(pszSourceFileName,pszDestFileName);
+ }
+ else
+ {
+ /* mfe: what to do here? */
+ nRet=ENOSYS;
+ }
+
+ if ( nRet > 0 && DestFileExists == 1 )
+ {
+ unlink(pszDestFileName);
+ rename(pszTmpDestFile,pszDestFileName);
+ }
+
+ if ( nRet > 0 )
+ {
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ if ( DestFileExists == 1 )
+ {
+ unlink(pszTmpDestFile);
+ }
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * oslChangeFileModes
+ ****************************************/
+
+static oslFileError oslChangeFileModes( const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID)
+{
+ int nRet=0;
+ struct utimbuf aTimeBuffer;
+
+ nRet = chmod(pszFileName,nMode);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ aTimeBuffer.actime=nAcTime;
+ aTimeBuffer.modtime=nModTime;
+ nRet=utime(pszFileName,&aTimeBuffer);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ if ( nUID != getuid() )
+ {
+ nUID=getuid();
+ }
+
+ nRet=chown(pszFileName,nUID,nGID);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+
+ /* mfe: do not return an error here! */
+ /* return oslTranslateFileError(nRet);*/
+ }
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * oslDoCopyLink
+ ****************************************/
+
+static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName)
+{
+ int nRet=0;
+
+ /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
+ /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
+ sal_Char pszLinkContent[PATH_MAX];
+
+ pszLinkContent[0] = '\0';
+
+ nRet = readlink(pszSourceFileName,pszLinkContent,PATH_MAX);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return nRet;
+ }
+ else
+ pszLinkContent[ nRet ] = 0;
+
+ nRet = symlink(pszLinkContent,pszDestFileName);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return nRet;
+ }
+
+ return 0;
+}
+
+/*****************************************
+ * oslDoCopyFile
+ ****************************************/
+
+static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode)
+{
+ int SourceFileFD=0;
+ int DestFileFD=0;
+ int nRet=0;
+ void* pSourceFile=0;
+ char buffer[ 4096];
+
+ SourceFileFD=open(pszSourceFileName,O_RDONLY | O_BINARY);
+ if ( SourceFileFD < 0 )
+ {
+ nRet=errno;
+ return nRet;
+ }
+
+ DestFileFD=open(pszDestFileName, O_WRONLY | O_CREAT | O_BINARY, mode);
+ if ( DestFileFD < 0 )
+ {
+ nRet=errno;
+ close(SourceFileFD);
+ return nRet;
+ }
+
+ /* HACK: because memory mapping fails on various
+ platforms if the size of the source file is 0 byte */
+ if (0 == nSourceSize)
+ {
+ close(SourceFileFD);
+ close(DestFileFD);
+ return 0;
+ }
+
+ while( (nRet = read(SourceFileFD, buffer, sizeof(buffer))) !=0 )
+ {
+ nRet = write( DestFileFD, buffer, nRet);
+ }
+
+ close(SourceFileFD);
+ close(DestFileFD);
+
+ return nRet;
+}
+
+static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
+{
+ time_t nAcTime=0;
+ time_t nModTime=0;
+ uid_t nUID=0;
+ gid_t nGID=0;
+ int nRet=0;
+ mode_t nMode=0;
+ struct stat aFileStat;
+ oslFileError tErr=osl_File_E_invalidError;
+ size_t nSourceSize=0;
+ int DestFileExists=1;
+
+ /* mfe: does the source file really exists? */
+ nRet = lstat(pszPath,&aFileStat);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ /* mfe: we do only copy files here! */
+ if ( S_ISDIR(aFileStat.st_mode) )
+ {
+ return osl_File_E_ISDIR;
+ }
+
+ nSourceSize=(size_t)aFileStat.st_size;
+ nMode=aFileStat.st_mode;
+ nAcTime=aFileStat.st_atime;
+ nModTime=aFileStat.st_mtime;
+ nUID=aFileStat.st_uid;
+ nGID=aFileStat.st_gid;
+
+ nRet = stat(pszDestPath,&aFileStat);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+
+ if ( nRet == ENOENT )
+ {
+ DestFileExists=0;
+ }
+/* return oslTranslateFileError(nRet);*/
+ }
+
+ /* mfe: the destination file must not be a directory! */
+ if ( nRet == 0 && S_ISDIR(aFileStat.st_mode) )
+ {
+ return osl_File_E_ISDIR;
+ }
+ else
+ {
+ /* mfe: file does not exists or is no dir */
+ }
+
+ tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
+
+ if ( tErr != osl_File_E_None )
+ {
+ return tErr;
+ }
+
+ /*
+ * mfe: ignore return code
+ * since only the success of the copy is
+ * important
+ */
+ oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
+
+ return tErr;
+}
+
+oslFileError osl_copyFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
+{
+ char srcPath[PATH_MAX];
+ char destPath[PATH_MAX];
+ oslFileError eRet;
+ APIRET rc;
+
+ OSL_ASSERT( ustrFileURL );
+ OSL_ASSERT( ustrDestURL );
+
+ /* convert source url to system path */
+ eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+ /* convert destination url to system path */
+ eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+ return osl_psz_copyFile( srcPath, destPath );
+}
+
+/****************************************************************************/
+/* osl_removeFile */
+/****************************************************************************/
+
+oslFileError osl_removeFile( rtl_uString* ustrFileURL )
+{
+ char path[PATH_MAX];
+ oslFileError eRet;
+ APIRET rc;
+
+ OSL_ASSERT( ustrFileURL );
+
+ /* convert file url to system path */
+ eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+ rc = DosDelete( (PCSZ)path);
+ if (!rc)
+ eRet = osl_File_E_None;
+ else
+ eRet = MapError( rc);
+
+ return eRet;
+}
+
+/****************************************************************************/
+/* osl_getVolumeInformation */
+/****************************************************************************/
+
+#define TXFSDC_BLOCKR 0x00 // block device removable
+#define TXFSDC_GETBPB 0x00 // get device bpb info
+#define TXFSBPB_REMOVABLE 0x08 // BPB attribute for removable
+
+typedef struct drivecmd
+{
+ BYTE cmd; // 0=unlock 1=lock 2=eject
+ BYTE drv; // 0=A, 1=B 2=C ...
+} DRIVECMD; // end of struct "drivecmd"
+
+#pragma pack(push, 1) // byte packing
+typedef struct txfs_ebpb // ext. boot parameter block
+{ // at offset 0x0b in bootsector
+ USHORT SectSize; // 0B bytes per sector
+ BYTE ClustSize; // 0D sectors per cluster
+ USHORT FatOffset; // 0E sectors to 1st FAT
+ BYTE NrOfFats; // 10 nr of FATS (FAT only)
+ USHORT RootEntries; // 11 Max entries \ (FAT only)
+ USHORT Sectors; // 13 nr of sectors if < 64K
+ BYTE MediaType; // 15 mediatype (F8 for HD)
+ USHORT FatSectors; // 16 sectors/FAT (FAT only)
+ USHORT LogGeoSect; // 18 sectors/Track
+ USHORT LogGeoHead; // 1a nr of heads
+ ULONG HiddenSectors; // 1c sector-offset from MBR/EBR
+ ULONG BigSectors; // 20 nr of sectors if >= 64K
+} TXFS_EBPB; // last byte is at offset 0x23
+
+typedef struct drivebpb
+{
+ TXFS_EBPB ebpb; // extended BPB
+ BYTE reserved[6];
+ USHORT cyls;
+ BYTE type;
+ USHORT attributes; // device attributes
+ BYTE fill[6]; // documented for IOCtl
+} DRIVEBPB; // end of struct "drivebpb"
+
+struct CDInfo {
+ USHORT usCount;
+ USHORT usFirst;
+};
+
+#pragma pack(pop)
+
+/*****************************************************************************/
+// Get number of cdrom readers
+/*****************************************************************************/
+BOOL GetCDInfo( CDInfo * pCDInfo )
+{
+ HFILE hFileCD;
+ ULONG ulAction;
+
+ if( NO_ERROR == DosOpen( (PCSZ)"\\DEV\\CD-ROM2$",
+ &hFileCD, &ulAction, 0, FILE_NORMAL,
+ OPEN_ACTION_OPEN_IF_EXISTS,
+ OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL )) {
+ ULONG ulDataSize = sizeof(CDInfo);
+ APIRET rc = DosDevIOCtl( hFileCD, 0x82, 0x60, NULL, 0,
+ NULL, (PVOID)pCDInfo, ulDataSize, &ulDataSize);
+ DosClose( hFileCD);
+ if(rc == NO_ERROR)
+ return TRUE;
+ }
+ // failed
+ pCDInfo->usFirst = 0;
+ pCDInfo->usCount = 0;
+ return FALSE;
+}
+
+/*****************************************************************************/
+// Determine if unit is a cdrom or not
+/*****************************************************************************/
+BOOL DriveIsCDROM(UINT uiDrive, CDInfo *pCDInfo)
+{
+ return (uiDrive >= pCDInfo->usFirst)
+ && (uiDrive < (pCDInfo->usFirst + pCDInfo->usCount));
+}
+
+/*****************************************************************************/
+// Determine attached fstype, e.g. HPFS for specified drive
+/*****************************************************************************/
+BOOL TxFsType // RET FS type resolved
+(
+ char *drive, // IN Drive specification
+ char *fstype, // OUT Attached FS type
+ char *details // OUT details (UNC) or NULL
+)
+{
+ BOOL rc = FALSE;
+ FSQBUFFER2 *fsinfo; // Attached FS info
+ ULONG fsdlen = 2048; // Fs info data length
+
+ strcpy(fstype, "none");
+ if (details)
+ {
+ strcpy(details, "");
+ }
+ if ((fsinfo = (FSQBUFFER2*)calloc(1, fsdlen)) != NULL)
+ {
+ if (DosQFSAttach((PCSZ)drive, 0, 1, fsinfo, &fsdlen) == NO_ERROR)
+ {
+ strcpy(fstype, (char*) fsinfo->szName + fsinfo->cbName +1);
+ if (details && (fsinfo->cbFSAData != 0))
+ {
+ strcpy( details, (char*) fsinfo->szName + fsinfo->cbName +
+ fsinfo->cbFSDName +2);
+ }
+ rc = TRUE;
+ }
+ free(fsinfo);
+ }
+ return (rc);
+} // end 'TxFsType'
+/*---------------------------------------------------------------------------*/
+
+
+/*****************************************************************************/
+// Determine if a driveletter represents a removable medium/device
+/*****************************************************************************/
+BOOL TxFsIsRemovable // RET drive is removable
+(
+ char *drive // IN Driveletter to test
+)
+{
+ BOOL rc = FALSE;
+ DRIVECMD IOCtl;
+ DRIVEBPB RemAt;
+ ULONG DataLen;
+ ULONG ParmLen;
+ BYTE NoRem;
+
+ DosError( FERR_DISABLEHARDERR); // avoid 'not ready' popups
+
+ ParmLen = sizeof(IOCtl);
+ IOCtl.cmd = TXFSDC_BLOCKR;
+ IOCtl.drv = toupper(drive[0]) - 'A';
+ DataLen = sizeof(NoRem);
+
+ if (DosDevIOCtl((HFILE) -1, IOCTL_DISK,
+ DSK_BLOCKREMOVABLE,
+ &IOCtl, ParmLen, &ParmLen,
+ &NoRem, DataLen, &DataLen) == NO_ERROR)
+ {
+ if (NoRem) // non-removable sofar, check
+ { // BPB as well (USB devices)
+ ParmLen = sizeof(IOCtl);
+ IOCtl.cmd = TXFSDC_GETBPB;
+ IOCtl.drv = toupper(drive[0]) - 'A';
+ DataLen = sizeof(RemAt);
+
+ if (DosDevIOCtl((HFILE) -1, IOCTL_DISK,
+ DSK_GETDEVICEPARAMS,
+ &IOCtl, ParmLen, &ParmLen,
+ &RemAt, DataLen, &DataLen) == NO_ERROR)
+
+ {
+ if (RemAt.attributes & TXFSBPB_REMOVABLE)
+ {
+ rc = TRUE; // removable, probably USB
+ }
+ }
+ }
+ else
+ {
+ rc = TRUE; // removable block device
+ }
+ }
+ DosError( FERR_ENABLEHARDERR); // enable criterror handler
+ return (rc);
+} // end 'TxFsIsRemovable'
+/*---------------------------------------------------------------------------*/
+
+static oslFileError get_drive_type(const char* path, oslVolumeInfo* pInfo)
+{
+ char Drive_Letter = toupper( *path);
+ char fstype[ 64];
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
+
+ // check for floppy A/B
+ BYTE nFloppies;
+ APIRET rc;
+ rc = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY );
+ if ((Drive_Letter - 'A') < nFloppies) {
+ pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
+ pInfo->uAttributes |= osl_Volume_Attribute_FloppyDisk;
+ return osl_File_E_None;
+ }
+
+ // query system for CD drives
+ CDInfo cdInfo;
+ GetCDInfo(&cdInfo);
+
+ // query if drive is a CDROM
+ if (DriveIsCDROM( Drive_Letter - 'A', &cdInfo))
+ pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
+
+ if (TxFsIsRemovable( (char*)path))
+ pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
+
+ if (TxFsType( (char*)path, fstype, NULL) == FALSE) {
+ // query failed, assume fixed disk
+ pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
+ return osl_File_E_None;
+ }
+
+ //- Note, connected Win-NT drives use the REAL FS-name like NTFS!
+ if ((strncasecmp( fstype, "LAN", 3) == 0) //- OS/2 LAN drives
+ || (strncasecmp( fstype, "NDFS", 4) == 0) //- NetDrive
+ || (strncasecmp( fstype, "REMOTE", 5) == 0) ) //- NT disconnected
+ pInfo->uAttributes |= osl_Volume_Attribute_Remote;
+ else if (strncasecmp( fstype, "RAMFS", 5) == 0)
+ pInfo->uAttributes |= osl_Volume_Attribute_RAMDisk;
+ else if ((strncasecmp( fstype, "CD", 2) == 0) // OS2:CDFS, DOS/WIN:CDROM
+ || (strncasecmp( fstype, "UDF", 3) == 0) ) // OS2:UDF DVD's
+ pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
+ else
+ pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
+
+ return osl_File_E_None;
+}
+
+//#############################################
+inline bool is_volume_space_info_request(sal_uInt32 field_mask)
+{
+ return (field_mask &
+ (osl_VolumeInfo_Mask_TotalSpace |
+ osl_VolumeInfo_Mask_UsedSpace |
+ osl_VolumeInfo_Mask_FreeSpace));
+}
+
+//#############################################
+static void get_volume_space_information(const char* path, oslVolumeInfo *pInfo)
+{
+ FSALLOCATE aFSInfoBuf;
+ ULONG nDriveNumber = toupper( *path) - 'A' + 1;
+
+ // disable error popups
+ DosError(FERR_DISABLEHARDERR);
+ APIRET rc = DosQueryFSInfo( nDriveNumber, FSIL_ALLOC,
+ &aFSInfoBuf, sizeof(aFSInfoBuf) );
+ // enable error popups
+ DosError(FERR_ENABLEHARDERR);
+ if (!rc)
+ {
+ uint64_t aBytesPerCluster( uint64_t(aFSInfoBuf.cbSector) *
+ uint64_t(aFSInfoBuf.cSectorUnit) );
+ pInfo->uFreeSpace = aBytesPerCluster * uint64_t(aFSInfoBuf.cUnitAvail);
+ pInfo->uTotalSpace = aBytesPerCluster * uint64_t(aFSInfoBuf.cUnit);
+ pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace |
+ osl_VolumeInfo_Mask_UsedSpace |
+ osl_VolumeInfo_Mask_FreeSpace;
+ }
+}
+
+//#############################################
+inline bool is_filesystem_attributes_request(sal_uInt32 field_mask)
+{
+ return (field_mask &
+ (osl_VolumeInfo_Mask_MaxNameLength |
+ osl_VolumeInfo_Mask_MaxPathLength |
+ osl_VolumeInfo_Mask_FileSystemName |
+ osl_VolumeInfo_Mask_FileSystemCaseHandling));
+}
+
+//#############################################
+inline bool is_drivetype_request(sal_uInt32 field_mask)
+{
+ return (field_mask & osl_VolumeInfo_Mask_Attributes);
+}
+
+typedef struct _FSQBUFFER_
+{
+ FSQBUFFER2 aBuf;
+ UCHAR sBuf[64];
+} FSQBUFFER_;
+
+//#############################################
+static oslFileError get_filesystem_attributes(const char* path, sal_uInt32 field_mask, oslVolumeInfo* pInfo)
+{
+ pInfo->uAttributes = 0;
+
+ oslFileError osl_error = osl_File_E_None;
+
+ // osl_get_drive_type must be called first because
+ // this function resets osl_VolumeInfo_Mask_Attributes
+ // on failure
+ if (is_drivetype_request(field_mask))
+ osl_error = get_drive_type(path, pInfo);
+
+ if ((osl_File_E_None == osl_error) && is_filesystem_attributes_request(field_mask))
+ {
+ FSQBUFFER_ aBuf;
+ ULONG nBufLen;
+ APIRET nRet;
+
+ nBufLen = sizeof( aBuf );
+ // disable error popups
+ DosError(FERR_DISABLEHARDERR);
+ nRet = DosQueryFSAttach( (PCSZ)path, 0, FSAIL_QUERYNAME, (_FSQBUFFER2*) &aBuf, &nBufLen );
+ if ( !nRet )
+ {
+ char *pType = (char*)(aBuf.aBuf.szName + aBuf.aBuf.cbName + 1);
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
+ pInfo->uMaxNameLength = _MAX_FNAME;
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
+ pInfo->uMaxPathLength = _MAX_PATH;
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
+ rtl_uString_newFromAscii(&pInfo->ustrFileSystemName, pType);
+
+ // case is preserved always except for FAT
+ if (strcmp( pType, "FAT" ))
+ pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
+ }
+ // enable error popups
+ DosError(FERR_ENABLEHARDERR);
+ }
+ return osl_error;
+}
+
+oslFileError SAL_CALL osl_getVolumeInformation( rtl_uString* ustrDirectoryURL, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask )
+{
+ char volume_root[PATH_MAX];
+ oslFileError error;
+
+ OSL_ASSERT( ustrDirectoryURL );
+ OSL_ASSERT( pInfo );
+
+ /* convert directory url to system path */
+ error = FileURLToPath( volume_root, PATH_MAX, ustrDirectoryURL );
+ if( error != osl_File_E_None )
+ return error;
+
+ if (!pInfo)
+ return osl_File_E_INVAL;
+
+ pInfo->uValidFields = 0;
+
+ if ((error = get_filesystem_attributes(volume_root, uFieldMask, pInfo)) != osl_File_E_None)
+ return error;
+
+ if (is_volume_space_info_request(uFieldMask))
+ get_volume_space_information(volume_root, pInfo);
+
+ if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
+ {
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
+ rtl_uString* uVolumeRoot;
+ rtl_uString_newFromAscii( &uVolumeRoot, volume_root);
+ osl_getFileURLFromSystemPath( uVolumeRoot, (rtl_uString**)&pInfo->pDeviceHandle);
+ rtl_uString_release( uVolumeRoot);
+ }
+
+ return osl_File_E_None;
+}
+
+/****************************************************************************/
+/* osl_getFileStatus */
+/****************************************************************************/
+static oslFileError _osl_getDriveInfo(
+ oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask)
+{
+ DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
+ sal_Unicode cDrive[3];
+ sal_Unicode cRoot[4];
+
+ if ( !pItemImpl )
+ return osl_File_E_INVAL;
+
+ pStatus->uValidFields = 0;
+
+ cDrive[0] = pItemImpl->ustrDrive->buffer[0];
+ cDrive[1] = (sal_Unicode)':';
+ cDrive[2] = 0;
+ cRoot[0] = pItemImpl->ustrDrive->buffer[0];
+ cRoot[1] = (sal_Unicode)':';
+ cRoot[2] = 0;
+
+ if ( uFieldMask & osl_FileStatus_Mask_FileName )
+ {
+ if ( pItemImpl->ustrDrive->buffer[0] == '\\' &&
+ pItemImpl->ustrDrive->buffer[1] == '\\' )
+ {
+ LPCWSTR lpFirstBkSlash = wcschr( (const wchar_t*)&pItemImpl->ustrDrive->buffer[2], '\\' );
+
+ if ( lpFirstBkSlash && lpFirstBkSlash[1] )
+ {
+ LPCWSTR lpLastBkSlash = wcschr( (const wchar_t*)&lpFirstBkSlash[1], '\\' );
+
+ if ( lpLastBkSlash )
+ rtl_uString_newFromStr_WithLength( &pStatus->ustrFileName, (sal_Unicode*)&lpFirstBkSlash[1], lpLastBkSlash - lpFirstBkSlash - 1 );
+ else
+ rtl_uString_newFromStr( &pStatus->ustrFileName, (sal_Unicode*)&lpFirstBkSlash[1] );
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
+ }
+ }
+ else
+ {
+ FSINFO aFSInfoBuf;
+ ULONG ulFSInfoLevel = FSIL_VOLSER;
+ ULONG nDriveNumber;
+ char szFileName[ _MAX_PATH];
+
+ nDriveNumber = toupper(*cDrive) - 'A' + 1;
+ memset( &aFSInfoBuf, 0, sizeof(FSINFO) );
+ // disable error popups
+ DosError(FERR_DISABLEHARDERR);
+ APIRET rc = DosQueryFSInfo( nDriveNumber, ulFSInfoLevel, &aFSInfoBuf, sizeof(FSINFO) );
+ // enable error popups
+ DosError(FERR_ENABLEHARDERR);
+ memset( szFileName, 0, sizeof( szFileName));
+ *szFileName = toupper(*cDrive);
+ strcat( szFileName, ": [");
+ if ( !rc || aFSInfoBuf.vol.cch)
+ strncat( szFileName, aFSInfoBuf.vol.szVolLabel, aFSInfoBuf.vol.cch);
+ strcat( szFileName, "]");
+ rtl_uString_newFromAscii( &pStatus->ustrFileName, szFileName );
+
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
+ }
+ }
+
+ pStatus->eType = osl_File_Type_Volume;
+ pStatus->uValidFields |= osl_FileStatus_Mask_Type;
+
+ if ( uFieldMask & osl_FileStatus_Mask_FileURL )
+ {
+ rtl_uString *ustrSystemPath = NULL;
+
+ rtl_uString_newFromStr( &ustrSystemPath, pItemImpl->ustrDrive->buffer );
+ osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL );
+ rtl_uString_release( ustrSystemPath );
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
+ }
+
+ return osl_File_E_None;
+}
+
+oslFileError SAL_CALL osl_getFileStatus(
+ oslDirectoryItem Item,
+ oslFileStatus *pStatus,
+ sal_uInt32 uFieldMask )
+{
+ DirectoryItem_Impl *pItemImpl = (DirectoryItem_Impl *)Item;
+ struct stat file_stat;
+
+ if ( !pItemImpl )
+ return osl_File_E_INVAL;
+
+ if ( pItemImpl->uType == DIRECTORYITEM_DRIVE)
+ return _osl_getDriveInfo( Item, pStatus, uFieldMask );
+
+ osl::lstat(pItemImpl->ustrFilePath, file_stat);
+ if ( uFieldMask & osl_FileStatus_Mask_Validate )
+ {
+ uFieldMask &= ~ osl_FileStatus_Mask_Validate;
+ }
+
+ /* If no fields to retrieve left ignore pStatus */
+ if ( !uFieldMask )
+ return osl_File_E_None;
+
+ /* Otherwise, this must be a valid pointer */
+ if ( !pStatus )
+ return osl_File_E_INVAL;
+
+ if ( pStatus->uStructSize != sizeof(oslFileStatus) )
+ return osl_File_E_INVAL;
+
+ pStatus->uValidFields = 0;
+
+ /* File time stamps */
+
+ if ( (uFieldMask & osl_FileStatus_Mask_ModifyTime))
+ {
+ pStatus->aModifyTime.Seconds = file_stat.st_mtime;
+ pStatus->aModifyTime.Nanosec = 0;
+ pStatus->uValidFields |= osl_FileStatus_Mask_ModifyTime;
+ }
+
+ if ( (uFieldMask & osl_FileStatus_Mask_AccessTime))
+ {
+ pStatus->aAccessTime.Seconds = file_stat.st_atime;
+ pStatus->aAccessTime.Nanosec = 0;
+ pStatus->uValidFields |= osl_FileStatus_Mask_AccessTime;
+ }
+
+ if ( (uFieldMask & osl_FileStatus_Mask_CreationTime))
+ {
+ pStatus->aAccessTime.Seconds = file_stat.st_birthtime;
+ pStatus->aAccessTime.Nanosec = 0;
+ pStatus->uValidFields |= osl_FileStatus_Mask_CreationTime;
+ }
+
+ /* Most of the fields are already set, regardless of requiered fields */
+
+ osl_systemPathGetFileNameOrLastDirectoryPart(pItemImpl->ustrFilePath, &pStatus->ustrFileName);
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
+
+ if (S_ISLNK(file_stat.st_mode))
+ pStatus->eType = osl_File_Type_Link;
+ else if (S_ISDIR(file_stat.st_mode))
+ pStatus->eType = osl_File_Type_Directory;
+ else if (S_ISREG(file_stat.st_mode))
+ pStatus->eType = osl_File_Type_Regular;
+ else if (S_ISFIFO(file_stat.st_mode))
+ pStatus->eType = osl_File_Type_Fifo;
+ else if (S_ISSOCK(file_stat.st_mode))
+ pStatus->eType = osl_File_Type_Socket;
+ else if (S_ISCHR(file_stat.st_mode) || S_ISBLK(file_stat.st_mode))
+ pStatus->eType = osl_File_Type_Special;
+ else
+ pStatus->eType = osl_File_Type_Unknown;
+
+ pStatus->uValidFields |= osl_FileStatus_Mask_Type;
+
+ pStatus->uAttributes = pItemImpl->d_attr;
+ pStatus->uValidFields |= osl_FileStatus_Mask_Attributes;
+
+ pStatus->uFileSize = file_stat.st_size;
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileSize;
+
+ if ( uFieldMask & osl_FileStatus_Mask_LinkTargetURL )
+ {
+ rtl_uString *ustrFullPath = NULL;
+
+ rtl_uString_newFromStr( &ustrFullPath, rtl_uString_getStr(pItemImpl->ustrFilePath) );
+ osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrLinkTargetURL );
+ rtl_uString_release( ustrFullPath );
+
+ pStatus->uValidFields |= osl_FileStatus_Mask_LinkTargetURL;
+ }
+
+ if ( uFieldMask & osl_FileStatus_Mask_FileURL )
+ {
+ rtl_uString *ustrFullPath = NULL;
+
+ rtl_uString_newFromStr( &ustrFullPath, rtl_uString_getStr(pItemImpl->ustrFilePath) );
+ osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrFileURL );
+ rtl_uString_release( ustrFullPath );
+ pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
+ }
+
+ return osl_File_E_None;
+}
+
+/****************************************************************************/
+/* osl_createDirectory */
+/****************************************************************************/
+
+oslFileError osl_createDirectory( rtl_uString* ustrDirectoryURL )
+{
+ char path[PATH_MAX];
+ oslFileError eRet;
+ APIRET rc;
+
+ OSL_ASSERT( ustrDirectoryURL );
+
+ /* convert directory url to system path */
+ eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+ rc = DosCreateDir( (PCSZ)path, NULL);
+ if (rc == ERROR_ACCESS_DENIED)
+ rc=ERROR_FILE_EXISTS;
+
+ if (!rc)
+ eRet = osl_File_E_None;
+ else
+ eRet = MapError( rc);
+
+ return eRet;
+}
+
+/****************************************************************************/
+/* osl_removeDirectory */
+/****************************************************************************/
+
+oslFileError osl_removeDirectory( rtl_uString* ustrDirectoryURL )
+{
+ char path[PATH_MAX];
+ oslFileError eRet;
+ APIRET rc;
+
+ OSL_ASSERT( ustrDirectoryURL );
+
+ /* convert directory url to system path */
+ eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+ rc = DosDeleteDir( (PCSZ)path);
+ if (!rc)
+ eRet = osl_File_E_None;
+ else
+ eRet = MapError( rc);
+
+ return eRet;
+}
+
+//#############################################
+int path_make_parent(sal_Unicode* path)
+{
+ int i = rtl_ustr_lastIndexOfChar(path, '/');
+
+ if (i > 0)
+ {
+ *(path + i) = 0;
+ return i;
+ }
+ else
+ return 0;
+}
+
+//#############################################
+int create_dir_with_callback(
+ sal_Unicode* directory_path,
+ oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
+ void* pData)
+{
+ int mode = S_IRWXU | S_IRWXG | S_IRWXO;
+
+ if (osl::mkdir(directory_path, mode) == 0)
+ {
+ if (aDirectoryCreationCallbackFunc)
+ {
+ rtl::OUString url;
+ osl::FileBase::getFileURLFromSystemPath(directory_path, url);
+ aDirectoryCreationCallbackFunc(pData, url.pData);
+ }
+ return 0;
+ }
+ return errno;
+}
+
+//#############################################
+oslFileError create_dir_recursively_(
+ sal_Unicode* dir_path,
+ oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
+ void* pData)
+{
+ OSL_PRECOND((rtl_ustr_getLength(dir_path) > 0) && ((dir_path + (rtl_ustr_getLength(dir_path) - 1)) != (dir_path + rtl_ustr_lastIndexOfChar(dir_path, '/'))), \
+ "Path must not end with a slash");
+
+ int native_err = create_dir_with_callback(
+ dir_path, aDirectoryCreationCallbackFunc, pData);
+
+ if (native_err == 0)
+ return osl_File_E_None;
+
+ if (native_err != ENOENT)
+ return oslTranslateFileError(OSL_FET_ERROR, native_err);
+
+ // we step back until '/a_dir' at maximum because
+ // we should get an error unequal ENOENT when
+ // we try to create 'a_dir' at '/' and would so
+ // return before
+ int pos = path_make_parent(dir_path);
+
+ oslFileError osl_error = create_dir_recursively_(
+ dir_path, aDirectoryCreationCallbackFunc, pData);
+
+ if (osl_File_E_None != osl_error)
+ return osl_error;
+
+ dir_path[pos] = '/';
+
+ return create_dir_recursively_(dir_path, aDirectoryCreationCallbackFunc, pData);
+}
+
+//#######################################
+oslFileError SAL_CALL osl_createDirectoryPath(
+ rtl_uString* aDirectoryUrl,
+ oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
+ void* pData)
+{
+ if (aDirectoryUrl == NULL)
+ return osl_File_E_INVAL;
+
+ rtl::OUString sys_path;
+ oslFileError osl_error = osl_getSystemPathFromFileURL_Ex(
+ aDirectoryUrl, &sys_path.pData, sal_False);
+
+ if (osl_error != osl_File_E_None)
+ return osl_error;
+
+ osl::systemPathRemoveSeparator(sys_path);
+
+ // const_cast because sys_path is a local copy which we want to modify inplace instead of
+ // coyp it into another buffer on the heap again
+ return create_dir_recursively_(sys_path.pData->buffer, aDirectoryCreationCallbackFunc, pData);
+}
+
+/****************************************************************************/
+/* osl_getCanonicalName */
+/****************************************************************************/
+
+oslFileError osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uString** pustrValidURL )
+{
+ OSL_ENSURE(sal_False, "osl_getCanonicalName not implemented");
+
+ rtl_uString_newFromString(pustrValidURL, ustrFileURL);
+ return osl_File_E_None;
+}
+
+
+/****************************************************************************/
+/* osl_setFileAttributes */
+/****************************************************************************/
+
+oslFileError osl_setFileAttributes( rtl_uString* ustrFileURL, sal_uInt64 uAttributes )
+{
+ char path[PATH_MAX];
+ oslFileError eRet;
+ FILESTATUS3 fsts3ConfigInfo;
+ ULONG ulBufSize = sizeof(FILESTATUS3);
+ APIRET rc = NO_ERROR;
+
+ OSL_ASSERT( ustrFileURL );
+
+ /* convert file url to system path */
+ eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+ /* query current attributes */
+ rc = DosQueryPathInfo( (PCSZ)path, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize);
+ if (rc != NO_ERROR)
+ return MapError( rc);
+
+ /* set/reset readonly/hidden (see w32\file.cxx) */
+ fsts3ConfigInfo.attrFile &= ~(FILE_READONLY | FILE_HIDDEN);
+ if ( uAttributes & osl_File_Attribute_ReadOnly )
+ fsts3ConfigInfo.attrFile |= FILE_READONLY;
+ if ( uAttributes & osl_File_Attribute_Hidden )
+ fsts3ConfigInfo.attrFile |= FILE_HIDDEN;
+
+ /* write new attributes */
+ rc = DosSetPathInfo( (PCSZ)path, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize, 0);
+ if (rc != NO_ERROR)
+ return MapError( rc);
+
+ /* everything ok */
+ return osl_File_E_None;
+}
+
+/****************************************************************************/
+/* osl_setFileTime */
+/****************************************************************************/
+
+oslFileError osl_setFileTime( rtl_uString* ustrFileURL, const TimeValue* pCreationTime,
+ const TimeValue* pLastAccessTime, const TimeValue* pLastWriteTime )
+{
+ char path[PATH_MAX];
+ oslFileError eRet;
+
+ OSL_ASSERT( ustrFileURL );
+
+ /* convert file url to system path */
+ eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
+ if( eRet != osl_File_E_None )
+ return eRet;
+
+ return osl_psz_setFileTime( path, pCreationTime, pLastAccessTime, pLastWriteTime );
+}
+
+/******************************************************************************
+ *
+ * Exported Module Functions
+ * (independent of C or Unicode Strings)
+ *
+ *****************************************************************************/
+
+
+/*******************************************
+ osl_readFile
+********************************************/
+
+oslFileError osl_readFile(oslFileHandle Handle, void* pBuffer, sal_uInt64 uBytesRequested, sal_uInt64* pBytesRead)
+{
+ ssize_t nBytes = 0;
+ oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
+
+ if ((0 == pHandleImpl) || (pHandleImpl->fd < 0) || (0 == pBuffer) || (0 == pBytesRead))
+ return osl_File_E_INVAL;
+
+ nBytes = read(pHandleImpl->fd, pBuffer, uBytesRequested);
+
+ if (-1 == nBytes)
+ return oslTranslateFileError(OSL_FET_ERROR, errno);
+
+ *pBytesRead = nBytes;
+ return osl_File_E_None;
+}
+
+/*******************************************
+ osl_writeFile
+********************************************/
+
+oslFileError osl_writeFile(oslFileHandle Handle, const void* pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64* pBytesWritten)
+{
+ ssize_t nBytes = 0;
+ oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
+
+ OSL_ASSERT(pHandleImpl);
+ OSL_ASSERT(pBuffer);
+ OSL_ASSERT(pBytesWritten);
+
+ if ((0 == pHandleImpl) || (0 == pBuffer) || (0 == pBytesWritten))
+ return osl_File_E_INVAL;
+
+ OSL_ASSERT(pHandleImpl->fd >= 0);
+
+ if (pHandleImpl->fd < 0)
+ return osl_File_E_INVAL;
+
+ nBytes = write(pHandleImpl->fd, pBuffer, uBytesToWrite);
+
+ if (-1 == nBytes)
+ return oslTranslateFileError(OSL_FET_ERROR, errno);
+
+ *pBytesWritten = nBytes;
+ return osl_File_E_None;
+}
+
+/*******************************************
+ osl_writeFile
+********************************************/
+
+oslFileError osl_setFilePos( oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uPos )
+{
+ oslFileHandleImpl* pHandleImpl=0;
+ int nRet=0;
+ off_t nOffset=0;
+
+ pHandleImpl = (oslFileHandleImpl*) Handle;
+ if ( pHandleImpl == 0 )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ if ( pHandleImpl->fd < 0 )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ /* FIXME mfe: setFilePos: Do we have any runtime function to determine LONG_MAX? */
+ if ( uPos > LONG_MAX )
+ {
+ return osl_File_E_OVERFLOW;
+ }
+
+ nOffset=(off_t)uPos;
+
+ switch(uHow)
+ {
+ case osl_Pos_Absolut:
+ nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_SET);
+ break;
+
+ case osl_Pos_Current:
+ nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_CUR);
+ break;
+
+ case osl_Pos_End:
+ nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_END);
+ break;
+
+ default:
+ return osl_File_E_INVAL;
+ }
+
+ if ( nOffset < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ return osl_File_E_None;
+}
+
+/************************************************
+ * osl_getFilePos
+ ***********************************************/
+
+oslFileError osl_getFilePos( oslFileHandle Handle, sal_uInt64* pPos )
+{
+ oslFileHandleImpl* pHandleImpl=0;
+ off_t nOffset=0;
+ int nRet=0;
+
+ pHandleImpl = (oslFileHandleImpl*) Handle;
+ if ( pHandleImpl == 0 || pPos == 0)
+ {
+ return osl_File_E_INVAL;
+ }
+
+ if ( pHandleImpl->fd < 0 )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ nOffset = lseek(pHandleImpl->fd,0,SEEK_CUR);
+
+ if (nOffset < 0)
+ {
+ nRet =errno;
+
+ /* *pPos =0; */
+
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ *pPos=nOffset;
+
+ return osl_File_E_None;
+}
+
+/****************************************************************************
+ * osl_getFileSize
+ ****************************************************************************/
+
+oslFileError osl_getFileSize( oslFileHandle Handle, sal_uInt64* pSize )
+{
+ oslFileHandleImpl* pHandleImpl=(oslFileHandleImpl*) Handle;
+ if (pHandleImpl == 0)
+ return osl_File_E_INVAL;
+
+ struct stat file_stat;
+ if (fstat(pHandleImpl->fd, &file_stat) == -1)
+ return oslTranslateFileError(OSL_FET_ERROR, errno);
+
+ *pSize = file_stat.st_size;
+ return osl_File_E_None;
+}
+
+/************************************************
+ * osl_setFileSize
+ ***********************************************/
+
+oslFileError osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize )
+{
+ oslFileHandleImpl* pHandleImpl=0;
+ off_t nOffset=0;
+
+ pHandleImpl = (oslFileHandleImpl*) Handle;
+ if ( pHandleImpl == 0 )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ if ( pHandleImpl->fd < 0 )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ /* FIXME: mfe: setFileSize: Do we have any runtime function to determine LONG_MAX? */
+ if ( uSize > LONG_MAX )
+ {
+ return osl_File_E_OVERFLOW;
+ }
+
+ nOffset = (off_t)uSize;
+ if (ftruncate (pHandleImpl->fd, nOffset) < 0)
+ {
+ /* Failure. Try fallback algorithm */
+ oslFileError result;
+ struct stat aStat;
+ off_t nCurPos;
+
+ /* Save original result */
+ result = oslTranslateFileError (OSL_FET_ERROR, errno);
+ PERROR("ftruncate", "Try osl_setFileSize [fallback]\n");
+
+ /* Check against current size. Fail upon 'shrink' */
+ if (fstat (pHandleImpl->fd, &aStat) < 0)
+ {
+ PERROR("ftruncate: fstat", "Out osl_setFileSize [error]\n");
+ return (result);
+ }
+ if ((0 <= nOffset) && (nOffset <= aStat.st_size))
+ {
+ /* Failure upon 'shrink'. Return original result */
+ return (result);
+ }
+
+ /* Save current position */
+ nCurPos = (off_t)lseek (pHandleImpl->fd, (off_t)0, SEEK_CUR);
+ if (nCurPos == (off_t)(-1))
+ {
+ PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
+ return (result);
+ }
+
+ /* Try 'expand' via 'lseek()' and 'write()' */
+ if (lseek (pHandleImpl->fd, (off_t)(nOffset - 1), SEEK_SET) < 0)
+ {
+ PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
+ return (result);
+ }
+ if (write (pHandleImpl->fd, (char*)"", (size_t)1) < 0)
+ {
+ /* Failure. Restore saved position */
+ PERROR("ftruncate: write", "Out osl_setFileSize [error]\n");
+ if (lseek (pHandleImpl->fd, (off_t)nCurPos, SEEK_SET) < 0)
+ {
+#ifdef DEBUG_OSL_FILE
+ perror("ftruncate: lseek");
+#endif /* DEBUG_OSL_FILE */
+ }
+ return (result);
+ }
+
+ /* Success. Restore saved position */
+ if (lseek (pHandleImpl->fd, (off_t)nCurPos, SEEK_SET) < 0)
+ {
+ PERROR("ftruncate: lseek", "Out osl_setFileSize [error]");
+ return (result);
+ }
+ }
+
+ return (osl_File_E_None);
+}
+
+/*###############################################*/
+oslFileError SAL_CALL osl_syncFile(oslFileHandle Handle)
+{
+ oslFileHandleImpl* handle_impl = (oslFileHandleImpl*)Handle;
+
+ if (handle_impl == 0)
+ return osl_File_E_INVAL;
+
+ if (fsync(handle_impl->fd) == -1)
+ return oslTranslateFileError(OSL_FET_ERROR, errno);
+
+ return osl_File_E_None;
+}
+
+/******************************************************************************
+ *
+ * C-String Versions of Exported Module Functions
+ *
+ *****************************************************************************/
+
+#ifdef HAVE_STATFS_H
+
+#if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
+# define __OSL_STATFS_STRUCT struct statfs
+# define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
+# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
+# define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
+# define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
+
+/* always return true if queried for the properties of
+ the file system. If you think this is wrong under any
+ of the target platforms fix it!!!! */
+# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
+# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
+#endif /* FREEBSD || NETBSD */
+
+#if defined(LINUX)
+# define __OSL_NFS_SUPER_MAGIC 0x6969
+# define __OSL_SMB_SUPER_MAGIC 0x517B
+# define __OSL_MSDOS_SUPER_MAGIC 0x4d44
+# define __OSL_NTFS_SUPER_MAGIC 0x5346544e
+# define __OSL_STATFS_STRUCT struct statfs
+# define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
+# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
+# define __OSL_STATFS_IS_NFS(a) (__OSL_NFS_SUPER_MAGIC == (a).f_type)
+# define __OSL_STATFS_IS_SMB(a) (__OSL_SMB_SUPER_MAGIC == (a).f_type)
+# define __OSL_STATFS_ISREMOTE(a) (__OSL_STATFS_IS_NFS((a)) || __OSL_STATFS_IS_SMB((a)))
+# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type) && (__OSL_NTFS_SUPER_MAGIC != (a).f_type))
+# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type))
+#endif /* LINUX */
+
+#if defined(SOLARIS)
+# define __OSL_STATFS_STRUCT struct statvfs
+# define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
+# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
+# define __OSL_STATFS_TYPENAME(a) ((a).f_basetype)
+# define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
+
+/* always return true if queried for the properties of
+ the file system. If you think this is wrong under any
+ of the target platforms fix it!!!! */
+# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
+# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
+#endif /* SOLARIS */
+
+# define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
+
+#else /* no statfs available */
+
+# define __OSL_STATFS_STRUCT struct dummy {int i;}
+# define __OSL_STATFS_INIT(a) ((void)0)
+# define __OSL_STATFS(dir, sfs) (1)
+# define __OSL_STATFS_ISREMOTE(sfs) (0)
+# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
+# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
+#endif /* HAVE_STATFS_H */
+
+
+static oslFileError osl_psz_getVolumeInformation (
+ const sal_Char* pszDirectory, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask)
+{
+ __OSL_STATFS_STRUCT sfs;
+
+ if (!pInfo)
+ return osl_File_E_INVAL;
+
+ __OSL_STATFS_INIT(sfs);
+
+ pInfo->uValidFields = 0;
+ pInfo->uAttributes = 0;
+
+ if ((__OSL_STATFS(pszDirectory, &sfs)) < 0)
+ {
+ oslFileError result = oslTranslateFileError(OSL_FET_ERROR, errno);
+ return (result);
+ }
+
+ /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
+ if (uFieldMask & osl_VolumeInfo_Mask_Attributes)
+ {
+ if (__OSL_STATFS_ISREMOTE(sfs))
+ pInfo->uAttributes |= osl_Volume_Attribute_Remote;
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
+ }
+
+ if (uFieldMask & osl_VolumeInfo_Mask_FileSystemCaseHandling)
+ {
+ if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs))
+ pInfo->uAttributes |= osl_Volume_Attribute_Case_Sensitive;
+
+ if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs))
+ pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
+ }
+
+ pInfo->uTotalSpace = 0;
+ pInfo->uFreeSpace = 0;
+ pInfo->uUsedSpace = 0;
+
+#if defined(__OSL_STATFS_BLKSIZ)
+
+ if ((uFieldMask & osl_VolumeInfo_Mask_TotalSpace) ||
+ (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
+ {
+ pInfo->uTotalSpace = __OSL_STATFS_BLKSIZ(sfs);
+ pInfo->uTotalSpace *= (sal_uInt64)(sfs.f_blocks);
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace;
+ }
+
+ if ((uFieldMask & osl_VolumeInfo_Mask_FreeSpace) ||
+ (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
+ {
+ pInfo->uFreeSpace = __OSL_STATFS_BLKSIZ(sfs);
+
+ if (getuid() == 0)
+ pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bfree);
+ else
+ pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bavail);
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_FreeSpace;
+ }
+
+#endif /* __OSL_STATFS_BLKSIZ */
+
+ if ((pInfo->uValidFields & osl_VolumeInfo_Mask_TotalSpace) &&
+ (pInfo->uValidFields & osl_VolumeInfo_Mask_FreeSpace ))
+ {
+ pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_UsedSpace;
+ }
+
+ pInfo->uMaxNameLength = 0;
+ if (uFieldMask & osl_VolumeInfo_Mask_MaxNameLength)
+ {
+ long nLen = pathconf(pszDirectory, _PC_NAME_MAX);
+ if (nLen > 0)
+ {
+ pInfo->uMaxNameLength = (sal_uInt32)nLen;
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
+ }
+ }
+
+ pInfo->uMaxPathLength = 0;
+ if (uFieldMask & osl_VolumeInfo_Mask_MaxPathLength)
+ {
+ long nLen = pathconf (pszDirectory, _PC_PATH_MAX);
+ if (nLen > 0)
+ {
+ pInfo->uMaxPathLength = (sal_uInt32)nLen;
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
+ }
+ }
+
+#if defined(__OSL_STATFS_TYPENAME)
+
+ if (uFieldMask & osl_VolumeInfo_Mask_FileSystemName)
+ {
+ rtl_string2UString(
+ &(pInfo->ustrFileSystemName),
+ __OSL_STATFS_TYPENAME(sfs),
+ rtl_str_getLength(__OSL_STATFS_TYPENAME(sfs)),
+ osl_getThreadTextEncoding(),
+ OUSTRING_TO_OSTRING_CVTFLAGS);
+ OSL_ASSERT(pInfo->ustrFileSystemName != 0);
+
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
+ }
+
+#endif /* __OSL_STATFS_TYPENAME */
+
+ if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
+ {
+ /* FIXME: check also entries in mntent for the device
+ and fill it with correct values */
+
+ *pInfo->pDeviceHandle = osl_isFloppyDrive(pszDirectory);
+
+ if (*pInfo->pDeviceHandle)
+ {
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
+ pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
+ pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
+ }
+ }
+ return osl_File_E_None;
+}
+
+/******************************************
+ * osl_psz_setFileTime
+ *****************************************/
+
+static oslFileError osl_psz_setFileTime( const sal_Char* pszFilePath,
+ const TimeValue* /*pCreationTime*/,
+ const TimeValue* pLastAccessTime,
+ const TimeValue* pLastWriteTime )
+{
+ int nRet=0;
+ struct utimbuf aTimeBuffer;
+ struct stat aFileStat;
+#ifdef DEBUG_OSL_FILE
+ struct tm* pTM=0;
+#endif
+
+ nRet = lstat(pszFilePath,&aFileStat);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"File Times are (in localtime):\n");
+ pTM=localtime(&aFileStat.st_ctime);
+ fprintf(stderr,"CreationTime is '%s'\n",asctime(pTM));
+ pTM=localtime(&aFileStat.st_atime);
+ fprintf(stderr,"AccessTime is '%s'\n",asctime(pTM));
+ pTM=localtime(&aFileStat.st_mtime);
+ fprintf(stderr,"Modification is '%s'\n",asctime(pTM));
+
+ fprintf(stderr,"File Times are (in UTC):\n");
+ fprintf(stderr,"CreationTime is '%s'\n",ctime(&aFileStat.st_ctime));
+ fprintf(stderr,"AccessTime is '%s'\n",ctime(&aTimeBuffer.actime));
+ fprintf(stderr,"Modification is '%s'\n",ctime(&aTimeBuffer.modtime));
+#endif
+
+ if ( pLastAccessTime != 0 )
+ {
+ aTimeBuffer.actime=pLastAccessTime->Seconds;
+ }
+ else
+ {
+ aTimeBuffer.actime=aFileStat.st_atime;
+ }
+
+ if ( pLastWriteTime != 0 )
+ {
+ aTimeBuffer.modtime=pLastWriteTime->Seconds;
+ }
+ else
+ {
+ aTimeBuffer.modtime=aFileStat.st_mtime;
+ }
+
+ /* mfe: Creation time not used here! */
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"File Times are (in localtime):\n");
+ pTM=localtime(&aFileStat.st_ctime);
+ fprintf(stderr,"CreationTime now '%s'\n",asctime(pTM));
+ pTM=localtime(&aTimeBuffer.actime);
+ fprintf(stderr,"AccessTime now '%s'\n",asctime(pTM));
+ pTM=localtime(&aTimeBuffer.modtime);
+ fprintf(stderr,"Modification now '%s'\n",asctime(pTM));
+
+ fprintf(stderr,"File Times are (in UTC):\n");
+ fprintf(stderr,"CreationTime now '%s'\n",ctime(&aFileStat.st_ctime));
+ fprintf(stderr,"AccessTime now '%s'\n",ctime(&aTimeBuffer.actime));
+ fprintf(stderr,"Modification now '%s'\n",ctime(&aTimeBuffer.modtime));
+#endif
+
+ nRet=utime(pszFilePath,&aTimeBuffer);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ return osl_File_E_None;
+}
+
+
+/*****************************************
+ * osl_psz_removeFile
+ ****************************************/
+#if 0
+static oslFileError osl_psz_removeFile( const sal_Char* pszPath )
+{
+ int nRet=0;
+ struct stat aStat;
+
+ nRet = stat(pszPath,&aStat);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ if ( S_ISDIR(aStat.st_mode) )
+ {
+ return osl_File_E_ISDIR;
+ }
+
+ nRet = unlink(pszPath);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ return osl_File_E_None;
+}
+#endif
+
+/*****************************************
+ * osl_psz_createDirectory
+ ****************************************/
+#if 0
+static oslFileError osl_psz_createDirectory( const sal_Char* pszPath )
+{
+ int nRet=0;
+ int mode = S_IRWXU | S_IRWXG | S_IRWXO;
+
+ nRet = mkdir(pszPath,mode);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ return osl_File_E_None;
+}
+#endif
+/*****************************************
+ * osl_psz_removeDirectory
+ ****************************************/
+#if 0
+static oslFileError osl_psz_removeDirectory( const sal_Char* pszPath )
+{
+ int nRet=0;
+
+ nRet = rmdir(pszPath);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ return osl_File_E_None;
+}
+#endif
+/*****************************************
+ * oslDoMoveFile
+ ****************************************/
+#if 0
+static oslFileError oslDoMoveFile( const sal_Char* pszPath, const sal_Char* pszDestPath)
+{
+ oslFileError tErr=osl_File_E_invalidError;
+
+ tErr = osl_psz_moveFile(pszPath,pszDestPath);
+ if ( tErr == osl_File_E_None )
+ {
+ return tErr;
+ }
+
+ if ( tErr != osl_File_E_XDEV )
+ {
+ return tErr;
+ }
+
+ tErr=osl_psz_copyFile(pszPath,pszDestPath);
+
+ if ( tErr != osl_File_E_None )
+ {
+ oslFileError tErrRemove;
+ tErrRemove=osl_psz_removeFile(pszDestPath);
+ return tErr;
+ }
+
+ tErr=osl_psz_removeFile(pszPath);
+
+ return tErr;
+}
+#endif
+/*****************************************
+ * osl_psz_moveFile
+ ****************************************/
+#if 0
+static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath)
+{
+
+ int nRet = 0;
+
+ nRet = rename(pszPath,pszDestPath);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ return osl_File_E_None;
+}
+#endif
+/*****************************************
+ * osl_psz_copyFile
+ ****************************************/
+#if 0
+static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
+{
+ time_t nAcTime=0;
+ time_t nModTime=0;
+ uid_t nUID=0;
+ gid_t nGID=0;
+ int nRet=0;
+ mode_t nMode=0;
+ struct stat aFileStat;
+ oslFileError tErr=osl_File_E_invalidError;
+ size_t nSourceSize=0;
+ int DestFileExists=1;
+
+ /* mfe: does the source file really exists? */
+ nRet = lstat(pszPath,&aFileStat);
+
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+ return oslTranslateFileError(OSL_FET_ERROR, nRet);
+ }
+
+ /* mfe: we do only copy files here! */
+ if ( S_ISDIR(aFileStat.st_mode) )
+ {
+ return osl_File_E_ISDIR;
+ }
+
+ nSourceSize=(size_t)aFileStat.st_size;
+ nMode=aFileStat.st_mode;
+ nAcTime=aFileStat.st_atime;
+ nModTime=aFileStat.st_mtime;
+ nUID=aFileStat.st_uid;
+ nGID=aFileStat.st_gid;
+
+ nRet = stat(pszDestPath,&aFileStat);
+ if ( nRet < 0 )
+ {
+ nRet=errno;
+
+ if ( nRet == ENOENT )
+ {
+ DestFileExists=0;
+ }
+/* return oslTranslateFileError(nRet);*/
+ }
+
+ /* mfe: the destination file must not be a directory! */
+ if ( nRet == 0 && S_ISDIR(aFileStat.st_mode) )
+ {
+ return osl_File_E_ISDIR;
+ }
+ else
+ {
+ /* mfe: file does not exists or is no dir */
+ }
+
+ tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
+
+ if ( tErr != osl_File_E_None )
+ {
+ return tErr;
+ }
+
+ /*
+ * mfe: ignore return code
+ * since only the success of the copy is
+ * important
+ */
+ oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
+
+ return tErr;
+}
+#endif
+
+/******************************************************************************
+ *
+ * Utility Functions
+ *
+ *****************************************************************************/
+
+
+/*****************************************
+ * oslMakeUStrFromPsz
+ ****************************************/
+
+rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr, rtl_uString** ustrValid)
+{
+ rtl_string2UString(
+ ustrValid,
+ pszStr,
+ rtl_str_getLength( pszStr ),
+ osl_getThreadTextEncoding(),
+ OUSTRING_TO_OSTRING_CVTFLAGS );
+ OSL_ASSERT(*ustrValid != 0);
+
+ return *ustrValid;
+}
+
+/*****************************************************************************
+ * UnicodeToText
+ * converting unicode to text manually saves us the penalty of a temporary
+ * rtl_String object.
+ ****************************************************************************/
+
+int UnicodeToText( char * buffer, size_t bufLen, const sal_Unicode * uniText, sal_Int32 uniTextLen )
+{
+ rtl_UnicodeToTextConverter hConverter;
+ sal_uInt32 nInfo;
+ sal_Size nSrcChars, nDestBytes;
+
+ /* stolen from rtl/string.c */
+ hConverter = rtl_createUnicodeToTextConverter( osl_getThreadTextEncoding() );
+
+ nDestBytes = rtl_convertUnicodeToText( hConverter, 0, uniText, uniTextLen,
+ buffer, bufLen,
+ OUSTRING_TO_OSTRING_CVTFLAGS | RTL_UNICODETOTEXT_FLAGS_FLUSH,
+ &nInfo, &nSrcChars );
+
+ rtl_destroyUnicodeToTextConverter( hConverter );
+
+ if( nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
+ {
+ errno = EOVERFLOW;
+ return 0;
+ }
+
+ /* ensure trailing '\0' */
+ buffer[nDestBytes] = '\0';
+
+ return nDestBytes;
+}
+
+/*****************************************************************************
+ TextToUnicode
+
+ @param text
+ The text to convert.
+
+ @param text_buffer_size
+ The number of characters.
+
+ @param unic_text
+ The unicode buffer.
+
+ @param unic_text_buffer_size
+ The size in characters of the unicode buffer.
+
+ ****************************************************************************/
+
+int TextToUnicode(
+ const char* text,
+ size_t text_buffer_size,
+ sal_Unicode* unic_text,
+ sal_Int32 unic_text_buffer_size)
+{
+ rtl_TextToUnicodeConverter hConverter;
+ sal_uInt32 nInfo;
+ sal_Size nSrcChars;
+ sal_Size nDestBytes;
+
+ /* stolen from rtl/string.c */
+ hConverter = rtl_createTextToUnicodeConverter(osl_getThreadTextEncoding());
+
+ nDestBytes = rtl_convertTextToUnicode(hConverter,
+ 0,
+ text, text_buffer_size,
+ unic_text, unic_text_buffer_size,
+ OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_FLUSH,
+ &nInfo, &nSrcChars);
+
+ rtl_destroyTextToUnicodeConverter(hConverter);
+
+ if (nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL)
+ {
+ errno = EOVERFLOW;
+ return 0;
+ }
+
+ /* ensure trailing '\0' */
+ unic_text[nDestBytes] = '\0';
+
+ return nDestBytes;
+}
+
+/******************************************************************************
+ *
+ * GENERIC FLOPPY FUNCTIONS
+ *
+ *****************************************************************************/
+
+
+/*****************************************
+ * osl_unmountVolumeDevice
+ ****************************************/
+
+oslFileError osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
+{
+ oslFileError tErr = osl_File_E_NOSYS;
+
+ tErr = osl_unmountFloppy(Handle);
+
+ /* Perhaps current working directory is set to mount point */
+
+ if ( tErr )
+ {
+ sal_Char *pszHomeDir = getenv("HOME");
+
+ if ( pszHomeDir && strlen( pszHomeDir ) && 0 == chdir( pszHomeDir ) )
+ {
+ /* try again */
+
+ tErr = osl_unmountFloppy(Handle);
+
+ OSL_ENSURE( tErr, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
+ }
+ }
+
+ return tErr;
+}
+
+/*****************************************
+ * osl_automountVolumeDevice
+ ****************************************/
+
+oslFileError osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
+{
+ oslFileError tErr = osl_File_E_NOSYS;
+
+ tErr = osl_mountFloppy(Handle);
+
+ return tErr;
+}
+
+/*****************************************
+ * osl_getVolumeDeviceMountPath
+ ****************************************/
+
+oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
+{
+ oslVolumeDeviceHandleImpl* pItem = (oslVolumeDeviceHandleImpl*) Handle;
+ sal_Char Buffer[PATH_MAX];
+
+ Buffer[0] = '\0';
+
+ if ( pItem == 0 || pstrPath == 0 )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+ return osl_File_E_INVAL;
+ }
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"Handle is:\n");
+ osl_printFloppyHandle(pItem);
+#endif
+
+ snprintf(Buffer, sizeof(Buffer), "file://%s", pItem->pszMountPoint);
+
+#ifdef DEBUG_OSL_FILE
+ fprintf(stderr,"Mount Point is: '%s'\n",Buffer);
+#endif
+
+ oslMakeUStrFromPsz(Buffer, pstrPath);
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * osl_acquireVolumeDeviceHandle
+ ****************************************/
+
+oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
+{
+ oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
+
+ if ( pItem == 0 )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ ++pItem->RefCount;
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * osl_releaseVolumeDeviceHandle
+ ****************************************/
+
+oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
+{
+ oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
+
+ if ( pItem == 0 )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+ return osl_File_E_INVAL;
+ }
+
+ --pItem->RefCount;
+
+ if ( pItem->RefCount == 0 )
+ {
+ rtl_freeMemory(pItem);
+ }
+
+ return osl_File_E_None;
+}
+
+/*****************************************
+ * osl_newVolumeDeviceHandleImpl
+ ****************************************/
+
+static oslVolumeDeviceHandleImpl* osl_newVolumeDeviceHandleImpl()
+{
+ oslVolumeDeviceHandleImpl* pHandle;
+ const size_t nSizeOfHandle = sizeof(oslVolumeDeviceHandleImpl);
+
+ pHandle = (oslVolumeDeviceHandleImpl*) rtl_allocateMemory (nSizeOfHandle);
+ if (pHandle != NULL)
+ {
+ pHandle->ident[0] = 'O';
+ pHandle->ident[1] = 'V';
+ pHandle->ident[2] = 'D';
+ pHandle->ident[3] = 'H';
+ pHandle->pszMountPoint[0] = '\0';
+ pHandle->pszFilePath[0] = '\0';
+ pHandle->pszDevice[0] = '\0';
+ pHandle->RefCount = 1;
+ }
+ return pHandle;
+}
+
+/*****************************************
+ * osl_freeVolumeDeviceHandleImpl
+ ****************************************/
+
+static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl* pHandle)
+{
+ if (pHandle != NULL)
+ rtl_freeMemory (pHandle);
+}
+
+
+/******************************************************************************
+ *
+ * OS/2 FLOPPY FUNCTIONS
+ *
+ *****************************************************************************/
+
+#if defined(OS2)
+static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath)
+{
+ return NULL;
+}
+
+static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
+{
+ return osl_File_E_BUSY;
+}
+
+static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
+{
+ return osl_File_E_BUSY;
+}
+
+static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
+{
+ return sal_False;
+}
+
+static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice)
+{
+ return sal_False;
+}
+
+
+#ifdef DEBUG_OSL_FILE
+static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* pItem)
+{
+ if (pItem == 0 )
+ {
+ fprintf(stderr,"NULL Handle\n");
+ return;
+ }
+ if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
+ {
+#ifdef TRACE_OSL_FILE
+ fprintf(stderr,"Invalid Handle]\n");
+#endif
+ return;
+ }
+
+
+ fprintf(stderr,"MountPoint : '%s'\n",pItem->pszMountPoint);
+ fprintf(stderr,"FilePath : '%s'\n",pItem->pszFilePath);
+ fprintf(stderr,"Device : '%s'\n",pItem->pszDevice);
+
+ return;
+}
+#endif
+
+#endif /* OS2 */