• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kio

kar.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, 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 ); }

kio

Skip menu "kio"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal