fr_archive_libarchive_add_files (FrArchive           *archive,
				 GList               *file_list,
				 GFile               *base_dir,
				 const char          *dest_dir,
				 gboolean             update,
				 gboolean             follow_links,
				 const char          *password,
				 gboolean             encrypt_header,
				 FrCompression        compression,
				 guint                volume_size,
				 GCancellable        *cancellable,
				 GAsyncReadyCallback  callback,
				 gpointer             user_data)
{
	AddData *add_data;
	GList   *scan;

	g_return_if_fail (base_dir != NULL);

	add_data = add_data_new ();
	add_data->follow_links = follow_links;

	if (dest_dir != NULL)
		dest_dir = (dest_dir[0] == '/' ? dest_dir + 1 : dest_dir);
	else
		dest_dir = "";

	for (scan = file_list; scan; scan = scan->next) {
		GFile *file = G_FILE (scan->data);
		char  *relative_pathname;
		char  *archive_pathname;

		relative_pathname = g_file_get_relative_path (base_dir, file);
		archive_pathname = g_build_filename (dest_dir, relative_pathname, NULL);
		g_hash_table_insert (add_data->files_to_add,
				     g_strdup (archive_pathname),
				     add_file_new (file, archive_pathname));
		add_data->n_files_to_add++;

		g_free (archive_pathname);
		g_free (relative_pathname);
	}

	_fr_archive_libarchive_save (archive,
				     update,
				     password,
				     encrypt_header,
				     compression,
				     volume_size,
				     cancellable,
				     g_simple_async_result_new (G_OBJECT (archive),
				     				callback,
				     				user_data,
				     				fr_archive_add_files),
				     _add_files_begin,
				     _add_files_end,
				     _add_files_entry_action,
				     add_data,
				     (GDestroyNotify) add_data_free);
}
fr_archive_libarchive_add_files (FrArchive           *archive,
				 GList               *file_list,
				 GFile               *base_dir,
				 const char          *dest_dir,
				 gboolean             update,
				 gboolean             follow_links,
				 const char          *password,
				 gboolean             encrypt_header,
				 FrCompression        compression,
				 guint                volume_size,
				 GCancellable        *cancellable,
				 GAsyncReadyCallback  callback,
				 gpointer             user_data)
{
	AddData *add_data;
	GList   *scan;

	g_return_if_fail (base_dir != NULL);

	add_data = add_data_new ();
	add_data->follow_links = follow_links;

	if (dest_dir != NULL)
		dest_dir = (dest_dir[0] == '/' ? dest_dir + 1 : dest_dir);
	else
		dest_dir = "";

	for (scan = file_list; scan; scan = scan->next) {
		GFile *file = G_FILE (scan->data);
		char  *relative_pathname;
		char  *archive_pathname;

		relative_pathname = g_file_get_relative_path (base_dir, file);
		archive_pathname = g_build_filename (dest_dir, relative_pathname, NULL);
		g_hash_table_insert (add_data->files_to_add,
				     g_strdup (archive_pathname),
				     add_file_new (file, archive_pathname));
		add_data->n_files_to_add++;

		g_free (archive_pathname);
		g_free (relative_pathname);
	}

	_fr_archive_libarchive_save (archive,
				     update,
				     password,
				     encrypt_header,
				     compression,
				     volume_size,
				     cancellable,
				     g_simple_async_result_new (G_OBJECT (archive),
				     				callback,
				     				user_data,
				     				fr_archive_add_files),
				     _add_files_begin,
				     _add_files_end,
				     _add_files_entry_action,
				     add_data,
				     (GDestroyNotify) add_data_free);
}