[file-roller] Support squashfs filesystems and .snap files
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [file-roller] Support squashfs filesystems and .snap files
- Date: Sat, 14 Oct 2017 07:27:43 +0000 (UTC)
commit 219ca078d470b647eb12211c3d4ebbb93a96f95a
Author: Robert Ancell <robert ancell canonical com>
Date: Sat Oct 14 09:24:21 2017 +0200
Support squashfs filesystems and .snap files
https://bugzilla.gnome.org/show_bug.cgi?id=662519
README | 2 +
po/POTFILES.in | 2 +
src/Makefile.am | 2 +
src/fr-command-unsquashfs.c | 245 +++++++++++++++++++++++++++++++++++++++++++
src/fr-command-unsquashfs.h | 51 +++++++++
src/fr-init.c | 6 +
6 files changed, 308 insertions(+), 0 deletions(-)
---
diff --git a/README b/README
index 1ce5348..5d6ba47 100644
--- a/README
+++ b/README
@@ -41,6 +41,8 @@
* lzop (.tar.lzo , .tzo)
* 7zip (.tar.7z)
* xz (.tar.xz)
+ * Snap packages (.snap)
+ * Squashfs images (.sqsh)
* Stuffit Archives (.bin, .sit)
* ZIP Archive (.zip)
* ZIP Archived Comic Book (.cbz)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 03282a8..844d3dc 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -80,6 +80,8 @@ src/fr-command-tar.c
src/fr-command-tar.h
src/fr-command-unarchiver.c
src/fr-command-unarchiver.h
+src/fr-command-unsquashfs.c
+src/fr-command-unsquashfs.h
src/fr-command-unstuff.c
src/fr-command-unstuff.h
src/fr-command-zip.c
diff --git a/src/Makefile.am b/src/Makefile.am
index c896326..12e8f6f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -113,6 +113,8 @@ COMMON_SOURCES = \
fr-command-rpm.h \
fr-command-tar.c \
fr-command-tar.h \
+ fr-command-unsquashfs.c \
+ fr-command-unsquashfs.h \
fr-command-unstuff.c \
fr-command-unstuff.h \
fr-command-zip.c \
diff --git a/src/fr-command-unsquashfs.c b/src/fr-command-unsquashfs.c
new file mode 100644
index 0000000..f568d85
--- /dev/null
+++ b/src/fr-command-unsquashfs.c
@@ -0,0 +1,245 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * File-Roller
+ *
+ * Copyright (C) 2001 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <glib.h>
+#include "file-data.h"
+#include "file-utils.h"
+#include "glib-utils.h"
+#include "fr-command.h"
+#include "fr-command-unsquashfs.h"
+
+
+G_DEFINE_TYPE (FrCommandUnsquashfs, fr_command_unsquashfs, FR_TYPE_COMMAND)
+
+typedef struct {
+ FrCommand *command;
+ gboolean read_header;
+} UnsquashfsData;
+
+
+static void
+process_data_line (char *line,
+ gpointer data)
+{
+ FileData *fdata;
+ UnsquashfsData *d = data;
+ char **fields;
+ char **tmfields;
+ struct tm tm = {0, };
+ const char *name;
+
+ g_return_if_fail (line != NULL);
+
+ /* Skip header */
+ if (!d->read_header) {
+ if (line[0] == '\0')
+ d->read_header = TRUE;
+ return;
+ }
+
+ fdata = file_data_new ();
+
+ fields = _g_str_split_line (line, 5);
+ fdata->size = g_ascii_strtoull (fields[2], NULL, 10);
+ tmfields = g_strsplit(fields[3], "-", 3);
+ if (tmfields[2]) {
+ tm.tm_year = atoi (tmfields[0]) - 1900;
+ tm.tm_mon = atoi (tmfields[1]) - 1;
+ tm.tm_mday = atoi (tmfields[2]);
+ }
+ g_strfreev (tmfields);
+ tmfields = g_strsplit (fields[4], ":", 2);
+ if (tmfields[1]) {
+ tm.tm_hour = atoi (tmfields[0]);
+ tm.tm_min = atoi (tmfields[1]);
+ }
+ g_strfreev (tmfields);
+ fdata->modified = mktime (&tm);
+ g_strfreev (fields);
+
+ name = _g_str_get_last_field (line, 6);
+ fields = g_strsplit (name, " -> ", 2);
+
+ fdata->dir = line[0] == 'd';
+ name = fields[0];
+ if (g_str_has_prefix (name, "squashfs-root/")) { /* Should generally be the case */
+ fdata->full_path = g_strdup (name + 13);
+ fdata->original_path = fdata->full_path;
+ } else if (strcmp (name, "squashfs-root") == 0) {
+ fdata->full_path = g_strdup ("/");
+ fdata->original_path = fdata->full_path;
+ } else {
+ fdata->full_path = g_strdup (name);
+ fdata->original_path = fdata->full_path;
+ }
+
+ if (fields[1] != NULL)
+ fdata->link = g_strdup (fields[1]);
+ g_strfreev (fields);
+
+ if (fdata->dir)
+ fdata->name = _g_path_get_dir_name (fdata->full_path);
+ else
+ fdata->name = g_strdup (_g_path_get_basename (fdata->full_path));
+ fdata->path = _g_path_remove_level (fdata->full_path);
+
+ if (*fdata->name == 0)
+ file_data_free (fdata);
+ else
+ fr_archive_add_file (FR_ARCHIVE (d->command), fdata);
+}
+
+
+static gboolean
+fr_command_unsquashfs_list (FrCommand *command)
+{
+ UnsquashfsData *data;
+
+ data = g_new0 (UnsquashfsData, 1);
+ data->command = command;
+
+ fr_process_begin_command (command->process, "unsquashfs");
+ fr_process_add_arg (command->process, "-lls");
+ fr_process_add_arg (command->process, command->filename);
+ fr_process_set_out_line_func (command->process, process_data_line, data);
+ fr_process_set_end_func (command->process, g_free, data);
+ fr_process_end_command (command->process);
+
+ return TRUE;
+}
+
+
+static void
+fr_command_unsquashfs_extract (FrCommand *command,
+ const char *from_file,
+ GList *file_list,
+ const char *dest_dir,
+ gboolean overwrite,
+ gboolean skip_older,
+ gboolean junk_paths)
+{
+ GList *scan;
+
+ fr_process_begin_command (command->process, "unsquashfs");
+ fr_process_add_arg (command->process, "-dest");
+ if (dest_dir != NULL) {
+ fr_process_add_arg (command->process, dest_dir);
+ } else {
+ fr_process_add_arg (command->process, ".");
+ }
+ if (overwrite) {
+ fr_process_add_arg (command->process, "-force");
+ }
+ fr_process_add_arg (command->process, command->filename);
+
+ for (scan = file_list; scan; scan = scan->next)
+ fr_process_add_arg (command->process, scan->data);
+
+ fr_process_end_command (command->process);
+}
+
+
+const char *unsquashfs_mime_type[] = { "application/vnd.squashfs",
+ "application/vnd.snap",
+ NULL };
+
+
+static const char **
+fr_command_unsquashfs_get_mime_types (FrArchive *archive)
+{
+ return unsquashfs_mime_type;
+}
+
+
+static FrArchiveCap
+fr_command_unsquashfs_get_capabilities (FrArchive *archive,
+ const char *mime_type,
+ gboolean check_command)
+{
+ FrArchiveCap capabilities;
+
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
+ if (_g_program_is_available ("unsquashfs", check_command))
+ capabilities |= FR_ARCHIVE_CAN_READ;
+
+ return capabilities;
+}
+
+
+static const char *
+fr_command_unsquashfs_get_packages (FrArchive *archive,
+ const char *mime_type)
+{
+ return PACKAGES ("unsquashfs");
+}
+
+
+static void
+fr_command_unsquashfs_finalize (GObject *object)
+{
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (FR_IS_COMMAND_UNSQUASHFS (object));
+
+ if (G_OBJECT_CLASS (fr_command_unsquashfs_parent_class)->finalize)
+ G_OBJECT_CLASS (fr_command_unsquashfs_parent_class)->finalize (object);
+}
+
+
+static void
+fr_command_unsquashfs_class_init (FrCommandUnsquashfsClass *klass)
+{
+ GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
+ FrCommandClass *command_class;
+
+ fr_command_unsquashfs_parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = fr_command_unsquashfs_finalize;
+
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_unsquashfs_get_mime_types;
+ archive_class->get_capabilities = fr_command_unsquashfs_get_capabilities;
+ archive_class->get_packages = fr_command_unsquashfs_get_packages;
+
+ command_class = FR_COMMAND_CLASS (klass);
+ command_class->list = fr_command_unsquashfs_list;
+ command_class->extract = fr_command_unsquashfs_extract;
+}
+
+
+static void
+fr_command_unsquashfs_init (FrCommandUnsquashfs *self)
+{
+ FrArchive *base = FR_ARCHIVE (self);
+
+ base->propAddCanUpdate = FALSE;
+ base->propAddCanReplace = FALSE;
+ base->propExtractCanAvoidOverwrite = FALSE;
+ base->propExtractCanSkipOlder = FALSE;
+ base->propExtractCanJunkPaths = FALSE;
+ base->propPassword = FALSE;
+ base->propTest = FALSE;
+}
diff --git a/src/fr-command-unsquashfs.h b/src/fr-command-unsquashfs.h
new file mode 100644
index 0000000..5a143ab
--- /dev/null
+++ b/src/fr-command-unsquashfs.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * File-Roller
+ *
+ * Copyright (C) 2001 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FR_COMMAND_UNSQUASHFS_H
+#define FR_COMMAND_UNSQUASHFS_H
+
+#include <glib.h>
+#include "fr-command.h"
+#include "fr-process.h"
+
+#define FR_TYPE_COMMAND_UNSQUASHFS (fr_command_unsquashfs_get_type ())
+#define FR_COMMAND_UNSQUASHFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
FR_TYPE_COMMAND_UNSQUASHFS, FrCommandUnsquashfs))
+#define FR_COMMAND_UNSQUASHFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FR_TYPE_COMMAND_UNSQUASHFS,
FrCommandUnsquashfsClass))
+#define FR_IS_COMMAND_UNSQUASHFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
FR_TYPE_COMMAND_UNSQUASHFS))
+#define FR_IS_COMMAND_UNSQUASHFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FR_TYPE_COMMAND_UNSQUASHFS))
+#define FR_COMMAND_UNSQUASHFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), FR_TYPE_COMMAND_UNSQUASHFS,
FrCommandUnsquashfsClass))
+
+typedef struct _FrCommandUnsquashfs FrCommandUnsquashfs;
+typedef struct _FrCommandUnsquashfsClass FrCommandUnsquashfsClass;
+
+struct _FrCommandUnsquashfs
+{
+ FrCommand __parent;
+};
+
+struct _FrCommandUnsquashfsClass
+{
+ FrCommandClass __parent_class;
+};
+
+GType fr_command_unsquashfs_get_type (void);
+
+#endif /* FR_COMMAND_UNSQUASHFS_H */
diff --git a/src/fr-init.c b/src/fr-init.c
index 1dd72ee..4e25467 100644
--- a/src/fr-init.c
+++ b/src/fr-init.c
@@ -46,6 +46,7 @@
#if HAVE_JSON_GLIB
#include "fr-command-unarchiver.h"
#endif
+#include "fr-command-unsquashfs.h"
#include "fr-command-unstuff.h"
#include "fr-command-zip.h"
#include "fr-command-zoo.h"
@@ -80,6 +81,8 @@ FrMimeTypeDescription mime_type_desc[] = {
{ "application/x-deb", ".deb", 0 },
{ "application/x-debian-package", ".deb", 0 },
{ "application/vnd.debian.binary-package", ".deb", 0 },
+ { "application/vnd.snap", ".snap", 0 },
+ { "application/vnd.squashfs", ".sqsh", 0 },
{ "application/x-ear", ".ear", 0 },
{ "application/x-ms-dos-executable", ".exe", 0 },
{ "application/x-gzip", ".gz", 0 },
@@ -143,6 +146,8 @@ FrExtensionType file_ext_type[] = {
{ ".rpm", "application/x-rpm" },
{ ".rz", "application/x-rzip" },
{ ".sit", "application/x-stuffit" },
+ { ".snap", "application/vnd.snap" },
+ { ".sqsh", "application/vnd.squashfs" },
{ ".swm", "application/x-ms-wim" },
{ ".tar", "application/x-tar" },
{ ".tar.bz", "application/x-bzip-compressed-tar" },
@@ -372,6 +377,7 @@ register_archives (void)
register_archive (FR_TYPE_COMMAND_LHA);
register_archive (FR_TYPE_COMMAND_RAR);
register_archive (FR_TYPE_COMMAND_RPM);
+ register_archive (FR_TYPE_COMMAND_UNSQUASHFS);
register_archive (FR_TYPE_COMMAND_UNSTUFF);
register_archive (FR_TYPE_COMMAND_ZIP);
register_archive (FR_TYPE_COMMAND_LRZIP);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]