kio Library API Documentation

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 00085 char magic[8]; 00086 dev->readBlock (magic, 8); 00087 if (qstrncmp(magic, "!<arch>", 7) != 0) { 00088 kdWarning(7042) << "Invalid main magic" << endl; 00089 return false; 00090 } 00091 00092 char *ar_longnames = 0; 00093 while (! dev->atEnd()) { 00094 QCString ar_header; 00095 ar_header.resize(61); 00096 QCString name; 00097 int date, uid, gid, mode, size; 00098 00099 dev->at( dev->at() + (2 - (dev->at() % 2)) % 2 ); // Ar headers are padded to byte boundary 00100 00101 if ( dev->readBlock (ar_header.data(), 60) != 60 ) { // Read ar header 00102 kdWarning(7042) << "Couldn't read header" << endl; 00103 delete[] ar_longnames; 00104 //return false; 00105 return true; // Probably EOF / trailing junk 00106 } 00107 00108 if (ar_header.right(2) != "`\n") { // Check header magic 00109 kdWarning(7042) << "Invalid magic" << endl; 00110 delete[] ar_longnames; 00111 return false; 00112 } 00113 00114 name = ar_header.mid( 0, 16 ); // Process header 00115 date = ar_header.mid( 16, 12 ).toInt(); 00116 uid = ar_header.mid( 28, 6 ).toInt(); 00117 gid = ar_header.mid( 34, 6 ).toInt(); 00118 mode = ar_header.mid( 40, 8 ).toInt(); 00119 size = ar_header.mid( 48, 10 ).toInt(); 00120 00121 bool skip_entry = false; // Deal with special entries 00122 if (name.mid(0, 1) == "/") { 00123 if (name.mid(1, 1) == "/") { // Longfilename table entry 00124 delete[] ar_longnames; 00125 ar_longnames = new char[size + 1]; 00126 ar_longnames[size] = '\0'; 00127 dev->readBlock (ar_longnames, size); 00128 skip_entry = true; 00129 kdDebug(7042) << "Read in longnames entry" << endl; 00130 } else if (name.mid(1, 1) == " ") { // Symbol table entry 00131 kdDebug(7042) << "Skipped symbol entry" << endl; 00132 dev->at( dev->at() + size ); 00133 skip_entry = true; 00134 } else { // Longfilename 00135 kdDebug(7042) << "Longfilename #" << name.mid(1, 15).toInt() << endl; 00136 if (! ar_longnames) { 00137 kdWarning(7042) << "Invalid longfilename reference" << endl; 00138 return false; 00139 } 00140 name = &ar_longnames[name.mid(1, 15).toInt()]; 00141 name = name.left(name.find("/")); 00142 } 00143 } 00144 if (skip_entry) continue; 00145 00146 name = name.stripWhiteSpace(); // Process filename 00147 name.replace( "/", "" ); 00148 kdDebug(7042) << "Filename: " << name << " Size: " << size << endl; 00149 00150 KArchiveEntry* entry; 00151 entry = new KArchiveFile(this, name, mode, date, /*uid*/ 0, /*gid*/ 0, 0, dev->at(), size); 00152 rootDir()->addEntry(entry); // Ar files don't support directorys, so everything in root 00153 00154 dev->at( dev->at() + size ); // Skip contents 00155 } 00156 delete[] ar_longnames; 00157 00158 return true; 00159 } 00160 00161 bool KAr::closeArchive() 00162 { 00163 // Close the archive 00164 return true; 00165 } 00166 00167 void KAr::virtual_hook( int id, void* data ) 00168 { KArchive::virtual_hook( id, data ); }
KDE Logo
This file is part of the documentation for kio Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:41:02 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003