Blame qtools/qfileinfo_unix.cpp

Packit Service 50c9f2
/****************************************************************************
Packit Service 50c9f2
** 
Packit Service 50c9f2
**
Packit Service 50c9f2
** Implementation of QFileInfo class
Packit Service 50c9f2
**
Packit Service 50c9f2
** Created : 950628
Packit Service 50c9f2
**
Packit Service 50c9f2
** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file is part of the tools module of the Qt GUI Toolkit.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file may be distributed under the terms of the Q Public License
Packit Service 50c9f2
** as defined by Trolltech AS of Norway and appearing in the file
Packit Service 50c9f2
** LICENSE.QPL included in the packaging of this file.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file may be distributed and/or modified under the terms of the
Packit Service 50c9f2
** GNU General Public License version 2 as published by the Free Software
Packit Service 50c9f2
** Foundation and appearing in the file LICENSE.GPL included in the
Packit Service 50c9f2
** packaging of this file.
Packit Service 50c9f2
**
Packit Service 50c9f2
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
Packit Service 50c9f2
** licenses for Unix/X11 or for Qt/Embedded may use this file in accordance
Packit Service 50c9f2
** with the Qt Commercial License Agreement provided with the Software.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
Packit Service 50c9f2
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Packit Service 50c9f2
**
Packit Service 50c9f2
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
Packit Service 50c9f2
**   information about Qt Commercial License Agreements.
Packit Service 50c9f2
** See http://www.trolltech.com/qpl/ for QPL licensing information.
Packit Service 50c9f2
** See http://www.trolltech.com/gpl/ for GPL licensing information.
Packit Service 50c9f2
**
Packit Service 50c9f2
** Contact info@trolltech.com if any conditions of this licensing are
Packit Service 50c9f2
** not clear to you.
Packit Service 50c9f2
**
Packit Service 50c9f2
**********************************************************************/
Packit Service 50c9f2
Packit Service 50c9f2
#include "qglobal.h"
Packit Service 50c9f2
Packit Service 50c9f2
#if defined(_OS_SUN_)
Packit Service 50c9f2
#define readlink _qt_hide_readlink
Packit Service 50c9f2
#endif
Packit Service 50c9f2
Packit Service 50c9f2
#include <pwd.h>
Packit Service 50c9f2
#include <grp.h>
Packit Service 50c9f2
Packit Service 50c9f2
#include "qfileinfo.h"
Packit Service 50c9f2
#include "qfiledefs_p.h"
Packit Service 50c9f2
#include "qdatetime.h"
Packit Service 50c9f2
#include "qdir.h"
Packit Service 50c9f2
Packit Service 50c9f2
#if defined(_OS_SUN_)
Packit Service 50c9f2
#undef readlink
Packit Service 50c9f2
extern "C" int readlink( const char *, void *, uint );
Packit Service 50c9f2
#endif
Packit Service 50c9f2
Packit Service 50c9f2
Packit Service 50c9f2
void QFileInfo::slashify( QString& )
Packit Service 50c9f2
{
Packit Service 50c9f2
    return;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
Packit Service 50c9f2
void QFileInfo::makeAbs( QString & )
Packit Service 50c9f2
{
Packit Service 50c9f2
    return;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
extern bool qt_file_access( const QString& fn, int t );
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns TRUE if we are pointing to a real file.
Packit Service 50c9f2
  \sa isDir(), isSymLink()
Packit Service 50c9f2
*/
Packit Service 50c9f2
bool QFileInfo::isFile() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    if ( !fic || !cache )
Packit Service 50c9f2
	doStat();
Packit Service 50c9f2
    return fic ? (fic->st.st_mode & STAT_MASK) == STAT_REG : FALSE;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns TRUE if we are pointing to a directory or a symbolic link to
Packit Service 50c9f2
  a directory.
Packit Service 50c9f2
  \sa isFile(), isSymLink()
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
bool QFileInfo::isDir() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    if ( !fic || !cache )
Packit Service 50c9f2
	doStat();
Packit Service 50c9f2
    return fic ? (fic->st.st_mode & STAT_MASK) == STAT_DIR : FALSE;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns TRUE if we are pointing to a symbolic link.
Packit Service 50c9f2
  \sa isFile(), isDir(), readLink()
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
bool QFileInfo::isSymLink() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    if ( !fic || !cache )
Packit Service 50c9f2
	doStat();
Packit Service 50c9f2
    return fic ? fic->isSymLink : FALSE;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns the name a symlink points to, or a null QString if the
Packit Service 50c9f2
  object does not refer to a symbolic link.
Packit Service 50c9f2
Packit Service 50c9f2
  This name may not represent an existing file; it is only a string.
Packit Service 50c9f2
  QFileInfo::exists() returns TRUE if the symlink points to an
Packit Service 50c9f2
  existing file.
Packit Service 50c9f2
Packit Service 50c9f2
  \sa exists(), isSymLink(), isDir(), isFile()
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
QString QFileInfo::readLink() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    QString r;
Packit Service 50c9f2
Packit Service 50c9f2
#if defined(_OS_UNIX_) && !defined(_OS_OS2EMX_)
Packit Service 50c9f2
    char s[PATH_MAX+1];
Packit Service 50c9f2
    if ( !isSymLink() )
Packit Service 50c9f2
	return QString();
Packit Service 50c9f2
    int len = (int)readlink( QFile::encodeName(fn).data(), s, PATH_MAX );
Packit Service 50c9f2
    if ( len >= 0 ) {
Packit Service 50c9f2
	s[len] = '\0';
Packit Service 50c9f2
	r = QFile::decodeName(s);
Packit Service 50c9f2
    }
Packit Service 50c9f2
#endif
Packit Service 50c9f2
Packit Service 50c9f2
    return r;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
static const uint nobodyID = (uint) -2;
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns the owner of the file.
Packit Service 50c9f2
Packit Service 50c9f2
  On systems where files do not have owners this function returns 0.
Packit Service 50c9f2
Packit Service 50c9f2
  Note that this function can be time-consuming under UNIX. (in the order
Packit Service 50c9f2
  of milliseconds on a 486 DX2/66 running Linux).
Packit Service 50c9f2
Packit Service 50c9f2
  \sa ownerId(), group(), groupId()
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
QString QFileInfo::owner() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    passwd *pw = getpwuid( ownerId() );
Packit Service 50c9f2
    if ( pw )
Packit Service 50c9f2
	return QFile::decodeName( pw->pw_name );
Packit Service 50c9f2
    return QString::null;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns the id of the owner of the file.
Packit Service 50c9f2
Packit Service 50c9f2
  On systems where files do not have owners this function returns ((uint) -2).
Packit Service 50c9f2
Packit Service 50c9f2
  \sa owner(), group(), groupId()
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
uint QFileInfo::ownerId() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    if ( !fic || !cache )
Packit Service 50c9f2
	doStat();
Packit Service 50c9f2
    if ( fic )
Packit Service 50c9f2
	return fic->st.st_uid;
Packit Service 50c9f2
    return nobodyID;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns the group the file belongs to.
Packit Service 50c9f2
Packit Service 50c9f2
  On systems where files do not have groups this function always
Packit Service 50c9f2
  returns 0.
Packit Service 50c9f2
Packit Service 50c9f2
  Note that this function can be time-consuming under UNIX (in the order of
Packit Service 50c9f2
  milliseconds on a 486 DX2/66 running Linux).
Packit Service 50c9f2
Packit Service 50c9f2
  \sa groupId(), owner(), ownerId()
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
QString QFileInfo::group() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    struct group *gr = getgrgid( groupId() );
Packit Service 50c9f2
    if ( gr )
Packit Service 50c9f2
	return QFile::decodeName( gr->gr_name );
Packit Service 50c9f2
    return QString::null;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns the id of the group the file belongs to.
Packit Service 50c9f2
Packit Service 50c9f2
  On systems where files do not have groups this function always
Packit Service 50c9f2
  returns ((uind) -2).
Packit Service 50c9f2
Packit Service 50c9f2
  \sa group(), owner(), ownerId()
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
uint QFileInfo::groupId() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    if ( !fic || !cache )
Packit Service 50c9f2
	doStat();
Packit Service 50c9f2
    if ( fic )
Packit Service 50c9f2
	return fic->st.st_gid;
Packit Service 50c9f2
    return nobodyID;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  \fn bool QFileInfo::permission( int permissionSpec ) const
Packit Service 50c9f2
Packit Service 50c9f2
  Tests for file permissions.  The \e permissionSpec argument can be several
Packit Service 50c9f2
  flags of type PermissionSpec or'ed together to check for permission
Packit Service 50c9f2
  combinations.
Packit Service 50c9f2
Packit Service 50c9f2
  On systems where files do not have permissions this function always
Packit Service 50c9f2
  returns TRUE.
Packit Service 50c9f2
Packit Service 50c9f2
  Example:
Packit Service 50c9f2
  \code
Packit Service 50c9f2
    QFileInfo fi( "/tmp/tonsils" );
Packit Service 50c9f2
    if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) )
Packit Service 50c9f2
	qWarning( "Tonsils can be changed by me, and the group can read them.");
Packit Service 50c9f2
    if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) )
Packit Service 50c9f2
	qWarning( "Danger! Tonsils can be changed by the group or others!" );
Packit Service 50c9f2
  \endcode
Packit Service 50c9f2
Packit Service 50c9f2
  \sa isReadable(), isWritable(), isExecutable()
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
bool QFileInfo::permission( int permissionSpec ) const
Packit Service 50c9f2
{
Packit Service 50c9f2
    if ( !fic || !cache )
Packit Service 50c9f2
	doStat();
Packit Service 50c9f2
    if ( fic ) {
Packit Service 50c9f2
	uint mask = 0;
Packit Service 50c9f2
	if ( permissionSpec & ReadUser)
Packit Service 50c9f2
	    mask |= S_IRUSR;
Packit Service 50c9f2
	if ( permissionSpec & WriteUser)
Packit Service 50c9f2
	    mask |= S_IWUSR;
Packit Service 50c9f2
	if ( permissionSpec & ExeUser)
Packit Service 50c9f2
	    mask |= S_IXUSR;
Packit Service 50c9f2
	if ( permissionSpec & ReadGroup)
Packit Service 50c9f2
	    mask |= S_IRGRP;
Packit Service 50c9f2
	if ( permissionSpec & WriteGroup)
Packit Service 50c9f2
	    mask |= S_IWGRP;
Packit Service 50c9f2
	if ( permissionSpec & ExeGroup)
Packit Service 50c9f2
	    mask |= S_IXGRP;
Packit Service 50c9f2
	if ( permissionSpec & ReadOther)
Packit Service 50c9f2
	    mask |= S_IROTH;
Packit Service 50c9f2
	if ( permissionSpec & WriteOther)
Packit Service 50c9f2
	    mask |= S_IWOTH;
Packit Service 50c9f2
	if ( permissionSpec & ExeOther)
Packit Service 50c9f2
	    mask |= S_IXOTH;
Packit Service 50c9f2
	if ( mask ) {
Packit Service 50c9f2
	   return (fic->st.st_mode & mask) == mask;
Packit Service 50c9f2
	} else {
Packit Service 50c9f2
#if defined(CHECK_NULL)
Packit Service 50c9f2
	   qWarning( "QFileInfo::permission: permissionSpec is 0" );
Packit Service 50c9f2
#endif
Packit Service 50c9f2
	   return TRUE;
Packit Service 50c9f2
	}
Packit Service 50c9f2
    } else {
Packit Service 50c9f2
	return FALSE;
Packit Service 50c9f2
    }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns the file size in bytes, or 0 if the file does not exist if the size
Packit Service 50c9f2
  cannot be fetched.
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
uint QFileInfo::size() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    if ( !fic || !cache )
Packit Service 50c9f2
	doStat();
Packit Service 50c9f2
    if ( fic )
Packit Service 50c9f2
	return (uint)fic->st.st_size;
Packit Service 50c9f2
    else
Packit Service 50c9f2
	return 0;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns the date and time when the file was last modified.
Packit Service 50c9f2
  \sa lastRead()
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
QDateTime QFileInfo::lastModified() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    QDateTime dt;
Packit Service 50c9f2
    if ( !fic || !cache )
Packit Service 50c9f2
	doStat();
Packit Service 50c9f2
    if ( fic )
Packit Service 50c9f2
	dt.setTime_t( (uint)fic->st.st_mtime );
Packit Service 50c9f2
    return dt;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns the date and time when the file was last read (accessed).
Packit Service 50c9f2
Packit Service 50c9f2
  On systems that do not support last read times, the modification time is
Packit Service 50c9f2
  returned.
Packit Service 50c9f2
Packit Service 50c9f2
  \sa lastModified()
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
QDateTime QFileInfo::lastRead() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    QDateTime dt;
Packit Service 50c9f2
    if ( !fic || !cache )
Packit Service 50c9f2
	doStat();
Packit Service 50c9f2
    if ( fic )
Packit Service 50c9f2
	dt.setTime_t( (uint)fic->st.st_atime );
Packit Service 50c9f2
    return dt;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
Packit Service 50c9f2
void QFileInfo::doStat() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    QFileInfo *that = ((QFileInfo*)this);	// mutable function
Packit Service 50c9f2
    if ( !that->fic )
Packit Service 50c9f2
	that->fic = new QFileInfoCache;
Packit Service 50c9f2
    STATBUF *b = &that->fic->st;
Packit Service 50c9f2
    that->fic->isSymLink = FALSE;
Packit Service 50c9f2
Packit Service 50c9f2
#if defined(_OS_UNIX_) && defined(S_IFLNK)
Packit Service 50c9f2
    if ( ::lstat(QFile::encodeName(fn),b) == 0 ) {
Packit Service 50c9f2
	if ( S_ISLNK( b->st_mode ) )
Packit Service 50c9f2
	    that->fic->isSymLink = TRUE;
Packit Service 50c9f2
	else
Packit Service 50c9f2
	    return;
Packit Service 50c9f2
    }
Packit Service 50c9f2
#endif
Packit Service 50c9f2
    int r;
Packit Service 50c9f2
Packit Service 50c9f2
    r = STAT( QFile::encodeName(fn), b );
Packit Service 50c9f2
Packit Service 50c9f2
    if ( r != 0 ) {
Packit Service 50c9f2
	delete that->fic;
Packit Service 50c9f2
	that->fic = 0;
Packit Service 50c9f2
    }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns the directory path of the file.
Packit Service 50c9f2
Packit Service 50c9f2
  If \e absPath is TRUE an absolute path is always returned.
Packit Service 50c9f2
Packit Service 50c9f2
  \sa dir(), filePath(), fileName(), isRelative()
Packit Service 50c9f2
*/
Packit Service 50c9f2
#ifndef QT_NO_DIR
Packit Service 50c9f2
QString QFileInfo::dirPath( bool absPath ) const
Packit Service 50c9f2
{
Packit Service 50c9f2
    QString s;
Packit Service 50c9f2
    if ( absPath )
Packit Service 50c9f2
	s = absFilePath();
Packit Service 50c9f2
    else
Packit Service 50c9f2
	s = fn;
Packit Service 50c9f2
    int pos = s.findRev( '/' );
Packit Service 50c9f2
    if ( pos == -1 ) {
Packit Service 50c9f2
	return QString::fromLatin1(".");
Packit Service 50c9f2
    } else {
Packit Service 50c9f2
	if ( pos == 0 )
Packit Service 50c9f2
	    return QString::fromLatin1( "/" );
Packit Service 50c9f2
	return s.left( pos );
Packit Service 50c9f2
    }
Packit Service 50c9f2
}
Packit Service 50c9f2
#endif
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns the name of the file, the file path is not included.
Packit Service 50c9f2
Packit Service 50c9f2
  Example:
Packit Service 50c9f2
  \code
Packit Service 50c9f2
     QFileInfo fi( "/tmp/abdomen.lower" );
Packit Service 50c9f2
     QString name = fi.fileName();		// name = "abdomen.lower"
Packit Service 50c9f2
  \endcode
Packit Service 50c9f2
Packit Service 50c9f2
  \sa isRelative(), filePath(), baseName(), extension()
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
QString QFileInfo::fileName() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    int p = fn.findRev( '/' );
Packit Service 50c9f2
    if ( p == -1 ) {
Packit Service 50c9f2
	return fn;
Packit Service 50c9f2
    } else {
Packit Service 50c9f2
	return fn.mid(p+1);
Packit Service 50c9f2
    }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Returns the absolute path name.
Packit Service 50c9f2
Packit Service 50c9f2
  The absolute path name is the file name including the absolute path. If
Packit Service 50c9f2
  the QFileInfo is absolute (i.e. not relative) this function will return
Packit Service 50c9f2
  the same string as filePath().
Packit Service 50c9f2
Packit Service 50c9f2
  Note that this function can be time-consuming under UNIX. (in the order
Packit Service 50c9f2
  of milliseconds on a 486 DX2/66 running Linux).
Packit Service 50c9f2
Packit Service 50c9f2
  \sa isRelative(), filePath()
Packit Service 50c9f2
*/
Packit Service 50c9f2
#ifndef QT_NO_DIR
Packit Service 50c9f2
QString QFileInfo::absFilePath() const
Packit Service 50c9f2
{
Packit Service 50c9f2
    if ( QDir::isRelativePath(fn) ) {
Packit Service 50c9f2
	QString tmp = QDir::currentDirPath();
Packit Service 50c9f2
	tmp += '/';
Packit Service 50c9f2
	tmp += fn;
Packit Service 50c9f2
	makeAbs( tmp );
Packit Service 50c9f2
	return QDir::cleanDirPath( tmp );
Packit Service 50c9f2
    } else {
Packit Service 50c9f2
	QString tmp = fn;
Packit Service 50c9f2
	makeAbs( tmp );
Packit Service 50c9f2
	return QDir::cleanDirPath( tmp );
Packit Service 50c9f2
    }
Packit Service 50c9f2
Packit Service 50c9f2
}
Packit Service 50c9f2
#endif