1 /*
2 *
3 * Copyright 2018 Britanicus <marcusbritanicus@gmail.com>
4 *
5
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
18 *
19
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 *
24 */
25
26 #include "Global.hpp"
27 #include "libarchiveqt.h"
28
29 #include "LibLzma.hpp"
30 #include "LibLzma2.hpp"
31 #include "LibBZip2.hpp"
32 #include "LibGZip.hpp"
33
34 extern "C" {
35 #include "lz4dec.h"
36 }
37
38 // SystemWide Headers
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42 #include <assert.h>
43 #include <libgen.h>
44
isDir(QString path)45 inline static bool isDir( QString path ) {
46
47 struct stat statbuf;
48 if ( stat( path.toLocal8Bit().data(), &statbuf ) == 0 )
49
50 if ( S_ISDIR( statbuf.st_mode ) )
51 return true;
52
53 else
54 return false;
55
56 else
57 return false;
58 };
59
recDirWalk(QString path)60 inline static QStringList recDirWalk( QString path ) {
61
62 QStringList fileList;
63
64 if ( not isDir( path ) )
65 return fileList;
66
67 QDirIterator it( path, QDir::AllEntries | QDir::System | QDir::NoDotAndDotDot | QDir::Hidden, QDirIterator::Subdirectories );
68 while ( it.hasNext() ) {
69 it.next();
70 if ( it.fileInfo().isFile() )
71 fileList.append( it.fileInfo().filePath() );
72 }
73
74 return fileList;
75 };
76
dirName(QString path)77 inline static QString dirName( QString path ) {
78
79 while( path.contains( "//" ) )
80 path = path.replace( "//", "/" );
81
82 if ( path.endsWith( "/" ) )
83 path.chop( 1 );
84
85 char *dupPath = strdup( path.toLocal8Bit().constData() );
86 QString dirPth = QString( dirname( dupPath ) ) + "/";
87 free( dupPath );
88
89 return ( dirPth == "//" ? "/" : dirPth );
90 };
91
baseName(QString path)92 inline static QString baseName( QString path ) {
93
94 while( path.contains( "//" ) )
95 path = path.replace( "//", "/" );
96
97 if ( path.endsWith( "/" ) )
98 path.chop( 1 );
99
100 char *dupPath = strdup( path.toLocal8Bit().constData() );
101 QString basePth = QString( basename( dupPath ) );
102 free( dupPath );
103
104 return basePth;
105 };
106
exists(QString path)107 inline static bool exists( QString path ) {
108
109 return not access( path.toLocal8Bit().constData(), F_OK );
110 }
111
mkpath(QString path,mode_t mode)112 inline static int mkpath( QString path, mode_t mode ) {
113
114 /* Root always exists */
115 if ( path == "/" )
116 return 0;
117
118 /* If the directory exists, thats okay for us */
119 if ( exists( path ) )
120 return 0;
121
122 /* If the path is absolute, remove the leading '/' */
123 if ( path.startsWith( '/' ) )
124 path.remove( 0, 1 );
125
126 mkpath( dirName( path ), mode );
127
128 return mkdir( path.toLocal8Bit().constData(), mode );
129 };
130
longestPath(QStringList & dirs)131 inline static QString longestPath( QStringList &dirs ) {
132
133 QStringList paths;
134 Q_FOREACH( QString file, dirs )
135 paths << QFileInfo( file ).absoluteFilePath();
136
137 /* Get shortest path: Shortest path is the one with least number of '/' */
138 QString shortest = paths.at( 0 );
139 int count = 10240;
140 Q_FOREACH( QString path, paths ) {
141 if ( path.count( "/" ) < count ) {
142 count = path.count( "/" );
143 shortest = path;
144 }
145 }
146
147 /* Remove the trailing '/' */
148 if ( shortest.endsWith( "/" ) )
149 shortest.chop( 1 );
150
151 QFileInfo sDir( shortest );
152 while ( paths.filter( sDir.absoluteFilePath() ).count() != paths.count() ) {
153 if ( sDir.absoluteFilePath() == "/" )
154 break;
155
156 sDir = QFileInfo( sDir.absolutePath() );
157 }
158
159 return sDir.absoluteFilePath();
160 };
161
LibArchiveQt(QString archive)162 LibArchiveQt::LibArchiveQt( QString archive ) {
163
164 readDone = false;
165 isRunning = false;
166 mJob = NoJob;
167 extractedMember = QString();
168 mExitStatus = 0; // 0 - Good, 1 - Bad
169
170 archiveName = QDir( archive ).absolutePath();
171
172 setFilterFormat( mimeDb.mimeTypeForFile( archiveName ) );
173 };
174
suffix(QString archiveName)175 QString LibArchiveQt::suffix( QString archiveName ) {
176
177 QMimeType mType = mimeDb.mimeTypeForFile( archiveName );
178
179 if ( mType == mimeDb.mimeTypeForFile( "file.cpio" ) )
180 return ".cpio";
181
182 else if ( mType == mimeDb.mimeTypeForFile( "file.shar" ) )
183 return ".shar";
184
185 else if ( mType == mimeDb.mimeTypeForFile( "file.tar" ) )
186 return ".tar";
187
188 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.gz" ) )
189 return ( archiveName.endsWith( ".tar.gz" ) ? ".tar.gz" : ".tgz" );
190
191 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.grz" ) )
192 return ( archiveName.endsWith( ".tar.grz" ) ? ".tar.grz" : ".tgrz" );
193
194 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.xz" ) )
195 return ( archiveName.endsWith( ".tar.xz" ) ? ".tar.xz" : ".txz" );
196
197 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.lzo" ) )
198 return ( archiveName.endsWith( ".tar.lzo" ) ? ".tar.lzo" : ".tlzo" );
199
200 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.lzma" ) )
201 return ( archiveName.endsWith( ".tar.lzma" ) ? ".tar.lzma" : ".tlzma" );
202
203 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.lz" ) )
204 return ( archiveName.endsWith( ".tar.lz" ) ? ".tar.lz" : ".tlz" );
205
206 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.lrz" ) )
207 return ( archiveName.endsWith( ".tar.lrz" ) ? ".tar.lrz" : ".tlrz" );
208
209 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.lz4" ) )
210 return ( archiveName.endsWith( ".tar.lz4" ) ? ".tar.lz4" : ".tlzo4" );
211
212 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.bz2" ) )
213 return ( archiveName.endsWith( ".tar.bz2" ) ? ".tar.bz2" : ".tbz2" );
214
215 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.Z" ) )
216 return ( archiveName.endsWith( ".tar.Z" ) ? ".tar.Z" : ".tZ" );
217
218 else if ( mType == mimeDb.mimeTypeForFile( "file.iso" ) )
219 return ".iso";
220
221 else if ( mType == mimeDb.mimeTypeForFile( "file.zip" ) )
222 return ".zip";
223
224 else if ( mType == mimeDb.mimeTypeForFile( "file.ar" ) )
225 return ".ar";
226
227 else if ( mType == mimeDb.mimeTypeForFile( "file.xar" ) )
228 return ".xar";
229
230 else if ( mType == mimeDb.mimeTypeForFile( "file.7z" ) )
231 return ".7z";
232
233 else if ( mType == mimeDb.mimeTypeForFile( "file.lz" ) )
234 return ".lz";
235
236 else if ( mType == mimeDb.mimeTypeForFile( "file.lz4" ) )
237 return ".lz4";
238
239 else if ( mType == mimeDb.mimeTypeForFile( "file.uu" ) )
240 return ".uu";
241
242 else if ( mType == mimeDb.mimeTypeForFile( "file.lzo" ) )
243 return ".lzo";
244
245 else if ( mType == mimeDb.mimeTypeForFile( "file.gz" ) )
246 return ".gz";
247
248 else if ( mType == mimeDb.mimeTypeForFile( "file.bz2" ) )
249 return ".bz2";
250
251 else if ( mType == mimeDb.mimeTypeForFile( "file.lzma" ) )
252 return ".lzma";
253
254 else if ( mType == mimeDb.mimeTypeForFile( "file.xz" ) )
255 return ".xz";
256
257 return "";
258 };
259
supportedFormats()260 QStringList LibArchiveQt::supportedFormats() {
261
262 QStringList supported;
263
264 supported << mimeDb.mimeTypeForFile( "file.cpio" ).name();
265 supported << mimeDb.mimeTypeForFile( "file.shar" ).name();
266 supported << mimeDb.mimeTypeForFile( "file.tar" ).name();
267 supported << mimeDb.mimeTypeForFile( "file.tar.gz" ).name();
268 supported << mimeDb.mimeTypeForFile( "file.tar.grz" ).name();
269 supported << mimeDb.mimeTypeForFile( "file.tar.xz" ).name();
270 supported << mimeDb.mimeTypeForFile( "file.tar.lzma" ).name();
271 supported << mimeDb.mimeTypeForFile( "file.tar.lz4" ).name();
272 supported << mimeDb.mimeTypeForFile( "file.tar.bz2" ).name();
273 supported << mimeDb.mimeTypeForFile( "file.tar.Z" ).name();
274 supported << mimeDb.mimeTypeForFile( "file.iso" ).name();
275 supported << mimeDb.mimeTypeForFile( "file.zip" ).name();
276 supported << mimeDb.mimeTypeForFile( "file.ar" ).name();
277 supported << mimeDb.mimeTypeForFile( "file.xar" ).name();
278 supported << mimeDb.mimeTypeForFile( "file.7z" ).name();
279 supported << mimeDb.mimeTypeForFile( "file.lz" ).name();
280 supported << mimeDb.mimeTypeForFile( "file.lz4" ).name();
281 supported << mimeDb.mimeTypeForFile( "file.uu" ).name();
282 supported << mimeDb.mimeTypeForFile( "file.lzo" ).name();
283 supported << mimeDb.mimeTypeForFile( "file.gz" ).name();
284 supported << mimeDb.mimeTypeForFile( "file.bz2" ).name();
285 supported << mimeDb.mimeTypeForFile( "file.lzma" ).name();
286 supported << mimeDb.mimeTypeForFile( "file.xz" ).name();
287
288 QString binary;
289
290 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
291 QStringList exeLocs = QString::fromLocal8Bit( qgetenv( "PATH" ) ).split( ":", Qt::SkipEmptyParts );
292 #else
293 QStringList exeLocs = QString::fromLocal8Bit( qgetenv( "PATH" ) ).split( ":", QString::SkipEmptyParts );
294 #endif
295
296 QString lzop = mimeDb.mimeTypeForFile( "file.lzo" ).name();
297 QString lzip = mimeDb.mimeTypeForFile( "file.lz" ).name();
298 QString lrzip = mimeDb.mimeTypeForFile( "file.lrz" ).name();
299
300 Q_FOREACH( QString loc, exeLocs ) {
301 if ( exists( loc + "/lzip" ) and not supported.contains( lzip ) )
302 supported << lzip;
303
304 if ( exists( loc + "/lzop" ) and not supported.contains( lzop ) )
305 supported << lzop;
306
307 if ( exists( loc + "/lrzip" ) and not supported.contains( lrzip ) )
308 supported << lrzip;
309 }
310
311 return supported;
312 };
313
createArchive()314 void LibArchiveQt::createArchive() {
315
316 mJob = CreateArchive;
317 isRunning = true;
318
319 start();
320 };
321
extractArchive()322 void LibArchiveQt::extractArchive() {
323
324 mJob = ExtractArchive;
325 isRunning = true;
326
327 start();
328 };
329
extractMember(QString memberName)330 void LibArchiveQt::extractMember( QString memberName ) {
331
332 extractedMember = memberName;
333 mJob = ExtractMember;
334 isRunning = true;
335
336 start();
337 };
338
listArchive()339 ArchiveEntries LibArchiveQt::listArchive() {
340
341 if ( readDone )
342 return memberList;
343
344 memberList.clear();
345
346 struct archive *a;
347 struct archive_entry *entry;
348 int r;
349
350 // Source Archive
351 a = archive_read_new();
352 archive_read_support_format_all( a );
353 archive_read_support_format_raw( a );
354 archive_read_support_filter_all( a );
355
356 if ( ( r = archive_read_open_filename( a, archiveName.toUtf8().data(), 10240 ) ) ) {
357 qDebug() << "[Error]" << archive_error_string( a );
358 readDone = true;
359 return ArchiveEntries();
360 }
361
362 while ( true ) {
363 r = archive_read_next_header( a, &entry );
364
365 if ( r == ARCHIVE_EOF )
366 break;
367
368 if ( r < ARCHIVE_OK )
369 qDebug() << archive_error_string( a );
370
371 ArchiveEntry *ae = new ArchiveEntry;
372 ae->name = archive_entry_pathname( entry );
373 ae->size = archive_entry_size( entry );
374 ae->type = archive_entry_filetype( entry );
375 memcpy( &ae->info, archive_entry_stat( entry ), sizeof( struct stat ) );
376
377 memberList << ae;
378 }
379
380 archive_read_close( a );
381 archive_read_free( a );
382
383 readDone = true;
384
385 return memberList;
386 };
387
exitStatus()388 int LibArchiveQt::exitStatus() {
389
390 return mExitStatus;
391 };
392
updateInputFiles(QStringList inFiles,LibArchiveQt::InputFileMode inMode)393 void LibArchiveQt::updateInputFiles( QStringList inFiles, LibArchiveQt::InputFileMode inMode ) {
394
395 if ( not inFiles.count() )
396 return;
397
398 /* First get the absolute filenames */
399 Q_FOREACH( QString file, inFiles ) {
400 if ( isDir( file ) )
401 updateInputFiles( recDirWalk( file ), inMode );
402
403 else {
404 QFileInfo info( file );
405 switch ( inMode ) {
406 case AbsolutePath: {
407 inputList.insert( info.absoluteFilePath(), info.absoluteFilePath() );
408 break;
409 }
410
411 case RelativeToRoot: {
412 inputList.insert( info.absoluteFilePath(), QDir::root().relativeFilePath( info.absoluteFilePath() ) );
413 break;
414 }
415
416 case RelativeToHome: {
417 QString relPath = QDir::home().relativeFilePath( info.absoluteFilePath() );
418 while ( relPath.startsWith( "../" ) )
419 relPath.remove( 0, 3 );
420
421 inputList.insert( info.absoluteFilePath(), relPath );
422 break;
423 }
424
425 case RelativeToCurrent: {
426 QString relPath = QDir::current().relativeFilePath( info.absoluteFilePath() );
427 while ( relPath.startsWith( "../" ) )
428 relPath.remove( 0, 3 );
429
430 inputList.insert( info.absoluteFilePath(), relPath );
431 break;
432 }
433
434 case RelativeToWorkDir: {
435 /* If @src is empty, set it to root */
436 src = ( src.isEmpty() ? "/" : src );
437
438 QString relPath = QDir( src ).relativeFilePath( info.absoluteFilePath() );
439 while ( relPath.startsWith( "../" ) )
440 relPath.remove( 0, 3 );
441
442 inputList.insert( info.absoluteFilePath(), relPath );
443 break;
444 }
445
446 case CommonRelativePath: {
447 QString common;
448 if ( inFiles.count() == 1 )
449 common = dirName( inFiles.at( 0 ) );
450
451 else
452 common = longestPath( inFiles );
453
454 QString relPath = QDir( common ).relativeFilePath( info.absoluteFilePath() );
455 while ( relPath.startsWith( "../" ) )
456 relPath.remove( 0, 3 );
457
458 inputList.insert( info.absoluteFilePath(), relPath );
459 break;
460 }
461
462 default: {
463 QString relPath = QDir::current().relativeFilePath( info.absoluteFilePath() );
464 while ( relPath.startsWith( "../" ) )
465 relPath.remove( 0, 3 );
466
467 inputList.insert( info.absoluteFilePath(), relPath );
468 break;
469 }
470 }
471 }
472 }
473 };
474
setWorkingDir(QString wDir)475 void LibArchiveQt::setWorkingDir( QString wDir ) {
476
477 src = QString( wDir );
478 };
479
setDestination(QString path)480 void LibArchiveQt::setDestination( QString path ) {
481
482 /*
483 *
484 * @p path will be a absolute.
485 * So QDir we construct will be home path
486 *
487 */
488
489 dest = QString( path );
490 if ( not QFileInfo( QDir( dest ).absolutePath() ).exists() )
491 mkpath( path, 0755 );
492
493 qDebug() << "Extracting to:" << dest;
494 };
495
waitForFinished()496 void LibArchiveQt::waitForFinished() {
497
498 if ( not isRunning )
499 return;
500
501 QEventLoop eventLoop;
502 #if QT_VERSION >= 0x050000
503 connect(this, &LibArchiveQt::jobFailed, &eventLoop, &QEventLoop::quit);
504 connect(this, &LibArchiveQt::jobComplete, &eventLoop, &QEventLoop::quit);
505 #else
506 connect(this, SIGNAL( jobFailed() ), &eventLoop, SLOT( quit() ) );
507 connect(this, SIGNAL( jobComplete() ), &eventLoop, SLOT( quit() ) );
508 #endif
509
510 eventLoop.exec();
511 };
512
run()513 void LibArchiveQt::run() {
514
515 switch( mJob ) {
516 case CreateArchive: {
517 if ( doCreateArchive() ) {
518 mExitStatus = 0;
519 emit jobComplete();
520 }
521
522 else {
523 mExitStatus = 1;
524 emit jobFailed();
525 }
526
527 isRunning = false;
528 return;
529 }
530
531 case ExtractArchive: {
532 if ( doExtractArchive() ) {
533 mExitStatus = 0;
534 emit jobComplete();
535 }
536
537 else {
538 mExitStatus = 1;
539 emit jobFailed();
540 }
541
542 isRunning = false;
543 return;
544 }
545
546 case ExtractMember: {
547 if ( doExtractMember( extractedMember ) ) {
548 mExitStatus = 0;
549 emit jobComplete();
550 }
551
552 else {
553 mExitStatus = 1;
554 emit jobFailed();
555 }
556
557 isRunning = false;
558 return;
559 }
560
561 case ListArchive: {
562 /* Nothing to run in the thread */
563 return;
564 }
565 }
566 };
567
doCreateArchive()568 bool LibArchiveQt::doCreateArchive() {
569
570 struct archive *a;
571 struct archive_entry *entry;
572 struct stat st;
573 char buff[ 8192 ];
574 int len;
575 int fd;
576 int r = ARCHIVE_OK;
577 int errors = 0;
578 int processed = 0;
579
580 /* Prepare the workingDir */
581 if ( src.isEmpty() )
582 src = "/";
583
584 a = archive_write_new();
585
586 // Depend on the format provided by the user
587 r |= archive_write_set_format( a, mArchiveFormat );
588 r |= archive_write_add_filter( a, mArchiveFilter );
589 if ( r < ARCHIVE_OK ) {
590 qDebug() << "Cannot use the input filter/format.";
591 return false;
592 }
593
594 r = archive_write_open_filename( a, archiveName.toUtf8().data() );
595 if ( r < ARCHIVE_OK ) {
596 qDebug() << "Unable to write file for writing.";
597 return false;
598 }
599
600 Q_FOREACH( QString file, inputList.keys() ) {
601 char *filename = new char[ file.count() + 1 ];
602 strcpy( filename, file.toUtf8().data() );
603
604 if ( stat( filename, &st ) != 0 ) {
605 errors++;
606 printf( "[Error %d]: %s: %s\n", errno, strerror( errno ), filename );
607 continue;
608 }
609
610 char *arcPath = new char[ file.count() + 1 ];
611 strcpy( arcPath, inputList.value( file ).toUtf8().data() );
612
613 entry = archive_entry_new();
614 archive_entry_set_pathname( entry, arcPath );
615 archive_entry_set_size( entry, st.st_size );
616 archive_entry_set_filetype( entry, st.st_mode );
617 archive_entry_set_perm( entry, st.st_mode );
618
619 archive_write_header( a, entry );
620
621 // Perform the write
622 fd = open( filename, O_RDONLY );
623 len = read( fd, buff, sizeof( buff ) );
624 while ( len > 0 ) {
625 archive_write_data( a, buff, len );
626 len = read( fd, buff, sizeof( buff ) );
627 }
628 close( fd );
629 archive_entry_free( entry );
630
631 processed++;
632
633 emit progress( processed * 100 / inputList.count() );
634 qApp->processEvents();
635 }
636
637 archive_write_close( a );
638 archive_write_free( a );
639
640 return ( errors ? false : true );
641 };
642
doExtractArchive()643 bool LibArchiveQt::doExtractArchive() {
644
645 if ( archiveType == None )
646 return false;
647
648 // Change to the target directory
649 char srcDir[ 10240 ] = { 0 };
650 getcwd( srcDir, 10240 );
651
652 if ( not dest.isEmpty() ) {
653 int ret = chdir( dest.toUtf8().data() );
654 if ( ret )
655 qDebug() << "chdir() failed:" << errno;
656 }
657
658 if ( archiveType == Single ) {
659 QMimeType mType = mimeDb.mimeTypeForFile( archiveName );
660
661 if ( mType == mimeDb.mimeTypeForFile( "file.lz" ) ) {
662 /* LZip Extractor */
663
664 QString lzip;
665
666 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
667 QStringList exeLocs = QString::fromLocal8Bit( qgetenv( "PATH" ) ).split( ":", Qt::SkipEmptyParts );
668 #else
669 QStringList exeLocs = QString::fromLocal8Bit( qgetenv( "PATH" ) ).split( ":", QString::SkipEmptyParts );
670 #endif
671
672 Q_FOREACH( QString loc, exeLocs ) {
673 if ( exists( loc + "/lzip" ) ) {
674 lzip = loc + "/lzip";
675 break;
676 }
677 }
678
679 if ( not lzip.count() ) {
680 qDebug() << "External program lzip not found.";
681 return false;
682 }
683
684 struct archive *a;
685 struct archive *ext;
686 struct archive_entry *entry;
687 int flags;
688
689 int r = ARCHIVE_OK;
690
691 /* Select which attributes we want to restore. */
692 flags = ARCHIVE_EXTRACT_TIME;
693 flags |= ARCHIVE_EXTRACT_PERM;
694 flags |= ARCHIVE_EXTRACT_ACL;
695 flags |= ARCHIVE_EXTRACT_FFLAGS;
696
697 // Source Archive
698 a = archive_read_new();
699 r |= archive_read_support_format_raw( a );
700 r |= archive_read_support_filter_program( a, QString( lzip + " -d" ).toLocal8Bit().data() );
701
702 if ( r < ARCHIVE_OK ) {
703 qDebug() << "Cannot use the input filter/format.";
704 return false;
705 }
706
707 // Structure to write files to disk
708 ext = archive_write_disk_new();
709 archive_write_disk_set_options( ext, flags );
710 archive_write_disk_set_standard_lookup( ext );
711
712 if ( ( r = archive_read_open_filename( a, archiveName.toLocal8Bit().data(), 10240 ) ) ) {
713 qDebug() << "Unable to read archive:" << archive_error_string( a );
714 return false;
715 }
716
717 while ( true ) {
718 r = archive_read_next_header( a, &entry );
719 if ( r == ARCHIVE_EOF ) {
720 qDebug() << "EOF";
721 break;
722 }
723
724 if ( r < ARCHIVE_OK )
725 fprintf( stderr, "%s\n", archive_error_string( a ) );
726
727 if ( r < ARCHIVE_WARN ) {
728 fprintf( stderr, "%s\n", archive_error_string( a ) );
729 return false;
730 }
731
732 r = archive_write_header( ext, entry );
733 if ( r < ARCHIVE_OK )
734 fprintf( stderr, "%s\n", archive_error_string( ext ) );
735
736 else if ( archive_entry_size( entry ) == 0 ) {
737 r = copyData( a, ext );
738 if ( r < ARCHIVE_OK )
739 fprintf( stderr, "%s\n", archive_error_string( ext ) );
740
741 if ( r < ARCHIVE_WARN )
742 return false;
743 }
744
745 r = archive_write_finish_entry( ext );
746 if ( r < ARCHIVE_OK )
747 fprintf( stderr, "%s\n", archive_error_string( ext ) );
748
749 if ( r < ARCHIVE_WARN )
750 return true;
751 }
752
753 archive_read_close( a );
754 archive_read_free( a );
755
756 archive_write_close( ext );
757 archive_write_free( ext );
758
759 return true;
760 }
761
762 else if ( mType == mimeDb.mimeTypeForFile( "file.uu" ) ) {
763 /* UUEncode Extractor */
764
765 return false;
766 }
767
768 else if ( mType == mimeDb.mimeTypeForFile( "file.lrz" ) ) {
769 /* lrzip Extractor */
770
771 QString lrzip;
772
773 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
774 QStringList exeLocs = QString::fromLocal8Bit( qgetenv( "PATH" ) ).split( ":", Qt::SkipEmptyParts );
775 #else
776 QStringList exeLocs = QString::fromLocal8Bit( qgetenv( "PATH" ) ).split( ":", QString::SkipEmptyParts );
777 #endif
778 Q_FOREACH( QString loc, exeLocs ) {
779 if ( exists( loc + "/lrzip" ) ) {
780 lrzip = loc + "/lrzip";
781 break;
782 }
783 }
784
785 if ( not lrzip.count() ) {
786 qDebug() << "External program lrzip not found.";
787 return false;
788 }
789
790 struct archive *a;
791 struct archive *ext;
792 struct archive_entry *entry;
793 int flags;
794
795 int r = ARCHIVE_OK;
796
797 /* Select which attributes we want to restore. */
798 flags = ARCHIVE_EXTRACT_TIME;
799 flags |= ARCHIVE_EXTRACT_PERM;
800 flags |= ARCHIVE_EXTRACT_ACL;
801 flags |= ARCHIVE_EXTRACT_FFLAGS;
802
803 // Source Archive
804 a = archive_read_new();
805 r |= archive_read_support_format_raw( a );
806 r |= archive_read_support_filter_program( a, QString( lrzip + " -d" ).toLocal8Bit().data() );
807
808 if ( r < ARCHIVE_OK )
809 qDebug() << "Cannot use the input filter/format.";
810
811 // Structure to write files to disk
812 ext = archive_write_disk_new();
813 archive_write_disk_set_options( ext, flags );
814 archive_write_disk_set_standard_lookup( ext );
815
816 if ( ( r = archive_read_open_filename( a, archiveName.toLocal8Bit().data(), 10240 ) ) ) {
817 qDebug() << "Unable to read archive:" << archive_error_string( a );
818 return false;
819 }
820
821 while ( true ) {
822 r = archive_read_next_header( a, &entry );
823 if ( r == ARCHIVE_EOF ) {
824 qDebug() << "EOF";
825 break;
826 }
827
828 if ( r < ARCHIVE_OK )
829 fprintf( stderr, "%s\n", archive_error_string( a ) );
830
831 if ( r < ARCHIVE_WARN ) {
832 fprintf( stderr, "%s\n", archive_error_string( a ) );
833 return false;
834 }
835
836 r = archive_write_header( ext, entry );
837 if ( r < ARCHIVE_OK )
838 fprintf( stderr, "%s\n", archive_error_string( ext ) );
839
840 else if ( archive_entry_size( entry ) == 0 ) {
841 r = copyData( a, ext );
842 if ( r < ARCHIVE_OK )
843 fprintf( stderr, "%s\n", archive_error_string( ext ) );
844
845 if ( r < ARCHIVE_WARN )
846 return false;
847 }
848
849 r = archive_write_finish_entry( ext );
850 if ( r < ARCHIVE_OK )
851 fprintf( stderr, "%s\n", archive_error_string( ext ) );
852
853 if ( r < ARCHIVE_WARN )
854 return true;
855 }
856
857 archive_read_close( a );
858 archive_read_free( a );
859
860 archive_write_close( ext );
861 archive_write_free( ext );
862
863 return true;
864 }
865
866 else if ( mType == mimeDb.mimeTypeForFile( "file.lzo" ) ) {
867 /* LZop Extractor */
868
869 QString lzop;
870
871 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
872 QStringList exeLocs = QString::fromLocal8Bit( qgetenv( "PATH" ) ).split( ":", Qt::SkipEmptyParts );
873 #else
874 QStringList exeLocs = QString::fromLocal8Bit( qgetenv( "PATH" ) ).split( ":", QString::SkipEmptyParts );
875 #endif
876 Q_FOREACH( QString loc, exeLocs ) {
877 if ( exists( loc + "/lzop" ) ) {
878 lzop = loc + "/lzop";
879 break;
880 }
881 }
882
883 if ( not lzop.count() ) {
884 qDebug() << "External program lzop not found.";
885 return false;
886 }
887
888 struct archive *a;
889 struct archive *ext;
890 struct archive_entry *entry;
891 int flags;
892
893 int r = ARCHIVE_OK;
894
895 /* Select which attributes we want to restore. */
896 flags = ARCHIVE_EXTRACT_TIME;
897 flags |= ARCHIVE_EXTRACT_PERM;
898 flags |= ARCHIVE_EXTRACT_ACL;
899 flags |= ARCHIVE_EXTRACT_FFLAGS;
900
901 // Source Archive
902 a = archive_read_new();
903 r |= archive_read_support_format_raw( a );
904 r |= archive_read_support_filter_program( a, QString( lzop + " -d" ).toLocal8Bit().data() );
905
906 if ( r < ARCHIVE_OK )
907 qDebug() << "Cannot use the input filter/format.";
908
909 // Structure to write files to disk
910 ext = archive_write_disk_new();
911 archive_write_disk_set_options( ext, flags );
912 archive_write_disk_set_standard_lookup( ext );
913
914 if ( ( r = archive_read_open_filename( a, archiveName.toLocal8Bit().data(), 10240 ) ) ) {
915 qDebug() << "Unable to read archive:" << archive_error_string( a );
916 return false;
917 }
918
919 while ( true ) {
920 r = archive_read_next_header( a, &entry );
921 if ( r == ARCHIVE_EOF ) {
922 qDebug() << "EOF";
923 break;
924 }
925
926 if ( r < ARCHIVE_OK )
927 fprintf( stderr, "%s\n", archive_error_string( a ) );
928
929 if ( r < ARCHIVE_WARN ) {
930 fprintf( stderr, "%s\n", archive_error_string( a ) );
931 return false;
932 }
933
934 r = archive_write_header( ext, entry );
935 if ( r < ARCHIVE_OK )
936 fprintf( stderr, "%s\n", archive_error_string( ext ) );
937
938 else if ( archive_entry_size( entry ) == 0 ) {
939 r = copyData( a, ext );
940 if ( r < ARCHIVE_OK )
941 fprintf( stderr, "%s\n", archive_error_string( ext ) );
942
943 if ( r < ARCHIVE_WARN )
944 return false;
945 }
946
947 r = archive_write_finish_entry( ext );
948 if ( r < ARCHIVE_OK )
949 fprintf( stderr, "%s\n", archive_error_string( ext ) );
950
951 if ( r < ARCHIVE_WARN )
952 return true;
953 }
954
955 archive_read_close( a );
956 archive_read_free( a );
957
958 archive_write_close( ext );
959 archive_write_free( ext );
960
961 return true;
962 }
963
964 else if ( mType == mimeDb.mimeTypeForFile( "file.lz4" ) ) {
965 /* LZ4 Extractor */
966
967 dest = archiveName;
968 dest.chop( 4 );
969
970 int i = 0;
971 while ( exists( dest ) ) {
972 i++;
973
974 dest = archiveName;
975 dest.chop( 3 );
976
977 dest = dirName( dest ) + QString( "(%1) - " ).arg( i ) + baseName( dest );
978 }
979
980 unlz4( archiveName.toLocal8Bit().constData(), dest.toLocal8Bit().constData(), NULL );
981 return true;
982 }
983
984 else if ( mType == mimeDb.mimeTypeForFile( "file.gz" ) ) {
985 /* GZip Extractor */
986
987 dest = archiveName;
988 dest.chop( 3 );
989
990 int i = 0;
991 while ( exists( dest ) ) {
992 i++;
993
994 dest = archiveName;
995 dest.chop( 3 );
996
997 dest = dirName( dest ) + QString( "(%1) - " ).arg( i ) + baseName( dest );
998 }
999
1000 NBGZip *gzExt = new NBGZip( archiveName, dest );
1001 return gzExt->extract();
1002 }
1003
1004 else if ( mType == mimeDb.mimeTypeForFile( "file.bz2" ) ) {
1005 /* BZip2 Extractor */
1006
1007 dest = archiveName;
1008 dest.chop( 3 );
1009
1010 int i = 0;
1011 while ( exists( dest ) ) {
1012 i++;
1013
1014 dest = archiveName;
1015 dest.chop( 3 );
1016
1017 dest = dirName( dest ) + QString( "(%1) - " ).arg( i ) + baseName( dest );
1018 }
1019
1020 NBBZip2 *bz2Ext = new NBBZip2( archiveName, dest );
1021 return bz2Ext->extract();
1022 }
1023
1024 else if ( mType == mimeDb.mimeTypeForFile( "file.lzma" ) ) {
1025 /* LZMA Extractor */
1026
1027 dest = archiveName;
1028 dest.chop( 3 );
1029
1030 int i = 0;
1031 while ( exists( dest ) ) {
1032 i++;
1033
1034 dest = archiveName;
1035 dest.chop( 3 );
1036
1037 dest = dirName( dest ) + QString( "(%1) - " ).arg( i ) + baseName( dest );
1038 }
1039
1040 NBLzma *lzmaExt = new NBLzma( archiveName, dest );
1041 return lzmaExt->extract();
1042 }
1043
1044 else if ( mType == mimeDb.mimeTypeForFile( "file.xz" ) ) {
1045 /* XZ Extractor */
1046
1047 dest = archiveName;
1048 dest.chop( 3 );
1049
1050 int i = 0;
1051 while ( exists( dest ) ) {
1052 i++;
1053
1054 dest = archiveName;
1055 dest.chop( 3 );
1056
1057 dest = dirName( dest ) + QString( "(%1) - " ).arg( i ) + baseName( dest );
1058 }
1059
1060 NBXz *xzExt = new NBXz( archiveName, dest );
1061 return xzExt->extract();
1062 }
1063
1064 return false;
1065 }
1066
1067 else {
1068 /* To show progress we want the number of entries. So list the archive first. */
1069 /* Then count the number of members. Then clear the memberList */
1070 listArchive();
1071 int entryCount = memberList.count();
1072 memberList.clear();
1073 readDone = false;
1074
1075 struct archive *a;
1076 struct archive *ext;
1077 struct archive_entry *entry;
1078 int flags;
1079 int r = ARCHIVE_OK;
1080
1081 int processedEntries = 0;
1082
1083 /* Select which attributes we want to restore. */
1084 flags = ARCHIVE_EXTRACT_TIME;
1085 flags |= ARCHIVE_EXTRACT_PERM;
1086 flags |= ARCHIVE_EXTRACT_ACL;
1087 flags |= ARCHIVE_EXTRACT_FFLAGS;
1088
1089 // Source Archive
1090 a = archive_read_new();
1091
1092 r |= archive_read_support_format_all( a );
1093 r |= archive_read_support_filter_all( a );
1094
1095 if ( ( r |= archive_read_open_filename( a, archiveName.toUtf8().data(), 10240 ) ) < ARCHIVE_OK ) {
1096 fprintf( stderr, "%s\n", archive_error_string( a ) );
1097 return false;
1098 }
1099
1100 r = ARCHIVE_OK;
1101
1102 // Structure to write files to disk
1103 ext = archive_write_disk_new();
1104 r |= archive_write_disk_set_options( ext, flags );
1105 r |= archive_write_disk_set_standard_lookup( ext );
1106
1107 if ( r < ARCHIVE_WARN ) {
1108 fprintf( stderr, "%s\n", archive_error_string( a ) );
1109 return false;
1110 }
1111
1112 while ( true ) {
1113 r = archive_read_next_header( a, &entry );
1114 if ( r == ARCHIVE_EOF ) {
1115 break;
1116 }
1117
1118 if ( r < ARCHIVE_OK )
1119 fprintf( stderr, "%s\n", archive_error_string( a ) );
1120
1121 if ( r < ARCHIVE_WARN )
1122 return 1;
1123
1124 r = archive_write_header( ext, entry );
1125 if ( r < ARCHIVE_OK )
1126 fprintf( stderr, "%s\n", archive_error_string( ext ) );
1127
1128 else if ( archive_entry_size( entry ) > 0 ) {
1129 r = copyData( a, ext );
1130 if ( r < ARCHIVE_OK )
1131 fprintf( stderr, "%s\n", archive_error_string( ext ) );
1132
1133 if ( r < ARCHIVE_WARN )
1134 return 1;
1135 }
1136
1137 processedEntries++;
1138 emit progress( processedEntries * 100 / entryCount );
1139
1140 qApp->processEvents();
1141
1142 r = archive_write_finish_entry( ext );
1143 if ( r < ARCHIVE_OK )
1144 fprintf( stderr, "%s\n", archive_error_string( ext ) );
1145
1146 if ( r < ARCHIVE_WARN )
1147 return 1;
1148 }
1149
1150 archive_read_close( a );
1151 archive_read_free( a );
1152
1153 archive_write_close( ext );
1154 archive_write_free( ext );
1155
1156 return true;
1157 }
1158
1159 chdir( srcDir );
1160 };
1161
doExtractMember(QString memberName)1162 bool LibArchiveQt::doExtractMember( QString memberName ) {
1163
1164 listArchive();
1165
1166 if ( archiveType == Single )
1167 return doExtractMember( memberName );
1168
1169 // Change to the target directory
1170 char srcDir[ 10240 ] = { 0 };
1171 getcwd( srcDir, 10240 );
1172 chdir( dest.toUtf8().data() );
1173
1174 struct archive *a;
1175 struct archive *ext;
1176 struct archive_entry *entry;
1177 int flags;
1178 int r;
1179
1180 /* Select which attributes we want to restore. */
1181 flags = ARCHIVE_EXTRACT_TIME;
1182 flags |= ARCHIVE_EXTRACT_PERM;
1183 flags |= ARCHIVE_EXTRACT_ACL;
1184 flags |= ARCHIVE_EXTRACT_FFLAGS;
1185
1186 // Source Archive
1187 a = archive_read_new();
1188 archive_read_support_format_all( a );
1189 archive_read_support_filter_all( a );
1190
1191 // Structure to write files to disk
1192 ext = archive_write_disk_new();
1193 archive_write_disk_set_options( ext, flags );
1194 archive_write_disk_set_standard_lookup( ext );
1195
1196 r = archive_read_open_filename( a, archiveName.toUtf8().data(), 10240 );
1197 if ( r != ARCHIVE_OK ) {
1198 qDebug() << "[ERROR]: Failed to open archive:" << archiveName;
1199 return true;
1200 }
1201
1202 bool dir = false, found = false;
1203
1204 /* Direct member */
1205 Q_FOREACH( ArchiveEntry *ae, memberList ) {
1206 if ( ae->name == memberName ) {
1207 dir = ( ae->type == AE_IFDIR );
1208 found = true;
1209 break;
1210 }
1211
1212 if ( ae->name == memberName + "/" ) {
1213 memberName += "/";
1214 dir = ( ae->type == AE_IFDIR );
1215 found = true;
1216 break;
1217 }
1218 }
1219
1220 if ( not found ) {
1221 /* Always check for @memberName + "/" because, all indirect members will be directories */
1222 memberName += "/";
1223
1224 /* Indirect member: ex. debug/ is a member if debug/path/to/file.ext exists */
1225 Q_FOREACH( ArchiveEntry *ae, memberList ) {
1226 if ( ae->name.startsWith( memberName ) == 0 ) {
1227 dir = true;
1228 found = true;
1229 break;
1230 }
1231 }
1232 }
1233
1234 if ( found ) {
1235 while ( true ) {
1236 r = archive_read_next_header( a, &entry );
1237 if ( r == ARCHIVE_EOF )
1238 break;
1239
1240 if ( r < ARCHIVE_OK )
1241 fprintf( stderr, "%s\n", archive_error_string( a ) );
1242
1243 if ( r < ARCHIVE_WARN )
1244 return true;
1245
1246 QString entryPath = archive_entry_pathname( entry );
1247
1248 /* Check if the current entry starts with @memberName */
1249 if ( entryPath.startsWith( memberName ) ) {
1250 if ( not dir ) {
1251 if ( entryPath != memberName )
1252 continue;
1253 }
1254
1255 r = archive_write_header( ext, entry );
1256 if ( r < ARCHIVE_OK )
1257 fprintf( stderr, "%s\n", archive_error_string( ext ) );
1258
1259 else if ( archive_entry_size( entry ) > 0 ) {
1260 r = copyData( a, ext );
1261 if ( r < ARCHIVE_OK )
1262 fprintf( stderr, "%s\n", archive_error_string( ext ) );
1263
1264 if ( r < ARCHIVE_WARN )
1265 return false;
1266 }
1267
1268 r = archive_write_finish_entry( ext );
1269 if ( r < ARCHIVE_OK )
1270 fprintf( stderr, "%s\n", archive_error_string( ext ) );
1271
1272 if ( r < ARCHIVE_WARN )
1273 return false;
1274 }
1275 }
1276 }
1277
1278 else {
1279
1280 qDebug() << "[Error]" << "File not found in the archive:" << memberName;
1281 return false;
1282 }
1283
1284 archive_read_close( a );
1285 archive_read_free( a );
1286
1287 archive_write_close( ext );
1288 archive_write_free( ext );
1289
1290 chdir( srcDir );
1291
1292 return true;
1293 };
1294
copyData(struct archive * ar,struct archive * aw)1295 int LibArchiveQt::copyData( struct archive *ar, struct archive *aw ) {
1296
1297 int r;
1298 const void *buff;
1299 size_t size;
1300
1301 #ifdef __LP64__
1302 off_t offset;
1303 #else
1304 la_int64_t offset;
1305 #endif
1306
1307 while ( true ) {
1308 r = archive_read_data_block( ar, &buff, &size, &offset );
1309 if ( r == ARCHIVE_EOF )
1310 return ( ARCHIVE_OK );
1311
1312 if ( r < ARCHIVE_OK )
1313 return ( r );
1314
1315 r = archive_write_data_block( aw, buff, size, offset );
1316 if ( r < ARCHIVE_OK ) {
1317 fprintf( stderr, "%s\n", archive_error_string( aw ) );
1318 return ( r );
1319 }
1320 }
1321 };
1322
setFilterFormat(QMimeType mType)1323 void LibArchiveQt::setFilterFormat( QMimeType mType ) {
1324
1325 if ( mType == mimeDb.mimeTypeForFile( "file.cpio" ) ) {
1326 mArchiveFilter = ARCHIVE_FILTER_NONE;
1327 mArchiveFormat = ARCHIVE_FORMAT_CPIO;
1328 archiveType = Container;
1329 }
1330
1331 else if ( mType == mimeDb.mimeTypeForFile( "file.shar" ) ) {
1332 mArchiveFilter = ARCHIVE_FILTER_NONE;
1333 mArchiveFormat = ARCHIVE_FORMAT_SHAR;
1334 archiveType = Container;
1335 }
1336
1337 else if ( mType == mimeDb.mimeTypeForFile( "file.tar" ) ) {
1338 mArchiveFilter = ARCHIVE_FILTER_NONE;
1339 mArchiveFormat = ARCHIVE_FORMAT_TAR;
1340 archiveType = Container;
1341 }
1342
1343 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.gz" ) ) {
1344 mArchiveFilter = ARCHIVE_FILTER_GZIP;
1345 mArchiveFormat = ARCHIVE_FORMAT_TAR;
1346 archiveType = Container;
1347 }
1348
1349 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.grz" ) ) {
1350 mArchiveFilter = ARCHIVE_FILTER_GRZIP;
1351 mArchiveFormat = ARCHIVE_FORMAT_TAR;
1352 archiveType = Container;
1353 }
1354
1355 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.xz" ) ) {
1356 mArchiveFilter = ARCHIVE_FILTER_XZ;
1357 mArchiveFormat = ARCHIVE_FORMAT_TAR;
1358 archiveType = Container;
1359 }
1360
1361 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.lzo" ) ) {
1362 mArchiveFilter = ARCHIVE_FILTER_LZOP;
1363 mArchiveFormat = ARCHIVE_FORMAT_TAR;
1364 archiveType = Container;
1365 }
1366
1367 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.lzma" ) ) {
1368 mArchiveFilter = ARCHIVE_FILTER_LZMA;
1369 mArchiveFormat = ARCHIVE_FORMAT_TAR;
1370 archiveType = Container;
1371 }
1372
1373 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.lz" ) ) {
1374 mArchiveFilter = ARCHIVE_FILTER_LZIP;
1375 mArchiveFormat = ARCHIVE_FORMAT_TAR;
1376 archiveType = Container;
1377 }
1378
1379 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.lrz" ) ) {
1380 mArchiveFilter = ARCHIVE_FILTER_LRZIP;
1381 mArchiveFormat = ARCHIVE_FORMAT_TAR;
1382 archiveType = Container;
1383 }
1384
1385 #if ARCHIVE_VERSION_NUMBER > 3001002
1386 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.lz4" ) ) {
1387 mArchiveFilter = ARCHIVE_FILTER_LZ4;
1388 mArchiveFormat = ARCHIVE_FORMAT_TAR;
1389 archiveType = Container;
1390 }
1391 #endif
1392
1393 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.bz2" ) ) {
1394 mArchiveFilter = ARCHIVE_FILTER_BZIP2;
1395 mArchiveFormat = ARCHIVE_FORMAT_TAR;
1396 archiveType = Container;
1397 }
1398
1399 else if ( mType == mimeDb.mimeTypeForFile( "file.tar.Z" ) ) {
1400 mArchiveFilter = ARCHIVE_FILTER_COMPRESS;
1401 mArchiveFormat = ARCHIVE_FORMAT_TAR;
1402 archiveType = Container;
1403 }
1404
1405 else if ( mType == mimeDb.mimeTypeForFile( "file.iso" ) ) {
1406 mArchiveFilter = ARCHIVE_FILTER_NONE;
1407 mArchiveFormat = ARCHIVE_FORMAT_ISO9660;
1408 archiveType = Container;
1409 }
1410
1411 else if ( mType == mimeDb.mimeTypeForFile( "file.zip" ) ) {
1412 mArchiveFilter = ARCHIVE_FILTER_NONE;
1413 mArchiveFormat = ARCHIVE_FORMAT_ZIP;
1414 archiveType = Container;
1415 }
1416
1417 else if ( mType == mimeDb.mimeTypeForFile( "file.ar" ) ) {
1418 mArchiveFilter = ARCHIVE_FILTER_NONE;
1419 mArchiveFormat = ARCHIVE_FORMAT_AR;
1420 archiveType = Container;
1421 }
1422
1423 else if ( mType == mimeDb.mimeTypeForFile( "file.xar" ) ) {
1424 mArchiveFilter = ARCHIVE_FILTER_NONE;
1425 mArchiveFormat = ARCHIVE_FORMAT_XAR;
1426 archiveType = Container;
1427 }
1428
1429 else if ( mType == mimeDb.mimeTypeForFile( "file.7z" ) ) {
1430 mArchiveFilter = ARCHIVE_FILTER_NONE;
1431 mArchiveFormat = ARCHIVE_FORMAT_7ZIP;
1432 archiveType = Container;
1433 }
1434
1435 else if ( mType == mimeDb.mimeTypeForFile( "file.lz" ) ) {
1436 mArchiveFilter = ARCHIVE_FILTER_LZIP;
1437 mArchiveFormat = ARCHIVE_FORMAT_RAW;
1438 archiveType = Single;
1439 }
1440
1441 #if ARCHIVE_VERSION_NUMBER > 3001002
1442 else if ( mType == mimeDb.mimeTypeForFile( "file.lz4" ) ) {
1443 mArchiveFilter = ARCHIVE_FILTER_LZ4;
1444 mArchiveFormat = ARCHIVE_FORMAT_RAW;
1445 archiveType = Single;
1446 }
1447 #endif
1448
1449 else if ( mType == mimeDb.mimeTypeForFile( "file.uu" ) ) {
1450 mArchiveFilter = ARCHIVE_FILTER_UU;
1451 mArchiveFormat = ARCHIVE_FORMAT_RAW;
1452 archiveType = Single;
1453 }
1454
1455 else if ( mType == mimeDb.mimeTypeForFile( "file.lzo" ) ) {
1456 mArchiveFilter = ARCHIVE_FILTER_LZOP;
1457 mArchiveFormat = ARCHIVE_FORMAT_RAW;
1458 archiveType = Single;
1459 }
1460
1461 else if ( mType == mimeDb.mimeTypeForFile( "file.gz" ) ) {
1462 mArchiveFilter = ARCHIVE_FILTER_GZIP;
1463 mArchiveFormat = ARCHIVE_FORMAT_RAW;
1464 archiveType = Single;
1465 }
1466
1467 else if ( mType == mimeDb.mimeTypeForFile( "file.bz2" ) ) {
1468 mArchiveFilter = ARCHIVE_FILTER_BZIP2;
1469 mArchiveFormat = ARCHIVE_FORMAT_RAW;
1470 archiveType = Single;
1471 }
1472
1473 else if ( mType == mimeDb.mimeTypeForFile( "file.lzma" ) ) {
1474 mArchiveFilter = ARCHIVE_FILTER_LZMA;
1475 mArchiveFormat = ARCHIVE_FORMAT_RAW;
1476 archiveType = Single;
1477 }
1478
1479 else if ( mType == mimeDb.mimeTypeForFile( "file.xz" ) ) {
1480 mArchiveFilter = ARCHIVE_FILTER_XZ;
1481 mArchiveFormat = ARCHIVE_FORMAT_RAW;
1482 archiveType = Single;
1483 }
1484
1485 else {
1486 mArchiveFormat = ARCHIVE_FORMAT_EMPTY;
1487 mArchiveFilter = ARCHIVE_FILTER_NONE;
1488 archiveType = None;
1489 }
1490 };
1491