[evince/wip/hadess/cbr-rarv5: 2/2] comics: Add support for RAR v5 archives through libarchive




commit 4390f9b4ac65cb10f1f561c4b225af6142d1967c
Author: Bastien Nocera <hadess hadess net>
Date:   Sun Feb 21 17:12:39 2021 +0100

    comics: Add support for RAR v5 archives through libarchive
    
    When unarr reports that the archive couldn't be opened because it's a
    RAR v5 archive, use libarchive to open it.
    
    Closes: #1190

 backend/comics/ev-archive.c | 21 ++++++++++++++++++++-
 backend/comics/ev-archive.h |  1 +
 2 files changed, 21 insertions(+), 1 deletion(-)
---
diff --git a/backend/comics/ev-archive.c b/backend/comics/ev-archive.c
index f32dc2cb..0ee31a61 100644
--- a/backend/comics/ev-archive.c
+++ b/backend/comics/ev-archive.c
@@ -55,6 +55,7 @@ ev_archive_finalize (GObject *object)
        case EV_ARCHIVE_TYPE_ZIP:
        case EV_ARCHIVE_TYPE_7Z:
        case EV_ARCHIVE_TYPE_TAR:
+       case EV_ARCHIVE_TYPE_RAR5:
                g_clear_pointer (&archive->libar, archive_free);
                break;
        default:
@@ -91,6 +92,10 @@ libarchive_set_archive_type (EvArchive *archive,
                archive_read_support_format_7zip (archive->libar);
        else if (archive_type == EV_ARCHIVE_TYPE_TAR)
                archive_read_support_format_tar (archive->libar);
+       else if (archive_type == EV_ARCHIVE_TYPE_RAR5)
+               archive_read_support_format_rar5 (archive->libar);
+       else
+               g_assert_not_reached ();
 }
 
 EvArchiveType
@@ -115,6 +120,7 @@ ev_archive_set_archive_type (EvArchive *archive,
        case EV_ARCHIVE_TYPE_ZIP:
        case EV_ARCHIVE_TYPE_7Z:
        case EV_ARCHIVE_TYPE_TAR:
+       case EV_ARCHIVE_TYPE_RAR5:
                libarchive_set_archive_type (archive, archive_type);
                break;
        default:
@@ -130,6 +136,7 @@ ev_archive_open_filename (EvArchive   *archive,
                          GError     **error)
 {
        int r;
+       ArArchiveError code;
 
        g_return_val_if_fail (EV_IS_ARCHIVE (archive), FALSE);
        g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, FALSE);
@@ -145,8 +152,13 @@ ev_archive_open_filename (EvArchive   *archive,
                                             "Error opening archive");
                        return FALSE;
                }
-               archive->unarr = ar_open_rar_archive (archive->unarr_stream);
+               archive->unarr = ar_open_rar_archive_with_error (archive->unarr_stream, &code);
                if (archive->unarr == NULL) {
+                       g_clear_pointer (&archive->unarr_stream, ar_close);
+                       if (code == AR_ARCHIVE_ERROR_RAR5) {
+                               libarchive_set_archive_type (archive, EV_ARCHIVE_TYPE_RAR5);
+                               return ev_archive_open_filename (archive, path, error);
+                       }
                        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                             "Error opening RAR archive");
                        return FALSE;
@@ -155,6 +167,7 @@ ev_archive_open_filename (EvArchive   *archive,
        case EV_ARCHIVE_TYPE_ZIP:
        case EV_ARCHIVE_TYPE_7Z:
        case EV_ARCHIVE_TYPE_TAR:
+       case EV_ARCHIVE_TYPE_RAR5:
                r = archive_read_open_filename (archive->libar, path, BUFFER_SIZE);
                if (r != ARCHIVE_OK) {
                        g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
@@ -211,6 +224,7 @@ ev_archive_read_next_header (EvArchive *archive,
        case EV_ARCHIVE_TYPE_ZIP:
        case EV_ARCHIVE_TYPE_7Z:
        case EV_ARCHIVE_TYPE_TAR:
+       case EV_ARCHIVE_TYPE_RAR5:
                return libarchive_read_next_header (archive, error);
        }
 
@@ -232,6 +246,7 @@ ev_archive_get_entry_pathname (EvArchive *archive)
        case EV_ARCHIVE_TYPE_ZIP:
        case EV_ARCHIVE_TYPE_7Z:
        case EV_ARCHIVE_TYPE_TAR:
+       case EV_ARCHIVE_TYPE_RAR5:
                g_return_val_if_fail (archive->libar_entry != NULL, NULL);
                return archive_entry_pathname (archive->libar_entry);
        }
@@ -254,6 +269,7 @@ ev_archive_get_entry_size (EvArchive *archive)
        case EV_ARCHIVE_TYPE_ZIP:
        case EV_ARCHIVE_TYPE_7Z:
        case EV_ARCHIVE_TYPE_TAR:
+       case EV_ARCHIVE_TYPE_RAR5:
                g_return_val_if_fail (archive->libar_entry != NULL, -1);
                return archive_entry_size (archive->libar_entry);
        }
@@ -277,6 +293,7 @@ ev_archive_get_entry_is_encrypted (EvArchive *archive)
        case EV_ARCHIVE_TYPE_ZIP:
        case EV_ARCHIVE_TYPE_7Z:
        case EV_ARCHIVE_TYPE_TAR:
+       case EV_ARCHIVE_TYPE_RAR5:
                g_return_val_if_fail (archive->libar_entry != NULL, -1);
                return archive_entry_is_encrypted (archive->libar_entry);
        }
@@ -310,6 +327,7 @@ ev_archive_read_data (EvArchive *archive,
        case EV_ARCHIVE_TYPE_ZIP:
        case EV_ARCHIVE_TYPE_7Z:
        case EV_ARCHIVE_TYPE_TAR:
+       case EV_ARCHIVE_TYPE_RAR5:
                g_return_val_if_fail (archive->libar_entry != NULL, -1);
                r = archive_read_data (archive->libar, buf, count);
                if (r < 0) {
@@ -336,6 +354,7 @@ ev_archive_reset (EvArchive *archive)
        case EV_ARCHIVE_TYPE_ZIP:
        case EV_ARCHIVE_TYPE_7Z:
        case EV_ARCHIVE_TYPE_TAR:
+       case EV_ARCHIVE_TYPE_RAR5:
                g_clear_pointer (&archive->libar, archive_free);
                libarchive_set_archive_type (archive, archive->type);
                break;
diff --git a/backend/comics/ev-archive.h b/backend/comics/ev-archive.h
index 9f015f21..53affa5f 100644
--- a/backend/comics/ev-archive.h
+++ b/backend/comics/ev-archive.h
@@ -30,6 +30,7 @@ G_DECLARE_FINAL_TYPE (EvArchive, ev_archive, EV, ARCHIVE, GObject)
 typedef enum {
        EV_ARCHIVE_TYPE_NONE = 0,
        EV_ARCHIVE_TYPE_RAR,
+       EV_ARCHIVE_TYPE_RAR5,
        EV_ARCHIVE_TYPE_ZIP,
        EV_ARCHIVE_TYPE_7Z,
        EV_ARCHIVE_TYPE_TAR


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