00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <stdlib.h>
00022
#include <time.h>
00023
00024
00025
00026
#include <assert.h>
00027
00028
#include <qcstring.h>
00029
#include <qdir.h>
00030
#include <qfile.h>
00031
#include <kdebug.h>
00032
#include <kmimetype.h>
00033
00034
#include <kfilterdev.h>
00035
#include <kfilterbase.h>
00036
00037
#include "ktar.h"
00038
00042
00043
class KTar::KTarPrivate
00044 {
00045
public:
00046 KTarPrivate() : tarEnd( 0 ) {}
00047
QStringList dirList;
00048
int tarEnd;
00049 };
00050
00051 KTar::KTar(
const QString& filename,
const QString & _mimetype )
00052 :
KArchive( 0L )
00053 {
00054 m_filename = filename;
00055 d =
new KTarPrivate;
00056
QString mimetype( _mimetype );
00057
bool forced =
true;
00058
if ( mimetype.isEmpty() )
00059 {
00060
if (
QFile::exists( filename ) )
00061 mimetype = KMimeType::findByFileContent( filename )->name();
00062
else
00063 mimetype = KMimeType::findByPath( filename, 0,
true )->name();
00064
kdDebug(7041) <<
"KTar::KTar mimetype=" << mimetype <<
endl;
00065
00066
00067
if ( mimetype ==
"application/x-tgz" || mimetype ==
"application/x-targz" ||
00068 mimetype ==
"application/x-webarchive" )
00069
00070 mimetype =
"application/x-gzip";
00071
else if ( mimetype ==
"application/x-tbz" )
00072 mimetype =
"application/x-bzip2";
00073
else
00074 {
00075
00076
QFile file( filename );
00077
if ( file.
open( IO_ReadOnly ) )
00078 {
00079
unsigned char firstByte = file.
getch();
00080
unsigned char secondByte = file.
getch();
00081
unsigned char thirdByte = file.
getch();
00082
if ( firstByte == 0037 && secondByte == 0213 )
00083 mimetype =
"application/x-gzip";
00084
else if ( firstByte ==
'B' && secondByte ==
'Z' && thirdByte ==
'h' )
00085 mimetype =
"application/x-bzip2";
00086
else if ( firstByte ==
'P' && secondByte ==
'K' && thirdByte == 3 )
00087 {
00088
unsigned char fourthByte = file.
getch();
00089
if ( fourthByte == 4 )
00090 mimetype =
"application/x-zip";
00091 }
00092 }
00093 }
00094 forced =
false;
00095 }
00096
00097 prepareDevice( filename, mimetype, forced );
00098 }
00099
00100
void KTar::prepareDevice(
const QString & filename,
00101
const QString & mimetype,
bool forced )
00102 {
00103
if(
"application/x-tar" == mimetype )
00104 setDevice(
new QFile( filename ) );
00105
else
00106 {
00107
if(
"application/x-gzip" == mimetype
00108 ||
"application/x-bzip2" == mimetype)
00109 forced =
true;
00110
00111
QIODevice *dev = KFilterDev::deviceForFile( filename, mimetype, forced );
00112
if( dev )
00113 setDevice( dev );
00114 }
00115 }
00116
00117 KTar::KTar(
QIODevice * dev )
00118 :
KArchive( dev )
00119 {
00120 d =
new KTarPrivate;
00121 }
00122
00123 KTar::~KTar()
00124 {
00125
00126
if(
isOpened() )
00127
close();
00128
if ( !m_filename.
isEmpty() )
00129
delete device();
00130
delete d;
00131 }
00132
00133 void KTar::setOrigFileName(
const QCString & fileName )
00134 {
00135
if ( !
isOpened() || !(
mode() & IO_WriteOnly) )
00136 {
00137
kdWarning(7041) <<
"KTar::setOrigFileName: File must be opened for writing first.\n";
00138
return;
00139 }
00140 static_cast<KFilterDev *>(
device())->setOrigFileName( fileName );
00141 }
00142
00143 Q_LONG KTar::readRawHeader(
char *buffer) {
00144
00145 Q_LONG n =
device()->
readBlock( buffer, 0x200 );
00146
if ( n == 0x200 && buffer[0] != 0 ) {
00147
00148
if (strncmp(buffer + 257,
"ustar", 5)) {
00149
00150
QCString s;
00151
00152
int check = 0;
00153
for( uint j = 0; j < 0x200; ++j )
00154 check += buffer[j];
00155
00156
00157
for( uint j = 0; j < 8 ; j++ )
00158 check -= buffer[148 + j];
00159 check += 8 *
' ';
00160
00161 s.
sprintf(
"%o", check );
00162
00163
00164
00165
if( strncmp( buffer + 148 + 6 - s.
length(), s.data(), s.
length() ) ) {
00166
kdWarning(7041) <<
"KTar: invalid TAR file. Header is: " <<
QCString( buffer+257, 5 ) <<
endl;
00167
return -1;
00168 }
00169 }
00170 }
else {
00171
00172
if (n == 0x200) n = 0;
00173 }
00174
return n;
00175 }
00176
00177
bool KTar::readLonglink(
char *buffer,
QCString &longlink) {
00178 Q_LONG n = 0;
00179
QIODevice *dev =
device();
00180
00181
00182 buffer[ 0x88 ] = 0;
00183
char *dummy;
00184
const char* p = buffer + 0x7c;
00185
while( *p ==
' ' ) ++p;
00186
int size = (
int)strtol( p, &dummy, 8 );
00187
00188 longlink.
resize(size);
00189 size--;
00190 dummy = longlink.data();
00191
int offset = 0;
00192
while (size > 0) {
00193
int chunksize = QMIN(size, 0x200);
00194 n = dev->
readBlock( dummy + offset, chunksize );
00195
if (n == -1)
return false;
00196 size -= chunksize;
00197 offset += 0x200;
00198 }
00199
00200
int skip = 0x200 - (n % 0x200);
00201
if (skip < 0x200) {
00202
if (dev->
readBlock(buffer,skip) != skip)
return false;
00203 }
00204
return true;
00205 }
00206
00207 Q_LONG KTar::readHeader(
char *buffer,
QString &name,
QString &symlink) {
00208
name.
truncate(0);
00209
symlink.truncate(0);
00210
while (
true) {
00211 Q_LONG n = readRawHeader(buffer);
00212
if (n != 0x200)
return n;
00213
00214
00215
if (strcmp(buffer,
"././@LongLink") == 0) {
00216
char typeflag = buffer[0x9c];
00217
QCString longlink;
00218 readLonglink(buffer,longlink);
00219
switch (typeflag) {
00220
case 'L':
name =
QFile::decodeName(longlink);
break;
00221
case 'K':
symlink =
QFile::decodeName(longlink);
break;
00222 }
00223 }
else {
00224
break;
00225 }
00226 }
00227
00228
00229
if (
name.
isEmpty())
00230
name =
QFile::decodeName(buffer);
00231
if (
symlink.isEmpty())
00232
symlink =
QFile::decodeName(buffer + 0x9d);
00233
00234
return 0x200;
00235 }
00236
00237 bool KTar::openArchive(
int mode )
00238 {
00239
if ( !(mode & IO_ReadOnly) )
00240
return true;
00241
00242
00243
00244
00245
00246
00247 d->dirList.clear();
00248
QIODevice* dev =
device();
00249
00250
00251
char buffer[ 0x200 ];
00252
bool ende =
false;
00253
do
00254 {
00255
QString name;
00256
QString symlink;
00257
00258
00259 Q_LONG n = readHeader(buffer,name,symlink);
00260
if (n < 0)
return false;
00261
if (n == 0x200)
00262 {
00263
bool isdir =
false;
00264
QString nm;
00265
00266
if ( name.
right(1) ==
"/" )
00267 {
00268 isdir =
true;
00269 name = name.
left( name.
length() - 1 );
00270 }
00271
00272
int pos = name.
findRev(
'/' );
00273
if ( pos == -1 )
00274 nm = name;
00275
else
00276 nm = name.
mid( pos + 1 );
00277
00278
00279 buffer[ 0x6b ] = 0;
00280
char *dummy;
00281
const char* p = buffer + 0x64;
00282
while( *p ==
' ' ) ++p;
00283
int access = (
int)strtol( p, &dummy, 8 );
00284
00285
00286
QString user( buffer + 0x109 );
00287
QString group( buffer + 0x129 );
00288
00289
00290 buffer[ 0x93 ] = 0;
00291 p = buffer + 0x88;
00292
while( *p ==
' ' ) ++p;
00293
int time = (
int)strtol( p, &dummy, 8 );
00294
00295
00296
char typeflag = buffer[ 0x9c ];
00297
00298
00299
00300
if ( typeflag ==
'1' )
00301 isdir =
true;
00302
00303
bool isDumpDir =
false;
00304
if ( typeflag ==
'D' )
00305 {
00306 isdir =
false;
00307 isDumpDir =
true;
00308 }
00309
00310
00311
00312
if (isdir)
00313 access |= S_IFDIR;
00314
00315
KArchiveEntry* e;
00316
if ( isdir )
00317 {
00318
00319 e =
new KArchiveDirectory(
this, nm, access, time, user, group, symlink );
00320 }
00321
else
00322 {
00323
00324 buffer[ 0x88 ] = 0;
00325
char *dummy;
00326
const char* p = buffer + 0x7c;
00327
while( *p ==
' ' ) ++p;
00328
int size = (
int)strtol( p, &dummy, 8 );
00329
00330
00331
if ( isDumpDir )
00332 {
00333 e =
new KArchiveDirectory(
this, nm, access, time, user, group, symlink );
00334 }
00335
else
00336 {
00337
00338
00339
if ( typeflag ==
'1' )
00340 {
00341 size = nm.
length();
00342
kdDebug(7041) <<
"HARD LINK, setting size to " << size <<
endl;
00343 }
00344
00345
00346
00347 e =
new KArchiveFile(
this, nm, access, time, user, group, symlink,
00348 dev->
at(), size );
00349 }
00350
00351
00352
int rest = size % 0x200;
00353
int skip = size + (rest ? 0x200 - rest : 0);
00354
00355
if (! dev->
at( dev->
at() + skip ) )
00356
kdWarning(7041) <<
"KArchive::open skipping " << skip <<
" failed" <<
endl;
00357 }
00358
00359
if ( pos == -1 )
00360 {
00361
if ( nm ==
"." )
00362 {
00363 Q_ASSERT( isdir );
00364
if ( isdir )
00365 setRootDir( static_cast<KArchiveDirectory *>( e ) );
00366 }
00367
else
00368
rootDir()->
addEntry( e );
00369 }
00370
else
00371 {
00372
00373
QString path = QDir::cleanDirPath( name.
left( pos ) );
00374
00375
KArchiveDirectory * d = findOrCreate( path );
00376 d->
addEntry( e );
00377 }
00378 }
00379
else
00380 {
00381
00382 d->tarEnd = dev->
at() - n;
00383 ende =
true;
00384 }
00385 }
while( !ende );
00386
return true;
00387 }
00388
00389 bool KTar::closeArchive()
00390 {
00391 d->dirList.clear();
00392
return true;
00393 }
00394
00395 bool KTar::writeDir(
const QString& name,
const QString& user,
const QString& group )
00396 {
00397 mode_t perm = 040755;
00398 time_t the_time = time(0);
00399
return writeDir(name,user,group,perm,the_time,the_time,the_time);
00400
#if 0
00401
if ( !
isOpened() )
00402 {
00403
kdWarning(7041) <<
"KTar::writeDir: You must open the tar file before writing to it\n";
00404
return false;
00405 }
00406
00407
if ( !(
mode() & IO_WriteOnly) )
00408 {
00409
kdWarning(7041) <<
"KTar::writeDir: You must open the tar file for writing\n";
00410
return false;
00411 }
00412
00413
00414
QString dirName ( QDir::cleanDirPath( name ) );
00415
00416
00417
if ( dirName.
right(1) !=
"/" )
00418 dirName +=
"/";
00419
00420
if ( d->dirList.contains( dirName ) )
00421
return true;
00422
00423
char buffer[ 0x201 ];
00424 memset( buffer, 0, 0x200 );
00425
if (
mode() & IO_ReadWrite )
device()->
at(d->tarEnd);
00426
00427
00428
if ( dirName.
length() > 99 )
00429 {
00430 strcpy( buffer,
"././@LongLink" );
00431 fillBuffer( buffer,
" 0", dirName.
length()+1,
'L', user.
local8Bit(), group.
local8Bit() );
00432
device()->
writeBlock( buffer, 0x200 );
00433 strncpy( buffer, QFile::encodeName(dirName), 0x200 );
00434 buffer[0x200] = 0;
00435
00436
device()->
writeBlock( buffer, 0x200 );
00437
00438 }
00439
else
00440 {
00441
00442 strncpy( buffer, QFile::encodeName(dirName), 0x200 );
00443 buffer[0x200] = 0;
00444 }
00445
00446 fillBuffer( buffer,
" 40755", 0, 0x35, user.
local8Bit(), group.
local8Bit());
00447
00448
00449
device()->
writeBlock( buffer, 0x200 );
00450
if (
mode() & IO_ReadWrite ) d->tarEnd =
device()->
at();
00451
00452 d->dirList.append( dirName );
00453
return true;
00454
#endif
00455
}
00456
00457 bool KTar::prepareWriting(
const QString& name,
const QString& user,
const QString& group, uint size )
00458 {
00459 mode_t dflt_perm = 0100644;
00460 time_t the_time = time(0);
00461
return prepareWriting(name,user,group,size,dflt_perm,
00462 the_time,the_time,the_time);
00463 }
00464
00465 bool KTar::doneWriting( uint size )
00466 {
00467
00468
int rest = size % 0x200;
00469
if (
mode() & IO_ReadWrite )
00470 d->tarEnd =
device()->
at() + (rest ? 0x200 - rest : 0);
00471
if ( rest )
00472 {
00473
char buffer[ 0x201 ];
00474
for( uint i = 0; i < 0x200; ++i )
00475 buffer[i] = 0;
00476 Q_LONG nwritten =
device()->
writeBlock( buffer, 0x200 - rest );
00477
return nwritten == 0x200 - rest;
00478 }
00479
return true;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
void KTar::fillBuffer(
char * buffer,
00506
const char * mode,
int size, time_t mtime,
char typeflag,
00507
const char * uname,
const char * gname )
00508 {
00509
00510 assert( strlen(mode) == 6 );
00511 strcpy( buffer+0x64, mode );
00512 buffer[ 0x6a ] =
' ';
00513 buffer[ 0x6b ] =
'\0';
00514
00515
00516 strcpy( buffer + 0x6c,
" 765 ");
00517
00518 strcpy( buffer + 0x74,
" 144 ");
00519
00520
00521
QCString s;
00522 s.
sprintf(
"%o", size);
00523 s = s.
rightJustify( 11,
' ' );
00524 strcpy( buffer + 0x7c, s.data() );
00525 buffer[ 0x87 ] =
' ';
00526
00527
00528 s.
sprintf(
"%lo", static_cast<unsigned long>(mtime) );
00529 s = s.
rightJustify( 11,
' ' );
00530 strcpy( buffer + 0x88, s.data() );
00531 buffer[ 0x93 ] =
' ';
00532
00533
00534 buffer[ 0x94 ] = 0x20;
00535 buffer[ 0x95 ] = 0x20;
00536 buffer[ 0x96 ] = 0x20;
00537 buffer[ 0x97 ] = 0x20;
00538 buffer[ 0x98 ] = 0x20;
00539 buffer[ 0x99 ] = 0x20;
00540
00541
00542
00543
00544
00545
00546 buffer[ 0x9a ] =
'\0';
00547 buffer[ 0x9b ] =
' ';
00548
00549
00550 buffer[ 0x9c ] = typeflag;
00551
00552
00553 strcpy( buffer + 0x101,
"ustar");
00554 strcpy( buffer + 0x107,
"00" );
00555
00556
00557 strcpy( buffer + 0x109, uname );
00558
00559 strcpy( buffer + 0x129, gname );
00560
00561
00562
int check = 32;
00563
for( uint j = 0; j < 0x200; ++j )
00564 check += buffer[j];
00565 s.
sprintf(
"%o", check );
00566 s = s.
rightJustify( 7,
' ' );
00567 strcpy( buffer + 0x94, s.data() );
00568 }
00569
00570
void KTar::writeLonglink(
char *buffer,
const QCString &name,
char typeflag,
00571
const char *uname,
const char *gname) {
00572 strcpy( buffer,
"././@LongLink" );
00573
int namelen =
name.
length() + 1;
00574 fillBuffer( buffer,
" 0", namelen, 0, typeflag, uname, gname );
00575
device()->
writeBlock( buffer, 0x200 );
00576
int offset = 0;
00577
while (namelen > 0) {
00578
int chunksize = QMIN(namelen, 0x200);
00579 memcpy(buffer,
name.data()+offset, chunksize);
00580
00581
device()->
writeBlock( buffer, 0x200 );
00582
00583 namelen -= chunksize;
00584 offset += 0x200;
00585 }
00586 }
00587
00588 bool KTar::prepareWriting(
const QString& name,
const QString& user,
00589
const QString& group, uint size, mode_t perm,
00590 time_t atime, time_t mtime, time_t ctime) {
00591
return KArchive::prepareWriting(name,user,group,size,perm,atime,mtime,ctime);
00592 }
00593
00594
bool KTar::prepareWriting_impl(
const QString &name,
const QString &user,
00595
const QString &group, uint size, mode_t perm,
00596 time_t , time_t mtime, time_t ) {
00597
if ( !
isOpened() )
00598 {
00599
kdWarning(7041) <<
"KTar::prepareWriting: You must open the tar file before writing to it\n";
00600
return false;
00601 }
00602
00603
if ( !(
mode() & IO_WriteOnly) )
00604 {
00605
kdWarning(7041) <<
"KTar::prepareWriting: You must open the tar file for writing\n";
00606
return false;
00607 }
00608
00609
00610
QString fileName ( QDir::cleanDirPath( name ) );
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
char buffer[ 0x201 ];
00632 memset( buffer, 0, 0x200 );
00633
if (
mode() & IO_ReadWrite )
device()->
at(d->tarEnd);
00634
00635
00636
QCString encodedFilename =
QFile::encodeName(fileName);
00637
QCString uname = user.
local8Bit();
00638
QCString gname = group.
local8Bit();
00639
00640
00641
if ( fileName.
length() > 99 )
00642 writeLonglink(buffer,encodedFilename,
'L',uname,gname);
00643
00644
00645 strncpy( buffer, encodedFilename, 99 );
00646 buffer[99] = 0;
00647
00648 memset(buffer+0x9d, 0, 0x200 - 0x9d);
00649
00650
QCString permstr;
00651 permstr.
sprintf(
"%o",perm);
00652 permstr.
rightJustify(6,
' ');
00653 fillBuffer(buffer, permstr, size, mtime, 0x30, uname, gname);
00654
00655
00656
return device()->
writeBlock( buffer, 0x200 ) == 0x200;
00657 }
00658
00659 bool KTar::writeDir(
const QString& name,
const QString& user,
00660
const QString& group, mode_t perm,
00661 time_t atime, time_t mtime, time_t ctime) {
00662
return KArchive::writeDir(name,user,group,perm,atime,mtime,ctime);
00663 }
00664
00665
bool KTar::writeDir_impl(
const QString &name,
const QString &user,
00666
const QString &group, mode_t perm,
00667 time_t , time_t mtime, time_t ) {
00668
if ( !
isOpened() )
00669 {
00670
kdWarning(7041) <<
"KTar::writeDir: You must open the tar file before writing to it\n";
00671
return false;
00672 }
00673
00674
if ( !(
mode() & IO_WriteOnly) )
00675 {
00676
kdWarning(7041) <<
"KTar::writeDir: You must open the tar file for writing\n";
00677
return false;
00678 }
00679
00680
00681
QString dirName ( QDir::cleanDirPath( name ) );
00682
00683
00684
if ( dirName.
right(1) !=
"/" )
00685 dirName +=
"/";
00686
00687
if ( d->dirList.contains( dirName ) )
00688
return true;
00689
00690
char buffer[ 0x201 ];
00691 memset( buffer, 0, 0x200 );
00692
if (
mode() & IO_ReadWrite )
device()->
at(d->tarEnd);
00693
00694
00695
QCString encodedDirname =
QFile::encodeName(dirName);
00696
QCString uname = user.
local8Bit();
00697
QCString gname = group.
local8Bit();
00698
00699
00700
if ( dirName.
length() > 99 )
00701 writeLonglink(buffer,encodedDirname,
'L',uname,gname);
00702
00703
00704 strncpy( buffer, encodedDirname, 99 );
00705 buffer[99] = 0;
00706
00707 memset(buffer+0x9d, 0, 0x200 - 0x9d);
00708
00709
QCString permstr;
00710 permstr.
sprintf(
"%o",perm);
00711 permstr.
rightJustify(6,
' ');
00712 fillBuffer( buffer, permstr, 0, mtime, 0x35, uname, gname);
00713
00714
00715
device()->
writeBlock( buffer, 0x200 );
00716
if (
mode() & IO_ReadWrite ) d->tarEnd =
device()->
at();
00717
00718 d->dirList.append( dirName );
00719
return true;
00720 }
00721
00722 bool KTar::writeSymLink(
const QString &name,
const QString &target,
00723
const QString &user,
const QString &group,
00724 mode_t perm, time_t atime, time_t mtime, time_t ctime) {
00725
return KArchive::writeSymLink(name,target,user,group,perm,atime,mtime,ctime);
00726 }
00727
00728
bool KTar::writeSymLink_impl(
const QString &name,
const QString &target,
00729
const QString &user,
const QString &group,
00730 mode_t perm, time_t , time_t mtime, time_t ) {
00731
if ( !
isOpened() )
00732 {
00733
kdWarning(7041) <<
"KTar::writeSymLink: You must open the tar file before writing to it\n";
00734
return false;
00735 }
00736
00737
if ( !(
mode() & IO_WriteOnly) )
00738 {
00739
kdWarning(7041) <<
"KTar::writeSymLink: You must open the tar file for writing\n";
00740
return false;
00741 }
00742
00743
device()->
flush();
00744
00745
00746
QString fileName ( QDir::cleanDirPath( name ) );
00747
00748
char buffer[ 0x201 ];
00749 memset( buffer, 0, 0x200 );
00750
if (
mode() & IO_ReadWrite )
device()->
at(d->tarEnd);
00751
00752
00753
QCString encodedFilename =
QFile::encodeName(fileName);
00754
QCString encodedTarget =
QFile::encodeName(target);
00755
QCString uname = user.
local8Bit();
00756
QCString gname = group.
local8Bit();
00757
00758
00759
if (target.
length() > 99)
00760 writeLonglink(buffer,encodedTarget,
'K',uname,gname);
00761
if ( fileName.
length() > 99 )
00762 writeLonglink(buffer,encodedFilename,
'L',uname,gname);
00763
00764
00765 strncpy( buffer, encodedFilename, 99 );
00766 buffer[99] = 0;
00767
00768 strncpy(buffer+0x9d, encodedTarget, 99);
00769 buffer[0x9d+99] = 0;
00770
00771 memset(buffer+0x9d+100, 0, 0x200 - 100 - 0x9d);
00772
00773
QCString permstr;
00774 permstr.
sprintf(
"%o",perm);
00775 permstr.
rightJustify(6,
' ');
00776 fillBuffer(buffer, permstr, 0, mtime, 0x32, uname, gname);
00777
00778
00779
bool retval =
device()->
writeBlock( buffer, 0x200 ) == 0x200;
00780
if (
mode() & IO_ReadWrite ) d->tarEnd =
device()->
at();
00781
return retval;
00782 }
00783
00784
void KTar::virtual_hook(
int id,
void* data ) {
00785
switch (
id) {
00786
case VIRTUAL_WRITE_SYMLINK: {
00787 WriteSymlinkParams *params = reinterpret_cast<WriteSymlinkParams *>(data);
00788 params->retval = writeSymLink_impl(*params->name,*params->target,
00789 *params->user,*params->group,params->perm,
00790 params->atime,params->mtime,params->ctime);
00791
break;
00792 }
00793
case VIRTUAL_WRITE_DIR: {
00794 WriteDirParams *params = reinterpret_cast<WriteDirParams *>(data);
00795 params->retval = writeDir_impl(*params->name,*params->user,
00796 *params->group,params->perm,
00797 params->atime,params->mtime,params->ctime);
00798
break;
00799 }
00800
case VIRTUAL_PREPARE_WRITING: {
00801 PrepareWritingParams *params = reinterpret_cast<PrepareWritingParams *>(data);
00802 params->retval = prepareWriting_impl(*params->name,*params->user,
00803 *params->group,params->size,params->perm,
00804 params->atime,params->mtime,params->ctime);
00805
break;
00806 }
00807
default:
00808 KArchive::virtual_hook(
id, data );
00809 }
00810 }
00811