[file-roller] Added a D-BUS service to create and extract archives.



commit f998fd8e33a08d686a1071db87d21f4a83963d99
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Nov 28 20:10:24 2010 +0100

    Added a D-BUS service to create and extract archives.

 data/Makefile.am                     |    6 +
 data/org.gnome.FileRoller.service.in |    3 +
 src/Makefile.am                      |   29 +-
 src/actions.c                        |    2 +-
 src/dlg-batch-add.c                  |    2 +-
 src/dlg-extract.c                    |    2 +-
 src/dlg-new.c                        |    2 +-
 src/dlg-open-with.c                  |    2 +-
 src/dlg-package-installer.c          |    2 +-
 src/dlg-update.c                     |    2 +-
 src/file-utils.c                     |    2 +-
 src/fr-archive.c                     |    2 +-
 src/fr-error.c                       |    2 +-
 src/fr-init.c                        |  660 ++++++++++++++++++++++++++
 src/{main.h => fr-init.h}            |   51 +--
 src/fr-marshal.list                  |    1 +
 src/fr-window.c                      |  112 ++++-
 src/fr-window.h                      |   11 +-
 src/main.c                           |  855 +++++-----------------------------
 src/preferences.c                    |    2 +-
 src/server.c                         |  421 +++++++++++++++++
 src/test-server.c                    |  178 +++++++
 22 files changed, 1542 insertions(+), 807 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index 2c81954..c9c8337 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -9,6 +9,12 @@ desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
 matchdir = $(datadir)/file-roller
 match_DATA = packages.match
 
+servicedir = $(datadir)/dbus-1/services
+service_in_files = org.gnome.FileRoller.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+$(service_DATA): $(service_in_files) Makefile
+	$(AM_V_GEN) $(SED) -e "s|\ libexecdir\@|$(libexecdir)|" $< > $@
+
 gsettingsschema_in_files = org.gnome.FileRoller.gschema.xml.in
 gsettings_SCHEMAS = $(gsettingsschema_in_files:.xml.in=.xml)
 .PRECIOUS: $(gsettings_SCHEMAS)
diff --git a/data/org.gnome.FileRoller.service.in b/data/org.gnome.FileRoller.service.in
new file mode 100644
index 0000000..b68b646
--- /dev/null
+++ b/data/org.gnome.FileRoller.service.in
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.gnome.FileRoller
+Exec= libexecdir@/file-roller-server
diff --git a/src/Makefile.am b/src/Makefile.am
index 2e3022b..fa88925 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,8 @@
 SUBDIRS = commands sh
 
 bin_PROGRAMS = file-roller
+libexec_PROGRAMS = file-roller-server
+noinst_PROGRAMS = test-server
 
 if MKDTEMP_MISSING
 MKDTEMP_FILES=mkdtemp.c mkdtemp.h
@@ -44,7 +46,7 @@ BUILT_SOURCES =			\
 	fr-enum-types.h		\
 	fr-enum-types.c
 
-file_roller_SOURCES = 			\
+COMMON_SOURCES = 			\
 	actions.h			\
 	actions.c			\
 	dlg-add-files.c			\
@@ -122,6 +124,8 @@ file_roller_SOURCES = 			\
 	fr-command-7z.h			\
 	fr-error.c			\
 	fr-error.h			\
+	fr-init.c			\
+	fr-init.h			\
 	fr-list-model.c			\
 	fr-list-model.h			\
 	fr-stock.c			\
@@ -138,8 +142,6 @@ file_roller_SOURCES = 			\
 	gtk-utils.h			\
 	java-utils.c			\
 	java-utils.h			\
-	main.c				\
-	main.h				\
 	open-file.c			\
 	open-file.h			\
 	preferences.c			\
@@ -177,9 +179,24 @@ fr-enum-types.c: typedefs.h fr-enum-types.h
 	&& (cmp -s xgen-$(@F) fr-enum-types.c || cp xgen-$(@F) fr-enum-types.c ) \
 	&& rm -f xgen-$(@F) )
 
-file_roller_LDADD =							\
-		    $(top_builddir)/copy-n-paste/libeggsmclient.la	\
-		    $(FR_LIBS)
+file_roller_SOURCES = 			\
+	$(COMMON_SOURCES)		\
+	main.c
+
+file_roller_LDADD =					\
+	$(top_builddir)/copy-n-paste/libeggsmclient.la	\
+	$(FR_LIBS)
+
+file_roller_server_SOURCES =		\
+	$(COMMON_SOURCES)		\
+	server.c
+	
+file_roller_server_LDADD =		\
+	$(file_roller_LDADD)
+
+test_server_SOURCES = test-server.c
+test_server_FLAGS = $(FR_CFLAGS)
+test_server_LDADD = $(FR_LIBS)
 
 EXTRA_DIST = fr-marshal.list
 
diff --git a/src/actions.c b/src/actions.c
index 2610dc4..c1a87bc 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -39,7 +39,7 @@
 #include "file-utils.h"
 #include "fr-process.h"
 #include "glib-utils.h"
-#include "main.h"
+#include "fr-init.h"
 #include "typedefs.h"
 
 
diff --git a/src/dlg-batch-add.c b/src/dlg-batch-add.c
index b1a8163..d469e45 100644
--- a/src/dlg-batch-add.c
+++ b/src/dlg-batch-add.c
@@ -32,7 +32,7 @@
 #include "gtk-utils.h"
 #include "glib-utils.h"
 #include "preferences.h"
-#include "main.h"
+#include "fr-init.h"
 
 
 #define ARCHIVE_ICON_SIZE (48)
diff --git a/src/dlg-extract.c b/src/dlg-extract.c
index 54ab4fb..76d1305 100644
--- a/src/dlg-extract.c
+++ b/src/dlg-extract.c
@@ -24,7 +24,7 @@
 #include <unistd.h>
 #include "file-utils.h"
 #include "fr-stock.h"
-#include "main.h"
+#include "fr-init.h"
 #include "gtk-utils.h"
 #include "fr-window.h"
 #include "typedefs.h"
diff --git a/src/dlg-new.c b/src/dlg-new.c
index 73c883a..3d42876 100644
--- a/src/dlg-new.c
+++ b/src/dlg-new.c
@@ -28,7 +28,7 @@
 #include "file-utils.h"
 #include "fr-stock.h"
 #include "gtk-utils.h"
-#include "main.h"
+#include "fr-init.h"
 #include "preferences.h"
 
 
diff --git a/src/dlg-open-with.c b/src/dlg-open-with.c
index f019e60..75b1950 100644
--- a/src/dlg-open-with.c
+++ b/src/dlg-open-with.c
@@ -25,7 +25,7 @@
 #include "file-utils.h"
 #include "glib-utils.h"
 #include "gtk-utils.h"
-#include "main.h"
+#include "fr-init.h"
 #include "fr-window.h"
 
 
diff --git a/src/dlg-package-installer.c b/src/dlg-package-installer.c
index 58b8dd1..6056c7d 100644
--- a/src/dlg-package-installer.c
+++ b/src/dlg-package-installer.c
@@ -26,7 +26,7 @@
 #include <gtk/gtk.h>
 #include "dlg-package-installer.h"
 #include "gtk-utils.h"
-#include "main.h"
+#include "fr-init.h"
 
 
 typedef struct {
diff --git a/src/dlg-update.c b/src/dlg-update.c
index 6425e52..a3efc4a 100644
--- a/src/dlg-update.c
+++ b/src/dlg-update.c
@@ -26,7 +26,7 @@
 #include "file-utils.h"
 #include "glib-utils.h"
 #include "gtk-utils.h"
-#include "main.h"
+#include "fr-init.h"
 #include "fr-window.h"
 
 
diff --git a/src/file-utils.c b/src/file-utils.c
index 5b3869d..5e5009f 100644
--- a/src/file-utils.c
+++ b/src/file-utils.c
@@ -36,7 +36,7 @@
 #include <gio/gio.h>
 #include "file-utils.h"
 #include "glib-utils.h"
-#include "main.h"
+#include "fr-init.h"
 
 
 #ifndef HAVE_MKDTEMP
diff --git a/src/fr-archive.c b/src/fr-archive.c
index 984d2a2..01597e4 100644
--- a/src/fr-archive.c
+++ b/src/fr-archive.c
@@ -38,7 +38,7 @@
 #include "fr-error.h"
 #include "fr-marshal.h"
 #include "fr-process.h"
-#include "main.h"
+#include "fr-init.h"
 
 #ifndef NCARGS
 #define NCARGS _POSIX_ARG_MAX
diff --git a/src/fr-error.c b/src/fr-error.c
index 6d29d92..6c4d0f5 100644
--- a/src/fr-error.c
+++ b/src/fr-error.c
@@ -29,7 +29,7 @@ fr_error_quark (void)
 	static GQuark quark;
         
         if (!quark)
-                quark = g_quark_from_static_string ("file_roller_error");
+                quark = g_quark_from_static_string ("file-roller-error");
 	
         return quark;
 }
diff --git a/src/fr-init.c b/src/fr-init.c
new file mode 100644
index 0000000..2ddb311
--- /dev/null
+++ b/src/fr-init.c
@@ -0,0 +1,660 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  File-Roller
+ *
+ *  Copyright (C) 2010 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 <glib/gi18n.h>
+#include "file-data.h"
+#include "file-utils.h"
+#include "glib-utils.h"
+#include "fr-command.h"
+#include "fr-command-ace.h"
+#include "fr-command-alz.h"
+#include "fr-command-ar.h"
+#include "fr-command-arj.h"
+#include "fr-command-cfile.h"
+#include "fr-command-cpio.h"
+#include "fr-command-dpkg.h"
+#include "fr-command-iso.h"
+#include "fr-command-jar.h"
+#include "fr-command-lha.h"
+#include "fr-command-rar.h"
+#include "fr-command-rpm.h"
+#include "fr-command-tar.h"
+#include "fr-command-unstuff.h"
+#include "fr-command-zip.h"
+#include "fr-command-zoo.h"
+#include "fr-command-7z.h"
+#include "fr-command-lrzip.h"
+#include "fr-init.h"
+#include "fr-process.h"
+#include "fr-stock.h"
+#include "fr-window.h"
+#include "typedefs.h"
+#include "preferences.h"
+
+
+/* The capabilities are computed automatically in
+ * compute_supported_archive_types() so it's correct to initialize to 0 here. */
+FrMimeTypeDescription mime_type_desc[] = {
+	{ "application/x-7z-compressed",        ".7z",       N_("7-Zip (.7z)"), 0 },
+	{ "application/x-7z-compressed-tar",    ".tar.7z",   N_("Tar compressed with 7z (.tar.7z)"), 0 },
+	{ "application/x-ace",                  ".ace",      N_("Ace (.ace)"), 0 },
+	{ "application/x-alz",                  ".alz",      NULL, 0 },
+	{ "application/x-ar",                   ".ar",       N_("Ar (.ar)"), 0 },
+	{ "application/x-arj",                  ".arj",      N_("Arj (.arj)"), 0 },
+	{ "application/x-bzip",                 ".bz2",      NULL, 0 },
+	{ "application/x-bzip-compressed-tar",  ".tar.bz2",  N_("Tar compressed with bzip2 (.tar.bz2)"), 0 },
+	{ "application/x-bzip1",                ".bz",       NULL, 0 },
+	{ "application/x-bzip1-compressed-tar", ".tar.bz",   N_("Tar compressed with bzip (.tar.bz)"), 0 },
+	{ "application/vnd.ms-cab-compressed",  ".cab",      N_("Cabinet (.cab)"), 0 },
+	{ "application/x-cbr",                  ".cbr",      N_("Rar Archived Comic Book (.cbr)"), 0 },
+	{ "application/x-cbz",                  ".cbz",      N_("Zip Archived Comic Book (.cbz)"), 0 },
+	{ "application/x-cd-image",             ".iso",      NULL, 0 },
+	{ "application/x-compress",             ".Z",        NULL, 0 },
+	{ "application/x-compressed-tar",       ".tar.gz",   N_("Tar compressed with gzip (.tar.gz)"), 0 },
+	{ "application/x-cpio",                 ".cpio",     NULL, 0 },
+	{ "application/x-deb",                  ".deb",      NULL, 0 },
+	{ "application/x-ear",                  ".ear",      N_("Ear (.ear)"), 0 },
+	{ "application/x-ms-dos-executable",    ".exe",      N_("Self-extracting zip (.exe)"), 0 },
+	{ "application/x-gzip",                 ".gz",       NULL, 0 },
+	{ "application/x-java-archive",         ".jar",      N_("Jar (.jar)"), 0 },
+	{ "application/x-lha",                  ".lzh",      N_("Lha (.lzh)"), 0 },
+	{ "application/x-lrzip",                ".lrz",      N_("Lrzip (.lrz)"), 0},
+	{ "application/x-lrzip-compressed-tar", ".tar.lrz",  N_("Tar compressed with lrzip (.tar.lrz)"), 0 },
+	{ "application/x-lzip",                 ".lz",       NULL, 0 },
+	{ "application/x-lzip-compressed-tar",  ".tar.lz",   N_("Tar compressed with lzip (.tar.lz)"), 0 },
+	{ "application/x-lzma",                 ".lzma",     NULL, 0 },
+	{ "application/x-lzma-compressed-tar",  ".tar.lzma", N_("Tar compressed with lzma (.tar.lzma)"), 0 },
+	{ "application/x-lzop",                 ".lzo",      NULL, 0 },
+	{ "application/x-lzop-compressed-tar",  ".tar.lzo",  N_("Tar compressed with lzop (.tar.lzo)"), 0 },
+	{ "application/x-ms-wim",               ".wim",      N_("Windows Imaging Format (.wim)"), 0 },
+	{ "application/x-rar",                  ".rar",      N_("Rar (.rar)"), 0 },
+	{ "application/x-rpm",                  ".rpm",      NULL, 0 },
+	{ "application/x-rzip",                 ".rz",       NULL, 0 },
+	{ "application/x-tar",                  ".tar",      N_("Tar uncompressed (.tar)"), 0 },
+	{ "application/x-tarz",                 ".tar.Z",    N_("Tar compressed with compress (.tar.Z)"), 0 },
+	{ "application/x-stuffit",              ".sit",      NULL, 0 },
+	{ "application/x-war",                  ".war",      N_("War (.war)"), 0 },
+	{ "application/x-xz",                   ".xz",       N_("Xz (.xz)"), 0 },
+	{ "application/x-xz-compressed-tar",    ".tar.xz",   N_("Tar compressed with xz (.tar.xz)"), 0 },
+	{ "application/x-zoo",                  ".zoo",      N_("Zoo (.zoo)"), 0 },
+	{ "application/zip",                    ".zip",      N_("Zip (.zip)"), 0 },
+	{ NULL, NULL, NULL, 0 }
+};
+
+FrExtensionType file_ext_type[] = {
+	{ ".7z", "application/x-7z-compressed" },
+	{ ".ace", "application/x-ace" },
+	{ ".alz", "application/x-alz" },
+	{ ".ar", "application/x-ar" },
+	{ ".arj", "application/x-arj" },
+	{ ".bin", "application/x-stuffit" },
+	{ ".bz", "application/x-bzip" },
+	{ ".bz2", "application/x-bzip" },
+	{ ".cab", "application/vnd.ms-cab-compressed" },
+	{ ".cbr", "application/x-cbr" },
+	{ ".cbz", "application/x-cbz" },
+	{ ".cpio", "application/x-cpio" },
+	{ ".deb", "application/x-deb" },
+	{ ".ear", "application/x-ear" },
+	{ ".exe", "application/x-ms-dos-executable" },
+	{ ".gz", "application/x-gzip" },
+	{ ".iso", "application/x-cd-image" },
+	{ ".jar", "application/x-java-archive" },
+	{ ".lha", "application/x-lha" },
+	{ ".lrz", "application/x-lrzip" },
+	{ ".lzh", "application/x-lha" },
+	{ ".lz", "application/x-lzip" },
+	{ ".lzma", "application/x-lzma" },
+	{ ".lzo", "application/x-lzop" },
+	{ ".rar", "application/x-rar" },
+	{ ".rpm", "application/x-rpm" },
+	{ ".rz", "application/x-rzip" },
+	{ ".sit", "application/x-stuffit" },
+	{ ".swm", "application/x-ms-wim" },
+	{ ".tar", "application/x-tar" },
+	{ ".tar.bz", "application/x-bzip-compressed-tar" },
+	{ ".tar.bz2", "application/x-bzip-compressed-tar" },
+	{ ".tar.gz", "application/x-compressed-tar" },
+	{ ".tar.lrz", "application/x-lrzip-compressed-tar" },
+	{ ".tar.lz", "application/x-lzip-compressed-tar" },
+	{ ".tar.lzma", "application/x-lzma-compressed-tar" },
+	{ ".tar.lzo", "application/x-lzop-compressed-tar" },
+	{ ".tar.7z", "application/x-7z-compressed-tar" },
+	{ ".tar.xz", "application/x-xz-compressed-tar" },
+	{ ".tar.Z", "application/x-tarz" },
+	{ ".taz", "application/x-tarz" },
+	{ ".tbz", "application/x-bzip-compressed-tar" },
+	{ ".tbz2", "application/x-bzip-compressed-tar" },
+	{ ".tgz", "application/x-compressed-tar" },
+	{ ".txz", "application/x-xz-compressed-tar" },
+	{ ".tlz", "application/x-lzip-compressed-tar" },
+	{ ".tzma", "application/x-lzma-compressed-tar" },
+	{ ".tzo", "application/x-lzop-compressed-tar" },
+	{ ".war", "application/x-war" },
+	{ ".wim", "application/x-ms-wim" },
+	{ ".xz", "application/x-xz" },
+	{ ".z", "application/x-gzip" },
+	{ ".Z", "application/x-compress" },
+	{ ".zip", "application/zip" },
+	{ ".zoo", "application/x-zoo" },
+	{ NULL, NULL }
+};
+
+
+GList        *WindowList;
+GList        *CommandList;
+gint          ForceDirectoryCreation;
+GHashTable   *ProgramsCache;
+GPtrArray    *Registered_Commands;
+int           single_file_save_type[64];
+int           save_type[64];
+int           open_type[64];
+int           create_type[64];
+
+
+static void
+migrate_options_directory (void)
+{
+	char *old_directory_path;
+	GFile *old_directory;
+	GFile *new_directory;
+
+	old_directory_path = get_home_relative_path (".gnome2/file-roller/options");
+	old_directory = g_file_new_for_path (old_directory_path);
+	new_directory = get_user_config_subdirectory (ADD_FOLDER_OPTIONS_DIR, FALSE);
+	if (g_file_query_exists (old_directory, NULL) && ! g_file_query_exists (new_directory, NULL)) {
+		GFile *parent;
+
+		parent = g_file_get_parent (new_directory);
+		if (make_directory_tree (parent, 0700, NULL))
+			g_file_move (old_directory, new_directory, 0, NULL, NULL, NULL, NULL);
+
+		g_object_unref (parent);
+	}
+
+	g_object_unref (new_directory);
+	g_object_unref (old_directory);
+	g_free (old_directory_path);
+}
+
+
+/* -- FrRegisteredCommand -- */
+
+
+FrRegisteredCommand *
+fr_registered_command_new (GType command_type)
+{
+	FrRegisteredCommand  *reg_com;
+	FrCommand            *command;
+	const char          **mime_types;
+	int                   i;
+
+	reg_com = g_new0 (FrRegisteredCommand, 1);
+	reg_com->ref = 1;
+	reg_com->type = command_type;
+	reg_com->caps = g_ptr_array_new ();
+	reg_com->packages = g_ptr_array_new ();
+
+	command = (FrCommand*) g_object_new (reg_com->type, NULL);
+	mime_types = fr_command_get_mime_types (command);
+	for (i = 0; mime_types[i] != NULL; i++) {
+		const char         *mime_type;
+		FrMimeTypeCap      *cap;
+		FrMimeTypePackages *packages;
+
+		mime_type = get_static_string (mime_types[i]);
+
+		cap = g_new0 (FrMimeTypeCap, 1);
+		cap->mime_type = mime_type;
+		cap->current_capabilities = fr_command_get_capabilities (command, mime_type, TRUE);
+		cap->potential_capabilities = fr_command_get_capabilities (command, mime_type, FALSE);
+		g_ptr_array_add (reg_com->caps, cap);
+
+		packages = g_new0 (FrMimeTypePackages, 1);
+		packages->mime_type = mime_type;
+		packages->packages = fr_command_get_packages (command, mime_type);
+		g_ptr_array_add (reg_com->packages, packages);
+	}
+
+	g_object_unref (command);
+
+	return reg_com;
+}
+
+
+void
+fr_registered_command_ref (FrRegisteredCommand *reg_com)
+{
+	reg_com->ref++;
+}
+
+
+void
+fr_registered_command_unref (FrRegisteredCommand *reg_com)
+{
+	if (--(reg_com->ref) != 0)
+		return;
+
+	g_ptr_array_foreach (reg_com->caps, (GFunc) g_free, NULL);
+	g_ptr_array_free (reg_com->caps, TRUE);
+	g_free (reg_com);
+}
+
+
+FrCommandCaps
+fr_registered_command_get_capabilities (FrRegisteredCommand *reg_com,
+				        const char          *mime_type)
+{
+	int i;
+
+	for (i = 0; i < reg_com->caps->len; i++) {
+		FrMimeTypeCap *cap;
+
+		cap = g_ptr_array_index (reg_com->caps, i);
+		if (strcmp (mime_type, cap->mime_type) == 0)
+			return cap->current_capabilities;
+	}
+
+	return FR_COMMAND_CAN_DO_NOTHING;
+}
+
+
+FrCommandCaps
+fr_registered_command_get_potential_capabilities (FrRegisteredCommand *reg_com,
+						  const char          *mime_type)
+{
+	int i;
+
+	if (mime_type == NULL)
+		return FR_COMMAND_CAN_DO_NOTHING;
+
+	for (i = 0; i < reg_com->caps->len; i++) {
+		FrMimeTypeCap *cap;
+
+		cap = g_ptr_array_index (reg_com->caps, i);
+		if ((cap->mime_type != NULL) && (strcmp (mime_type, cap->mime_type) == 0))
+			return cap->potential_capabilities;
+	}
+
+	return FR_COMMAND_CAN_DO_NOTHING;
+}
+
+
+void
+register_command (GType command_type)
+{
+	if (Registered_Commands == NULL)
+		Registered_Commands = g_ptr_array_sized_new (5);
+	g_ptr_array_add (Registered_Commands, fr_registered_command_new (command_type));
+}
+
+
+gboolean
+unregister_command (GType command_type)
+{
+	int i;
+
+	for (i = 0; i < Registered_Commands->len; i++) {
+		FrRegisteredCommand *command;
+
+		command = g_ptr_array_index (Registered_Commands, i);
+		if (command->type == command_type) {
+			g_ptr_array_remove_index (Registered_Commands, i);
+			fr_registered_command_unref (command);
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+
+static void
+register_commands (void)
+{
+	/* The order here is important. Commands registered earlier have higher
+	 * priority.  However commands that can read and write a file format
+	 * have higher priority over commands that can only read the same
+	 * format, regardless of the registration order. */
+
+	register_command (FR_TYPE_COMMAND_TAR);
+	register_command (FR_TYPE_COMMAND_CFILE);
+	register_command (FR_TYPE_COMMAND_7Z);
+	register_command (FR_TYPE_COMMAND_DPKG);
+
+	register_command (FR_TYPE_COMMAND_ACE);
+	register_command (FR_TYPE_COMMAND_ALZ);
+	register_command (FR_TYPE_COMMAND_AR);
+	register_command (FR_TYPE_COMMAND_ARJ);
+	register_command (FR_TYPE_COMMAND_CPIO);
+	register_command (FR_TYPE_COMMAND_ISO);
+	register_command (FR_TYPE_COMMAND_JAR);
+	register_command (FR_TYPE_COMMAND_LHA);
+	register_command (FR_TYPE_COMMAND_RAR);
+	register_command (FR_TYPE_COMMAND_RPM);
+	register_command (FR_TYPE_COMMAND_UNSTUFF);
+	register_command (FR_TYPE_COMMAND_ZIP);
+	register_command (FR_TYPE_COMMAND_LRZIP);
+	register_command (FR_TYPE_COMMAND_ZOO);
+}
+
+
+GType
+get_command_type_from_mime_type (const char    *mime_type,
+				 FrCommandCaps  requested_capabilities)
+{
+	int i;
+
+	if (mime_type == NULL)
+		return 0;
+
+	for (i = 0; i < Registered_Commands->len; i++) {
+		FrRegisteredCommand *command;
+		FrCommandCaps        capabilities;
+
+		command = g_ptr_array_index (Registered_Commands, i);
+		capabilities = fr_registered_command_get_capabilities (command, mime_type);
+
+		/* the command must support all the requested capabilities */
+		if (((capabilities ^ requested_capabilities) & requested_capabilities) == 0)
+			return command->type;
+	}
+
+	return 0;
+}
+
+
+GType
+get_preferred_command_for_mime_type (const char    *mime_type,
+				     FrCommandCaps  requested_capabilities)
+{
+	int i;
+
+	for (i = 0; i < Registered_Commands->len; i++) {
+		FrRegisteredCommand *command;
+		FrCommandCaps        capabilities;
+
+		command = g_ptr_array_index (Registered_Commands, i);
+		capabilities = fr_registered_command_get_potential_capabilities (command, mime_type);
+
+		/* the command must support all the requested capabilities */
+		if (((capabilities ^ requested_capabilities) & requested_capabilities) == 0)
+			return command->type;
+	}
+
+	return 0;
+}
+
+
+void
+update_registered_commands_capabilities (void)
+{
+	int i;
+
+	g_hash_table_remove_all (ProgramsCache);
+
+	for (i = 0; i < Registered_Commands->len; i++) {
+		FrRegisteredCommand *reg_com;
+		FrCommand           *command;
+		int                  j;
+
+		reg_com = g_ptr_array_index (Registered_Commands, i);
+		command = (FrCommand*) g_object_new (reg_com->type, NULL);
+		for (j = 0; j < reg_com->caps->len; j++) {
+			FrMimeTypeCap *cap = g_ptr_array_index (reg_com->caps, j);
+
+			cap->current_capabilities = fr_command_get_capabilities (command, cap->mime_type, TRUE);
+			cap->potential_capabilities = fr_command_get_capabilities (command, cap->mime_type, FALSE);
+		}
+
+		g_object_unref (command);
+	}
+}
+
+
+const char *
+get_mime_type_from_extension (const char *ext)
+{
+	int i;
+
+	if (ext == NULL)
+		return NULL;
+
+	for (i = G_N_ELEMENTS (file_ext_type) - 1; i >= 0; i--) {
+		if (file_ext_type[i].ext == NULL)
+			continue;
+		if (strcasecmp (ext, file_ext_type[i].ext) == 0)
+			return get_static_string (file_ext_type[i].mime_type);
+	}
+
+	return NULL;
+}
+
+
+const char *
+get_archive_filename_extension (const char *filename)
+{
+	const char *ext;
+	int         i;
+
+	if (filename == NULL)
+		return NULL;
+
+	ext = get_file_extension (filename);
+	if (ext == NULL)
+		return NULL;
+
+	for (i = G_N_ELEMENTS (file_ext_type) - 1; i >= 0; i--) {
+		if (file_ext_type[i].ext == NULL)
+			continue;
+		if (strcasecmp (ext, file_ext_type[i].ext) == 0)
+			return ext;
+	}
+
+	return NULL;
+}
+
+
+int
+get_mime_type_index (const char *mime_type)
+{
+	int i;
+
+	for (i = 0; mime_type_desc[i].mime_type != NULL; i++)
+		if (strcmp (mime_type_desc[i].mime_type, mime_type) == 0)
+			return i;
+	return -1;
+}
+
+
+static void
+add_if_non_present (int *a,
+	            int *n,
+	            int  o)
+{
+	int i;
+
+	for (i = 0; i < *n; i++) {
+		if (a[i] == o)
+			return;
+	}
+	a[*n] = o;
+	*n = *n + 1;
+}
+
+
+static int
+cmp_mime_type_by_extension (const void *p1,
+			    const void *p2)
+{
+	int i1 = * (int*) p1;
+	int i2 = * (int*) p2;
+
+	return strcmp (mime_type_desc[i1].default_ext, mime_type_desc[i2].default_ext);
+}
+
+
+static int
+cmp_mime_type_by_description (const void *p1,
+			      const void *p2)
+{
+	int i1 = * (int*) p1;
+	int i2 = * (int*) p2;
+
+	return g_utf8_collate (_(mime_type_desc[i1].name), _(mime_type_desc[i2].name));
+}
+
+
+static void
+sort_mime_types (int *a,
+                 int(*compar)(const void *, const void *))
+{
+	int n = 0;
+
+	while (a[n] != -1)
+		n++;
+	qsort (a, n, sizeof (int), compar);
+}
+
+
+void
+sort_mime_types_by_extension (int *a)
+{
+	sort_mime_types (a, cmp_mime_type_by_extension);
+}
+
+
+void
+sort_mime_types_by_description (int *a)
+{
+	sort_mime_types (a, cmp_mime_type_by_description);
+}
+
+
+static void
+compute_supported_archive_types (void)
+{
+	int sf_i = 0, s_i = 0, o_i = 0, c_i = 0;
+	int i;
+
+	for (i = 0; i < Registered_Commands->len; i++) {
+		FrRegisteredCommand *reg_com;
+		int                  j;
+
+		reg_com = g_ptr_array_index (Registered_Commands, i);
+		for (j = 0; j < reg_com->caps->len; j++) {
+			FrMimeTypeCap *cap;
+			int            idx;
+
+			cap = g_ptr_array_index (reg_com->caps, j);
+			idx = get_mime_type_index (cap->mime_type);
+			if (idx < 0) {
+				g_warning ("mime type not recognized: %s", cap->mime_type);
+				continue;
+			}
+			mime_type_desc[idx].capabilities |= cap->current_capabilities;
+			if (cap->current_capabilities & FR_COMMAND_CAN_READ)
+				add_if_non_present (open_type, &o_i, idx);
+			if (cap->current_capabilities & FR_COMMAND_CAN_WRITE) {
+				if (cap->current_capabilities & FR_COMMAND_CAN_ARCHIVE_MANY_FILES) {
+					add_if_non_present (save_type, &s_i, idx);
+					if (cap->current_capabilities & FR_COMMAND_CAN_WRITE)
+						add_if_non_present (create_type, &c_i, idx);
+				}
+				add_if_non_present (single_file_save_type, &sf_i, idx);
+			}
+		}
+	}
+
+	open_type[o_i] = -1;
+	save_type[s_i] = -1;
+	single_file_save_type[sf_i] = -1;
+	create_type[c_i] = -1;
+}
+
+
+static initialized = FALSE;
+
+
+void
+initialize_data (void)
+{
+	if (initialized)
+		return;
+	initialized = TRUE;
+
+	ProgramsCache = g_hash_table_new_full (g_str_hash,
+					       g_str_equal,
+					       g_free,
+					       NULL);
+
+	migrate_options_directory ();
+	register_commands ();
+	compute_supported_archive_types ();
+
+	fr_stock_init ();
+}
+
+
+static void
+command_done (CommandData *cdata)
+{
+	if (cdata == NULL)
+		return;
+
+	if ((cdata->temp_dir != NULL) && path_is_dir (cdata->temp_dir)) {
+		char *argv[4];
+
+		argv[0] = "rm";
+		argv[1] = "-rf";
+		argv[2] = cdata->temp_dir;
+		argv[3] = NULL;
+		g_spawn_sync (g_get_tmp_dir (), argv, NULL,
+			      G_SPAWN_SEARCH_PATH,
+			      NULL, NULL,
+			      NULL, NULL, NULL,
+			      NULL);
+	}
+
+	g_free (cdata->command);
+	if (cdata->app != NULL)
+		g_object_unref (cdata->app);
+	path_list_free (cdata->file_list);
+	g_free (cdata->temp_dir);
+	if (cdata->process != NULL)
+		g_object_unref (cdata->process);
+
+	CommandList = g_list_remove (CommandList, cdata);
+	g_free (cdata);
+}
+
+
+void
+release_data (void)
+{
+	g_hash_table_destroy (ProgramsCache);
+
+	while (CommandList != NULL) {
+		CommandData *cdata = CommandList->data;
+		command_done (cdata);
+	}
+}
diff --git a/src/main.h b/src/fr-init.h
similarity index 63%
rename from src/main.h
rename to src/fr-init.h
index 90d3bb1..1e31d54 100644
--- a/src/main.h
+++ b/src/fr-init.h
@@ -3,7 +3,7 @@
 /*
  *  File-Roller
  *
- *  Copyright (C) 2001, 2008 The Free Software Foundation, Inc.
+ *  Copyright (C) 2010 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
@@ -19,18 +19,13 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef MAIN_H
-#define MAIN_H
+#ifndef FR_INIT_H
+#define FR_INIT_H
 
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gio/gio.h>
 #include "preferences.h"
 #include "fr-process.h"
 #include "fr-window.h"
 
-
 typedef struct {
 	FrWindow  *window;
 	FrProcess *process;
@@ -48,26 +43,20 @@ typedef struct {
 	char      *temp_dir;
 } CommandData;
 
-
-void  viewer_done      (ViewerData  *vdata);
-void  command_done     (CommandData *cdata);
-
-
-extern GList       *WindowList;
-extern GList       *CommandList;
-extern gint         ForceDirectoryCreation;
-extern GHashTable  *ProgramsCache;
-extern GPtrArray   *Registered_Commands;
-
-extern FrMimeTypeDescription mime_type_desc[];
-extern FrExtensionType file_ext_type[];
-extern int single_file_save_type[]; /* File types that can be saved when
-				     * a single file is selected.
-				     * Includes single file compressors
-				     * such as gzip, compress, etc. */
-extern int save_type[];             /* File types that can be saved. */
-extern int open_type[];             /* File types that can be opened. */
-extern int create_type[];           /* File types that can be created. */
+extern GList                 *WindowList;
+extern GList                 *CommandList;
+extern gint                   ForceDirectoryCreation;
+extern GHashTable            *ProgramsCache;
+extern GPtrArray             *Registered_Commands;
+extern FrMimeTypeDescription  mime_type_desc[];
+extern FrExtensionType        file_ext_type[];
+extern int                    single_file_save_type[]; /* File types that can be saved when
+ 	 	 	 	 	 	 	* a single file is selected.
+ 	 	 	 	 	 	 	* Includes single file compressors
+ 	 	 	 	 	 	 	* such as gzip, compress, etc. */
+extern int                    save_type[];             /* File types that can be saved. */
+extern int                    open_type[];             /* File types that can be opened. */
+extern int                    create_type[];           /* File types that can be created. */
 
 GType        get_command_type_from_mime_type         (const char    *mime_type,
 						      FrCommandCaps  requested_capabilities);
@@ -79,5 +68,7 @@ const char * get_archive_filename_extension          (const char    *uri);
 int          get_mime_type_index                     (const char    *mime_type);
 void         sort_mime_types_by_extension            (int           *a);
 void         sort_mime_types_by_description          (int           *a);
-		                              
-#endif /* MAIN_H */
+void         initialize_data                         (void);
+void         release_data                            (void);
+
+#endif /* FR_INIT_H */
diff --git a/src/fr-marshal.list b/src/fr-marshal.list
index d3fcc1a..d5d5313 100644
--- a/src/fr-marshal.list
+++ b/src/fr-marshal.list
@@ -4,5 +4,6 @@ VOID:INT,POINTER
 VOID:POINTER
 VOID:VOID
 VOID:DOUBLE
+VOID:DOUBLE,STRING
 VOID:STRING
 VOID:BOOL
diff --git a/src/fr-window.c b/src/fr-window.c
index 8b43c63..1b5e2e3 100644
--- a/src/fr-window.c
+++ b/src/fr-window.c
@@ -47,7 +47,7 @@
 #include "file-data.h"
 #include "file-utils.h"
 #include "glib-utils.h"
-#include "main.h"
+#include "fr-init.h"
 #include "gtk-utils.h"
 #include "open-file.h"
 #include "typedefs.h"
@@ -233,6 +233,8 @@ fr_clipboard_data_set_password (FrClipboardData *clipboard_data,
 
 enum {
 	ARCHIVE_LOADED,
+	PROGRESS,
+	READY,
 	LAST_SIGNAL
 };
 
@@ -371,6 +373,9 @@ struct _FrWindowPrivateData {
 	FrAction          pd_last_action;
 	char             *pd_last_archive;
 	char             *working_archive;
+	double            pd_last_fraction;
+	char             *pd_last_message;
+	gboolean          use_progress_dialog;
 
 	/* update dialog data */
 
@@ -622,6 +627,7 @@ fr_window_free_private_data (FrWindow *window)
 	fr_window_reset_current_batch_action (window);
 
 	g_free (window->priv->pd_last_archive);
+	g_free (window->priv->pd_last_message);
 	g_free (window->priv->extract_here_dir);
 	g_free (window->priv->last_status_message);
 
@@ -665,12 +671,14 @@ fr_window_finalize (GObject *object)
 					      gh_unref_pixbuf,
 					      NULL);
 			g_hash_table_destroy (pixbuf_hash);
+			pixbuf_hash = NULL;
 		}
 		if (tree_pixbuf_hash != NULL) {
 			g_hash_table_foreach (tree_pixbuf_hash,
 					      gh_unref_pixbuf,
 					      NULL);
 			g_hash_table_destroy (tree_pixbuf_hash);
+			tree_pixbuf_hash = NULL;
 		}
 
 		gtk_main_quit ();
@@ -732,6 +740,25 @@ fr_window_class_init (FrWindowClass *class)
 			      fr_marshal_VOID__BOOLEAN,
 			      G_TYPE_NONE, 1,
 			      G_TYPE_BOOLEAN);
+	fr_window_signals[PROGRESS] =
+		g_signal_new ("progress",
+			      G_TYPE_FROM_CLASS (class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (FrWindowClass, progress),
+			      NULL, NULL,
+			      fr_marshal_VOID__DOUBLE_STRING,
+			      G_TYPE_NONE, 2,
+			      G_TYPE_DOUBLE,
+			      G_TYPE_STRING);
+	fr_window_signals[READY] =
+		g_signal_new ("ready",
+			      G_TYPE_FROM_CLASS (class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (FrWindowClass, ready),
+			      NULL, NULL,
+			      fr_marshal_VOID__POINTER,
+			      G_TYPE_NONE, 1,
+			      G_TYPE_POINTER);
 
 	gobject_class = (GObjectClass*) class;
 	gobject_class->finalize = fr_window_finalize;
@@ -785,6 +812,7 @@ fr_window_init (FrWindow *window)
 	window->priv = g_new0 (FrWindowPrivateData, 1);
 	window->priv->update_dropped_files = FALSE;
 	window->priv->filter_mode = FALSE;
+	window->priv->use_progress_dialog = TRUE;
 
 	g_signal_connect (window,
 			  "realize",
@@ -2434,9 +2462,20 @@ fr_window_message_cb (FrCommand  *command,
 
 		if (g_utf8_validate (utf8_msg, -1, NULL))
 			gtk_label_set_text (GTK_LABEL (window->priv->pd_message), utf8_msg);
+
+		g_free (window->priv->pd_last_message);
+		window->priv->pd_last_message = g_strdup (utf8_msg);
+
+		g_signal_emit (G_OBJECT (window),
+			       fr_window_signals[PROGRESS],
+			       0,
+			       window->priv->pd_last_fraction,
+			       window->priv->pd_last_message);
+
 #ifdef LOG_PROGRESS
 		g_print ("message > %s\n", utf8_msg);
 #endif
+
 		g_free (utf8_msg);
 	}
 
@@ -2594,7 +2633,7 @@ display_progress_dialog (gpointer data)
 	if (window->priv->progress_timeout != 0)
 		g_source_remove (window->priv->progress_timeout);
 
-	if (window->priv->progress_dialog != NULL) {
+	if (window->priv->use_progress_dialog && (window->priv->progress_dialog != NULL)) {
 		gtk_dialog_set_response_sensitive (GTK_DIALOG (window->priv->progress_dialog),
 						   GTK_RESPONSE_OK,
 						   window->priv->stoppable);
@@ -2660,6 +2699,15 @@ fr_window_progress_cb (FrCommand  *command,
 		if (window->priv->progress_dialog != NULL)
 			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->pd_progress_bar), fraction);
 		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->progress_bar), fraction);
+
+		window->priv->pd_last_fraction = fraction;
+
+		g_signal_emit (G_OBJECT (window),
+			       fr_window_signals[PROGRESS],
+			       0,
+			       window->priv->pd_last_fraction,
+			       window->priv->pd_last_message);
+
 #ifdef LOG_PROGRESS
 		g_print ("progress > %2.2f\n", fraction);
 #endif
@@ -2831,23 +2879,42 @@ error_dialog_response_cb (GtkDialog *dialog,
 	if ((dialog_parent != NULL) && (gtk_widget_get_toplevel (GTK_WIDGET (dialog_parent)) != (GtkWidget*) dialog_parent))
 		gtk_window_set_modal (dialog_parent, TRUE);
 	gtk_widget_destroy (GTK_WIDGET (dialog));
+
 	if (window->priv->destroy_with_error_dialog)
 		gtk_widget_destroy (GTK_WIDGET (window));
 }
 
 
 static void
-fr_window_show_error_dialog (FrWindow  *window,
-			     GtkWidget *dialog,
-			     GtkWindow *dialog_parent)
+fr_window_show_error_dialog (FrWindow   *window,
+			     GtkWidget  *dialog,
+			     GtkWindow  *dialog_parent,
+			     const char *details)
 {
+	if (window->priv->batch_mode && ! window->priv->use_progress_dialog) {
+		GError *error;
+
+		error = g_error_new_literal (FR_ERROR, FR_PROC_ERROR_GENERIC, details ? details : _("Command exited abnormally."));
+		g_signal_emit (window,
+			       fr_window_signals[READY],
+			       0,
+			       error);
+
+		gtk_widget_destroy (GTK_WIDGET (window));
+
+		return;
+	}
+
 	close_progress_dialog (window, TRUE);
 
+	if (window->priv->batch_mode)
+		fr_window_destroy_with_error_dialog (window);
+
 	if (dialog_parent != NULL)
 		gtk_window_set_modal (dialog_parent, FALSE);
 	g_signal_connect (dialog,
 			  "response",
-			  (window->priv->batch_mode) ? G_CALLBACK (gtk_main_quit) : G_CALLBACK (error_dialog_response_cb),
+			  G_CALLBACK (error_dialog_response_cb),
 			  window);
 	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
 	gtk_widget_show (dialog);
@@ -2984,7 +3051,7 @@ handle_errors (FrWindow    *window,
 						msg,
 						((details != NULL) ? "%s" : NULL),
 						details);
-		fr_window_show_error_dialog (window, dialog, dialog_parent);
+		fr_window_show_error_dialog (window, dialog, dialog_parent, details);
 
 		return FALSE;
 	}
@@ -5542,6 +5609,8 @@ fr_window_construct (FrWindow *window)
 	window->priv->current_batch_action.free_func = NULL;
 
 	window->priv->pd_last_archive = NULL;
+	window->priv->pd_last_message = NULL;
+	window->priv->pd_last_fraction = 0.0;
 
 	/* Create the widgets. */
 
@@ -6653,18 +6722,22 @@ fr_window_archive_extract (FrWindow   *window,
 		}
 
 		if (! do_not_extract && ! ensure_dir_exists (edata->extract_to_dir, 0755, &error)) {
-			GtkWidget  *d;
+			GtkWidget *d;
+			char      *details;
 
+			details = g_strdup_printf (_("Could not create the destination folder: %s."), error->message);
 			d = _gtk_error_dialog_new (GTK_WINDOW (window),
 						   0,
 						   NULL,
 						   _("Extraction not performed"),
-						   _("Could not create the destination folder: %s."),
-						   error->message);
+						   "%s",
+						   details);
 			g_clear_error (&error);
-			fr_window_show_error_dialog (window, d, GTK_WINDOW (window));
+			fr_window_show_error_dialog (window, d, GTK_WINDOW (window), details);
 			fr_window_stop_batch (window);
 
+			g_free (details);
+
 			return;
 		}
 	}
@@ -6680,7 +6753,7 @@ fr_window_archive_extract (FrWindow   *window,
 					     GTK_STOCK_OK, GTK_RESPONSE_OK,
 					     NULL);
 		gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_OK);
-		fr_window_show_error_dialog (window, d, GTK_WINDOW (window));
+		fr_window_show_error_dialog (window, d, GTK_WINDOW (window), _("Extraction not performed"));
 		fr_window_stop_batch (window);
 
 		return;
@@ -8480,6 +8553,14 @@ fr_window_set_folders_visibility (FrWindow   *window,
 }
 
 
+void
+fr_window_use_progress_dialog (FrWindow *window,
+			       gboolean  value)
+{
+	window->priv->use_progress_dialog = value;
+}
+
+
 /* -- batch mode procedures -- */
 
 
@@ -8617,6 +8698,13 @@ fr_window_exec_batch_action (FrWindow      *window,
 	case FR_BATCH_ACTION_QUIT:
 		debug (DEBUG_INFO, "[BATCH] QUIT\n");
 
+		g_signal_emit (window,
+			       fr_window_signals[READY],
+			       0,
+			       NULL);
+
+		if ((window->priv->progress_dialog != NULL) && (gtk_widget_get_parent (window->priv->progress_dialog) != GTK_WIDGET (window)))
+			gtk_widget_destroy (window->priv->progress_dialog);
 		gtk_widget_destroy (GTK_WIDGET (window));
 		break;
 
diff --git a/src/fr-window.h b/src/fr-window.h
index d5d0207..8b4f72e 100644
--- a/src/fr-window.h
+++ b/src/fr-window.h
@@ -92,8 +92,13 @@ struct _FrWindowClass
 
 	/*<signals>*/
 
-	void (*archive_loaded) (FrWindow *window,
-				gboolean  success);
+	void (*archive_loaded) (FrWindow   *window,
+				gboolean    success);
+	void (*progress)       (FrWindow   *window,
+			        double      fraction,
+			        const char *msg);
+	void (*ready)          (FrWindow   *window,
+				GError     *error);
 };
 
 GType       fr_window_get_type                  (void);
@@ -273,6 +278,8 @@ void        fr_window_set_statusbar_visibility    (FrWindow   *window,
 						   gboolean    value);
 void        fr_window_set_folders_visibility      (FrWindow   *window,
 						   gboolean    value);
+void        fr_window_use_progress_dialog         (FrWindow   *window,
+						   gboolean    value);
 
 /* batch mode procedures. */
 
diff --git a/src/main.c b/src/main.c
index cb934cc..b126ef6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -24,50 +24,16 @@
 #include <sys/types.h>
 #include <signal.h>
 #include <stdlib.h>
+#include <glib/gi18n.h>
+#include <glib.h>
 #include <gio/gio.h>
-#include "file-utils.h"
-#include "glib-utils.h"
-#include "fr-command.h"
-#include "fr-command-ace.h"
-#include "fr-command-alz.h"
-#include "fr-command-ar.h"
-#include "fr-command-arj.h"
-#include "fr-command-cfile.h"
-#include "fr-command-cpio.h"
-#include "fr-command-dpkg.h"
-#include "fr-command-iso.h"
-#include "fr-command-jar.h"
-#include "fr-command-lha.h"
-#include "fr-command-rar.h"
-#include "fr-command-rpm.h"
-#include "fr-command-tar.h"
-#include "fr-command-unstuff.h"
-#include "fr-command-zip.h"
-#include "fr-command-zoo.h"
-#include "fr-command-7z.h"
-#include "fr-command-lrzip.h"
-#include "fr-process.h"
-#include "fr-stock.h"
-#include "fr-window.h"
-#include "typedefs.h"
-#include "preferences.h"
-#include "file-data.h"
-#include "main.h"
-
 #include "eggsmclient.h"
-
-static void     prepare_app         (void);
-static void     initialize_data     (void);
-static void     release_data        (void);
+#include "fr-init.h"
 
 GList        *WindowList = NULL;
-GList        *CommandList = NULL;
 gint          ForceDirectoryCreation;
-GHashTable   *ProgramsCache = NULL;
-GPtrArray    *Registered_Commands = NULL;
 
 static char **remaining_args;
-
 static char  *add_to = NULL;
 static int    add;
 static char  *extract_to = NULL;
@@ -75,118 +41,10 @@ static int    extract;
 static int    extract_here;
 static char  *default_url = NULL;
 
-/* The capabilities are computed automatically in
- * compute_supported_archive_types() so it's correct to initialize to 0 here. */
-FrMimeTypeDescription mime_type_desc[] = {
-	{ "application/x-7z-compressed",        ".7z",       N_("7-Zip (.7z)"), 0 },
-	{ "application/x-7z-compressed-tar",    ".tar.7z",   N_("Tar compressed with 7z (.tar.7z)"), 0 },
-	{ "application/x-ace",                  ".ace",      N_("Ace (.ace)"), 0 },
-	{ "application/x-alz",                  ".alz",      NULL, 0 },
-	{ "application/x-ar",                   ".ar",       N_("Ar (.ar)"), 0 },
-	{ "application/x-arj",                  ".arj",      N_("Arj (.arj)"), 0 },
-	{ "application/x-bzip",                 ".bz2",      NULL, 0 },
-	{ "application/x-bzip-compressed-tar",  ".tar.bz2",  N_("Tar compressed with bzip2 (.tar.bz2)"), 0 },
-	{ "application/x-bzip1",                ".bz",       NULL, 0 },
-	{ "application/x-bzip1-compressed-tar", ".tar.bz",   N_("Tar compressed with bzip (.tar.bz)"), 0 },
-	{ "application/vnd.ms-cab-compressed",  ".cab",      N_("Cabinet (.cab)"), 0 },
-	{ "application/x-cbr",                  ".cbr",      N_("Rar Archived Comic Book (.cbr)"), 0 },
-	{ "application/x-cbz",                  ".cbz",      N_("Zip Archived Comic Book (.cbz)"), 0 },
-	{ "application/x-cd-image",             ".iso",      NULL, 0 },
-	{ "application/x-compress",             ".Z",        NULL, 0 },
-	{ "application/x-compressed-tar",       ".tar.gz",   N_("Tar compressed with gzip (.tar.gz)"), 0 },
-	{ "application/x-cpio",                 ".cpio",     NULL, 0 },
-	{ "application/x-deb",                  ".deb",      NULL, 0 },
-	{ "application/x-ear",                  ".ear",      N_("Ear (.ear)"), 0 },
-	{ "application/x-ms-dos-executable",    ".exe",      N_("Self-extracting zip (.exe)"), 0 },
-	{ "application/x-gzip",                 ".gz",       NULL, 0 },
-	{ "application/x-java-archive",         ".jar",      N_("Jar (.jar)"), 0 },
-	{ "application/x-lha",                  ".lzh",      N_("Lha (.lzh)"), 0 },
-	{ "application/x-lrzip",                ".lrz",      N_("Lrzip (.lrz)"), 0},
-	{ "application/x-lrzip-compressed-tar", ".tar.lrz",  N_("Tar compressed with lrzip (.tar.lrz)"), 0 },
-	{ "application/x-lzip",                 ".lz",       NULL, 0 },
-	{ "application/x-lzip-compressed-tar",  ".tar.lz",   N_("Tar compressed with lzip (.tar.lz)"), 0 },
-	{ "application/x-lzma",                 ".lzma",     NULL, 0 },
-	{ "application/x-lzma-compressed-tar",  ".tar.lzma", N_("Tar compressed with lzma (.tar.lzma)"), 0 },
-	{ "application/x-lzop",                 ".lzo",      NULL, 0 },
-	{ "application/x-lzop-compressed-tar",  ".tar.lzo",  N_("Tar compressed with lzop (.tar.lzo)"), 0 },
-	{ "application/x-ms-wim",               ".wim",      N_("Windows Imaging Format (.wim)"), 0 },
-	{ "application/x-rar",                  ".rar",      N_("Rar (.rar)"), 0 },
-	{ "application/x-rpm",                  ".rpm",      NULL, 0 },
-	{ "application/x-rzip",                 ".rz",       NULL, 0 },
-	{ "application/x-tar",                  ".tar",      N_("Tar uncompressed (.tar)"), 0 },
-	{ "application/x-tarz",                 ".tar.Z",    N_("Tar compressed with compress (.tar.Z)"), 0 },
-	{ "application/x-stuffit",              ".sit",      NULL, 0 },
-	{ "application/x-war",                  ".war",      N_("War (.war)"), 0 },
-	{ "application/x-xz",                   ".xz",       N_("Xz (.xz)"), 0 },
-	{ "application/x-xz-compressed-tar",    ".tar.xz",   N_("Tar compressed with xz (.tar.xz)"), 0 },
-	{ "application/x-zoo",                  ".zoo",      N_("Zoo (.zoo)"), 0 },
-	{ "application/zip",                    ".zip",      N_("Zip (.zip)"), 0 },
-	{ NULL, NULL, NULL, 0 }
-};
+static guint  startup_id = 0;
 
-FrExtensionType file_ext_type[] = {
-	{ ".7z", "application/x-7z-compressed" },
-	{ ".ace", "application/x-ace" },
-	{ ".alz", "application/x-alz" },
-	{ ".ar", "application/x-ar" },
-	{ ".arj", "application/x-arj" },
-	{ ".bin", "application/x-stuffit" },
-	{ ".bz", "application/x-bzip" },
-	{ ".bz2", "application/x-bzip" },
-	{ ".cab", "application/vnd.ms-cab-compressed" },
-	{ ".cbr", "application/x-cbr" },
-	{ ".cbz", "application/x-cbz" },
-	{ ".cpio", "application/x-cpio" },
-	{ ".deb", "application/x-deb" },
-	{ ".ear", "application/x-ear" },
-	{ ".exe", "application/x-ms-dos-executable" },
-	{ ".gz", "application/x-gzip" },
-	{ ".iso", "application/x-cd-image" },
-	{ ".jar", "application/x-java-archive" },
-	{ ".lha", "application/x-lha" },
-	{ ".lrz", "application/x-lrzip" },
-	{ ".lzh", "application/x-lha" },
-	{ ".lz", "application/x-lzip" },
-	{ ".lzma", "application/x-lzma" },
-	{ ".lzo", "application/x-lzop" },
-	{ ".rar", "application/x-rar" },
-	{ ".rpm", "application/x-rpm" },
-	{ ".rz", "application/x-rzip" },
-	{ ".sit", "application/x-stuffit" },
-	{ ".swm", "application/x-ms-wim" },
-	{ ".tar", "application/x-tar" },
-	{ ".tar.bz", "application/x-bzip-compressed-tar" },
-	{ ".tar.bz2", "application/x-bzip-compressed-tar" },
-	{ ".tar.gz", "application/x-compressed-tar" },
-	{ ".tar.lrz", "application/x-lrzip-compressed-tar" },
-	{ ".tar.lz", "application/x-lzip-compressed-tar" },
-	{ ".tar.lzma", "application/x-lzma-compressed-tar" },
-	{ ".tar.lzo", "application/x-lzop-compressed-tar" },
-	{ ".tar.7z", "application/x-7z-compressed-tar" },
-	{ ".tar.xz", "application/x-xz-compressed-tar" },
-	{ ".tar.Z", "application/x-tarz" },
-	{ ".taz", "application/x-tarz" },
-	{ ".tbz", "application/x-bzip-compressed-tar" },
-	{ ".tbz2", "application/x-bzip-compressed-tar" },
-	{ ".tgz", "application/x-compressed-tar" },
-	{ ".txz", "application/x-xz-compressed-tar" },
-	{ ".tlz", "application/x-lzip-compressed-tar" },
-	{ ".tzma", "application/x-lzma-compressed-tar" },
-	{ ".tzo", "application/x-lzop-compressed-tar" },
-	{ ".war", "application/x-war" },
-	{ ".wim", "application/x-ms-wim" },
-	{ ".xz", "application/x-xz" },
-	{ ".z", "application/x-gzip" },
-	{ ".Z", "application/x-compress" },
-	{ ".zip", "application/zip" },
-	{ ".zoo", "application/x-zoo" },
-	{ NULL, NULL }
-};
-
-int single_file_save_type[64];
-int save_type[64];
-int open_type[64];
-int create_type[64];
+/* argv[0] from main(); used as the command to restart the program */
+static const char *program_argv0 = NULL;
 
 static const GOptionEntry options[] = {
 	{ "add-to", 'a', 0, G_OPTION_ARG_STRING, &add_to,
@@ -225,580 +83,6 @@ static const GOptionEntry options[] = {
 };
 
 
-/* -- Main -- */
-
-
-static guint startup_id = 0;
-
-/* argv[0] from main(); used as the command to restart the program */
-static const char *program_argv0 = NULL;
-
-
-static gboolean
-startup_cb (gpointer data)
-{
-	g_source_remove (startup_id);
-	startup_id = 0;
-
-	initialize_data ();
-	prepare_app ();
-
-	return FALSE;
-}
-
-
-static void
-fr_save_state (EggSMClient *client, GKeyFile *state, gpointer user_data)
-{
-	/* discard command is automatically set by EggSMClient */
-
-	GList *window;
-	const char *argv[2] = { NULL };
-	guint i;
-
-	/* restart command */
-	argv[0] = program_argv0;
-	argv[1] = NULL;
-
-	egg_sm_client_set_restart_command (client, 1, argv);
-
-	/* state */
-	for (window = WindowList, i = 0; window; window = window->next, i++) {
-		FrWindow *session = window->data;
-		gchar *key;
-
-		key = g_strdup_printf ("archive%d", i);
-		if ((session->archive == NULL) || (session->archive->file == NULL)) {
-			g_key_file_set_string (state, "Session", key, "");
-		} else {
-			gchar *uri;
-
-			uri = g_file_get_uri (session->archive->file);
-			g_key_file_set_string (state, "Session", key, uri);
-			g_free (uri);
-		}
-		g_free (key);
-	}
-
-	g_key_file_set_integer (state, "Session", "archives", i);
-}
-
-int
-main (int argc, char **argv)
-{
-	GError *error = NULL;
-	EggSMClient *client = NULL;
-	GOptionContext *context = NULL;
-
-	program_argv0 = argv[0];
-
-	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
-	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-	textdomain (GETTEXT_PACKAGE);
-
-	context = g_option_context_new (N_("- Create and modify an archive"));
-	g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
-	g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
-
-	g_option_context_add_group (context, gtk_get_option_group (TRUE));
-	g_option_context_add_group (context, egg_sm_client_get_option_group ());
-
-	if (! g_option_context_parse (context, &argc, &argv, &error)) {
-		g_critical ("Failed to parse arguments: %s", error->message);
-		g_error_free (error);
-		g_option_context_free (context);
-		return EXIT_FAILURE;
-	}
-
-	g_option_context_free (context);
-
-	g_set_application_name (_("File Roller"));
-	gtk_window_set_default_icon_name ("file-roller");
-
-	client = egg_sm_client_get ();
-	g_signal_connect (client, "save-state", G_CALLBACK (fr_save_state), NULL);
-
-	gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
-					   PKG_DATA_DIR G_DIR_SEPARATOR_S "icons");
-
-	fr_stock_init ();
-	/* init_session (argv); */
-	startup_id = g_idle_add (startup_cb, NULL);
-	gtk_main ();
-	release_data ();
-
-	return 0;
-}
-
-/* Initialize application data. */
-
-
-static void
-initialize_data (void)
-{
-	ProgramsCache = g_hash_table_new_full (g_str_hash,
-					       g_str_equal,
-					       g_free,
-					       NULL);
-}
-
-/* Free application data. */
-
-
-void
-command_done (CommandData *cdata)
-{
-	if (cdata == NULL)
-		return;
-
-	if ((cdata->temp_dir != NULL) && path_is_dir (cdata->temp_dir)) {
-		char *argv[4];
-
-		argv[0] = "rm";
-		argv[1] = "-rf";
-		argv[2] = cdata->temp_dir;
-		argv[3] = NULL;
-		g_spawn_sync (g_get_tmp_dir (), argv, NULL,
-			      G_SPAWN_SEARCH_PATH,
-			      NULL, NULL,
-			      NULL, NULL, NULL,
-			      NULL);
-	}
-
-	g_free (cdata->command);
-	if (cdata->app != NULL)
-		g_object_unref (cdata->app);
-	path_list_free (cdata->file_list);
-	g_free (cdata->temp_dir);
-	if (cdata->process != NULL)
-		g_object_unref (cdata->process);
-
-	CommandList = g_list_remove (CommandList, cdata);
-	g_free (cdata);
-}
-
-
-static void
-release_data ()
-{
-	g_hash_table_destroy (ProgramsCache);
-
-	while (CommandList != NULL) {
-		CommandData *cdata = CommandList->data;
-		command_done (cdata);
-	}
-}
-
-
-/* -- FrRegisteredCommand -- */
-
-
-FrRegisteredCommand *
-fr_registered_command_new (GType command_type)
-{
-	FrRegisteredCommand  *reg_com;
-	FrCommand            *command;
-	const char          **mime_types;
-	int                   i;
-
-	reg_com = g_new0 (FrRegisteredCommand, 1);
-	reg_com->ref = 1;
-	reg_com->type = command_type;
-	reg_com->caps = g_ptr_array_new ();
-	reg_com->packages = g_ptr_array_new ();
-
-	command = (FrCommand*) g_object_new (reg_com->type, NULL);
-	mime_types = fr_command_get_mime_types (command);
-	for (i = 0; mime_types[i] != NULL; i++) {
-		const char         *mime_type;
-		FrMimeTypeCap      *cap;
-		FrMimeTypePackages *packages;
-
-		mime_type = get_static_string (mime_types[i]);
-
-		cap = g_new0 (FrMimeTypeCap, 1);
-		cap->mime_type = mime_type;
-		cap->current_capabilities = fr_command_get_capabilities (command, mime_type, TRUE);
-		cap->potential_capabilities = fr_command_get_capabilities (command, mime_type, FALSE);
-		g_ptr_array_add (reg_com->caps, cap);
-
-		packages = g_new0 (FrMimeTypePackages, 1);
-		packages->mime_type = mime_type;
-		packages->packages = fr_command_get_packages (command, mime_type);
-		g_ptr_array_add (reg_com->packages, packages);
-	}
-
-	g_object_unref (command);
-
-	return reg_com;
-}
-
-
-void
-fr_registered_command_ref (FrRegisteredCommand *reg_com)
-{
-	reg_com->ref++;
-}
-
-
-void
-fr_registered_command_unref (FrRegisteredCommand *reg_com)
-{
-	if (--(reg_com->ref) != 0)
-		return;
-
-	g_ptr_array_foreach (reg_com->caps, (GFunc) g_free, NULL);
-	g_ptr_array_free (reg_com->caps, TRUE);
-	g_free (reg_com);
-}
-
-
-FrCommandCaps
-fr_registered_command_get_capabilities (FrRegisteredCommand *reg_com,
-				        const char          *mime_type)
-{
-	int i;
-
-	for (i = 0; i < reg_com->caps->len; i++) {
-		FrMimeTypeCap *cap;
-
-		cap = g_ptr_array_index (reg_com->caps, i);
-		if (strcmp (mime_type, cap->mime_type) == 0)
-			return cap->current_capabilities;
-	}
-
-	return FR_COMMAND_CAN_DO_NOTHING;
-}
-
-
-FrCommandCaps
-fr_registered_command_get_potential_capabilities (FrRegisteredCommand *reg_com,
-						  const char          *mime_type)
-{
-	int i;
-
-	if (mime_type == NULL)
-		return FR_COMMAND_CAN_DO_NOTHING;
-
-	for (i = 0; i < reg_com->caps->len; i++) {
-		FrMimeTypeCap *cap;
-
-		cap = g_ptr_array_index (reg_com->caps, i);
-		if ((cap->mime_type != NULL) && (strcmp (mime_type, cap->mime_type) == 0))
-			return cap->potential_capabilities;
-	}
-
-	return FR_COMMAND_CAN_DO_NOTHING;
-}
-
-
-void
-register_command (GType command_type)
-{
-	if (Registered_Commands == NULL)
-		Registered_Commands = g_ptr_array_sized_new (5);
-	g_ptr_array_add (Registered_Commands, fr_registered_command_new (command_type));
-}
-
-
-gboolean
-unregister_command (GType command_type)
-{
-	int i;
-
-	for (i = 0; i < Registered_Commands->len; i++) {
-		FrRegisteredCommand *command;
-
-		command = g_ptr_array_index (Registered_Commands, i);
-		if (command->type == command_type) {
-			g_ptr_array_remove_index (Registered_Commands, i);
-			fr_registered_command_unref (command);
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-
-static void
-register_commands (void)
-{
-	/* The order here is important. Commands registered earlier have higher
-	 * priority.  However commands that can read and write a file format
-	 * have higher priority over commands that can only read the same
-	 * format, regardless of the registration order. */
-
-	register_command (FR_TYPE_COMMAND_TAR);
-	register_command (FR_TYPE_COMMAND_CFILE);
-	register_command (FR_TYPE_COMMAND_7Z);
-	register_command (FR_TYPE_COMMAND_DPKG);
-
-	register_command (FR_TYPE_COMMAND_ACE);
-	register_command (FR_TYPE_COMMAND_ALZ);
-	register_command (FR_TYPE_COMMAND_AR);
-	register_command (FR_TYPE_COMMAND_ARJ);
-	register_command (FR_TYPE_COMMAND_CPIO);
-	register_command (FR_TYPE_COMMAND_ISO);
-	register_command (FR_TYPE_COMMAND_JAR);
-	register_command (FR_TYPE_COMMAND_LHA);
-	register_command (FR_TYPE_COMMAND_RAR);
-	register_command (FR_TYPE_COMMAND_RPM);
-	register_command (FR_TYPE_COMMAND_UNSTUFF);
-	register_command (FR_TYPE_COMMAND_ZIP);
-	register_command (FR_TYPE_COMMAND_LRZIP);
-	register_command (FR_TYPE_COMMAND_ZOO);
-}
-
-
-GType
-get_command_type_from_mime_type (const char    *mime_type,
-				 FrCommandCaps  requested_capabilities)
-{
-	int i;
-
-	if (mime_type == NULL)
-		return 0;
-
-	for (i = 0; i < Registered_Commands->len; i++) {
-		FrRegisteredCommand *command;
-		FrCommandCaps        capabilities;
-
-		command = g_ptr_array_index (Registered_Commands, i);
-		capabilities = fr_registered_command_get_capabilities (command, mime_type);
-
-		/* the command must support all the requested capabilities */
-		if (((capabilities ^ requested_capabilities) & requested_capabilities) == 0)
-			return command->type;
-	}
-
-	return 0;
-}
-
-
-GType
-get_preferred_command_for_mime_type (const char    *mime_type,
-				     FrCommandCaps  requested_capabilities)
-{
-	int i;
-
-	for (i = 0; i < Registered_Commands->len; i++) {
-		FrRegisteredCommand *command;
-		FrCommandCaps        capabilities;
-
-		command = g_ptr_array_index (Registered_Commands, i);
-		capabilities = fr_registered_command_get_potential_capabilities (command, mime_type);
-
-		/* the command must support all the requested capabilities */
-		if (((capabilities ^ requested_capabilities) & requested_capabilities) == 0)
-			return command->type;
-	}
-
-	return 0;
-}
-
-
-void
-update_registered_commands_capabilities (void)
-{
-	int i;
-
-	g_hash_table_remove_all (ProgramsCache);
-
-	for (i = 0; i < Registered_Commands->len; i++) {
-		FrRegisteredCommand *reg_com;
-		FrCommand           *command;
-		int                  j;
-
-		reg_com = g_ptr_array_index (Registered_Commands, i);
-		command = (FrCommand*) g_object_new (reg_com->type, NULL);
-		for (j = 0; j < reg_com->caps->len; j++) {
-			FrMimeTypeCap *cap = g_ptr_array_index (reg_com->caps, j);
-
-			cap->current_capabilities = fr_command_get_capabilities (command, cap->mime_type, TRUE);
-			cap->potential_capabilities = fr_command_get_capabilities (command, cap->mime_type, FALSE);
-		}
-
-		g_object_unref (command);
-	}
-}
-
-
-const char *
-get_mime_type_from_extension (const char *ext)
-{
-	int i;
-
-	if (ext == NULL)
-		return NULL;
-
-	for (i = G_N_ELEMENTS (file_ext_type) - 1; i >= 0; i--) {
-		if (file_ext_type[i].ext == NULL)
-			continue;
-		if (strcasecmp (ext, file_ext_type[i].ext) == 0)
-			return get_static_string (file_ext_type[i].mime_type);
-	}
-
-	return NULL;
-}
-
-
-const char *
-get_archive_filename_extension (const char *filename)
-{
-	const char *ext;
-	int         i;
-
-	if (filename == NULL)
-		return NULL;
-
-	ext = get_file_extension (filename);
-	if (ext == NULL)
-		return NULL;
-
-	for (i = G_N_ELEMENTS (file_ext_type) - 1; i >= 0; i--) {
-		if (file_ext_type[i].ext == NULL)
-			continue;
-		if (strcasecmp (ext, file_ext_type[i].ext) == 0)
-			return ext;
-	}
-
-	return NULL;
-}
-
-
-int
-get_mime_type_index (const char *mime_type)
-{
-	int i;
-
-	for (i = 0; mime_type_desc[i].mime_type != NULL; i++)
-		if (strcmp (mime_type_desc[i].mime_type, mime_type) == 0)
-			return i;
-	return -1;
-}
-
-
-static void
-add_if_non_present (int *a,
-	            int *n,
-	            int  o)
-{
-	int i;
-
-	for (i = 0; i < *n; i++) {
-		if (a[i] == o)
-			return;
-	}
-	a[*n] = o;
-	*n = *n + 1;
-}
-
-
-static int
-cmp_mime_type_by_extension (const void *p1,
-			    const void *p2)
-{
-	int i1 = * (int*) p1;
-	int i2 = * (int*) p2;
-
-	return strcmp (mime_type_desc[i1].default_ext, mime_type_desc[i2].default_ext);
-}
-
-
-static int
-cmp_mime_type_by_description (const void *p1,
-			      const void *p2)
-{
-	int i1 = * (int*) p1;
-	int i2 = * (int*) p2;
-
-	return g_utf8_collate (_(mime_type_desc[i1].name), _(mime_type_desc[i2].name));
-}
-
-
-static void
-sort_mime_types (int *a,
-                 int(*compar)(const void *, const void *))
-{
-	int n = 0;
-
-	while (a[n] != -1)
-		n++;
-	qsort (a, n, sizeof (int), compar);
-}
-
-
-void
-sort_mime_types_by_extension (int *a)
-{
-	sort_mime_types (a, cmp_mime_type_by_extension);
-}
-
-
-void
-sort_mime_types_by_description (int *a)
-{
-	sort_mime_types (a, cmp_mime_type_by_description);
-}
-
-
-static void
-compute_supported_archive_types (void)
-{
-	int sf_i = 0, s_i = 0, o_i = 0, c_i = 0;
-	int i;
-
-	for (i = 0; i < Registered_Commands->len; i++) {
-		FrRegisteredCommand *reg_com;
-		int                  j;
-
-		reg_com = g_ptr_array_index (Registered_Commands, i);
-		for (j = 0; j < reg_com->caps->len; j++) {
-			FrMimeTypeCap *cap;
-			int            idx;
-
-			cap = g_ptr_array_index (reg_com->caps, j);
-			idx = get_mime_type_index (cap->mime_type);
-			if (idx < 0) {
-				g_warning ("mime type not recognized: %s", cap->mime_type);
-				continue;
-			}
-			mime_type_desc[idx].capabilities |= cap->current_capabilities;
-			if (cap->current_capabilities & FR_COMMAND_CAN_READ)
-				add_if_non_present (open_type, &o_i, idx);
-			if (cap->current_capabilities & FR_COMMAND_CAN_WRITE) {
-				if (cap->current_capabilities & FR_COMMAND_CAN_ARCHIVE_MANY_FILES) {
-					add_if_non_present (save_type, &s_i, idx);
-					if (cap->current_capabilities & FR_COMMAND_CAN_WRITE)
-						add_if_non_present (create_type, &c_i, idx);
-				}
-				add_if_non_present (single_file_save_type, &sf_i, idx);
-			}
-		}
-	}
-
-	open_type[o_i] = -1;
-	save_type[s_i] = -1;
-	single_file_save_type[sf_i] = -1;
-	create_type[c_i] = -1;
-}
-
-
-static char *
-get_uri_from_command_line (const char *path)
-{
-	GFile *file;
-	char  *uri;
-
-	file = g_file_new_for_commandline_arg (path);
-	uri = g_file_get_uri (file);
-	g_object_unref (file);
-
-	return uri;
-}
-
-
 static void
 fr_restore_session (EggSMClient *client)
 {
@@ -827,29 +111,17 @@ fr_restore_session (EggSMClient *client)
 }
 
 
-static void
-migrate_options_directory (void)
+static char *
+get_uri_from_command_line (const char *path)
 {
-	char *old_directory_path;
-	GFile *old_directory;
-	GFile *new_directory;
-
-	old_directory_path = get_home_relative_path (".gnome2/file-roller/options");
-	old_directory = g_file_new_for_path (old_directory_path);
-	new_directory = get_user_config_subdirectory (ADD_FOLDER_OPTIONS_DIR, FALSE);
-	if (g_file_query_exists (old_directory, NULL) && ! g_file_query_exists (new_directory, NULL)) {
-		GFile *parent;
-
-		parent = g_file_get_parent (new_directory);
-		if (make_directory_tree (parent, 0700, NULL))
-			g_file_move (old_directory, new_directory, 0, NULL, NULL, NULL, NULL);
+	GFile *file;
+	char  *uri;
 
-		g_object_unref (parent);
-	}
+	file = g_file_new_for_commandline_arg (path);
+	uri = g_file_get_uri (file);
+	g_object_unref (file);
 
-	g_object_unref (new_directory);
-	g_object_unref (old_directory);
-	g_free (old_directory_path);
+	return uri;
 }
 
 
@@ -860,10 +132,6 @@ prepare_app (void)
 	char        *add_to_uri = NULL;
 	EggSMClient *client = NULL;
 
-	migrate_options_directory ();
-	register_commands ();
-	compute_supported_archive_types ();
-
 	client = egg_sm_client_get ();
 	if (egg_sm_client_is_resumed (client)) {
 		fr_restore_session (client);
@@ -961,3 +229,98 @@ prepare_app (void)
 	g_free (add_to_uri);
 	g_free (extract_to_uri);
 }
+
+
+static gboolean
+startup_cb (gpointer data)
+{
+	g_source_remove (startup_id);
+	startup_id = 0;
+
+	initialize_data ();
+	prepare_app ();
+
+	return FALSE;
+}
+
+
+static void
+fr_save_state (EggSMClient *client, GKeyFile *state, gpointer user_data)
+{
+	/* discard command is automatically set by EggSMClient */
+
+	GList *window;
+	const char *argv[2] = { NULL };
+	guint i;
+
+	/* restart command */
+	argv[0] = program_argv0;
+	argv[1] = NULL;
+
+	egg_sm_client_set_restart_command (client, 1, argv);
+
+	/* state */
+	for (window = WindowList, i = 0; window; window = window->next, i++) {
+		FrWindow *session = window->data;
+		gchar *key;
+
+		key = g_strdup_printf ("archive%d", i);
+		if ((session->archive == NULL) || (session->archive->file == NULL)) {
+			g_key_file_set_string (state, "Session", key, "");
+		} else {
+			gchar *uri;
+
+			uri = g_file_get_uri (session->archive->file);
+			g_key_file_set_string (state, "Session", key, uri);
+			g_free (uri);
+		}
+		g_free (key);
+	}
+
+	g_key_file_set_integer (state, "Session", "archives", i);
+}
+
+int
+main (int argc, char **argv)
+{
+	GOptionContext *context = NULL;
+	GError         *error = NULL;
+	EggSMClient    *client = NULL;
+
+	program_argv0 = argv[0];
+
+	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+
+	context = g_option_context_new (N_("- Create and modify an archive"));
+	g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
+	g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
+
+	g_option_context_add_group (context, gtk_get_option_group (TRUE));
+	g_option_context_add_group (context, egg_sm_client_get_option_group ());
+
+	if (! g_option_context_parse (context, &argc, &argv, &error)) {
+		g_critical ("Failed to parse arguments: %s", error->message);
+		g_error_free (error);
+		g_option_context_free (context);
+		return EXIT_FAILURE;
+	}
+
+	g_option_context_free (context);
+
+	g_set_application_name (_("File Roller"));
+	gtk_window_set_default_icon_name ("file-roller");
+
+	client = egg_sm_client_get ();
+	g_signal_connect (client, "save-state", G_CALLBACK (fr_save_state), NULL);
+
+	gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
+					   PKG_DATA_DIR G_DIR_SEPARATOR_S "icons");
+
+	startup_id = g_idle_add (startup_cb, NULL);
+	gtk_main ();
+	release_data ();
+
+	return 0;
+}
diff --git a/src/preferences.c b/src/preferences.c
index 7286cd2..7afcea3 100644
--- a/src/preferences.c
+++ b/src/preferences.c
@@ -22,7 +22,7 @@
 #include <string.h>
 #include "typedefs.h"
 #include "preferences.h"
-#include "main.h"
+#include "fr-init.h"
 #include "file-utils.h"
 #include "fr-window.h"
 
diff --git a/src/server.c b/src/server.c
new file mode 100644
index 0000000..9e3e2a2
--- /dev/null
+++ b/src/server.c
@@ -0,0 +1,421 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  File-Roller
+ *
+ *  Copyright (C) 2010 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 <glib/gi18n.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include "file-utils.h"
+#include "fr-init.h"
+
+
+#define FR_SERVICE_NAME "org.gnome.FileRoller"
+#define FR_SERVICE_PATH "/org/gnome/FileRoller"
+
+
+static const char introspection_xml[] =
+	"<node>"
+	"  <interface name='org.gnome.ArchiveManager'>"
+
+#if 0
+	/**
+	 * GetSuppertedTypes:
+	 *
+	 * Returns the supported archive types for a specific action.
+	 *
+	 * Input arguments:
+	 *
+	 * @action:
+	 *   Can be one of the following values: create, extract
+	 *
+	 * Output arguments:
+	 *
+	 * @types:
+	 *   The supported archive types described as an array of tuples, where
+	 *   the tuple is composed by: the mime type, the default extension,
+	 *   a human readable description.
+	 */
+
+	"    <method name='GetSuppertedTypes'>"
+	"      <arg name='action' type='s' direction='in'/>"
+	"      <arg name='types' type='a(sss)' direction='out'/>"
+	"    </method>"
+#endif
+
+	/**
+	 * AddToArchive:
+	 *
+	 * Adds the specified files to an archive.  If the archive already
+	 * exists the archive is updated.
+	 *
+	 * Input arguments:
+	 *
+	 * @archive:
+	 *   The archive URI.
+	 * @files:
+	 *   The files to add to the archive, as an array of URIs.
+	 */
+
+	"    <method name='AddToArchive'>"
+	"      <arg name='archive' type='s' direction='in'/>"
+	"      <arg name='files' type='as' direction='in'/>"
+	"      <arg name='use_progress_dialog' type='b' direction='in'/>"
+	"    </method>"
+
+	/**
+	 * Compress:
+	 *
+	 * Compresses a series of files in an archive. The user is asked to
+	 * enter an archive name, archive type and other options.  In this case
+	 * it's used the same dialog used by the "Compress..." command from the
+	 * Nautilus context menu.
+	 * If the user chooses an existing archive, the archive is updated.
+	 *
+	 * Input arguments:
+	 *
+	 * @files:
+	 *   The files to add to the archive, as an array of URIs.
+	 * @destination:
+	 *   An optional destination, if not specified the folder of the first
+	 *   file in @files is used.
+	 */
+
+	"    <method name='Compress'>"
+	"      <arg name='files' type='as' direction='in'/>"
+	"      <arg name='destination' type='s' direction='in'/>"
+	"      <arg name='use_progress_dialog' type='b' direction='in'/>"
+	"    </method>"
+
+	/**
+	 * Extract:
+	 *
+	 * Extract an archive in a specified location.
+	 *
+	 * Input arguments:
+	 *
+	 * @archive:
+	 *   The archive to extract.
+	 * @destination:
+	 *   The location where to extract the archive.
+	 */
+
+	"    <method name='Extract'>"
+	"      <arg name='archive' type='s' direction='in'/>"
+	"      <arg name='destination' type='s' direction='in'/>"
+	"      <arg name='use_progress_dialog' type='b' direction='in'/>"
+	"    </method>"
+
+	/**
+	 * ExtractHere:
+	 *
+	 * Extract an archive in a specified location.
+	 *
+	 * Input arguments:
+	 *
+	 * @archive:
+	 *   The archive to extract.
+	 */
+
+	"    <method name='ExtractHere'>"
+	"      <arg name='archive' type='s' direction='in'/>"
+	"      <arg name='use_progress_dialog' type='b' direction='in'/>"
+	"    </method>"
+
+	/**
+	 * Progress (signal)
+	 *
+	 * Arguments:
+	 *
+	 * @fraction:
+	 *   number from 0.0 to 100.0 that indicates the percentage of
+	 *   completion of the operation.
+	 * @details:
+	 *   text message that describes the current operation.
+	 */
+	"    <signal name='Progress'>"
+	"      <arg name='fraction' type='d'/>"
+	"      <arg name='details' type='s'/>"
+	"    </signal>"
+
+	"  </interface>"
+	"</node>";
+
+static GDBusNodeInfo *introspection_data = NULL;
+
+
+static void
+window_ready_cb (GtkWidget *widget,
+		 GError    *error,
+		 gpointer   user_data)
+{
+	if (error == NULL)
+		g_dbus_method_invocation_return_value ((GDBusMethodInvocation *) user_data, NULL);
+	else
+		g_dbus_method_invocation_return_error ((GDBusMethodInvocation *) user_data,
+						       error->domain,
+						       error->code,
+						       "%s",
+						       error->message);
+}
+
+
+static gboolean
+window_progress_cb (FrWindow *window,
+		    double    fraction,
+		    char     *details,
+		    gpointer  user_data)
+{
+	GDBusConnection *connection = user_data;
+
+	g_dbus_connection_emit_signal (connection,
+				       NULL,
+				       FR_SERVICE_PATH,
+				       "org.gnome.ArchiveManager",
+				       "Progress",
+				       g_variant_new ("(ds)",
+						      fraction,
+						      details),
+				       NULL);
+}
+
+
+static void
+handle_method_call (GDBusConnection       *connection,
+		    const char            *sender,
+		    const char            *object_path,
+		    const char            *interface_name,
+		    const char            *method_name,
+		    GVariant              *parameters,
+		    GDBusMethodInvocation *invocation,
+		    gpointer               user_data)
+{
+	update_registered_commands_capabilities ();
+
+	if (g_strcmp0 (method_name, "GetSuppertedTypes") == 0) {
+		/* TODO */
+	}
+	else if (g_strcmp0 (method_name, "AddToArchive") == 0) {
+		char       *archive;
+		char      **files;
+		gboolean    use_progress_dialog;
+		int         i;
+		GList      *file_list = NULL;
+		GtkWidget  *window;
+
+		g_variant_get (parameters, "(s^asb)", &archive, &files, &use_progress_dialog);
+
+		for (i = 0; files[i] != NULL; i++)
+			file_list = g_list_prepend (file_list, files[i]);
+		file_list = g_list_reverse (file_list);
+
+		window = fr_window_new ();
+		fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
+
+		g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
+		g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
+
+		fr_window_new_batch (FR_WINDOW (window));
+		fr_window_set_batch__add (FR_WINDOW (window), archive, file_list);
+		fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
+		fr_window_start_batch (FR_WINDOW (window));
+
+		g_free (archive);
+
+		gtk_main ();
+	}
+	else if (g_strcmp0 (method_name, "Compress") == 0) {
+		char      **files;
+		char       *destination;
+		gboolean    use_progress_dialog;
+		int         i;
+		GList      *file_list = NULL;
+		GtkWidget  *window;
+
+		g_variant_get (parameters, "(^assb)", &files, &destination, &use_progress_dialog);
+
+		for (i = 0; files[i] != NULL; i++)
+			file_list = g_list_prepend (file_list, files[i]);
+		file_list = g_list_reverse (file_list);
+
+		if ((destination == NULL) || (strcmp (destination, "") == 0))
+			destination = remove_level_from_path (file_list->data);
+
+		window = fr_window_new ();
+		fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
+		fr_window_set_default_dir (FR_WINDOW (window), destination, TRUE);
+
+		g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
+		g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
+
+		fr_window_new_batch (FR_WINDOW (window));
+		fr_window_set_batch__add (FR_WINDOW (window), NULL, file_list);
+		fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
+		fr_window_start_batch (FR_WINDOW (window));
+
+		g_free (destination);
+
+		gtk_main ();
+	}
+	else if (g_strcmp0 (method_name, "Extract") == 0) {
+		char      *archive;
+		char      *destination;
+		gboolean   use_progress_dialog;
+		GtkWidget *window;
+
+		g_variant_get (parameters, "(ssb)", &archive, &destination, &use_progress_dialog);
+
+		window = fr_window_new ();
+		fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
+		if ((destination != NULL) & (strcmp (destination, "") != 0))
+			fr_window_set_default_dir (FR_WINDOW (window), destination, TRUE);
+
+		g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
+		g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
+
+		fr_window_new_batch (FR_WINDOW (window));
+		fr_window_set_batch__extract (FR_WINDOW (window), archive, destination);
+		fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
+		fr_window_start_batch (FR_WINDOW (window));
+
+		g_free (destination);
+		g_free (archive);
+
+		gtk_main ();
+	}
+	else if (g_strcmp0 (method_name, "ExtractHere") == 0) {
+		char      *archive;
+		gboolean   use_progress_dialog;
+		GtkWidget *window;
+
+		g_variant_get (parameters, "(sb)", &archive, &use_progress_dialog);
+
+		window = fr_window_new ();
+		fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
+
+		g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
+		g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
+
+		fr_window_new_batch (FR_WINDOW (window));
+		fr_window_set_batch__extract_here (FR_WINDOW (window), archive);
+		fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
+		fr_window_start_batch (FR_WINDOW (window));
+
+		g_free (archive);
+
+		gtk_main ();
+	}
+}
+
+
+static const GDBusInterfaceVTable interface_vtable = {
+	handle_method_call,
+	NULL, 			/* handle_get_property */
+	NULL 			/* handle_set_property */
+};
+
+
+static void
+on_bus_acquired (GDBusConnection *connection,
+		 const char      *name,
+		 gpointer         user_data)
+{
+	guint registration_id;
+
+	registration_id = g_dbus_connection_register_object (connection,
+							     FR_SERVICE_PATH,
+							     introspection_data->interfaces[0],
+							     &interface_vtable,
+							     NULL,
+							     NULL,  /* user_data_free_func */
+							     NULL); /* GError** */
+	g_assert (registration_id > 0);
+
+	initialize_data ();
+}
+
+
+static void
+on_name_acquired (GDBusConnection *connection,
+		  const char      *name,
+		  gpointer         user_data)
+{
+}
+
+
+static void
+on_name_lost (GDBusConnection *connection,
+	      const char      *name,
+	      gpointer         user_data)
+{
+	gtk_main_quit ();
+}
+
+
+int
+main (int argc, char *argv[])
+{
+	GOptionContext *context = NULL;
+	GError         *error = NULL;
+	guint           owner_id;
+
+	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+
+	context = g_option_context_new (N_("- Create and modify an archive"));
+	g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
+	g_option_context_add_group (context, gtk_get_option_group (TRUE));
+
+	if (! g_option_context_parse (context, &argc, &argv, &error)) {
+		g_critical ("Failed to parse arguments: %s", error->message);
+		g_error_free (error);
+		g_option_context_free (context);
+		return EXIT_FAILURE;
+	}
+
+	g_option_context_free (context);
+
+	g_set_application_name (_("File Roller"));
+	gtk_window_set_default_icon_name ("file-roller");
+
+	gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
+					   PKG_DATA_DIR G_DIR_SEPARATOR_S "icons");
+
+	introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+	g_assert (introspection_data != NULL);
+
+	owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+				   FR_SERVICE_NAME,
+				   G_BUS_NAME_OWNER_FLAGS_NONE,
+				   on_bus_acquired,
+				   on_name_acquired,
+				   on_name_lost,
+				   NULL,
+				   NULL);
+
+	gtk_main ();
+
+	g_bus_unown_name (owner_id);
+	g_dbus_node_info_unref (introspection_data);
+
+	return 0;
+}
diff --git a/src/test-server.c b/src/test-server.c
new file mode 100644
index 0000000..4d499df
--- /dev/null
+++ b/src/test-server.c
@@ -0,0 +1,178 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  File-Roller
+ *
+ *  Copyright (C) 2010 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 <gio/gio.h>
+
+
+GMainLoop *loop;
+
+
+static void
+fileroller_addtoarchive_ready_cb (GObject      *source_object,
+				  GAsyncResult *res,
+				  gpointer      user_data)
+{
+	GDBusProxy *proxy;
+	GVariant   *values;
+	GError     *error = NULL;
+
+	proxy = G_DBUS_PROXY (source_object);
+	values = g_dbus_proxy_call_finish (proxy, res, &error);
+	if (values == NULL) {
+		g_error ("%s\n", error->message);
+		g_clear_error (&error);
+	}
+
+	if (values != NULL)
+		g_variant_unref (values);
+	g_object_unref (proxy);
+
+	g_main_loop_quit (loop);
+}
+
+
+static void
+on_signal (GDBusProxy *proxy,
+	   char       *sender_name,
+	   char       *signal_name,
+	   GVariant   *parameters,
+	   gpointer    user_data)
+{
+	if (g_strcmp0 (signal_name, "Progress") == 0) {
+		double  fraction;
+		char   *details;
+
+		g_variant_get (parameters, "(ds)", &fraction, &details);
+		g_print ("Progress: %f (%s)\n", fraction, details);
+
+		g_free (details);
+	}
+}
+
+
+int
+main (int argc, char *argv[])
+{
+	GDBusConnection *connection;
+	GError          *error = NULL;
+
+	g_type_init ();
+
+	connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+	if (connection != NULL) {
+		GDBusProxy *proxy;
+
+		proxy = g_dbus_proxy_new_sync (connection,
+					       G_DBUS_PROXY_FLAGS_NONE,
+					       NULL,
+					       "org.gnome.FileRoller",
+					       "/org/gnome/FileRoller",
+					       "org.gnome.ArchiveManager",
+					       NULL,
+					       &error);
+
+		if (proxy != NULL) {
+
+			g_signal_connect (proxy,
+			                  "g-signal",
+			                  G_CALLBACK (on_signal),
+			                  NULL);
+
+			/* -- AddToArchive -- */
+
+			char  *archive;
+			char **files;
+
+			archive = g_strdup ("file:///home/paolo/Scrivania/firefox-4.0b8pre.tar.gz");
+			files = g_new0 (char *, 2);
+			files[0] = g_strdup ("file:///home/paolo/Scrivania/firefox-4.0b8pre");
+			files[1] = NULL;
+
+			g_dbus_proxy_call (proxy,
+					   "AddToArchive",
+					   g_variant_new ("(s^asb)", archive, files, FALSE),
+					   G_DBUS_CALL_FLAGS_NONE,
+					   G_MAXINT,
+					   NULL,
+					   fileroller_addtoarchive_ready_cb,
+					   NULL);
+
+			g_free (archive);
+			g_strfreev (files);
+
+			/* -- Compress --
+
+			char **files;
+			char  *destination;
+
+			files = g_new0 (char *, 2);
+			files[0] = g_strdup ("file:///home/paolo/Scrivania/firefox-4.0b8pre");
+			files[1] = NULL;
+			destination = g_strdup ("file:///home/paolo/Scrivania");
+
+			g_dbus_proxy_call (proxy,
+					   "Compress",
+					   g_variant_new ("(^assb)", files, destination, TRUE),
+					   G_DBUS_CALL_FLAGS_NONE,
+					   G_MAXINT,
+					   NULL,
+					   fileroller_addtoarchive_ready_cb,
+					   NULL);
+
+			g_strfreev (files);
+			g_free (destination);
+			*/
+
+			/* -- Extract --
+
+			g_dbus_proxy_call (proxy,
+					   "Extract",
+					   g_variant_new ("(ssb)",
+							  "file:///home/paolo/Scrivania/test.tar.gz",
+							  "file:///home/paolo/Scrivania",
+							  TRUE),
+					   G_DBUS_CALL_FLAGS_NONE,
+					   G_MAXINT,
+					   NULL,
+					   fileroller_addtoarchive_ready_cb,
+					   NULL);
+			*/
+
+			/* -- ExtractHere --
+
+			g_dbus_proxy_call (proxy,
+					   "ExtractHere",
+					   g_variant_new ("(sb)",
+					                  "file:///home/paolo/Scrivania/test.tar.gz",
+					                  TRUE),
+					   G_DBUS_CALL_FLAGS_NONE,
+					   G_MAXINT,
+					   NULL,
+					   fileroller_addtoarchive_ready_cb,
+					   NULL);
+			*/
+		}
+	}
+
+	loop = g_main_loop_new (NULL, FALSE);
+	g_main_loop_run (loop);
+}



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