kio
kar.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00031
00035
00036 class KAr::KArPrivate
00037 {
00038 public:
00039 KArPrivate() {}
00040 };
00041
00042 KAr::KAr( const QString& filename )
00043 : KArchive( 0L )
00044 {
00045
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
00055 d = new KArPrivate;
00056 }
00057
00058 KAr::~KAr()
00059 {
00060
00061
00062 if( isOpened() )
00063 close();
00064 if ( !m_filename.isEmpty() )
00065 delete device();
00066 delete d;
00067 }
00068
00069 bool KAr::openArchive( int mode )
00070 {
00071
00072
00073
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 );
00102
00103 if ( dev->readBlock (ar_header.data(), 60) != 60 ) {
00104 kdWarning(7042) << "Couldn't read header" << endl;
00105 delete[] ar_longnames;
00106
00107 return true;
00108 }
00109
00110 if (ar_header.right(2) != "`\n") {
00111 kdWarning(7042) << "Invalid magic" << endl;
00112 delete[] ar_longnames;
00113 return false;
00114 }
00115
00116 name = ar_header.mid( 0, 16 );
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;
00124 if (name.mid(0, 1) == "/") {
00125 if (name.mid(1, 1) == "/") {
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) == " ") {
00133 kdDebug(7042) << "Skipped symbol entry" << endl;
00134 dev->at( dev->at() + size );
00135 skip_entry = true;
00136 } else {
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();
00149 name.replace( "/", "" );
00150 kdDebug(7042) << "Filename: " << name << " Size: " << size << endl;
00151
00152 KArchiveEntry* entry;
00153 entry = new KArchiveFile(this, name, mode, date, 0, 0, 0, dev->at(), size);
00154 rootDir()->addEntry(entry);
00155
00156 dev->at( dev->at() + size );
00157 }
00158 delete[] ar_longnames;
00159
00160 return true;
00161 }
00162
00163 bool KAr::closeArchive()
00164 {
00165
00166 return true;
00167 }
00168
00169 void KAr::virtual_hook( int id, void* data )
00170 { KArchive::virtual_hook( id, data ); }