[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Convert kio_tar to use SubURLs
From:       Laurence Anderson <l.d.anderson () warwick ! ac ! uk>
Date:       2003-08-19 19:04:01
[Download RAW message or body]

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
["kio_tar_suburl.diff" (text/x-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 <faure@kde.org>
+
+    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 <sys/types.h>
@@ -6,7 +25,6 @@
 #include <unistd.h>
 
 #include <qfile.h>
-#include <kurl.h>
 #include <kdebug.h>
 #include <kinstance.h>
 #include <ktar.h>
@@ -14,8 +32,6 @@
 #include <kar.h>
 #include <kmimemagic.h>
 
-#include <errno.h> // 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";
     }



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic