[file-roller/wip/jtojnar/7zip] Add support for the official 7-Zip project




commit 02e997a3c7d6c9d4fd7b74c37da7a1cd587bb29b
Author: Jan Tojnar <jtojnar gmail com>
Date:   Mon Jun 20 23:33:47 2022 +0200

    Add support for the official 7-Zip project
    
    Quoting from the project’s README:
    
        Now there are two different ports of 7-Zip for Linux/macOS:
    
        1) p7zip - another port of 7-Zip for Linux, made by an independent developer.
           The latest version of p7zip now is 16.02, and that p7zip 16.02 is outdated now.
    
        2) 7-Zip for Linux/macOS - this package - it's new code with all changes from latest 7-Zip for 
Windows.
    
        These two ports are not identical.
        Note also that some Linux specific things can be implemented better in p7zip than in new 7-Zip for 
Linux.
    
        There are several main executables in 7-Zip and p7zip:
    
            7zz  (7-Zip) - standalone full version of 7-Zip that supports all formats.
    
            7zzs (7-Zip) - standalone full version of 7-Zip that supports all formats (static library 
linking).
    
            7z  (p7zip) - 7-Zip that requires 7z.so shared library, and it supports all formats via 7z.so.
    
            7zr (p7zip) - standalone reduced version of 7-Zip that supports some 7-Zip's formats:
                          7z, xz, lzma and split.
    
            7za (p7zip) - standalone version of 7-Zip that supports some main formats:
                          7z, xz, lzma, zip, bzip2, gzip, tar, cab, ppmd and split.
    
        7zzs is similar to 7zz, but 7zzs was compiled for static library linking,
        so 7zzs does not use external shared library (".so") files.
        You can use 7zzs, if 7zz does not work due to lack of required shared library (".so") files.
    
        The command line syntax for executables from p7zip is similar to 7zz syntax from this package.
    
    This change also renames the package names for PackageKit integration. If a distro wants File-Roller to 
suggest installing `p7zip`, point `7zip` packages listed in packages.match file to it.
    
    Most package repositories that ship 7zz disable the RAR support by default (e.g. Debian, NixOS).

 data/packages.match         |  6 ++--
 src/fr-archive-libarchive.c |  8 +++--
 src/fr-command-7z.c         | 73 ++++++++++++++++++++++++++++++++++++++++-----
 src/fr-command-tar.c        |  6 ++--
 4 files changed, 78 insertions(+), 15 deletions(-)
---
diff --git a/data/packages.match b/data/packages.match
index 68ce591f..80e1099f 100644
--- a/data/packages.match
+++ b/data/packages.match
@@ -1,4 +1,7 @@
 [Package Matches]
+7zip=
+7zip-full=
+7zip-rar=
 arj=
 binutils=
 brotli=
@@ -13,9 +16,6 @@ lzip=
 lzma=
 lzop=
 ncompress=
-p7zip=
-p7zip-full=
-p7zip-rar=
 rar=
 rpm=
 rzip=
diff --git a/src/fr-archive-libarchive.c b/src/fr-archive-libarchive.c
index bc601c07..e7b0cfe1 100644
--- a/src/fr-archive-libarchive.c
+++ b/src/fr-archive-libarchive.c
@@ -116,7 +116,9 @@ fr_archive_libarchive_get_capabilities (FrArchive  *archive,
 
        /* give priority to 7z* for 7z archives. */
        if (strcmp (mime_type, "application/x-7z-compressed") == 0) {
-               if (_g_program_is_available ("7za", check_command)
+               if (_g_program_is_available ("7zz", check_command)
+                   || _g_program_is_available ("7zzs", check_command)
+                   || _g_program_is_available ("7za", check_command)
                    || _g_program_is_available ("7zr", check_command)
                    || _g_program_is_available ("7z", check_command))
                {
@@ -135,7 +137,9 @@ fr_archive_libarchive_get_capabilities (FrArchive  *archive,
        if ((strcmp (mime_type, "application/zip") == 0)
            || (strcmp (mime_type, "application/x-cbz") == 0))
        {
-               if (_g_program_is_available ("7z", check_command)) {
+               if (_g_program_is_available ("7zz", check_command)
+                   || _g_program_is_available ("7zzs", check_command)
+                   || _g_program_is_available ("7z", check_command)) {
                        return capabilities;
                }
                if (!_g_program_is_available ("unzip", check_command)) {
diff --git a/src/fr-command-7z.c b/src/fr-command-7z.c
index fe76d1ea..6277aa5c 100644
--- a/src/fr-command-7z.c
+++ b/src/fr-command-7z.c
@@ -179,7 +179,11 @@ list__process_line (char     *line,
 static void
 fr_command_7z_begin_command (FrCommand *comm)
 {
-       if (_g_program_is_in_path ("7z"))
+       if (_g_program_is_in_path ("7zz"))
+               fr_process_begin_command (comm->process, "7zz");
+       else if (_g_program_is_in_path ("7zzs"))
+               fr_process_begin_command (comm->process, "7zzs");
+       else if (_g_program_is_in_path ("7z"))
                fr_process_begin_command (comm->process, "7z");
        else if (_g_program_is_in_path ("7za"))
                fr_process_begin_command (comm->process, "7za");
@@ -589,6 +593,55 @@ fr_command_7z_get_mime_types (FrArchive *archive)
 }
 
 
+static gboolean
+check_rar_support (const char *program_name) {
+       if (! _g_program_is_in_path (program_name)) {
+               return FALSE;
+       }
+
+       g_autofree gchar **standard_output = NULL;
+
+       const gchar* argv[] = {
+               program_name,
+               "i"
+       };
+       if (!g_spawn_sync (
+               /* working_directory = */ NULL,
+               argv,
+               /* envp = */ NULL,
+               G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
+               /* child_setup = */ NULL,
+               /* user_data = */ NULL,
+               standard_output,
+               /* standard_error = */ NULL,
+               /* wait_status = */ NULL,
+               /* error = */ NULL
+       )) {
+               return FALSE;
+       }
+
+       const gchar *codecs = g_strrstr(*standard_output, "Codecs:");
+
+       if (codecs == NULL) {
+               return FALSE;
+       }
+
+       const gchar *rar3 = g_strrstr(codecs, "Rar3");
+
+       return rar3 != NULL;
+}
+
+
+static gboolean
+has_rar_support (gboolean check_command)
+{
+       return !check_command
+              || g_file_test ("/usr/lib/p7zip/Codecs/Rar29.so", G_FILE_TEST_EXISTS)
+              || check_rar_support ("7zz")
+              || check_rar_support ("7zzs");
+}
+
+
 static FrArchiveCap
 fr_command_7z_get_capabilities (FrArchive  *archive,
                                const char *mime_type,
@@ -597,7 +650,11 @@ fr_command_7z_get_capabilities (FrArchive  *archive,
        FrArchiveCap capabilities;
 
        capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
-       if (! _g_program_is_available ("7za", check_command) && ! _g_program_is_available ("7zr", 
check_command) && ! _g_program_is_available ("7z", check_command))
+       if (! _g_program_is_available ("7zz", check_command)
+           && ! _g_program_is_available ("7zzs", check_command)
+           && ! _g_program_is_available ("7za", check_command)
+           && ! _g_program_is_available ("7zr", check_command)
+           && ! _g_program_is_available ("7z", check_command))
                return capabilities;
 
        if (_g_mime_type_matches (mime_type, "application/x-7z-compressed")) {
@@ -617,7 +674,7 @@ fr_command_7z_get_capabilities (FrArchive  *archive,
                        /* give priority to rar and unrar that supports RAR files better. */
                        if (!_g_program_is_available ("rar", check_command)
                            && !_g_program_is_available ("unrar", check_command)
-                           && (! check_command || g_file_test ("/usr/lib/p7zip/Codecs/Rar29.so", 
G_FILE_TEST_EXISTS)))
+                           && has_rar_support (check_command))
                                capabilities |= FR_ARCHIVE_CAN_READ;
                }
                else
@@ -630,7 +687,9 @@ fr_command_7z_get_capabilities (FrArchive  *archive,
                        capabilities |= FR_ARCHIVE_CAN_WRITE | FR_ARCHIVE_CAN_ENCRYPT;
                }
        }
-       else if (_g_program_is_available ("7za", check_command)) {
+       else if (_g_program_is_available ("7zz", check_command)
+                || _g_program_is_available ("7zzs", check_command)
+                || _g_program_is_available ("7za", check_command)) {
                if (_g_mime_type_matches (mime_type, "application/vnd.ms-cab-compressed")
                    || _g_mime_type_matches (mime_type, "application/zip"))
                {
@@ -654,11 +713,11 @@ fr_command_7z_get_packages (FrArchive  *archive,
                            const char *mime_type)
 {
        if (_g_mime_type_matches (mime_type, "application/x-rar"))
-               return PACKAGES ("p7zip,p7zip-rar");
+               return PACKAGES ("7zip,7zip-rar");
        else if (_g_mime_type_matches (mime_type, "application/zip") || _g_mime_type_matches (mime_type, 
"application/vnd.ms-cab-compressed"))
-               return PACKAGES ("p7zip,p7zip-full");
+               return PACKAGES ("7zip,7zip-full");
        else
-               return PACKAGES ("p7zip");
+               return PACKAGES ("7zip");
 }
 
 
diff --git a/src/fr-command-tar.c b/src/fr-command-tar.c
index 3c620772..a9f3d5df 100644
--- a/src/fr-command-tar.c
+++ b/src/fr-command-tar.c
@@ -1241,7 +1241,7 @@ fr_command_tar_get_capabilities (FrArchive  *archive,
                        capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
        }
        else if (_g_mime_type_matches (mime_type, "application/x-7z-compressed-tar")) {
-               char *try_command[3] = { "7za", "7zr", "7z" };
+               char *try_command[5] = { "7zz", "7zzs", "7za", "7zr", "7z" };
                int   i;
 
                for (i = 0; i < G_N_ELEMENTS (try_command); i++) {
@@ -1273,7 +1273,7 @@ fr_command_tar_set_mime_type (FrArchive  *archive,
        FR_ARCHIVE_CLASS (fr_command_tar_parent_class)->set_mime_type (archive, mime_type);
 
        if (_g_mime_type_matches (mime_type, "application/x-7z-compressed-tar")) {
-               char *try_command[3] = { "7za", "7zr", "7z" };
+               char *try_command[5] = { "7zz", "7zzs", "7za", "7zr", "7z" };
                int   i;
 
                for (i = 0; i < G_N_ELEMENTS (try_command); i++) {
@@ -1313,7 +1313,7 @@ fr_command_tar_get_packages (FrArchive  *archive,
        else if (_g_mime_type_matches (mime_type, "application/x-tzo"))
                return PACKAGES ("tar,lzop");
        else if (_g_mime_type_matches (mime_type, "application/x-7z-compressed-tar"))
-               return PACKAGES ("tar,p7zip");
+               return PACKAGES ("tar,7zip");
        else if (_g_mime_type_matches (mime_type, "application/x-rzip-compressed-tar"))
                return PACKAGES ("tar,rzip");
        else if (_g_mime_type_matches (mime_type, "application/x-zstd-compressed-tar"))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]