|
Packit Bot |
201734 |
/* vim: set sw=2 ts=2 sts=2 et: */
|
|
Packit Bot |
201734 |
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
Packit Bot |
201734 |
/*
|
|
Packit Bot |
201734 |
* autoar-compressor.c
|
|
Packit Bot |
201734 |
* Automatically create archives in some GNOME programs
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Copyright (C) 2013 Ting-Wei Lan
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* This program is free software; you can redistribute it and/or
|
|
Packit Bot |
201734 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit Bot |
201734 |
* License as published by the Free Software Foundation; either
|
|
Packit Bot |
201734 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Bot |
201734 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Bot |
201734 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Bot |
201734 |
* Lesser General Public License for more details.
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Bot |
201734 |
* License along with this program; if not, write to the
|
|
Packit Bot |
201734 |
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
Packit Bot |
201734 |
* Boston, MA 02110-1301, USA.
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
*/
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
#include "config.h"
|
|
Packit Bot |
201734 |
#include "autoar-compressor.h"
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
#include "autoar-misc.h"
|
|
Packit Bot |
201734 |
#include "autoar-private.h"
|
|
Packit Bot |
201734 |
#include "autoar-format-filter.h"
|
|
Packit Bot |
201734 |
#include "autoar-enum-types.h"
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
#include <archive.h>
|
|
Packit Bot |
201734 |
#include <archive_entry.h>
|
|
Packit Bot |
201734 |
#include <gio/gio.h>
|
|
Packit Bot |
201734 |
#include <glib.h>
|
|
Packit Bot |
201734 |
#include <stdarg.h>
|
|
Packit Bot |
201734 |
#include <sys/stat.h>
|
|
Packit Bot |
201734 |
#include <sys/types.h>
|
|
Packit Bot |
201734 |
#include <unistd.h>
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* SECTION:autoar-compressor
|
|
Packit Bot |
201734 |
* @Short_description: Automatically compress files
|
|
Packit Bot |
201734 |
* @Title: AutoarCompressor
|
|
Packit Bot |
201734 |
* @Include: gnome-autoar/autoar.h
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* The #AutoarCompressor object is used to automatically compress files and
|
|
Packit Bot |
201734 |
* directories into an archive. The new archive can contain a top-level directory.
|
|
Packit Bot |
201734 |
* Applying multiple filters is currently not supported because most
|
|
Packit Bot |
201734 |
* applications do not need this function. GIO is used for both read and write
|
|
Packit Bot |
201734 |
* operations. A few POSIX functions are also used to get more information from
|
|
Packit Bot |
201734 |
* files if GIO does not provide relevant functions.
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* When #AutoarCompressor stop all work, it will emit one of the three signals:
|
|
Packit Bot |
201734 |
* #AutoarCompressor::cancelled, #AutoarCompressor::error, and
|
|
Packit Bot |
201734 |
* #AutoarCompressor::completed. After one of these signals is received, the
|
|
Packit Bot |
201734 |
* #AutoarCompressor object should be destroyed because it cannot be used to
|
|
Packit Bot |
201734 |
* start another archive operation. An #AutoarCompressor object can only be
|
|
Packit Bot |
201734 |
* used once and create one archive.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_quark:
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Gets the #AutoarCompressor Error Quark.
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: a #GQuark.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
G_DEFINE_QUARK (autoar-compressor, autoar_compressor)
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
#define BUFFER_SIZE (64 * 1024)
|
|
Packit Bot |
201734 |
#define ARCHIVE_WRITE_RETRY_TIMES 5
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
#define INVALID_FORMAT 1
|
|
Packit Bot |
201734 |
#define INVALID_FILTER 2
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
struct _AutoarCompressor
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
GObject parent_instance;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
GList *source_files;
|
|
Packit Bot |
201734 |
GFile *output_file;
|
|
Packit Bot |
201734 |
AutoarFormat format;
|
|
Packit Bot |
201734 |
AutoarFilter filter;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
int output_is_dest : 1;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
guint64 size; /* This field is currently unused */
|
|
Packit Bot |
201734 |
guint64 completed_size;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
guint files;
|
|
Packit Bot |
201734 |
guint completed_files;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
gint64 notify_last;
|
|
Packit Bot |
201734 |
gint64 notify_interval;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
GOutputStream *ostream;
|
|
Packit Bot |
201734 |
void *buffer;
|
|
Packit Bot |
201734 |
gssize buffer_size;
|
|
Packit Bot |
201734 |
GError *error;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
GCancellable *cancellable;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
struct archive *a;
|
|
Packit Bot |
201734 |
struct archive_entry *entry;
|
|
Packit Bot |
201734 |
struct archive_entry_linkresolver *resolver;
|
|
Packit Bot |
201734 |
GFile *dest;
|
|
Packit Bot |
201734 |
GHashTable *pathname_to_g_file;
|
|
Packit Bot |
201734 |
char *source_basename_noext;
|
|
Packit Bot |
201734 |
char *extension;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
int in_thread : 1;
|
|
Packit Bot |
201734 |
gboolean create_top_level_directory;
|
|
Packit Bot |
201734 |
};
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
G_DEFINE_TYPE (AutoarCompressor, autoar_compressor, G_TYPE_OBJECT)
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
enum
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
DECIDE_DEST,
|
|
Packit Bot |
201734 |
PROGRESS,
|
|
Packit Bot |
201734 |
CANCELLED,
|
|
Packit Bot |
201734 |
COMPLETED,
|
|
Packit Bot |
201734 |
AR_ERROR,
|
|
Packit Bot |
201734 |
LAST_SIGNAL
|
|
Packit Bot |
201734 |
};
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
enum
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
PROP_0,
|
|
Packit Bot |
201734 |
PROP_SOURCE_FILES,
|
|
Packit Bot |
201734 |
PROP_OUTPUT_FILE,
|
|
Packit Bot |
201734 |
PROP_FORMAT,
|
|
Packit Bot |
201734 |
PROP_FILTER,
|
|
Packit Bot |
201734 |
PROP_CREATE_TOP_LEVEL_DIRECTORY,
|
|
Packit Bot |
201734 |
PROP_SIZE, /* This property is currently unused */
|
|
Packit Bot |
201734 |
PROP_COMPLETED_SIZE,
|
|
Packit Bot |
201734 |
PROP_FILES,
|
|
Packit Bot |
201734 |
PROP_COMPLETED_FILES,
|
|
Packit Bot |
201734 |
PROP_OUTPUT_IS_DEST,
|
|
Packit Bot |
201734 |
PROP_NOTIFY_INTERVAL
|
|
Packit Bot |
201734 |
};
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static guint autoar_compressor_signals[LAST_SIGNAL] = { 0 };
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_get_property (GObject *object,
|
|
Packit Bot |
201734 |
guint property_id,
|
|
Packit Bot |
201734 |
GValue *value,
|
|
Packit Bot |
201734 |
GParamSpec *pspec)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
AutoarCompressor *self;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self = AUTOAR_COMPRESSOR (object);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
switch (property_id) {
|
|
Packit Bot |
201734 |
case PROP_SOURCE_FILES:
|
|
Packit Bot |
201734 |
g_value_set_pointer (value, self->source_files);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_OUTPUT_FILE:
|
|
Packit Bot |
201734 |
g_value_set_object (value, self->output_file);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_FORMAT:
|
|
Packit Bot |
201734 |
g_value_set_enum (value, self->format);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_FILTER:
|
|
Packit Bot |
201734 |
g_value_set_enum (value, self->format);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_CREATE_TOP_LEVEL_DIRECTORY:
|
|
Packit Bot |
201734 |
g_value_set_boolean (value, self->create_top_level_directory);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_SIZE:
|
|
Packit Bot |
201734 |
g_value_set_uint64 (value, self->size);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_COMPLETED_SIZE:
|
|
Packit Bot |
201734 |
g_value_set_uint64 (value, self->completed_size);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_FILES:
|
|
Packit Bot |
201734 |
g_value_set_uint (value, self->files);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_COMPLETED_FILES:
|
|
Packit Bot |
201734 |
g_value_set_uint (value, self->completed_files);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_OUTPUT_IS_DEST:
|
|
Packit Bot |
201734 |
g_value_set_boolean (value, self->output_is_dest);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_NOTIFY_INTERVAL:
|
|
Packit Bot |
201734 |
g_value_set_int64 (value, self->notify_interval);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
default:
|
|
Packit Bot |
201734 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_set_property (GObject *object,
|
|
Packit Bot |
201734 |
guint property_id,
|
|
Packit Bot |
201734 |
const GValue *value,
|
|
Packit Bot |
201734 |
GParamSpec *pspec)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
AutoarCompressor *self;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self = AUTOAR_COMPRESSOR (object);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
switch (property_id) {
|
|
Packit Bot |
201734 |
case PROP_SOURCE_FILES:
|
|
Packit Bot |
201734 |
if (self->source_files != NULL)
|
|
Packit Bot |
201734 |
g_list_free_full (self->source_files, g_object_unref);
|
|
Packit Bot |
201734 |
self->source_files = g_list_copy_deep (g_value_get_pointer (value),
|
|
Packit Bot |
201734 |
(GCopyFunc)g_object_ref,
|
|
Packit Bot |
201734 |
NULL);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_OUTPUT_FILE:
|
|
Packit Bot |
201734 |
autoar_common_g_object_unref (self->output_file);
|
|
Packit Bot |
201734 |
self->output_file = g_object_ref (g_value_get_object (value));
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_FORMAT:
|
|
Packit Bot |
201734 |
self->format = g_value_get_enum (value);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_FILTER:
|
|
Packit Bot |
201734 |
self->filter = g_value_get_enum (value);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_CREATE_TOP_LEVEL_DIRECTORY:
|
|
Packit Bot |
201734 |
self->create_top_level_directory = g_value_get_boolean (value);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_OUTPUT_IS_DEST:
|
|
Packit Bot |
201734 |
self->output_is_dest = g_value_get_boolean (value);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
case PROP_NOTIFY_INTERVAL:
|
|
Packit Bot |
201734 |
self->notify_interval = g_value_get_int64 (value);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
default:
|
|
Packit Bot |
201734 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_get_source_files:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Gets the list of source files.
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: (transfer none): a #GList with the source files
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
GList*
|
|
Packit Bot |
201734 |
autoar_compressor_get_source_files (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_val_if_fail (AUTOAR_IS_COMPRESSOR (self), NULL);
|
|
Packit Bot |
201734 |
return self->source_files;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_get_output_file:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* If #AutoarCompressor:output_is_dest is %FALSE, gets the directory which
|
|
Packit Bot |
201734 |
* contains the new archive. Otherwise, gets the the new archive. See
|
|
Packit Bot |
201734 |
* autoar_compressor_set_output_is_dest().
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: (transfer none): a #GFile
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
GFile*
|
|
Packit Bot |
201734 |
autoar_compressor_get_output_file (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_val_if_fail (AUTOAR_IS_COMPRESSOR (self), NULL);
|
|
Packit Bot |
201734 |
return self->output_file;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_get_format:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Gets the compression format
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: the compression format
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
AutoarFormat
|
|
Packit Bot |
201734 |
autoar_compressor_get_format (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_val_if_fail (AUTOAR_IS_COMPRESSOR (self), AUTOAR_FORMAT_0);
|
|
Packit Bot |
201734 |
return self->format;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_get_filter:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Gets the compression filter
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: the compression filter
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
AutoarFilter
|
|
Packit Bot |
201734 |
autoar_compressor_get_filter (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_val_if_fail (AUTOAR_IS_COMPRESSOR (self), AUTOAR_FILTER_0);
|
|
Packit Bot |
201734 |
return self->filter;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_get_create_top_level_directory:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Gets whether a top level directory will be created in the new archive.
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: whether a top level directory will be created
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
gboolean
|
|
Packit Bot |
201734 |
autoar_compressor_get_create_top_level_directory (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_val_if_fail (AUTOAR_IS_COMPRESSOR (self), FALSE);
|
|
Packit Bot |
201734 |
return self->create_top_level_directory;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_get_size:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Gets the size in bytes will be read when the operation is completed. This
|
|
Packit Bot |
201734 |
* value is currently unset, so calling this function is useless.
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: total file size in bytes
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
guint64
|
|
Packit Bot |
201734 |
autoar_compressor_get_size (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_val_if_fail (AUTOAR_IS_COMPRESSOR (self), 0);
|
|
Packit Bot |
201734 |
return self->size;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_get_completed_size:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Gets the size in bytes has been read from the source files and directories.
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: file size in bytes has been read
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
guint64
|
|
Packit Bot |
201734 |
autoar_compressor_get_completed_size (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_val_if_fail (AUTOAR_IS_COMPRESSOR (self), 0);
|
|
Packit Bot |
201734 |
return self->completed_size;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_get_files:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Gets the number of files will be read when the operation is completed. This
|
|
Packit Bot |
201734 |
* value is currently unset, so calling this function is useless.
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: total number of files
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
guint
|
|
Packit Bot |
201734 |
autoar_compressor_get_files (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_val_if_fail (AUTOAR_IS_COMPRESSOR (self), 0);
|
|
Packit Bot |
201734 |
return self->files;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_get_completed_files:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Gets the number of files has been read
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: number of files has been read
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
guint
|
|
Packit Bot |
201734 |
autoar_compressor_get_completed_files (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_val_if_fail (AUTOAR_IS_COMPRESSOR (self), 0);
|
|
Packit Bot |
201734 |
return self->completed_files;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_get_output_is_dest:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* See autoar_compressor_set_output_is_dest().
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: %TRUE if #AutoarCompressor:output is the location of the new
|
|
Packit Bot |
201734 |
* archive.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
gboolean
|
|
Packit Bot |
201734 |
autoar_compressor_get_output_is_dest (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_val_if_fail (AUTOAR_IS_COMPRESSOR (self), 0);
|
|
Packit Bot |
201734 |
return self->output_is_dest;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_get_notify_interval:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* See autoar_compressor_set_notify_interval().
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: the minimal interval in microseconds between the emission of the
|
|
Packit Bot |
201734 |
* #AutoarCompressor::progress signal.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
gint64
|
|
Packit Bot |
201734 |
autoar_compressor_get_notify_interval (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_val_if_fail (AUTOAR_IS_COMPRESSOR (self), 0);
|
|
Packit Bot |
201734 |
return self->notify_interval;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_set_output_is_dest:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
* @output_is_dest: %TRUE if the location of the new archive has been already
|
|
Packit Bot |
201734 |
* decided
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* By default #AutoarCompressor:output-is-dest is set to %FALSE, which means
|
|
Packit Bot |
201734 |
* the new archive will be created as a regular file under
|
|
Packit Bot |
201734 |
* #AutoarCompressor:output directory. The name of the new archive will be
|
|
Packit Bot |
201734 |
* automatically generated and you will be notified via
|
|
Packit Bot |
201734 |
* #AutoarCompressor::decide-dest when the name is decided. If you have already
|
|
Packit Bot |
201734 |
* decided the location of the new archive, and you do not want
|
|
Packit Bot |
201734 |
* #AutoarCompressor to decide it for you, you can set
|
|
Packit Bot |
201734 |
* #AutoarCompressor:output-is-dest to %TRUE. #AutoarCompressor will use
|
|
Packit Bot |
201734 |
* #AutoarCompressor:output as the location of the new archive, and it will
|
|
Packit Bot |
201734 |
* neither check whether the file exists nor create the necessary
|
|
Packit Bot |
201734 |
* directories for you. This function should only be called before calling
|
|
Packit Bot |
201734 |
* autoar_compressor_start() or autoar_compressor_start_async().
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
void
|
|
Packit Bot |
201734 |
autoar_compressor_set_output_is_dest (AutoarCompressor *self,
|
|
Packit Bot |
201734 |
gboolean output_is_dest)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_if_fail (AUTOAR_IS_COMPRESSOR (self));
|
|
Packit Bot |
201734 |
self->output_is_dest = output_is_dest;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_set_notify_interval:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor
|
|
Packit Bot |
201734 |
* @notify_interval: the minimal interval in microseconds
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Sets the minimal interval between emission of #AutoarCompressor::progress
|
|
Packit Bot |
201734 |
* signal. This prevent too frequent signal emission, which may cause
|
|
Packit Bot |
201734 |
* performance impact. If you do not want this feature, you can set the
|
|
Packit Bot |
201734 |
* interval to 0, so you will receive every progress update.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
void
|
|
Packit Bot |
201734 |
autoar_compressor_set_notify_interval (AutoarCompressor *self,
|
|
Packit Bot |
201734 |
gint64 notify_interval)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
g_return_if_fail (AUTOAR_IS_COMPRESSOR (self));
|
|
Packit Bot |
201734 |
g_return_if_fail (notify_interval >= 0);
|
|
Packit Bot |
201734 |
self->notify_interval = notify_interval;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_dispose (GObject *object)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
AutoarCompressor *self;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self = AUTOAR_COMPRESSOR (object);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("AutoarCompressor: dispose");
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->ostream != NULL) {
|
|
Packit Bot |
201734 |
if (!g_output_stream_is_closed (self->ostream)) {
|
|
Packit Bot |
201734 |
g_output_stream_close (self->ostream,
|
|
Packit Bot |
201734 |
self->cancellable,
|
|
Packit Bot |
201734 |
NULL);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
g_object_unref (self->ostream);
|
|
Packit Bot |
201734 |
self->ostream = NULL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_clear_object (&(self->dest));
|
|
Packit Bot |
201734 |
g_clear_object (&(self->cancellable));
|
|
Packit Bot |
201734 |
g_clear_object (&(self->output_file));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->pathname_to_g_file != NULL) {
|
|
Packit Bot |
201734 |
g_hash_table_unref (self->pathname_to_g_file);
|
|
Packit Bot |
201734 |
self->pathname_to_g_file = NULL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->source_files != NULL) {
|
|
Packit Bot |
201734 |
g_list_free_full (self->source_files, g_object_unref);
|
|
Packit Bot |
201734 |
self->source_files = NULL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
G_OBJECT_CLASS (autoar_compressor_parent_class)->dispose (object);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_finalize (GObject *object)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
AutoarCompressor *self;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self = AUTOAR_COMPRESSOR (object);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("AutoarCompressor: finalize");
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_free (self->buffer);
|
|
Packit Bot |
201734 |
self->buffer = NULL;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/* If self->error == NULL, no errors occurs. Therefore, we can safely
|
|
Packit Bot |
201734 |
* free libarchive objects because it will not call the callbacks during the
|
|
Packit Bot |
201734 |
* the process of freeing.
|
|
Packit Bot |
201734 |
* If self->error != NULL, we must free libarchive objects beforce
|
|
Packit Bot |
201734 |
* freeing self->error in order to prevent libarchive callbacks from
|
|
Packit Bot |
201734 |
* accessing freed private objects and buffers.
|
|
Packit Bot |
201734 |
*/
|
|
Packit Bot |
201734 |
if (self->a != NULL) {
|
|
Packit Bot |
201734 |
archive_write_free (self->a);
|
|
Packit Bot |
201734 |
self->a = NULL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->entry != NULL) {
|
|
Packit Bot |
201734 |
archive_entry_free (self->entry);
|
|
Packit Bot |
201734 |
self->entry = NULL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->resolver != NULL) {
|
|
Packit Bot |
201734 |
archive_entry_linkresolver_free (self->resolver);
|
|
Packit Bot |
201734 |
self->resolver = NULL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->error != NULL) {
|
|
Packit Bot |
201734 |
g_error_free (self->error);
|
|
Packit Bot |
201734 |
self->error = NULL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_free (self->source_basename_noext);
|
|
Packit Bot |
201734 |
self->source_basename_noext = NULL;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_free (self->extension);
|
|
Packit Bot |
201734 |
self->extension = NULL;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
G_OBJECT_CLASS (autoar_compressor_parent_class)->finalize (object);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static int
|
|
Packit Bot |
201734 |
libarchive_write_open_cb (struct archive *ar_write,
|
|
Packit Bot |
201734 |
void *client_data)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
AutoarCompressor *self;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("libarchive_write_open_cb: called");
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self = AUTOAR_COMPRESSOR (client_data);
|
|
Packit Bot |
201734 |
if (self->error != NULL) {
|
|
Packit Bot |
201734 |
return ARCHIVE_FATAL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self->ostream = (GOutputStream*)g_file_create (self->dest,
|
|
Packit Bot |
201734 |
G_FILE_CREATE_NONE,
|
|
Packit Bot |
201734 |
self->cancellable,
|
|
Packit Bot |
201734 |
&(self->error));
|
|
Packit Bot |
201734 |
if (self->error != NULL) {
|
|
Packit Bot |
201734 |
g_debug ("libarchive_write_open_cb: ARCHIVE_FATAL");
|
|
Packit Bot |
201734 |
return ARCHIVE_FATAL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("libarchive_write_open_cb: ARCHIVE_OK");
|
|
Packit Bot |
201734 |
return ARCHIVE_OK;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static int
|
|
Packit Bot |
201734 |
libarchive_write_close_cb (struct archive *ar_write,
|
|
Packit Bot |
201734 |
void *client_data)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
AutoarCompressor *self;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("libarchive_write_close_cb: called");
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self = AUTOAR_COMPRESSOR (client_data);
|
|
Packit Bot |
201734 |
if (self->error != NULL) {
|
|
Packit Bot |
201734 |
return ARCHIVE_FATAL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->ostream != NULL) {
|
|
Packit Bot |
201734 |
g_output_stream_close (self->ostream,
|
|
Packit Bot |
201734 |
self->cancellable, &(self->error));
|
|
Packit Bot |
201734 |
g_object_unref (self->ostream);
|
|
Packit Bot |
201734 |
self->ostream = NULL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->error != NULL) {
|
|
Packit Bot |
201734 |
g_debug ("libarchive_write_close_cb: ARCHIVE_FATAL");
|
|
Packit Bot |
201734 |
return ARCHIVE_FATAL;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("libarchive_write_close_cb: ARCHIVE_OK");
|
|
Packit Bot |
201734 |
return ARCHIVE_OK;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static ssize_t
|
|
Packit Bot |
201734 |
libarchive_write_write_cb (struct archive *ar_write,
|
|
Packit Bot |
201734 |
void *client_data,
|
|
Packit Bot |
201734 |
const void *buffer,
|
|
Packit Bot |
201734 |
size_t length)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
AutoarCompressor *self;
|
|
Packit Bot |
201734 |
gssize write_size;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("libarchive_write_write_cb: called");
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self = AUTOAR_COMPRESSOR (client_data);
|
|
Packit Bot |
201734 |
if (self->error != NULL || self->ostream == NULL) {
|
|
Packit Bot |
201734 |
return -1;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
write_size = g_output_stream_write (self->ostream,
|
|
Packit Bot |
201734 |
buffer,
|
|
Packit Bot |
201734 |
length,
|
|
Packit Bot |
201734 |
self->cancellable,
|
|
Packit Bot |
201734 |
&(self->error));
|
|
Packit Bot |
201734 |
if (self->error != NULL)
|
|
Packit Bot |
201734 |
return -1;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("libarchive_write_write_cb: %" G_GSSIZE_FORMAT, write_size);
|
|
Packit Bot |
201734 |
return write_size;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static inline void
|
|
Packit Bot |
201734 |
autoar_compressor_signal_decide_dest (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
autoar_common_g_signal_emit (self, self->in_thread,
|
|
Packit Bot |
201734 |
autoar_compressor_signals[DECIDE_DEST], 0,
|
|
Packit Bot |
201734 |
self->dest);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static inline void
|
|
Packit Bot |
201734 |
autoar_compressor_signal_progress (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
gint64 mtime;
|
|
Packit Bot |
201734 |
mtime = g_get_monotonic_time ();
|
|
Packit Bot |
201734 |
if (mtime - self->notify_last >= self->notify_interval) {
|
|
Packit Bot |
201734 |
autoar_common_g_signal_emit (self, self->in_thread,
|
|
Packit Bot |
201734 |
autoar_compressor_signals[PROGRESS], 0,
|
|
Packit Bot |
201734 |
self->completed_size,
|
|
Packit Bot |
201734 |
self->completed_files);
|
|
Packit Bot |
201734 |
self->notify_last = mtime;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static inline void
|
|
Packit Bot |
201734 |
autoar_compressor_signal_cancelled (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
autoar_common_g_signal_emit (self, self->in_thread,
|
|
Packit Bot |
201734 |
autoar_compressor_signals[CANCELLED], 0);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static inline void
|
|
Packit Bot |
201734 |
autoar_compressor_signal_completed (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
autoar_common_g_signal_emit (self, self->in_thread,
|
|
Packit Bot |
201734 |
autoar_compressor_signals[COMPLETED], 0);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static inline void
|
|
Packit Bot |
201734 |
autoar_compressor_signal_error (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
if (self->error != NULL) {
|
|
Packit Bot |
201734 |
if (self->error->domain == G_IO_ERROR &&
|
|
Packit Bot |
201734 |
self->error->code == G_IO_ERROR_CANCELLED) {
|
|
Packit Bot |
201734 |
g_error_free (self->error);
|
|
Packit Bot |
201734 |
self->error = NULL;
|
|
Packit Bot |
201734 |
autoar_compressor_signal_cancelled (self);
|
|
Packit Bot |
201734 |
} else {
|
|
Packit Bot |
201734 |
autoar_common_g_signal_emit (self, self->in_thread,
|
|
Packit Bot |
201734 |
autoar_compressor_signals[AR_ERROR], 0,
|
|
Packit Bot |
201734 |
self->error);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_do_write_data (AutoarCompressor *self,
|
|
Packit Bot |
201734 |
struct archive_entry *entry,
|
|
Packit Bot |
201734 |
GFile *file)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
int r;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_write_data: called");
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->error != NULL)
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (g_cancellable_is_cancelled (self->cancellable))
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
while ((r = archive_write_header (self->a, entry)) == ARCHIVE_RETRY);
|
|
Packit Bot |
201734 |
if (r == ARCHIVE_FATAL) {
|
|
Packit Bot |
201734 |
if (self->error == NULL)
|
|
Packit Bot |
201734 |
self->error =
|
|
Packit Bot |
201734 |
autoar_common_g_error_new_a_entry (self->a, entry);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_write_data: write header OK");
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/* Non-regular files have no content to write */
|
|
Packit Bot |
201734 |
if (archive_entry_size (entry) > 0 && archive_entry_filetype (entry) == AE_IFREG) {
|
|
Packit Bot |
201734 |
GInputStream *istream;
|
|
Packit Bot |
201734 |
ssize_t read_actual, written_actual, written_acc;
|
|
Packit Bot |
201734 |
int written_try;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_write_data: entry size is %"G_GUINT64_FORMAT,
|
|
Packit Bot |
201734 |
archive_entry_size (entry));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
written_actual = 0;
|
|
Packit Bot |
201734 |
written_try = 0;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
istream = (GInputStream*)g_file_read (file,
|
|
Packit Bot |
201734 |
self->cancellable,
|
|
Packit Bot |
201734 |
&(self->error));
|
|
Packit Bot |
201734 |
if (istream == NULL)
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
do {
|
|
Packit Bot |
201734 |
read_actual = g_input_stream_read (istream,
|
|
Packit Bot |
201734 |
self->buffer,
|
|
Packit Bot |
201734 |
self->buffer_size,
|
|
Packit Bot |
201734 |
self->cancellable,
|
|
Packit Bot |
201734 |
&(self->error));
|
|
Packit Bot |
201734 |
self->completed_size += read_actual > 0 ? read_actual : 0;
|
|
Packit Bot |
201734 |
autoar_compressor_signal_progress (self);
|
|
Packit Bot |
201734 |
if (read_actual > 0) {
|
|
Packit Bot |
201734 |
written_acc = 0;
|
|
Packit Bot |
201734 |
written_try = 0;
|
|
Packit Bot |
201734 |
do {
|
|
Packit Bot |
201734 |
written_actual =
|
|
Packit Bot |
201734 |
archive_write_data (self->a,
|
|
Packit Bot |
201734 |
(const char*)(self->buffer) + written_acc,
|
|
Packit Bot |
201734 |
read_actual);
|
|
Packit Bot |
201734 |
written_acc += written_actual > 0 ? written_actual : 0;
|
|
Packit Bot |
201734 |
written_try = written_actual ? 0 : written_try + 1;
|
|
Packit Bot |
201734 |
/* archive_write_data may return zero, so we have to limit the
|
|
Packit Bot |
201734 |
* retry times to prevent infinite loop */
|
|
Packit Bot |
201734 |
} while (written_acc < read_actual && written_actual >= 0 && written_try < ARCHIVE_WRITE_RETRY_TIMES);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
} while (read_actual > 0 && written_actual >= 0);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self->completed_files++;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_input_stream_close (istream, self->cancellable, NULL);
|
|
Packit Bot |
201734 |
g_object_unref (istream);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (read_actual < 0)
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (written_actual < 0 || written_try >= ARCHIVE_WRITE_RETRY_TIMES) {
|
|
Packit Bot |
201734 |
if (self->error == NULL)
|
|
Packit Bot |
201734 |
self->error =
|
|
Packit Bot |
201734 |
autoar_common_g_error_new_a_entry (self->a, entry);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_write_data: write data OK");
|
|
Packit Bot |
201734 |
} else {
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_write_data: no data, return now!");
|
|
Packit Bot |
201734 |
self->completed_files++;
|
|
Packit Bot |
201734 |
autoar_compressor_signal_progress (self);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_do_add_to_archive (AutoarCompressor *self,
|
|
Packit Bot |
201734 |
GFile *root,
|
|
Packit Bot |
201734 |
GFile *file)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
GFileInfo *info;
|
|
Packit Bot |
201734 |
GFileType filetype;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->error != NULL)
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (g_cancellable_is_cancelled (self->cancellable))
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
archive_entry_clear (self->entry);
|
|
Packit Bot |
201734 |
info = g_file_query_info (file, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
Packit Bot |
201734 |
self->cancellable, &(self->error));
|
|
Packit Bot |
201734 |
if (info == NULL)
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
filetype = g_file_info_get_file_type (info);
|
|
Packit Bot |
201734 |
switch (archive_format (self->a)) {
|
|
Packit Bot |
201734 |
case ARCHIVE_FORMAT_AR:
|
|
Packit Bot |
201734 |
case ARCHIVE_FORMAT_AR_GNU:
|
|
Packit Bot |
201734 |
case ARCHIVE_FORMAT_AR_BSD:
|
|
Packit Bot |
201734 |
if (filetype == G_FILE_TYPE_DIRECTORY ||
|
|
Packit Bot |
201734 |
filetype == G_FILE_TYPE_SYMBOLIC_LINK ||
|
|
Packit Bot |
201734 |
filetype == G_FILE_TYPE_SPECIAL) {
|
|
Packit Bot |
201734 |
/* ar only support regular files, so we abort this operation to
|
|
Packit Bot |
201734 |
* prevent producing a malformed archive. */
|
|
Packit Bot |
201734 |
g_object_unref (info);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
case ARCHIVE_FORMAT_ZIP:
|
|
Packit Bot |
201734 |
if (filetype == G_FILE_TYPE_SPECIAL) {
|
|
Packit Bot |
201734 |
/* Add special files to zip archives cause unknown fatal error
|
|
Packit Bot |
201734 |
* in libarchive. */
|
|
Packit Bot |
201734 |
g_object_unref (info);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
char *root_basename;
|
|
Packit Bot |
201734 |
char *pathname_relative;
|
|
Packit Bot |
201734 |
char *pathname;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
switch (archive_format (self->a)) {
|
|
Packit Bot |
201734 |
/* ar format does not support directories */
|
|
Packit Bot |
201734 |
case ARCHIVE_FORMAT_AR:
|
|
Packit Bot |
201734 |
case ARCHIVE_FORMAT_AR_GNU:
|
|
Packit Bot |
201734 |
case ARCHIVE_FORMAT_AR_BSD:
|
|
Packit Bot |
201734 |
pathname = g_file_get_basename (file);
|
|
Packit Bot |
201734 |
archive_entry_set_pathname (self->entry, pathname);
|
|
Packit Bot |
201734 |
g_free (pathname);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
default:
|
|
Packit Bot |
201734 |
root_basename = g_file_get_basename (root);
|
|
Packit Bot |
201734 |
pathname_relative = g_file_get_relative_path (root, file);
|
|
Packit Bot |
201734 |
pathname =
|
|
Packit Bot |
201734 |
g_strconcat (self->create_top_level_directory ?
|
|
Packit Bot |
201734 |
self->source_basename_noext : "",
|
|
Packit Bot |
201734 |
self->create_top_level_directory ? "/" : "",
|
|
Packit Bot |
201734 |
root_basename,
|
|
Packit Bot |
201734 |
pathname_relative != NULL ? "/" : "",
|
|
Packit Bot |
201734 |
pathname_relative != NULL ? pathname_relative : "",
|
|
Packit Bot |
201734 |
NULL);
|
|
Packit Bot |
201734 |
archive_entry_set_pathname (self->entry, pathname);
|
|
Packit Bot |
201734 |
g_free (root_basename);
|
|
Packit Bot |
201734 |
g_free (pathname_relative);
|
|
Packit Bot |
201734 |
g_free (pathname);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_add_to_archive: %s",
|
|
Packit Bot |
201734 |
archive_entry_pathname (self->entry));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
time_t atime, btime, ctime, mtime;
|
|
Packit Bot |
201734 |
long atimeu, btimeu, ctimeu, mtimeu;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
atime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS);
|
|
Packit Bot |
201734 |
btime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CREATED);
|
|
Packit Bot |
201734 |
ctime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CHANGED);
|
|
Packit Bot |
201734 |
mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
atimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
|
|
Packit Bot |
201734 |
btimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_CREATED_USEC);
|
|
Packit Bot |
201734 |
ctimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_CHANGED_USEC);
|
|
Packit Bot |
201734 |
mtimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
archive_entry_set_atime (self->entry, atime, atimeu * 1000);
|
|
Packit Bot |
201734 |
archive_entry_set_birthtime (self->entry, btime, btimeu * 1000);
|
|
Packit Bot |
201734 |
archive_entry_set_ctime (self->entry, ctime, ctimeu * 1000);
|
|
Packit Bot |
201734 |
archive_entry_set_mtime (self->entry, mtime, mtimeu * 1000);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
archive_entry_set_uid (self->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID));
|
|
Packit Bot |
201734 |
archive_entry_set_gid (self->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID));
|
|
Packit Bot |
201734 |
archive_entry_set_uname (self->entry, g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_USER));
|
|
Packit Bot |
201734 |
archive_entry_set_gname (self->entry, g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP));
|
|
Packit Bot |
201734 |
archive_entry_set_mode (self->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE));
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
archive_entry_set_size (self->entry, g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE));
|
|
Packit Bot |
201734 |
archive_entry_set_dev (self->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_DEVICE));
|
|
Packit Bot |
201734 |
archive_entry_set_ino64 (self->entry, g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_INODE));
|
|
Packit Bot |
201734 |
archive_entry_set_nlink (self->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_NLINK));
|
|
Packit Bot |
201734 |
archive_entry_set_rdev (self->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_RDEV));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
switch (filetype) {
|
|
Packit Bot |
201734 |
case G_FILE_TYPE_DIRECTORY:
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_add_to_archive: file type set to DIR");
|
|
Packit Bot |
201734 |
archive_entry_set_filetype (self->entry, AE_IFDIR);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
case G_FILE_TYPE_SYMBOLIC_LINK:
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_add_to_archive: file type set to SYMLINK");
|
|
Packit Bot |
201734 |
archive_entry_set_filetype (self->entry, AE_IFLNK);
|
|
Packit Bot |
201734 |
archive_entry_set_symlink (self->entry,
|
|
Packit Bot |
201734 |
g_file_info_get_attribute_byte_string (info,
|
|
Packit Bot |
201734 |
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET));
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
case G_FILE_TYPE_SPECIAL:
|
|
Packit Bot |
201734 |
#if (defined HAVE_STAT) && \
|
|
Packit Bot |
201734 |
(defined S_ISBLK) && (defined S_ISSOCK) && \
|
|
Packit Bot |
201734 |
(defined S_ISCHR) && (defined S_ISFIFO)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
struct stat filestat;
|
|
Packit Bot |
201734 |
char *local_pathname;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
local_pathname = g_file_get_path (file);
|
|
Packit Bot |
201734 |
if (local_pathname != NULL && stat (local_pathname, &filestat) >= 0) {
|
|
Packit Bot |
201734 |
if (S_ISBLK (filestat.st_mode)) {
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_add_to_archive: file type set to BLOCK");
|
|
Packit Bot |
201734 |
archive_entry_set_filetype (self->entry, AE_IFBLK);
|
|
Packit Bot |
201734 |
} else if (S_ISSOCK (filestat.st_mode)) {
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_add_to_archive: file type set to SOCKET");
|
|
Packit Bot |
201734 |
archive_entry_set_filetype (self->entry, AE_IFSOCK);
|
|
Packit Bot |
201734 |
} else if (S_ISCHR (filestat.st_mode)) {
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_add_to_archive: file type set to CHAR");
|
|
Packit Bot |
201734 |
archive_entry_set_filetype (self->entry, AE_IFCHR);
|
|
Packit Bot |
201734 |
} else if (S_ISFIFO (filestat.st_mode)) {
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_add_to_archive: file type set to FIFO");
|
|
Packit Bot |
201734 |
archive_entry_set_filetype (self->entry, AE_IFIFO);
|
|
Packit Bot |
201734 |
} else {
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_add_to_archive: file type set to REGULAR");
|
|
Packit Bot |
201734 |
archive_entry_set_filetype (self->entry, AE_IFREG);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
g_free (local_pathname);
|
|
Packit Bot |
201734 |
} else {
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_add_to_archive: file type set to REGULAR");
|
|
Packit Bot |
201734 |
archive_entry_set_filetype (self->entry, AE_IFREG);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
#endif
|
|
Packit Bot |
201734 |
case G_FILE_TYPE_UNKNOWN:
|
|
Packit Bot |
201734 |
case G_FILE_TYPE_SHORTCUT:
|
|
Packit Bot |
201734 |
case G_FILE_TYPE_MOUNTABLE:
|
|
Packit Bot |
201734 |
case G_FILE_TYPE_REGULAR:
|
|
Packit Bot |
201734 |
default:
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_do_add_to_archive: file type set to REGULAR");
|
|
Packit Bot |
201734 |
archive_entry_set_filetype (self->entry, AE_IFREG);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_hash_table_insert (self->pathname_to_g_file,
|
|
Packit Bot |
201734 |
g_strdup (archive_entry_pathname (self->entry)),
|
|
Packit Bot |
201734 |
g_object_ref (file));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
struct archive_entry *entry, *sparse;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
entry = self->entry;
|
|
Packit Bot |
201734 |
archive_entry_linkify (self->resolver, &entry, &sparse);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (entry != NULL) {
|
|
Packit Bot |
201734 |
GFile *file_to_read;
|
|
Packit Bot |
201734 |
const char *pathname_in_entry;
|
|
Packit Bot |
201734 |
pathname_in_entry = archive_entry_pathname (entry);
|
|
Packit Bot |
201734 |
file_to_read = g_hash_table_lookup (self->pathname_to_g_file,
|
|
Packit Bot |
201734 |
pathname_in_entry);
|
|
Packit Bot |
201734 |
autoar_compressor_do_write_data (self, entry, file_to_read);
|
|
Packit Bot |
201734 |
/* Entries for non-regular files might have their size attribute
|
|
Packit Bot |
201734 |
* different to their actual size on the disk
|
|
Packit Bot |
201734 |
*/
|
|
Packit Bot |
201734 |
if (archive_entry_filetype (entry) != AE_IFREG &&
|
|
Packit Bot |
201734 |
archive_entry_size (entry) != g_file_info_get_size (info)) {
|
|
Packit Bot |
201734 |
self->completed_size += g_file_info_get_size (info);
|
|
Packit Bot |
201734 |
autoar_compressor_signal_progress (self);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_hash_table_remove (self->pathname_to_g_file, pathname_in_entry);
|
|
Packit Bot |
201734 |
/* We have registered g_object_unref function to free the GFile object,
|
|
Packit Bot |
201734 |
* so we do not have to unref it here. */
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (sparse != NULL) {
|
|
Packit Bot |
201734 |
GFile *file_to_read;
|
|
Packit Bot |
201734 |
const char *pathname_in_entry;
|
|
Packit Bot |
201734 |
pathname_in_entry = archive_entry_pathname (entry);
|
|
Packit Bot |
201734 |
file_to_read = g_hash_table_lookup (self->pathname_to_g_file,
|
|
Packit Bot |
201734 |
pathname_in_entry);
|
|
Packit Bot |
201734 |
autoar_compressor_do_write_data (self, sparse, file_to_read);
|
|
Packit Bot |
201734 |
g_hash_table_remove (self->pathname_to_g_file, pathname_in_entry);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_unref (info);
|
|
Packit Bot |
201734 |
};
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_do_recursive_read (AutoarCompressor *self,
|
|
Packit Bot |
201734 |
GFile *root,
|
|
Packit Bot |
201734 |
GFile *file)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
GFileEnumerator *enumerator;
|
|
Packit Bot |
201734 |
GFileInfo *info;
|
|
Packit Bot |
201734 |
GFile *thisfile;
|
|
Packit Bot |
201734 |
const char *thisname;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
enumerator = g_file_enumerate_children (file,
|
|
Packit Bot |
201734 |
"standard::*",
|
|
Packit Bot |
201734 |
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
Packit Bot |
201734 |
self->cancellable,
|
|
Packit Bot |
201734 |
&(self->error));
|
|
Packit Bot |
201734 |
if (enumerator == NULL)
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
while ((info = g_file_enumerator_next_file (enumerator,
|
|
Packit Bot |
201734 |
self->cancellable,
|
|
Packit Bot |
201734 |
&(self->error))) != NULL) {
|
|
Packit Bot |
201734 |
thisname = g_file_info_get_name (info);
|
|
Packit Bot |
201734 |
thisfile = g_file_get_child (file, thisname);
|
|
Packit Bot |
201734 |
autoar_compressor_do_add_to_archive (self, root, thisfile);
|
|
Packit Bot |
201734 |
if (self->error != NULL) {
|
|
Packit Bot |
201734 |
g_object_unref (thisfile);
|
|
Packit Bot |
201734 |
g_object_unref (info);
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
|
|
Packit Bot |
201734 |
autoar_compressor_do_recursive_read (self, root, thisfile);
|
|
Packit Bot |
201734 |
g_object_unref (thisfile);
|
|
Packit Bot |
201734 |
g_object_unref (info);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->error != NULL)
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
if (g_cancellable_is_cancelled (self->cancellable))
|
|
Packit Bot |
201734 |
break;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_unref (enumerator);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_class_init (AutoarCompressorClass *klass)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
GObjectClass *object_class;
|
|
Packit Bot |
201734 |
GType type;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
object_class = G_OBJECT_CLASS (klass);
|
|
Packit Bot |
201734 |
type = G_TYPE_FROM_CLASS (klass);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
object_class->get_property = autoar_compressor_get_property;
|
|
Packit Bot |
201734 |
object_class->set_property = autoar_compressor_set_property;
|
|
Packit Bot |
201734 |
object_class->dispose = autoar_compressor_dispose;
|
|
Packit Bot |
201734 |
object_class->finalize = autoar_compressor_finalize;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_class_install_property (object_class, PROP_SOURCE_FILES,
|
|
Packit Bot |
201734 |
g_param_spec_pointer ("source-files",
|
|
Packit Bot |
201734 |
"Source files list",
|
|
Packit Bot |
201734 |
"The list of GFiles to be archived",
|
|
Packit Bot |
201734 |
G_PARAM_READWRITE |
|
|
Packit Bot |
201734 |
G_PARAM_CONSTRUCT_ONLY |
|
|
Packit Bot |
201734 |
G_PARAM_STATIC_STRINGS));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_class_install_property (object_class, PROP_OUTPUT_FILE,
|
|
Packit Bot |
201734 |
g_param_spec_object ("output-file",
|
|
Packit Bot |
201734 |
"Output directory GFile",
|
|
Packit Bot |
201734 |
"Output directory (GFile) of created archive",
|
|
Packit Bot |
201734 |
G_TYPE_FILE,
|
|
Packit Bot |
201734 |
G_PARAM_READWRITE |
|
|
Packit Bot |
201734 |
G_PARAM_CONSTRUCT_ONLY |
|
|
Packit Bot |
201734 |
G_PARAM_STATIC_STRINGS));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_class_install_property (object_class, PROP_FORMAT,
|
|
Packit Bot |
201734 |
g_param_spec_enum ("format",
|
|
Packit Bot |
201734 |
"Compression format",
|
|
Packit Bot |
201734 |
"The compression format that will be used",
|
|
Packit Bot |
201734 |
AUTOAR_TYPE_FORMAT,
|
|
Packit Bot |
201734 |
AUTOAR_FORMAT_ZIP,
|
|
Packit Bot |
201734 |
G_PARAM_READWRITE |
|
|
Packit Bot |
201734 |
G_PARAM_CONSTRUCT_ONLY |
|
|
Packit Bot |
201734 |
G_PARAM_STATIC_STRINGS));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_class_install_property (object_class, PROP_FILTER,
|
|
Packit Bot |
201734 |
g_param_spec_enum ("filter",
|
|
Packit Bot |
201734 |
"Compression filter",
|
|
Packit Bot |
201734 |
"The compression filter that will be used",
|
|
Packit Bot |
201734 |
AUTOAR_TYPE_FILTER,
|
|
Packit Bot |
201734 |
AUTOAR_FILTER_NONE,
|
|
Packit Bot |
201734 |
G_PARAM_READWRITE |
|
|
Packit Bot |
201734 |
G_PARAM_CONSTRUCT_ONLY |
|
|
Packit Bot |
201734 |
G_PARAM_STATIC_STRINGS));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_class_install_property (object_class, PROP_CREATE_TOP_LEVEL_DIRECTORY,
|
|
Packit Bot |
201734 |
g_param_spec_boolean ("create-top-level-directory",
|
|
Packit Bot |
201734 |
"Create top level directory",
|
|
Packit Bot |
201734 |
"Whether to create a top level directory",
|
|
Packit Bot |
201734 |
FALSE,
|
|
Packit Bot |
201734 |
G_PARAM_READWRITE |
|
|
Packit Bot |
201734 |
G_PARAM_CONSTRUCT |
|
|
Packit Bot |
201734 |
G_PARAM_STATIC_STRINGS));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_class_install_property (object_class, PROP_SIZE, /* This propery is unused! */
|
|
Packit Bot |
201734 |
g_param_spec_uint64 ("size",
|
|
Packit Bot |
201734 |
"Size",
|
|
Packit Bot |
201734 |
"Total bytes will be read from disk",
|
|
Packit Bot |
201734 |
0, G_MAXUINT64, 0,
|
|
Packit Bot |
201734 |
G_PARAM_READABLE |
|
|
Packit Bot |
201734 |
G_PARAM_STATIC_STRINGS));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_class_install_property (object_class, PROP_COMPLETED_SIZE,
|
|
Packit Bot |
201734 |
g_param_spec_uint64 ("completed-size",
|
|
Packit Bot |
201734 |
"Read file size",
|
|
Packit Bot |
201734 |
"Bytes has read from disk",
|
|
Packit Bot |
201734 |
0, G_MAXUINT64, 0,
|
|
Packit Bot |
201734 |
G_PARAM_READABLE |
|
|
Packit Bot |
201734 |
G_PARAM_STATIC_STRINGS));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_class_install_property (object_class, PROP_FILES,
|
|
Packit Bot |
201734 |
g_param_spec_uint ("files",
|
|
Packit Bot |
201734 |
"Files",
|
|
Packit Bot |
201734 |
"Number of files will be compressed",
|
|
Packit Bot |
201734 |
0, G_MAXUINT32, 0,
|
|
Packit Bot |
201734 |
G_PARAM_READABLE |
|
|
Packit Bot |
201734 |
G_PARAM_STATIC_STRINGS));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_class_install_property (object_class, PROP_COMPLETED_FILES,
|
|
Packit Bot |
201734 |
g_param_spec_uint ("completed-files",
|
|
Packit Bot |
201734 |
"Read files",
|
|
Packit Bot |
201734 |
"Number of files has been read",
|
|
Packit Bot |
201734 |
0, G_MAXUINT32, 0,
|
|
Packit Bot |
201734 |
G_PARAM_READABLE |
|
|
Packit Bot |
201734 |
G_PARAM_STATIC_STRINGS));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_class_install_property (object_class, PROP_OUTPUT_IS_DEST,
|
|
Packit Bot |
201734 |
g_param_spec_boolean ("output-is-dest",
|
|
Packit Bot |
201734 |
"Output is destination",
|
|
Packit Bot |
201734 |
"Whether output file is used as destination",
|
|
Packit Bot |
201734 |
FALSE,
|
|
Packit Bot |
201734 |
G_PARAM_READWRITE |
|
|
Packit Bot |
201734 |
G_PARAM_CONSTRUCT |
|
|
Packit Bot |
201734 |
G_PARAM_STATIC_STRINGS));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_class_install_property (object_class, PROP_NOTIFY_INTERVAL,
|
|
Packit Bot |
201734 |
g_param_spec_int64 ("notify-interval",
|
|
Packit Bot |
201734 |
"Notify interval",
|
|
Packit Bot |
201734 |
"Minimal time interval between progress signal",
|
|
Packit Bot |
201734 |
0, G_MAXINT64, 100000,
|
|
Packit Bot |
201734 |
G_PARAM_READWRITE |
|
|
Packit Bot |
201734 |
G_PARAM_CONSTRUCT |
|
|
Packit Bot |
201734 |
G_PARAM_STATIC_STRINGS));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* AutoarCompressor::decide-dest:
|
|
Packit Bot |
201734 |
* @self: the #AutoarCompressor
|
|
Packit Bot |
201734 |
* @destination: the location of the new archive
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* This signal is emitted when the location of the new archive is determined.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
autoar_compressor_signals[DECIDE_DEST] =
|
|
Packit Bot |
201734 |
g_signal_new ("decide-dest",
|
|
Packit Bot |
201734 |
type,
|
|
Packit Bot |
201734 |
G_SIGNAL_RUN_LAST,
|
|
Packit Bot |
201734 |
0, NULL, NULL,
|
|
Packit Bot |
201734 |
g_cclosure_marshal_generic,
|
|
Packit Bot |
201734 |
G_TYPE_NONE,
|
|
Packit Bot |
201734 |
1,
|
|
Packit Bot |
201734 |
G_TYPE_FILE);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* AutoarCompressor::progress:
|
|
Packit Bot |
201734 |
* @self: the #AutoarCompressor
|
|
Packit Bot |
201734 |
* @completed_size: bytes has been read from source files and directories
|
|
Packit Bot |
201734 |
* @completed_files: number of files and directories has been read
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* This signal is used to report progress of creating archives. The value of
|
|
Packit Bot |
201734 |
* @completed_size and @completed_files are the same as the
|
|
Packit Bot |
201734 |
* #AutoarCompressor:completed_size and #AutoarCompressor:completed_files properties,
|
|
Packit Bot |
201734 |
* respectively.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
autoar_compressor_signals[PROGRESS] =
|
|
Packit Bot |
201734 |
g_signal_new ("progress",
|
|
Packit Bot |
201734 |
type,
|
|
Packit Bot |
201734 |
G_SIGNAL_RUN_LAST,
|
|
Packit Bot |
201734 |
0, NULL, NULL,
|
|
Packit Bot |
201734 |
g_cclosure_marshal_generic,
|
|
Packit Bot |
201734 |
G_TYPE_NONE,
|
|
Packit Bot |
201734 |
2,
|
|
Packit Bot |
201734 |
G_TYPE_UINT64,
|
|
Packit Bot |
201734 |
G_TYPE_UINT);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* AutoarCompressor::cancelled:
|
|
Packit Bot |
201734 |
* @self: the #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* This signal is emitted after archive creating job is cancelled by the
|
|
Packit Bot |
201734 |
* #GCancellable.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
autoar_compressor_signals[CANCELLED] =
|
|
Packit Bot |
201734 |
g_signal_new ("cancelled",
|
|
Packit Bot |
201734 |
type,
|
|
Packit Bot |
201734 |
G_SIGNAL_RUN_LAST,
|
|
Packit Bot |
201734 |
0, NULL, NULL,
|
|
Packit Bot |
201734 |
g_cclosure_marshal_VOID__VOID,
|
|
Packit Bot |
201734 |
G_TYPE_NONE,
|
|
Packit Bot |
201734 |
0);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* AutoarCompressor::completed:
|
|
Packit Bot |
201734 |
* @self: the #AutoarCompressor
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* This signal is emitted after the archive creating job is successfully
|
|
Packit Bot |
201734 |
* completed.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
autoar_compressor_signals[COMPLETED] =
|
|
Packit Bot |
201734 |
g_signal_new ("completed",
|
|
Packit Bot |
201734 |
type,
|
|
Packit Bot |
201734 |
G_SIGNAL_RUN_LAST,
|
|
Packit Bot |
201734 |
0, NULL, NULL,
|
|
Packit Bot |
201734 |
g_cclosure_marshal_VOID__VOID,
|
|
Packit Bot |
201734 |
G_TYPE_NONE,
|
|
Packit Bot |
201734 |
0);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* AutoarCompressor::error:
|
|
Packit Bot |
201734 |
* @self: the #AutoarCompressor
|
|
Packit Bot |
201734 |
* @error: the #GError
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* This signal is emitted when error occurs and all jobs should be terminated.
|
|
Packit Bot |
201734 |
* Possible error domains are %AUTOAR_COMPRESSOR_ERROR, %G_IO_ERROR, and
|
|
Packit Bot |
201734 |
* %AUTOAR_LIBARCHIVE_ERROR, which represent error occurs in #AutoarCompressor,
|
|
Packit Bot |
201734 |
* GIO, and libarchive, respectively. The #GError is owned by #AutoarCompressor
|
|
Packit Bot |
201734 |
* and should not be freed.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
autoar_compressor_signals[AR_ERROR] =
|
|
Packit Bot |
201734 |
g_signal_new ("error",
|
|
Packit Bot |
201734 |
type,
|
|
Packit Bot |
201734 |
G_SIGNAL_RUN_LAST,
|
|
Packit Bot |
201734 |
0, NULL, NULL,
|
|
Packit Bot |
201734 |
g_cclosure_marshal_generic,
|
|
Packit Bot |
201734 |
G_TYPE_NONE,
|
|
Packit Bot |
201734 |
1,
|
|
Packit Bot |
201734 |
G_TYPE_ERROR);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_init (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
self->size = 0;
|
|
Packit Bot |
201734 |
self->completed_size = 0;
|
|
Packit Bot |
201734 |
self->files = 0;
|
|
Packit Bot |
201734 |
self->completed_files = 0;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self->notify_last = 0;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self->ostream = NULL;
|
|
Packit Bot |
201734 |
self->buffer_size = BUFFER_SIZE;
|
|
Packit Bot |
201734 |
self->buffer = g_new (char, self->buffer_size);
|
|
Packit Bot |
201734 |
self->error = NULL;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self->cancellable = NULL;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self->a = archive_write_new ();
|
|
Packit Bot |
201734 |
self->entry = archive_entry_new ();
|
|
Packit Bot |
201734 |
self->resolver = archive_entry_linkresolver_new ();
|
|
Packit Bot |
201734 |
self->pathname_to_g_file = g_hash_table_new_full (g_str_hash,
|
|
Packit Bot |
201734 |
g_str_equal,
|
|
Packit Bot |
201734 |
g_free,
|
|
Packit Bot |
201734 |
g_object_unref);
|
|
Packit Bot |
201734 |
self->source_basename_noext = NULL;
|
|
Packit Bot |
201734 |
self->extension = NULL;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self->in_thread = FALSE;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_new:
|
|
Packit Bot |
201734 |
* @source_files: a #GList of source #GFiles to be archived
|
|
Packit Bot |
201734 |
* @output_file: output directory of the new archive, or the file name of the
|
|
Packit Bot |
201734 |
* new archive if you set #AutoarCompressor:output-is-dest on the returned object
|
|
Packit Bot |
201734 |
* @format: the compression format
|
|
Packit Bot |
201734 |
* @filter: the compression filter
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Create a new #AutoarCompressor object.
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Returns: (transfer full): a new #AutoarCompressor object
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
AutoarCompressor*
|
|
Packit Bot |
201734 |
autoar_compressor_new (GList *source_files,
|
|
Packit Bot |
201734 |
GFile *output_file,
|
|
Packit Bot |
201734 |
AutoarFormat format,
|
|
Packit Bot |
201734 |
AutoarFilter filter,
|
|
Packit Bot |
201734 |
gboolean create_top_level_directory)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
AutoarCompressor *self;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self =
|
|
Packit Bot |
201734 |
g_object_new (AUTOAR_TYPE_COMPRESSOR,
|
|
Packit Bot |
201734 |
"source-files", g_list_copy_deep (source_files,
|
|
Packit Bot |
201734 |
(GCopyFunc)g_object_ref,
|
|
Packit Bot |
201734 |
NULL),
|
|
Packit Bot |
201734 |
"output-file", g_object_ref (output_file),
|
|
Packit Bot |
201734 |
"format", format,
|
|
Packit Bot |
201734 |
"filter", filter,
|
|
Packit Bot |
201734 |
"create-top-level-directory", create_top_level_directory,
|
|
Packit Bot |
201734 |
NULL);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
return self;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_step_initialize_object (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
/* Step 0: Setup the libarchive object and the file name extension */
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
AutoarFormatFunc format_func;
|
|
Packit Bot |
201734 |
AutoarFilterFunc filter_func;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
int r;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (!autoar_format_is_valid (self->format)) {
|
|
Packit Bot |
201734 |
self->error = g_error_new (AUTOAR_COMPRESSOR_ERROR, INVALID_FORMAT,
|
|
Packit Bot |
201734 |
"Format %d is invalid", self->format);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (!autoar_filter_is_valid (self->filter)) {
|
|
Packit Bot |
201734 |
self->error = g_error_new (AUTOAR_COMPRESSOR_ERROR, INVALID_FILTER,
|
|
Packit Bot |
201734 |
"Filter %d is invalid", self->filter);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
self->extension = autoar_format_filter_get_extension (self->format,
|
|
Packit Bot |
201734 |
self->filter);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
r = archive_write_set_bytes_in_last_block (self->a, 1);
|
|
Packit Bot |
201734 |
if (r != ARCHIVE_OK) {
|
|
Packit Bot |
201734 |
self->error = autoar_common_g_error_new_a (self->a, NULL);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
format_func = autoar_format_get_libarchive_write (self->format);
|
|
Packit Bot |
201734 |
r = (*format_func)(self->a);
|
|
Packit Bot |
201734 |
if (r != ARCHIVE_OK) {
|
|
Packit Bot |
201734 |
self->error = autoar_common_g_error_new_a (self->a, NULL);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
filter_func = autoar_filter_get_libarchive_write (self->filter);
|
|
Packit Bot |
201734 |
r = (*filter_func)(self->a);
|
|
Packit Bot |
201734 |
if (r != ARCHIVE_OK) {
|
|
Packit Bot |
201734 |
self->error = autoar_common_g_error_new_a (self->a, NULL);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_step_decide_dest (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
/* Step 1: Set the destination file name
|
|
Packit Bot |
201734 |
* Use the first source file name */
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_step_decide_dest: called");
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
GFile *file_source; /* Do not unref */
|
|
Packit Bot |
201734 |
GFileInfo *source_info;
|
|
Packit Bot |
201734 |
char *source_basename;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
file_source = self->source_files->data;
|
|
Packit Bot |
201734 |
source_info = g_file_query_info (file_source,
|
|
Packit Bot |
201734 |
G_FILE_ATTRIBUTE_STANDARD_TYPE,
|
|
Packit Bot |
201734 |
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
Packit Bot |
201734 |
self->cancellable,
|
|
Packit Bot |
201734 |
&(self->error));
|
|
Packit Bot |
201734 |
if (source_info == NULL)
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
source_basename = g_file_get_basename (file_source);
|
|
Packit Bot |
201734 |
if (g_file_info_get_file_type (source_info) == G_FILE_TYPE_REGULAR)
|
|
Packit Bot |
201734 |
self->source_basename_noext =
|
|
Packit Bot |
201734 |
autoar_common_get_basename_remove_extension (source_basename);
|
|
Packit Bot |
201734 |
else
|
|
Packit Bot |
201734 |
self->source_basename_noext = g_strdup (source_basename);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_unref (source_info);
|
|
Packit Bot |
201734 |
g_free (source_basename);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
char *dest_basename;
|
|
Packit Bot |
201734 |
int i;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
dest_basename = g_strconcat (self->source_basename_noext,
|
|
Packit Bot |
201734 |
self->extension, NULL);
|
|
Packit Bot |
201734 |
self->dest = g_file_get_child (self->output_file, dest_basename);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
for (i = 1;
|
|
Packit Bot |
201734 |
g_file_query_exists (self->dest, self->cancellable);
|
|
Packit Bot |
201734 |
i++) {
|
|
Packit Bot |
201734 |
g_free (dest_basename);
|
|
Packit Bot |
201734 |
g_object_unref (self->dest);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (g_cancellable_is_cancelled (self->cancellable))
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
dest_basename = g_strdup_printf ("%s(%d)%s",
|
|
Packit Bot |
201734 |
self->source_basename_noext,
|
|
Packit Bot |
201734 |
i, self->extension);
|
|
Packit Bot |
201734 |
self->dest = g_file_get_child (self->output_file,
|
|
Packit Bot |
201734 |
dest_basename);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_free (dest_basename);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (!g_file_query_exists (self->output_file, self->cancellable)) {
|
|
Packit Bot |
201734 |
g_file_make_directory_with_parents (self->output_file,
|
|
Packit Bot |
201734 |
self->cancellable,
|
|
Packit Bot |
201734 |
&(self->error));
|
|
Packit Bot |
201734 |
if (self->error != NULL)
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
autoar_compressor_signal_decide_dest (self);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_step_decide_dest_already (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
/* Alternative step 1: Output is destination */
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
char *output_basename;
|
|
Packit Bot |
201734 |
self->dest = g_object_ref (self->output_file);
|
|
Packit Bot |
201734 |
output_basename = g_file_get_basename (self->output_file);
|
|
Packit Bot |
201734 |
self->source_basename_noext =
|
|
Packit Bot |
201734 |
autoar_common_get_basename_remove_extension (output_basename);
|
|
Packit Bot |
201734 |
g_free (output_basename);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
autoar_compressor_signal_decide_dest (self);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_step_create (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
/* Step 2: Create and open the new archive file */
|
|
Packit Bot |
201734 |
GList *l;
|
|
Packit Bot |
201734 |
int r;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_step_create: called");
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
r = archive_write_open (self->a, self,
|
|
Packit Bot |
201734 |
libarchive_write_open_cb,
|
|
Packit Bot |
201734 |
libarchive_write_write_cb,
|
|
Packit Bot |
201734 |
libarchive_write_close_cb);
|
|
Packit Bot |
201734 |
if (r != ARCHIVE_OK) {
|
|
Packit Bot |
201734 |
if (self->error == NULL)
|
|
Packit Bot |
201734 |
self->error = autoar_common_g_error_new_a (self->a, NULL);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
archive_entry_linkresolver_set_strategy (self->resolver,
|
|
Packit Bot |
201734 |
archive_format (self->a));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
for (l = self->source_files; l != NULL; l = l->next) {
|
|
Packit Bot |
201734 |
GFile *file; /* Do not unref */
|
|
Packit Bot |
201734 |
GFileType filetype;
|
|
Packit Bot |
201734 |
GFileInfo *fileinfo;
|
|
Packit Bot |
201734 |
g_autofree gchar *pathname;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
file = l->data;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
pathname = g_file_get_path (file);
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_step_create: %s", pathname);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
fileinfo = g_file_query_info (file,
|
|
Packit Bot |
201734 |
G_FILE_ATTRIBUTE_STANDARD_TYPE,
|
|
Packit Bot |
201734 |
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
Packit Bot |
201734 |
self->cancellable,
|
|
Packit Bot |
201734 |
&(self->error));
|
|
Packit Bot |
201734 |
if (self->error != NULL)
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
filetype = g_file_info_get_file_type (fileinfo);
|
|
Packit Bot |
201734 |
g_object_unref (fileinfo);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
autoar_compressor_do_add_to_archive (self, file, file);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (filetype == G_FILE_TYPE_DIRECTORY)
|
|
Packit Bot |
201734 |
autoar_compressor_do_recursive_read (self, file, file);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->error != NULL)
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (g_cancellable_is_cancelled (self->cancellable))
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/* Process the final entry */
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
struct archive_entry *entry, *sparse;
|
|
Packit Bot |
201734 |
entry = NULL;
|
|
Packit Bot |
201734 |
archive_entry_linkify (self->resolver, &entry, &sparse);
|
|
Packit Bot |
201734 |
if (entry != NULL) {
|
|
Packit Bot |
201734 |
GFile *file_to_read;
|
|
Packit Bot |
201734 |
const char *pathname_in_entry;
|
|
Packit Bot |
201734 |
pathname_in_entry = archive_entry_pathname (entry);
|
|
Packit Bot |
201734 |
file_to_read = g_hash_table_lookup (self->pathname_to_g_file,
|
|
Packit Bot |
201734 |
pathname_in_entry);
|
|
Packit Bot |
201734 |
autoar_compressor_do_write_data (self, entry, file_to_read);
|
|
Packit Bot |
201734 |
/* I think we do not have to remove the entry in the hash table now
|
|
Packit Bot |
201734 |
* because we are going to free the entire hash table. */
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_step_cleanup (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
/* Step 3: Close the libarchive object and force progress to be updated.
|
|
Packit Bot |
201734 |
* We do not have to do other cleanup because they are handled in dispose
|
|
Packit Bot |
201734 |
* and finalize functions. */
|
|
Packit Bot |
201734 |
self->notify_last = 0;
|
|
Packit Bot |
201734 |
autoar_compressor_signal_progress (self);
|
|
Packit Bot |
201734 |
if (archive_write_close (self->a) != ARCHIVE_OK) {
|
|
Packit Bot |
201734 |
g_autofree gchar *output_name;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
output_name = autoar_common_g_file_get_name (self->output_file);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (self->error == NULL)
|
|
Packit Bot |
201734 |
self->error =
|
|
Packit Bot |
201734 |
autoar_common_g_error_new_a (self->a, output_name);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_run (AutoarCompressor *self)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
/* Numbers of steps.
|
|
Packit Bot |
201734 |
* The array size must be modified if more steps are added. */
|
|
Packit Bot |
201734 |
void (*steps[5])(AutoarCompressor*);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
int i;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_return_if_fail (AUTOAR_IS_COMPRESSOR (self));
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_return_if_fail (self->source_files != NULL);
|
|
Packit Bot |
201734 |
g_return_if_fail (self->output_file != NULL);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/* A GFile* list without a GFile* is not allowed */
|
|
Packit Bot |
201734 |
g_return_if_fail (self->source_files->data != NULL);
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
if (g_cancellable_is_cancelled (self->cancellable)) {
|
|
Packit Bot |
201734 |
autoar_compressor_signal_cancelled (self);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
i = 0;
|
|
Packit Bot |
201734 |
steps[i++] = autoar_compressor_step_initialize_object;
|
|
Packit Bot |
201734 |
steps[i++] = self->output_is_dest ?
|
|
Packit Bot |
201734 |
autoar_compressor_step_decide_dest_already :
|
|
Packit Bot |
201734 |
autoar_compressor_step_decide_dest;
|
|
Packit Bot |
201734 |
steps[i++] = autoar_compressor_step_create;
|
|
Packit Bot |
201734 |
steps[i++] = autoar_compressor_step_cleanup;
|
|
Packit Bot |
201734 |
steps[i++] = NULL;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
for (i = 0; steps[i] != NULL; i++) {
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_run: Step %d Begin", i);
|
|
Packit Bot |
201734 |
(*steps[i])(self);
|
|
Packit Bot |
201734 |
g_debug ("autoar_compressor_run: Step %d End", i);
|
|
Packit Bot |
201734 |
if (self->error != NULL) {
|
|
Packit Bot |
201734 |
autoar_compressor_signal_error (self);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
if (g_cancellable_is_cancelled (self->cancellable)) {
|
|
Packit Bot |
201734 |
autoar_compressor_signal_cancelled (self);
|
|
Packit Bot |
201734 |
return;
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
autoar_compressor_signal_completed (self);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_start:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor object
|
|
Packit Bot |
201734 |
* @cancellable: optional #GCancellable object, or %NULL to ignore
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Runs the archive creating work. All callbacks will be called in the same
|
|
Packit Bot |
201734 |
* thread as the caller of this functions.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
void
|
|
Packit Bot |
201734 |
autoar_compressor_start (AutoarCompressor *self,
|
|
Packit Bot |
201734 |
GCancellable *cancellable)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
if (cancellable != NULL)
|
|
Packit Bot |
201734 |
g_object_ref (cancellable);
|
|
Packit Bot |
201734 |
self->cancellable = cancellable;
|
|
Packit Bot |
201734 |
self->in_thread = FALSE;
|
|
Packit Bot |
201734 |
autoar_compressor_run (self);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
static void
|
|
Packit Bot |
201734 |
autoar_compressor_start_async_thread (GTask *task,
|
|
Packit Bot |
201734 |
gpointer source_object,
|
|
Packit Bot |
201734 |
gpointer task_data,
|
|
Packit Bot |
201734 |
GCancellable *cancellable)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
AutoarCompressor *self = source_object;
|
|
Packit Bot |
201734 |
autoar_compressor_run (self);
|
|
Packit Bot |
201734 |
g_task_return_pointer (task, NULL, g_free);
|
|
Packit Bot |
201734 |
g_object_unref (self);
|
|
Packit Bot |
201734 |
g_object_unref (task);
|
|
Packit Bot |
201734 |
}
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
/**
|
|
Packit Bot |
201734 |
* autoar_compressor_start_async:
|
|
Packit Bot |
201734 |
* @self: an #AutoarCompressor object
|
|
Packit Bot |
201734 |
* @cancellable: optional #GCancellable object, or %NULL to ignore
|
|
Packit Bot |
201734 |
*
|
|
Packit Bot |
201734 |
* Asynchronously runs the archive creating work. You should connect to
|
|
Packit Bot |
201734 |
* #AutoarCompressor::cancelled, #AutoarCompressor::error, and
|
|
Packit Bot |
201734 |
* #AutoarCompressor::completed signal to get notification when the work is
|
|
Packit Bot |
201734 |
* terminated. All callbacks will be called in the main thread, so you can
|
|
Packit Bot |
201734 |
* safely manipulate GTK+ widgets in the callbacks.
|
|
Packit Bot |
201734 |
**/
|
|
Packit Bot |
201734 |
void
|
|
Packit Bot |
201734 |
autoar_compressor_start_async (AutoarCompressor *self,
|
|
Packit Bot |
201734 |
GCancellable *cancellable)
|
|
Packit Bot |
201734 |
{
|
|
Packit Bot |
201734 |
GTask *task;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
g_object_ref (self);
|
|
Packit Bot |
201734 |
if (cancellable != NULL)
|
|
Packit Bot |
201734 |
g_object_ref (cancellable);
|
|
Packit Bot |
201734 |
self->cancellable = cancellable;
|
|
Packit Bot |
201734 |
self->in_thread = TRUE;
|
|
Packit Bot |
201734 |
|
|
Packit Bot |
201734 |
task = g_task_new (self, NULL, NULL, NULL);
|
|
Packit Bot |
201734 |
g_task_set_task_data (task, NULL, NULL);
|
|
Packit Bot |
201734 |
g_task_run_in_thread (task, autoar_compressor_start_async_thread);
|
|
Packit Bot |
201734 |
}
|