kio Library: kar.cpp Source File (kio Library)

| # kio Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kar.cpp

    00001
    00002 /* This file is part of the KDE libraries
    00003    Copyright (C) 2002 Laurence Anderson <l.d.anderson@warwick.ac.uk>
    00004
    00005    This library is free software; you can redistribute it and/or
    00006    modify it under the terms of the GNU Library General Public
    00007    License version 2 as published by the Free Software Foundation.
    00008
    00009    This library is distributed in the hope that it will be useful,
    00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012    Library General Public License for more details.
    00013
    00014    You should have received a copy of the GNU Library General Public License
    00015    along with this library; see the file COPYING.LIB.  If not, write to
    00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00017    Boston, MA 02111-1307, USA.
    00018 */
    00019
    00020 #include <qfile.h>
    00021 #include <qdir.h>
    00022 #include <time.h>
    00023 #include <kdebug.h>
    00024 #include <qptrlist.h>
    00025 #include <kmimetype.h>
    00026 #include <qregexp.h>
    00027
    00028 #include "kfilterdev.h"
    00029 #include "kar.h"
    00030 //#include "klimitediodevice.h"
    00031
    00035
    00036 class KAr::KArPrivate
    00037 {
    00038 public:
    00039     KArPrivate() {}
    00040 };
    00041
    00042 KAr::KAr( const QString& filename )
    00043     : KArchive( 0L )
    00044 {
    00045     //kdDebug(7042) << "KAr(filename) reached." << endl;
    00046     m_filename = filename;
    00047     d = new KArPrivate;
    00048     setDevice( new QFile( filename ) );
    00049 }
    00050
    00051 KAr::KAr( QIODevice * dev )
    00052     : KArchive( dev )
    00053 {
    00054     //kdDebug(7042) << "KAr::KAr( QIODevice * dev) reached." << endl;
    00055     d = new KArPrivate;
    00056 }
    00057
    00058 KAr::~KAr()
    00059 {
    00060     // mjarrett: Closes to prevent ~KArchive from aborting w/o device
    00061     //kdDebug(7042) << "~KAr reached." << endl;
    00062     if( isOpened() )
    00063         close();
    00064     if ( !m_filename.isEmpty() )
    00065         delete device(); // we created it ourselves
    00066     delete d;
    00067 }
    00068
    00069 bool KAr::openArchive( int mode )
    00070 {
    00071     // Open archive
    00072
    00073     //kdDebug(7042) << "openarchive reached." << endl;
    00074
    00075     if ( mode == IO_WriteOnly )
    00076         return true;
    00077     if ( mode != IO_ReadOnly && mode != IO_ReadWrite )
    00078     {
    00079         kdWarning(7042) << "Unsupported mode " << mode << endl;
    00080         return false;
    00081     }
    00082
    00083     QIODevice* dev = device();
    00084     if ( !dev )
    00085         return false;
    00086
    00087     char magic[8];
    00088     dev->readBlock (magic, 8);
    00089     if (qstrncmp(magic, "!<arch>", 7) != 0) {
    00090         kdWarning(7042) << "Invalid main magic" << endl;
    00091         return false;
    00092     }
    00093
    00094     char *ar_longnames = 0;
    00095     while (! dev->atEnd()) {
    00096         QCString ar_header;
    00097         ar_header.resize(61);
    00098         QCString name;
    00099         int date, uid, gid, mode, size;
    00100
    00101         dev->at( dev->at() + (2 - (dev->at() % 2)) % 2 ); // Ar headers are padded to byte boundary
    00102
    00103         if ( dev->readBlock (ar_header.data(), 60) != 60 ) { // Read ar header
    00104             kdWarning(7042) << "Couldn't read header" << endl;
    00105             delete[] ar_longnames;
    00106             //return false;
    00107             return true; // Probably EOF / trailing junk
    00108         }
    00109
    00110         if (ar_header.right(2) != "`\n") { // Check header magic
    00111             kdWarning(7042) << "Invalid magic" << endl;
    00112             delete[] ar_longnames;
    00113             return false;
    00114         }
    00115
    00116         name = ar_header.mid( 0, 16 ); // Process header
    00117         date = ar_header.mid( 16, 12 ).toInt();
    00118         uid = ar_header.mid( 28, 6 ).toInt();
    00119         gid = ar_header.mid( 34, 6 ).toInt();
    00120         mode = ar_header.mid( 40, 8 ).toInt();
    00121         size = ar_header.mid( 48, 10 ).toInt();
    00122
    00123         bool skip_entry = false; // Deal with special entries
    00124         if (name.mid(0, 1) == "/") {
    00125             if (name.mid(1, 1) == "/") { // Longfilename table entry
    00126                 delete[] ar_longnames;
    00127                 ar_longnames = new char[size + 1];
    00128                 ar_longnames[size] = '\0';
    00129                 dev->readBlock (ar_longnames, size);
    00130                 skip_entry = true;
    00131                 kdDebug(7042) << "Read in longnames entry" << endl;
    00132             } else if (name.mid(1, 1) == " ") { // Symbol table entry
    00133                 kdDebug(7042) << "Skipped symbol entry" << endl;
    00134                 dev->at( dev->at() + size );
    00135                 skip_entry = true;
    00136             } else { // Longfilename
    00137                 kdDebug(7042) << "Longfilename #" << name.mid(1, 15).toInt() << endl;
    00138                 if (! ar_longnames) {
    00139                     kdWarning(7042) << "Invalid longfilename reference" << endl;
    00140                     return false;
    00141                 }
    00142                 name = &ar_longnames[name.mid(1, 15).toInt()];
    00143                 name = name.left(name.find("/"));
    00144             }
    00145         }
    00146         if (skip_entry) continue;
    00147
    00148         name = name.stripWhiteSpace(); // Process filename
    00149         name.replace( "/", "" );
    00150         kdDebug(7042) << "Filename: " << name << " Size: " << size << endl;
    00151
    00152         KArchiveEntry* entry;
    00153         entry = new KArchiveFile(this, name, mode, date, /*uid*/ 0, /*gid*/ 0, 0, dev->at(), size);
    00154         rootDir()->addEntry(entry); // Ar files don't support directorys, so everything in root
    00155
    00156         dev->at( dev->at() + size ); // Skip contents
    00157     }
    00158     delete[] ar_longnames;
    00159
    00160     return true;
    00161 }
    00162
    00163 bool KAr::closeArchive()
    00164 {
    00165     // Close the archive
    00166     return true;
    00167 }
    00168
    00169 void KAr::virtual_hook( int id, void* data )
    00170 { KArchive::virtual_hook( id, data ); }

This file is part of the documentation for kio Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:23:54 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003