Пример #1
0
void KURLCompletion::adjustMatch(QString &match) const
{
    if(match.at(match.length() - 1) != '/')
    {
        QString copy;

        if(match.startsWith(QString("file:")))
            copy = KURL(match).path();
        else
            copy = match;

        expandTilde(copy);
        expandEnv(copy);
        if(QDir::isRelativePath(copy))
            copy.prepend(d->cwd + '/');

        //		kdDebug() << "postProcess: stating " << copy << endl;

        KDE_struct_stat sbuff;

        QCString file = QFile::encodeName(copy);

        if(KDE_stat((const char *)file, &sbuff) == 0)
        {
            if(S_ISDIR(sbuff.st_mode))
                match.append('/');
        }
        else
        {
            kdDebug() << "Could not stat file " << copy << endl;
        }
    }
}
Пример #2
0
QString KStandardDirs::saveLocation(const char *type,
				    const QString& suffix,
				    bool create) const
{
    checkConfig();

    QString *pPath = savelocations.find(type);
    if (!pPath)
    {
       QStringList *dirs = relatives.find(type);
       if (!dirs && (
                     (strcmp(type, "socket") == 0) ||
                     (strcmp(type, "tmp") == 0) ||
                     (strcmp(type, "cache") == 0) ))
       {
          (void) resourceDirs(type); // Generate socket|tmp|cache resource.
          dirs = relatives.find(type); // Search again.
       }
       if (dirs)
       {
          // Check for existence of typed directory + suffix
          if (strncmp(type, "xdgdata-", 8) == 0)
             pPath = new QString(realPath(localxdgdatadir() + dirs->last()));
          else if (strncmp(type, "xdgconf-", 8) == 0)
             pPath = new QString(realPath(localxdgconfdir() + dirs->last()));
          else
             pPath = new QString(realPath(localkdedir() + dirs->last()));
       }
       else {
          dirs = absolutes.find(type);
          if (!dirs)
             qFatal("KStandardDirs: The resource type %s is not registered", type);
          pPath = new QString(realPath(dirs->last()));
       }

       savelocations.insert(type, pPath);
    }
    QString fullPath = *pPath + (pPath->endsWith("/") ? "" : "/") + suffix;

    KDE_struct_stat st;
    if (KDE_stat(QFile::encodeName(fullPath), &st) != 0 || !(S_ISDIR(st.st_mode))) {
	if(!create) {
#ifndef NDEBUG
	    kdDebug() << QString("save location %1 doesn't exist").arg(fullPath) << endl;
#endif
	    return fullPath;
	}
	if(!makeDir(fullPath, 0700)) {
	    return fullPath;
	}
        dircache.remove(type);
    }
    if (!fullPath.endsWith("/"))
	    fullPath += "/";
    return fullPath;
}
Пример #3
0
static Q_UINT32 updateHash(const QString &file, Q_UINT32 hash)
{
    QCString cFile = QFile::encodeName(file);
    KDE_struct_stat buff;
    if((access(cFile, R_OK) == 0) && (KDE_stat(cFile, &buff) == 0) && (S_ISREG(buff.st_mode)))
    {
        hash = hash + (Q_UINT32)buff.st_ctime;
    }
    return hash;
}
Пример #4
0
bool KStandardDirs::exists(const QString &fullPath)
{
    KDE_struct_stat buff;
    if (access(QFile::encodeName(fullPath), R_OK) == 0 && KDE_stat( QFile::encodeName(fullPath), &buff ) == 0)
	if (fullPath.at(fullPath.length() - 1) != '/') {
	    if (S_ISREG( buff.st_mode ))
		return true;
	} else
	    if (S_ISDIR( buff.st_mode ))
		return true;
    return false;
}
Пример #5
0
bool TrashProtocol::createUDSEntry(const QString &physicalPath, const QString &fileName, const QString &url, KIO::UDSEntry &entry,
                                   const TrashedFileInfo &info)
{
    QCString physicalPath_c = QFile::encodeName(physicalPath);
    KDE_struct_stat buff;
    if(KDE_lstat(physicalPath_c, &buff) == -1)
    {
        kdWarning() << "couldn't stat " << physicalPath << endl;
        return false;
    }
    if(S_ISLNK(buff.st_mode))
    {
        char buffer2[1000];
        int n = readlink(physicalPath_c, buffer2, 1000);
        if(n != -1)
        {
            buffer2[n] = 0;
        }

        addAtom(entry, KIO::UDS_LINK_DEST, 0, QFile::decodeName(buffer2));
// Follow symlink
// That makes sense in kio_file, but not in the trash, especially for the size
// #136876
#if 0
        if ( KDE_stat( physicalPath_c, &buff ) == -1 ) {
            // It is a link pointing to nowhere
            buff.st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
            buff.st_mtime = 0;
            buff.st_atime = 0;
            buff.st_size = 0;
        }
#endif
    }
    mode_t type = buff.st_mode & S_IFMT;  // extract file type
    mode_t access = buff.st_mode & 07777; // extract permissions
    access &= 07555;                      // make it readonly, since it's in the trashcan
    addAtom(entry, KIO::UDS_NAME, 0, fileName);
    addAtom(entry, KIO::UDS_FILE_TYPE, type);
    if(!url.isEmpty())
        addAtom(entry, KIO::UDS_URL, 0, url);

    KMimeType::Ptr mt = KMimeType::findByPath(physicalPath, buff.st_mode);
    addAtom(entry, KIO::UDS_MIME_TYPE, 0, mt->name());
    addAtom(entry, KIO::UDS_ACCESS, access);
    addAtom(entry, KIO::UDS_SIZE, buff.st_size);
    addAtom(entry, KIO::UDS_USER, 0, m_userName);   // assumption
    addAtom(entry, KIO::UDS_GROUP, 0, m_groupName); // assumption
    addAtom(entry, KIO::UDS_MODIFICATION_TIME, buff.st_mtime);
    addAtom(entry, KIO::UDS_ACCESS_TIME, buff.st_atime); // ## or use it for deletion time?
    addAtom(entry, KIO::UDS_EXTRA, 0, info.origPath);
    addAtom(entry, KIO::UDS_EXTRA, 0, info.deletionDate.toString(Qt::ISODate));
    return true;
}
Пример #6
0
bool TrashProtocol::createUDSEntry( const QString& physicalPath, const QString& displayFileName, const QString& internalFileName, KIO::UDSEntry& entry, const TrashedFileInfo& info )
{
    QByteArray physicalPath_c = QFile::encodeName( physicalPath );
    KDE_struct_stat buff;
    if ( KDE_lstat( physicalPath_c, &buff ) == -1 ) {
        kWarning() << "couldn't stat " << physicalPath ;
        return false;
    }
    if (S_ISLNK(buff.st_mode)) {
        char buffer2[ 1000 ];
        int n = readlink( physicalPath_c, buffer2, 999 );
        if ( n != -1 ) {
            buffer2[ n ] = 0;
        }

        entry.insert( KIO::UDSEntry::UDS_LINK_DEST, QFile::decodeName( buffer2 ) );
        // Follow symlink
        // That makes sense in kio_file, but not in the trash, especially for the size
        // #136876
#if 0
        if ( KDE_stat( physicalPath_c, &buff ) == -1 ) {
            // It is a link pointing to nowhere
            buff.st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
            buff.st_mtime = 0;
            buff.st_atime = 0;
            buff.st_size = 0;
        }
#endif
    }
    mode_t type = buff.st_mode & S_IFMT; // extract file type
    mode_t access = buff.st_mode & 07777; // extract permissions
    access &= 07555; // make it readonly, since it's in the trashcan
    Q_ASSERT(!internalFileName.isEmpty());
    entry.insert( KIO::UDSEntry::UDS_NAME, internalFileName ); // internal filename, like "0-foo"
    entry.insert( KIO::UDSEntry::UDS_DISPLAY_NAME, displayFileName ); // user-visible filename, like "foo"
    entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, type );
    //if ( !url.isEmpty() )
    //    entry.insert( KIO::UDSEntry::UDS_URL, url );

    KMimeType::Ptr mt = KMimeType::findByPath( physicalPath, buff.st_mode );
    if ( mt )
        entry.insert( KIO::UDSEntry::UDS_MIME_TYPE, mt->name() );
    entry.insert( KIO::UDSEntry::UDS_ACCESS, access );
    entry.insert( KIO::UDSEntry::UDS_SIZE, buff.st_size );
    entry.insert( KIO::UDSEntry::UDS_USER, m_userName ); // assumption
    entry.insert( KIO::UDSEntry::UDS_GROUP, m_groupName ); // assumption
    entry.insert( KIO::UDSEntry::UDS_MODIFICATION_TIME, buff.st_mtime );
    entry.insert( KIO::UDSEntry::UDS_ACCESS_TIME, buff.st_atime ); // ## or use it for deletion time?
    entry.insert( KIO::UDSEntry::UDS_EXTRA, info.origPath );
    entry.insert( KIO::UDSEntry::UDS_EXTRA + 1, info.deletionDate.toString( Qt::ISODate ) );
    return true;
}
Пример #7
0
time_t KFileItem::time( unsigned int which, bool &hasTime ) const
{
  hasTime = true;
  unsigned int mappedWhich = 0;

  switch( which ) {
    case KIO::UDS_MODIFICATION_TIME:
      mappedWhich = Modification;
      break;
    case KIO::UDS_ACCESS_TIME:
      mappedWhich = Access;
      break;
    case KIO::UDS_CREATION_TIME:
      mappedWhich = Creation;
      break;
  }

  if ( m_time[mappedWhich] != (time_t) -1 )
    return m_time[mappedWhich];

  // Extract it from the KIO::UDSEntry
  KIO::UDSEntry::ConstIterator it = m_entry.begin();
  for( ; it != m_entry.end(); ++it )
    if ( (*it).m_uds == which ) {
      m_time[mappedWhich] = static_cast<time_t>((*it).m_long);
      return m_time[mappedWhich];
    }

  // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL]
  if ( m_bIsLocalURL )
  {
    KDE_struct_stat buf;
    if ( KDE_stat( QFile::encodeName(m_url.path(-1)), &buf ) == 0 )
    {
	if(which == KIO::UDS_CREATION_TIME) {
	    // We can't determine creation time for local files
	    hasTime = false;
            m_time[mappedWhich] = static_cast<time_t>(0);
	    return m_time[mappedWhich];
	}
        m_time[mappedWhich] = (which == KIO::UDS_MODIFICATION_TIME) ?
                               buf.st_mtime :
                               /* which == KIO::UDS_ACCESS_TIME)*/
			       buf.st_atime;
        return m_time[mappedWhich];
    }
  }
  hasTime = false;
  return static_cast<time_t>(0);
}
Пример #8
0
bool KDEsuClient::isServerSGID()
{
    if(d->daemon.isEmpty())
        d->daemon = findDaemon();
    if(d->daemon.isEmpty())
        return false;

    KDE_struct_stat sbuf;
    if(KDE_stat(QFile::encodeName(d->daemon), &sbuf) < 0)
    {
        kdWarning(900) << k_lineinfo << "stat(): " << perror << "\n";
        return false;
    }
    return (sbuf.st_mode & S_ISGID);
}
Пример #9
0
TDEIO::filesize_t
ArkUtils::getSizes(TQStringList *list)
{
  TDEIO::filesize_t sum = 0;
  TQString str;
  KDE_struct_stat st;

  for ( TQStringList::Iterator it = list->begin(); it != list->end(); ++it)
  {
    str = *it;
    str = str.right(str.length()-5);
    if (KDE_stat(TQFile::encodeName(str), &st ) < 0)
       continue;
    sum += st.st_size;
  }
  return sum;
}
Пример #10
0
bool KStandardDirs::makeDir(const QString &dir, int mode)
{
    // we want an absolute path
    if(QDir::isRelativePath(dir))
        return false;

    QString target = dir;
    uint len = target.length();

    // append trailing slash if missing
    if(dir.at(len - 1) != '/')
        target += '/';

    QString base("");
    uint i = 1;

    while(i < len)
    {
        KDE_struct_stat st;
        int pos = target.find('/', i);
        base += target.mid(i - 1, pos - i + 1);
        QCString baseEncoded = QFile::encodeName(base);
        // bail out if we encountered a problem
        if(KDE_stat(baseEncoded, &st) != 0)
        {
            // Directory does not exist....
            // Or maybe a dangling symlink ?
            if(KDE_lstat(baseEncoded, &st) == 0)
                (void)unlink(baseEncoded); // try removing

            if(KDE_mkdir(baseEncoded, (mode_t)mode) != 0)
            {
                baseEncoded.prepend("trying to create local folder ");
                perror(baseEncoded.data());
                return false; // Couldn't create it :-(
            }
        }
        i = pos + 1;
    }
    return true;
}
Пример #11
0
bool MultiSegmentCopyJob::checkLocalFile()
{
    QString dest_orig = m_dest.path();
    QString dest_part( dest_orig );
    dest_part += QLatin1String(".part");
    QByteArray _dest_part( QFile::encodeName(dest_part));

    KDE_struct_stat buff_part;
    bool bPartExists = (KDE_stat( _dest_part.data(), &buff_part ) != -1);
    if(!bPartExists)
    {
        QByteArray _dest = QFile::encodeName(dest_part);
        int fd = -1;
        mode_t initialMode;
        if (m_permissions != -1)
            initialMode = m_permissions | S_IWUSR | S_IRUSR;
        else
            initialMode = 0666;

        fd = KDE_open(_dest.data(), O_CREAT | O_TRUNC | O_WRONLY, initialMode);
        if ( fd < 0 )
        {
             kDebug(5001) << " error";
/*          if ( errno == EACCES )
            error( ERR_WRITE_ACCESS_DENIED, dest_part );
          else
            error( ERR_CANNOT_OPEN_FOR_WRITING, dest_part );*/
             return false;
        }
        else
        {
            close(fd);
        }
    }
    m_dest_part = m_dest;
    m_dest_part.setPath(dest_part);
    kDebug(5001) << "success";
    return true;
}
Пример #12
0
KIO::filesize_t KFileItem::size(bool &exists) const
{
  exists = true;
  if ( m_size != (KIO::filesize_t) -1 )
    return m_size;

  // Extract it from the KIO::UDSEntry
  KIO::UDSEntry::ConstIterator it = m_entry.begin();
  for( ; it != m_entry.end(); ++it )
    if ( (*it).m_uds == KIO::UDS_SIZE ) {
      m_size = (*it).m_long;
      return m_size;
    }
  // If not in the KIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL]
  if ( m_bIsLocalURL )
  {
    KDE_struct_stat buf;
    if ( KDE_stat( QFile::encodeName(m_url.path( -1 )), &buf ) == 0 )
        return buf.st_size;
  }
  exists = false;
  return 0L;
}
Пример #13
0
bool PakProtocol::checkNewFile(const KURL &url, QString &path, KIO::Error &errorNum) {
	QString fullPath = url.path();

	kdDebug(PAK_DEBUG_ID) << "Entering checkNewFile() - " << fullPath << endl;

	// Are we already looking at that file ?
	if ( _pakFile && _pakFileName == fullPath.left(_pakFileName.length()) )
	{
		// Has it changed ?
		KDE_struct_stat statbuf;
		if ( KDE_stat( QFile::encodeName( _pakFileName ), &statbuf ) == 0 )
		{
			if ( _pakFileTime == statbuf.st_mtime )
			{
				// It hasn't changed, so just return
				path = fullPath.mid( _pakFileName.length() );
				kdDebug(PAK_DEBUG_ID) << "checkNewFile() returning " << path << endl;
				return true;
			}
		}
	}
	kdDebug(PAK_DEBUG_ID) << "Need to open a new file or check if dir" << endl;

	// Close previous file
	if ( _pakFile )
	{
		_pakFile->close();
		delete _pakFile;
		_pakFile = NULL;
	}

	kdDebug(PAK_DEBUG_ID) << "Going to find full path" << endl;

	// Find where the tar file is in the full path
	int pos = 0;
	QString archiveFile;
	path = QString::null;

	int len = fullPath.length();
	if ( len != 0 && fullPath[ len - 1 ] != '/' )
		fullPath += '/';

	kdDebug(PAK_DEBUG_ID) << "the full path is " << fullPath << endl;
	KDE_struct_stat statbuf;
	statbuf.st_mode = 0; // be sure to clear the directory bit
	while ( (pos=fullPath.find( '/', pos+1 )) != -1 )
	{
		QString tryPath = fullPath.left( pos );
		kdDebug(PAK_DEBUG_ID) << fullPath << "  trying " << tryPath << endl;
		if ( KDE_stat( QFile::encodeName(tryPath), &statbuf ) == -1 )
		{
			// We are not in the file system anymore, either we have already enough data or we will never get any useful data anymore
			break;
		}
		if ( !S_ISDIR(statbuf.st_mode) )
		{
			archiveFile = tryPath;
			_pakFileTime = statbuf.st_mtime;
			path = fullPath.mid( pos + 1 );
			kdDebug(PAK_DEBUG_ID) << "fullPath=" << fullPath << " path=" << path << endl;
			len = path.length();
			if ( len > 1 )
			{
				if ( path[ len - 1 ] == '/' )
					path.truncate( len - 1 );
			}
			else
				path = QString::fromLatin1("/");
			kdDebug(PAK_DEBUG_ID) << "Found. archiveFile=" << archiveFile << " path=" << path << endl;
			break;
		}
	}
	if ( archiveFile.isEmpty() )
	{
		kdDebug(PAK_DEBUG_ID) << "checkNewFile(): not found" << endl;
		if ( S_ISDIR(statbuf.st_mode) ) // Was the last stat about a directory?
		{
			// Too bad, it is a directory, not an archive.
			kdDebug(PAK_DEBUG_ID) << "Path is a directory, not an archive." << endl;
			errorNum = KIO::ERR_IS_DIRECTORY;
		}
		else
			errorNum = KIO::ERR_DOES_NOT_EXIST;
		return false;
	}

	if (url.protocol() == "pak") {
		kdDebug(PAK_DEBUG_ID) << "Creating a KPak object on " << archiveFile << endl;
		_pakFile = new KPak(archiveFile);
	} else {
		kdWarning(PAK_DEBUG_ID) << "Protocol " << url.protocol() << " not supported by this IOSlave" << endl;
		errorNum = KIO::ERR_UNSUPPORTED_PROTOCOL;
		return false;
	}

	if ( !_pakFile->open(IO_ReadOnly) )
	{
		kdDebug(PAK_DEBUG_ID) << "Opening " << archiveFile << "failed." << endl;
		delete _pakFile;
		_pakFile = NULL;
		errorNum = KIO::ERR_CANNOT_OPEN_FOR_READING;
		return false;
	}

	_pakFileName = archiveFile;
	return true;
}
Пример #14
0
bool KPty::open()
{
  Q_D(KPty);

  if (d->masterFd >= 0)
    return true;

  d->ownMaster = true;

  QByteArray ptyName;

  // Find a master pty that we can open ////////////////////////////////

  // Because not all the pty animals are created equal, they want to
  // be opened by several different methods.

  // We try, as we know them, one by one.

#ifdef HAVE_OPENPTY

  char ptsn[PATH_MAX];
  if (::openpty( &d->masterFd, &d->slaveFd, ptsn, 0, 0))
  {
    d->masterFd = -1;
    d->slaveFd = -1;
    kWarning(175) << "Can't open a pseudo teletype";
    return false;
  }
  d->ttyName = ptsn;

#else

#ifdef HAVE__GETPTY // irix

  char *ptsn = _getpty(&d->masterFd, O_RDWR|O_NOCTTY, S_IRUSR|S_IWUSR, 0);
  if (ptsn) {
    d->ttyName = ptsn;
    goto grantedpt;
  }

#elif defined(HAVE_PTSNAME) || defined(TIOCGPTN)

#ifdef HAVE_POSIX_OPENPT
  d->masterFd = ::posix_openpt(O_RDWR|O_NOCTTY);
#elif defined(HAVE_GETPT)
  d->masterFd = ::getpt();
#elif defined(PTM_DEVICE)
  d->masterFd = KDE_open(PTM_DEVICE, O_RDWR|O_NOCTTY);
#else
# error No method to open a PTY master detected.
#endif
  if (d->masterFd >= 0)
  {
#ifdef HAVE_PTSNAME
    char *ptsn = ptsname(d->masterFd);
    if (ptsn) {
        d->ttyName = ptsn;
#else
    int ptyno;
    if (!ioctl(d->masterFd, TIOCGPTN, &ptyno)) {
        char buf[32];
        sprintf(buf, "/dev/pts/%d", ptyno);
        d->ttyName = buf;
#endif
#ifdef HAVE_GRANTPT
        if (!grantpt(d->masterFd))
           goto grantedpt;
#else
        goto gotpty;
#endif
    }
    ::close(d->masterFd);
    d->masterFd = -1;
  }
#endif // HAVE_PTSNAME || TIOCGPTN

  // Linux device names, FIXME: Trouble on other systems?
  for (const char* s3 = "pqrstuvwxyzabcde"; *s3; s3++)
  {
    for (const char* s4 = "0123456789abcdef"; *s4; s4++)
    {
      ptyName = QString().sprintf("/dev/pty%c%c", *s3, *s4).toAscii();
      d->ttyName = QString().sprintf("/dev/tty%c%c", *s3, *s4).toAscii();

      d->masterFd = KDE_open(ptyName.data(), O_RDWR);
      if (d->masterFd >= 0)
      {
#ifdef Q_OS_SOLARIS
        /* Need to check the process group of the pty.
         * If it exists, then the slave pty is in use,
         * and we need to get another one.
         */
        int pgrp_rtn;
        if (ioctl(d->masterFd, TIOCGPGRP, &pgrp_rtn) == 0 || errno != EIO) {
          ::close(d->masterFd);
          d->masterFd = -1;
          continue;
        }
#endif /* Q_OS_SOLARIS */
        if (!access(d->ttyName.data(),R_OK|W_OK)) // checks availability based on permission bits
        {
          if (!geteuid())
          {
            struct group* p = getgrnam(TTY_GROUP);
            if (!p)
              p = getgrnam("wheel");
            gid_t gid = p ? p->gr_gid : getgid ();

            chown(d->ttyName.data(), getuid(), gid);
            chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
          }
          goto gotpty;
        }
        ::close(d->masterFd);
        d->masterFd = -1;
      }
    }
  }

  kWarning(175) << "Can't open a pseudo teletype";
  return false;

 gotpty:
  KDE_struct_stat st;
  if (KDE_stat(d->ttyName.data(), &st))
    return false; // this just cannot happen ... *cough*  Yeah right, I just
                  // had it happen when pty #349 was allocated.  I guess
                  // there was some sort of leak?  I only had a few open.
  if (((st.st_uid != getuid()) ||
       (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) &&
      !d->chownpty(true))
  {
    kWarning(175)
      << "chownpty failed for device " << ptyName << "::" << d->ttyName
      << "\nThis means the communication can be eavesdropped." << endl;
  }

 grantedpt:

#ifdef HAVE_REVOKE
  revoke(d->ttyName.data());
#endif

#ifdef HAVE_UNLOCKPT
  unlockpt(d->masterFd);
#elif defined(TIOCSPTLCK)
  int flag = 0;
  ioctl(d->masterFd, TIOCSPTLCK, &flag);
#endif

  d->slaveFd = KDE_open(d->ttyName.data(), O_RDWR | O_NOCTTY);
  if (d->slaveFd < 0)
  {
    kWarning(175) << "Can't open slave pseudo teletype";
    ::close(d->masterFd);
    d->masterFd = -1;
    return false;
  }

#if (defined(__svr4__) || defined(__sgi__) || defined(Q_OS_SOLARIS))
  // Solaris uses STREAMS for terminal handling. It is possible
  // for the pty handling modules to be left off the stream; in that
  // case push them on. ioctl(fd, I_FIND, ...) is documented to return
  // 1 if the module is on the stream already.
  {
    static const char *pt = "ptem";
    static const char *ld = "ldterm";
    if (ioctl(d->slaveFd, I_FIND, pt) == 0)
      ioctl(d->slaveFd, I_PUSH, pt);
    if (ioctl(d->slaveFd, I_FIND, ld) == 0)
      ioctl(d->slaveFd, I_PUSH, ld);
  }
#endif

#endif /* HAVE_OPENPTY */

  fcntl(d->masterFd, F_SETFD, FD_CLOEXEC);
  fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC);

  return true;
}

bool KPty::open(int fd)
{
#if !defined(HAVE_PTSNAME) && !defined(TIOCGPTN)
    kWarning(175) << "Unsupported attempt to open pty with fd" << fd;
    return false;
#else
    Q_D(KPty);

    if (d->masterFd >= 0) {
        kWarning(175) << "Attempting to open an already open pty";
        return false;
    }

    d->ownMaster = false;

# ifdef HAVE_PTSNAME
    char *ptsn = ptsname(fd);
    if (ptsn) {
        d->ttyName = ptsn;
# else
    int ptyno;
    if (!ioctl(fd, TIOCGPTN, &ptyno)) {
        char buf[32];
        sprintf(buf, "/dev/pts/%d", ptyno);
        d->ttyName = buf;
# endif
    } else {
        kWarning(175) << "Failed to determine pty slave device for fd" << fd;
        return false;
    }

    d->masterFd = fd;
    if (!openSlave()) {
        d->masterFd = -1;
        return false;
    }

    return true;
#endif
}

void KPty::closeSlave()
{
    Q_D(KPty);

    if (d->slaveFd < 0)
        return;
    ::close(d->slaveFd);
    d->slaveFd = -1;
}
Пример #15
0
void KFileTreeBranch::addItems( const KFileItemList& list )
{
    KFileItemListIterator it( list );
    kdDebug(250) << "Adding " << list.count() << " items !" << endl;
    KFileItem *currItem;
    KFileTreeViewItemList treeViewItList;
    KFileTreeViewItem *parentItem = 0;

    while ( (currItem = it.current()) != 0 )
    {
        parentItem = parentKFTVItem( currItem );


        /* Only create a new KFileTreeViewItem if it does not yet exist */
        KFileTreeViewItem *newKFTVI =
            static_cast<KFileTreeViewItem *>(currItem->extraData( this ));

        if( ! newKFTVI )
        {
            newKFTVI = createTreeViewItem( parentItem, currItem );
            if (!newKFTVI)
            {
                // TODO: Don't fail if parentItem == 0
                ++it;
                continue;
            }
            currItem->setExtraData( this, newKFTVI );

            /* Cut off the file extension in case it is not a directory */
            if( !m_showExtensions && !currItem->isDir() )	/* Need to cut the extension */
            {
                TQString name = currItem->text();
                int mPoint = name.findRev( '.' );
                if( mPoint > 0 )
                    name = name.left( mPoint );
                newKFTVI->setText( 0, name );
            }
        }

        /* Now try to find out if there are children for dirs in the treeview */
        /* This stats a directory on the local file system and checks the */
        /* hardlink entry in the stat-buf. This works only for local directories. */
        if( dirOnlyMode() && !m_recurseChildren && currItem->isLocalFile( ) && currItem->isDir() )
        {
            KURL url = currItem->url();
            TQString filename = url.directory( false, true ) + url.fileName();
            /* do the stat trick of Carsten. The problem is, that the hardlink
             *  count only contains directory links. Thus, this method only seem
             * to work in dir-only mode */
            kdDebug(250) << "Doing stat on " << filename << endl;
            KDE_struct_stat statBuf;
            if( KDE_stat( TQFile::encodeName( filename ), &statBuf ) == 0 )
            {
                int hardLinks = statBuf.st_nlink;  /* Count of dirs */
                kdDebug(250) << "stat succeeded, hardlinks: " << hardLinks << endl;
                // If the link count is > 2, the directory likely has subdirs. If it's < 2
                // it's something weird like a mounted SMB share. In that case we don't know
                // if there are subdirs, thus show it as expandable.

                if( hardLinks != 2 )
                {
                    newKFTVI->setExpandable(true);
                }
                else
                {
                    newKFTVI->setExpandable(false);
                }
                if( hardLinks >= 2 ) // "Normal" directory with subdirs
                {
                    kdDebug(250) << "Emitting for " << url.prettyURL() << endl;
                    emit( directoryChildCount( newKFTVI, hardLinks-2)); // parentItem, hardLinks-1 ));
                }
            }
            else
            {
                kdDebug(250) << "stat of " << filename << " failed !" << endl;
            }
        }
        ++it;

        treeViewItList.append( newKFTVI );
    }

    emit newTreeViewItems( this, treeViewItList );
}
Пример #16
0
/* antlarr: KDE 4.0:  make the first parameter "const QString &" */
bool KConfigINIBackEnd::writeConfigFile(QString filename, bool bGlobal, bool bMerge)
{
    // is the config object read-only?
    if(pConfig->isReadOnly())
        return true; // pretend we wrote it

    KEntryMap aTempMap;
    QFile *mergeFile = (bMerge ? new QFile(filename) : 0);
    bool bEntriesLeft = getEntryMap(aTempMap, bGlobal, mergeFile);
    delete mergeFile;
    if(bFileImmutable)
        return true; // pretend we wrote it

    // OK now the temporary map should be full of ALL entries.
    // write it out to disk.

    // Check if file exists:
    int fileMode = -1;
    bool createNew = true;

    KDE_struct_stat buf;
    if(KDE_stat(QFile::encodeName(filename), &buf) == 0)
    {
        if(buf.st_uid == getuid())
        {
            // Preserve file mode if file exists and is owned by user.
            fileMode = buf.st_mode & 0777;
        }
        else
        {
            // File is not owned by user:
            // Don't create new file but write to existing file instead.
            createNew = false;
        }
    }

    KSaveFile *pConfigFile = 0;
    FILE *pStream = 0;

    if(createNew)
    {
        pConfigFile = new KSaveFile(filename, 0600);

        if(pConfigFile->status() != 0)
        {
            delete pConfigFile;
            return bEntriesLeft;
        }

        if(!bGlobal && (fileMode == -1))
            fileMode = mFileMode;

        if(fileMode != -1)
        {
            fchmod(pConfigFile->handle(), fileMode);
        }

        pStream = pConfigFile->fstream();
    }
    else
    {
        // Open existing file.
        // We use open() to ensure that we call without O_CREAT.
        int fd = KDE_open(QFile::encodeName(filename), O_WRONLY | O_TRUNC);
        if(fd < 0)
        {
            return bEntriesLeft;
        }
        pStream = KDE_fdopen(fd, "w");
        if(!pStream)
        {
            close(fd);
            return bEntriesLeft;
        }
    }

    writeEntries(pStream, aTempMap);

    if(pConfigFile)
    {
        bool bEmptyFile = (ftell(pStream) == 0);
        if(bEmptyFile && ((fileMode == -1) || (fileMode == 0600)))
        {
            // File is empty and doesn't have special permissions: delete it.
            ::unlink(QFile::encodeName(filename));
            pConfigFile->abort();
        }
        else
        {
            // Normal case: Close the file
            pConfigFile->close();
        }
        delete pConfigFile;
    }
    else
    {
        fclose(pStream);
    }

    return bEntriesLeft;
}
Пример #17
0
static void lookupDirectory(const QString& path, const QString &relPart,
			    const QRegExp &regexp,
			    QStringList& list,
			    QStringList& relList,
			    bool recursive, bool unique)
{
  QString pattern = regexp.pattern();
  if (recursive || pattern.contains('?') || pattern.contains('*'))
  {
    if (path.isEmpty()) //for sanity
      return;
    // We look for a set of files.
    DIR *dp = opendir( QFile::encodeName(path));
    if (!dp)
      return;

#ifdef Q_WS_WIN
    assert(path.at(path.length() - 1) == '/' || path.at(path.length() - 1) == '\\');
#else
    assert(path.at(path.length() - 1) == '/');
#endif

    struct dirent *ep;
    KDE_struct_stat buff;

    QString _dot(".");
    QString _dotdot("..");

    while( ( ep = readdir( dp ) ) != 0L )
    {
      QString fn( QFile::decodeName(ep->d_name));
      if (fn == _dot || fn == _dotdot || fn.at(fn.length() - 1).latin1() == '~')
	continue;

      if (!recursive && !regexp.exactMatch(fn))
	continue; // No match

      QString pathfn = path + fn;
      if ( KDE_stat( QFile::encodeName(pathfn), &buff ) != 0 ) {
	kdDebug() << "Error stat'ing " << pathfn << " : " << perror << endl;
	continue; // Couldn't stat (e.g. no read permissions)
      }
      if ( recursive ) {
	if ( S_ISDIR( buff.st_mode )) {
	  lookupDirectory(pathfn + '/', relPart + fn + '/', regexp, list, relList, recursive, unique);
	}
        if (!regexp.exactMatch(fn))
	  continue; // No match
      }
      if ( S_ISREG( buff.st_mode))
      {
        if (!unique || !relList.contains(relPart + fn))
        {
	    list.append( pathfn );
	    relList.append( relPart + fn );
        }
      }
    }
    closedir( dp );
  }
  else
  {
     // We look for a single file.
     QString fn = pattern;
     QString pathfn = path + fn;
     KDE_struct_stat buff;
     if ( KDE_stat( QFile::encodeName(pathfn), &buff ) != 0 )
        return; // File not found
     if ( S_ISREG( buff.st_mode))
     {
       if (!unique || !relList.contains(relPart + fn))
       {
         list.append( pathfn );
         relList.append( relPart + fn );
       }
     }
  }
}
Пример #18
0
void PakProtocol::stat(const KURL &url) {
	kdDebug(PAK_DEBUG_ID) << "Entering stat()" << endl;
	QString path;
	KIO::UDSEntry entry;
	KIO::Error errorNum;
	if ( !checkNewFile( url, path, errorNum ) )
	{
		// We may be looking at a real directory - this happens
		// when pressing up after being in the root of an archive
		if ( errorNum == KIO::ERR_CANNOT_OPEN_FOR_READING )
		{
			// If we cannot open, it might be a problem with the archive header (e.g. unsupported format)
			// Therefore give a more specific error message
			error( KIO::ERR_SLAVE_DEFINED,
					i18n( "Could not open the file, probably due to an unsupported file format.\n%1")
					.arg( url.prettyURL() ) );
			return;
		}
		else if ( errorNum != KIO::ERR_IS_DIRECTORY )
		{
			// We have any other error
			error( errorNum, url.prettyURL() );
			return;
		}
		// Real directory. Return just enough information for KRun to work
		KIO::UDSAtom atom;
		atom.m_uds = KIO::UDS_NAME;
		atom.m_str = url.fileName();
		entry.append( atom );
		kdDebug( PAK_DEBUG_ID ) << "ArchiveProtocol::stat returning name=" << url.fileName() << endl;

		KDE_struct_stat buff;
		if ( KDE_stat( QFile::encodeName( url.path() ), &buff ) == -1 )
		{
			// Should not happen, as the file was already stated by checkNewFile
			error( KIO::ERR_COULD_NOT_STAT, url.prettyURL() );
			return;
		}

		atom.m_uds = KIO::UDS_FILE_TYPE;
		atom.m_long = buff.st_mode & S_IFMT;
		entry.append( atom );

		statEntry( entry );

		finished();

		// And let go of the tar file - for people who want to unmount a cdrom after that
		delete _pakFile;
		_pakFile = 0L;
		return;
	}

	const KArchiveDirectory* root = _pakFile->directory();
	const KArchiveEntry* archiveEntry;
	if ( path.isEmpty() )
	{
		path = QString::fromLatin1( "/" );
		archiveEntry = root;
	} else {
		path = QString::fromLocal8Bit(remoteEncoding()->encode(path));
		archiveEntry = root->entry( path );
	}
	if ( !archiveEntry )
	{
		error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() );
		return;
	}

	createUDSEntry( archiveEntry, entry );
	statEntry( entry );

	finished();

	/*kdDebug(PAK_DEBUG_ID) << "Entering stat()" << endl;
	KIO::UDSEntry entry;
	createUDSEntry(NULL, entry);
	kdDebug(PAK_DEBUG_ID) << "Giving file away" << endl;
	statEntry(entry);
	finished();
	kdDebug(PAK_DEBUG_ID) << "-<> Exiting stat()" << endl;*/
}
Пример #19
0
static void lookupPrefix(const QString& prefix, const QString& relpath,
                         const QString& relPart,
			 const QRegExp &regexp,
			 QStringList& list,
			 QStringList& relList,
			 bool recursive, bool unique)
{
    if (relpath.isEmpty()) {
       lookupDirectory(prefix, relPart, regexp, list,
		       relList, recursive, unique);
       return;
    }
    QString path;
    QString rest;

    if (relpath.length())
    {
       int slash = relpath.find('/');
       if (slash < 0)
	   rest = relpath.left(relpath.length() - 1);
       else {
	   path = relpath.left(slash);
	   rest = relpath.mid(slash + 1);
       }
    }

    if (prefix.isEmpty()) //for sanity
      return;
#ifdef Q_WS_WIN
    assert(prefix.at(prefix.length() - 1) == '/' || prefix.at(prefix.length() - 1) == '\\');
#else
    assert(prefix.at(prefix.length() - 1) == '/');
#endif
    KDE_struct_stat buff;

    if (path.contains('*') || path.contains('?')) {

	QRegExp pathExp(path, true, true);
	DIR *dp = opendir( QFile::encodeName(prefix) );
	if (!dp) {
	    return;
	}

	struct dirent *ep;

        QString _dot(".");
        QString _dotdot("..");

	while( ( ep = readdir( dp ) ) != 0L )
	    {
		QString fn( QFile::decodeName(ep->d_name));
		if (fn == _dot || fn == _dotdot || fn.at(fn.length() - 1) == '~')
		    continue;

		if ( !pathExp.exactMatch(fn) )
		    continue; // No match
		QString rfn = relPart+fn;
		fn = prefix + fn;
		if ( KDE_stat( QFile::encodeName(fn), &buff ) != 0 ) {
		    kdDebug() << "Error statting " << fn << " : " << perror << endl;
		    continue; // Couldn't stat (e.g. no permissions)
		}
		if ( S_ISDIR( buff.st_mode ))
		    lookupPrefix(fn + '/', rest, rfn + '/', regexp, list, relList, recursive, unique);
	    }

	closedir( dp );
    } else {
        // Don't stat, if the dir doesn't exist we will find out
        // when we try to open it.
        lookupPrefix(prefix + path + '/', rest,
                     relPart + path + '/', regexp, list,
                     relList, recursive, unique);
    }
}
Пример #20
0
void DirectoryListThread::run()
{
    // Thread safety notes:
    //
    // There very possibly may be thread safety issues here, but I've done a check
    // of all of the things that would seem to be problematic.  Here are a few
    // things that I have checked to be safe here (some used indirectly):
    //
    // QDir::currentDirPath(), QDir::setCurrent(), QFile::decodeName(), QFile::encodeName()
    // QString::fromLocal8Bit(), QString::local8Bit(), QTextCodec::codecForLocale()
    //
    // Also see (for POSIX functions):
    // http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html

    DIR *dir = 0;

    for(QStringList::ConstIterator it = m_dirList.begin(); it != m_dirList.end() && !terminationRequested(); ++it)
    {
        // Open the next directory

        if(!dir)
        {
            dir = ::opendir(QFile::encodeName(*it));
            if(!dir)
            {
                kdDebug() << "Failed to open dir: " << *it << endl;
                done();
                return;
            }
        }

        // A trick from KIO that helps performance by a little bit:
        // chdir to the directroy so we won't have to deal with full paths
        // with stat()

        QString path = QDir::currentDirPath();
        QDir::setCurrent(*it);

// Loop through all directory entries
// Solaris and IRIX dirent structures do not allocate space for d_name. On
// systems that do (HP-UX, Linux, Tru64 UNIX), we overallocate space but
// that's ok.
#ifndef HAVE_READDIR_R
        struct dirent *dirEntry = 0;
        while(!terminationRequested() && (dirEntry = ::readdir(dir)))
#else
        struct dirent *dirPosition = (struct dirent *)malloc(sizeof(struct dirent) + MAXPATHLEN + 1);
        struct dirent *dirEntry = 0;
        while(!terminationRequested() && ::readdir_r(dir, dirPosition, &dirEntry) == 0 && dirEntry)
#endif

        {
            // Skip hidden files if m_noHidden is true

            if(dirEntry->d_name[0] == '.' && m_noHidden)
                continue;

            // Skip "."

            if(dirEntry->d_name[0] == '.' && dirEntry->d_name[1] == '\0')
                continue;

            // Skip ".."

            if(dirEntry->d_name[0] == '.' && dirEntry->d_name[1] == '.' && dirEntry->d_name[2] == '\0')
                continue;

            QString file = QFile::decodeName(dirEntry->d_name);

            if(m_filter.isEmpty() || file.startsWith(m_filter))
            {

                if(m_onlyExe || m_onlyDir || m_appendSlashToDir)
                {
                    KDE_struct_stat sbuff;

                    if(KDE_stat(dirEntry->d_name, &sbuff) == 0)
                    {

                        // Verify executable

                        if(m_onlyExe && (sbuff.st_mode & MODE_EXE) == 0)
                            continue;

                        // Verify directory

                        if(m_onlyDir && !S_ISDIR(sbuff.st_mode))
                            continue;

                        // Add '/' to directories

                        if(m_appendSlashToDir && S_ISDIR(sbuff.st_mode))
                            file.append('/');
                    }
                    else
                    {
                        kdDebug() << "Could not stat file " << file << endl;
                        continue;
                    }
                }

                addMatch(file);
            }
        }

        // chdir to the original directory

        QDir::setCurrent(path);

        ::closedir(dir);
        dir = 0;
#ifdef HAVE_READDIR_R
        free(dirPosition);
#endif
    }

    done();
}
Пример #21
0
void RenameImagesWidget::slotNext()
{
    QTreeWidgetItem* it = ui->m_listView->selectedItems().first();
    if (!it)
    {
        slotAbort();
        return;
    }

    BatchProcessImagesItem* item = static_cast<BatchProcessImagesItem*>(it);
    KUrl src;
    src.setPath(item->pathSrc());
    KUrl dst = src.upUrl();
    dst.addPath(item->text(2));

    bool skip      = false;
    bool overwrite = false;

    if (!m_overwriteAll)
    {
        KDE_struct_stat info;
        while (KDE_stat(QFile::encodeName(dst.toLocalFile()), &info) == 0)
        {
            if (m_autoSkip)
            {
                skip = true;
                break;
            }

            QPointer<KIO::RenameDialog> dlg = new KIO::RenameDialog(this, i18n("Rename File"),
                                              src.path(), dst.path(),
                                              KIO::RenameDialog_Mode(KIO::M_MULTI | KIO::M_OVERWRITE | KIO::M_SKIP));
            int result = dlg->exec();
            dst        = dlg->newDestUrl();

            delete dlg;

            switch (result)
            {
                case KIO::R_CANCEL:
                {
                    slotAbort();
                    return;
                }
                case KIO::R_SKIP:
                {
                    skip = true;
                    break;
                }
                case KIO::R_AUTO_SKIP:
                {
                    m_autoSkip = true;
                    skip       = true;
                    break;
                }
                case KIO::R_OVERWRITE:
                {
                    overwrite       = true;
                    break;
                }
                case KIO::R_OVERWRITE_ALL:
                {
                    m_overwriteAll = true;
                    overwrite      = true;
                    break;
                }
                default:
                    break;
            }

            if (skip || overwrite)
                break;
        }
    }

    if (skip)
    {
        item->changeResult(i18nc("batch process result", "Skipped"));
    }
    else
    {
        // Get the src info
        KIPIPlugins::KPImageInfo srcInfo(src);

        if (KDE_rename(QFile::encodeName(src.toLocalFile()),
                       QFile::encodeName(dst.toLocalFile())) == 0)
        {
            // Rename XMP sidecar file
            KIPIPlugins::KPMetadata::moveSidecar(src, dst);

            srcInfo.setName(dst.fileName());

            item->changeResult(i18nc("batch process result", "OK"));
        }
        else
        {
            item->changeResult(i18nc("batch process result", "Failed"));
        }
    }

    m_progress->progressBar()->setValue(m_progress->progressBar()->value() + 1);

    it = ui->m_listView->itemBelow(it);
    if (it)
    {
        ui->m_listView->setCurrentItem(it);
        ui->m_listView->scrollToItem(it);
        m_timer->setSingleShot(true);
        m_timer->start(0);
    }
}
Пример #22
0
void KFileItem::init( bool _determineMimeTypeOnDemand )
{
  m_access = QString::null;
  m_size = (KIO::filesize_t) -1;
  //  metaInfo = KFileMetaInfo();
  for ( int i = 0; i < NumFlags; i++ )
      m_time[i] = (time_t) -1;

  // determine mode and/or permissions if unknown
  if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown )
  {
    mode_t mode = 0;
    if ( m_url.isLocalFile() )
    {
      /* directories may not have a slash at the end if
       * we want to stat() them; it requires that we
       * change into it .. which may not be allowed
       * stat("/is/unaccessible")  -> rwx------
       * stat("/is/unaccessible/") -> EPERM            H.Z.
       * This is the reason for the -1
       */
      KDE_struct_stat buf;
      QCString path = QFile::encodeName(m_url.path( -1 ));
      if ( KDE_lstat( path.data(), &buf ) == 0 )
      {
        mode = buf.st_mode;
        if ( S_ISLNK( mode ) )
        {
          m_bLink = true;
          if ( KDE_stat( path.data(), &buf ) == 0 )
              mode = buf.st_mode;
          else // link pointing to nowhere (see kio/file/file.cc)
              mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO;
        }
        // While we're at it, store the times
        m_time[ Modification ] = buf.st_mtime;
        m_time[ Access ] = buf.st_atime;
        if ( m_fileMode == KFileItem::Unknown )
          m_fileMode = mode & S_IFMT; // extract file type
        if ( m_permissions == KFileItem::Unknown )
          m_permissions = mode & 07777; // extract permissions
      }
    }
  }

  // determine the mimetype
  if (!m_pMimeType && !m_url.isEmpty())
  {
      bool accurate = false;
      bool isLocalURL;
      KURL url = mostLocalURL(isLocalURL);

      m_pMimeType = KMimeType::findByURL( url, m_fileMode, isLocalURL,
                                          // use fast mode if not mimetype on demand
                                          _determineMimeTypeOnDemand, &accurate );
      //kdDebug() << "finding mimetype for " << url.url() << " : " << m_pMimeType->name() << endl;
      // if we didn't use fast mode, or if we got a result, then this is the mimetype
      // otherwise, determineMimeType will be able to do better.
      m_bMimeTypeKnown = (!_determineMimeTypeOnDemand) || accurate;
  }
}