| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_tools.hxx" |
| |
| #include <stdio.h> |
| #include <ctype.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <utime.h> |
| #if defined HPUX || defined LINUX |
| #include <mntent.h> |
| #define mnttab mntent |
| #elif defined SCO |
| #include <mnttab.h> |
| #elif defined AIX |
| #include <sys/mntctl.h> |
| #include <sys/vmount.h> |
| extern "C" int mntctl( int cmd, size_t size, char* buf ); |
| #elif defined(NETBSD) |
| #include <sys/mount.h> |
| #elif defined(FREEBSD) || defined(MACOSX) |
| #elif defined DECUNIX |
| struct mnttab |
| { |
| char *mnt_dir; |
| char *mnt_fsname; |
| }; |
| #else |
| #include <sys/mnttab.h> |
| #endif |
| |
| #ifndef MAXPATHLEN |
| #define MAXPATHLEN 1024 |
| #endif |
| |
| #include <tools/debug.hxx> |
| #include <tools/list.hxx> |
| #include <tools/fsys.hxx> |
| #include "comdep.hxx" |
| #include <rtl/instance.hxx> |
| |
| DECLARE_LIST( DirEntryList, DirEntry* ) |
| DECLARE_LIST( FSysSortList, FSysSort* ) |
| DECLARE_LIST( FileStatList, FileStat* ) |
| |
| #if defined SOLARIS || defined SINIX |
| #define MOUNTSPECIAL mnt_special |
| #define MOUNTPOINT mnt_mountp |
| #define MOUNTOPTS mnt_mntopts |
| #define MOUNTFS mnt_fstype |
| #elif defined SCO |
| #define MNTTAB "/etc/mnttab" |
| #define MOUNTSPECIAL mt_dev |
| #define MOUNTPOINT mt_filsys |
| #else |
| #define MOUNTSPECIAL mnt_fsname |
| #define MOUNTPOINT mnt_dir |
| #define MOUNTFS mnt_type |
| #endif |
| |
| struct mymnttab |
| { |
| dev_t mountdevice; |
| ByteString mountspecial; |
| ByteString mountpoint; |
| ByteString mymnttab_filesystem; |
| mymnttab() { mountdevice = (dev_t) -1; } |
| }; |
| |
| |
| #if defined(NETBSD) || defined(FREEBSD) || defined(MACOSX) |
| sal_Bool GetMountEntry(dev_t /* dev */, struct mymnttab * /* mytab */ ) |
| { |
| DBG_WARNING( "Sorry, not implemented: GetMountEntry" ); |
| return sal_False; |
| } |
| |
| #elif defined AIX |
| sal_Bool GetMountEntry(dev_t dev, struct mymnttab *mytab) |
| { |
| int bufsize; |
| if (mntctl (MCTL_QUERY, sizeof bufsize, (char*) &bufsize)) |
| return sal_False; |
| |
| char* buffer = (char *)malloc( bufsize * sizeof(char) ); |
| if (mntctl (MCTL_QUERY, bufsize, buffer) != -1) |
| for ( char* vmt = buffer; |
| vmt < buffer + bufsize; |
| vmt += ((struct vmount*)vmt)->vmt_length) |
| { |
| struct stat buf; |
| char *mountp = vmt2dataptr((struct vmount*)vmt, VMT_STUB); |
| if ((stat (mountp, &buf) != -1) && (buf.st_dev == dev)) |
| { |
| mytab->mountpoint = mountp; |
| mytab->mountspecial |
| = vmt2dataptr((struct vmount*)vmt, VMT_HOSTNAME); |
| if (mytab->mountspecial.Len()) |
| mytab->mountspecial += ':'; |
| mytab->mountspecial |
| += vmt2dataptr((struct vmount*)vmt, VMT_OBJECT); |
| mytab->mountdevice = dev; |
| free( buffer ); |
| return sal_True; |
| } |
| } |
| free( buffer ); |
| return sal_False; |
| } |
| |
| #else |
| |
| |
| static sal_Bool GetMountEntry(dev_t dev, struct mymnttab *mytab) |
| { |
| #if defined SOLARIS || defined SINIX |
| FILE *fp = fopen (MNTTAB, "r"); |
| if (! fp) |
| return sal_False; |
| struct mnttab mnt[1]; |
| while (getmntent (fp, mnt) != -1) |
| #elif defined SCO |
| FILE *fp = fopen (MNTTAB, "r"); |
| if (! fp) |
| return sal_False; |
| struct mnttab mnt[1]; |
| while (fread (&mnt, sizeof mnt, 1, fp) > 0) |
| #elif defined DECUNIX || defined AIX |
| FILE *fp = NULL; |
| if (! fp) |
| return sal_False; |
| struct mnttab mnt[1]; |
| while ( 0 ) |
| #else |
| FILE *fp = setmntent (MOUNTED, "r"); |
| if (! fp) |
| return sal_False; |
| struct mnttab *mnt; |
| while ((mnt = getmntent (fp)) != NULL) |
| #endif |
| { |
| #ifdef SOLARIS |
| char *devopt = NULL; |
| if ( mnt->MOUNTOPTS != NULL ) |
| devopt = strstr (mnt->MOUNTOPTS, "dev="); |
| if (devopt) |
| { |
| if (dev != (dev_t) strtoul (devopt+4, NULL, 16)) |
| continue; |
| } |
| else |
| #endif |
| { |
| struct stat buf; |
| if ((stat (mnt->MOUNTPOINT, &buf) == -1) || (buf.st_dev != dev)) |
| continue; |
| } |
| # ifdef LINUX |
| /* #61624# File mit setmntent oeffnen und mit fclose schliessen stoesst |
| bei der glibc-2.1 auf wenig Gegenliebe */ |
| endmntent( fp ); |
| # else |
| fclose (fp); |
| # endif |
| mytab->mountspecial = mnt->MOUNTSPECIAL; |
| mytab->mountpoint = mnt->MOUNTPOINT; |
| mytab->mountdevice = dev; |
| #ifndef SCO |
| mytab->mymnttab_filesystem = mnt->MOUNTFS; |
| #else |
| mytab->mymnttab_filesystem = "ext2"; //default ist case sensitiv unter unix |
| #endif |
| return sal_True; |
| } |
| # ifdef LINUX |
| /* #61624# dito */ |
| endmntent( fp ); |
| # else |
| fclose (fp); |
| # endif |
| return sal_False; |
| } |
| |
| #endif |
| |
| /************************************************************************ |
| |* |
| |* DirEntry::IsCaseSensitive() |
| |* |
| |* Beschreibung |
| |* Ersterstellung TPF 25.02.1999 |
| |* Letzte Aenderung TPF 25.02.1999 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::IsCaseSensitive( FSysPathStyle eFormatter ) const |
| { |
| |
| if (eFormatter==FSYS_STYLE_HOST) |
| { |
| #ifdef NETBSD |
| return sal_True; |
| #else |
| struct stat buf; |
| DirEntry aPath(*this); |
| aPath.ToAbs(); |
| |
| while (stat (ByteString(aPath.GetFull(), osl_getThreadTextEncoding()).GetBuffer(), &buf)) |
| { |
| if (aPath.Level() == 1) |
| { |
| return sal_True; // ich bin unter UNIX, also ist der default im Zweifelsfall case sensitiv |
| } |
| aPath = aPath [1]; |
| } |
| |
| struct mymnttab fsmnt; |
| GetMountEntry(buf.st_dev, &fsmnt); |
| if ((fsmnt.mymnttab_filesystem.CompareTo("msdos")==COMPARE_EQUAL) || |
| (fsmnt.mymnttab_filesystem.CompareTo("umsdos")==COMPARE_EQUAL) || |
| (fsmnt.mymnttab_filesystem.CompareTo("vfat")==COMPARE_EQUAL) || |
| (fsmnt.mymnttab_filesystem.CompareTo("hpfs")==COMPARE_EQUAL) || |
| (fsmnt.mymnttab_filesystem.CompareTo("smb") ==COMPARE_EQUAL) || |
| (fsmnt.mymnttab_filesystem.CompareTo("ncpfs")==COMPARE_EQUAL)) |
| { |
| return sal_False; |
| } |
| else |
| { |
| return sal_True; |
| } |
| #endif |
| } |
| else |
| { |
| sal_Bool isCaseSensitive = sal_True; // ich bin unter UNIX, also ist der default im Zweifelsfall case sensitiv |
| switch ( eFormatter ) |
| { |
| case FSYS_STYLE_MAC: |
| case FSYS_STYLE_FAT: |
| case FSYS_STYLE_VFAT: |
| case FSYS_STYLE_NTFS: |
| case FSYS_STYLE_NWFS: |
| case FSYS_STYLE_HPFS: |
| { |
| isCaseSensitive = sal_False; |
| break; |
| } |
| case FSYS_STYLE_SYSV: |
| case FSYS_STYLE_BSD: |
| case FSYS_STYLE_DETECT: |
| { |
| isCaseSensitive = sal_True; |
| break; |
| } |
| default: |
| { |
| isCaseSensitive = sal_True; // ich bin unter UNIX, also ist der default im Zweifelsfall case sensitiv |
| break; |
| } |
| } |
| return isCaseSensitive; |
| } |
| } |
| |
| /************************************************************************ |
| |* |
| |* DirEntry::ToAbs() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 13:30 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::ToAbs() |
| { |
| if ( FSYS_FLAG_VOLUME == eFlag ) |
| { |
| eFlag = FSYS_FLAG_ABSROOT; |
| return sal_True; |
| } |
| |
| if ( IsAbs() ) |
| return sal_True; |
| |
| char sBuf[MAXPATHLEN + 1]; |
| *this = DirEntry( String( getcwd( sBuf, MAXPATHLEN ), osl_getThreadTextEncoding() ) ) + *this; |
| return IsAbs(); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetVolume() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 04.03.92 |
| |* Letzte Aenderung |
| |* |
| *************************************************************************/ |
| |
| namespace { struct mymnt : public rtl::Static< mymnttab, mymnt > {}; } |
| |
| String DirEntry::GetVolume() const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| DirEntry aPath( *this ); |
| aPath.ToAbs(); |
| |
| struct stat buf; |
| while (stat (ByteString(aPath.GetFull(), osl_getThreadTextEncoding()).GetBuffer(), &buf)) |
| { |
| if (aPath.Level() <= 1) |
| return String(); |
| aPath = aPath [1]; |
| } |
| mymnttab &rMnt = mymnt::get(); |
| return ((buf.st_dev == rMnt.mountdevice || |
| GetMountEntry(buf.st_dev, &rMnt)) ? |
| String(rMnt.mountspecial, osl_getThreadTextEncoding()) : |
| String()); |
| } |
| |
| DirEntry DirEntry::GetDevice() const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| DirEntry aPath( *this ); |
| aPath.ToAbs(); |
| |
| struct stat buf; |
| while (stat (ByteString(aPath.GetFull(), osl_getThreadTextEncoding()).GetBuffer(), &buf)) |
| { |
| if (aPath.Level() <= 1) |
| return String(); |
| aPath = aPath [1]; |
| } |
| mymnttab &rMnt = mymnt::get(); |
| return ((buf.st_dev == rMnt.mountdevice || |
| GetMountEntry(buf.st_dev, &rMnt)) ? |
| String( rMnt.mountpoint, osl_getThreadTextEncoding()) : |
| String()); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::SetCWD() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung DV 04.11.92 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::SetCWD( sal_Bool bSloppy ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| |
| ByteString aPath( GetFull(), osl_getThreadTextEncoding()); |
| if ( !chdir( aPath.GetBuffer() ) ) |
| { |
| return sal_True; |
| } |
| else |
| { |
| if ( bSloppy && !chdir(aPath.GetBuffer()) ) |
| { |
| return sal_True; |
| } |
| else |
| { |
| return sal_False; |
| } |
| } |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| sal_uInt16 DirReader_Impl::Init() |
| { |
| return 0; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| sal_uInt16 DirReader_Impl::Read() |
| { |
| if (!pDosDir) |
| { |
| pDosDir = opendir( (char*) ByteString(aPath, osl_getThreadTextEncoding()).GetBuffer() ); |
| } |
| |
| if (!pDosDir) |
| { |
| bReady = sal_True; |
| return 0; |
| } |
| |
| // Directories und Files auflisten? |
| if ( ( pDir->eAttrMask & FSYS_KIND_DIR || pDir->eAttrMask & FSYS_KIND_FILE ) && |
| ( ( pDosEntry = readdir( pDosDir ) ) != NULL ) ) |
| { |
| String aD_Name(pDosEntry->d_name, osl_getThreadTextEncoding()); |
| if ( pDir->aNameMask.Matches( aD_Name ) ) |
| { |
| DirEntryFlag eFlag = |
| 0 == strcmp( pDosEntry->d_name, "." ) ? FSYS_FLAG_CURRENT |
| : 0 == strcmp( pDosEntry->d_name, ".." ) ? FSYS_FLAG_PARENT |
| : FSYS_FLAG_NORMAL; |
| DirEntry *pTemp = new DirEntry( ByteString(pDosEntry->d_name), eFlag, FSYS_STYLE_UNX ); |
| if ( pParent ) |
| pTemp->ImpChangeParent( new DirEntry( *pParent ), sal_False); |
| FileStat aStat( *pTemp ); |
| if ( ( ( ( pDir->eAttrMask & FSYS_KIND_DIR ) && |
| ( aStat.IsKind( FSYS_KIND_DIR ) ) ) || |
| ( ( pDir->eAttrMask & FSYS_KIND_FILE ) && |
| !( aStat.IsKind( FSYS_KIND_DIR ) ) ) ) && |
| !( pDir->eAttrMask & FSYS_KIND_VISIBLE && |
| pDosEntry->d_name[0] == '.' ) ) |
| { |
| if ( pDir->pStatLst ) //Status fuer Sort gewuenscht? |
| pDir->ImpSortedInsert( pTemp, new FileStat( aStat ) ); |
| else |
| pDir->ImpSortedInsert( pTemp, NULL );; |
| return 1; |
| } |
| else |
| delete pTemp; |
| } |
| } |
| else |
| bReady = sal_True; |
| return 0; |
| } |
| |
| /************************************************************************* |
| |* |
| |* FileStat::FileStat() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MA 05.11.91 |
| |* Letzte Aenderung MA 07.11.91 |
| |* |
| *************************************************************************/ |
| |
| FileStat::FileStat( const void *, const void * ): |
| aDateCreated(0), |
| aTimeCreated(0), |
| aDateModified(0), |
| aTimeModified(0), |
| aDateAccessed(0), |
| aTimeAccessed(0) |
| { |
| } |
| |
| /************************************************************************* |
| |* |
| |* FileStat::Update() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 11.06.91 |
| |* Letzte Aenderung MA 07.11.91 |
| |* |
| *************************************************************************/ |
| sal_Bool FileStat::Update( const DirEntry& rDirEntry, sal_Bool ) |
| { |
| |
| nSize = 0; |
| nKindFlags = 0; |
| aCreator.Erase(); |
| aType.Erase(); |
| aDateCreated = Date(0); |
| aTimeCreated = Time(0); |
| aDateModified = Date(0); |
| aTimeModified = Time(0); |
| aDateAccessed = Date(0); |
| aTimeAccessed = Time(0); |
| |
| if ( !rDirEntry.IsValid() ) |
| { |
| nError = FSYS_ERR_NOTEXISTS; |
| return sal_False; |
| } |
| |
| // Sonderbehandlung falls es sich um eine Root handelt |
| if ( rDirEntry.eFlag == FSYS_FLAG_ABSROOT ) |
| { |
| nKindFlags = FSYS_KIND_DIR; |
| nError = FSYS_ERR_OK; |
| return sal_True; |
| } |
| |
| struct stat aStat; |
| ByteString aPath( rDirEntry.GetFull(), osl_getThreadTextEncoding() ); |
| if ( stat( (char*) aPath.GetBuffer(), &aStat ) ) |
| { |
| // pl: #67851# |
| // do this here, because an existing filename containing "wildcards" |
| // should be handled as a file, not a wildcard |
| // note that this is not a solution, since filenames containing special characters |
| // are handled badly across the whole Office |
| |
| // Sonderbehandlung falls es sich um eine Wildcard handelt |
| ByteString aTempName( rDirEntry.GetName(), osl_getThreadTextEncoding() ); |
| if ( strchr( (char*) aTempName.GetBuffer(), '?' ) || |
| strchr( (char*) aTempName.GetBuffer(), '*' ) || |
| strchr( (char*) aTempName.GetBuffer(), ';' ) ) |
| { |
| nKindFlags = FSYS_KIND_WILD; |
| nError = FSYS_ERR_OK; |
| return sal_True; |
| } |
| |
| nError = FSYS_ERR_NOTEXISTS; |
| return sal_False; |
| } |
| |
| nError = FSYS_ERR_OK; |
| nSize = aStat.st_size; |
| |
| nKindFlags = FSYS_KIND_UNKNOWN; |
| if ( ( aStat.st_mode & S_IFDIR ) == S_IFDIR ) |
| nKindFlags = nKindFlags | FSYS_KIND_DIR; |
| if ( ( aStat.st_mode & S_IFREG ) == S_IFREG ) |
| nKindFlags = nKindFlags | FSYS_KIND_FILE; |
| if ( ( aStat.st_mode & S_IFCHR ) == S_IFCHR ) |
| nKindFlags = nKindFlags | FSYS_KIND_DEV | FSYS_KIND_CHAR; |
| if ( ( aStat.st_mode & S_IFBLK ) == S_IFBLK ) |
| nKindFlags = nKindFlags | FSYS_KIND_DEV | FSYS_KIND_BLOCK; |
| if ( nKindFlags == FSYS_KIND_UNKNOWN ) |
| nKindFlags = nKindFlags | FSYS_KIND_FILE; |
| |
| Unx2DateAndTime( aStat.st_ctime, aTimeCreated, aDateCreated ); |
| Unx2DateAndTime( aStat.st_mtime, aTimeModified, aDateModified ); |
| Unx2DateAndTime( aStat.st_atime, aTimeAccessed, aDateAccessed ); |
| |
| return sal_True; |
| } |
| |
| //==================================================================== |
| |
| const char *TempDirImpl( char *pBuf ) |
| { |
| #ifdef MACOSX |
| // P_tmpdir is /var/tmp on Mac OS X, and it is not cleaned up on system |
| // startup |
| strcpy( pBuf, "/tmp" ); |
| #else |
| const char *pValue = getenv( "TEMP" ); |
| if ( !pValue ) |
| pValue = getenv( "TMP" ); |
| if ( pValue ) |
| strcpy( pBuf, pValue ); |
| else |
| // auf Solaris und Linux ist P_tmpdir vorgesehen |
| strcpy( pBuf, P_tmpdir ); |
| // hart auf "/tmp" sollte wohl nur im Notfall verwendet werden |
| //strcpy( pBuf, "/tmp" ); |
| #endif /* MACOSX */ |
| |
| return pBuf; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetPathStyle() const |
| |* |
| |* Beschreibung |
| |* Ersterstellung MI 11.05.95 |
| |* Letzte Aenderung MI 11.05.95 |
| |* |
| *************************************************************************/ |
| |
| FSysPathStyle DirEntry::GetPathStyle( const String & ) |
| { |
| return FSYS_STYLE_UNX; |
| } |
| |
| /************************************************************************* |
| |* |
| |* FileStat::SetDateTime |
| |* |
| |* Ersterstellung PB 27.06.97 |
| |* Letzte Aenderung |
| |* |
| *************************************************************************/ |
| |
| void FileStat::SetDateTime( const String& rFileName, |
| const DateTime& rNewDateTime ) |
| { |
| tm times; |
| |
| times.tm_year = rNewDateTime.GetYear() - 1900; // 1997 -> 97 |
| times.tm_mon = rNewDateTime.GetMonth() - 1; // 0 == Januar! |
| times.tm_mday = rNewDateTime.GetDay(); |
| |
| times.tm_hour = rNewDateTime.GetHour(); |
| times.tm_min = rNewDateTime.GetMin(); |
| times.tm_sec = rNewDateTime.GetSec(); |
| |
| times.tm_wday = 0; |
| times.tm_yday = 0; |
| #ifdef SOLARIS |
| times.tm_isdst = -1; |
| #else |
| times.tm_isdst = 0; |
| #endif |
| |
| time_t time = mktime (×); |
| |
| if (time != (time_t) -1) |
| { |
| struct utimbuf u_time; |
| u_time.actime = time; |
| u_time.modtime = time; |
| utime (ByteString(rFileName, osl_getThreadTextEncoding()).GetBuffer(), &u_time); |
| } |
| } |
| |
| //========================================================================= |
| |
| ErrCode FileStat::QueryDiskSpace( const String &, BigInt &, BigInt & ) |
| { |
| return ERRCODE_IO_NOTSUPPORTED; |
| } |
| |
| //========================================================================= |
| |
| void FSysEnableSysErrorBox( sal_Bool ) |
| { |
| } |
| |