--Boundary-00=_hSnQ/RP69uFiKJt Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi, I've attached a patch to kdebase to change over to using suburls for archives. This means that before if you clicked on an archive you would get something like: tar:/home/me/archive.tar/ but now you get: file:/home/me/archive.tar#tar:/ This has various benefits, such as making the ioslave simpler, and will (soon) support archives within archives, and archives from other protocols (like floppy, mac & network protocols like ftp etc). I'd like to apply it to CVS later on this week, I'd appreciate it if more people could test the code first. Any objections? Laurence --Boundary-00=_hSnQ/RP69uFiKJt Content-Type: text/x-diff; charset="us-ascii"; name="kio_tar_suburl.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="kio_tar_suburl.diff" Index: kioslave/tar/tar.cc =================================================================== RCS file: /home/kde/kdebase/kioslave/tar/tar.cc,v retrieving revision 1.31 diff -u -p -r1.31 tar.cc --- kioslave/tar/tar.cc 12 Aug 2003 19:18:02 -0000 1.31 +++ kioslave/tar/tar.cc 19 Aug 2003 18:49:45 -0000 @@ -1,3 +1,22 @@ +/* This file is part of the KDE libraries + Copyright (C) 2000 David Faure + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + // $Id: tar.cc,v 1.31 2003/08/12 19:18:02 landers Exp $ #include @@ -6,7 +25,6 @@ #include #include -#include #include #include #include @@ -14,8 +32,6 @@ #include #include -#include // to be removed - #include "tar.h" using namespace KIO; @@ -52,27 +68,31 @@ ArchiveProtocol::~ArchiveProtocol() delete m_archiveFile; } -bool ArchiveProtocol::checkNewFile( const KURL & url, QString & path ) +bool ArchiveProtocol::checkNewFile( const KURL & _url, QString & path ) { - QString fullPath = url.path(); - kdDebug(7109) << "ArchiveProtocol::checkNewFile " << fullPath << endl; - - - // Are we already looking at that file ? - if ( m_archiveFile && m_archiveName == fullPath.left(m_archiveName.length()) ) + // 1st we need to get the archive url out of _url + KURL::List list = KURL::split(_url); + KURL::List::Iterator it = list.fromLast(); + KURL url = *it; + path = url.path(); + + if (! m_subURL.isLocalFile()) return false; // Nonlocal files not supported at present + kdDebug(7109) << "ArchiveProtocol::checkNewFile " << path << endl; + + // Has it changed ? + struct stat statbuf; + if ( m_archiveFile && m_archiveName == m_subURL.path() ) // We already have the same archive open { - // Has it changed ? - struct stat statbuf; if ( ::stat( QFile::encodeName( m_archiveName ), &statbuf ) == 0 ) { if ( m_mtime == statbuf.st_mtime ) { - path = fullPath.mid( m_archiveName.length() ); kdDebug(7109) << "ArchiveProtocol::checkNewFile returning " << path << endl; return true; } } } + kdDebug(7109) << "Need to open a new file" << endl; // Close previous file @@ -83,55 +103,21 @@ bool ArchiveProtocol::checkNewFile( cons m_archiveFile = 0L; } - // 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(7109) << "the full path is " << fullPath << endl; - while ( (pos=fullPath.find( '/', pos+1 )) != -1 ) - { - QString tryPath = fullPath.left( pos ); - kdDebug(7109) << fullPath << " trying " << tryPath << endl; - struct stat statbuf; - if ( ::stat( QFile::encodeName(tryPath), &statbuf ) == 0 && !S_ISDIR(statbuf.st_mode) ) - { - archiveFile = tryPath; - m_mtime = statbuf.st_mtime; - path = fullPath.mid( pos + 1 ); - kdDebug(7109) << "fullPath=" << fullPath << " path=" << path << endl; - len = path.length(); - if ( len > 1 ) - { - if ( path[ len - 1 ] == '/' ) - path.truncate( len - 1 ); - } - else - path = QString::fromLatin1("/"); - kdDebug(7109) << "Found. archiveFile=" << archiveFile << " path=" << path << endl; - break; - } - } - if ( archiveFile.isEmpty() ) - { - kdDebug(7109) << "ArchiveProtocol::checkNewFile: not found" << endl; - return false; - } + m_archiveName = m_subURL.path(); + + if ( ::stat( QFile::encodeName(m_archiveName), &statbuf ) == 0 ) m_mtime = statbuf.st_mtime; // Update our mtime value, so we can tell if the archive has changed // Open new file + kdDebug(7123) << "ArchiveProtocol::checkNewFile: Protocol is " << url.protocol() << endl; if ( url.protocol() == "tar" ) { - kdDebug(7109) << "Opening KTar on " << archiveFile << endl; - m_archiveFile = new KTar( archiveFile ); + kdDebug(7109) << "Opening KTar on " << m_archiveName << endl; + m_archiveFile = new KTar( m_archiveName ); } else if ( url.protocol() == "ar" ) { - kdDebug(7109) << "Opening KAr on " << archiveFile << endl; - m_archiveFile = new KAr( archiveFile ); + kdDebug(7109) << "Opening KAr on " << m_archiveName << endl; + m_archiveFile = new KAr( m_archiveName ); } else if ( url.protocol() == "zip" ) { - kdDebug(7109) << "Opening KZip on " << archiveFile << endl; - m_archiveFile = new KZip( archiveFile ); + kdDebug(7109) << "Opening KZip on " << m_archiveName << endl; + m_archiveFile = new KZip( m_archiveName ); } else { kdWarning(7109) << "Protocol " << url.protocol() << " not supported by this IOSlave" << endl; return false; @@ -139,13 +125,12 @@ bool ArchiveProtocol::checkNewFile( cons if ( !m_archiveFile->open( IO_ReadOnly ) ) { - kdDebug(7109) << "Opening " << archiveFile << "failed." << endl; + kdDebug(7109) << "Opening " << m_archiveName << "failed." << endl; delete m_archiveFile; m_archiveFile = 0L; return false; } - m_archiveName = archiveFile; return true; } @@ -194,33 +179,7 @@ void ArchiveProtocol::listDir( const KUR QString path; if ( !checkNewFile( url, path ) ) { - QCString _path( QFile::encodeName(url.path())); - kdDebug( 7109 ) << "Checking (stat) on " << _path << endl; - struct stat buff; - if ( ::stat( _path.data(), &buff ) == -1 || !S_ISDIR( buff.st_mode ) ) { - error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() ); - return; - } - // It's a real dir -> redirect - KURL redir; - redir.setPath( url.path() ); - kdDebug( 7109 ) << "Ok, redirection to " << redir.url() << endl; - redirection( redir ); - finished(); - // And let go of the tar file - for people who want to unmount a cdrom after that - delete m_archiveFile; - m_archiveFile = 0L; - return; - } - - if ( path.isEmpty() ) - { - KURL redir( url.protocol() + QString::fromLatin1( ":/") ); - kdDebug( 7109 ) << "url.path()==" << url.path() << endl; - redir.setPath( url.path() + QString::fromLatin1("/") ); - kdDebug( 7109 ) << "ArchiveProtocol::listDir: redirection " << redir.url() << endl; - redirection( redir ); - finished(); + error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() ); return; } @@ -274,34 +233,7 @@ void ArchiveProtocol::stat( const KURL & UDSEntry entry; if ( !checkNewFile( url, path ) ) { - // We may be looking at a real directory - this happens - // when pressing up after being in the root of an archive - QCString _path( QFile::encodeName(url.path())); - kdDebug( 7109 ) << "ArchiveProtocol::stat (stat) on " << _path << endl; - struct stat buff; - if ( ::stat( _path.data(), &buff ) == -1 || !S_ISDIR( buff.st_mode ) ) { - kdDebug( 7109 ) << "isdir=" << S_ISDIR( buff.st_mode ) << " errno=" << strerror(errno) << endl; - error( KIO::ERR_DOES_NOT_EXIST, url.path() ); - return; - } - // Real directory. Return just enough information for KRun to work - UDSAtom atom; - atom.m_uds = KIO::UDS_NAME; - atom.m_str = url.fileName(); - entry.append( atom ); - kdDebug( 7109 ) << "ArchiveProtocol::stat returning name=" << url.fileName() << endl; - - 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 m_archiveFile; - m_archiveFile = 0L; + error( KIO::ERR_DOES_NOT_EXIST, url.path() ); return; } @@ -375,6 +307,12 @@ void ArchiveProtocol::get( const KURL & data( QByteArray() ); finished(); +} + +void ArchiveProtocol::setSubURL(const KURL &url) +{ + kdDebug(7109) << "ArchiveProtocol(" << getpid() << ")::setSubURL " << url.url() << endl; + m_subURL = url; } /* Index: kioslave/tar/tar.h =================================================================== RCS file: /home/kde/kdebase/kioslave/tar/tar.h,v retrieving revision 1.13 diff -u -p -r1.13 tar.h --- kioslave/tar/tar.h 23 Jun 2003 16:38:11 -0000 1.13 +++ kioslave/tar/tar.h 19 Aug 2003 18:49:45 -0000 @@ -32,6 +32,7 @@ public: virtual void listDir( const KURL & url ); virtual void stat( const KURL & url ); virtual void get( const KURL & url ); + virtual void setSubURL ( const KURL& url ); protected: void createUDSEntry( const KArchiveEntry * tarEntry, KIO::UDSEntry & entry ); @@ -40,6 +41,7 @@ protected: KArchive * m_archiveFile; QString m_archiveName; time_t m_mtime; + KURL m_subURL; }; #endif Index: konqueror/konq_mainwindow.cc =================================================================== RCS file: /home/kde/kdebase/konqueror/konq_mainwindow.cc,v retrieving revision 1.1215 diff -u -p -r1.1215 konq_mainwindow.cc --- konqueror/konq_mainwindow.cc 12 Aug 2003 14:15:37 -0000 1.1215 +++ konqueror/konq_mainwindow.cc 19 Aug 2003 18:50:01 -0000 @@ -625,35 +625,47 @@ bool KonqMainWindow::openView( QString s KURL url( _url ); - //////////// Tar/zip files support + //////////// Archive file support // The hack-ish and hardcoded way. // Possible cleaner solution: 2 properties in the mimetype definition, // e.g. X-Konq-Redirect-URL set to tar:%f/ // and X-Konq-Redirect-Mimetype set to inode/directory - if ( url.isLocalFile()) // kio_tar/kio_zip only support local files + if ( url.isLocalFile()) // kio_tar only supports local files { if ( serviceType == QString::fromLatin1("application/x-tar") || serviceType == QString::fromLatin1("application/x-tgz") || serviceType == QString::fromLatin1("application/x-tbz") ) { - url.setProtocol( QString::fromLatin1("tar") ); - url.setPath( url.path() + '/' ); + KURL::List lst(url); + lst.append("tar:/"); + url = KURL::join(lst); + serviceType = "inode/directory"; // kdDebug(1202) << "TAR FILE. Now trying with " << url.url() << endl; } else if (serviceType == QString::fromLatin1("application/x-webarchive") ) { - url.setProtocol( QString::fromLatin1("tar") ); - url.setPath( url.path() + "/index.html"); + KURL::List lst(url); + lst.append("tar:/index.html"); + url = KURL::join(lst); serviceType = "text/html"; } else if (serviceType == QString::fromLatin1("application/x-zip")) { - url.setProtocol( QString::fromLatin1("zip") ); - url.setPath( url.path() + '/' ); + KURL::List lst(url); + lst.append("zip:/"); + url = KURL::join(lst); + + serviceType = "inode/directory"; + } + else if (serviceType == QString::fromLatin1("application/x-archive")) + { + KURL::List lst(url); + lst.append("ar:/"); + url = KURL::join(lst); serviceType = "inode/directory"; } --Boundary-00=_hSnQ/RP69uFiKJt--