41 #include "kfilterdev.h"
42 #include "klimitediodevice.h"
43 #include <kmimetype.h>
44 #include <ksavefile.h>
47 #include <tqasciidict.h>
50 #include <tqdatetime.h>
51 #include <tqptrlist.h>
57 const int max_path_len = 4095;
59 static void transformToMsDos(
const TQDateTime& dt,
char* buffer)
63 const TQ_UINT16 time =
64 ( dt.time().hour() << 11 )
65 | ( dt.time().minute() << 5 )
66 | ( dt.time().second() >> 1 );
68 buffer[0] = char(time);
69 buffer[1] = char(time >> 8);
71 const TQ_UINT16 date =
72 ( ( dt.date().year() - 1980 ) << 9 )
73 | ( dt.date().month() << 5 )
74 | ( dt.date().day() );
76 buffer[2] = char(date);
77 buffer[3] = char(date >> 8);
88 static time_t transformFromMsDos(
const char* buffer)
90 TQ_UINT16 time = (uchar)buffer[0] | ( (uchar)buffer[1] << 8 );
92 int m = ( time & 0x7ff ) >> 5;
93 int s = ( time & 0x1f ) * 2 ;
96 TQ_UINT16 date = (uchar)buffer[2] | ( (uchar)buffer[3] << 8 );
97 int y = ( date >> 9 ) + 1980;
98 int o = ( date & 0x1ff ) >> 5;
99 int d = ( date & 0x1f );
102 TQDateTime dt( qd, qt );
103 return dt.toTime_t();
109 struct ParseFileInfo {
118 TQCString guessed_symlink;
122 bool exttimestamp_seen;
124 bool newinfounix_seen;
127 ParseFileInfo() : perm(0100644), uid(-1), gid(-1), extralen(0),
128 exttimestamp_seen(false), newinfounix_seen(false) {
129 ctime = mtime = atime = time(0);
141 static bool parseExtTimestamp(
const char *buffer,
int size,
bool islocal,
142 ParseFileInfo &pfi) {
144 kdDebug(7040) <<
"premature end of extended timestamp (#1)" << endl;
153 kdDebug(7040) <<
"premature end of extended timestamp (#2)" << endl;
156 pfi.mtime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8
157 | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24);
164 pfi.exttimestamp_seen =
true;
170 kdDebug(7040) <<
"premature end of extended timestamp (#3)" << endl;
173 pfi.atime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8
174 | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24);
181 kdDebug(7040) <<
"premature end of extended timestamp (#4)" << endl;
184 pfi.ctime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8
185 | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24);
189 pfi.exttimestamp_seen =
true;
201 static bool parseInfoZipUnixOld(
const char *buffer,
int size,
bool islocal,
202 ParseFileInfo &pfi) {
204 if (pfi.exttimestamp_seen || pfi.newinfounix_seen)
return true;
207 kdDebug(7040) <<
"premature end of Info-ZIP unix extra field old" << endl;
211 pfi.atime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8
212 | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24);
214 pfi.mtime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8
215 | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24);
217 if (islocal && size >= 12) {
218 pfi.uid = (uchar)buffer[0] | (uchar)buffer[1] << 8;
220 pfi.gid = (uchar)buffer[0] | (uchar)buffer[1] << 8;
226 #if 0 // not needed yet
235 static bool parseInfoZipUnixNew(
const char *buffer,
int size,
bool islocal,
236 ParseFileInfo &pfi) {
238 pfi.newinfounix =
true;
243 kdDebug(7040) <<
"premature end of Info-ZIP unix extra field new" << endl;
247 pfi.uid = (uchar)buffer[0] | (uchar)buffer[1] << 8;
249 pfi.gid = (uchar)buffer[0] | (uchar)buffer[1] << 8;
252 pfi.newinfounix =
true;
265 static bool parseExtraField(
const char *buffer,
int size,
bool islocal,
266 ParseFileInfo &pfi) {
269 if (!islocal)
return true;
272 int magic = (uchar)buffer[0] | (uchar)buffer[1] << 8;
274 int fieldsize = (uchar)buffer[0] | (uchar)buffer[1] << 8;
278 if (fieldsize > size) {
280 kdDebug(7040) <<
"premature end of extra fields reached" << endl;
286 if (!parseExtTimestamp(buffer, fieldsize, islocal, pfi))
return false;
289 if (!parseInfoZipUnixOld(buffer, fieldsize, islocal, pfi))
return false;
291 #if 0 // not needed yet
293 if (!parseInfoZipUnixNew(buffer, fieldsize, islocal, pfi))
return false;
310 class KZip::KZipPrivate
323 KZipFileEntry* m_currentFile;
324 TQIODevice* m_currentDev;
325 TQPtrList<KZipFileEntry> m_fileList;
328 unsigned int m_offset;
332 KSaveFile* m_saveFile;
339 Q_ASSERT( !filename.isEmpty() );
340 m_filename = filename;
360 if ( !m_filename.isEmpty() ) {
362 delete d->m_saveFile;
372 d->m_fileList.clear();
378 if ( !m_filename.isEmpty() ) {
379 kdDebug(7040) <<
"Writing to a file using KSaveFile" << endl;
380 d->m_saveFile =
new KSaveFile( m_filename );
381 if ( d->m_saveFile->status() != 0 ) {
382 kdWarning(7040) <<
"KSaveFile creation for " << m_filename <<
" failed, " << strerror( d->m_saveFile->status() ) << endl;
383 delete d->m_saveFile;
387 Q_ASSERT( d->m_saveFile->file() );
388 setDevice( d->m_saveFile->file() );
395 if ( !m_filename.isEmpty() ) {
396 setDevice(
new TQFile( m_filename ) );
403 kdWarning(7040) <<
"Unsupported mode " <<
mode << endl;
411 TQIODevice* dev =
device();
421 TQAsciiDict<ParseFileInfo> pfi_map(1009,
true ,
true );
422 pfi_map.setAutoDelete(
true);
425 bool startOfFile =
true;
429 kdDebug(7040) <<
"loop starts" << endl;
430 kdDebug(7040) <<
"dev->at() now : " << dev->at() << endl;
431 n = dev->readBlock( buffer, 4 );
435 kdWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#1)" << endl;
440 if ( !memcmp( buffer,
"PK\5\6", 4 ) )
442 kdDebug(7040) <<
"PK56 found end of archive" << endl;
447 if ( !memcmp( buffer,
"PK\3\4", 4 ) )
449 kdDebug(7040) <<
"PK34 found local file header" << endl;
452 dev->at( dev->at() + 2 );
455 n = dev->readBlock( buffer, 24 );
457 kdWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#4)" << endl;
461 int gpf = (uchar)buffer[0];
462 int compression_mode = (uchar)buffer[2] | (uchar)buffer[3] << 8;
463 time_t mtime = transformFromMsDos( buffer+4 );
465 TQ_LONG compr_size = (uchar)buffer[12] | (uchar)buffer[13] << 8
466 | (uchar)buffer[14] << 16 | (uchar)buffer[15] << 24;
467 TQ_LONG uncomp_size = (uchar)buffer[16] | (uchar)buffer[17] << 8
468 | (uchar)buffer[18] << 16 | (uchar)buffer[19] << 24;
469 int namelen = (uchar)buffer[20] | (uchar)buffer[21] << 8;
470 int extralen = (uchar)buffer[22] | (uchar)buffer[23] << 8;
472 kdDebug(7040) <<
"general purpose bit flag: " << gpf << endl;
473 kdDebug(7040) <<
"compressed size: " << compr_size << endl;
474 kdDebug(7040) <<
"uncompressed size: " << uncomp_size << endl;
475 kdDebug(7040) <<
"namelen: " << namelen << endl;
476 kdDebug(7040) <<
"extralen: " << extralen << endl;
477 kdDebug(7040) <<
"archive size: " << dev->size() << endl;
480 TQCString filename(namelen + 1);
481 n = dev->readBlock(filename.data(), namelen);
483 kdWarning(7040) <<
"Invalid ZIP file. Name not completely read (#2)" << endl;
487 ParseFileInfo *pfi =
new ParseFileInfo();
489 pfi_map.insert(filename.data(), pfi);
493 unsigned int extraFieldEnd = dev->at() + extralen;
494 pfi->extralen = extralen;
495 int handledextralen = TQMIN(extralen, (
int)
sizeof buffer);
497 kdDebug(7040) <<
"handledextralen: " << handledextralen << endl;
499 n = dev->readBlock(buffer, handledextralen);
501 if (!parseExtraField(buffer, handledextralen,
true, *pfi))
503 kdWarning(7040) <<
"Invalid ZIP File. Broken ExtraField." << endl;
508 dev->at( extraFieldEnd );
517 kdDebug(7040) <<
"trying to seek for next PK78" << endl;
518 bool foundSignature =
false;
520 while (!foundSignature)
522 n = dev->readBlock( buffer, 1 );
525 kdWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#2)" << endl;
529 if ( buffer[0] !=
'P' )
532 n = dev->readBlock( buffer, 3 );
535 kdWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#3)" << endl;
544 if ( buffer[0] ==
'K' && buffer[1] == 7 && buffer[2] == 8 )
546 foundSignature =
true;
547 dev->at( dev->at() + 12 );
549 else if ( ( buffer[0] ==
'K' && buffer[1] == 1 && buffer[2] == 2 )
550 || ( buffer[0] ==
'K' && buffer[1] == 3 && buffer[2] == 4 ) )
552 foundSignature =
true;
553 dev->at( dev->at() - 4 );
555 else if ( buffer[0] ==
'P' || buffer[1] ==
'P' || buffer[2] ==
'P' )
558 dev->at( dev->at() - 3 );
566 kdDebug(7040) <<
"general purpose bit flag indicates, that local file header contains valid size" << endl;
569 && uncomp_size <= max_path_len
570 && uncomp_size > 0) {
572 pfi->guessed_symlink.resize(uncomp_size + 1);
573 kdDebug(7040) <<
"guessed symlink size: " << uncomp_size << endl;
574 n = dev->readBlock(pfi->guessed_symlink.data(), uncomp_size);
575 if (n < uncomp_size) {
576 kdWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#5)" << endl;
581 if ( compr_size > (TQ_LONG)dev->size() )
585 bool foundSignature =
false;
587 while (!foundSignature)
589 n = dev->readBlock( buffer, 1 );
592 kdWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#2)" << endl;
596 if ( buffer[0] !=
'P' )
599 n = dev->readBlock( buffer, 3 );
602 kdWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. (#3)" << endl;
611 if ( buffer[0] ==
'K' && buffer[1] == 7 && buffer[2] == 8 )
613 foundSignature =
true;
614 dev->at( dev->at() + 12 );
617 if ( ( buffer[0] ==
'K' && buffer[1] == 1 && buffer[2] == 2 )
618 || ( buffer[0] ==
'K' && buffer[1] == 3 && buffer[2] == 4 ) )
620 foundSignature =
true;
621 dev->at( dev->at() - 4 );
631 success = dev->at( dev->at() + compr_size );
648 else if ( !memcmp( buffer,
"PK\1\2", 4 ) )
650 kdDebug(7040) <<
"PK12 found central block" << endl;
656 offset = dev->at() - 4;
659 if ( d->m_offset == 0L ) d->m_offset = offset;
661 n = dev->readBlock( buffer + 4, 42 );
663 kdWarning(7040) <<
"Invalid ZIP file, central entry too short" << endl;
670 int namelen = (uchar)buffer[29] << 8 | (uchar)buffer[28];
671 TQCString bufferName( namelen + 1 );
672 n = dev->readBlock( bufferName.data(), namelen );
674 kdWarning(7040) <<
"Invalid ZIP file. Name not completely read" << endl;
676 ParseFileInfo *pfi = pfi_map[bufferName];
678 pfi_map.insert(bufferName.data(), pfi =
new ParseFileInfo());
680 TQString name( TQFile::decodeName(bufferName) );
685 int extralen = (uchar)buffer[31] << 8 | (uchar)buffer[30];
687 int commlen = (uchar)buffer[33] << 8 | (uchar)buffer[32];
689 int cmethod = (uchar)buffer[11] << 8 | (uchar)buffer[10];
695 uint ucsize = (uchar)buffer[27] << 24 | (uchar)buffer[26] << 16 |
696 (uchar)buffer[25] << 8 | (uchar)buffer[24];
698 uint csize = (uchar)buffer[23] << 24 | (uchar)buffer[22] << 16 |
699 (uchar)buffer[21] << 8 | (uchar)buffer[20];
702 uint localheaderoffset = (uchar)buffer[45] << 24 | (uchar)buffer[44] << 16 |
703 (uchar)buffer[43] << 8 | (uchar)buffer[42];
709 int localextralen = pfi->extralen;
715 uint dataoffset = localheaderoffset + 30 + localextralen + namelen;
721 int os_madeby = (uchar)buffer[5];
723 int access = 0100644;
725 if (os_madeby == 3) {
726 access = (uchar)buffer[40] | (uchar)buffer[41] << 8;
731 if ( name.endsWith(
"/" ) )
734 name = name.left( name.length() - 1 );
735 if (os_madeby != 3) access = S_IFDIR | 0755;
736 else Q_ASSERT(access & S_IFDIR);
739 int pos = name.findRev(
'/' );
743 entryName = name.mid( pos + 1 );
744 Q_ASSERT( !entryName.isEmpty() );
749 TQString path = TQDir::cleanDirPath( name );
765 if (S_ISLNK(access)) {
766 symlink = TQFile::decodeName(pfi->guessed_symlink);
768 entry =
new KZipFileEntry(
this, entryName, access, pfi->mtime,
770 symlink, name, dataoffset,
771 ucsize, cmethod, csize );
772 static_cast<KZipFileEntry *
>(entry)->setHeaderStart( localheaderoffset );
774 d->m_fileList.append(
static_cast<KZipFileEntry *
>( entry ) );
786 TQString path = TQDir::cleanDirPath( name.left( pos ) );
789 tdir->addEntry(entry);
794 offset += 46 + commlen + extralen + namelen;
795 bool b = dev->at(offset);
800 else if ( startOfFile )
804 kdDebug(7040) <<
"Try to skip start of file" << endl;
806 bool foundSignature =
false;
808 while (!foundSignature)
810 n = dev->readBlock( buffer, 1 );
813 kdWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. " << k_funcinfo << endl;
817 if ( buffer[0] !=
'P' )
820 n = dev->readBlock( buffer, 3 );
823 kdWarning(7040) <<
"Invalid ZIP file. Unexpected end of file. " << k_funcinfo << endl;
832 if ( buffer[0] ==
'K' && buffer[1] == 3 && buffer[2] == 4 )
834 foundSignature =
true;
835 dev->at( dev->at() - 4 );
837 else if ( buffer[0] ==
'P' || buffer[1] ==
'P' || buffer[2] ==
'P' )
840 dev->at( dev->at() - 3 );
846 kdWarning(7040) <<
"Invalid ZIP file. Unrecognized header at offset " << offset << endl;
857 if ( ! (
mode() & IO_WriteOnly ) )
863 kdDebug() << k_funcinfo <<
"device=" <<
device() << endl;
872 uLong crc = crc32(0L, Z_NULL, 0);
874 TQ_LONG centraldiroffset =
device()->at();
876 TQ_LONG atbackup = centraldiroffset;
877 TQPtrListIterator<KZipFileEntry> it( d->m_fileList );
879 for ( ; it.current() ; ++it )
881 if ( !
device()->at( it.current()->headerStart() + 14 ) )
887 uLong mycrc = it.current()->crc32();
888 buffer[0] = char(mycrc);
889 buffer[1] = char(mycrc >> 8);
890 buffer[2] = char(mycrc >> 16);
891 buffer[3] = char(mycrc >> 24);
893 int mysize1 = it.current()->compressedSize();
894 buffer[4] = char(mysize1);
895 buffer[5] = char(mysize1 >> 8);
896 buffer[6] = char(mysize1 >> 16);
897 buffer[7] = char(mysize1 >> 24);
899 int myusize = it.current()->size();
900 buffer[8] = char(myusize);
901 buffer[9] = char(myusize >> 8);
902 buffer[10] = char(myusize >> 16);
903 buffer[11] = char(myusize >> 24);
905 if (
device()->writeBlock( buffer, 12 ) != 12 )
910 for ( it.toFirst(); it.current() ; ++it )
915 TQCString path = TQFile::encodeName(it.current()->path());
917 const int extra_field_len = 9;
918 int bufferSize = extra_field_len + path.length() + 46;
919 char* buffer =
new char[ bufferSize ];
921 memset(buffer, 0, 46);
932 tqmemmove(buffer, head,
sizeof(head));
934 buffer[ 10 ] = char(it.current()->encoding());
935 buffer[ 11 ] = char(it.current()->encoding() >> 8);
937 transformToMsDos( it.current()->datetime(), &buffer[ 12 ] );
939 uLong mycrc = it.current()->crc32();
940 buffer[ 16 ] = char(mycrc);
941 buffer[ 17 ] = char(mycrc >> 8);
942 buffer[ 18 ] = char(mycrc >> 16);
943 buffer[ 19 ] = char(mycrc >> 24);
945 int mysize1 = it.current()->compressedSize();
946 buffer[ 20 ] = char(mysize1);
947 buffer[ 21 ] = char(mysize1 >> 8);
948 buffer[ 22 ] = char(mysize1 >> 16);
949 buffer[ 23 ] = char(mysize1 >> 24);
951 int mysize = it.current()->size();
952 buffer[ 24 ] = char(mysize);
953 buffer[ 25 ] = char(mysize >> 8);
954 buffer[ 26 ] = char(mysize >> 16);
955 buffer[ 27 ] = char(mysize >> 24);
957 buffer[ 28 ] = char(it.current()->path().length());
958 buffer[ 29 ] = char(it.current()->path().length() >> 8);
960 buffer[ 30 ] = char(extra_field_len);
961 buffer[ 31 ] = char(extra_field_len >> 8);
963 buffer[ 40 ] = char(it.current()->permissions());
964 buffer[ 41 ] = char(it.current()->permissions() >> 8);
966 int myhst = it.current()->headerStart();
967 buffer[ 42 ] = char(myhst);
968 buffer[ 43 ] = char(myhst >> 8);
969 buffer[ 44 ] = char(myhst >> 16);
970 buffer[ 45 ] = char(myhst >> 24);
973 strncpy( buffer + 46, path, path.length() );
977 char *extfield = buffer + 46 + path.length();
982 extfield[4] = 1 | 2 | 4;
985 unsigned long time = (
unsigned long)it.current()->date();
986 extfield[5] = char(time);
987 extfield[6] = char(time >> 8);
988 extfield[7] = char(time >> 16);
989 extfield[8] = char(time >> 24);
991 crc = crc32(crc, (Bytef *)buffer, bufferSize );
992 bool ok = (
device()->writeBlock( buffer, bufferSize ) == bufferSize );
997 TQ_LONG centraldirendoffset =
device()->at();
1013 int count = d->m_fileList.count();
1017 buffer[ 8 ] = char(count);
1018 buffer[ 9 ] = char(count >> 8);
1020 buffer[ 10 ] = buffer[ 8 ];
1021 buffer[ 11 ] = buffer[ 9 ];
1023 int cdsize = centraldirendoffset - centraldiroffset;
1024 buffer[ 12 ] = char(cdsize);
1025 buffer[ 13 ] = char(cdsize >> 8);
1026 buffer[ 14 ] = char(cdsize >> 16);
1027 buffer[ 15 ] = char(cdsize >> 24);
1032 buffer[ 16 ] = char(centraldiroffset);
1033 buffer[ 17 ] = char(centraldiroffset >> 8);
1034 buffer[ 18 ] = char(centraldiroffset >> 16);
1035 buffer[ 19 ] = char(centraldiroffset >> 24);
1040 if (
device()->writeBlock( buffer, 22 ) != 22 )
1043 if ( d->m_saveFile ) {
1044 d->m_saveFile->close();
1046 delete d->m_saveFile;
1054 bool KZip::writeDir(
const TQString& name,
const TQString& user,
const TQString& group)
1059 TQString dirName = name;
1060 if (!name.endsWith(
"/")) {
1061 dirName = dirName.append(
'/');
1064 mode_t perm = 040755;
1065 time_t the_time = time(0);
1066 return writeFile(dirName, user, group, 0, perm, the_time, the_time, the_time, 0);
1070 bool KZip::writeFile(
const TQString& name,
const TQString& user,
const TQString& group, uint size,
const char* data )
1072 mode_t
mode = 0100644;
1073 time_t the_time = time(0);
1075 the_time, the_time, data );
1080 const TQString& group, uint size, mode_t perm,
1081 time_t atime, time_t mtime, time_t ctime,
1082 const char* data ) {
1090 mode_t dflt_perm = 0100644;
1091 time_t the_time = time(0);
1093 the_time,the_time,the_time);
1098 const TQString& group, uint size, mode_t perm,
1099 time_t atime, time_t mtime, time_t ctime) {
1103 bool KZip::prepareWriting_impl(
const TQString &name,
const TQString &user,
1104 const TQString &group, uint , mode_t perm,
1105 time_t atime, time_t mtime, time_t ctime) {
1109 tqWarning(
"KZip::writeFile: You must open the zip file before writing to it\n");
1113 if ( ! (
mode() & IO_WriteOnly ) )
1115 tqWarning(
"KZip::writeFile: You must open the zip file for writing\n");
1125 if ( !
device()->at( d->m_offset ) ) {
1126 kdWarning(7040) <<
"prepareWriting_impl: cannot seek in ZIP file. Disk full?" << endl;
1135 TQPtrListIterator<KZipFileEntry> it( d->m_fileList );
1138 for ( ; it.current() ; ++it )
1141 if (name == it.current()->path() )
1144 d->m_fileList.remove();
1151 int i = name.findRev(
'/' );
1154 TQString dir = name.left( i );
1161 KZipFileEntry * e =
new KZipFileEntry(
this,
fileName, perm, mtime, user, group, TQString::null,
1162 name,
device()->at() + 30 + name.length(),
1163 0 , d->m_compression, 0 );
1164 e->setHeaderStart(
device()->at() );
1166 parentDir->addEntry( e );
1168 d->m_currentFile = e;
1169 d->m_fileList.append( e );
1171 int extra_field_len = 0;
1173 extra_field_len = 17;
1176 TQCString encodedName = TQFile::encodeName(name);
1177 int bufferSize = extra_field_len + encodedName.length() + 30;
1179 char* buffer =
new char[ bufferSize ];
1192 buffer[ 8 ] = char(e->encoding());
1193 buffer[ 9 ] = char(e->encoding() >> 8);
1195 transformToMsDos( e->datetime(), &buffer[ 10 ] );
1212 buffer[ 26 ] = (uchar)(encodedName.length());
1213 buffer[ 27 ] = (uchar)(encodedName.length() >> 8);
1215 buffer[ 28 ] = (uchar)(extra_field_len);
1216 buffer[ 29 ] = (uchar)(extra_field_len >> 8);
1219 strncpy( buffer + 30, encodedName, encodedName.length() );
1224 char *extfield = buffer + 30 + encodedName.length();
1230 extfield[4] = 1 | 2 | 4;
1232 extfield[5] = char(mtime);
1233 extfield[6] = char(mtime >> 8);
1234 extfield[7] = char(mtime >> 16);
1235 extfield[8] = char(mtime >> 24);
1237 extfield[9] = char(atime);
1238 extfield[10] = char(atime >> 8);
1239 extfield[11] = char(atime >> 16);
1240 extfield[12] = char(atime >> 24);
1242 extfield[13] = char(ctime);
1243 extfield[14] = char(ctime >> 8);
1244 extfield[15] = char(ctime >> 16);
1245 extfield[16] = char(ctime >> 24);
1249 bool b = (
device()->writeBlock( buffer, bufferSize ) == bufferSize );
1261 if ( d->m_compression == 0 ) {
1262 d->m_currentDev =
device();
1267 Q_ASSERT( d->m_currentDev );
1268 if ( !d->m_currentDev ) {
1272 static_cast<KFilterDev *
>(d->m_currentDev)->setSkipHeaders();
1274 b = d->m_currentDev->
open( IO_WriteOnly );
1281 if ( d->m_currentFile->encoding() == 8 ) {
1283 (void)d->m_currentDev->writeBlock( 0, 0 );
1284 delete d->m_currentDev;
1287 d->m_currentDev = 0L;
1289 Q_ASSERT( d->m_currentFile );
1293 d->m_currentFile->setSize(size);
1294 int extra_field_len = 0;
1296 extra_field_len = 17;
1298 int csize =
device()->at() -
1299 d->m_currentFile->headerStart() - 30 -
1300 d->m_currentFile->path().length() - extra_field_len;
1301 d->m_currentFile->setCompressedSize(csize);
1307 d->m_currentFile->setCRC32( d->m_crc );
1309 d->m_currentFile = 0L;
1312 d->m_offset =
device()->at();
1316 bool KZip::writeSymLink(
const TQString &name,
const TQString &target,
1317 const TQString &user,
const TQString &group,
1318 mode_t perm, time_t atime, time_t mtime, time_t ctime) {
1322 bool KZip::writeSymLink_impl(
const TQString &name,
const TQString &target,
1323 const TQString &user,
const TQString &group,
1324 mode_t perm, time_t atime, time_t mtime, time_t ctime) {
1332 if (!
prepareWriting(name, user, group, 0, perm, atime, mtime, ctime)) {
1333 kdWarning() <<
"KZip::writeFile prepareWriting failed" << endl;
1338 TQCString symlink_target = TQFile::encodeName(target);
1339 if (!
writeData(symlink_target, symlink_target.length())) {
1340 kdWarning() <<
"KZip::writeFile writeData failed" << endl;
1346 kdWarning() <<
"KZip::writeFile doneWriting failed" << endl;
1355 void KZip::virtual_hook(
int id,
void* data )
1358 case VIRTUAL_WRITE_DATA: {
1359 WriteDataParams* params =
reinterpret_cast<WriteDataParams *
>(data);
1360 params->retval = writeData_impl( params->data, params->size );
1363 case VIRTUAL_WRITE_SYMLINK: {
1364 WriteSymlinkParams *params =
reinterpret_cast<WriteSymlinkParams *
>(data);
1365 params->retval = writeSymLink_impl(*params->name,*params->target,
1366 *params->user,*params->group,params->perm,
1367 params->atime,params->mtime,params->ctime);
1370 case VIRTUAL_PREPARE_WRITING: {
1371 PrepareWritingParams *params =
reinterpret_cast<PrepareWritingParams *
>(data);
1372 params->retval = prepareWriting_impl(*params->name,*params->user,
1373 *params->group,params->size,params->perm,
1374 params->atime,params->mtime,params->ctime);
1378 KArchive::virtual_hook(
id, data );
1388 bool KZip::writeData_impl(
const char * c, uint i)
1390 Q_ASSERT( d->m_currentFile );
1391 Q_ASSERT( d->m_currentDev );
1392 if (!d->m_currentFile || !d->m_currentDev) {
1399 d->m_crc = crc32(d->m_crc, (
const Bytef *) c , i);
1401 TQ_LONG written = d->m_currentDev->writeBlock( c, i );
1403 bool ok = written == (TQ_LONG)i;
1421 d->m_extraField = ef;
1426 return d->m_extraField;
1431 if ( d->m_saveFile ) {
1432 d->m_saveFile->abort();
1440 TQByteArray KZipFileEntry::data()
const
1442 TQIODevice* dev = device();
1445 arr = dev->readAll();
1451 TQIODevice* KZipFileEntry::device()
const
1456 if ( encoding() == 0 || compressedSize() == 0 )
1459 if ( encoding() == 8 )
1465 static_cast<KFilterDev *
>(filterDev)->setSkipHeaders();
1466 bool b = filterDev->
open( IO_ReadOnly );
1471 kdError() <<
"This zip file contains files compressed with method "
1472 << encoding() <<
", this method is currently not supported by KZip,"
1473 <<
" please use a command-line tool to handle this file." << endl;