From e7c490162408134f20994e56cc3bec19e3cae927 Mon Sep 17 00:00:00 2001
From: Sebastião Guerra <sebastiao.luiz.guerra@gmail.com>
Date: Fri, 28 Aug 2026 16:52:07 -0300
Subject: Add Lzip archive support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add support for plain Lzip files and Lzip-compressed tar archives.

Detect the lzip executable and expose Lzip in archive configuration, packing, unpacking, testing, searching and archive browsing.

Handle plain .lz files through krarc. Route .tar.lz and .tlz archives through the tar TDEIO slave, matching the existing handling of other compressed tar formats.

Add the required MIME protocol mappings and migrate existing Krusader protocol configurations to the new Lzip mappings.

Based on and completing the Lzip support proposed in TDE/krusader#1.

Co-authored-by: Antonio Diaz Diaz <antonio@gnu.org>
Signed-off-by: Antonio Diaz Diaz <antonio@gnu.org>
Signed-off-by: Sebastião Guerra <sebastiao.luiz.guerra@gmail.com>
---
 doc/en/krusader/archives.docbook        |  2 +-
 doc/en/krusader/features.docbook        |  2 +-
 doc/en/krusader/introduction.docbook    |  4 +-
 doc/en/krusader/konfigurator.docbook    | 22 +++++++++-
 doc/en/krusader/vfs.docbook             |  2 +-
 doc/man/krusader.1                      |  4 +-
 src/app/Dialogs/packgui.cpp             |  1 +
 src/app/Konfigurator/kgarchives.cpp     |  4 +-
 src/app/Konfigurator/kgdependencies.cpp | 17 +++----
 src/app/Konfigurator/kggeneral.cpp      |  1 +
 src/app/Konfigurator/kgprotocols.cpp    | 78 ++++++++++++++++++++++++++++++++-
 src/app/Konfigurator/krresulttable.cpp  |  3 ++
 src/app/Panel/krbriefview.cpp           |  1 +
 src/app/Panel/krdetailedview.cpp        |  4 +-
 src/app/Panel/krviewitem.cpp            |  1 +
 src/app/Search/krsearchmod.cpp          |  3 +-
 src/app/VFS/arc_vfs.cpp                 | 43 +++++++++++++-----
 src/app/VFS/krarchandler.cpp            | 33 +++++++++++---
 src/app/defaults.h                      |  2 +
 src/krArc/krarc.cpp                     | 38 +++++++++++++---
 20 files changed, 222 insertions(+), 43 deletions(-)

diff --git a/doc/en/krusader/archives.docbook b/doc/en/krusader/archives.docbook
index 4cbd645..7288062 100644
--- a/doc/en/krusader/archives.docbook
+++ b/doc/en/krusader/archives.docbook
@@ -8,7 +8,7 @@
     <para>The &vfs-lnk; allows you to browse archives as
     if it was a directory. Currently &krusader; supports
     the following archives types: ace, arj, bzip2, deb, gzip, iso,
-    lha, rar, rpm, tar, zip and 7-zip and supports the following
+    lha, lzip, rar, rpm, tar, zip and 7-zip and supports the following
     passworded archives: arj, ace, rar and zip. Passwords can be
     stored in &tdewallet;. Please note that the archive
     support first needs to be properly 
diff --git a/doc/en/krusader/features.docbook b/doc/en/krusader/features.docbook
index b1a454c..6659caf 100644
--- a/doc/en/krusader/features.docbook
+++ b/doc/en/krusader/features.docbook
@@ -106,7 +106,7 @@
           <listitem>
             <para>Archive Handling: browsing, unpack, pack,
             testing. Supported &archives-lnk; : ace,
-            arj, bzip2, deb, gzip, iso, lha, rar, rpm, tar, zip and
+            arj, bzip2, deb, gzip, iso, lha, lzip, rar, rpm, tar, zip and
             7-zip.</para>
           </listitem>
           <listitem>
diff --git a/doc/en/krusader/introduction.docbook b/doc/en/krusader/introduction.docbook
index 3873d90..3cb3889 100644
--- a/doc/en/krusader/introduction.docbook
+++ b/doc/en/krusader/introduction.docbook
@@ -14,7 +14,7 @@
     module, viewer/editor, directory synchronization, file content
     comparisons, powerful batch renaming and much, much more.
     &krusader; supports archive formats: ace, arj, bzip2, deb, gzip, iso, lha,
-    rar, rpm, tar, zip and 7-zip and handles other
+    lzip, rar, rpm, tar, zip and 7-zip and handles other
     &tdeioslaves1-url; such as smb:// or fish://.</para>
     <para>&krusader; is almost completely customizable and therefore
     very user-friendly.</para>
@@ -95,7 +95,7 @@
     ISO,rpm,tar.gz) between these data sources/containers
     effortlessly. &krusader; currently supports VFSs for
     all popular and some specialized types of archives (ace, arj,
-    bzip2, gzip, iso, lha, rar, tar, zip and 7-zip), configuration
+    bzip2, gzip, iso, lha, lzip, rar, tar, zip and 7-zip), configuration
     packages (rpm, deb), and traditional remote file system types
     (&FTP;, NFS, Samba, FISH, SFTP).</para>
     <para>&krusader; also includes a built-in
diff --git a/doc/en/krusader/konfigurator.docbook b/doc/en/krusader/konfigurator.docbook
index ab23a78..170f0d4 100644
--- a/doc/en/krusader/konfigurator.docbook
+++ b/doc/en/krusader/konfigurator.docbook
@@ -1070,7 +1070,7 @@ HTML_PARSING-->
     certain archive is grayed-out, it means that
     &krusader; could not find the appropriate executables
     in the configured path. The next archives are supported: ace,
-    arj, bzip2, deb, gzip, iso, lha, rar, rpm, tar, zip and
+    arj, bzip2, deb, gzip, iso, lha, lzip, rar, rpm, tar, zip and
     7-zip.</para>
     <!-- OLD
 <screenshot>
@@ -1446,6 +1446,20 @@ HTML_PARSING-->
               </para>
             </entry>
           </row>
+          <row>
+            <entry>
+              <para>
+                <command>lzip</command>
+              </para>
+            </entry>
+            <entry>
+              <para>
+                <filename class="directory">
+                  <replaceable>/usr/bin/lzip</replaceable>
+                </filename>
+              </para>
+            </entry>
+          </row>
           <row>
             <entry>
               <para>
@@ -1874,6 +1888,9 @@ HTML_PARSING-->
           <listitem>
             <para>application/x-lha</para>
           </listitem>
+          <listitem>
+            <para>application/x-lzip</para>
+          </listitem>
           <listitem>
             <para>application/x-rar</para>
           </listitem>
@@ -1900,6 +1917,9 @@ HTML_PARSING-->
           <listitem>
             <para>application/x-tgz</para>
           </listitem>
+          <listitem>
+            <para>application/x-tlz</para>
+          </listitem>
         </itemizedlist>
       </listitem>
     </itemizedlist></para>
diff --git a/doc/en/krusader/vfs.docbook b/doc/en/krusader/vfs.docbook
index 8acb910..22ff092 100644
--- a/doc/en/krusader/vfs.docbook
+++ b/doc/en/krusader/vfs.docbook
@@ -26,7 +26,7 @@
       <para>
       <link linkend="archives">Archive VFS</link>: allows to browse
       archives in VFS as it was a directory (ace, arj, bzip2, deb,
-      gzip, iso, lha, rar, rpm, tar, zip and 7-zip).</para>
+      gzip, iso, lha, lzip, rar, rpm, tar, zip and 7-zip).</para>
     </listitem>
     <listitem>
       <para>
diff --git a/doc/man/krusader.1 b/doc/man/krusader.1
index 2d129e3..c04af55 100644
--- a/doc/man/krusader.1
+++ b/doc/man/krusader.1
@@ -13,7 +13,7 @@ mounted filesystem support, FTP, advanced search module,
 viewer/editor, directory synchronisation, file content comparisons,
 powerful batch renaming and much much more.
 It supports the following archive formats: ace, arj, bzip2, deb, 
-gzip, iso, lha, rar, rpm, tar, zip and 7-zip
+gzip, iso, lha, lzip, rar, rpm, tar, zip and 7-zip
 and can handle other KIOSlaves such as smb:// or fish://
 It is (almost) completely customizable, very user friendly,
 fast and looks great on your desktop! :-)
@@ -102,7 +102,7 @@ Powerful internal viewer and editor.
 
 Advanced search module that can search in archives.
      
-Supports: ace, arj, bzip2, deb, gzip, iso, lha, rar, rpm, tar, zip and 7-zip.
+Supports: ace, arj, bzip2, deb, gzip, iso, lha, lzip, rar, rpm, tar, zip and 7-zip.
 
 Directory comparison and filtering.
 
diff --git a/src/app/Dialogs/packgui.cpp b/src/app/Dialogs/packgui.cpp
index e479060..c374b4b 100644
--- a/src/app/Dialogs/packgui.cpp
+++ b/src/app/Dialogs/packgui.cpp
@@ -63,6 +63,7 @@ PackGUI::PackGUI(TQString defaultName, TQString defaultPath, int noOfFiles, TQSt
   if (PS("tar")) typeData->insertItem("tar");
   if (PS("tar") && PS("gzip")) typeData->insertItem("tar.gz");
   if (PS("tar") && PS("bzip2")) typeData->insertItem("tar.bz2");
+  if (PS("tar") && PS("lzip")) typeData->insertItem("tar.lz");
   if (PS("tar") && PS("xz")) typeData->insertItem("tar.xz");
   if (PS("zip")) typeData->insertItem("zip");
   if (PS("rar")) typeData->insertItem("rar");
diff --git a/src/app/Konfigurator/kgarchives.cpp b/src/app/Konfigurator/kgarchives.cpp
index 950aed1..9b1a4a8 100644
--- a/src/app/Konfigurator/kgarchives.cpp
+++ b/src/app/Konfigurator/kgarchives.cpp
@@ -59,6 +59,7 @@ KgArchives::KgArchives( bool first, TQWidget* parent,  const char* name ) :
     {{"Archives","Do Tar",   _DoTar,   i18n( "Tar" ),   false,  ""},
      {"Archives","Do GZip",  _DoGZip,  i18n( "GZip" ),  false,  ""},
      {"Archives","Do BZip2", _DoBZip2, i18n( "BZip2" ), false,  ""},
+     {"Archives","Do LZip",  _DoLZip,  i18n( "LZip" ),  false,  ""},
      {"Archives","Do UnZip", _DoUnZip, i18n( "Zip" ),   false,  ""},
      {"Archives","Do UnRar", _DoUnRar, i18n( "Rar" ),   false,  ""},
      {"Archives","Do Unarj", _DoArj,   i18n( "Arj" ),   false,  ""},
@@ -70,7 +71,7 @@ KgArchives::KgArchives( bool first, TQWidget* parent,  const char* name ) :
      {"Archives","Do Xz",    _DoXz,    i18n( "Xz" ),    false,  ""}
     };
 
-  cbs = createCheckBoxGroup( 3, 0, packers, 12, generalGrp );
+  cbs = createCheckBoxGroup( 3, 0, packers, 13, generalGrp );
   generalGrid->addWidget( cbs, 1, 0 );
 
   addLabel( generalGrid, 2, 0, i18n( "The archives that are \"greyed-out\" were unavailable on your\nsystem last time Krusader checked. If you wish Krusader to\nsearch again, click the 'Auto Configure' button." ),
@@ -126,6 +127,7 @@ void KgArchives::disableNonExistingPackers()
   cbs->find( "Do Tar" )->setEnabled(PS("tar"));
   cbs->find( "Do GZip" )->setEnabled(PS("gzip"));
   cbs->find( "Do BZip2" )->setEnabled(PS("bzip2"));
+  cbs->find( "Do LZip" )->setEnabled(PS("lzip"));
   cbs->find( "Do UnZip" )->setEnabled(PS("unzip"));
   cbs->find( "Do Lha" )->setEnabled(PS("lha"));
   cbs->find( "Do RPM" )->setEnabled(PS("rpm") || PS("cpio"));
diff --git a/src/app/Konfigurator/kgdependencies.cpp b/src/app/Konfigurator/kgdependencies.cpp
index b7f6f9f..6c466f9 100644
--- a/src/app/Konfigurator/kgdependencies.cpp
+++ b/src/app/Konfigurator/kgdependencies.cpp
@@ -86,14 +86,15 @@ KgDependencies::KgDependencies( bool first, TQWidget* parent,  const char* name
   addApplication( "dpkg",  archGrid1, 4, packers_tab, PAGE_PACKERS );
   addApplication( "gzip",  archGrid1, 5, packers_tab, PAGE_PACKERS );
   addApplication( "lha",   archGrid1, 6, packers_tab, PAGE_PACKERS );
-  addApplication( "rar",   archGrid1, 7, packers_tab, PAGE_PACKERS );
-  addApplication( "tar",   archGrid1, 8, packers_tab, PAGE_PACKERS );
-  addApplication( "unace", archGrid1, 9, packers_tab, PAGE_PACKERS );
-  addApplication( "unarj", archGrid1,10, packers_tab, PAGE_PACKERS );
-  addApplication( "unrar", archGrid1,11, packers_tab, PAGE_PACKERS );
-  addApplication( "unzip", archGrid1,12, packers_tab, PAGE_PACKERS );
-  addApplication( "zip",   archGrid1,13, packers_tab, PAGE_PACKERS );
-  addApplication( "xz",    archGrid1,14, packers_tab, PAGE_PACKERS );
+  addApplication( "lzip",  archGrid1, 7, packers_tab, PAGE_PACKERS );
+  addApplication( "rar",   archGrid1, 8, packers_tab, PAGE_PACKERS );
+  addApplication( "tar",   archGrid1, 9, packers_tab, PAGE_PACKERS );
+  addApplication( "unace", archGrid1,10, packers_tab, PAGE_PACKERS );
+  addApplication( "unarj", archGrid1,11, packers_tab, PAGE_PACKERS );
+  addApplication( "unrar", archGrid1,12, packers_tab, PAGE_PACKERS );
+  addApplication( "unzip", archGrid1,13, packers_tab, PAGE_PACKERS );
+  addApplication( "zip",   archGrid1,14, packers_tab, PAGE_PACKERS );
+  addApplication( "xz",    archGrid1,15, packers_tab, PAGE_PACKERS );
 
   //  ---------------------------- CHECKSUM TAB -------------------------------------
   TQWidget *checksum_tab = new TQWidget( tabWidget, "tab_4" );
diff --git a/src/app/Konfigurator/kggeneral.cpp b/src/app/Konfigurator/kggeneral.cpp
index 390b912..2614d0f 100644
--- a/src/app/Konfigurator/kggeneral.cpp
+++ b/src/app/Konfigurator/kggeneral.cpp
@@ -131,6 +131,7 @@ TQFrame *line2 = createLine( generalGrp, "line2" );
   TQStringList defaultAtomicExtensions;
   defaultAtomicExtensions += ".tar.gz";
   defaultAtomicExtensions += ".tar.bz2";
+  defaultAtomicExtensions += ".tar.lz";
   defaultAtomicExtensions += ".moc.cpp";
   defaultAtomicExtensions += ".tar.xz";
 
diff --git a/src/app/Konfigurator/kgprotocols.cpp b/src/app/Konfigurator/kgprotocols.cpp
index 1dcc81f..598b47d 100644
--- a/src/app/Konfigurator/kgprotocols.cpp
+++ b/src/app/Konfigurator/kgprotocols.cpp
@@ -49,13 +49,15 @@ TQString KgProtocols::defaultKrarcMimes = "application/x-7z,application/x-7z-com
                                          "application/x-debian-package,"
                                          "application/x-gzip,application/x-jar,"
                                          "application/x-lha,application/x-lha-compressed,"
+                                         "application/x-lzip,"
                                          "application/x-rar,"
                                          "application/x-rpm,"
                                          "application/x-xz,"
                                          "application/x-zip";
 TQString KgProtocols::defaultTarMimes  = "application/x-tar,application/x-tarz,"
                                          "application/x-compressed-tar,"
-                                         "application/x-tbz,application/x-tgz,application/x-txz";
+                                         "application/x-tbz,application/x-tgz,"
+                                         "application/x-tlz,application/x-txz";
 
 KgProtocols::KgProtocols( bool first, TQWidget* parent,  const char* name ) :
       KonfiguratorPage( first, parent, name )
@@ -406,14 +408,86 @@ bool KgProtocols::apply()
 
 void KgProtocols::init()
 {
+  const TQString lzipMigrationKey = "Lzip Tar Routing Initialized";
+
   if( !krConfig->groupList().contains( "Protocols" ) )
   {
     krConfig->setGroup( "Protocols" );
     krConfig->writeEntry( "Handled Protocols", defaultProtocols );
     krConfig->writeEntry( "Mimes For iso",     defaultIsoMimes );
     krConfig->writeEntry( "Mimes For krarc",   defaultKrarcMimes );
-	 krConfig->writeEntry( "Mimes For tar",     defaultTarMimes );
+    krConfig->writeEntry( "Mimes For tar",     defaultTarMimes );
+    krConfig->writeEntry( lzipMigrationKey, true );
+    return;
+  }
+
+  krConfig->setGroup( "Protocols" );
+
+  if( krConfig->readBoolEntry( lzipMigrationKey, false ) )
+    return;
+
+  TQStringList protList =
+      krConfig->readListEntry( "Handled Protocols" );
+
+  bool changed = false;
+
+  // tar.lz/tlz must use the tar TDEIO slave. Remove the mapping
+  // from krarc if it was present in an older configuration.
+  if( protList.contains( "krarc" ) )
+  {
+    TQStringList krarcMimes =
+        krConfig->readListEntry( "Mimes For krarc" );
+
+    if( krarcMimes.contains( "application/x-tlz" ) )
+    {
+      krarcMimes.remove( "application/x-tlz" );
+      krConfig->writeEntry( "Mimes For krarc", krarcMimes );
+      changed = true;
+    }
   }
+
+  bool lzipMapped = false;
+  bool tlzMapped = false;
+
+  for( TQStringList::Iterator it = protList.begin();
+       it != protList.end(); ++it )
+  {
+    TQStringList mimes =
+        krConfig->readListEntry(
+            TQString( "Mimes For %1" ).arg( *it ) );
+
+    if( mimes.contains( "application/x-lzip" ) )
+      lzipMapped = true;
+
+    if( mimes.contains( "application/x-tlz" ) )
+      tlzMapped = true;
+  }
+
+  // Preserve custom mappings. Only add a MIME type when it is
+  // currently not assigned to any handled protocol.
+  if( !lzipMapped && protList.contains( "krarc" ) )
+  {
+    TQStringList mimes =
+        krConfig->readListEntry( "Mimes For krarc" );
+    mimes.append( "application/x-lzip" );
+    krConfig->writeEntry( "Mimes For krarc", mimes );
+    changed = true;
+  }
+
+  if( !tlzMapped && protList.contains( "tar" ) )
+  {
+    TQStringList mimes =
+        krConfig->readListEntry( "Mimes For tar" );
+    mimes.append( "application/x-tlz" );
+    krConfig->writeEntry( "Mimes For tar", mimes );
+    changed = true;
+  }
+
+  krConfig->writeEntry( lzipMigrationKey, true );
+  krConfig->sync();
+
+  if( changed )
+    KrServices::clearProtocolCache();
 }
 
 #include "kgprotocols.moc"
diff --git a/src/app/Konfigurator/krresulttable.cpp b/src/app/Konfigurator/krresulttable.cpp
index 4a11213..2679d15 100644
--- a/src/app/Konfigurator/krresulttable.cpp
+++ b/src/app/Konfigurator/krresulttable.cpp
@@ -102,6 +102,7 @@ KrArchiverResultTable::KrArchiverResultTable(TQWidget* parent)
   Archiver* tar   = new Archiver("tar",   "http://www.gnu.org",      		PS("tar"),   true,  true);
   Archiver* gzip  = new Archiver("gzip",  "http://www.gnu.org",      		PS("gzip"),  true,  true);
   Archiver* bzip2 = new Archiver("bzip2", "http://www.gnu.org",      		PS("bzip2"), true,  true);
+  Archiver* lzip  = new Archiver("lzip",  "http://www.nongnu.org/lzip/lzip.html", PS("lzip"),  true,  true);
   Archiver* lha   = new Archiver("lha",   "http://www.gnu.org",      		PS("lha"),   true,  true);
   Archiver* zip   = new Archiver("zip",   "http://www.info-zip.org", 		PS("zip"),   true,  false);
   Archiver* unzip = new Archiver("unzip", "http://www.info-zip.org", 		PS("unzip"), false, true);
@@ -139,6 +140,7 @@ KrArchiverResultTable::KrArchiverResultTable(TQWidget* parent)
   addRow(tar, _grid);
   addRow(gzip, _grid);
   addRow(bzip2, _grid);
+  addRow(lzip, _grid);
   addRow(lha, _grid);
   addRow(zip, _grid);
   addRow(unzip, _grid);
@@ -155,6 +157,7 @@ KrArchiverResultTable::KrArchiverResultTable(TQWidget* parent)
   delete tar;
   delete gzip;
   delete bzip2;
+  delete lzip;
   delete lha;
   delete zip;
   delete unzip;
diff --git a/src/app/Panel/krbriefview.cpp b/src/app/Panel/krbriefview.cpp
index 687dc17..bc24b0b 100644
--- a/src/app/Panel/krbriefview.cpp
+++ b/src/app/Panel/krbriefview.cpp
@@ -1318,6 +1318,7 @@ void KrBriefView::initProperties() {
 	TQStringList defaultAtomicExtensions;
 	defaultAtomicExtensions += ".tar.gz";
 	defaultAtomicExtensions += ".tar.bz2";
+	defaultAtomicExtensions += ".tar.lz";
 	defaultAtomicExtensions += ".moc.cpp";
 	defaultAtomicExtensions += ".tar.xz";
 	TQStringList atomicExtensions = krConfig->readListEntry("Atomic Extensions", defaultAtomicExtensions);
diff --git a/src/app/Panel/krdetailedview.cpp b/src/app/Panel/krdetailedview.cpp
index c8c9bbb..929184c 100644
--- a/src/app/Panel/krdetailedview.cpp
+++ b/src/app/Panel/krdetailedview.cpp
@@ -1029,7 +1029,8 @@ void KrDetailedView::keyPressEvent( TQKeyEvent * e ) {
 
                if( KRarcHandler::arcSupported( type ) ) {
                  KURL url = i->VF->vfile_getUrl();
-                 if( type == "-tar" || type == "-tgz" || type == "-tbz" )
+                 if( type == "-tar" || type == "-tgz" ||
+                     type == "-tbz" || type == "-tlz" )
                    url.setProtocol( "tar" );
                  else
                    url.setProtocol( "krarc" );
@@ -1413,6 +1414,7 @@ void KrDetailedView::initProperties() {
 	TQStringList defaultAtomicExtensions;
 	defaultAtomicExtensions += ".tar.gz";
 	defaultAtomicExtensions += ".tar.bz2";
+	defaultAtomicExtensions += ".tar.lz";
 	defaultAtomicExtensions += ".moc.cpp";
 	defaultAtomicExtensions += ".tar.xz";
 	TQStringList atomicExtensions = krConfig->readListEntry("Atomic Extensions", defaultAtomicExtensions);
diff --git a/src/app/Panel/krviewitem.cpp b/src/app/Panel/krviewitem.cpp
index cdb9ed9..4f4fcb4 100644
--- a/src/app/Panel/krviewitem.cpp
+++ b/src/app/Panel/krviewitem.cpp
@@ -11,6 +11,7 @@
 TQString atomicExtensions[] = {
 	".tar.gz",
 	".tar.bz2",
+	".tar.lz",
 	".moc.cpp",
 	".tar.xz",
 };
diff --git a/src/app/Search/krsearchmod.cpp b/src/app/Search/krsearchmod.cpp
index 3198197..2a69185 100644
--- a/src/app/Search/krsearchmod.cpp
+++ b/src/app/Search/krsearchmod.cpp
@@ -173,7 +173,8 @@ void KRSearchMod::scanLocalDir( KURL urlToScan )
         TQString realType = KRarcHandler::getType( encrypted, url.path(), mime );
 
         if( !encrypted ) {
-          if ( realType == "-tbz" || realType == "-tgz" || realType == "tarz" || realType == "-tar" )
+          if ( realType == "-tbz" || realType == "-tgz" || realType == "-tlz" ||
+               realType == "tarz" || realType == "-tar" )
             archiveURL.setProtocol( "tar" );
           else
             archiveURL.setProtocol( "krarc" );
diff --git a/src/app/VFS/arc_vfs.cpp b/src/app/VFS/arc_vfs.cpp
index 809868c..d883bdc 100644
--- a/src/app/VFS/arc_vfs.cpp
+++ b/src/app/VFS/arc_vfs.cpp
@@ -102,6 +102,15 @@ arc_vfs::arc_vfs(TQString origin,TQString type,TQObject* panel,bool write):
 		ignoreLines = -1;
     isWritable = false;
   }
+  if( type == "lzip" ){
+    cmd = KrServices::fullPathName ( "lzip" );
+    listCmd = " -l ";
+    delCmd  = "";
+    addCmd  = cmd + " -c ";
+    getCmd  = " -dc ";
+    ignoreLines = -1;
+    isWritable = false;
+  }
   if(type == "-tar"){
     cmd = KrServices::fullPathName( "tar" );
     listCmd = " -tvf";
@@ -124,6 +133,14 @@ arc_vfs::arc_vfs(TQString origin,TQString type,TQObject* panel,bool write):
     addCmd  = cmd+" -uvjf";
     getCmd  = " -xjvf";
     isWritable = false;
+  }
+  if(type == "-tlz"){
+    cmd = KrServices::fullPathName( "tar" );
+    listCmd = " -tvf";		// tar detects format automatically
+    delCmd  = "";
+    addCmd  = "";		// compressed tar archives can't be modified
+    getCmd  = " -xvf";
+    isWritable = false;
   }
 	if(type == "-zip"){
     password = KRarcHandler::getPassword(arcFile,type);
@@ -233,7 +250,7 @@ bool arc_vfs::getDirs(){
     temp.open(IO_ReadOnly);
     char buf[1000];
     TQString line;
-    if(vfs_type == "gzip" || vfs_type == "-zip" )
+    if( vfs_type == "gzip" || vfs_type == "lzip" || vfs_type == "-zip" )
       temp.readLine(line,10000);  // skip the first line - it's garbage
     if( vfs_type == "-rar" ){
       while(temp.readLine(line,10000) != -1)
@@ -399,7 +416,8 @@ KURL::List* arc_vfs::vfs_getFiles(TQStringList* names){
             krApp, TQ_SLOT(incProgress(TDEProcess*,char*,int)) );
 		
 		proc << cmd << getCmd << "\""+arcFile+"\"";
-  	if( vfs_type == "gzip" || vfs_type == "zip2" ) proc << ">";
+	if( vfs_type == "gzip" || vfs_type == "zip2" || vfs_type == "lzip" )
+	    proc << ">";
 		for(unsigned int i=0 ; i < files.count() ; ){
   		proc << (prefix+*files.at(i++));
 			if ( i%MAX_FILES==0 || i==files.count() ){
@@ -595,7 +613,8 @@ void arc_vfs::repack(){
 	}
 
   // finaly repack tmpDir
-  if( vfs_isWritable() || vfs_type=="gzip" || vfs_type=="zip2" ){
+  if( vfs_isWritable() || vfs_type == "gzip" ||
+      vfs_type == "zip2" || vfs_type == "lzip" ){
     TQStringList filesToPack;
 		getFilesToPack(&filesToPack);
 		if( !filesToPack.isEmpty() ){
@@ -604,7 +623,7 @@ void arc_vfs::repack(){
     	connect(&addProc,TQ_SIGNAL(receivedStdout(TDEProcess*,char*,int)),
             krApp, TQ_SLOT(incProgress(TDEProcess*,char*,int)) );
 
-			if( vfs_type=="gzip" || vfs_type=="zip2" ){
+    if( vfs_type == "gzip" || vfs_type == "zip2" || vfs_type == "lzip" ){
       	addProc << addCmd << *filesToPack.at(0)<< ">" << "\""+arcFile+"\"";
 				addProc.start(TDEProcess::NotifyOnExit);
       	while( addProc.isRunning() ) tqApp->processEvents();
@@ -752,16 +771,19 @@ void arc_vfs::parseLine(TQString line, TQFile* temp){
   mode_t mode = 0;
 
 
-  // parse gziped files
-  if(vfs_type == "gzip"){
+  // parse gziped and lzipped files
+  if( vfs_type == "gzip" || vfs_type == "lzip" ) {
     KDE_struct_stat stat_p;
     KDE_stat(arcFile.local8Bit(),&stat_p);
 
-    nextWord(line);
-    size = nextWord(line).toLong();
-    nextWord(line);
+    if( vfs_type == "gzip" ) nextWord(line);	// gzip compressed size
+    size = nextWord(line).toLong();		// uncompressed size
+    if( vfs_type == "lzip" ) nextWord(line);	// lzip compressed size
+    nextWord(line);				// ratio or saved
     name = nextWord(line,'\n');
     if(name.contains('/')) name = name.mid(name.findRev('/')+1,name.length());
+    if( vfs_type == "lzip" && name.endsWith(".lz") )
+      name.truncate(name.length() - 3);
     perm  = KRpermHandler::mode2TQString(stat_p.st_mode) ;
     owner = KRpermHandler::user2uid(qfi.owner());
     group = KRpermHandler::group2gid(qfi.group());
@@ -783,7 +805,8 @@ void arc_vfs::parseLine(TQString line, TQFile* temp){
   }
 
   // parse tar files
-  if(vfs_type == "-tar" || vfs_type == "-tbz" || vfs_type == "-tgz" ){
+  if(vfs_type == "-tar" || vfs_type == "-tbz" ||
+     vfs_type == "-tgz" || vfs_type == "-tlz" ){
     perm = nextWord(line);
     TQString temp = nextWord(line);
     owner = temp.left(temp.findRev('/')).toInt();
diff --git a/src/app/VFS/krarchandler.cpp b/src/app/VFS/krarchandler.cpp
index dd68310..06818ab 100644
--- a/src/app/VFS/krarchandler.cpp
+++ b/src/app/VFS/krarchandler.cpp
@@ -46,7 +46,7 @@
 #include "../krservices.h"
 #include "../Dialogs/krpleasewait.h"
 
-static TQStringList arcProtocols = TQStringList::split(";", "tar;bzip;bzip2;gzip;krarc;zip;xz");
+static TQStringList arcProtocols = TQStringList::split(";", "tar;bzip;bzip2;gzip;krarc;lzip;zip;xz");
 
 TDEWallet::Wallet * KRarcHandler::wallet = 0;
 
@@ -57,6 +57,7 @@ TQStringList KRarcHandler::supportedPackers() {
   if ( KrServices::cmdExist( "tar" ) ) packers.append( "tar" );
   if ( KrServices::cmdExist( "gzip" ) ) packers.append( "gzip" );
   if ( KrServices::cmdExist( "bzip2" ) ) packers.append( "bzip2" );
+  if ( KrServices::cmdExist( "lzip" ) ) packers.append( "lzip" );
   if ( KrServices::cmdExist( "unzip" ) ) packers.append( "unzip" );
   if ( KrServices::cmdExist( "zip" ) ) packers.append( "zip" );
   if ( KrServices::cmdExist( "lha" ) ) packers.append( "lha" );
@@ -91,6 +92,8 @@ bool KRarcHandler::arcSupported( TQString type ) {
     return true;
   else if ( type == "-tgz" && lst.contains( "tar" ) )
     return true;
+  else if ( type == "-tlz" && lst.contains( "tar" ) )
+    return true;
   else if ( type == "-txz" && lst.contains( "tar" ) )
     return true;
   else if ( type == "tarz" && lst.contains( "tar" ) )
@@ -99,6 +102,8 @@ bool KRarcHandler::arcSupported( TQString type ) {
     return true;
   else if ( type == "zip2" && lst.contains( "bzip2" ) )
     return true;
+  else if ( type == "lzip" && lst.contains( "lzip" ) )
+    return true;
   else if ( type == "-lha" && lst.contains( "lha" ) )
     return true;
   else if ( type == "-ace" && lst.contains( "unace" ) )
@@ -130,9 +135,11 @@ bool KRarcHandler::arcHandled( TQString type ) {
        ( type == "tarz" && krConfig->readBoolEntry( "Do GZip" , _DoGZip ) ) ||
        ( type == "-tar" && krConfig->readBoolEntry( "Do Tar"  , _DoTar ) ) ||
        ( type == "-tbz" && krConfig->readBoolEntry( "Do BZip2", _DoBZip2 ) ) ||
+       ( type == "-tlz" && krConfig->readBoolEntry( "Do LZip" , _DoLZip ) ) ||
        ( type == "-txz" && krConfig->readBoolEntry( "Do Xz"   , _DoXz ) ) ||
        ( type == "gzip" && krConfig->readBoolEntry( "Do GZip" , _DoGZip ) ) ||
        ( type == "zip2" && krConfig->readBoolEntry( "Do BZip2", _DoBZip2 ) ) ||
+       ( type == "lzip" && krConfig->readBoolEntry( "Do LZip" , _DoLZip ) ) ||
        ( type == "-zip" && krConfig->readBoolEntry( "Do UnZip", _DoUnZip ) ) ||
        ( type == "-lha" && krConfig->readBoolEntry( "Do Lha"  , _DoUnZip ) ) ||
        ( type == "-rar" && krConfig->readBoolEntry( "Do UnRar", _DoUnRar ) ) ||
@@ -155,8 +162,9 @@ long KRarcHandler::arcFileCount( TQString archive, TQString type, TQString passw
   // first check if supported
   if ( !arcSupported( type ) ) return 0;
 
-  // bzip, gzip and xz archives contain only one file
-  if ( type == "zip2" || type == "gzip" || type == "-xz") return 1L;
+  // bzip, gzip, lzip and xz archives contain only one file
+  if ( type == "zip2" || type == "gzip" || type == "lzip" || type == "-xz" )
+    return 1L;
 
   // set the right lister to do the job
   TQString lister;
@@ -166,6 +174,7 @@ long KRarcHandler::arcFileCount( TQString archive, TQString type, TQString passw
   else if ( type == "-tgz" ) lister = KrServices::fullPathName( "tar" ) + " -tvzf";
   else if ( type == "tarz" ) lister = KrServices::fullPathName( "tar" ) + " -tvzf";
   else if ( type == "-tbz" ) lister = KrServices::fullPathName( "tar" ) + " -tjvf";
+  else if ( type == "-tlz" ) lister = KrServices::fullPathName( "tar" ) + " -tvf";
   else if ( type == "-txz" ) lister = KrServices::fullPathName( "tar" ) + " -tJvf";
   else if ( type == "-lha" ) lister = KrServices::fullPathName( "lha" ) + " l";
   else if ( type == "-rar" ) lister = KrServices::fullPathName( KrServices::cmdExist( "rar" ) ? "rar" : "unrar" ) + " l -v";
@@ -250,9 +259,11 @@ bool KRarcHandler::unpack( TQString archive, TQString type, TQString password, T
   else if ( type == "-tgz" ) packer = KrServices::fullPathName( "tar" ) + " -xvzf";
   else if ( type == "tarz" ) packer = KrServices::fullPathName( "tar" ) + " -xvzf";
   else if ( type == "-tbz" ) packer = KrServices::fullPathName( "tar" ) + " -xjvf";
+  else if ( type == "-tlz" ) packer = KrServices::fullPathName( "tar" ) + " -xvf";
   else if ( type == "-txz" ) packer = KrServices::fullPathName( "tar" ) + " -xJvf";
   else if ( type == "gzip" ) packer = KrServices::fullPathName( "gzip" ) + " -cd";
   else if ( type == "zip2" ) packer = KrServices::fullPathName( "bzip2" ) + " -cdk";
+  else if ( type == "lzip" ) packer = KrServices::fullPathName( "lzip" ) + " -cd";
   else if ( type == "-lha" ) packer = KrServices::fullPathName( "lha" ) + " xf";
   else if ( type == "-rar" ) packer = KrServices::fullPathName( KrServices::cmdExist( "rar" ) ? "rar" : "unrar" ) + " -y x";
   else if ( type == "-ace" ) packer = KrServices::fullPathName( "unace" ) + " x";
@@ -309,7 +320,7 @@ bool KRarcHandler::unpack( TQString archive, TQString type, TQString password, T
   // unpack the files
   KrShellProcess proc;
   proc << packer << " " + KrServices::quote( archive );
-  if( type == "zip2" || type=="gzip" ){
+  if( type == "zip2" || type=="gzip" || type=="lzip" ){
     TQString arcname = archive.mid(archive.findRev("/")+1);
     if( arcname.contains(".") ) arcname = arcname.left(arcname.findRev("."));
     proc << ">" << KrServices::quote( dest+"/"+arcname );
@@ -365,9 +376,11 @@ bool KRarcHandler::test( TQString archive, TQString type, TQString password, lon
   else if ( type == "-tgz" ) packer = KrServices::fullPathName( "tar" ) + " -tvzf";
   else if ( type == "tarz" ) packer = KrServices::fullPathName( "tar" ) + " -tvzf";
   else if ( type == "-tbz" ) packer = KrServices::fullPathName( "tar" ) + " -tjvf";
+  else if ( type == "-tlz" ) packer = KrServices::fullPathName( "tar" ) + " -tvf";
   else if ( type == "-txz" ) packer = KrServices::fullPathName( "tar" ) + " -tJvf";
   else if ( type == "gzip" ) packer = KrServices::fullPathName( "gzip" ) + " -tv";
   else if ( type == "zip2" ) packer = KrServices::fullPathName( "bzip2" ) + " -tv";
+  else if ( type == "lzip" ) packer = KrServices::fullPathName( "lzip" ) + " -tv";
   else if ( type == "-rar" ) packer = KrServices::fullPathName( KrServices::cmdExist( "rar" ) ? "rar" : "unrar" ) + " t";
   else if ( type == "-ace" ) packer = KrServices::fullPathName( "unace" ) + " t";
   else if ( type == "-lha" ) packer = KrServices::fullPathName( "lha" ) + " t";
@@ -424,6 +437,7 @@ bool KRarcHandler::pack( TQStringList fileNames, TQString type, TQString dest, l
   else if ( type == "tar" ) { packer = KrServices::fullPathName( "tar" ) + " -cvf"; type = "-tar"; }
   else if ( type == "tar.gz" ) { packer = KrServices::fullPathName( "tar" ) + " -cvzf"; type = "-tgz"; }
   else if ( type == "tar.bz2" ) { packer = KrServices::fullPathName( "tar" ) + " -cvjf"; type = "-tbz"; }
+  else if ( type == "tar.lz" ) { packer = KrServices::fullPathName( "tar" ) + " -cv --lzip -f"; type = "-tlz"; }
   else if ( type == "tar.xz" ) { packer = KrServices::fullPathName( "tar" ) + " -cvJf"; type = "-txz"; }
   else if ( type == "rar" ) { packer = KrServices::fullPathName( "rar" ) + " -r a"; type = "-rar"; }
   else if ( type == "lha" ) { packer = KrServices::fullPathName( "lha" ) + " a"; type = "-lha"; }
@@ -604,6 +618,8 @@ bool KRarcHandler::isArchive(const KURL& url) {
 
 TQString KRarcHandler::getType( bool &encrypted, TQString fileName, TQString mime, bool checkEncrypted ) {
 	TQString result = detectArchive( encrypted, fileName, checkEncrypted );
+
+
 	if( result.isNull() )
 		result = mime;
 	else
@@ -627,7 +643,7 @@ bool KRarcHandler::checkStatus( TQString type, int exitCode ) {
 		return exitCode == 0 || exitCode == 1;
 	else if( type == "-ace" || type == "zip2" || type == "-lha" || type == "-rpm" || type == "cpio" ||
 	         type == "-tar" || type == "tarz" || type == "-tbz" || type == "-tgz" || type == "-arj" ||
-	         type == "-deb" || type == "-txz")
+	         type == "lzip" || type == "-tlz" || type == "-deb" || type == "-txz" )
 		return exitCode == 0;
 	else if (type == "gzip" || type == "-xz")
 		return exitCode == 0 || exitCode == 2;
@@ -649,6 +665,7 @@ TQString KRarcHandler::detectArchive( bool &encrypted, TQString fileName, bool c
 	                                              {"ace",  7, "**ACE**" },
 	                                              {"bzip2",0, "\x42\x5a\x68?\x31" },
 	                                              {"gzip", 0, "\x1f\x8b"},
+	                                              {"lzip", 0, "\x4c\x5a\x49\x50\x01" },
 	                                              {"deb",  0, "!<arch>\ndebian-binary   " },
 	                                              {"7z",   0, "7z\xbc\xaf\x27\x1c" },
 	                                              {"xz",   0, "\xfd" "7zXZ\x00" } };
@@ -680,14 +697,16 @@ TQString KRarcHandler::detectArchive( bool &encrypted, TQString fileName, bool c
 
 			if( j == detectionString.length() ) {
 				TQString type = autoDetectParams[ i ].type;
-				if( type == "bzip2" || type == "gzip" ) {
+				if( type == "bzip2" || type == "gzip" || type == "lzip" ) {
 					KTar tapeArchive( fileName );
 					if( tapeArchive.open( IO_ReadOnly ) ) {
 						tapeArchive.close();
 						if( type == "bzip2" )
 							type = "tbz";
-						else
+						else if( type == "gzip" )
 							type = "tgz";
+						else
+							type = "tlz";
 					}
 				}
 				else if( type == "zip" )
diff --git a/src/app/defaults.h b/src/app/defaults.h
index 55dacf4..036ea11 100644
--- a/src/app/defaults.h
+++ b/src/app/defaults.h
@@ -173,6 +173,8 @@
 #define _DoUnZip       true
 // Do BZip2 ///////////
 #define _DoBZip2       true
+// Do LZip ////////////
+#define _DoLZip        true
 // Do Rar /////////////
 #define _DoRar         true
 // Do UnRar ///////////
diff --git a/src/krArc/krarc.cpp b/src/krArc/krarc.cpp
index 1160748..6eb3bfc 100644
--- a/src/krArc/krarc.cpp
+++ b/src/krArc/krarc.cpp
@@ -313,7 +313,9 @@ void tdeio_krarcProtocol::get(const KURL& url, int tries ){
 		KMimeType::Ptr mt = KMimeType::findByURL( arcTempDir+file, 0, false /* NOT local URL */ );
 		emit mimeType( mt->name() );
 		proc << getCmd << convertName( arcFile->url().path() )+" ";
-		if( arcType != "gzip" && arcType != "bzip2" && arcType != "xz") proc << convertFileName( file );
+		if( arcType != "gzip" && arcType != "bzip2" &&
+		    arcType != "lzip" && arcType != "xz" )
+			proc << convertFileName( file );
 		connect(&proc,TQ_SIGNAL(receivedStdout(TDEProcess*,char*,int)),
 				this,TQ_SLOT(receivedData(TDEProcess*,char*,int)) );
 	}
@@ -324,7 +326,8 @@ void tdeio_krarcProtocol::get(const KURL& url, int tries ){
 
 	if( !extArcReady && !decompressToFile ) {
 		if( !proc.normalExit() || !checkStatus( proc.exitStatus() ) ||
-		   ( arcType != "bzip2" && arcType != "xz" && expectedSize != decompressedLen ) ) {
+		   ( arcType != "bzip2" && arcType != "lzip" &&
+		     arcType != "xz" && expectedSize != decompressedLen ) ) {
 			if( encrypted && tries ) {
 				invalidatePassword();
 				get( url, tries - 1 );
@@ -675,6 +678,7 @@ bool tdeio_krarcProtocol::setArcFile(const KURL& url){
 	arcPath = arcFile->url().path(-1);
 	arcType = detectArchive( encrypted, arcPath );
 
+
 	if( arcType == "tbz" )
 		arcType = "bzip2";
 	else if( arcType == "tgz" )
@@ -707,7 +711,7 @@ bool tdeio_krarcProtocol::initDirDict(const KURL&url, bool forced){
 	KrShellProcess proc;
 	KTempFile temp( TQString(), "tmp" );
 	temp.setAutoDelete(true);
-	if (arcType != "bzip2" && arcType != "xz") {
+	if( arcType != "bzip2" && arcType != "xz" ) {
 		if( arcType == "rpm" )
 			proc << listCmd << convertName( arcPath ) <<" > " << temp.name();
 		else
@@ -739,7 +743,7 @@ bool tdeio_krarcProtocol::initDirDict(const KURL&url, bool forced){
 
 	root->append(entry);
 
-	if (arcType == "bzip2" || arcType == "xz"){
+	if( arcType == "bzip2" || arcType == "xz" ) {
 		KRDEBUG("Got me here...");
 		parseLine(0,"",temp.file());
 		return true;
@@ -1062,6 +1066,21 @@ void tdeio_krarcProtocol::parseLine(int lineNo, TQString line, TQFile*) {
 		mode = arcFile->mode();
 		size = arcFile->size();
 	}
+	if( arcType == "lzip" ){
+		if( !lineNo ) return; // ignore the column headings from lzip -l
+
+		// lzip reports the uncompressed size in the first column. Use it
+		// instead of the size of the .lz container. The listing is also
+		// correct for multimember files.
+		TQString sizeString = nextWord(line);
+		sizeString.remove('_');
+		size = strtoull(sizeString.latin1(), 0, 10);
+
+		fullName = arcFile->name();
+		if( fullName.endsWith(".lz") )
+			fullName.truncate(fullName.length() - 3);
+		mode = arcFile->mode();
+	}
 	if(arcType == "lha"){
 		// permissions
 		perm = nextWord(line);
@@ -1311,6 +1330,13 @@ bool tdeio_krarcProtocol::initArcParameters() {
 		copyCmd = TQString();
 		delCmd  = TQString();
 		putCmd  = TQString();
+	} else if(arcType == "lzip") {
+		cmd     = fullPathName( "lzip" );
+		listCmd = cmd + " -l";
+		getCmd  = cmd + " -dc";
+		copyCmd = TQString();
+		delCmd  = TQString();
+		putCmd  = TQString();
 	} else if(arcType == "arj"){
 		cmd     = fullPathName( "arj" );
 		listCmd = fullPathName( "arj" ) + " v -y -v ";
@@ -1398,7 +1424,8 @@ bool tdeio_krarcProtocol::checkStatus( int exitCode ) {
 
 	if( arcType == "zip" || arcType == "rar" || arcType == "7z" )
 		return exitCode == 0 || exitCode == 1;
-	else if( arcType == "ace" || arcType == "bzip2" || arcType == "lha" || arcType == "rpm" || arcType == "arj" )
+	else if( arcType == "ace" || arcType == "bzip2" || arcType == "lha" ||
+	         arcType == "lzip" || arcType == "rpm" || arcType == "arj" )
 		return exitCode == 0;
 	else if( arcType == "gzip"|| arcType == "xz" )
 		return exitCode == 0 || exitCode == 2;
@@ -1420,6 +1447,7 @@ TQString tdeio_krarcProtocol::detectArchive( bool &encrypted, TQString fileName
 	                                              {"ace",  7, "**ACE**" },
 	                                              {"bzip2",0, "\x42\x5a\x68?\x31" },
 	                                              {"gzip", 0, "\x1f\x8b"},
+	                                              {"lzip", 0, "\x4c\x5a\x49\x50\x01" },
 	                                              {"deb",  0, "!<arch>\ndebian-binary   " },
 	                                              {"7z",   0, "7z\xbc\xaf\x27\x1c" },
 	                                              {"xz",   0, "\xfd" "7zXZ\x00"} };
-- 
cgit v1.2.3

