kar.cpp
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 
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 ); 
00100 
00101         if ( dev->readBlock (ar_header.data(), 60) != 60 ) { 
00102             kdWarning(7042) << "Couldn't read header" << endl;
00103             delete[] ar_longnames;
00104             
00105             return true; 
00106         }
00107 
00108         if (ar_header.right(2) != "`\n") { 
00109             kdWarning(7042) << "Invalid magic" << endl;
00110             delete[] ar_longnames;
00111             return false;
00112         }
00113 
00114         name = ar_header.mid( 0, 16 ); 
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; 
00122         if (name.mid(0, 1) == "/") {
00123             if (name.mid(1, 1) == "/") { 
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) == " ") { 
00131                 kdDebug(7042) << "Skipped symbol entry" << endl;
00132                 dev->at( dev->at() + size );
00133                 skip_entry = true;
00134             } else { 
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(); 
00147         name.replace( "/", "" );
00148         kdDebug(7042) << "Filename: " << name << " Size: " << size << endl;
00149 
00150         KArchiveEntry* entry;
00151         entry = new KArchiveFile(this, name, mode, date,  0,  0, 0, dev->at(), size);
00152         rootDir()->addEntry(entry); 
00153 
00154         dev->at( dev->at() + size ); 
00155     }
00156     delete[] ar_longnames;
00157 
00158     return true;
00159 }
00160 
00161 bool KAr::closeArchive()
00162 {
00163     
00164     return true;
00165 }
00166 
00167 void KAr::virtual_hook( int id, void* data )
00168 { KArchive::virtual_hook( id, data ); }
 
This file is part of the documentation for kio Library Version 3.2.0.